diff --git a/packages/oid4vci/src/credential-offer/v-credential-offer.ts b/packages/oid4vci/src/credential-offer/v-credential-offer.ts index 0bfcb4c..879ac09 100644 --- a/packages/oid4vci/src/credential-offer/v-credential-offer.ts +++ b/packages/oid4vci/src/credential-offer/v-credential-offer.ts @@ -4,9 +4,11 @@ import { vCredentialIssuerIdentifier } from '../metadata/credential-issuer/v-cre export const vPreAuthorizedCodeGrantIdentifier = v.literal('urn:ietf:params:oauth:grant-type:pre-authorized_code') export const preAuthorizedCodeGrantIdentifier = vPreAuthorizedCodeGrantIdentifier.literal +export type PreAuthorizedCodeGrantIdentifier = v.InferOutput export const vAuthorizationCodeGrantIdentifier = v.literal('authorization_code') export const authorizationCodeGrantIdentifier = vAuthorizationCodeGrantIdentifier.literal +export type AuthorizationCodeGrantIdentifier = v.InferOutput export const vCredentialOfferGrants = v.looseObject({ authorization_code: v.optional( diff --git a/packages/oid4vci/src/index.ts b/packages/oid4vci/src/index.ts index cee0b75..8f9451f 100644 --- a/packages/oid4vci/src/index.ts +++ b/packages/oid4vci/src/index.ts @@ -24,7 +24,11 @@ export { } from './metadata/credential-issuer/credential-configurations' export type { AuthorizationServerMetadata } from './metadata/authorization-server/v-authorization-server-metadata' -export { getAuthorizationServerMetadataFromList } from './metadata/authorization-server/authorization-server-metadata' +export { + getAuthorizationServerMetadataFromList, + determineAuthorizationServerForOffer, + type DetermineAuthorizationForOfferOptions, +} from './metadata/authorization-server/authorization-server-metadata' export { AccessTokenErrorResponse, @@ -32,9 +36,11 @@ export { } from './authorization/access-token/v-access-token' export { - type CredentialOfferObject, authorizationCodeGrantIdentifier, preAuthorizedCodeGrantIdentifier, + type CredentialOfferObject, + type PreAuthorizedCodeGrantIdentifier, + type AuthorizationCodeGrantIdentifier, } from './credential-offer/v-credential-offer' export type { diff --git a/packages/oid4vci/src/metadata/authorization-server/authorization-server-metadata.ts b/packages/oid4vci/src/metadata/authorization-server/authorization-server-metadata.ts index f1b1e66..cf14cc5 100644 --- a/packages/oid4vci/src/metadata/authorization-server/authorization-server-metadata.ts +++ b/packages/oid4vci/src/metadata/authorization-server/authorization-server-metadata.ts @@ -1,6 +1,12 @@ +import type { + AuthorizationCodeGrantIdentifier, + CredentialOfferObject, + PreAuthorizedCodeGrantIdentifier, +} from '../../credential-offer/v-credential-offer' import { Oid4vcError } from '../../error/Oid4vcError' import type { Fetch } from '../../globals' import { joinUriParts } from '../../utils/path' +import type { IssuerMetadataResult } from '../fetch-issuer-metadata' import { fetchWellKnownMetadata } from '../fetch-metadata' import { type AuthorizationServerMetadata, vAuthorizationServerMetadata } from './v-authorization-server-metadata' @@ -71,3 +77,27 @@ export function getAuthorizationServerMetadataFromList( return authorizationServerMetadata } + +export interface DetermineAuthorizationForOfferOptions { + grantType: PreAuthorizedCodeGrantIdentifier | AuthorizationCodeGrantIdentifier + credentialOffer: CredentialOfferObject + issuerMetadata: IssuerMetadataResult +} + +export function determineAuthorizationServerForOffer(options: DetermineAuthorizationForOfferOptions) { + // Try infer authorization server based on credential offer + const authorizationServer = options.credentialOffer.grants?.[options.grantType]?.authorization_server + if (authorizationServer) { + return getAuthorizationServerMetadataFromList(options.issuerMetadata.authorizationServers, authorizationServer) + } + + // Otherwise if there's only one we can use that + if (options.issuerMetadata.authorizationServers.length === 1) { + return options.issuerMetadata.authorizationServers[0] + } + + // We can't safely determine the authorization server + throw new Oid4vcError( + `Unable to determine authorization server. Multiple authorization servers available and credential offer does not specify which 'authorization_server' to use for the '${options.grantType}' grant type.` + ) +}