@sphereon/ssi-sdk.oid4vci-issuer
Version:
1,001 lines (995 loc) • 36.9 kB
JavaScript
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