From 7127167b0d1f1e70d9786d7b1713687a2cf74513 Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Wed, 26 Jun 2024 14:42:23 +0545 Subject: [PATCH] feat: Re-request credential if error gives c_nonce #2734 --- packages/oidc4vc/lib/src/oidc4vc.dart | 109 ++++++++++++++++++-------- 1 file changed, 77 insertions(+), 32 deletions(-) diff --git a/packages/oidc4vc/lib/src/oidc4vc.dart b/packages/oidc4vc/lib/src/oidc4vc.dart index 486035582..1ca37b74c 100644 --- a/packages/oidc4vc/lib/src/oidc4vc.dart +++ b/packages/oidc4vc/lib/src/oidc4vc.dart @@ -623,6 +623,8 @@ class OIDC4VC { return (tokenResponse, accessToken, cnonce, authorizationDetails); } + int count = 0; + Future getSingleCredential({ required IssuerTokenParameters issuerTokenParameters, required OpenIdConfiguration openIdConfiguration, @@ -644,44 +646,87 @@ class OIDC4VC { required String? nonce, required Dio dio, }) async { - final credentialData = await buildCredentialData( - nonce: nonce, - issuerTokenParameters: issuerTokenParameters, - openIdConfiguration: openIdConfiguration, - credentialType: credentialType, - types: types, - format: format, - credentialIdentifier: credentialIdentifier, - cryptoHolderBinding: cryptoHolderBinding, - oidc4vciDraftType: oidc4vciDraftType, - credentialDefinition: credentialDefinition, - clientAuthentication: clientAuthentication, - vct: vct, - proofType: proofType, - did: did, - issuer: issuer, - kid: kid, - privateKey: privateKey, - ); + try { + final credentialData = await buildCredentialData( + nonce: nonce, + issuerTokenParameters: issuerTokenParameters, + openIdConfiguration: openIdConfiguration, + credentialType: credentialType, + types: types, + format: format, + credentialIdentifier: credentialIdentifier, + cryptoHolderBinding: cryptoHolderBinding, + oidc4vciDraftType: oidc4vciDraftType, + credentialDefinition: credentialDefinition, + clientAuthentication: clientAuthentication, + vct: vct, + proofType: proofType, + did: did, + issuer: issuer, + kid: kid, + privateKey: privateKey, + ); - /// sign proof + /// sign proof - final credentialEndpoint = readCredentialEndpoint(openIdConfiguration); + final credentialEndpoint = readCredentialEndpoint(openIdConfiguration); - final credentialHeaders = { - 'Content-Type': 'application/json', - 'Authorization': 'Bearer $accessToken', - }; + final credentialHeaders = { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer $accessToken', + }; - final dynamic credentialResponse = await dio.post( - credentialEndpoint, - options: Options(headers: credentialHeaders), - data: credentialData, - ); + final dynamic credentialResponse = await dio.post( + credentialEndpoint, + options: Options(headers: credentialHeaders), + data: credentialData, + ); - final credentialResponseData = credentialResponse.data; + final credentialResponseData = credentialResponse.data; - return credentialResponseData; + return credentialResponseData; + } catch (e) { + if (count == 1) { + count = 0; + rethrow; + } + + if (e is DioException && + e.response != null && + e.response!.data is Map && + (e.response!.data as Map).containsKey('c_nonce')) { + count++; + + final nonce = e.response!.data['c_nonce'].toString(); + + final credentialResponseDataValue = await getSingleCredential( + issuerTokenParameters: issuerTokenParameters, + openIdConfiguration: openIdConfiguration, + credentialType: credentialType, + types: types, + format: format, + cryptoHolderBinding: cryptoHolderBinding, + oidc4vciDraftType: oidc4vciDraftType, + credentialDefinition: credentialDefinition, + clientAuthentication: clientAuthentication, + vct: vct, + credentialIdentifier: null, + proofType: proofType, + did: did, + issuer: issuer, + kid: kid, + privateKey: privateKey, + accessToken: accessToken, + nonce: nonce, + dio: dio, + ); + count = 0; + return credentialResponseDataValue; + } else { + count = 0; + rethrow; + } + } } /// get Deferred credential from url