@@ -2,6 +2,7 @@ import { createDPoP, CreateDPoPClientOpts, getCreateDPoPOptions } from '@sphereo
22import {
33 acquireDeferredCredential ,
44 CredentialResponse ,
5+ DPoPResponseParams ,
56 getCredentialRequestForVersion ,
67 getUniformFormat ,
78 isDeferredCredentialResponse ,
@@ -21,6 +22,7 @@ import Debug from 'debug';
2122import { buildProof } from './CredentialRequestClient' ;
2223import { CredentialRequestClientBuilderV1_0_11 } from './CredentialRequestClientBuilderV1_0_11' ;
2324import { ProofOfPossessionBuilder } from './ProofOfPossessionBuilder' ;
25+ import { dPoPShouldRetryResourceRequestWithNonce } from './functions/dpopUtil' ;
2426
2527const debug = Debug ( 'sphereon:oid4vci:credential' ) ;
2628
@@ -66,7 +68,7 @@ export class CredentialRequestClientV1_0_11 {
6668 context ?: string [ ] ;
6769 format ?: CredentialFormat | OID4VCICredentialFormat ;
6870 createDPoPOpts ?: CreateDPoPClientOpts ;
69- } ) : Promise < OpenIDResponse < CredentialResponse > & { access_token : string } > {
71+ } ) : Promise < OpenIDResponse < CredentialResponse , DPoPResponseParams > & { access_token : string } > {
7072 const { credentialTypes, proofInput, format, context } = opts ;
7173
7274 const request = await this . createCredentialRequest ( { proofInput, credentialTypes, context, format, version : this . version ( ) } ) ;
@@ -76,7 +78,7 @@ export class CredentialRequestClientV1_0_11 {
7678 public async acquireCredentialsUsingRequest (
7779 uniformRequest : UniformCredentialRequest ,
7880 createDPoPOpts ?: CreateDPoPClientOpts ,
79- ) : Promise < OpenIDResponse < CredentialResponse > & { access_token : string } > {
81+ ) : Promise < OpenIDResponse < CredentialResponse , DPoPResponseParams > & { access_token : string } > {
8082 const request = getCredentialRequestForVersion ( uniformRequest , this . version ( ) ) ;
8183 const credentialEndpoint : string = this . credentialRequestOpts . credentialEndpoint ;
8284 if ( ! isValidURL ( credentialEndpoint ) ) {
@@ -87,25 +89,44 @@ export class CredentialRequestClientV1_0_11 {
8789 debug ( `request\n: ${ JSON . stringify ( request , null , 2 ) } ` ) ;
8890 const requestToken : string = this . credentialRequestOpts . token ;
8991
90- let dPoP : string | undefined ;
91- if ( createDPoPOpts ) {
92- dPoP = createDPoPOpts ? await createDPoP ( getCreateDPoPOptions ( createDPoPOpts , credentialEndpoint , { accessToken : requestToken } ) ) : undefined ;
93- }
92+ let dPoP = createDPoPOpts ? await createDPoP ( getCreateDPoPOptions ( createDPoPOpts , credentialEndpoint , { accessToken : requestToken } ) ) : undefined ;
9493
9594 let response = ( await post ( credentialEndpoint , JSON . stringify ( request ) , {
9695 bearerToken : requestToken ,
9796 customHeaders : { ...( createDPoPOpts && { dpop : dPoP } ) } ,
9897 } ) ) as OpenIDResponse < CredentialResponse > & {
9998 access_token : string ;
10099 } ;
100+
101+ let nextDPoPNonce = createDPoPOpts ?. jwtPayloadProps . nonce ;
102+ const retryWithNonce = dPoPShouldRetryResourceRequestWithNonce ( response ) ;
103+ if ( retryWithNonce . ok && createDPoPOpts ) {
104+ createDPoPOpts . jwtPayloadProps . nonce = retryWithNonce . dpopNonce ;
105+ dPoP = await createDPoP ( getCreateDPoPOptions ( createDPoPOpts , credentialEndpoint , { accessToken : requestToken } ) ) ;
106+
107+ response = ( await post ( credentialEndpoint , JSON . stringify ( request ) , {
108+ bearerToken : requestToken ,
109+ customHeaders : { ...( createDPoPOpts && { dPoP } ) } ,
110+ } ) ) as OpenIDResponse < CredentialResponse > & {
111+ access_token : string ;
112+ } ;
113+
114+ const successDPoPNonce = response . origResponse . headers . get ( 'DPoP-Nonce' ) ;
115+ nextDPoPNonce = successDPoPNonce ?? retryWithNonce . dpopNonce ;
116+ }
117+
101118 this . _isDeferred = isDeferredCredentialResponse ( response ) ;
102119 if ( this . isDeferred ( ) && this . credentialRequestOpts . deferredCredentialAwait && response . successBody ) {
103120 response = await this . acquireDeferredCredential ( response . successBody , { bearerToken : this . credentialRequestOpts . token } ) ;
104121 }
105122 response . access_token = requestToken ;
106123
107124 debug ( `Credential endpoint ${ credentialEndpoint } response:\r\n${ JSON . stringify ( response , null , 2 ) } ` ) ;
108- return response ;
125+
126+ return {
127+ ...response ,
128+ params : { ...( nextDPoPNonce && { dpop : { dpopNonce : nextDPoPNonce } } ) } ,
129+ } ;
109130 }
110131
111132 public async acquireDeferredCredential (
0 commit comments