@sphereon/ssi-sdk.siopv2-oid4vp-rp-auth
Version:
243 lines • 14 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRequestVersion = getRequestVersion;
exports.getPresentationVerificationCallback = getPresentationVerificationCallback;
exports.createRPBuilder = createRPBuilder;
exports.signCallback = signCallback;
exports.createRP = createRP;
exports.getSigningAlgo = getSigningAlgo;
const did_auth_siop_1 = require("@sphereon/did-auth-siop");
const oid4vc_common_1 = require("@sphereon/oid4vc-common");
const ssi_sdk_ext_did_utils_1 = require("@sphereon/ssi-sdk-ext.did-utils");
const ssi_sdk_ext_identifier_resolution_1 = require("@sphereon/ssi-sdk-ext.identifier-resolution");
const ssi_types_1 = require("@sphereon/ssi-types");
const events_1 = require("events");
const ssi_sdk_core_1 = require("@sphereon/ssi-sdk.core");
function getRequestVersion(rpOptions) {
if (Array.isArray(rpOptions.supportedVersions) && rpOptions.supportedVersions.length > 0) {
return rpOptions.supportedVersions[0];
}
return did_auth_siop_1.SupportedVersion.JWT_VC_PRESENTATION_PROFILE_v1;
}
function getWellKnownDIDVerifyCallback(siopIdentifierOpts, context) {
return siopIdentifierOpts.wellknownDIDVerifyCallback
? siopIdentifierOpts.wellknownDIDVerifyCallback
: (args) => __awaiter(this, void 0, void 0, function* () {
const result = yield context.agent.cvVerifyCredential({
credential: args.credential,
fetchRemoteContexts: true,
});
return { verified: result.result };
});
}
function getPresentationVerificationCallback(idOpts, context) {
function presentationVerificationCallback(args, // FIXME any
presentationSubmission) {
return __awaiter(this, void 0, void 0, function* () {
var _a;
if (ssi_types_1.CredentialMapper.isSdJwtEncoded(args)) {
const result = yield context.agent.verifySdJwtPresentation({
presentation: args,
kb: true,
});
// fixme: investigate the correct way to handle this
return { verified: !!result.payload };
}
if (ssi_types_1.CredentialMapper.isMsoMdocOid4VPEncoded(args)) {
// TODO Funke reevaluate
if (context.agent.mdocOid4vpRPVerify === undefined) {
return Promise.reject('ImDLMdoc agent plugin must be enabled to support MsoMdoc types');
}
if (presentationSubmission !== undefined && presentationSubmission !== null) {
const verifyResult = yield context.agent.mdocOid4vpRPVerify({
vp_token: args,
presentation_submission: presentationSubmission,
});
return { verified: !verifyResult.error };
}
throw Error(`mdocOid4vpRPVerify(...) method requires a presentation submission`);
}
const result = yield context.agent.verifyPresentation({
presentation: args,
fetchRemoteContexts: true,
domain: (_a = (yield context.agent.identifierManagedGet(idOpts)).kid) === null || _a === void 0 ? void 0 : _a.split('#')[0],
});
return { verified: result.verified };
});
}
return presentationVerificationCallback;
}
function createRPBuilder(args) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
const { rpOpts, pexOpts, context } = args;
const { identifierOpts } = rpOpts;
let definition = args.definition;
let dcqlQuery = args.dcql;
if (!definition && pexOpts && pexOpts.definitionId) {
const presentationDefinitionItems = yield 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; // cast from DcqlQueryREST back to valibot DcqlQuery
}
}
}
const didMethods = (_a = identifierOpts.supportedDIDMethods) !== null && _a !== void 0 ? _a : (yield (0, ssi_sdk_ext_did_utils_1.getAgentDIDMethods)(context));
const eventEmitter = (_b = rpOpts.eventEmitter) !== null && _b !== void 0 ? _b : new events_1.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: [oid4vc_common_1.SigningAlgo.EDDSA, oid4vc_common_1.SigningAlgo.ES256, oid4vc_common_1.SigningAlgo.ES256K], // added newly
requestObjectSigningAlgValuesSupported: [oid4vc_common_1.SigningAlgo.EDDSA, oid4vc_common_1.SigningAlgo.ES256, oid4vc_common_1.SigningAlgo.ES256K], // added newly
responseTypesSupported: [did_auth_siop_1.ResponseType.ID_TOKEN], // added newly
client_name: 'Sphereon',
vpFormatsSupported: {
jwt_vc: { alg: ['EdDSA', 'ES256K'] },
jwt_vp: { alg: ['ES256K', 'EdDSA'] },
},
scopesSupported: [did_auth_siop_1.Scope.OPENID_DIDAUTHN],
subjectTypesSupported: [did_auth_siop_1.SubjectType.PAIRWISE],
subject_syntax_types_supported: didMethods.map((method) => `did:${method}`),
passBy: did_auth_siop_1.PassBy.VALUE,
};
const resolver = (_d = (_c = rpOpts.identifierOpts.resolveOpts) === null || _c === void 0 ? void 0 : _c.resolver) !== null && _d !== void 0 ? _d : (0, ssi_sdk_ext_did_utils_1.getAgentResolver)(context, {
resolverResolution: true,
localResolution: true,
uniresolverResolution: ((_e = rpOpts.identifierOpts.resolveOpts) === null || _e === void 0 ? void 0 : _e.noUniversalResolverFallback) !== true,
});
//todo: probably wise to first look and see if we actually need the hasher to begin with
let hasher = (_f = rpOpts.credentialOpts) === null || _f === void 0 ? void 0 : _f.hasher;
if (!((_g = rpOpts.credentialOpts) === null || _g === void 0 ? void 0 : _g.hasher) || typeof ((_h = rpOpts.credentialOpts) === null || _h === void 0 ? void 0 : _h.hasher) !== 'function') {
hasher = ssi_sdk_core_1.defaultHasher;
}
const builder = did_auth_siop_1.RP.builder({ requestVersion: getRequestVersion(rpOpts) })
.withScope('openid', did_auth_siop_1.PropertyTarget.REQUEST_OBJECT)
.withResponseMode((_j = rpOpts.responseMode) !== null && _j !== void 0 ? _j : did_auth_siop_1.ResponseMode.POST)
.withResponseType(did_auth_siop_1.ResponseType.VP_TOKEN, did_auth_siop_1.PropertyTarget.REQUEST_OBJECT)
// todo: move to options fill/correct method
.withSupportedVersions((_k = rpOpts.supportedVersions) !== null && _k !== void 0 ? _k : [did_auth_siop_1.SupportedVersion.JWT_VC_PRESENTATION_PROFILE_v1, did_auth_siop_1.SupportedVersion.SIOPv2_ID1, did_auth_siop_1.SupportedVersion.SIOPv2_D11])
.withEventEmitter(eventEmitter)
.withSessionManager((_l = rpOpts.sessionManager) !== null && _l !== void 0 ? _l : new did_auth_siop_1.InMemoryRPSessionManager(eventEmitter))
.withClientMetadata((_m = rpOpts.clientMetadataOpts) !== null && _m !== void 0 ? _m : defaultClientMetadata, did_auth_siop_1.PropertyTarget.REQUEST_OBJECT)
.withVerifyJwtCallback(rpOpts.verifyJwtCallback
? rpOpts.verifyJwtCallback
: getVerifyJwtCallback({
resolver,
verifyOpts: {
wellknownDIDVerifyCallback: getWellKnownDIDVerifyCallback(rpOpts.identifierOpts, context),
checkLinkedDomain: 'if_present',
},
}, context))
.withRevocationVerification(did_auth_siop_1.RevocationVerification.NEVER)
.withPresentationVerification(getPresentationVerificationCallback(identifierOpts.idOpts, context));
const oidfOpts = identifierOpts.oidfOpts;
if (oidfOpts && (0, ssi_sdk_ext_identifier_resolution_1.isExternalIdentifierOIDFEntityIdOpts)(oidfOpts)) {
builder.withEntityId(oidfOpts.identifier, did_auth_siop_1.PropertyTarget.REQUEST_OBJECT).withClientIdScheme('entity_id', did_auth_siop_1.PropertyTarget.REQUEST_OBJECT);
}
else {
const resolution = yield context.agent.identifierManagedGet(identifierOpts.idOpts);
builder
.withClientId((_o = resolution.issuer) !== null && _o !== void 0 ? _o : ((0, ssi_sdk_ext_identifier_resolution_1.isManagedIdentifierDidResult)(resolution) ? resolution.did : resolution.jwkThumbprint), did_auth_siop_1.PropertyTarget.REQUEST_OBJECT)
.withClientIdScheme((_p = resolution.clientIdScheme) !== null && _p !== void 0 ? _p : identifierOpts.idOpts.clientIdScheme, did_auth_siop_1.PropertyTarget.REQUEST_OBJECT);
}
if (hasher) {
builder.withHasher(hasher);
}
//fixme: this has been removed in the new version of did-auth-siop
/*if (!rpOpts.clientMetadataOpts?.subjectTypesSupported) {
// Do not update in case it is already provided via client metadata opts
didMethods.forEach((method) => builder.addDidMethod(method))
}*/
//fixme: this has been removed in the new version of did-auth-siop
// builder.withWellknownDIDVerifyCallback(getWellKnownDIDVerifyCallback(didOpts, context))
if (definition) {
builder.withPresentationDefinition({ definition }, did_auth_siop_1.PropertyTarget.REQUEST_OBJECT);
}
if (dcqlQuery) {
builder.withDcqlQuery(dcqlQuery);
}
if (rpOpts.responseRedirectUri) {
builder.withResponseRedirectUri(rpOpts.responseRedirectUri);
}
//const key = resolution.key
//fixme: this has been removed in the new version of did-auth-siop
//builder.withSuppliedSignature(SuppliedSigner(key, context, getSigningAlgo(key.type) as unknown as KeyAlgo), did, kid, getSigningAlgo(key.type))
/*if (isManagedIdentifierDidResult(resolution)) {
//fixme: only accepts dids in version used. New SIOP lib also accepts other types
builder.withSuppliedSignature(
SuppliedSigner(key, context, getSigningAlgo(key.type) as unknown as KeyAlgo),
resolution.did,
resolution.kid,
getSigningAlgo(key.type),
)
}*/
//fixme: signcallback and it's return type are not totally compatible with our CreateJwtCallbackBase
const createJwtCallback = signCallback(rpOpts.identifierOpts.idOpts, context);
builder.withCreateJwtCallback(createJwtCallback);
return builder;
});
}
function signCallback(idOpts, context) {
return (jwtIssuer, jwt, kid) => __awaiter(this, void 0, void 0, function* () {
if (!((0, ssi_sdk_ext_identifier_resolution_1.isManagedIdentifierDidOpts)(idOpts) || (0, ssi_sdk_ext_identifier_resolution_1.isManagedIdentifierX5cOpts)(idOpts))) {
return Promise.reject(Error(`JWT issuer method ${jwtIssuer.method} not yet supported`));
}
const result = yield 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;
});
}
function getVerifyJwtCallback(_opts, context) {
return (_jwtVerifier, jwt) => __awaiter(this, void 0, void 0, function* () {
const result = yield context.agent.jwtVerifyJwsSignature({ jws: jwt.raw });
console.log(result.message);
return !result.error;
});
}
function createRP(_a) {
return __awaiter(this, arguments, void 0, function* ({ rpOptions, context }) {
return (yield createRPBuilder({ rpOpts: rpOptions, context })).build();
});
}
function getSigningAlgo(type) {
switch (type) {
case 'Ed25519':
return oid4vc_common_1.SigningAlgo.EDDSA;
case 'Secp256k1':
return oid4vc_common_1.SigningAlgo.ES256K;
case 'Secp256r1':
return oid4vc_common_1.SigningAlgo.ES256;
// @ts-ignore
case 'RSA':
return oid4vc_common_1.SigningAlgo.RS256;
default:
throw Error('Key type not yet supported');
}
}
//# sourceMappingURL=functions.js.map