Skip to content

Commit

Permalink
feat: add dummy cards and support pre-authorized code is jwt
Browse files Browse the repository at this point in the history
  • Loading branch information
bibash28 committed Aug 10, 2023
1 parent 621f0f6 commit 5694cc6
Show file tree
Hide file tree
Showing 13 changed files with 143 additions and 47 deletions.
Binary file added assets/image/dummy_employee_credential.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions lib/app/shared/constants/image_strings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class ImageStrings {
'$imagePath/default_polygon_card.png';
static const String euDiplomaCard = '$imagePath/eu_diploma_card.png';
static const String employeeCard = '$imagePath/employee_credential.png';
static const String employeeCardDummy = '$imagePath/employee_credential.png';
static const String defiComplianceCard =
'$imagePath/defi-compliance-card.png';
static const String euVerifiableId = '$imagePath/eu_verifiable_id.png';
Expand Down Expand Up @@ -141,6 +142,8 @@ class ImageStrings {
'$imagePath/dummy_arago_identity_card.png';
static const String dummyAragoEmailPassCard =
'$imagePath/dummy_arago_email_pass_card.png';
static const String dummyEmployeeCard =
'$imagePath/dummy_employee_credential.png';

static const String onBoardingFirstImage =
'$imagePath/onBoardingFirstImage.png';
Expand Down
5 changes: 2 additions & 3 deletions lib/dashboard/discover/view/discover_details_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,8 @@ class DiscoverDetailsView extends StatelessWidget {
children: [
Padding(
padding: const EdgeInsets.all(10),
child: AspectRatio(
aspectRatio: Sizes.credentialAspectRatio,
child: CredentialImage(image: dummyCredential.image!),
child: DummyCredentialImage(
discoverDummyCredential: dummyCredential,
),
),
DetailFields(dummyCredential: dummyCredential),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class DiscoverCredentialItem extends StatelessWidget {
),
);
},
child: CredentialImage(image: dummyCredential.image!),
child: DummyCredentialImage(discoverDummyCredential: dummyCredential),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,10 @@ class DiscoverDummyCredential extends Equatable {
image = ImageStrings.tezosOwnershipCard;
break;

case CredentialSubjectType.employeeCredential:
image = ImageStrings.dummyEmployeeCard;
break;

case CredentialSubjectType.voucher:
case CredentialSubjectType.selfIssued:
case CredentialSubjectType.defaultCredential:
Expand Down Expand Up @@ -305,7 +309,6 @@ class DiscoverDummyCredential extends Equatable {
case CredentialSubjectType.kycCountryOfResidence:
case CredentialSubjectType.proofOfTwitterStats:
case CredentialSubjectType.civicPassCredential:
case CredentialSubjectType.employeeCredential:
}

return DiscoverDummyCredential(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,8 @@ class Oidc4vcCredentialPickView extends StatelessWidget {
child: Column(
children: [
if (discoverDummyCredential.image != null) ...[
AspectRatio(
aspectRatio: Sizes.credentialAspectRatio,
child: CredentialImage(
image: discoverDummyCredential.image!,
),
DummyCredentialImage(
discoverDummyCredential: discoverDummyCredential,
),
] else ...[
AspectRatio(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import 'package:altme/app/app.dart';
import 'package:altme/dashboard/dashboard.dart';
import 'package:altme/theme/theme.dart';
import 'package:flutter/material.dart';

class DummyCredentialImage extends StatelessWidget {
const DummyCredentialImage({
required this.discoverDummyCredential,
this.aspectRatio = Sizes.credentialAspectRatio,
super.key,
});

final DiscoverDummyCredential discoverDummyCredential;
final double aspectRatio;

@override
Widget build(BuildContext context) {
String? title;

if (discoverDummyCredential.credentialSubjectType ==
CredentialSubjectType.employeeCredential) {
title = discoverDummyCredential.credentialSubjectType.title;
}

return CredentialContainer(
child: DecoratedBox(
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.fill,
image: AssetImage(discoverDummyCredential.image!),
),
),
child: AspectRatio(
aspectRatio: aspectRatio,
child: CustomMultiChildLayout(
delegate: CredentialBaseWidgetDelegate(position: Offset.zero),
children: [
if (title != null)
LayoutId(
id: 'title',
child: FractionallySizedBox(
widthFactor: 0.7,
heightFactor: 0.19,
child: Container(
alignment: Alignment.centerLeft,
child: MyText(
title,
style:
Theme.of(context).textTheme.identitiyBaseTitleText,
),
),
),
),
],
),
),
),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export 'display_name_card.dart';
export 'display_properties_widget.dart';
export 'display_signature.dart';
export 'display_title_widget.dart';
export 'dummy_credential_image.dart';
export 'labeled_display_mapping_widget.dart';
export 'list_item.dart';
export 'skills_list_display.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,9 @@ class MissingCredentialsView extends StatelessWidget {
physics: const ScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context, i) {
final homeCredential = state.dummyCredentials[i];
final credentialType = homeCredential.credentialSubjectType;
final discoverDummyCredential = state.dummyCredentials[i];
final credentialType =
discoverDummyCredential.credentialSubjectType;
return Container(
margin: const EdgeInsets.only(
bottom: 15,
Expand All @@ -104,10 +105,8 @@ class MissingCredentialsView extends StatelessWidget {
),
child: credentialType.isBlockchainAccount
? credentialType.blockchainWidget
: AspectRatio(
aspectRatio: Sizes.credentialAspectRatio,
child:
CredentialImage(image: homeCredential.image!),
: DummyCredentialImage(
discoverDummyCredential: discoverDummyCredential,
),
);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {
didKitProvider: didKitProvider,
qrCodeScanCubit: qrCodeScanCubit,
secureStorageProvider: getSecureStorage,
jwtDecode: jwtDecode,
);
return;
}
Expand Down Expand Up @@ -567,6 +568,7 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {
secureStorageProvider: getSecureStorage,
credentialTypeOrId: credentialTypeOrId.toString(),
isLastCall: i + 1 == credentials.length,
jwtDecode: jwtDecode,
);
}
oidc4vc.resetNonceAndAccessToken();
Expand Down
71 changes: 40 additions & 31 deletions lib/oidc4vc/initiate_oidv4vc_credential_issuance.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:altme/oidc4vc/add_oidc4vc_credential.dart';
import 'package:crypto/crypto.dart';
import 'package:did_kit/did_kit.dart';
import 'package:fast_base58/fast_base58.dart';
import 'package:jwt_decode/jwt_decode.dart';
import 'package:oidc4vc/oidc4vc.dart';
import 'package:secure_storage/secure_storage.dart';

Expand All @@ -17,6 +18,7 @@ Future<void> initiateOIDC4VCCredentialIssuance({
required DIDKitProvider didKitProvider,
required CredentialsCubit credentialsCubit,
required SecureStorageProvider secureStorageProvider,
required JWTDecode jwtDecode,
}) async {
final Uri uriFromScannedResponse = Uri.parse(scannedResponse);

Expand All @@ -31,12 +33,6 @@ Future<void> initiateOIDC4VCCredentialIssuance({
credentialTypeOrId = credentialOfferJson['credentials'];
break;
case OIDC4VCType.GAIAX:
final credentialOfferJson = jsonDecode(
uriFromScannedResponse.queryParameters['credential_offer'].toString(),
);
credentialTypeOrId = credentialOfferJson['credential_type'];

break;
case OIDC4VCType.EBSIV2:
credentialTypeOrId =
uriFromScannedResponse.queryParameters['credential_type'];
Expand All @@ -60,6 +56,7 @@ Future<void> initiateOIDC4VCCredentialIssuance({
credentialTypeOrId: credentialTypeOrId.toString(),
secureStorageProvider: secureStorageProvider,
isLastCall: true,
jwtDecode: jwtDecode,
);
oidc4vc.resetNonceAndAccessToken();
qrCodeScanCubit.goBack();
Expand All @@ -75,21 +72,12 @@ Future<void> getAndAddCredential({
required String credentialTypeOrId,
required SecureStorageProvider secureStorageProvider,
required bool isLastCall,
required JWTDecode jwtDecode,
}) async {
final Uri uriFromScannedResponse = Uri.parse(scannedResponse);

String? preAuthorizedCode;
late String issuer;
late String did;
late String kid;

final mnemonic =
await secureStorageProvider.get(SecureStorageKeys.ssiMnemonic);

final privateKey = await oidc4vc.privateKeyFromMnemonic(
mnemonic: mnemonic!,
index: oidc4vcType.index,
);

switch (oidc4vcType) {
case OIDC4VCType.DEFAULT:
Expand All @@ -102,27 +90,50 @@ Future<void> getAndAddCredential({
['pre-authorized_code']
.toString();
issuer = credentialOfferJson['credential_issuer'].toString();

const didMethod = AltMeStrings.defaultDIDMethod;
did = didKitProvider.keyToDID(didMethod, privateKey);
kid = await didKitProvider.keyToVerificationMethod(didMethod, privateKey);
break;
case OIDC4VCType.GAIAX:
final credentialOfferJson = jsonDecode(
uriFromScannedResponse.queryParameters['credential_offer'].toString(),
);
preAuthorizedCode = credentialOfferJson['pre-authorized_code'].toString();
issuer = credentialOfferJson['issuer'].toString();
case OIDC4VCType.EBSIV2:
issuer = uriFromScannedResponse.queryParameters['issuer'].toString();
preAuthorizedCode =
uriFromScannedResponse.queryParameters['pre-authorized_code'];

break;
case OIDC4VCType.EBSIV3:
case OIDC4VCType.JWTVC:
break;
}

/// if preAuthorizedCode is jwt then parse it
if (preAuthorizedCode != null) {
final isJwt = jwtDecode.isJWT(preAuthorizedCode);
if (isJwt) {
final data = jwtDecode.parseJwt(preAuthorizedCode);
preAuthorizedCode = data['sub'].toString();
}
}

late String did;
late String kid;

final mnemonic =
await secureStorageProvider.get(SecureStorageKeys.ssiMnemonic);

final privateKey = await oidc4vc.privateKeyFromMnemonic(
mnemonic: mnemonic!,
index: oidc4vcType.index,
);

switch (oidc4vcType) {
case OIDC4VCType.DEFAULT:
case OIDC4VCType.HEDERA:
case OIDC4VCType.GAIAX:
const didMethod = AltMeStrings.defaultDIDMethod;
did = didKitProvider.keyToDID(didMethod, privateKey);
kid = await didKitProvider.keyToVerificationMethod(didMethod, privateKey);

break;
case OIDC4VCType.EBSIV2:
preAuthorizedCode =
uriFromScannedResponse.queryParameters['pre-authorized_code'];
issuer = uriFromScannedResponse.queryParameters['issuer'].toString();

case OIDC4VCType.EBSIV2:
final private = await oidc4vc.getPrivateKey(mnemonic, privateKey);

final thumbprint = getThumbprint(private);
Expand All @@ -148,8 +159,6 @@ Future<void> getAndAddCredential({
privateKey,
);

print(encodedCredentialFromOIDC4VC);

await addOIDC4VCCredential(
encodedCredentialFromOIDC4VC,
uriFromScannedResponse,
Expand Down
1 change: 1 addition & 0 deletions lib/splash/view/splash_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ class _SplashViewState extends State<SplashView> {
didKitProvider: DIDKitProvider(),
qrCodeScanCubit: context.read<QRCodeScanCubit>(),
secureStorageProvider: secure_storage.getSecureStorage,
jwtDecode: JWTDecode(),
);
}
}
Expand Down
22 changes: 22 additions & 0 deletions packages/jwt_decode/lib/src/jwt_decode.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,28 @@ import 'dart:convert';
/// JWT decode package
/// {@endtemplate}
class JWTDecode {
///isJWT
bool isJWT(String input) {
final parts = input.split('.');

if (parts.length != 3) {
return false;
}

try {
final payload = _decodeBase64(parts[1]);

final dynamic payloadMap = json.decode(payload);
if (payloadMap is! Map<String, dynamic>) {
return false;
}

return true;
} catch (e) {
return false;
}
}

///parseJwt
Map<String, dynamic> parseJwt(String token) {
final parts = token.split('.');
Expand Down

0 comments on commit 5694cc6

Please sign in to comment.