UNPKG

@sphereon/ssi-sdk.oid4vci-issuer

Version:

1,001 lines (995 loc) • 36.9 kB
var __defProp = Object.defineProperty; var __getOwnPropNames = Object.getOwnPropertyNames; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; // plugin.schema.json var require_plugin_schema = __commonJS({ "plugin.schema.json"(exports, module) { module.exports = { IDidAuthSiopOpAuthenticator: { components: { schemas: { IGetSiopSessionArgs: { type: "object", properties: { sessionId: { type: "string" }, additionalProperties: false }, required: ["sessionId"], description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.getSessionForSiop } " }, IRegisterSiopSessionArgs: { type: "object", properties: { identifier: { type: "object", properties: { did: { type: "string" }, alias: { type: "string" }, provider: { type: "string" }, controllerKeyId: { type: "string" }, keys: { type: "array", items: { type: "object", properties: { additionalProperties: true } } }, services: { type: "array", items: { type: "object", properties: { additionalProperties: true } } } }, additionalProperties: false, required: ["did", "provider", "keys", "services"] }, sessionId: { type: "string" }, expiresIn: { type: "number" }, additionalProperties: false }, required: ["identifier"], description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.registerSessionForSiop } " }, IRemoveSiopSessionArgs: { type: "object", properties: { sessionId: { type: "string" }, additionalProperties: false }, required: ["sessionId"], description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.removeSessionForSiop } " }, IAuthenticateWithSiopArgs: { type: "object", properties: { sessionId: { type: "string" }, stateId: { type: "string" }, redirectUrl: { type: "string" }, additionalProperties: false }, required: ["sessionId", "stateId", "redirectUrl"], description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.authenticateWithSiop } " }, IResponse: { type: "object", properties: { status: { type: "number" }, additionalProperties: true }, required: ["status"], description: "Result of {@link DidAuthSiopOpAuthenticator.authenticateWithSiop & DidAuthSiopOpAuthenticator.sendSiopAuthenticationResponse } " }, IGetSiopAuthenticationRequestFromRpArgs: { type: "object", properties: { sessionId: { type: "string" }, stateId: { type: "string" }, redirectUrl: { type: "string" }, additionalProperties: false }, required: ["sessionId", "stateId", "redirectUrl"], description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.getSiopAuthenticationRequestFromRP } " }, ParsedAuthenticationRequestURI: { type: "object", properties: { jwt: { type: "string" }, requestPayload: { type: "object", properties: { additionalProperties: true } }, registration: { type: "object", properties: { additionalProperties: true } }, additionalProperties: false }, required: ["jwt", "requestPayload", "registration"], description: "Result of {@link DidAuthSiopOpAuthenticator.getSiopAuthenticationRequestFromRP } " }, IGetSiopAuthenticationRequestDetailsArgs: { type: "object", properties: { sessionId: { type: "string" }, verifiedAuthenticationRequest: { type: "object", properties: { additionalProperties: true } }, credentialFilter: { type: "object", properties: { additionalProperties: true } }, additionalProperties: false }, required: ["sessionId", "verifiedAuthenticationRequest"], description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.getSiopAuthenticationRequestDetails } " }, IAuthRequestDetails: { type: "object", properties: { id: { type: "string" }, alsoKnownAs: { type: "array", items: { type: "string" } }, vpResponseOpts: { type: "object", properties: { additionalProperties: true } }, additionalProperties: false }, required: ["id", "vpResponseOpts"], description: "Result of {@link DidAuthSiopOpAuthenticator.getSiopAuthenticationRequestDetails } " }, IVerifySiopAuthenticationRequestUriArgs: { type: "object", properties: { sessionId: { type: "string" }, ParsedAuthenticationRequestURI: { type: "object", properties: { additionalProperties: true } }, additionalProperties: false }, required: ["sessionId", "ParsedAuthenticationRequestURI"], description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.verifySiopAuthenticationRequestURI } " }, VerifiedAuthorizationRequest: { type: "object", properties: { payload: { type: "object", properties: { additionalProperties: true } }, presentationDefinitions: { type: "object", properties: { additionalProperties: true } }, verifyOpts: { type: "object", properties: { additionalProperties: true } }, additionalProperties: false }, required: ["payload", "verifyOpts"], description: "Result of {@link DidAuthSiopOpAuthenticator.verifySiopAuthenticationRequestURI } " }, ISendSiopAuthenticationResponseArgs: { type: "object", properties: { sessionId: { type: "string" }, verifiedAuthenticationRequest: { type: "object", properties: { additionalProperties: true } }, verifiablePresentationResponse: { type: "object", properties: { additionalProperties: true } }, additionalProperties: false }, required: ["sessionId", "verifiedAuthenticationRequest"], description: "Arguments needed for {@link DidAuthSiopOpAuthenticator.sendSiopAuthenticationResponse } " } }, methods: { getSessionForSiop: { description: "Get SIOP session", arguments: { $ref: "#/components/schemas/IGetSiopSessionArgs" }, returnType: "object" }, registerSessionForSiop: { description: "Register SIOP session", arguments: { $ref: "#/components/schemas/IRegisterSiopSessionArgs" }, returnType: "object" }, removeSessionForSiop: { description: "Remove SIOP session", arguments: { $ref: "#/components/schemas/IRemoveSiopSessionArgs" }, returnType: "boolean" }, authenticateWithSiop: { description: "Authenticate using DID Auth SIOP", arguments: { $ref: "#/components/schemas/IAuthenticateWithSiopArgs" }, returnType: { $ref: "#/components/schemas/Response" } }, getSiopAuthenticationRequestFromRP: { description: "Get authentication request from RP", arguments: { $ref: "#/components/schemas/IGetSiopAuthenticationRequestFromRpArgs" }, returnType: { $ref: "#/components/schemas/ParsedAuthenticationRequestURI" } }, getSiopAuthenticationRequestDetails: { description: "Get authentication request details", arguments: { $ref: "#/components/schemas/IGetSiopAuthenticationRequestDetailsArgs" }, returnType: { $ref: "#/components/schemas/IAuthRequestDetails" } }, verifySiopAuthenticationRequestURI: { description: "Verify authentication request URI", arguments: { $ref: "#/components/schemas/IVerifySiopAuthenticationRequestUriArgs" }, returnType: { $ref: "#/components/schemas/VerifiedAuthorizationRequest" } }, sendSiopAuthenticationResponse: { description: "Send authentication response", arguments: { $ref: "#/components/schemas/ISendSiopAuthenticationResponseArgs" }, returnType: { $ref: "#/components/schemas/IRequiredContext" } } } } } }; } }); // src/agent/OID4VCIIssuer.ts import { retrieveWellknown } from "@sphereon/oid4vci-client"; import { WellKnownEndpoints } from "@sphereon/oid4vci-common"; import { assertValidAccessTokenRequest, createAccessTokenResponse } from "@sphereon/oid4vci-issuer"; import { getAgentResolver as getAgentResolver2 } from "@sphereon/ssi-sdk-ext.did-utils"; // src/functions.ts import { AuthorizationResponseStateStatus } from "@sphereon/did-auth-siop"; import { OpenId4VCIVersion } from "@sphereon/oid4vci-common"; import { VcIssuerBuilder } from "@sphereon/oid4vci-issuer"; import { getAgentResolver } from "@sphereon/ssi-sdk-ext.did-utils"; import { legacyKeyRefsToIdentifierOpts } from "@sphereon/ssi-sdk-ext.identifier-resolution"; import { contextHasPlugin } from "@sphereon/ssi-sdk.agent-config"; import { CredentialMapper } from "@sphereon/ssi-types"; import { bytesToBase64 } from "@veramo/utils"; import fetch from "cross-fetch"; import { createJWT, decodeJWT, verifyJWT } from "did-jwt"; import { jwtDecode } from "jwt-decode"; var CLOCK_SKEW_ISSUANCE = 2; function getJwtVerifyCallback({ verifyOpts }, _context) { return async (args) => { const resolver = getAgentResolver(_context, { resolverResolution: true, uniresolverResolution: true, localResolution: true }); verifyOpts = { ...verifyOpts, resolver: verifyOpts?.resolver }; if (!verifyOpts?.resolver || typeof verifyOpts?.resolver?.resolve !== "function") { verifyOpts.resolver = resolver; } const result = await _context.agent.jwtVerifyJwsSignature({ jws: args.jwt }); if (!result.error) { const identifier = result.jws.signatures[0].identifier; if (!identifier) { return Promise.reject(Error("the jws did not contain a signature with an identifier")); } const jwkInfo = identifier.jwks[0]; if (!jwkInfo) { return Promise.reject(Error(`the identifier of type ${identifier.method} is missing jwks (ExternalJwkInfo)`)); } const { alg: alg2 } = jwkInfo.jwk; const header = jwtDecode(args.jwt, { header: true }); const payload = jwtDecode(args.jwt, { header: false }); const kid2 = args.kid ?? header.kid; const jwk = jwkInfo.jwk; return { alg: alg2, ...identifier, jwt: { header, payload }, ...kid2 && { kid: kid2 }, ...jwk && { jwk } }; } const decodedJwt = await decodeJWT(args.jwt); const kid = args.kid ?? decodedJwt.header.kid; if (!kid || !kid.startsWith("did:")) { return { alg: decodedJwt.header.alg, jwt: decodedJwt }; } const did = kid.split("#")[0]; const didResult = await verifyJWT(args.jwt, verifyOpts); if (!didResult.verified) { console.log(`JWT invalid: ${args.jwt}`); throw Error("JWT did not verify successfully"); } const didResolution = await resolver.resolve(did); if (!didResolution || !didResolution.didDocument) { throw Error(`Could not resolve did: ${did}, metadata: ${didResolution?.didResolutionMetadata}`); } const alg = decodedJwt.header.alg; return { alg, kid, did, didDocument: didResolution.didDocument, jwt: decodedJwt }; }; } __name(getJwtVerifyCallback, "getJwtVerifyCallback"); async function getAccessTokenKeyRef(opts, context) { let identifier = legacyKeyRefsToIdentifierOpts(opts); return await context.agent.identifierManagedGet(identifier); } __name(getAccessTokenKeyRef, "getAccessTokenKeyRef"); async function getAccessTokenSignerCallback(opts, context) { const resolution = legacyKeyRefsToIdentifierOpts(opts); const identifier = await context.agent.identifierManagedGet({ identifier: resolution.identifier, vmRelationship: "authentication" }); const keyRef = identifier.kmsKeyRef; if (!keyRef) { throw Error("Cannot sign access tokens without a key ref"); } const signer = /* @__PURE__ */ __name(async (data) => { let dataString, encoding; if (typeof data === "string") { dataString = data; encoding = void 0; } else { dataString = bytesToBase64(data); encoding = "base64"; } return context.agent.keyManagerSign({ keyRef, data: dataString, encoding }); }, "signer"); async function accessTokenSignerCallback(jwt, kid) { const issuer = opts.idOpts?.issuer ?? (typeof opts.idOpts?.identifier === "string" ? opts.idOpts.identifier : opts.didOpts?.idOpts?.identifier?.toString() ?? opts?.iss); if (!issuer) { throw Error("No issuer configured for access tokens"); } let kidHeader = jwt?.header?.kid ?? kid; if (!kidHeader && identifier.kid) { kidHeader = identifier.kid; } if (!kidHeader) { if (opts.idOpts?.method === "did" || opts.idOpts?.method === "kid" || typeof opts.didOpts?.idOpts.identifier === "string" && opts.didOpts?.idOpts?.identifier?.startsWith("did:")) { kidHeader = opts.idOpts?.kid ?? opts.didOpts?.idOpts?.kid ?? opts?.didOpts?.identifierOpts?.kid; } } const alg = identifier.jwk?.alg; if (!alg) { return Promise.reject(Error("No algorithm found in identifier JWK")); } return await createJWT(jwt.payload, { signer, issuer }, { ...jwt.header, ...kidHeader && { kid: kidHeader }, typ: "JWT", alg }); } __name(accessTokenSignerCallback, "accessTokenSignerCallback"); return accessTokenSignerCallback; } __name(getAccessTokenSignerCallback, "getAccessTokenSignerCallback"); async function getCredentialSignerCallback(idOpts, context) { async function issueVCCallback(args) { const { jwtVerifyResult, format, statusLists } = args; const credential = args.credential; let proofFormat; let resolution; if (typeof idOpts.identifier !== "string") { resolution = idOpts; } else { resolution = await context.agent.identifierManagedGet({ identifier: idOpts.identifier, vmRelationship: "assertionMethod" }); } proofFormat = format?.includes("ld") ? "lds" : "jwt"; const issuer = resolution.issuer ?? resolution.kmsKeyRef; if (CredentialMapper.isW3cCredential(credential)) { if (!credential.issuer) { credential.issuer = { id: issuer }; } else if (typeof credential.issuer === "object" && !credential.issuer.id) { credential.issuer.id = issuer; } const subjectIsArray = Array.isArray(credential.credentialSubject); let credentialSubjects = Array.isArray(credential.credentialSubject) ? credential.credentialSubject : [ credential.credentialSubject ]; credentialSubjects = credentialSubjects.map((subject) => { if (!subject.id) { subject.id = jwtVerifyResult.did; } return subject; }); credential.credentialSubject = subjectIsArray ? credentialSubjects : credentialSubjects[0]; if (contextHasPlugin(context, "slAddStatusToCredential")) { const credentialStatusVC = await context.agent.slAddStatusToCredential({ credential, statusLists }); if (credential.credentialStatus && !credential.credentialStatus.statusListCredential) { credential.credentialStatus = credentialStatusVC.credentialStatus; } } const result = await context.agent.createVerifiableCredential({ credential, proofFormat, removeOriginalFields: false, fetchRemoteContexts: true, domain: typeof credential.issuer === "object" ? credential.issuer.id : credential.issuer, ...resolution.kid && { header: { kid: resolution.kid } } }); return proofFormat === "jwt" && "jwt" in result.proof ? result.proof.jwt : result; } else if (CredentialMapper.isSdJwtDecodedCredentialPayload(credential)) { const sdJwtPayload = credential; if (sdJwtPayload.iss === void 0) { sdJwtPayload.iss = issuer; } if (sdJwtPayload.iat === void 0) { sdJwtPayload.iat = Math.floor((/* @__PURE__ */ new Date()).getTime() / 1e3) - CLOCK_SKEW_ISSUANCE; } let disclosureFrame; if ("disclosureFrame" in credential) { disclosureFrame = credential["disclosureFrame"]; delete credential["disclosureFrame"]; } else { disclosureFrame = { _sd: credential["_sd"] }; } if (contextHasPlugin(context, "slAddStatusToSdJwtCredential")) { if (sdJwtPayload.status && sdJwtPayload.status.status_list || statusLists && statusLists.length > 0) { const sdJwtPayloadWithStatus = await context.agent.slAddStatusToSdJwtCredential({ credential: sdJwtPayload, statusLists }); if (sdJwtPayload.status?.status_list?.idx) { if (!sdJwtPayloadWithStatus.status || !sdJwtPayloadWithStatus.status.status_list) { return Promise.reject(Error("slAddStatusToSdJwtCredential did not return a status_list")); } if (statusLists && statusLists.length > 0) { const statusList = statusLists[0]; statusList.statusListId = sdJwtPayloadWithStatus.status.status_list.uri; statusList.statusListIndex = sdJwtPayloadWithStatus.status.status_list.idx; } sdJwtPayload.status.status_list.idx = sdJwtPayloadWithStatus.status.status_list.idx; } } } const result = await context.agent.createSdJwtVc({ credentialPayload: sdJwtPayload, disclosureFrame, resolution }); return result.credential; } return Promise.reject("VC issuance failed, an incorrect or unsupported credential was supplied"); } __name(issueVCCallback, "issueVCCallback"); return issueVCCallback; } __name(getCredentialSignerCallback, "getCredentialSignerCallback"); async function createVciIssuerBuilder(args, context) { const { issuerOpts, issuerMetadata, authorizationServerMetadata } = args; const builder = new VcIssuerBuilder(); const resolver = args.resolver ?? args?.issuerOpts?.didOpts?.resolveOpts?.resolver ?? args.issuerOpts?.didOpts?.resolveOpts?.jwtVerifyOpts?.resolver ?? getAgentResolver(context); if (!resolver) { throw Error("A Resolver is necessary to verify DID JWTs"); } const idOpts = legacyKeyRefsToIdentifierOpts({ didOpts: issuerOpts.didOpts, idOpts: issuerOpts.idOpts }); const jwtVerifyOpts = { ...issuerOpts?.didOpts?.resolveOpts?.jwtVerifyOpts, ...args?.issuerOpts?.resolveOpts?.jwtVerifyOpts, resolver, audience: issuerMetadata.credential_issuer }; builder.withVersion(issuerOpts.version ?? OpenId4VCIVersion.VER_1_0); builder.withIssuerMetadata(issuerMetadata); builder.withAuthorizationMetadata(authorizationServerMetadata); builder.withCredentialSignerCallback(await getCredentialSignerCallback(idOpts, context)); if (issuerOpts.nonceEndpoint) { builder.withNonceEndpoint(issuerOpts.nonceEndpoint); } else if (issuerMetadata.nonce_endpoint) { builder.withNonceEndpoint(issuerOpts.nonceEndpoint ?? issuerMetadata.nonce_endpoint); } if (issuerOpts.asClientOpts) { builder.withASClientMetadata(issuerOpts.asClientOpts); } builder.withJWTVerifyCallback(getJwtVerifyCallback({ verifyOpts: jwtVerifyOpts }, context)); if (args.credentialDataSupplier) { builder.withCredentialDataSupplier(args.credentialDataSupplier); } builder.withInMemoryCNonceState(); builder.withInMemoryCredentialOfferState(); builder.withInMemoryCredentialOfferURIState(); return builder; } __name(createVciIssuerBuilder, "createVciIssuerBuilder"); async function createVciIssuer({ issuerOpts, issuerMetadata, authorizationServerMetadata, credentialDataSupplier }, context) { return (await createVciIssuerBuilder({ issuerOpts, issuerMetadata, authorizationServerMetadata, credentialDataSupplier }, context)).build(); } __name(createVciIssuer, "createVciIssuer"); async function createAuthRequestUriCallback(opts) { async function authRequestUriCallback() { const path = opts.path.replace(":definitionId", opts.presentationDefinitionId); return fetch(path, { method: "POST", headers: { "Content-Type": "application/json" } }).then(async (response) => { if (response.status >= 400) { return Promise.reject(Error(await response.text())); } else { const responseData = await response.json(); if (!responseData.authRequestURI) { return Promise.reject(Error("Missing auth request uri in response body")); } return responseData.authRequestURI; } }); } __name(authRequestUriCallback, "authRequestUriCallback"); return authRequestUriCallback; } __name(createAuthRequestUriCallback, "createAuthRequestUriCallback"); async function createVerifyAuthResponseCallback(opts) { async function verifyAuthResponseCallback(correlationId) { return fetch(opts.path, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ definitionId: opts.presentationDefinitionId, correlationId }) }).then(async (response) => { if (response.status >= 400) { return Promise.reject(Error(await response.text())); } else { const responseData = await response.json(); if (!responseData.status) { return Promise.reject(Error("Missing status in response body")); } return responseData.status === AuthorizationResponseStateStatus.VERIFIED; } }); } __name(verifyAuthResponseCallback, "verifyAuthResponseCallback"); return verifyAuthResponseCallback; } __name(createVerifyAuthResponseCallback, "createVerifyAuthResponseCallback"); // src/IssuerInstance.ts import { legacyKeyRefsToIdentifierOpts as legacyKeyRefsToIdentifierOpts2 } from "@sphereon/ssi-sdk-ext.identifier-resolution"; var IssuerInstance = class { static { __name(this, "IssuerInstance"); } _issuer; _metadataOptions; _issuerOptions; _issuerMetadata; _authorizationServerMetadata; constructor({ issuerOpts, metadataOpts, issuerMetadata, authorizationServerMetadata }) { this._issuerOptions = issuerOpts; this._metadataOptions = metadataOpts; this._issuerMetadata = issuerMetadata; this._authorizationServerMetadata = authorizationServerMetadata; } /** * Returns the (lazily-built and cached) {@link VcIssuer} for this instance. * * When `wrapCredentialSignerCallback` is provided on first invocation, the wrapper is applied to the * configured {@link CredentialSignerCallback} before `build()` is called, so the resulting issuer's * signer callback is the wrapped one. This is the supported injection point for cross-cutting concerns * such as persisting the issued credential server-side (see DEV-35). Avoid mutating the issuer's * signer callback after construction. */ async get(opts) { if (!this._issuer) { const builder = await createVciIssuerBuilder({ issuerOpts: this.issuerOptions, issuerMetadata: this.issuerMetadata, authorizationServerMetadata: this.authorizationServerMetadata, credentialDataSupplier: opts?.credentialDataSupplier }, opts.context); if (opts.wrapCredentialSignerCallback) { const idOpts = legacyKeyRefsToIdentifierOpts2({ didOpts: this._issuerOptions.didOpts, idOpts: this._issuerOptions.idOpts }); const original = await getCredentialSignerCallback(idOpts, opts.context); builder.withCredentialSignerCallback(opts.wrapCredentialSignerCallback(original)); } this._issuer = builder.build(); } return this._issuer; } get issuerOptions() { return this._issuerOptions; } get metadataOptions() { return this._metadataOptions; } get issuerMetadata() { return this._issuerMetadata; } set issuerMetadata(value) { if (this._issuer?.issuerMetadata) { this._issuer.issuerMetadata = { ...this._issuer?.issuerMetadata, credential_configurations_supported: value.credential_configurations_supported }; } this._issuerMetadata = value; } get authorizationServerMetadata() { return this._authorizationServerMetadata; } }; // src/agent/OID4VCIIssuer.ts var oid4vciIssuerMethods = [ "oid4vciCreateOfferURI", "oid4vciIssueCredential", "oid4vciCreateAccessTokenResponse", "oid4vciGetInstance", "oid4vciRefreshInstanceMetadata" ]; var OID4VCIIssuer = class _OID4VCIIssuer { static { __name(this, "OID4VCIIssuer"); } static _DEFAULT_OPTS_KEY = "_default"; instances = /* @__PURE__ */ new Map(); schema = schema.IDidAuthSiopOpAuthenticator; methods = { oid4vciCreateOfferURI: this.oid4vciCreateOfferURI.bind(this), oid4vciIssueCredential: this.oid4vciIssueCredential.bind(this), oid4vciCreateAccessTokenResponse: this.oid4vciCreateAccessTokenResponse.bind(this), oid4vciGetInstance: this.oid4vciGetInstance.bind(this), oid4vciRefreshInstanceMetadata: this.oid4vciRefreshInstanceMetadata.bind(this) }; _opts; constructor(opts) { this._opts = opts ?? {}; } async oid4vciCreateOfferURI(createArgs, context) { return await this.oid4vciGetInstance(createArgs, context).then((instance) => instance.get({ context })).then((issuer) => issuer.createCredentialOfferURI(createArgs).then((response) => { const result = response; if (this._opts.returnSessions === false) { delete result.session; } return result; })); } async oid4vciIssueCredential(issueArgs, context) { return await this.oid4vciGetInstance(issueArgs, context).then((instance) => instance.get({ context })).then((issuer) => issuer.issueCredential(issueArgs)); } async oid4vciCreateAccessTokenResponse(accessTokenArgs, context) { return await this.oid4vciGetInstance(accessTokenArgs, context).then(async (instance) => { const issuer = await instance.get({ context }); await assertValidAccessTokenRequest(accessTokenArgs.request, { credentialOfferSessions: issuer.credentialOfferSessions, expirationDuration: accessTokenArgs.expirationDuration }); const accessTokenIssuer = instance.issuerOptions.idOpts?.issuer ?? instance.issuerOptions.didOpts?.idOpts.identifier.toString(); if (!accessTokenIssuer) { return Promise.reject(Error(`Could not determine access token issuer`)); } return createAccessTokenResponse(accessTokenArgs.request, { accessTokenIssuer, tokenExpiresIn: accessTokenArgs.expirationDuration, cNonceExpiresIn: accessTokenArgs.expirationDuration, cNonces: issuer.cNonces, credentialOfferSessions: issuer.credentialOfferSessions, accessTokenSignerCallback: await getAccessTokenSignerCallback(instance.issuerOptions, context) }); }); } getExternalAS(issuerMetadata) { if ("authorization_servers" in issuerMetadata && Array.isArray(issuerMetadata.authorization_servers)) { return issuerMetadata.authorization_servers.find((as) => as !== issuerMetadata.credential_issuer); } return void 0; } async createIssuerInstance(args, context) { const credentialIssuer = args.credentialIssuer ?? _OID4VCIIssuer._DEFAULT_OPTS_KEY; const metadataOpts = await this.getMetadataOpts({ ...args, credentialIssuer }, context); const issuerMetadata = await this.getIssuerMetadata({ ...args, credentialIssuer }, context); const externalAS = this.getExternalAS(issuerMetadata); let asMetadataResponse = void 0; if (externalAS) { asMetadataResponse = await retrieveWellknown(externalAS, WellKnownEndpoints.OPENID_CONFIGURATION, { errorOnNotFound: false }); if (!asMetadataResponse) { asMetadataResponse = await retrieveWellknown(externalAS, WellKnownEndpoints.OAUTH_AS, { errorOnNotFound: true }); } } const authorizationServerMetadata = asMetadataResponse?.successBody ? asMetadataResponse.successBody : await this.getAuthorizationServerMetadataFromStore({ ...args, credentialIssuer }, context); const issuerOpts = await this.getIssuerOptsFromStore({ ...args, credentialIssuer }, context); if (!issuerOpts.resolveOpts) { issuerOpts.resolveOpts = { ...issuerOpts.didOpts?.resolveOpts, ...this._opts.resolveOpts }; } if (!issuerOpts.resolveOpts?.resolver) { issuerOpts.resolveOpts.resolver = getAgentResolver2(context); } this.instances.set(credentialIssuer, new IssuerInstance({ issuerOpts, metadataOpts, issuerMetadata, authorizationServerMetadata })); return this.oid4vciGetInstance(args, context); } // TODO SSISDK-87 create proper solution to update issuer metadata async oid4vciRefreshInstanceMetadata(args, context) { const instance = this.instances.get(args.credentialIssuer); if (instance) { instance.issuerMetadata = await this.getIssuerMetadata({ ...args }, context); return true; } return false; } async oid4vciGetInstance(args, context) { const credentialIssuer = args.credentialIssuer ?? _OID4VCIIssuer._DEFAULT_OPTS_KEY; if (!this.instances.has(credentialIssuer)) { await this.createIssuerInstance(args, context); } return this.instances.get(credentialIssuer); } async getIssuerOptsFromStore(opts, context) { const credentialIssuer = opts.credentialIssuer; const storeId = await this.storeId(opts, context); const namespace = await this.namespace(opts, context); const options = await context.agent.oid4vciStoreGetIssuerOpts({ metadataType: "issuer", correlationId: credentialIssuer, storeId, namespace }); if (!options) { throw Error(`Could not get specific nor default options for definition ${credentialIssuer}`); } return options; } async getMetadataOpts(opts, context) { const credentialIssuer = opts.credentialIssuer; const storeId = await this.storeId(opts, context); const storeNamespace = await this.namespace(opts, context); return { credentialIssuer, storeId, storeNamespace }; } async getIssuerMetadata(opts, context) { const metadataOpts = await this.getMetadataOpts(opts, context); const metadata = await context.agent.oid4vciStoreGetMetadata({ metadataType: "issuer", correlationId: metadataOpts.credentialIssuer, namespace: metadataOpts.storeNamespace, storeId: metadataOpts.storeId }); if (!metadata) { throw Error(`Issuer metadata not found for issuer ${opts.credentialIssuer}, namespace ${opts.namespace} and store ${opts.storeId}`); } return metadata; } async getAuthorizationServerMetadataFromStore(opts, context) { const metadataOpts = await this.getMetadataOpts(opts, context); const metadata = await context.agent.oid4vciStoreGetMetadata({ metadataType: "authorizationServer", correlationId: metadataOpts.credentialIssuer, namespace: metadataOpts.storeNamespace, storeId: metadataOpts.storeId }); if (!metadata) { throw Error(`Authorization server ${opts.credentialIssuer} metadata not found for namespace ${metadataOpts.storeNamespace} and store ${metadataOpts.storeId}`); } return metadata; } async storeId(opts, context) { const storeId = opts?.storeId ?? this._opts?.defaultStoreId ?? await context?.agent.oid4vciStoreDefaultStoreId(); if (!storeId) { throw Error("Please provide a store id a default value, or provide the context for a global default store id"); } return storeId; } async namespace(opts, context) { const namespace = opts?.namespace ?? this._opts?.defaultNamespace ?? await context?.agent.oid4vciStoreDefaultNamespace(); if (!namespace) { throw Error("Please provide a namespace a default value, or provide the context for a global default namespace"); } return namespace; } }; // src/index.ts var schema = require_plugin_schema(); export { IssuerInstance, OID4VCIIssuer, createAuthRequestUriCallback, createVciIssuer, createVciIssuerBuilder, createVerifyAuthResponseCallback, getAccessTokenKeyRef, getAccessTokenSignerCallback, getCredentialSignerCallback, getJwtVerifyCallback, oid4vciIssuerMethods, schema }; //# sourceMappingURL=index.js.map