UNPKG

@sphereon/ssi-sdk.presentation-exchange

Version:

148 lines • 9.9 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.createPEXPresentationSignCallback = createPEXPresentationSignCallback; const ssi_sdk_ext_identifier_resolution_1 = require("@sphereon/ssi-sdk-ext.identifier-resolution"); const ssi_types_1 = require("@sphereon/ssi-types"); function createPEXPresentationSignCallback(args, context) { return __awaiter(this, void 0, void 0, function* () { function determineProofFormat(determineArgs) { var _a; const { format, presentationDefinition, presentation } = determineArgs; var formatOptions = (_a = format !== null && format !== void 0 ? format : presentationDefinition.format) !== null && _a !== void 0 ? _a : args.format; // TODO Refactor so it takes into account the Input Descriptors and we can lookup from there. Now we only do that if there is 1 descriptor if (!formatOptions && presentationDefinition.input_descriptors.length == 1 && 'format' in presentationDefinition.input_descriptors[0]) { formatOptions = presentationDefinition.input_descriptors[0].format; } // All format arguments are optional. So if no format has been given we go for the most supported 'jwt' if (!formatOptions) { if (ssi_types_1.CredentialMapper.isSdJwtDecodedCredentialPayload(presentation.decodedPayload)) { return 'vc+sd-jwt'; } else if (ssi_types_1.CredentialMapper.isMsoMdocDecodedPresentation(presentation.decodedPayload)) { return 'mso_mdoc'; } else if (ssi_types_1.CredentialMapper.isW3cPresentation(presentation.decodedPayload)) { if (typeof presentation.signedPayload === 'string') { return 'jwt'; } return 'lds'; } return 'jwt'; } else if (typeof formatOptions === 'string') { // if formatOptions is a singular string we can return that as the format return formatOptions; } // here we transform all format options to either lds or jwt. but we also want to support sd-jwt, so we need to specifically check for this one. which is ['vc+sd-jwt'] const formats = new Set(Object.keys(formatOptions).map((form) => (form.includes('ldp') ? 'lds' : form.includes('vc+sd-jwt') ? 'vc+sd-jwt' : 'jwt'))); // if we only have 1 format type we can return that if (formats.size === 1) { return formats.values().next().value; } formats.keys().next(); // if we can go for sd-jwt, we go for sd-jwt if (formats.has('vc+sd-jwt')) { return 'vc+sd-jwt'; } // if it is not sd-jwt we would like to go for jwt else if (formats.has('jwt')) { return 'jwt'; } // else we go for lds return 'lds'; } return (_a) => __awaiter(this, [_a], void 0, function* ({ presentation, domain, presentationDefinition, format, challenge, }) { var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o; const proofFormat = determineProofFormat({ format, presentationDefinition, presentation }); const { idOpts } = args; const CLOCK_SKEW = 120; if (args.skipDidResolution && (0, ssi_sdk_ext_identifier_resolution_1.isManagedIdentifierDidOpts)(idOpts)) { idOpts.offlineWhenNoDIDRegistered = true; } if ('compactSdJwtVc' in presentation) { if (proofFormat !== 'vc+sd-jwt') { return Promise.reject(Error(`presentation payload does not match proof format ${proofFormat}`)); } const presentationResult = yield context.agent.createSdJwtPresentation(Object.assign(Object.assign({}, ((idOpts === null || idOpts === void 0 ? void 0 : idOpts.method) === 'oid4vci-issuer' && { holder: idOpts === null || idOpts === void 0 ? void 0 : idOpts.issuer })), { presentation: presentation.compactSdJwtVc, kb: { payload: Object.assign(Object.assign({}, (_b = presentation.kbJwt) === null || _b === void 0 ? void 0 : _b.payload), { iat: (_e = (_d = (_c = presentation.kbJwt) === null || _c === void 0 ? void 0 : _c.payload) === null || _d === void 0 ? void 0 : _d.iat) !== null && _e !== void 0 ? _e : Math.floor(Date.now() / 1000 - CLOCK_SKEW), nonce: challenge !== null && challenge !== void 0 ? challenge : (_g = (_f = presentation.kbJwt) === null || _f === void 0 ? void 0 : _f.payload) === null || _g === void 0 ? void 0 : _g.nonce, aud: (_l = (_k = (_j = (_h = presentation.kbJwt) === null || _h === void 0 ? void 0 : _h.payload) === null || _j === void 0 ? void 0 : _j.aud) !== null && _k !== void 0 ? _k : domain) !== null && _l !== void 0 ? _l : args.domain }), } })); return ssi_types_1.CredentialMapper.storedPresentationToOriginalFormat(presentationResult.presentation); } else { const resolution = yield context.agent.identifierManagedGet(idOpts); if (proofFormat === 'vc+sd-jwt') { return Promise.reject(Error(`presentation payload does not match proof format ${proofFormat}`)); } let header; if (!presentation.holder) { presentation.holder = resolution.issuer; } if (proofFormat === 'jwt') { header = Object.assign(Object.assign({}, (((0, ssi_sdk_ext_identifier_resolution_1.isManagedIdentifierDidResult)(resolution) || (0, ssi_sdk_ext_identifier_resolution_1.isManagedIdentifierX5cResult)(resolution)) && resolution.kid && { kid: resolution.kid })), ((0, ssi_sdk_ext_identifier_resolution_1.isManagedIdentifierX5cResult)(resolution) && { jwk: resolution.jwk })); if (presentation.verifier || !presentation.aud) { presentation.aud = Array.isArray(presentation.verifier) ? presentation.verifier : ((_o = (_m = presentation.verifier) !== null && _m !== void 0 ? _m : domain) !== null && _o !== void 0 ? _o : args.domain); delete presentation.verifier; } if (!presentation.nbf) { if (presentation.issuanceDate) { const converted = Date.parse(presentation.issuanceDate); if (!isNaN(converted)) { presentation.nbf = Math.floor(converted / 1000); // no skew here, as an explicit value was given } } else { presentation.nbf = Math.floor(Date.now() / 1000 - CLOCK_SKEW); } } if (!presentation.iat) { presentation.iat = presentation.nbf; } if (!presentation.exp) { if (presentation.expirationDate) { const converted = Date.parse(presentation.expirationDate); if (!isNaN(converted)) { presentation.exp = Math.floor(converted / 1000); // no skew here as an explicit value w as given } } else { presentation.exp = presentation.nbf + 600 + CLOCK_SKEW; } } if (!presentation.vp) { presentation.vp = {}; } /*if (!presentation.sub) { presentation.sub = id.did }*/ if (!presentation.vp.holder) { presentation.vp.holder = presentation.holder; } } // we ignore the alg / proof_format for now, as we already have the kid anyway at this point // todo: look for jwt_vc_json and remove types and @context const vp = yield context.agent.createVerifiablePresentation({ presentation: presentation, removeOriginalFields: false, keyRef: resolution.kmsKeyRef, // domain: domain ?? args.domain, // handled above, and did-jwt-vc creates an array even for 1 entry challenge: challenge !== null && challenge !== void 0 ? challenge : args.challenge, fetchRemoteContexts: args.fetchRemoteContexts !== false, proofFormat: proofFormat, header, }); // makes sure we extract an actual JWT from the internal representation in case it is a JWT return ssi_types_1.CredentialMapper.storedPresentationToOriginalFormat(vp); } }); }); } //# sourceMappingURL=functions.js.map