UNPKG

@animo-id/pex

Version:

A Typescript implementation of the v1 and v2 DIF Presentation Exchange specification

109 lines 15.3 kB
import { JSONPath as jp } from '@astronautlabs/jsonpath'; import { Optionality } from '@sphereon/pex-models'; import { Status } from '../../ConstraintUtils'; import { AbstractEvaluationHandler } from './abstractEvaluationHandler'; export class SubjectIsHolderEvaluationHandler extends AbstractEvaluationHandler { fieldIdzInputDescriptorsSameSubjectRequired; fieldIdzInputDescriptorsSameSubjectPreferred; fieldIds; isHolder; credentialsSubjectsByPath; credentialsByPath; messages; constructor(client) { super(client); this.fieldIdzInputDescriptorsSameSubjectRequired = new Map(); this.fieldIdzInputDescriptorsSameSubjectPreferred = new Map(); this.isHolder = []; this.fieldIds = []; this.credentialsSubjectsByPath = new Map(); this.credentialsByPath = new Map(); this.messages = new Map(); this.messages.set(Status.INFO, 'The field ids requiring the subject to be the holder'); this.messages.set(Status.WARN, 'The field ids preferring the subject to be the holder'); this.messages.set(Status.ERROR, 'The field id missing'); } getName() { return 'IsHolderEvaluation'; } handle(pd, wrappedVcs) { this.findIsHolderFieldIdsToInputDescriptorsSets(pd); this.findAllCredentialSubjects(wrappedVcs); this.confirmAllFieldSetHasSameSubject(this.fieldIdzInputDescriptorsSameSubjectRequired, Status.INFO, Optionality.Required); this.confirmAllFieldSetHasSameSubject(this.fieldIdzInputDescriptorsSameSubjectPreferred, Status.WARN, Optionality.Preferred); this.updatePresentationSubmission(pd); } /** * We have input descriptor to field ids mapping. This function gets a (reverse) map from field id to input descriptor */ findIsHolderFieldIdsToInputDescriptorsSets(pd) { this.fieldIds.push(...jp.nodes(pd, '$..fields[*].id')); this.isHolder.push(...jp.nodes(pd, '$..is_holder[*]')); const fields = this.fieldIds?.map((n) => n.value); const error = []; error.push(...this.evaluateFields(this.fieldIdzInputDescriptorsSameSubjectPreferred, this.isHolder, fields, Optionality.Preferred)); error.push(...this.evaluateFields(this.fieldIdzInputDescriptorsSameSubjectRequired, this.isHolder, fields, Optionality.Required)); error.forEach((q) => this.getResults().push(this.createResult(q[1], q[0], ['', {}], Status.ERROR, undefined))); } evaluateFields(fieldsMapping, isHolder, fields, directive) { const error = []; isHolder .filter((d) => d.value.directive === directive) .filter((e) => e.value.field_id.every((id) => fields.includes(id))) .forEach((p) => fieldsMapping.set(jp.stringify(p.path.slice(0, 3)), p.value.field_id)); isHolder .filter((d) => d.value.directive === directive) .filter((e) => !e.value.field_id.every((id) => fields.includes(id))) .forEach((p) => error.push([jp.stringify(p.path.slice(0, 3)), p.value.field_id])); return error; } findAllCredentialSubjects(wrappedVcs) { //TODO handle nested path const credentialSubjects = jp.nodes(wrappedVcs.map((wvc) => wvc.credential), '$..credentialSubject'); for (let idx = 0; idx < credentialSubjects.length; idx++) { const cs = credentialSubjects[idx]; const path = jp.stringify(cs.path.slice(0, 2)); this.credentialsSubjectsByPath.set(path, cs.value); this.credentialsByPath.set(path, wrappedVcs[idx]); } } confirmAllFieldSetHasSameSubject(fieldIdsInputDescriptorsGroups, status, directive) { const subjectsMatchingFields = Array.from(fieldIdsInputDescriptorsGroups).flatMap((k) => Array.from(this.credentialsSubjectsByPath).filter((a) => k[1].find((c) => Object.keys(a[1]).includes(c)))); const credentialPathsToInputDescriptors = this.mapCredentialPathsToInputDescriptors(directive); const fields = Array.from(subjectsMatchingFields).flatMap((s) => Object.keys(s[1]).filter((w) => w !== 'id')); const allFieldsMatched = Array.from(fieldIdsInputDescriptorsGroups.values()).flatMap((v) => v.every((e) => fields.includes(e)))[0]; subjectsMatchingFields.forEach((subject) => { const inDescPath = credentialPathsToInputDescriptors.get(subject[0]); if (allFieldsMatched && subject[1].id && this.client.dids.includes(subject[1].id)) { this.getResults().push(this.createResult(Object.keys(subject[1]).filter((k) => k !== 'id'), inDescPath, subject, status, this.credentialsByPath.get(subject[0]))); } else { this.getResults().push(this.createResult(Object.keys(subject[1]).filter((k) => k !== 'id'), inDescPath, subject, Status.ERROR, this.credentialsByPath.get(subject[0]))); } }); } mapCredentialPathsToInputDescriptors(directive) { const credentialsToInputDescriptors = new Map(); this.fieldIds?.forEach((id) => { const inDescPath = jp.stringify(id.path.slice(0, 3)); this.credentialsSubjectsByPath.forEach((cs, credentialPath) => { const hs = this.isHolder.find((e) => jp.stringify(e.path.slice(0, 3)) === inDescPath); if (Object.keys(cs).includes(id.value) && hs?.value.directive === directive) { credentialsToInputDescriptors.set(credentialPath, inDescPath); } }); }); return credentialsToInputDescriptors; } createResult(fieldIdSet, inputDescriptorPath, credentialSub, myStatus, wvc, message) { return { input_descriptor_path: inputDescriptorPath, verifiable_credential_path: credentialSub[0], evaluator: this.getName(), status: myStatus, payload: { fieldIdSet, credentialSubject: credentialSub[1], ...(wvc ? { format: wvc.format } : {}) }, message: message ?? this.messages.get(myStatus), }; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3ViamVjdElzSG9sZGVyRXZhbHVhdGlvbkhhbmRsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWIvZXZhbHVhdGlvbi9oYW5kbGVycy9zdWJqZWN0SXNIb2xkZXJFdmFsdWF0aW9uSGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxJQUFJLEVBQUUsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3pELE9BQU8sRUFBaUIsV0FBVyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFHbEUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBTS9DLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBRXhFLE1BQU0sT0FBTyxnQ0FBaUMsU0FBUSx5QkFBeUI7SUFDNUQsMkNBQTJDLENBQXdCO0lBQ25FLDRDQUE0QyxDQUF3QjtJQUNwRSxRQUFRLENBQTZDO0lBQ3JELFFBQVEsQ0FBb0Q7SUFFckUseUJBQXlCLENBQWtDO0lBQzNELGlCQUFpQixDQUEyQztJQUU1RCxRQUFRLENBQXNCO0lBRXRDLFlBQVksTUFBd0I7UUFDbEMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRWQsSUFBSSxDQUFDLDJDQUEyQyxHQUFHLElBQUksR0FBRyxFQUFvQixDQUFDO1FBQy9FLElBQUksQ0FBQyw0Q0FBNEMsR0FBRyxJQUFJLEdBQUcsRUFBb0IsQ0FBQztRQUNoRixJQUFJLENBQUMsUUFBUSxHQUFHLEVBQUUsQ0FBQztRQUNuQixJQUFJLENBQUMsUUFBUSxHQUFHLEVBQUUsQ0FBQztRQUNuQixJQUFJLENBQUMseUJBQXlCLEdBQUcsSUFBSSxHQUFHLEVBQThCLENBQUM7UUFDdkUsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksR0FBRyxFQUF1QyxDQUFDO1FBRXhFLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7UUFDMUMs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