UNPKG

@sphereon/ssi-sdk.siopv2-oid4vp-rp-auth

Version:

243 lines • 14 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getRequestVersion = getRequestVersion; exports.getPresentationVerificationCallback = getPresentationVerificationCallback; exports.createRPBuilder = createRPBuilder; exports.signCallback = signCallback; exports.createRP = createRP; exports.getSigningAlgo = getSigningAlgo; const did_auth_siop_1 = require("@sphereon/did-auth-siop"); const oid4vc_common_1 = require("@sphereon/oid4vc-common"); const ssi_sdk_ext_did_utils_1 = require("@sphereon/ssi-sdk-ext.did-utils"); const ssi_sdk_ext_identifier_resolution_1 = require("@sphereon/ssi-sdk-ext.identifier-resolution"); const ssi_types_1 = require("@sphereon/ssi-types"); const events_1 = require("events"); const ssi_sdk_core_1 = require("@sphereon/ssi-sdk.core"); function getRequestVersion(rpOptions) { if (Array.isArray(rpOptions.supportedVersions) && rpOptions.supportedVersions.length > 0) { return rpOptions.supportedVersions[0]; } return did_auth_siop_1.SupportedVersion.JWT_VC_PRESENTATION_PROFILE_v1; } function getWellKnownDIDVerifyCallback(siopIdentifierOpts, context) { return siopIdentifierOpts.wellknownDIDVerifyCallback ? siopIdentifierOpts.wellknownDIDVerifyCallback : (args) => __awaiter(this, void 0, void 0, function* () { const result = yield context.agent.cvVerifyCredential({ credential: args.credential, fetchRemoteContexts: true, }); return { verified: result.result }; }); } function getPresentationVerificationCallback(idOpts, context) { function presentationVerificationCallback(args, // FIXME any presentationSubmission) { return __awaiter(this, void 0, void 0, function* () { var _a; if (ssi_types_1.CredentialMapper.isSdJwtEncoded(args)) { const result = yield context.agent.verifySdJwtPresentation({ presentation: args, kb: true, }); // fixme: investigate the correct way to handle this return { verified: !!result.payload }; } if (ssi_types_1.CredentialMapper.isMsoMdocOid4VPEncoded(args)) { // TODO Funke reevaluate if (context.agent.mdocOid4vpRPVerify === undefined) { return Promise.reject('ImDLMdoc agent plugin must be enabled to support MsoMdoc types'); } if (presentationSubmission !== undefined && presentationSubmission !== null) { const verifyResult = yield context.agent.mdocOid4vpRPVerify({ vp_token: args, presentation_submission: presentationSubmission, }); return { verified: !verifyResult.error }; } throw Error(`mdocOid4vpRPVerify(...) method requires a presentation submission`); } const result = yield context.agent.verifyPresentation({ presentation: args, fetchRemoteContexts: true, domain: (_a = (yield context.agent.identifierManagedGet(idOpts)).kid) === null || _a === void 0 ? void 0 : _a.split('#')[0], }); return { verified: result.verified }; }); } return presentationVerificationCallback; } function createRPBuilder(args) { return __awaiter(this, void 0, void 0, function* () { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p; const { rpOpts, pexOpts, context } = args; const { identifierOpts } = rpOpts; let definition = args.definition; let dcqlQuery = args.dcql; if (!definition && pexOpts && pexOpts.definitionId) { const presentationDefinitionItems = yield context.agent.pdmGetDefinitions({ filter: [ { definitionId: pexOpts.definitionId, version: pexOpts.version, tenantId: pexOpts.tenantId, }, ], }); if (presentationDefinitionItems.length > 0) { const presentationDefinitionItem = presentationDefinitionItems[0]; definition = presentationDefinitionItem.definitionPayload; if (!dcqlQuery && presentationDefinitionItem.dcqlPayload) { dcqlQuery = presentationDefinitionItem.dcqlPayload; // cast from DcqlQueryREST back to valibot DcqlQuery } } } const didMethods = (_a = identifierOpts.supportedDIDMethods) !== null && _a !== void 0 ? _a : (yield (0, ssi_sdk_ext_did_utils_1.getAgentDIDMethods)(context)); const eventEmitter = (_b = rpOpts.eventEmitter) !== null && _b !== void 0 ? _b : new events_1.EventEmitter(); const defaultClientMetadata = { // FIXME: All of the below should be configurable. Some should come from builder, some should be determined by the agent. // For now it is either preconfigured or everything passed in as a single object idTokenSigningAlgValuesSupported: [oid4vc_common_1.SigningAlgo.EDDSA, oid4vc_common_1.SigningAlgo.ES256, oid4vc_common_1.SigningAlgo.ES256K], // added newly requestObjectSigningAlgValuesSupported: [oid4vc_common_1.SigningAlgo.EDDSA, oid4vc_common_1.SigningAlgo.ES256, oid4vc_common_1.SigningAlgo.ES256K], // added newly responseTypesSupported: [did_auth_siop_1.ResponseType.ID_TOKEN], // added newly client_name: 'Sphereon', vpFormatsSupported: { jwt_vc: { alg: ['EdDSA', 'ES256K'] }, jwt_vp: { alg: ['ES256K', 'EdDSA'] }, }, scopesSupported: [did_auth_siop_1.Scope.OPENID_DIDAUTHN], subjectTypesSupported: [did_auth_siop_1.SubjectType.PAIRWISE], subject_syntax_types_supported: didMethods.map((method) => `did:${method}`), passBy: did_auth_siop_1.PassBy.VALUE, }; const resolver = (_d = (_c = rpOpts.identifierOpts.resolveOpts) === null || _c === void 0 ? void 0 : _c.resolver) !== null && _d !== void 0 ? _d : (0, ssi_sdk_ext_did_utils_1.getAgentResolver)(context, { resolverResolution: true, localResolution: true, uniresolverResolution: ((_e = rpOpts.identifierOpts.resolveOpts) === null || _e === void 0 ? void 0 : _e.noUniversalResolverFallback) !== true, }); //todo: probably wise to first look and see if we actually need the hasher to begin with let hasher = (_f = rpOpts.credentialOpts) === null || _f === void 0 ? void 0 : _f.hasher; if (!((_g = rpOpts.credentialOpts) === null || _g === void 0 ? void 0 : _g.hasher) || typeof ((_h = rpOpts.credentialOpts) === null || _h === void 0 ? void 0 : _h.hasher) !== 'function') { hasher = ssi_sdk_core_1.defaultHasher; } const builder = did_auth_siop_1.RP.builder({ requestVersion: getRequestVersion(rpOpts) }) .withScope('openid', did_auth_siop_1.PropertyTarget.REQUEST_OBJECT) .withResponseMode((_j = rpOpts.responseMode) !== null && _j !== void 0 ? _j : did_auth_siop_1.ResponseMode.POST) .withResponseType(did_auth_siop_1.ResponseType.VP_TOKEN, did_auth_siop_1.PropertyTarget.REQUEST_OBJECT) // todo: move to options fill/correct method .withSupportedVersions((_k = rpOpts.supportedVersions) !== null && _k !== void 0 ? _k : [did_auth_siop_1.SupportedVersion.JWT_VC_PRESENTATION_PROFILE_v1, did_auth_siop_1.SupportedVersion.SIOPv2_ID1, did_auth_siop_1.SupportedVersion.SIOPv2_D11]) .withEventEmitter(eventEmitter) .withSessionManager((_l = rpOpts.sessionManager) !== null && _l !== void 0 ? _l : new did_auth_siop_1.InMemoryRPSessionManager(eventEmitter)) .withClientMetadata((_m = rpOpts.clientMetadataOpts) !== null && _m !== void 0 ? _m : defaultClientMetadata, did_auth_siop_1.PropertyTarget.REQUEST_OBJECT) .withVerifyJwtCallback(rpOpts.verifyJwtCallback ? rpOpts.verifyJwtCallback : getVerifyJwtCallback({ resolver, verifyOpts: { wellknownDIDVerifyCallback: getWellKnownDIDVerifyCallback(rpOpts.identifierOpts, context), checkLinkedDomain: 'if_present', }, }, context)) .withRevocationVerification(did_auth_siop_1.RevocationVerification.NEVER) .withPresentationVerification(getPresentationVerificationCallback(identifierOpts.idOpts, context)); const oidfOpts = identifierOpts.oidfOpts; if (oidfOpts && (0, ssi_sdk_ext_identifier_resolution_1.isExternalIdentifierOIDFEntityIdOpts)(oidfOpts)) { builder.withEntityId(oidfOpts.identifier, did_auth_siop_1.PropertyTarget.REQUEST_OBJECT).withClientIdScheme('entity_id', did_auth_siop_1.PropertyTarget.REQUEST_OBJECT); } else { const resolution = yield context.agent.identifierManagedGet(identifierOpts.idOpts); builder .withClientId((_o = resolution.issuer) !== null && _o !== void 0 ? _o : ((0, ssi_sdk_ext_identifier_resolution_1.isManagedIdentifierDidResult)(resolution) ? resolution.did : resolution.jwkThumbprint), did_auth_siop_1.PropertyTarget.REQUEST_OBJECT) .withClientIdScheme((_p = resolution.clientIdScheme) !== null && _p !== void 0 ? _p : identifierOpts.idOpts.clientIdScheme, did_auth_siop_1.PropertyTarget.REQUEST_OBJECT); } if (hasher) { builder.withHasher(hasher); } //fixme: this has been removed in the new version of did-auth-siop /*if (!rpOpts.clientMetadataOpts?.subjectTypesSupported) { // Do not update in case it is already provided via client metadata opts didMethods.forEach((method) => builder.addDidMethod(method)) }*/ //fixme: this has been removed in the new version of did-auth-siop // builder.withWellknownDIDVerifyCallback(getWellKnownDIDVerifyCallback(didOpts, context)) if (definition) { builder.withPresentationDefinition({ definition }, did_auth_siop_1.PropertyTarget.REQUEST_OBJECT); } if (dcqlQuery) { builder.withDcqlQuery(dcqlQuery); } if (rpOpts.responseRedirectUri) { builder.withResponseRedirectUri(rpOpts.responseRedirectUri); } //const key = resolution.key //fixme: this has been removed in the new version of did-auth-siop //builder.withSuppliedSignature(SuppliedSigner(key, context, getSigningAlgo(key.type) as unknown as KeyAlgo), did, kid, getSigningAlgo(key.type)) /*if (isManagedIdentifierDidResult(resolution)) { //fixme: only accepts dids in version used. New SIOP lib also accepts other types builder.withSuppliedSignature( SuppliedSigner(key, context, getSigningAlgo(key.type) as unknown as KeyAlgo), resolution.did, resolution.kid, getSigningAlgo(key.type), ) }*/ //fixme: signcallback and it's return type are not totally compatible with our CreateJwtCallbackBase const createJwtCallback = signCallback(rpOpts.identifierOpts.idOpts, context); builder.withCreateJwtCallback(createJwtCallback); return builder; }); } function signCallback(idOpts, context) { return (jwtIssuer, jwt, kid) => __awaiter(this, void 0, void 0, function* () { if (!((0, ssi_sdk_ext_identifier_resolution_1.isManagedIdentifierDidOpts)(idOpts) || (0, ssi_sdk_ext_identifier_resolution_1.isManagedIdentifierX5cOpts)(idOpts))) { return Promise.reject(Error(`JWT issuer method ${jwtIssuer.method} not yet supported`)); } const result = yield context.agent.jwtCreateJwsCompactSignature({ // FIXME fix cose-key inference // @ts-ignore issuer: { identifier: idOpts.identifier, kmsKeyRef: idOpts.kmsKeyRef, noIdentifierInHeader: false }, // FIXME fix JWK key_ops // @ts-ignore protectedHeader: jwt.header, payload: jwt.payload, }); return result.jwt; }); } function getVerifyJwtCallback(_opts, context) { return (_jwtVerifier, jwt) => __awaiter(this, void 0, void 0, function* () { const result = yield context.agent.jwtVerifyJwsSignature({ jws: jwt.raw }); console.log(result.message); return !result.error; }); } function createRP(_a) { return __awaiter(this, arguments, void 0, function* ({ rpOptions, context }) { return (yield createRPBuilder({ rpOpts: rpOptions, context })).build(); }); } function getSigningAlgo(type) { switch (type) { case 'Ed25519': return oid4vc_common_1.SigningAlgo.EDDSA; case 'Secp256k1': return oid4vc_common_1.SigningAlgo.ES256K; case 'Secp256r1': return oid4vc_common_1.SigningAlgo.ES256; // @ts-ignore case 'RSA': return oid4vc_common_1.SigningAlgo.RS256; default: throw Error('Key type not yet supported'); } } //# sourceMappingURL=functions.js.map