Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into feature/funke-mdoc
Browse files Browse the repository at this point in the history
# Conflicts:
#	test/SdJwt.spec.ts
  • Loading branch information
sanderPostma committed Sep 17, 2024
2 parents 466539b + 6023f0e commit 46af7d8
Show file tree
Hide file tree
Showing 13 changed files with 424 additions and 67 deletions.
26 changes: 26 additions & 0 deletions lib/evaluation/core/submissionRequirementMatch.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,32 @@
import { Rules } from '@sphereon/pex-models';

export enum SubmissionRequirementMatchType {
/**
* Match for a submission_requirements entry in the presentation definition. If the match type
* is `SubmissionRequirement` the {@link SubmissionRequirementMatch.id} property refers to the index
* of the `submission_requirements` entry in the presentation definition.
*
* If the match is a nested match result, this match type refers to the nested index. E.g. a presentation
* definition has three `submission_requirements` entries where the second submission requirement (index 1)
* has two `from_nested` `submission_requirements` entries and this match refers to the second (index 1) of
* this from nested, the {@link SubmissionRequirementMatch.id} property of the outer match refers to the outer index
* in the `submission_requirements` entries, and the nested {@link SubmissionRequirementMatch.id} refers to index of the
* `from_nested` entries. This can go multiple layers deep.
*/
SubmissionRequirement = 'SubmissionRequirement',

/**
* Match for an input_descriptors entry in the presentation definition. This type will be used
* if no submission_requirements are present in the presentation definition. If the match type
* is `InputDescriptor` the {@link SubmissionRequirementMatch.id} property refers to the `id`
* of the `input_descriptors` entry in the presentation definition.
*/
InputDescriptor = 'InputDescriptor',
}

export interface SubmissionRequirementMatch {
type: SubmissionRequirementMatchType;
id: string | number;
name?: string;
rule: Rules;
min?: number;
Expand Down
69 changes: 39 additions & 30 deletions lib/evaluation/evaluationClientWrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,14 @@ import {
import { JsonPathUtils, ObjectUtils } from '../utils';
import { getVpFormatForVcFormat } from '../utils/formatMap';

import { EvaluationResults, HandlerCheckResult, PresentationEvaluationResults, SelectResults, SubmissionRequirementMatch } from './core';
import {
EvaluationResults,
HandlerCheckResult,
PresentationEvaluationResults,
SelectResults,
SubmissionRequirementMatch,
SubmissionRequirementMatchType,
} from './core';
import { EvaluationClient } from './evaluationClient';

interface SubmissionSatisfiesSubmissionRequirementResult {
Expand Down Expand Up @@ -252,13 +259,17 @@ export class EvaluationClientWrapper {
marked: HandlerCheckResult[],
): SubmissionRequirementMatch[] {
const submissionRequirementMatches: SubmissionRequirementMatch[] = [];
for (const sr of submissionRequirements) {
for (const [srIndex, sr] of Object.entries(submissionRequirements)) {
// Create a default SubmissionRequirementMatch object
const srm: SubmissionRequirementMatch = {
name: pd.name || pd.id,
rule: sr.rule,
vc_path: [],

name: sr.name,
type: SubmissionRequirementMatchType.SubmissionRequirement,
id: Number(srIndex),
};

if (sr.from) {
srm.from = sr.from;
}
Expand All @@ -268,12 +279,9 @@ export class EvaluationClientWrapper {
sr.count ? (srm.count = sr.count) : undefined;

if (sr.from) {
const matchingDescriptors = this.mapMatchingDescriptors(pd, sr, marked);
if (matchingDescriptors) {
srm.vc_path.push(...matchingDescriptors.vc_path);
srm.name = matchingDescriptors.name;
submissionRequirementMatches.push(srm);
}
const matchingVcPaths = this.getMatchingVcPathsForSubmissionRequirement(pd, sr, marked);
srm.vc_path.push(...matchingVcPaths);
submissionRequirementMatches.push(srm);
} else if (sr.from_nested) {
// Recursive call to matchSubmissionRequirements for nested requirements
try {
Expand All @@ -298,42 +306,43 @@ export class EvaluationClientWrapper {
continue;
}
for (const vcPath of sameIdVcs) {
const idRes = JsonPathUtils.extractInputField(pd, [idPath]);
if (idRes.length) {
const inputDescriptorResults = JsonPathUtils.extractInputField<InputDescriptorV1 | InputDescriptorV2>(pd, [idPath]);
if (inputDescriptorResults.length) {
const inputDescriptor = inputDescriptorResults[0].value;
submissionRequirementMatches.push({
name: (idRes[0].value as InputDescriptorV1 | InputDescriptorV2).name || (idRes[0].value as InputDescriptorV1 | InputDescriptorV2).id,
name: inputDescriptor.name || inputDescriptor.id,
rule: Rules.All,
vc_path: [vcPath],

type: SubmissionRequirementMatchType.InputDescriptor,
id: inputDescriptor.id,
});
}
}
}
return this.removeDuplicateSubmissionRequirementMatches(submissionRequirementMatches);
}

private mapMatchingDescriptors(
private getMatchingVcPathsForSubmissionRequirement(
pd: IInternalPresentationDefinition,
sr: SubmissionRequirement,
marked: HandlerCheckResult[],
): SubmissionRequirementMatch {
const srm: Partial<SubmissionRequirementMatch> = { rule: sr.rule, vc_path: [] };
if (sr?.from) {
srm.from = sr.from;
// updating the srm.name everytime and since we have only one, we're sending the last one
for (const m of marked) {
const inDesc: InputDescriptorV2 = jp.query(pd, m.input_descriptor_path)[0];
if (inDesc.group && inDesc.group.indexOf(sr.from) === -1) {
continue;
}
srm.name = inDesc.name || inDesc.id;
if (m.payload.group.includes(sr.from)) {
if (srm.vc_path?.indexOf(m.verifiable_credential_path) === -1) {
srm.vc_path.push(m.verifiable_credential_path);
}
}
): string[] {
const vcPaths = new Set<string>();

if (!sr.from) return Array.from(vcPaths);

for (const m of marked) {
const inputDescriptor: InputDescriptorV2 = jp.query(pd, m.input_descriptor_path)[0];
if (inputDescriptor.group && inputDescriptor.group.indexOf(sr.from) === -1) {
continue;
}
if (m.payload.group.includes(sr.from)) {
vcPaths.add(m.verifiable_credential_path);
}
}
return srm as SubmissionRequirementMatch;

return Array.from(vcPaths);
}

public evaluate(
Expand Down
4 changes: 2 additions & 2 deletions lib/utils/jsonPathUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export class JsonPathUtils {
}
result: [ { value: 19, path: [ '$', 'details', 'information', 0, 'age' ] } ]
*/
public static extractInputField(obj: InputFieldType, paths: string[]): { value: unknown; path: PathComponent[] }[] {
public static extractInputField<PathValue = unknown>(obj: InputFieldType, paths: string[]): { value: PathValue; path: PathComponent[] }[] {
let result: { value: unknown; path: PathComponent[] }[] = [];
if (paths) {
for (const path of paths) {
Expand All @@ -58,7 +58,7 @@ export class JsonPathUtils {
}
}
}
return result;
return result as { value: PathValue; path: PathComponent[] }[];
}

public static changePropertyNameRecursively(
Expand Down
Loading

0 comments on commit 46af7d8

Please sign in to comment.