11import {
22 AuthorizationServerMetadata ,
33 AuthorizationServerType ,
4+ CredentialIssuerMetadataV1_0_11 ,
45 CredentialIssuerMetadataV1_0_13 ,
6+ CredentialOfferPayload ,
57 CredentialOfferPayloadV1_0_13 ,
68 CredentialOfferRequestWithBaseUrl ,
9+ determineSpecVersionFromOffer ,
10+ EndpointMetadataResultV1_0_11 ,
711 EndpointMetadataResultV1_0_13 ,
812 getIssuerFromCredentialOfferPayload ,
9- IssuerMetadataV1_0_13 ,
13+ IssuerMetadataV1_0_08 ,
14+ OpenId4VCIVersion ,
1015 OpenIDResponse ,
1116 WellKnownEndpoints ,
1217} from '@sphereon/oid4vci-common' ;
1318import Debug from 'debug' ;
1419
20+ import { MetadataClientV1_0_11 } from './MetadataClientV1_0_11' ;
21+ import { MetadataClientV1_0_13 } from './MetadataClientV1_0_13' ;
1522import { retrieveWellknown } from './functions/OpenIDUtils' ;
1623
1724const debug = Debug ( 'sphereon:oid4vci:metadata' ) ;
@@ -24,18 +31,28 @@ export class MetadataClient {
2431 */
2532 public static async retrieveAllMetadataFromCredentialOffer (
2633 credentialOffer : CredentialOfferRequestWithBaseUrl ,
27- ) : Promise < EndpointMetadataResultV1_0_13 > {
28- return MetadataClient . retrieveAllMetadataFromCredentialOfferRequest ( credentialOffer . credential_offer as CredentialOfferPayloadV1_0_13 ) ;
34+ ) : Promise < EndpointMetadataResultV1_0_13 | EndpointMetadataResultV1_0_11 > {
35+ if ( determineSpecVersionFromOffer ( credentialOffer . credential_offer ) >= OpenId4VCIVersion . VER_1_0_13 ) {
36+ return await MetadataClientV1_0_13 . retrieveAllMetadataFromCredentialOffer ( credentialOffer ) ;
37+ } else {
38+ return await MetadataClientV1_0_11 . retrieveAllMetadataFromCredentialOffer ( credentialOffer ) ;
39+ }
2940 }
3041
3142 /**
3243 * Retrieve the metada using the initiation request obtained from a previous step
3344 * @param request
3445 */
35- public static async retrieveAllMetadataFromCredentialOfferRequest ( request : CredentialOfferPayloadV1_0_13 ) : Promise < EndpointMetadataResultV1_0_13 > {
46+ public static async retrieveAllMetadataFromCredentialOfferRequest (
47+ request : CredentialOfferPayload ,
48+ ) : Promise < EndpointMetadataResultV1_0_13 | EndpointMetadataResultV1_0_11 > {
3649 const issuer = getIssuerFromCredentialOfferPayload ( request ) ;
3750 if ( issuer ) {
38- return MetadataClient . retrieveAllMetadata ( issuer ) ;
51+ if ( determineSpecVersionFromOffer ( request ) >= OpenId4VCIVersion . VER_1_0_13 ) {
52+ return MetadataClientV1_0_13 . retrieveAllMetadataFromCredentialOfferRequest ( request as CredentialOfferPayloadV1_0_13 ) ;
53+ } else {
54+ return MetadataClientV1_0_11 . retrieveAllMetadataFromCredentialOfferRequest ( request ) ;
55+ }
3956 }
4057 throw new Error ( "can't retrieve metadata from CredentialOfferRequest. No issuer field is present" ) ;
4158 }
@@ -45,24 +62,33 @@ export class MetadataClient {
4562 * @param issuer The issuer URL
4663 * @param opts
4764 */
48- public static async retrieveAllMetadata ( issuer : string , opts ?: { errorOnNotFound : boolean } ) : Promise < EndpointMetadataResultV1_0_13 > {
65+ public static async retrieveAllMetadata (
66+ issuer : string ,
67+ opts ?: { errorOnNotFound : boolean } ,
68+ ) : Promise < EndpointMetadataResultV1_0_13 | EndpointMetadataResultV1_0_11 > {
4969 let token_endpoint : string | undefined ;
5070 let credential_endpoint : string | undefined ;
5171 let deferred_credential_endpoint : string | undefined ;
5272 let authorization_endpoint : string | undefined ;
5373 let authorizationServerType : AuthorizationServerType = 'OID4VCI' ;
54- let authorization_servers : string [ ] = [ issuer ] ;
74+ let authorization_servers : string [ ] | undefined = [ issuer ] ;
75+ let authorization_server : string | undefined = undefined ;
5576 const oid4vciResponse = await MetadataClient . retrieveOpenID4VCIServerMetadata ( issuer , { errorOnNotFound : false } ) ; // We will handle errors later, given we will also try other metadata locations
5677 let credentialIssuerMetadata = oid4vciResponse ?. successBody ;
5778 if ( credentialIssuerMetadata ) {
5879 debug ( `Issuer ${ issuer } OID4VCI well-known server metadata\r\n${ JSON . stringify ( credentialIssuerMetadata ) } ` ) ;
5980 credential_endpoint = credentialIssuerMetadata . credential_endpoint ;
60- deferred_credential_endpoint = credentialIssuerMetadata . deferred_credential_endpoint ;
81+ deferred_credential_endpoint = credentialIssuerMetadata . deferred_credential_endpoint
82+ ? ( credentialIssuerMetadata . deferred_credential_endpoint as string )
83+ : undefined ;
6184 if ( credentialIssuerMetadata . token_endpoint ) {
6285 token_endpoint = credentialIssuerMetadata . token_endpoint ;
6386 }
6487 if ( credentialIssuerMetadata . authorization_servers ) {
65- authorization_servers = credentialIssuerMetadata . authorization_servers ;
88+ authorization_servers = credentialIssuerMetadata . authorization_servers as string [ ] ;
89+ } else if ( credentialIssuerMetadata . authorization_server ) {
90+ authorization_server = credentialIssuerMetadata . authorization_server as string ;
91+ authorization_servers = [ authorization_server ] ;
6692 }
6793 }
6894 // No specific OID4VCI endpoint. Either can be an OAuth2 AS or an OIDC IDP. Let's start with OIDC first
@@ -154,20 +180,24 @@ export class MetadataClient {
154180
155181 if ( ! credentialIssuerMetadata && authMetadata ) {
156182 // Apparently everything worked out and the issuer is exposing everything in oAuth2/OIDC well-knowns. Spec is vague about this situation, but we can support it
157- credentialIssuerMetadata = authMetadata as CredentialIssuerMetadataV1_0_13 ;
183+ credentialIssuerMetadata = authorization_server
184+ ? ( authMetadata as CredentialIssuerMetadataV1_0_11 )
185+ : ( authMetadata as CredentialIssuerMetadataV1_0_13 ) ;
158186 }
159187 debug ( `Issuer ${ issuer } token endpoint ${ token_endpoint } , credential endpoint ${ credential_endpoint } ` ) ;
160188 return {
161189 issuer,
162190 token_endpoint,
163191 credential_endpoint,
164192 deferred_credential_endpoint,
165- authorization_server : authorization_servers [ 0 ] ,
193+ ... ( authorization_server ? { authorization_server } : { authorization_servers : authorization_servers } ) ,
166194 authorization_endpoint,
167195 authorizationServerType,
168- credentialIssuerMetadata : credentialIssuerMetadata ,
196+ credentialIssuerMetadata : authorization_server
197+ ? ( credentialIssuerMetadata as IssuerMetadataV1_0_08 & Partial < AuthorizationServerMetadata > )
198+ : ( credentialIssuerMetadata as CredentialIssuerMetadataV1_0_13 ) ,
169199 authorizationServerMetadata : authMetadata ,
170- } ;
200+ } as EndpointMetadataResultV1_0_13 | EndpointMetadataResultV1_0_11 ;
171201 }
172202
173203 /**
@@ -180,7 +210,12 @@ export class MetadataClient {
180210 opts ?: {
181211 errorOnNotFound ?: boolean ;
182212 } ,
183- ) : Promise < OpenIDResponse < IssuerMetadataV1_0_13 > | undefined > {
213+ ) : Promise <
214+ | OpenIDResponse <
215+ CredentialIssuerMetadataV1_0_11 | CredentialIssuerMetadataV1_0_13 | ( IssuerMetadataV1_0_08 & Partial < AuthorizationServerMetadata > )
216+ >
217+ | undefined
218+ > {
184219 return retrieveWellknown ( issuerHost , WellKnownEndpoints . OPENID4VCI_ISSUER , {
185220 errorOnNotFound : opts ?. errorOnNotFound === undefined ? true : opts . errorOnNotFound ,
186221 } ) ;
0 commit comments