UNPKG

@sphereon/oid4vci-common

Version:

OpenID 4 Verifiable Credential Issuance Common Types

135 lines (126 loc) 5.18 kB
import { AuthorizationDetails, CredentialConfigurationSupportedMsoMdocV1_0_13, CredentialOfferPayload, CredentialSupportedMsoMdoc, UniformCredentialOfferPayload, UniformCredentialOfferRequest, VCI_LOG_COMMON, } from '../index'; import { CredentialConfigurationSupported, CredentialConfigurationSupportedSdJwtVcV1_0_13, CredentialDefinitionJwtVcJsonLdAndLdpVcV1_0_13, CredentialDefinitionJwtVcJsonV1_0_13, CredentialOfferFormatV1_0_11, CredentialsSupportedLegacy, CredentialSupportedSdJwtVc, JsonLdIssuerCredentialDefinition, } from '../types'; export function isW3cCredentialSupported( supported: CredentialConfigurationSupported | CredentialsSupportedLegacy, ): supported is Exclude< CredentialConfigurationSupported, | CredentialConfigurationSupportedMsoMdocV1_0_13 | CredentialSupportedMsoMdoc | CredentialConfigurationSupportedSdJwtVcV1_0_13 | CredentialSupportedSdJwtVc > { return ['jwt_vc_json', 'jwt_vc_json-ld', 'ldp_vc', 'jwt_vc'].includes(supported.format); } export const getNumberOrUndefined = (input?: string): number | undefined => { return input && !isNaN(+input) ? +input : undefined; }; /** * The specs had many places where types could be expressed. This method ensures we get them in any way possible * @param subject */ export function getTypesFromObject( subject: | CredentialConfigurationSupported | CredentialOfferFormatV1_0_11 | CredentialDefinitionJwtVcJsonLdAndLdpVcV1_0_13 | CredentialDefinitionJwtVcJsonV1_0_13 | JsonLdIssuerCredentialDefinition | string, ): string[] | undefined { if (subject === undefined) { return undefined; } else if (typeof subject === 'string') { return [subject]; } else if ('credential_definition' in subject) { return getTypesFromObject( subject.credential_definition as | CredentialDefinitionJwtVcJsonLdAndLdpVcV1_0_13 | CredentialDefinitionJwtVcJsonV1_0_13 | JsonLdIssuerCredentialDefinition, ); } else if ('types' in subject && subject.types) { return Array.isArray(subject.types) ? subject.types : [subject.types]; } else if ('type' in subject && subject.type) { return Array.isArray(subject.type) ? subject.type : [subject.type]; } else if ('vct' in subject && subject.vct) { return [subject.vct as string]; } else if ('doctype' in subject && subject.doctype) { return [subject.doctype as string]; } VCI_LOG_COMMON.warning('Could not deduce credential types. Probably a failure down the line will happen!'); return undefined; } export function getTypesFromCredentialOffer( offer: UniformCredentialOfferRequest | CredentialOfferPayload | UniformCredentialOfferPayload, opts?: { configIdAsType?: boolean }, ): Array<Array<string>> | undefined { const { configIdAsType = false } = { ...opts }; if ('credentials' in offer && Array.isArray(offer.credentials)) { return offer.credentials.map((cred) => getTypesFromObject(cred)).filter((cred): cred is string[] => cred !== undefined); } else if (configIdAsType && 'credential_configuration_ids' in offer && Array.isArray(offer.credential_configuration_ids)) { return offer.credential_configuration_ids.map((id) => [id]); } else if ('credential_offer' in offer && offer.credential_offer) { return getTypesFromCredentialOffer(offer.credential_offer, opts); } else if ('credential_type' in offer && offer.credential_type) { if (typeof offer.credential_type === 'string') { return [[offer.credential_type]]; } else if (Array.isArray(offer.credential_type)) { return [offer.credential_type]; } } VCI_LOG_COMMON.warning('Could not deduce credential types from offer. Probably a failure down the line will happen!'); return undefined; } export function getTypesFromAuthorizationDetails(authDetails: AuthorizationDetails, opts?: { configIdAsType?: boolean }): string[] | undefined { const { configIdAsType = false } = { ...opts }; if (typeof authDetails === 'string') { return [authDetails]; } else if ('types' in authDetails && Array.isArray(authDetails.types)) { return authDetails.types; } else if (configIdAsType && authDetails.credential_configuration_id) { return [authDetails.credential_configuration_id]; } return undefined; } export function getTypesFromCredentialSupported( credentialSupported: CredentialConfigurationSupported, opts?: { filterVerifiableCredential: boolean }, ) { let types: string[] = []; if ( credentialSupported.format === 'jwt_vc_json' || credentialSupported.format === 'jwt_vc' || credentialSupported.format === 'jwt_vc_json-ld' || credentialSupported.format === 'ldp_vc' ) { types = getTypesFromObject(credentialSupported) ?? []; } else if (credentialSupported.format === 'vc+sd-jwt') { types = [credentialSupported.vct]; } else if (credentialSupported.format === 'mso_mdoc') { types = [credentialSupported.doctype]; } if (!types || types.length === 0) { throw Error('Could not deduce types from credential supported'); } if (opts?.filterVerifiableCredential) { return types.filter((type) => type !== 'VerifiableCredential'); } return types; }