@@ -220,7 +220,8 @@ export function authorizationChallengeEndpoint(
220220}
221221
222222export function accessTokenEndpoint ( router : Router , issuer : VcIssuer , opts : ITokenEndpointOpts & ISingleEndpointOpts & {
223- baseUrl : string | URL
223+ baseUrl : string | URL ,
224+ authRequestsData ?: Map < string , AuthorizationRequest >
224225} ) {
225226 const externalAS = isExternalAS ( issuer . issuerMetadata ) || issuer . asClientOpts
226227 if ( externalAS || ( opts . accessTokenProvider && opts . accessTokenProvider !== 'internal' ) ) {
@@ -263,12 +264,14 @@ export function accessTokenEndpoint(router: Router, issuer: VcIssuer, opts: ITok
263264
264265 LOG . log ( `[OID4VCI] Token endpoint enabled at ${ url . toString ( ) } ` )
265266
267+
266268 // this.issuer.issuerMetadata.token_endpoint = url.toString()
267269 router . post (
268270 determinePath ( baseUrl , url . pathname , { stripBasePath : true } ) ,
269271 verifyTokenRequest ( {
270272 issuer,
271- preAuthorizedCodeExpirationDuration
273+ preAuthorizedCodeExpirationDuration,
274+ authRequestsData : opts . authRequestsData
272275 } ) ,
273276 handleTokenRequest ( {
274277 issuer,
@@ -313,6 +316,23 @@ export function getCredentialEndpoint(
313316 if ( 'issuer_state' in tokenClaims && typeof tokenClaims . issuer_state === 'string' ) {
314317 issuerCorrelation . issuerState = tokenClaims . issuer_state
315318 }
319+
320+ // Handle credential_identifier from authorization_details flow
321+ if ( 'authorization_details' in tokenClaims && Array . isArray ( tokenClaims . authorization_details ) ) {
322+ issuerCorrelation . authorizationDetails = tokenClaims . authorization_details
323+
324+ if ( credentialRequest . credential_identifier ) {
325+ const validIdentifiers = tokenClaims . authorization_details
326+ . flatMap ( ( detail : any ) => detail . credential_identifiers || [ ] )
327+
328+ if ( ! validIdentifiers . includes ( credentialRequest . credential_identifier ) ) {
329+ return sendErrorResponse ( response , 400 , {
330+ error : 'invalid_credential_request' ,
331+ error_description : 'credential_identifier not found in authorization_details'
332+ } )
333+ }
334+ }
335+ }
316336 } catch ( e ) {
317337 LOG . warning ( e )
318338 return sendErrorResponse ( response , 400 , {
@@ -670,13 +690,51 @@ export function pushedAuthorizationEndpoint(
670690 } )
671691 }
672692
673- //TODO Implement authorization_details verification
693+ // Add the authorization_details validation here:
694+ if ( req . body . authorization_details ) {
695+ const authDetails = Array . isArray ( req . body . authorization_details )
696+ ? req . body . authorization_details
697+ : JSON . parse ( req . body . authorization_details )
698+
699+ // Validate each authorization detail
700+ for ( const detail of authDetails ) {
701+ if ( detail . type !== 'openid_credential' ) {
702+ return sendErrorResponse ( res , 400 , {
703+ error : 'invalid_authorization_details' ,
704+ error_description : 'Only openid_credential type is supported'
705+ } )
706+ }
707+
708+ // Validate credential_configuration_id exists in issuer metadata
709+ if ( detail . credential_configuration_id &&
710+ ! issuer . issuerMetadata . credential_configurations_supported [ detail . credential_configuration_id ] ) {
711+ return sendErrorResponse ( res , 400 , {
712+ error : 'invalid_credential_request' ,
713+ error_description : `Unsupported credential configuration: ${ detail . credential_configuration_id } `
714+ } )
715+ }
716+ }
717+ }
674718
675719 // TODO: Both UUID and requestURI need to be configurable for the server
676720 const uuid = uuidv4 ( )
677721 const requestUri = `urn:ietf:params:oauth:request_uri:${ uuid } `
678- // The redirect_uri is created and set in a map, to keep track of the actual request
679- authRequestsData . set ( requestUri , req . body )
722+
723+ // Store authorization_details in the request for later retrieval
724+ let requestData = req . body
725+ if ( req . body . authorization_details ) {
726+ const authDetails = Array . isArray ( req . body . authorization_details )
727+ ? req . body . authorization_details
728+ : JSON . parse ( req . body . authorization_details )
729+
730+ requestData = {
731+ ...req . body ,
732+ authorization_details : authDetails // Store parsed authorization details
733+ }
734+ }
735+
736+ authRequestsData . set ( requestUri , requestData )
737+
680738 // Invalidates the request_uri removing it from the mapping after it is expired, needs to be refactored because
681739 // some of the properties will be needed in subsequent steps if the authorization succeeds
682740 // TODO in the /token endpoint the code_challenge must be matched against the hashed code_verifier
0 commit comments