UNPKG

@sphereon/oid4vci-issuer

Version:

OpenID 4 Verifiable Credential Issuance issuer REST endpoints

167 lines • 10.1 kB
"use strict"; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.assertValidPinNumber = exports.isPreAuthorizedCodeExpired = exports.createCredentialOfferURIv1_0_11 = exports.createCredentialOfferURI = exports.createCredentialOfferURIFromObject = exports.createCredentialOfferObjectv1_0_11 = exports.createCredentialOfferObject = void 0; const oid4vc_common_1 = require("@sphereon/oid4vc-common"); const oid4vci_common_1 = require("@sphereon/oid4vci-common"); function createCredentialOfferGrants(inputGrants) { var _a, _b; // Grants is optional if (!inputGrants || Object.keys(inputGrants).length === 0) { return undefined; } const grants = {}; if (inputGrants === null || inputGrants === void 0 ? void 0 : inputGrants[oid4vci_common_1.PRE_AUTH_GRANT_LITERAL]) { const grant = Object.assign(Object.assign({}, inputGrants[oid4vci_common_1.PRE_AUTH_GRANT_LITERAL]), { 'pre-authorized_code': (_a = inputGrants[oid4vci_common_1.PRE_AUTH_GRANT_LITERAL]['pre-authorized_code']) !== null && _a !== void 0 ? _a : (0, oid4vc_common_1.uuidv4)() }); if (grant.tx_code && !grant.tx_code.length) { grant.tx_code.length = 4; } grants[oid4vci_common_1.PRE_AUTH_GRANT_LITERAL] = grant; } if (inputGrants === null || inputGrants === void 0 ? void 0 : inputGrants.authorization_code) { grants.authorization_code = Object.assign(Object.assign({}, inputGrants.authorization_code), { // TODO: it should be possible to create offer without issuer_state // this is added to avoid breaking changes. issuer_state: (_b = inputGrants.authorization_code.issuer_state) !== null && _b !== void 0 ? _b : (0, oid4vc_common_1.uuidv4)() }); } return grants; } function parseCredentialOfferSchemeAndBaseUri(scheme, baseUri, credentialIssuer) { var _a; const newScheme = (_a = scheme === null || scheme === void 0 ? void 0 : scheme.replace('://', '')) !== null && _a !== void 0 ? _a : ((baseUri === null || baseUri === void 0 ? void 0 : baseUri.includes('://')) ? baseUri.split('://')[0] : 'openid-credential-offer'); let newBaseUri; if (baseUri) { newBaseUri = baseUri; } else if (newScheme.startsWith('http')) { if (credentialIssuer) { newBaseUri = credentialIssuer; if (!newBaseUri.startsWith(`${newScheme}://`)) { throw Error(`scheme ${newScheme} is different from base uri ${newBaseUri}`); } } else { throw Error(`A '${newScheme}' scheme requires a URI to be present as baseUri`); } } else { newBaseUri = ''; } newBaseUri = newBaseUri === null || newBaseUri === void 0 ? void 0 : newBaseUri.replace(`${newScheme}://`, ''); return { scheme: newScheme, baseUri: newBaseUri }; } function createCredentialOfferObject(issuerMetadata, // todo: probably it's wise to create another builder for CredentialOfferPayload that will generate different kinds of CredentialOfferPayload opts) { if (!issuerMetadata && !(opts === null || opts === void 0 ? void 0 : opts.credentialOffer) && !(opts === null || opts === void 0 ? void 0 : opts.credentialOfferUri)) { throw new Error('You have to provide issuerMetadata or credentialOffer object for creating a deeplink'); } const grants = createCredentialOfferGrants(opts === null || opts === void 0 ? void 0 : opts.grants); let credential_offer; if (opts === null || opts === void 0 ? void 0 : opts.credentialOffer) { credential_offer = Object.assign({}, opts.credentialOffer); } else { if (!(issuerMetadata === null || issuerMetadata === void 0 ? void 0 : issuerMetadata.credential_configurations_supported)) { throw new Error('credential_configurations_supported is mandatory in the metadata'); } credential_offer = { credential_issuer: issuerMetadata.credential_issuer, credential_configuration_ids: Object.keys(issuerMetadata.credential_configurations_supported), }; } if (grants) { credential_offer.grants = grants; } if (opts === null || opts === void 0 ? void 0 : opts.client_id) { credential_offer.client_id = opts.client_id; } // todo: check payload against issuer metadata. Especially strings in the credentials array: When processing, the Wallet MUST resolve this string value to the respective object. return { credential_offer, credential_offer_uri: opts === null || opts === void 0 ? void 0 : opts.credentialOfferUri }; } exports.createCredentialOfferObject = createCredentialOfferObject; function createCredentialOfferObjectv1_0_11(issuerMetadata, // todo: probably it's wise to create another builder for CredentialOfferPayload that will generate different kinds of CredentialOfferPayload opts) { var _a, _b, _c; if (!issuerMetadata && !(opts === null || opts === void 0 ? void 0 : opts.credentialOffer) && !(opts === null || opts === void 0 ? void 0 : opts.credentialOfferUri)) { throw new Error('You have to provide issuerMetadata or credentialOffer object for creating a deeplink'); } // v13 to v11 grant const grants = createCredentialOfferGrants(opts === null || opts === void 0 ? void 0 : opts.grants); if ((_a = grants === null || grants === void 0 ? void 0 : grants[oid4vci_common_1.PRE_AUTH_GRANT_LITERAL]) === null || _a === void 0 ? void 0 : _a.tx_code) { const _d = grants[oid4vci_common_1.PRE_AUTH_GRANT_LITERAL], { tx_code } = _d, rest = __rest(_d, ["tx_code"]); grants[oid4vci_common_1.PRE_AUTH_GRANT_LITERAL] = Object.assign({ user_pin_required: true }, rest); } let credential_offer; if (opts === null || opts === void 0 ? void 0 : opts.credentialOffer) { credential_offer = Object.assign(Object.assign({}, opts.credentialOffer), { credentials: (_c = (_b = opts.credentialOffer) === null || _b === void 0 ? void 0 : _b.credentials) !== null && _c !== void 0 ? _c : issuerMetadata === null || issuerMetadata === void 0 ? void 0 : issuerMetadata.credentials_supported.map((s) => s.id).filter((i) => i !== undefined) }); } else { if (!issuerMetadata) { throw new Error('Issuer metadata is required when no credential offer is provided'); } credential_offer = { credential_issuer: issuerMetadata.credential_issuer, credentials: issuerMetadata === null || issuerMetadata === void 0 ? void 0 : issuerMetadata.credentials_supported.map((s) => s.id).filter((i) => i !== undefined), }; } return { credential_offer, credential_offer_uri: opts === null || opts === void 0 ? void 0 : opts.credentialOfferUri }; } exports.createCredentialOfferObjectv1_0_11 = createCredentialOfferObjectv1_0_11; function createCredentialOfferURIFromObject(credentialOffer, offerMode, opts) { var _a; const { scheme, baseUri } = parseCredentialOfferSchemeAndBaseUri(opts === null || opts === void 0 ? void 0 : opts.scheme, opts === null || opts === void 0 ? void 0 : opts.baseUri, (_a = credentialOffer.credential_offer) === null || _a === void 0 ? void 0 : _a.credential_issuer); if (offerMode === 'REFERENCE') { if (!credentialOffer.credential_offer_uri) { throw Error(`credential_offer_uri must be set for offerMode ${offerMode}`); } if (credentialOffer.credential_offer_uri.includes('credential_offer_uri=')) { // discard the scheme. Apparently a URI is set and it already contains the actual uri, so assume that takes priority return credentialOffer.credential_offer_uri; } return `${scheme}://${baseUri}?credential_offer_uri=${encodeURIComponent(credentialOffer.credential_offer_uri)}`; } else if (offerMode === 'VALUE') { return `${scheme}://${baseUri}?credential_offer=${encodeURIComponent(JSON.stringify(credentialOffer.credential_offer))}`; } throw Error(`unsupported offerMode ${offerMode}`); } exports.createCredentialOfferURIFromObject = createCredentialOfferURIFromObject; function createCredentialOfferURI(offerMode, issuerMetadata, // todo: probably it's wise to create another builder for CredentialOfferPayload that will generate different kinds of CredentialOfferPayload opts) { const credentialOffer = createCredentialOfferObject(issuerMetadata, opts); return createCredentialOfferURIFromObject(credentialOffer, offerMode, opts); } exports.createCredentialOfferURI = createCredentialOfferURI; function createCredentialOfferURIv1_0_11(offerMode, issuerMetadata, // todo: probably it's wise to create another builder for CredentialOfferPayload that will generate different kinds of CredentialOfferPayload opts) { const credentialOffer = createCredentialOfferObjectv1_0_11(issuerMetadata, opts); return createCredentialOfferURIFromObject(credentialOffer, offerMode, opts); } exports.createCredentialOfferURIv1_0_11 = createCredentialOfferURIv1_0_11; const isPreAuthorizedCodeExpired = (state, expirationDurationInSeconds) => { const now = +new Date(); const expirationTime = state.createdAt + expirationDurationInSeconds * 1000; return now >= expirationTime; }; exports.isPreAuthorizedCodeExpired = isPreAuthorizedCodeExpired; const assertValidPinNumber = (pin, pinLength) => { if (pin && !RegExp(`[\\d\\D]{${pinLength !== null && pinLength !== void 0 ? pinLength : 6}}`).test(pin)) { throw Error(`${oid4vci_common_1.PIN_NOT_MATCH_ERROR}`); } }; exports.assertValidPinNumber = assertValidPinNumber; //# sourceMappingURL=CredentialOfferUtils.js.map