@sphereon/ssi-sdk.siopv2-oid4vp-rp-auth
Version:
990 lines (983 loc) • 37.8 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/SIOPv2RP.ts
import { AuthorizationResponseStateStatus, decodeUriAsJson } from "@sphereon/did-auth-siop";
import { getAgentResolver as getAgentResolver2 } from "@sphereon/ssi-sdk-ext.did-utils";
import { CredentialMapper as CredentialMapper2 } from "@sphereon/ssi-types";
// src/functions.ts
import { InMemoryRPSessionManager, PassBy, PropertyTarget, ResponseMode, ResponseType, RevocationVerification, RP, Scope, SubjectType, SupportedVersion } from "@sphereon/did-auth-siop";
import { SigningAlgo } from "@sphereon/oid4vc-common";
import { getAgentDIDMethods, getAgentResolver } from "@sphereon/ssi-sdk-ext.did-utils";
import { isExternalIdentifierOIDFEntityIdOpts, isManagedIdentifierDidOpts, isManagedIdentifierDidResult, isManagedIdentifierX5cOpts } from "@sphereon/ssi-sdk-ext.identifier-resolution";
import { CredentialMapper } from "@sphereon/ssi-types";
import { EventEmitter } from "events";
import { defaultHasher } from "@sphereon/ssi-sdk.core";
function getRequestVersion(rpOptions) {
if (Array.isArray(rpOptions.supportedVersions) && rpOptions.supportedVersions.length > 0) {
return rpOptions.supportedVersions[0];
}
return SupportedVersion.JWT_VC_PRESENTATION_PROFILE_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 getPresentationVerificationCallback(idOpts, context) {
async function presentationVerificationCallback(args, presentationSubmission) {
if (CredentialMapper.isSdJwtEncoded(args)) {
const result2 = await context.agent.verifySdJwtPresentation({
presentation: args,
kb: true
});
return {
verified: !!result2.payload
};
}
if (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, pexOpts, context } = args;
const { identifierOpts } = rpOpts;
let definition = args.definition;
let dcqlQuery = args.dcql;
if (!definition && pexOpts && pexOpts.definitionId) {
const presentationDefinitionItems = await context.agent.pdmGetDefinitions({
filter: [
{
definitionId: pexOpts.definitionId,
version: pexOpts.version,
tenantId: pexOpts.tenantId
}
]
});
if (presentationDefinitionItems.length > 0) {
const presentationDefinitionItem = presentationDefinitionItems[0];
definition = presentationDefinitionItem.definitionPayload;
if (!dcqlQuery && presentationDefinitionItem.dcqlPayload) {
dcqlQuery = presentationDefinitionItem.dcqlPayload;
}
}
}
const didMethods = identifierOpts.supportedDIDMethods ?? await getAgentDIDMethods(context);
const eventEmitter = rpOpts.eventEmitter ?? new 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: [
SigningAlgo.EDDSA,
SigningAlgo.ES256,
SigningAlgo.ES256K
],
requestObjectSigningAlgValuesSupported: [
SigningAlgo.EDDSA,
SigningAlgo.ES256,
SigningAlgo.ES256K
],
responseTypesSupported: [
ResponseType.ID_TOKEN
],
client_name: "Sphereon",
vpFormatsSupported: {
jwt_vc: {
alg: [
"EdDSA",
"ES256K"
]
},
jwt_vp: {
alg: [
"ES256K",
"EdDSA"
]
}
},
scopesSupported: [
Scope.OPENID_DIDAUTHN
],
subjectTypesSupported: [
SubjectType.PAIRWISE
],
subject_syntax_types_supported: didMethods.map((method) => `did:${method}`),
passBy: PassBy.VALUE
};
const resolver = rpOpts.identifierOpts.resolveOpts?.resolver ?? 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 = defaultHasher;
}
const builder = RP.builder({
requestVersion: getRequestVersion(rpOpts)
}).withScope("openid", PropertyTarget.REQUEST_OBJECT).withResponseMode(rpOpts.responseMode ?? ResponseMode.POST).withResponseType(ResponseType.VP_TOKEN, PropertyTarget.REQUEST_OBJECT).withSupportedVersions(rpOpts.supportedVersions ?? [
SupportedVersion.JWT_VC_PRESENTATION_PROFILE_v1,
SupportedVersion.SIOPv2_ID1,
SupportedVersion.SIOPv2_D11
]).withEventEmitter(eventEmitter).withSessionManager(rpOpts.sessionManager ?? new InMemoryRPSessionManager(eventEmitter)).withClientMetadata(rpOpts.clientMetadataOpts ?? defaultClientMetadata, PropertyTarget.REQUEST_OBJECT).withVerifyJwtCallback(rpOpts.verifyJwtCallback ? rpOpts.verifyJwtCallback : getVerifyJwtCallback({
resolver,
verifyOpts: {
wellknownDIDVerifyCallback: getWellKnownDIDVerifyCallback(rpOpts.identifierOpts, context),
checkLinkedDomain: "if_present"
}
}, context)).withRevocationVerification(RevocationVerification.NEVER).withPresentationVerification(getPresentationVerificationCallback(identifierOpts.idOpts, context));
const oidfOpts = identifierOpts.oidfOpts;
if (oidfOpts && isExternalIdentifierOIDFEntityIdOpts(oidfOpts)) {
builder.withEntityId(oidfOpts.identifier, PropertyTarget.REQUEST_OBJECT).withClientIdScheme("entity_id", PropertyTarget.REQUEST_OBJECT);
} else {
const resolution = await context.agent.identifierManagedGet(identifierOpts.idOpts);
builder.withClientId(resolution.issuer ?? (isManagedIdentifierDidResult(resolution) ? resolution.did : resolution.jwkThumbprint), PropertyTarget.REQUEST_OBJECT).withClientIdScheme(resolution.clientIdScheme ?? identifierOpts.idOpts.clientIdScheme, PropertyTarget.REQUEST_OBJECT);
}
if (hasher) {
builder.withHasher(hasher);
}
if (definition) {
builder.withPresentationDefinition({
definition
}, PropertyTarget.REQUEST_OBJECT);
}
if (dcqlQuery) {
builder.withDcqlQuery(dcqlQuery);
}
if (rpOpts.responseRedirectUri) {
builder.withResponseRedirectUri(rpOpts.responseRedirectUri);
}
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 (!(isManagedIdentifierDidOpts(idOpts) || 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 SigningAlgo.EDDSA;
case "Secp256k1":
return SigningAlgo.ES256K;
case "Secp256r1":
return SigningAlgo.ES256;
// @ts-ignore
case "RSA":
return SigningAlgo.RS256;
default:
throw Error("Key type not yet supported");
}
}
__name(getSigningAlgo, "getSigningAlgo");
// src/RPInstance.ts
import { v4 as uuidv4 } from "uuid";
import { ensureManagedIdentifierResult, isManagedIdentifierDidResult as isManagedIdentifierDidResult2, isManagedIdentifierX5cResult } from "@sphereon/ssi-sdk-ext.identifier-resolution";
var RPInstance = class {
static {
__name(this, "RPInstance");
}
_rp;
_pexOptions;
_rpOptions;
constructor({ rpOpts, pexOpts }) {
this._rpOptions = rpOpts;
this._pexOptions = pexOpts;
}
async get(context) {
if (!this._rp) {
const builder = await createRPBuilder({
rpOpts: this._rpOptions,
pexOpts: this._pexOptions,
context
});
this._rp = builder.build();
}
return this._rp;
}
get rpOptions() {
return this._rpOptions;
}
get pexOptions() {
return this._pexOptions;
}
hasDefinition() {
return this.definitionId !== void 0;
}
get definitionId() {
return this.pexOptions?.definitionId;
}
async getPresentationDefinition(context) {
return this.definitionId ? await context.agent.pexStoreGetDefinition({
definitionId: this.definitionId,
tenantId: this.pexOptions?.tenantId
}) : void 0;
}
async createAuthorizationRequestURI(createArgs, context) {
const { correlationId, claims, requestByReferenceURI, responseURI, responseURIType } = createArgs;
const nonce = createArgs.nonce ?? uuidv4();
const state = createArgs.state ?? correlationId;
let jwtIssuer;
const idOpts = this.rpOptions.identifierOpts.idOpts;
const resolution = await ensureManagedIdentifierResult(idOpts, context);
if (isManagedIdentifierDidResult2(resolution)) {
jwtIssuer = {
didUrl: resolution.kid,
method: "did",
alg: getSigningAlgo(resolution.key.type)
};
} else if (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,
nonce,
state,
claims,
requestByReferenceURI,
responseURI,
responseURIType,
jwtIssuer
}));
}
async createAuthorizationRequest(createArgs, context) {
const { correlationId, claims, requestByReferenceURI, responseURI, responseURIType } = createArgs;
const nonce = createArgs.nonce ?? uuidv4();
const state = createArgs.state ?? correlationId;
const idOpts = this.rpOptions.identifierOpts.idOpts;
const resolution = await ensureManagedIdentifierResult(idOpts, context);
let jwtIssuer;
if (isManagedIdentifierX5cResult(resolution) && resolution.issuer) {
jwtIssuer = {
method: resolution.method,
alg: getSigningAlgo(resolution.key.type),
x5c: resolution.x5c,
issuer: resolution.issuer
};
} else if (isManagedIdentifierDidResult2(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
}));
}
};
// src/agent/SIOPv2RP.ts
import { shaHasher as defaultHasher2 } from "@sphereon/ssi-sdk.core";
var SIOPv2RP = class _SIOPv2RP {
static {
__name(this, "SIOPv2RP");
}
opts;
static _DEFAULT_OPTS_KEY = "_default";
instances = /* @__PURE__ */ new Map();
schema = schema.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: getAgentResolver2(context, {
uniresolverResolution: true,
resolverResolution: true,
localResolution: true
})
};
}
}
async createAuthorizationRequestURI(createArgs, context) {
return await this.getRPInstance({
definitionId: createArgs.definitionId,
responseRedirectURI: createArgs.responseRedirectURI
}, context).then((rp) => rp.createAuthorizationRequestURI(createArgs, context)).then((URI) => URI.encodedUri);
}
async createAuthorizationRequestPayloads(createArgs, context) {
return await this.getRPInstance({
definitionId: createArgs.definitionId
}, context).then((rp) => rp.createAuthorizationRequest(createArgs, context)).then(async (request) => {
const authRequest = {
authorizationRequest: request.payload,
requestObject: await request.requestObjectJwt(),
requestObjectDecoded: await request.requestObject?.getPayload()
};
return authRequest;
});
}
async siopGetRequestState(args, context) {
return await this.getRPInstance({
definitionId: args.definitionId
}, context).then((rp) => rp.get(context).then((rp2) => rp2.sessionManager.getRequestStateByCorrelationId(args.correlationId, args.errorOnNotFound)));
}
async siopGetResponseState(args, context) {
const rpInstance = await this.getRPInstance({
definitionId: args.definitionId
}, 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 === AuthorizationResponseStateStatus.VERIFIED && args.includeVerifiedData && args.includeVerifiedData !== VerifiedDataMode.NONE) {
let hasher;
if (CredentialMapper2.isSdJwtEncoded(responseState.response.payload.vp_token) && (!rpInstance.rpOptions.credentialOpts?.hasher || typeof rpInstance.rpOptions.credentialOpts?.hasher !== "function")) {
hasher = defaultHasher2;
}
const presentationDecoded = CredentialMapper2.decodeVerifiablePresentation(
responseState.response.payload.vp_token,
//todo: later we want to conditionally pass in options for mdl-mdoc here
hasher
);
switch (args.includeVerifiedData) {
case VerifiedDataMode.VERIFIED_PRESENTATION:
responseState.response.payload.verifiedData = this.presentationOrClaimsFrom(presentationDecoded);
break;
case VerifiedDataMode.CREDENTIAL_SUBJECT_FLATTENED:
const allClaims = {};
for (const credential of this.presentationOrClaimsFrom(presentationDecoded).verifiableCredential || []) {
const vc = credential;
const schemaValidationResult = await context.agent.cvVerifySchema({
credential,
hasher,
validationPolicy: rpInstance.rpOptions.verificationPolicies?.schemaValidation
});
if (!schemaValidationResult.result) {
responseState.status = 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;
}
});
}
responseState.verifiedData = allClaims;
break;
}
}
return responseState;
}
presentationOrClaimsFrom = /* @__PURE__ */ __name((presentationDecoded) => CredentialMapper2.isSdJwtDecodedCredential(presentationDecoded) ? presentationDecoded.decodedPayload : CredentialMapper2.toUniformPresentation(presentationDecoded), "presentationOrClaimsFrom");
async siopUpdateRequestState(args, context) {
if (args.state !== "sent") {
throw Error(`Only 'sent' status is supported for this method at this point`);
}
return await this.getRPInstance({
definitionId: args.definitionId
}, 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({
definitionId: args.definitionId
}, 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" ? decodeUriAsJson(args.authorizationResponse) : args.authorizationResponse;
return await this.getRPInstance({
definitionId: args.definitionId
}, context).then((rp) => rp.get(context).then((rp2) => rp2.verifyAuthorizationResponse(authResponse, {
correlationId: args.correlationId,
...args.presentationDefinitions && !args.dcqlQuery ? {
presentationDefinitions: args.presentationDefinitions
} : {},
...args.dcqlQuery ? {
dcqlQuery: args.dcqlQuery
} : {},
audience: args.audience
})));
}
async siopImportDefinitions(args, context) {
const { definitions, tenantId, version, versionControlMode } = args;
await Promise.all(definitions.map(async (definitionPair) => {
const definitionPayload = definitionPair.definitionPayload;
await context.agent.pexValidateDefinition({
definition: definitionPayload
});
console.log(`persisting definition ${definitionPayload.id} / ${definitionPayload.name} with versionControlMode ${versionControlMode}`);
return context.agent.pdmPersistDefinition({
definitionItem: {
tenantId,
version,
definitionPayload,
dcqlPayload: definitionPair.dcqlPayload
},
opts: {
versionControlMode
}
});
}));
}
async siopGetRedirectURI(args, context) {
const instanceId = args.definitionId ?? _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 rp.getResponseRedirectUri({
correlation_id: args.correlationId,
correlationId: args.correlationId,
...args.state && {
state: args.state
}
});
}
}
return void 0;
}
async getRPInstance({ definitionId, responseRedirectURI }, context) {
const instanceId = definitionId ?? _SIOPv2RP._DEFAULT_OPTS_KEY;
if (!this.instances.has(instanceId)) {
const instanceOpts = this.getInstanceOpts(definitionId);
const rpOpts = await this.getRPOptions(context, {
definitionId,
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 " + definitionId);
rpOpts.identifierOpts.resolveOpts.resolver = getAgentResolver2(context, {
uniresolverResolution: true,
localResolution: true,
resolverResolution: true
});
}
this.instances.set(instanceId, new RPInstance({
rpOpts,
pexOpts: instanceOpts
}));
}
const rpInstance = this.instances.get(instanceId);
if (responseRedirectURI) {
rpInstance.rpOptions.responseRedirectUri = responseRedirectURI;
}
return rpInstance;
}
async getRPOptions(context, opts) {
const { definitionId, responseRedirectURI } = opts;
const options = this.getInstanceOpts(definitionId)?.rpOpts ?? this.opts.defaultOpts;
if (!options) {
throw Error(`Could not get specific nor default options for definition ${definitionId}`);
}
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 ?? getAgentResolver2(context, {
localResolution: true,
resolverResolution: true,
uniresolverResolution: true
})
};
}
}
if (responseRedirectURI !== void 0 && responseRedirectURI !== options.responseRedirectUri) {
options.responseRedirectUri = responseRedirectURI;
}
return options;
}
getInstanceOpts(definitionId) {
if (!this.opts.instanceOpts) return void 0;
const instanceOpt = definitionId ? this.opts.instanceOpts.find((i) => i.definitionId === definitionId) : void 0;
return instanceOpt ?? this.getDefaultOptions(definitionId);
}
getDefaultOptions(definitionId) {
if (!this.opts.instanceOpts) return void 0;
const defaultOptions = this.opts.instanceOpts.find((i) => i.definitionId === "default");
if (defaultOptions) {
const clonedOptions = {
...defaultOptions
};
if (definitionId !== void 0) {
clonedOptions.definitionId = definitionId;
}
return clonedOptions;
}
return void 0;
}
};
// src/types/ISIOPv2RP.ts
var VerifiedDataMode = /* @__PURE__ */ function(VerifiedDataMode2) {
VerifiedDataMode2["NONE"] = "none";
VerifiedDataMode2["VERIFIED_PRESENTATION"] = "vp";
VerifiedDataMode2["CREDENTIAL_SUBJECT_FLATTENED"] = "cs-flat";
return VerifiedDataMode2;
}({});
// src/index.ts
var schema = require_plugin_schema();
export {
SIOPv2RP,
VerifiedDataMode,
schema
};
//# sourceMappingURL=index.js.map