@sphereon/ssi-sdk.siopv2-oid4vp-rp-auth
Version:
1,078 lines (1,072 loc) • 40.1 kB
JavaScript
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var index_exports = {};
__export(index_exports, {
SIOPv2RP: () => SIOPv2RP,
schema: () => plugin_schema_default
});
module.exports = __toCommonJS(index_exports);
// plugin.schema.json
var plugin_schema_default = {
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/SIOPv2RP.ts
var import_did_auth_siop2 = require("@sphereon/did-auth-siop");
var import_ssi_sdk_ext4 = require("@sphereon/ssi-sdk-ext.did-utils");
var import_ssi_sdk2 = require("@sphereon/ssi-sdk.core");
var import_uuid3 = require("uuid");
var import_ssi_types2 = require("@sphereon/ssi-types");
var import_dcql = require("dcql");
// src/functions.ts
var import_did_auth_siop = require("@sphereon/did-auth-siop");
var import_oid4vc_common = require("@sphereon/oid4vc-common");
var import_ssi_sdk_ext = require("@sphereon/ssi-sdk-ext.did-utils");
var import_ssi_sdk_ext2 = require("@sphereon/ssi-sdk-ext.identifier-resolution");
var import_ssi_types = require("@sphereon/ssi-types");
var import_events = require("events");
var import_uuid = require("uuid");
var import_ssi_sdk = require("@sphereon/ssi-sdk.core");
function getRequestVersion(rpOptions) {
if (Array.isArray(rpOptions.supportedVersions) && rpOptions.supportedVersions.length > 0) {
return rpOptions.supportedVersions[0];
}
return import_did_auth_siop.SupportedVersion.OID4VP_v1;
}
__name(getRequestVersion, "getRequestVersion");
function getWellKnownDIDVerifyCallback(siopIdentifierOpts, context) {
return siopIdentifierOpts.wellknownDIDVerifyCallback ? siopIdentifierOpts.wellknownDIDVerifyCallback : async (args) => {
const result = await context.agent.cvVerifyCredential({
credential: args.credential,
fetchRemoteContexts: true
});
return {
verified: result.result
};
};
}
__name(getWellKnownDIDVerifyCallback, "getWellKnownDIDVerifyCallback");
function getDcqlQueryLookupCallback(context) {
async function dcqlQueryLookup(queryId, version, tenantId) {
const result = await context.agent.pdmGetDefinitions({
filter: [
{
queryId,
...tenantId && {
tenantId
},
...version && {
version
}
},
...(0, import_uuid.validate)(queryId) ? [
{
id: queryId
}
] : []
]
});
if (result && result.length > 0) {
return result[0].query;
}
return Promise.reject(Error(`No dcql query found for queryId ${queryId}`));
}
__name(dcqlQueryLookup, "dcqlQueryLookup");
return dcqlQueryLookup;
}
__name(getDcqlQueryLookupCallback, "getDcqlQueryLookupCallback");
function getPresentationVerificationCallback(idOpts, context) {
async function presentationVerificationCallback(args, presentationSubmission) {
if (import_ssi_types.CredentialMapper.isSdJwtEncoded(args)) {
const result2 = await context.agent.verifySdJwtPresentation({
presentation: args
});
return {
verified: !!result2.payload
};
}
if (import_ssi_types.CredentialMapper.isMsoMdocOid4VPEncoded(args)) {
if (context.agent.mdocOid4vpRPVerify === void 0) {
return Promise.reject("ImDLMdoc agent plugin must be enabled to support MsoMdoc types");
}
if (presentationSubmission !== void 0 && presentationSubmission !== null) {
const verifyResult = await context.agent.mdocOid4vpRPVerify({
vp_token: args,
presentation_submission: presentationSubmission
});
return {
verified: !verifyResult.error
};
}
throw Error(`mdocOid4vpRPVerify(...) method requires a presentation submission`);
}
const result = await context.agent.verifyPresentation({
presentation: args,
fetchRemoteContexts: true,
domain: (await context.agent.identifierManagedGet(idOpts)).kid?.split("#")[0]
});
return {
verified: result.verified
};
}
__name(presentationVerificationCallback, "presentationVerificationCallback");
return presentationVerificationCallback;
}
__name(getPresentationVerificationCallback, "getPresentationVerificationCallback");
async function createRPBuilder(args) {
const { rpOpts, context } = args;
const { identifierOpts } = rpOpts;
const didMethods = identifierOpts.supportedDIDMethods ?? await (0, import_ssi_sdk_ext.getAgentDIDMethods)(context);
const eventEmitter = rpOpts.eventEmitter ?? new import_events.EventEmitter();
const defaultClientMetadata = {
// FIXME: All of the below should be configurable. Some should come from builder, some should be determined by the agent.
// For now it is either preconfigured or everything passed in as a single object
idTokenSigningAlgValuesSupported: [
import_oid4vc_common.SigningAlgo.EDDSA,
import_oid4vc_common.SigningAlgo.ES256,
import_oid4vc_common.SigningAlgo.ES256K
],
requestObjectSigningAlgValuesSupported: [
import_oid4vc_common.SigningAlgo.EDDSA,
import_oid4vc_common.SigningAlgo.ES256,
import_oid4vc_common.SigningAlgo.ES256K
],
responseTypesSupported: [
import_did_auth_siop.ResponseType.ID_TOKEN
],
client_name: "Sphereon",
vpFormatsSupported: {
jwt_vc: {
alg: [
"EdDSA",
"ES256K"
]
},
jwt_vp: {
alg: [
"ES256K",
"EdDSA"
]
}
},
scopesSupported: [
import_did_auth_siop.Scope.OPENID_DIDAUTHN
],
subjectTypesSupported: [
import_did_auth_siop.SubjectType.PAIRWISE
],
subject_syntax_types_supported: didMethods.map((method) => `did:${method}`),
passBy: import_did_auth_siop.PassBy.VALUE
};
const resolver = rpOpts.identifierOpts.resolveOpts?.resolver ?? (0, import_ssi_sdk_ext.getAgentResolver)(context, {
resolverResolution: true,
localResolution: true,
uniresolverResolution: rpOpts.identifierOpts.resolveOpts?.noUniversalResolverFallback !== true
});
let hasher = rpOpts.credentialOpts?.hasher;
if (!rpOpts.credentialOpts?.hasher || typeof rpOpts.credentialOpts?.hasher !== "function") {
hasher = import_ssi_sdk.defaultHasher;
}
const builder = import_did_auth_siop.RP.builder({
requestVersion: getRequestVersion(rpOpts)
}).withScope("openid", import_did_auth_siop.PropertyTarget.REQUEST_OBJECT).withResponseMode(rpOpts.responseMode ?? import_did_auth_siop.ResponseMode.POST).withResponseType(import_did_auth_siop.ResponseType.VP_TOKEN, import_did_auth_siop.PropertyTarget.REQUEST_OBJECT).withSupportedVersions(rpOpts.supportedVersions ?? [
import_did_auth_siop.SupportedVersion.OID4VP_v1,
import_did_auth_siop.SupportedVersion.SIOPv2_OID4VP_D28
]).withEventEmitter(eventEmitter).withSessionManager(rpOpts.sessionManager ?? new import_did_auth_siop.InMemoryRPSessionManager(eventEmitter)).withClientMetadata(rpOpts.clientMetadataOpts ?? defaultClientMetadata, import_did_auth_siop.PropertyTarget.REQUEST_OBJECT).withVerifyJwtCallback(rpOpts.verifyJwtCallback ? rpOpts.verifyJwtCallback : getVerifyJwtCallback({
resolver,
verifyOpts: {
wellknownDIDVerifyCallback: getWellKnownDIDVerifyCallback(rpOpts.identifierOpts, context),
checkLinkedDomain: "if_present"
}
}, context)).withDcqlQueryLookup(getDcqlQueryLookupCallback(context)).withRevocationVerification(import_did_auth_siop.RevocationVerification.NEVER).withPresentationVerification(getPresentationVerificationCallback(identifierOpts.idOpts, context));
const oidfOpts = identifierOpts.oidfOpts;
if (oidfOpts && (0, import_ssi_sdk_ext2.isExternalIdentifierOIDFEntityIdOpts)(oidfOpts)) {
builder.withEntityId(oidfOpts.identifier, import_did_auth_siop.PropertyTarget.REQUEST_OBJECT);
} else {
const resolution = await context.agent.identifierManagedGet(identifierOpts.idOpts);
const clientId = rpOpts.clientMetadataOpts?.client_id ?? resolution.issuer ?? ((0, import_ssi_sdk_ext2.isManagedIdentifierDidResult)(resolution) ? resolution.did : resolution.jwkThumbprint);
const clientIdPrefixed = prefixClientId(clientId);
builder.withClientId(clientIdPrefixed, import_did_auth_siop.PropertyTarget.REQUEST_OBJECT);
}
if (hasher) {
builder.withHasher(hasher);
}
if (rpOpts.responseRedirectUri) {
builder.withResponseRedirectUri(rpOpts.responseRedirectUri);
}
if (rpOpts.transactionData) {
builder.withTransactionData(rpOpts.transactionData);
}
if (rpOpts.verifierInfo) {
builder.withVerifierInfo(rpOpts.verifierInfo);
}
if (rpOpts.verifierAttestations) {
builder.withVerifierAttestations(rpOpts.verifierAttestations);
}
if (rpOpts.requestUriMethod) {
builder.withRequestUriMethod(rpOpts.requestUriMethod);
}
if (rpOpts.expectedOrigins) {
builder.withExpectedOrigins(rpOpts.expectedOrigins);
}
if (rpOpts.walletNonce) {
builder.withWalletNonce(rpOpts.walletNonce);
}
const createJwtCallback = signCallback(rpOpts.identifierOpts.idOpts, context);
builder.withCreateJwtCallback(createJwtCallback);
return builder;
}
__name(createRPBuilder, "createRPBuilder");
function signCallback(idOpts, context) {
return async (jwtIssuer, jwt, kid) => {
if (!((0, import_ssi_sdk_ext2.isManagedIdentifierDidOpts)(idOpts) || (0, import_ssi_sdk_ext2.isManagedIdentifierX5cOpts)(idOpts))) {
return Promise.reject(Error(`JWT issuer method ${jwtIssuer.method} not yet supported`));
}
const result = await context.agent.jwtCreateJwsCompactSignature({
// FIXME fix cose-key inference
// @ts-ignore
issuer: {
identifier: idOpts.identifier,
kmsKeyRef: idOpts.kmsKeyRef,
noIdentifierInHeader: false
},
// FIXME fix JWK key_ops
// @ts-ignore
protectedHeader: jwt.header,
payload: jwt.payload
});
return result.jwt;
};
}
__name(signCallback, "signCallback");
function getVerifyJwtCallback(_opts, context) {
return async (_jwtVerifier, jwt) => {
const result = await context.agent.jwtVerifyJwsSignature({
jws: jwt.raw
});
console.log(result.message);
return !result.error;
};
}
__name(getVerifyJwtCallback, "getVerifyJwtCallback");
function getSigningAlgo(type) {
switch (type) {
case "Ed25519":
return import_oid4vc_common.SigningAlgo.EDDSA;
case "Secp256k1":
return import_oid4vc_common.SigningAlgo.ES256K;
case "Secp256r1":
return import_oid4vc_common.SigningAlgo.ES256;
// @ts-ignore
case "RSA":
return import_oid4vc_common.SigningAlgo.RS256;
default:
throw Error("Key type not yet supported");
}
}
__name(getSigningAlgo, "getSigningAlgo");
function prefixClientId(clientId) {
if (clientId.startsWith("did:")) {
return `${import_did_auth_siop.ClientIdentifierPrefix.DECENTRALIZED_IDENTIFIER}:${clientId}`;
}
return clientId;
}
__name(prefixClientId, "prefixClientId");
// src/RPInstance.ts
var import_uuid2 = require("uuid");
var import_ssi_sdk_ext3 = require("@sphereon/ssi-sdk-ext.identifier-resolution");
var RPInstance = class {
static {
__name(this, "RPInstance");
}
_rp;
_presentationOptions;
_rpOptions;
constructor({ rpOpts, pexOpts }) {
this._rpOptions = rpOpts;
this._presentationOptions = pexOpts;
}
async get(context) {
if (!this._rp) {
const builder = await createRPBuilder({
rpOpts: this._rpOptions,
context
});
this._rp = builder.build();
}
return this._rp;
}
get rpOptions() {
return this._rpOptions;
}
get presentationOptions() {
return this._presentationOptions;
}
async createAuthorizationRequestURI(createArgs, context) {
const { correlationId, queryId, claims, requestByReferenceURI, responseURI, responseURIType, callback, responseRedirectURI } = createArgs;
const nonce = createArgs.nonce ?? (0, import_uuid2.v4)();
const state = createArgs.state ?? correlationId;
let jwtIssuer;
const idOpts = this.rpOptions.identifierOpts.idOpts;
const resolution = await (0, import_ssi_sdk_ext3.ensureManagedIdentifierResult)(idOpts, context);
if ((0, import_ssi_sdk_ext3.isManagedIdentifierDidResult)(resolution)) {
jwtIssuer = {
didUrl: resolution.kid,
method: "did",
alg: getSigningAlgo(resolution.key.type)
};
} else if ((0, import_ssi_sdk_ext3.isManagedIdentifierX5cResult)(resolution)) {
if (!resolution.issuer) {
return Promise.reject("missing issuer in idOpts");
}
jwtIssuer = {
issuer: resolution.issuer,
x5c: resolution.x5c,
method: "x5c",
alg: getSigningAlgo(resolution.key.type)
};
} else {
return Promise.reject(Error(`JWT issuer method ${resolution.method} not yet supported`));
}
return await this.get(context).then((rp) => rp.createAuthorizationRequestURI({
version: getRequestVersion(this.rpOptions),
correlationId,
queryId,
nonce,
state,
claims,
requestByReferenceURI,
responseURI,
responseURIType,
jwtIssuer,
callback,
responseRedirectURI
}));
}
async createAuthorizationRequest(createArgs, context) {
const { correlationId, claims, requestByReferenceURI, responseURI, responseURIType, responseRedirectURI } = createArgs;
const nonce = createArgs.nonce ?? (0, import_uuid2.v4)();
const state = createArgs.state ?? correlationId;
const idOpts = this.rpOptions.identifierOpts.idOpts;
const resolution = await (0, import_ssi_sdk_ext3.ensureManagedIdentifierResult)(idOpts, context);
let jwtIssuer;
if ((0, import_ssi_sdk_ext3.isManagedIdentifierX5cResult)(resolution) && resolution.issuer) {
jwtIssuer = {
method: resolution.method,
alg: getSigningAlgo(resolution.key.type),
x5c: resolution.x5c,
issuer: resolution.issuer
};
} else if ((0, import_ssi_sdk_ext3.isManagedIdentifierDidResult)(resolution)) {
jwtIssuer = {
method: resolution.method,
alg: getSigningAlgo(resolution.key.type),
didUrl: resolution.did
};
} else {
return Promise.reject(Error("Only did & x5c supported at present"));
}
return await this.get(context).then((rp) => rp.createAuthorizationRequest({
version: getRequestVersion(this.rpOptions),
correlationId,
nonce,
state,
claims,
requestByReferenceURI,
responseURIType,
responseURI,
jwtIssuer,
responseRedirectURI
}));
}
};
// src/agent/SIOPv2RP.ts
var SIOPv2RP = class _SIOPv2RP {
static {
__name(this, "SIOPv2RP");
}
opts;
static _DEFAULT_OPTS_KEY = "_default";
instances = /* @__PURE__ */ new Map();
schema = plugin_schema_default.IDidAuthSiopOpAuthenticator;
methods = {
siopCreateAuthRequestURI: this.createAuthorizationRequestURI.bind(this),
siopCreateAuthRequestPayloads: this.createAuthorizationRequestPayloads.bind(this),
siopGetAuthRequestState: this.siopGetRequestState.bind(this),
siopGetAuthResponseState: this.siopGetResponseState.bind(this),
siopUpdateAuthRequestState: this.siopUpdateRequestState.bind(this),
siopDeleteAuthState: this.siopDeleteState.bind(this),
siopVerifyAuthResponse: this.siopVerifyAuthResponse.bind(this),
siopImportDefinitions: this.siopImportDefinitions.bind(this),
siopGetRedirectURI: this.siopGetRedirectURI.bind(this)
};
constructor(opts) {
this.opts = opts;
}
setDefaultOpts(rpDefaultOpts, context) {
this.opts.defaultOpts = rpDefaultOpts;
if (!this.opts.defaultOpts.identifierOpts.resolveOpts?.resolver || typeof this.opts.defaultOpts.identifierOpts.resolveOpts.resolver.resolve !== "function") {
this.opts.defaultOpts.identifierOpts.resolveOpts = {
...this.opts.defaultOpts.identifierOpts.resolveOpts,
resolver: (0, import_ssi_sdk_ext4.getAgentResolver)(context, {
uniresolverResolution: true,
resolverResolution: true,
localResolution: true
})
};
}
}
async createAuthorizationRequestURI(createArgs, context) {
return await this.getRPInstance({
createWhenNotPresent: true,
responseRedirectURI: createArgs.responseRedirectURI,
...createArgs.useQueryIdInstance === true && {
queryId: createArgs.queryId
}
}, context).then((rp) => rp.createAuthorizationRequestURI(createArgs, context)).then((URI) => URI.encodedUri);
}
async createAuthorizationRequestPayloads(createArgs, context) {
return await this.getRPInstance({
createWhenNotPresent: true,
queryId: createArgs.queryId
}, context).then((rp) => rp.createAuthorizationRequest(createArgs, context)).then(async (request) => {
const authRequest = {
authorizationRequest: request.payload,
requestObject: await request.requestObjectJwt(),
requestObjectDecoded: request.requestObject?.getPayload()
};
return authRequest;
});
}
async siopGetRequestState(args, context) {
return await this.getRPInstance({
createWhenNotPresent: false,
queryId: args.queryId
}, context).then((rp) => rp.get(context).then((rp2) => rp2.sessionManager.getRequestStateByCorrelationId(args.correlationId, args.errorOnNotFound)));
}
async siopGetResponseState(args, context) {
const rpInstance = await this.getRPInstance({
createWhenNotPresent: false,
queryId: args.queryId
}, context);
const authorizationResponseState = await rpInstance.get(context).then((rp) => rp.sessionManager.getResponseStateByCorrelationId(args.correlationId, args.errorOnNotFound));
if (authorizationResponseState === void 0) {
return void 0;
}
const responseState = authorizationResponseState;
if (responseState.status === import_did_auth_siop2.AuthorizationResponseStateStatus.VERIFIED) {
let hasher;
if (import_ssi_types2.CredentialMapper.isSdJwtEncoded(responseState.response.payload.vp_token) && (!rpInstance.rpOptions.credentialOpts?.hasher || typeof rpInstance.rpOptions.credentialOpts?.hasher !== "function")) {
hasher = import_ssi_sdk2.shaHasher;
}
const rawVpToken = responseState.response.payload.vp_token;
const vpToken = rawVpToken && (typeof rawVpToken === "string" ? JSON.parse(rawVpToken) : rawVpToken);
const claims = [];
for (const [credentialQueryId, presentationValue] of Object.entries(vpToken)) {
let singleVP;
if (Array.isArray(presentationValue)) {
if (presentationValue.length === 0) {
throw Error(`DCQL query '${credentialQueryId}' has empty array of presentations`);
}
if (presentationValue.length > 1) {
throw Error(`DCQL query '${credentialQueryId}' has multiple presentations (${presentationValue.length}), but only one is supported atm`);
}
singleVP = presentationValue[0];
} else {
singleVP = presentationValue;
}
const presentationDecoded = import_ssi_types2.CredentialMapper.decodeVerifiablePresentation(
singleVP,
//todo: later we want to conditionally pass in options for mdl-mdoc here
hasher
);
console.log(`presentationDecoded: ${JSON.stringify(presentationDecoded)}`);
const allClaims = {};
const presentationOrClaims = this.presentationOrClaimsFrom(presentationDecoded);
if ("verifiableCredential" in presentationOrClaims) {
for (const credential of presentationOrClaims.verifiableCredential) {
const vc = credential;
const schemaValidationResult = await context.agent.cvVerifySchema({
credential,
hasher,
validationPolicy: rpInstance.rpOptions.verificationPolicies?.schemaValidation
});
if (!schemaValidationResult.result) {
responseState.status = import_did_auth_siop2.AuthorizationResponseStateStatus.ERROR;
responseState.error = new Error(schemaValidationResult.error);
return responseState;
}
const credentialSubject = vc.credentialSubject;
if (!("id" in allClaims)) {
allClaims["id"] = credentialSubject.id;
}
Object.entries(credentialSubject).forEach(([key, value]) => {
if (!(key in allClaims)) {
allClaims[key] = value;
}
});
claims.push({
id: credentialQueryId,
type: vc.type[0],
claims: allClaims
});
}
} else {
claims.push({
id: credentialQueryId,
type: presentationDecoded.decodedPayload.vct,
claims: presentationOrClaims
});
}
}
responseState.verifiedData = {
...responseState.response.payload.vp_token && {
authorization_response: {
vp_token: typeof responseState.response.payload.vp_token === "string" ? JSON.parse(responseState.response.payload.vp_token) : responseState.response.payload.vp_token
}
},
...claims.length > 0 && {
credential_claims: claims
}
};
}
return responseState;
}
presentationOrClaimsFrom = /* @__PURE__ */ __name((presentationDecoded) => {
return import_ssi_types2.CredentialMapper.isSdJwtDecodedCredential(presentationDecoded) ? presentationDecoded.decodedPayload : import_ssi_types2.CredentialMapper.toUniformPresentation(presentationDecoded);
}, "presentationOrClaimsFrom");
async siopUpdateRequestState(args, context) {
if (args.state !== "authorization_request_created") {
throw Error(`Only 'authorization_request_created' status is supported for this method at this point`);
}
return await this.getRPInstance({
createWhenNotPresent: false,
queryId: args.queryId
}, context).then((rp) => rp.get(context).then(async (rp2) => {
await rp2.signalAuthRequestRetrieved({
correlationId: args.correlationId,
error: args.error ? new Error(args.error) : void 0
});
return await rp2.sessionManager.getRequestStateByCorrelationId(args.correlationId, true);
}));
}
async siopDeleteState(args, context) {
return await this.getRPInstance({
createWhenNotPresent: false,
queryId: args.queryId
}, context).then((rp) => rp.get(context).then((rp2) => rp2.sessionManager.deleteStateForCorrelationId(args.correlationId))).then(() => true);
}
async siopVerifyAuthResponse(args, context) {
if (!args.authorizationResponse) {
throw Error("No SIOPv2 Authorization Response received");
}
const authResponse = typeof args.authorizationResponse === "string" ? (0, import_did_auth_siop2.decodeUriAsJson)(args.authorizationResponse) : args.authorizationResponse;
return await this.getRPInstance({
createWhenNotPresent: false,
queryId: args.queryId
}, context).then((rp) => rp.get(context).then((rp2) => rp2.verifyAuthorizationResponse(authResponse, {
correlationId: args.correlationId,
...args.dcqlQuery && {
dcqlQuery: args.dcqlQuery
},
audience: args.audience
})));
}
async siopImportDefinitions(args, context) {
const { importItems, tenantId, version, versionControlMode } = args;
await Promise.all(importItems.map(async (importItem) => {
import_dcql.DcqlQuery.validate(importItem.query);
console.log(`persisting DCQL definition ${importItem.queryId} with versionControlMode ${versionControlMode}`);
return context.agent.pdmPersistDefinition({
definitionItem: {
queryId: importItem.queryId,
tenantId,
version,
query: importItem.query
},
opts: {
versionControlMode
}
});
}));
}
async siopGetRedirectURI(args, context) {
const instanceId = args.queryId ?? _SIOPv2RP._DEFAULT_OPTS_KEY;
if (this.instances.has(instanceId)) {
const rpInstance = this.instances.get(instanceId);
if (rpInstance !== void 0) {
const rp = await rpInstance.get(context);
return await rp.getResponseRedirectUri({
correlation_id: args.correlationId,
correlationId: args.correlationId,
...args.state && {
state: args.state
}
});
}
}
return void 0;
}
async getRPInstance({ createWhenNotPresent, queryId, responseRedirectURI }, context) {
let rpInstanceId = _SIOPv2RP._DEFAULT_OPTS_KEY;
let rpInstance;
if (queryId) {
if (this.instances.has(queryId)) {
rpInstanceId = queryId;
rpInstance = this.instances.get(rpInstanceId);
} else if ((0, import_uuid3.validate)(queryId)) {
try {
const pd = await context.agent.pdmGetDefinition({
itemId: queryId
});
if (this.instances.has(pd.queryId)) {
rpInstanceId = pd.queryId;
rpInstance = this.instances.get(rpInstanceId);
}
} catch (ignore) {
}
}
if (createWhenNotPresent) {
rpInstanceId = queryId;
} else {
rpInstance = this.instances.get(rpInstanceId);
}
} else {
rpInstance = this.instances.get(rpInstanceId);
}
if (!rpInstance) {
if (!createWhenNotPresent) {
return Promise.reject(`No RP instance found for key ${rpInstanceId}`);
}
const instanceOpts = this.getInstanceOpts(queryId);
const rpOpts = await this.getRPOptions(context, {
queryId,
responseRedirectURI
});
if (!rpOpts.identifierOpts.resolveOpts?.resolver || typeof rpOpts.identifierOpts.resolveOpts.resolver.resolve !== "function") {
if (!rpOpts.identifierOpts?.resolveOpts) {
rpOpts.identifierOpts = {
...rpOpts.identifierOpts
};
rpOpts.identifierOpts.resolveOpts = {
...rpOpts.identifierOpts.resolveOpts
};
}
console.log("Using agent DID resolver for RP instance with definition id " + queryId);
rpOpts.identifierOpts.resolveOpts.resolver = (0, import_ssi_sdk_ext4.getAgentResolver)(context, {
uniresolverResolution: true,
localResolution: true,
resolverResolution: true
});
}
rpInstance = new RPInstance({
rpOpts,
pexOpts: instanceOpts
});
this.instances.set(rpInstanceId, rpInstance);
}
if (responseRedirectURI) {
rpInstance.rpOptions.responseRedirectUri = responseRedirectURI;
}
return rpInstance;
}
async getRPOptions(context, opts) {
const { queryId, responseRedirectURI } = opts;
const options = this.getInstanceOpts(queryId)?.rpOpts ?? this.opts.defaultOpts;
if (!options) {
throw Error(`Could not get specific nor default options for definition ${queryId}`);
}
if (this.opts.defaultOpts) {
if (!options.identifierOpts) {
options.identifierOpts = this.opts.defaultOpts?.identifierOpts;
} else {
if (!options.identifierOpts.idOpts) {
options.identifierOpts.idOpts = this.opts.defaultOpts.identifierOpts.idOpts;
}
if (!options.identifierOpts.supportedDIDMethods) {
options.identifierOpts.supportedDIDMethods = this.opts.defaultOpts.identifierOpts.supportedDIDMethods;
}
if (!options.supportedVersions) {
options.supportedVersions = this.opts.defaultOpts.supportedVersions;
}
}
if (!options.identifierOpts.resolveOpts || typeof options.identifierOpts.resolveOpts.resolver?.resolve !== "function") {
options.identifierOpts.resolveOpts = {
...this.opts.defaultOpts.identifierOpts.resolveOpts,
resolver: this.opts.defaultOpts.identifierOpts?.resolveOpts?.resolver ?? (0, import_ssi_sdk_ext4.getAgentResolver)(context, {
localResolution: true,
resolverResolution: true,
uniresolverResolution: true
})
};
}
}
if (responseRedirectURI !== void 0 && responseRedirectURI !== options.responseRedirectUri) {
options.responseRedirectUri = responseRedirectURI;
}
return options;
}
getInstanceOpts(queryId) {
if (!this.opts.instanceOpts) return void 0;
const instanceOpt = queryId ? this.opts.instanceOpts.find((i) => i.queryId === queryId) : void 0;
return instanceOpt ?? this.getDefaultOptions(queryId);
}
getDefaultOptions(queryId) {
if (!this.opts.instanceOpts) return void 0;
const defaultOptions = this.opts.instanceOpts.find((i) => i.queryId === "default");
if (defaultOptions) {
const clonedOptions = {
...defaultOptions
};
if (queryId !== void 0) {
clonedOptions.queryId = queryId;
}
return clonedOptions;
}
return void 0;
}
};
//# sourceMappingURL=index.cjs.map