Skip to content

Commit

Permalink
feat: Test 3 - issuance of multiple vc with use of authorization deta…
Browse files Browse the repository at this point in the history
…ils #1883
  • Loading branch information
bibash28 committed Sep 11, 2023
1 parent 676e4fd commit 08d3782
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 93 deletions.
8 changes: 7 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,13 @@
"request": "launch",
"type": "dart",
"program": "lib/main_production.dart",
"args": ["--flavor", "production", "--target", "lib/main_production.dart"]
"args": [
"--flavor",
"production",
"--target",
"lib/main_production.dart",
"--release"
]
}
]
}
6 changes: 4 additions & 2 deletions lib/credentials/cubit/credentials_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,9 @@ class CredentialsCubit extends Cubit<CredentialsState> {
),
),
);
if (!isPendingCredential)
if (!isPendingCredential) {
await modifyCredential(credential: updatedCredential);
}
await credentialsRepository.insert(updatedCredential);
credentials = List.of(state.credentials)..add(updatedCredential);
} else if (credential.isDefaultCredential && credential.isPolygonIdCard) {
Expand All @@ -226,8 +227,9 @@ class CredentialsCubit extends Cubit<CredentialsState> {
),
),
);
if (!isPendingCredential)
if (!isPendingCredential) {
await modifyCredential(credential: updatedCredential);
}
await credentialsRepository.insert(updatedCredential);
credentials = List.of(state.credentials)..add(updatedCredential);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -981,7 +981,7 @@ class QRCodeScanCubit extends Cubit<QRCodeScanState> {
);
}

oidc4vc.resetNonceAndAccessToken();
oidc4vc.resetNonceAndAccessTokenAndAuthorizationDetails();
goBack();
} catch (e) {
if (e is MessageHandler) {
Expand Down
114 changes: 60 additions & 54 deletions lib/oidc4vc/get_and_add_credential.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Future<void> getAndAddCredential({
/// preAuthorizedCode != null
/// this is full phase flow for preAuthorizedCode
final (
dynamic encodedCredentialOrFutureToken,
List<dynamic> encodedCredentialOrFutureTokens,
String? deferredCredentialEndpoint,
String format
) = await oidc4vc.getCredential(
Expand All @@ -65,63 +65,69 @@ Future<void> getAndAddCredential({
code: codeForAuthorisedFlow,
codeVerifier: codeVerifier,
);
final String credentialName = getCredentialData(credential);
final acceptanceToken = encodedCredentialOrFutureToken['acceptance_token'];

if (acceptanceToken != null && deferredCredentialEndpoint != null) {
/// add deferred card
final id = const Uuid().v4();
for (int i = 0; i < encodedCredentialOrFutureTokens.length; i++) {
final data = encodedCredentialOrFutureTokens[i];
final String credentialName = getCredentialData(credential);
final acceptanceToken = data['acceptance_token'];

final credentialModel = CredentialModel(
id: id,
credentialPreview: Credential(
'dummy1',
['dummy2'],
[credentialName],
'dummy4',
'dummy5',
'',
[Proof.dummy()],
CredentialSubjectModel(
id: 'dummy7',
type: 'dummy8',
issuedBy: const Author(''),
credentialCategory: CredentialCategory.pendingCards,
credentialSubjectType: CredentialSubjectType.defaultCredential,
if (acceptanceToken != null && deferredCredentialEndpoint != null) {
/// add deferred card
final id = const Uuid().v4();

final credentialModel = CredentialModel(
id: id,
credentialPreview: Credential(
'dummy1',
['dummy2'],
[credentialName],
'dummy4',
'dummy5',
'',
[Proof.dummy()],
CredentialSubjectModel(
id: 'dummy7',
type: 'dummy8',
issuedBy: const Author(''),
credentialCategory: CredentialCategory.pendingCards,
credentialSubjectType: CredentialSubjectType.defaultCredential,
),
[Translation('en', '')],
[Translation('en', '')],
CredentialStatusField.emptyCredentialStatusField(),
[Evidence.emptyEvidence()],
),
data: const {},
display: Display.emptyDisplay(),
image: '',
shareLink: '',
pendingInfo: PendingInfo(
acceptanceToken: acceptanceToken.toString(),
deferredCredentialEndpoint: deferredCredentialEndpoint,
format: format,
url: scannedResponse,
),
[Translation('en', '')],
[Translation('en', '')],
CredentialStatusField.emptyCredentialStatusField(),
[Evidence.emptyEvidence()],
),
data: const {},
display: Display.emptyDisplay(),
image: '',
shareLink: '',
pendingInfo: PendingInfo(
acceptanceToken: acceptanceToken.toString(),
deferredCredentialEndpoint: deferredCredentialEndpoint,
);
// insert the credential in the wallet
await credentialsCubit.insertCredential(
credential: credentialModel,
showStatus: false,
showMessage:
isLastCall && i + 1 == encodedCredentialOrFutureTokens.length,
isPendingCredential: true,
);
} else {
await addOIDC4VCCredential(
encodedCredentialFromOIDC4VC: data,
credentialsCubit: credentialsCubit,
oidc4vcType: oidc4vcType,
issuer: issuer,
credentialType: credentialName,
isLastCall:
isLastCall && i + 1 == encodedCredentialOrFutureTokens.length,
format: format,
url: scannedResponse,
),
);
// insert the credential in the wallet
await credentialsCubit.insertCredential(
credential: credentialModel,
showStatus: false,
showMessage: isLastCall,
isPendingCredential: true,
);
} else {
await addOIDC4VCCredential(
encodedCredentialFromOIDC4VC: encodedCredentialOrFutureToken,
credentialsCubit: credentialsCubit,
oidc4vcType: oidc4vcType,
issuer: issuer,
credentialType: credentialName,
isLastCall: isLastCall,
format: format,
);
);
}
}
} else {
throw Exception();
Expand Down
2 changes: 1 addition & 1 deletion lib/oidc4vc/initiate_oidv4vc_credential_issuance.dart
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ Future<void> initiateOIDC4VCCredentialIssuance({
issuer: issuer,
preAuthorizedCode: preAuthorizedCode,
);
oidc4vc.resetNonceAndAccessToken();
oidc4vc.resetNonceAndAccessTokenAndAuthorizationDetails();
qrCodeScanCubit.goBack();
}
}
136 changes: 102 additions & 34 deletions packages/oidc4vc/lib/src/oidc4vc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,10 @@ class OIDC4VC {

String? nonce;
String? accessToken;
List<dynamic>? authorizationDetails;

/// Retreive credential_type from url
Future<(dynamic, String?, String)> getCredential({
Future<(List<dynamic>, String?, String)> getCredential({
required String issuer,
required dynamic credential,
required String did,
Expand Down Expand Up @@ -259,6 +260,8 @@ class OIDC4VC {
final response = await getToken(tokenEndPoint, tokenData);
nonce = response['c_nonce'] as String;
accessToken = response['access_token'] as String;
authorizationDetails =
response['authorization_details'] as List<dynamic>?;
}

final private = await getPrivateKey(
Expand All @@ -276,11 +279,80 @@ class OIDC4VC {

if (nonce == null) throw Exception();

final (credentialData, format) = await buildCredentialData(
String? deferredCredentialEndpoint;

if (openidConfigurationResponse['deferred_credential_endpoint'] != null) {
deferredCredentialEndpoint =
openidConfigurationResponse['deferred_credential_endpoint']
.toString();
}

final (credentialType, types, format) = await getCredentialData(
openidConfigurationResponse: openidConfigurationResponse,
credential: credential,
);

final credentialResponseData = <dynamic>[];

if (authorizationDetails != null) {
final dynamic authDetailForCredential = authorizationDetails!
.where(
(dynamic element) =>
(element['types'] as List).contains(credentialType),
)
.firstOrNull;

if (authDetailForCredential == null) throw Exception();

final identifiers =
(authDetailForCredential['identifiers'] as List<dynamic>)
.map((dynamic element) => element.toString())
.toList();

for (final identifier in identifiers) {
final credentialResponseDataValue = await getSingleCredential(
issuerTokenParameters: issuerTokenParameters,
openidConfigurationResponse: openidConfigurationResponse,
credentialType: credentialType,
types: types,
format: format,
identifier: identifier,
);

credentialResponseData.add(credentialResponseDataValue);
}
//
} else {
final credentialResponseDataValue = await getSingleCredential(
issuerTokenParameters: issuerTokenParameters,
openidConfigurationResponse: openidConfigurationResponse,
credentialType: credentialType,
types: types,
format: format,
);

credentialResponseData.add(credentialResponseDataValue);
}

return (credentialResponseData, deferredCredentialEndpoint, format);
}

Future<dynamic> getSingleCredential({
required IssuerTokenParameters issuerTokenParameters,
required Map<String, dynamic> openidConfigurationResponse,
required String credentialType,
required List<String> types,
required String format,
String? identifier,
}) async {
final credentialData = await buildCredentialData(
nonce: nonce!,
issuerTokenParameters: issuerTokenParameters,
openidConfigurationResponse: openidConfigurationResponse,
credential: credential,
credentialType: credentialType,
types: types,
format: format,
identifier: identifier,
);

/// sign proof
Expand All @@ -300,15 +372,7 @@ class OIDC4VC {

nonce = credentialResponse.data['c_nonce'].toString();

String? deferredCredentialEndpoint;

if (openidConfigurationResponse['deferred_credential_endpoint'] != null) {
deferredCredentialEndpoint =
openidConfigurationResponse['deferred_credential_endpoint']
.toString();
}

return (credentialResponse.data, deferredCredentialEndpoint, format);
return credentialResponse.data;
}

/// get Deferred credential from url
Expand All @@ -326,9 +390,10 @@ class OIDC4VC {
return credentialResponse.data;
}

void resetNonceAndAccessToken() {
void resetNonceAndAccessTokenAndAuthorizationDetails() {
nonce = null;
accessToken = null;
authorizationDetails = null;
}

Map<String, dynamic> buildTokenData({
Expand Down Expand Up @@ -456,26 +521,38 @@ class OIDC4VC {
return private;
}

Future<(Map<String, dynamic>, String)> buildCredentialData({
Future<Map<String, dynamic>> buildCredentialData({
required String nonce,
required IssuerTokenParameters issuerTokenParameters,
required Map<String, dynamic> openidConfigurationResponse,
required dynamic credential,
required String credentialType,
required List<String> types,
required String format,
String? identifier,
}) async {
final vcJwt = await getIssuerJwt(issuerTokenParameters, nonce);

//final issuerDid = readIssuerDid(openidConfigurationResponse);
final credentialData = <String, dynamic>{
'type': credentialType,
'types': types,
'format': format,
'proof': {
'proof_type': 'jwt',
'jwt': vcJwt,
},
};

// final isVerified = await verifyEncodedData(
// issuerDid: issuerDid,
// jwt: vcJwt,
// holderKid: issuerTokenParameters.kid,
// );
if (identifier != null) {
credentialData['identifier'] = identifier;
}

// if (isVerified == VerificationType.notVerified) {
// throw Exception('VERIFICATION_ISSUE');
// }
return credentialData;
}

Future<(String, List<String>, String)> getCredentialData({
required Map<String, dynamic> openidConfigurationResponse,
required dynamic credential,
}) async {
String? credentialType;
List<String>? types;
String? format;
Expand Down Expand Up @@ -510,16 +587,7 @@ class OIDC4VC {
throw Exception();
}

final credentialData = <String, dynamic>{
'type': credentialType,
'types': types,
'format': format,
'proof': {
'proof_type': 'jwt',
'jwt': vcJwt,
},
};
return (credentialData, format);
return (credentialType, types, format);
}

Future<VerificationType> verifyEncodedData({
Expand Down

0 comments on commit 08d3782

Please sign in to comment.