UNPKG

@sphereon/openid4vci-client

Version:

OpenID for Verifiable Credential Issuance (OpenID4VCI) client

144 lines 12 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()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.MetadataClient = void 0; const debug_1 = __importDefault(require("debug")); const functions_1 = require("./functions"); const types_1 = require("./types"); const debug = (0, debug_1.default)('sphereon:openid4vci:metadata'); class MetadataClient { /** * Retrieve metadata using the Initiation obtained from a previous step * * @param initiation */ static retrieveAllMetadataFromInitiation(initiation) { return __awaiter(this, void 0, void 0, function* () { return MetadataClient.retrieveAllMetadataFromInitiationRequest(initiation.issuanceInitiationRequest); }); } /** * Retrieve the metada using the initiation request obtained from a previous step * @param initiationRequest */ static retrieveAllMetadataFromInitiationRequest(initiationRequest) { return __awaiter(this, void 0, void 0, function* () { return MetadataClient.retrieveAllMetadata(initiationRequest.issuer); }); } /** * Retrieve all metadata from an issuer * @param issuer The issuer URL */ static retrieveAllMetadata(issuer, opts) { var _a; return __awaiter(this, void 0, void 0, function* () { let token_endpoint; let credential_endpoint; const response = yield MetadataClient.retrieveOpenID4VCIServerMetadata(issuer); let oid4vciMetadata = response.successBody ? response.successBody : undefined; if (oid4vciMetadata) { debug(`Issuer ${issuer} OID4VCI well-known server metadata\r\n${oid4vciMetadata}`); credential_endpoint = oid4vciMetadata.credential_endpoint; token_endpoint = oid4vciMetadata.token_endpoint; if (!token_endpoint && oid4vciMetadata.authorization_server) { debug(`Issuer ${issuer} OID4VCI metadata has separate authorization_server ${oid4vciMetadata.authorization_server} that contains the token endpoint`); // Crossword uses this to separate the AS metadata. We fail when not found, since we now have no way of getting the token endpoint const response = yield this.retrieveWellknown(oid4vciMetadata.authorization_server, types_1.WellKnownEndpoints.OAUTH_AS, { errorOnNotFound: true, }); token_endpoint = (_a = response.successBody) === null || _a === void 0 ? void 0 : _a.token_endpoint; } } else { // No specific OID4VCI endpoint. Either can be an OAuth2 AS or an OpenID IDP. Let's start with OIDC first let response = yield MetadataClient.retrieveWellknown(issuer, types_1.WellKnownEndpoints.OPENID_CONFIGURATION, { errorOnNotFound: false, }); let asConfig = response.successBody; if (asConfig) { debug(`Issuer ${issuer} has OpenID Connect Server metadata in well-known location`); } else { // Now oAuth2 response = yield MetadataClient.retrieveWellknown(issuer, types_1.WellKnownEndpoints.OAUTH_AS, { errorOnNotFound: false }); asConfig = response.successBody; } if (asConfig) { debug(`Issuer ${issuer} has oAuth2 Server metadata in well-known location`); oid4vciMetadata = asConfig; credential_endpoint = oid4vciMetadata.credential_endpoint; token_endpoint = oid4vciMetadata.token_endpoint; } } if (!token_endpoint) { debug(`Issuer ${issuer} does not have a token_endpoint listed in well-known locations!`); if (opts === null || opts === void 0 ? void 0 : opts.errorOnNotFound) { throw new Error(`Could not deduce the token endpoint for ${issuer}`); } else { token_endpoint = `${issuer}${issuer.endsWith('/') ? '' : '/'}token`; } } if (!credential_endpoint) { debug(`Issuer ${issuer} does not have a credential_endpoint listed in well-known locations!`); if (opts === null || opts === void 0 ? void 0 : opts.errorOnNotFound) { throw new Error(`Could not deduce the credential endpoint for ${issuer}`); } else { credential_endpoint = `${issuer}${issuer.endsWith('/') ? '' : '/'}credential`; } } debug(`Issuer ${issuer} token endpoint ${token_endpoint}, credential endpoint ${credential_endpoint}`); return { issuer, token_endpoint, credential_endpoint, openid4vci_metadata: oid4vciMetadata, }; }); } /** * Retrieve only the OID4VCI metadata for the issuer. So no OIDC/OAuth2 metadata * * @param issuerHost The issuer hostname */ static retrieveOpenID4VCIServerMetadata(issuerHost) { return __awaiter(this, void 0, void 0, function* () { // Since the server metadata endpoint is optional we are not going to throw an error. return MetadataClient.retrieveWellknown(issuerHost, types_1.WellKnownEndpoints.OPENID4VCI_ISSUER, { errorOnNotFound: false }); }); } /** * Allows to retrieve information from a well-known location * * @param host The host * @param endpointType The endpoint type, currently supports OID4VCI, OIDC and OAuth2 endpoint types * @param opts Options, like for instance whether an error should be thrown in case the endpoint doesn't exist */ static retrieveWellknown(host, endpointType, opts) { return __awaiter(this, void 0, void 0, function* () { const result = yield (0, functions_1.getJson)(`${host.endsWith('/') ? host.slice(0, -1) : host}${endpointType}`, { exceptionOnHttpErrorStatus: opts === null || opts === void 0 ? void 0 : opts.errorOnNotFound, }); if (result.origResponse.status === 404) { // We only get here when error on not found is false debug(`host ${host} with endpoint type ${endpointType} was not found (404)`); } return result; }); } } exports.MetadataClient = MetadataClient; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWV0YWRhdGFDbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9saWIvTWV0YWRhdGFDbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsa0RBQTBCO0FBRTFCLDJDQUFzQztBQUN0QyxtQ0FTaUI7QUFFakIsTUFBTSxLQUFLLEdBQUcsSUFBQSxlQUFLLEVBQUMsOEJBQThCLENBQUMsQ0FBQztBQUVwRCxNQUFhLGNBQWM7SUFHekI7Ozs7T0FJRztJQUNJLE1BQU0sQ0FBTyxpQ0FBaUMsQ0FBQyxVQUF5Qzs7WUFDN0YsT0FBTyxjQUFjLENBQUMsd0NBQXdDLENBQUMsVUFBVSxDQUFDLHlCQUF5QixDQUFDLENBQUM7UUFDdkcsQ0FBQztLQUFBO0lBRUQ7OztPQUdHO0lBQ0ksTUFBTSxDQUFPLHdDQUF3QyxDQUFDLGlCQUFtRDs7WUFDOUcsT0FBTyxjQUFjLENBQUMsbUJBQW1CLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdEUsQ0FBQztLQUFBO0lBRUQ7OztPQUdHO0lBQ0ksTUFBTSxDQUFPLG1CQUFtQixDQUFDLE1BQWMsRUFBRSxJQUFtQzs7O1lBQ3pGLElBQUksY0FBYyxDQUFDO1lBQ25CLElBQUksbUJBQW1CLENBQUM7WUFDeEIsTUFBTSxRQUFRLEdBQUcsTUFBTSxjQUFjLENBQUMsZ0NBQWdDLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDL0UsSUFBSSxlQUFlLEdBQUcsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQzlFLElBQUksZUFBZSxFQUFFO2dCQUNuQixLQUFLLENBQUMsVUFBVSxNQUFNLDBDQUEwQyxlQUFlLEVBQUUsQ0FBQyxDQUFDO2dCQUNuRixtQkFBbUIsR0FBRyxlQUFlLENBQUMsbUJBQW1CLENBQUM7Z0JBQzFELGNBQWMsR0FBRyxlQUFlLENBQUMsY0FBYyxDQUFD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