diff --git a/src/authorization-response/PresentationExchange.ts b/src/authorization-response/PresentationExchange.ts index 6dcc31c..830825d 100644 --- a/src/authorization-response/PresentationExchange.ts +++ b/src/authorization-response/PresentationExchange.ts @@ -324,9 +324,9 @@ export class PresentationExchange { ) { const pex = new PEX({ hasher: opts?.hasher }); - function filterOutCorrectPresentation() { + async function filterOutCorrectPresentation() { //TODO: add support for multiple VPs here - return vpPayloads.filter(async (vpw: WrappedVerifiablePresentation) => { + const matchingVps = vpPayloads.map(async (vpw: WrappedVerifiablePresentation): Promise => { const presentationSubmission = opts?.presentationSubmission ?? (CredentialMapper.isWrappedW3CVerifiablePresentation(vpw) ? vpw.presentation.presentation_submission : undefined); @@ -364,11 +364,20 @@ export class PresentationExchange { if (!presentation || !submission) { throw new Error(SIOPErrors.NO_PRESENTATION_SUBMISSION); } - return submission && submission.definition_id === definition.id; + + // No match + if (submission.definition_id !== definition.id) { + return undefined; + } + + return vpw; }); + + // Wait for all results to finish and filter out undefined (no match) values + return (await Promise.all(matchingVps)).filter((vp) => vp !== undefined); } - const checkedPresentations: WrappedVerifiablePresentation[] = filterOutCorrectPresentation(); + const checkedPresentations = await filterOutCorrectPresentation(); if (checkedPresentations.length !== 1) { throw new Error(`${SIOPErrors.COULD_NOT_FIND_VCS_MATCHING_PD}`); diff --git a/test/PresentationExchange.spec.ts b/test/PresentationExchange.spec.ts index 65e675f..46eed0a 100644 --- a/test/PresentationExchange.spec.ts +++ b/test/PresentationExchange.spec.ts @@ -422,4 +422,36 @@ describe('presentation exchange manager tests', () => { console.log(e); } }); + + it("'validatePresentationsAgainstDefinitions' should fail if provided VP verification callback fails", async () => { + const payload: AuthorizationRequestPayload = await getPayloadVID1Val(); + const pd: PresentationDefinitionWithLocation[] = await PresentationExchange.findValidPresentationDefinitions(payload); + const vcs = getVCs(); + const pex = new PresentationExchange({ allDIDs: [HOLDER_DID], allVerifiableCredentials: vcs }); + await pex.selectVerifiableCredentialsForSubmission(pd[0].definition); + const presentationSignCallback: PresentationSignCallback = async (_args) => ({ + ...(_args.presentation as IPresentation), + proof: { + type: 'RsaSignature2018', + created: '2018-09-14T21:19:10Z', + proofPurpose: 'authentication', + verificationMethod: 'did:example:ebfeb1f712ebc6f1c276e12ec21#keys-1', + challenge: '1f44d55f-f161-4938-a659-f8026467f126', + domain: '4jt78h47fh47', + jws: 'eyJhbGciOiJSUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..kTCYt5XsITJX1CxPCT8yAV-TVIw5WEuts01mq-pQy7UJiN5mgREEMGlv50aqzpqh4Qq_PbChOMqsLfRoPsnsgxD-WUcX16dUOqV0G_zS245-kronKb78cPktb3rk-BuQy72IFLN25DYuNzVBAh4vGHSrQyHUGlcTwLtjPAnKb78', + }, + }); + const verifiablePresentationResult = await pex.createVerifiablePresentation(pd[0].definition, vcs, presentationSignCallback, {}); + + await expect( + PresentationExchange.validatePresentationsAgainstDefinitions( + pd, + [CredentialMapper.toWrappedVerifiablePresentation(verifiablePresentationResult.verifiablePresentation)], + () => { + throw new Error('Verification failed'); + }, + {}, + ), + ).rejects.toThrow(SIOPErrors.VERIFIABLE_PRESENTATION_SIGNATURE_NOT_VALID); + }); });