Skip to content

Commit

Permalink
fix: submission generation logic
Browse files Browse the repository at this point in the history
  • Loading branch information
nklomp committed Nov 28, 2023
1 parent 7b34c6d commit c2c8367
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 21 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Release Notes

## v2.2.2 - 2023-11-28

- Updated:
- Updated pex-model deps
- Added more logic to deduce holder(s) for a VP
- Fixed:
- Logic when to generate a presentation submission was incorrect

## v2.2.1 - 2023-10-23

- Updated:
- Updated logic to return holder DID when constructing presentation
- Fixed:
- Issue with determining whether to generate submission data or not.

## v2.2.0 - 2023-10-12

- Updated:
Expand Down
40 changes: 28 additions & 12 deletions lib/PEX.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Format, PresentationDefinitionV1, PresentationDefinitionV2, PresentationSubmission } from '@sphereon/pex-models';
import {
CredentialMapper,
IPresentation,
IProof,
OriginalVerifiableCredential,
Expand All @@ -21,7 +22,7 @@ import {
VerifiablePresentationResult,
} from './signing';
import { DiscoveredVersion, IInternalPresentationDefinition, IPresentationDefinition, PEVersion, SSITypesBuilder } from './types';
import { definitionVersionDiscovery } from './utils';
import { definitionVersionDiscovery, getSubjectIdsAsString } from './utils';
import { PresentationDefinitionV1VB, PresentationDefinitionV2VB, PresentationSubmissionVB, Validated, ValidationEngine } from './validation';

/**
Expand Down Expand Up @@ -58,7 +59,7 @@ export class PEX {
},
): EvaluationResults {
const generatePresentationSubmission =
opts?.generatePresentationSubmission !== undefined ? opts.generatePresentationSubmission : opts?.presentationSubmission !== undefined;
opts?.generatePresentationSubmission !== undefined ? opts.generatePresentationSubmission : opts?.presentationSubmission === undefined;
const pd: IInternalPresentationDefinition = SSITypesBuilder.toInternalPresentationDefinition(presentationDefinition);
const presentationCopy: OriginalVerifiablePresentation = JSON.parse(JSON.stringify(presentation));
const wrappedPresentation: WrappedVerifiablePresentation = SSITypesBuilder.mapExternalVerifiablePresentationToWrappedVP(presentationCopy);
Expand Down Expand Up @@ -190,6 +191,7 @@ export class PEX {
const presentationSubmission = this.presentationSubmissionFrom(presentationDefinition, selectedCredentials, opts);
const presentation = PEX.constructPresentation(selectedCredentials, {
...opts,
// We only pass in the submission in case it needs to be included in the presentation
presentationSubmission: presentationSubmissionLocation === PresentationSubmissionLocation.PRESENTATION ? presentationSubmission : undefined,
});
return {
Expand All @@ -207,12 +209,28 @@ export class PEX {
basePresentationPayload?: IPresentation;
},
): IPresentation {
const holder = opts?.holderDID;
const type = Array.isArray(opts?.basePresentationPayload?.type)
? opts?.basePresentationPayload?.type || []
: opts?.basePresentationPayload?.type
? [opts.basePresentationPayload.type]
if (!selectedCredentials) {
throw Error(`At least a verifiable credential needs to be passed in to create a presentation`);
}
const verifiableCredential = (Array.isArray(selectedCredentials) ? selectedCredentials : [selectedCredentials]) as W3CVerifiableCredential[];
const wVCs = verifiableCredential.map((vc) => CredentialMapper.toWrappedVerifiableCredential(vc));
const holders = Array.from(new Set(wVCs.flatMap((wvc) => getSubjectIdsAsString(wvc.credential))));
if (holders.length !== 1 && !opts?.holderDID) {
console.log(
`We deduced ${holders.length} subject from ${wVCs.length} Verifiable Credentials, and no holder property was given. This might lead to undesired results`,
);
}
const holder = opts?.holderDID ?? (holders.length === 1 ? holders[0] : undefined);

const type = opts?.basePresentationPayload?.type
? Array.isArray(opts.basePresentationPayload.type)
? opts.basePresentationPayload.type
: [opts.basePresentationPayload.type]
: [];
if (!type.includes('VerifiablePresentation')) {
type.push('VerifiablePresentation');
}

const context = opts?.basePresentationPayload?.['@context']
? Array.isArray(opts.basePresentationPayload['@context'])
? opts.basePresentationPayload['@context']
Expand All @@ -222,9 +240,6 @@ export class PEX {
context.push('https://www.w3.org/2018/credentials/v1');
}

if (!type.includes('VerifiablePresentation')) {
type.push('VerifiablePresentation');
}
if (opts?.presentationSubmission) {
if (!type.includes('PresentationSubmission')) {
type.push('PresentationSubmission');
Expand All @@ -238,8 +253,8 @@ export class PEX {
'@context': context,
type,
holder,
...(!!opts?.presentationSubmission && { presentation_submission: opts.presentationSubmission }),
verifiableCredential: (Array.isArray(selectedCredentials) ? selectedCredentials : [selectedCredentials]) as W3CVerifiableCredential[],
...(opts?.presentationSubmission && { presentation_submission: opts.presentationSubmission }),
verifiableCredential,
};
}

Expand Down Expand Up @@ -334,6 +349,7 @@ export class PEX {
const evaluationResults = this.evaluatePresentation(presentationDefinition, presentationResult.presentation, {
limitDisclosureSignatureSuites,
...(presentationSubmissionLocation === PresentationSubmissionLocation.EXTERNAL && {
// The method will pickup submissions included in the Presentation anyway
presentationSubmission: presentationResult.presentationSubmission,
}),
});
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sphereon/pex",
"version": "2.2.1-unstable.0",
"version": "2.2.2-unstable.0",
"description": "A Typescript implementation of the v1 and v2 DIF Presentation Exchange specification",
"main": "dist/main/index.js",
"module": "dist/module/index.js",
Expand Down Expand Up @@ -41,7 +41,7 @@
"node": ">=16"
},
"dependencies": {
"@sphereon/pex-models": "^2.1.1",
"@sphereon/pex-models": "^2.1.2",
"@sphereon/ssi-types": "^0.17.5",
"ajv": "^8.12.0",
"ajv-formats": "^2.1.1",
Expand Down
9 changes: 6 additions & 3 deletions test/PEX.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,12 @@ describe('evaluate', () => {
// Delete the submission to trigger an error
delete vpSimple.presentation_submission;
const pex: PEX = new PEX();
expect(() => pex.evaluatePresentation(pdSchema, vpSimple, { limitDisclosureSignatureSuites: LIMIT_DISCLOSURE_SIGNATURE_SUITES })).toThrowError(
'Either a presentation submission as part of the VP or provided separately was expected',
);
expect(() =>
pex.evaluatePresentation(pdSchema, vpSimple, {
limitDisclosureSignatureSuites: LIMIT_DISCLOSURE_SIGNATURE_SUITES,
generatePresentationSubmission: false,
}),
).toThrowError('Either a presentation submission as part of the VP or provided separately was expected');
});

it('Evaluate case without any error 2', () => {
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -689,10 +689,10 @@
dependencies:
"@sinonjs/commons" "^3.0.0"

"@sphereon/pex-models@^2.1.1":
version "2.1.1"
resolved "https://registry.yarnpkg.com/@sphereon/pex-models/-/pex-models-2.1.1.tgz#399e529db2a7e3b9abbd7314cdba619ceb6cb758"
integrity sha512-0UX/CMwgiJSxzuBn6SLOTSKkm+uPq3dkNjl8w4EtppXp6zBB4lQMd1mJX7OifX5Bp5vPUfoz7bj2B+yyDtbZww==
"@sphereon/pex-models@^2.1.2":
version "2.1.2"
resolved "https://registry.yarnpkg.com/@sphereon/pex-models/-/pex-models-2.1.2.tgz#e1a0ce16ccc6b32128fc8c2da79d65fc35f6d10f"
integrity sha512-Ec1qZl8tuPd+s6E+ZM7v+HkGkSOjGDMLNN1kqaxAfWpITBYtTLb+d5YvwjvBZ1P2upZ7zwNER97FfW5n/30y2w==

"@sphereon/ssi-types@^0.17.5":
version "0.17.5"
Expand Down

0 comments on commit c2c8367

Please sign in to comment.