From 4936ccff31d67a6fd57edd92af467499ad1f331f Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Wed, 18 Sep 2024 12:55:38 +0200 Subject: [PATCH 01/47] chore: removed /src import --- lib/signing/types.ts | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/signing/types.ts b/lib/signing/types.ts index 2961df82..a962e8ed 100644 --- a/lib/signing/types.ts +++ b/lib/signing/types.ts @@ -9,8 +9,8 @@ import { SdJwtDecodedVerifiableCredential, SdJwtVcKbJwtPayload, W3CVerifiablePresentation, + SdJwtVcKbJwtHeader } from '@sphereon/ssi-types'; -import { SdJwtVcKbJwtHeader } from '@sphereon/ssi-types/src/types/sd-jwt-vc'; import { PresentationEvaluationResults } from '../evaluation'; diff --git a/package.json b/package.json index dd0a31de..6c171885 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sphereon/pex", - "version": "5.0.0-unstable.0", + "version": "5.0.0-unstable.1", "description": "A Typescript implementation of the v1 and v2 DIF Presentation Exchange specification", "main": "dist/main/index.js", "module": "dist/module/index.js", From fd50b2ea0603f54d9c29ef65789b933a18919ee4 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Wed, 18 Sep 2024 23:53:28 +0200 Subject: [PATCH 02/47] chore: elligible -> eligible --- .../limitDisclosureEvaluationHandler.ts | 30 ++++++++----------- .../markForSubmissionEvaluationHandler.ts | 2 +- lib/signing/types.ts | 2 +- package.json | 2 +- 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/lib/evaluation/handlers/limitDisclosureEvaluationHandler.ts b/lib/evaluation/handlers/limitDisclosureEvaluationHandler.ts index c49a5c7c..1945824d 100644 --- a/lib/evaluation/handlers/limitDisclosureEvaluationHandler.ts +++ b/lib/evaluation/handlers/limitDisclosureEvaluationHandler.ts @@ -17,7 +17,7 @@ import { applySdJwtLimitDisclosure, JsonPathUtils } from '../../utils'; import { EvaluationClient } from '../evaluationClient'; import { AbstractEvaluationHandler } from './abstractEvaluationHandler'; -import { elligibleInputDescriptorsForWrappedVc } from './markForSubmissionEvaluationHandler'; +import { eligibleInputDescriptorsForWrappedVc } from './markForSubmissionEvaluationHandler'; export class LimitDisclosureEvaluationHandler extends AbstractEvaluationHandler { constructor(client: EvaluationClient) { @@ -33,7 +33,7 @@ export class LimitDisclosureEvaluationHandler extends AbstractEvaluationHandler } private isLimitDisclosureSupported( - elligibleInputDescriptors: InputDescriptorWithIndex[], + eligibleInputDescriptors: InputDescriptorWithIndex[], wvc: WrappedVerifiableCredential, vcIndex: number, ): boolean { @@ -42,7 +42,7 @@ export class LimitDisclosureEvaluationHandler extends AbstractEvaluationHandler const limitDisclosureSignatures = this.client.limitDisclosureSignatureSuites; const decoded = wvc.decoded as IVerifiableCredential; const proofs = Array.isArray(decoded.proof) ? decoded.proof : decoded.proof ? [decoded.proof] : undefined; - const requiredLimitDisclosureInputDescriptorIds = elligibleInputDescriptors + const requiredLimitDisclosureInputDescriptorIds = eligibleInputDescriptors .map(({ inputDescriptor: { constraints }, inputDescriptorIndex }) => constraints?.limit_disclosure === Optionality.Required ? inputDescriptorIndex : undefined, ) @@ -52,7 +52,7 @@ export class LimitDisclosureEvaluationHandler extends AbstractEvaluationHandler // todo: Support/inspect array based proofs if (requiredLimitDisclosureInputDescriptorIds.length > 0) { this.createLimitDisclosureNotSupportedResult( - elligibleInputDescriptors.map((i) => i.inputDescriptorIndex), + eligibleInputDescriptors.map((i) => i.inputDescriptorIndex), vcIndex, 'Multiple proofs on verifiable credential not supported for limit disclosure', ); @@ -78,27 +78,23 @@ export class LimitDisclosureEvaluationHandler extends AbstractEvaluationHandler private evaluateLimitDisclosure(inputDescriptors: Array, wrappedVcs: WrappedVerifiableCredential[]): void { wrappedVcs.forEach((wvc, vcIndex) => { - const elligibleInputDescriptors = elligibleInputDescriptorsForWrappedVc(inputDescriptors, vcIndex, this.getResults()); - const includeLimitDisclosure = elligibleInputDescriptors.some( + const eligibleInputDescriptors = eligibleInputDescriptorsForWrappedVc(inputDescriptors, vcIndex, this.getResults()); + const includeLimitDisclosure = eligibleInputDescriptors.some( ({ inputDescriptor: { constraints } }) => constraints?.limit_disclosure === Optionality.Preferred || constraints?.limit_disclosure === Optionality.Required, ); - if ( - elligibleInputDescriptors.length > 0 && - includeLimitDisclosure && - this.isLimitDisclosureSupported(elligibleInputDescriptors, wvc, vcIndex) - ) { - this.enforceLimitDisclosure(wrappedVcs, elligibleInputDescriptors, vcIndex); + if (eligibleInputDescriptors.length > 0 && includeLimitDisclosure && this.isLimitDisclosureSupported(eligibleInputDescriptors, wvc, vcIndex)) { + this.enforceLimitDisclosure(wrappedVcs, eligibleInputDescriptors, vcIndex); } }); } - private enforceLimitDisclosure(wrappedVcs: WrappedVerifiableCredential[], elligibleInputDescriptors: InputDescriptorWithIndex[], vcIndex: number) { + private enforceLimitDisclosure(wrappedVcs: WrappedVerifiableCredential[], eligibleInputDescriptors: InputDescriptorWithIndex[], vcIndex: number) { const wvc = wrappedVcs[vcIndex]; if (CredentialMapper.isWrappedSdJwtVerifiableCredential(wvc)) { - const presentationFrame = this.createSdJwtPresentationFrame(elligibleInputDescriptors, wvc.credential, vcIndex); + const presentationFrame = this.createSdJwtPresentationFrame(eligibleInputDescriptors, wvc.credential, vcIndex); // We update the SD-JWT to it's presentation format (remove disclosures, update pretty payload, etc..), except // we don't create or include the (optional) KB-JWT yet, this is done when we create the presentation @@ -109,18 +105,18 @@ export class LimitDisclosureEvaluationHandler extends AbstractEvaluationHandler // But we also want to keep the format of the original credential. wvc.original = CredentialMapper.isSdJwtDecodedCredential(wvc.original) ? wvc.credential : wvc.credential.compactSdJwtVc; - for (const { inputDescriptorIndex, inputDescriptor } of elligibleInputDescriptors) { + for (const { inputDescriptorIndex, inputDescriptor } of eligibleInputDescriptors) { this.createSuccessResult(inputDescriptorIndex, `$[${vcIndex}]`, inputDescriptor.constraints?.limit_disclosure); } } } else if (CredentialMapper.isW3cCredential(wvc.credential)) { - const internalCredentialToSend = this.createVcWithRequiredFields(elligibleInputDescriptors, wvc.credential, vcIndex); + const internalCredentialToSend = this.createVcWithRequiredFields(eligibleInputDescriptors, wvc.credential, vcIndex); /* When verifiableCredentialToSend is null/undefined an error is raised, the credential will * remain untouched and the verifiable credential won't be submitted. */ if (internalCredentialToSend) { wvc.credential = internalCredentialToSend; - for (const { inputDescriptorIndex, inputDescriptor } of elligibleInputDescriptors) { + for (const { inputDescriptorIndex, inputDescriptor } of eligibleInputDescriptors) { this.createSuccessResult(inputDescriptorIndex, `$[${vcIndex}]`, inputDescriptor.constraints?.limit_disclosure); } } diff --git a/lib/evaluation/handlers/markForSubmissionEvaluationHandler.ts b/lib/evaluation/handlers/markForSubmissionEvaluationHandler.ts index f9e422ac..412b4fbe 100644 --- a/lib/evaluation/handlers/markForSubmissionEvaluationHandler.ts +++ b/lib/evaluation/handlers/markForSubmissionEvaluationHandler.ts @@ -10,7 +10,7 @@ import { EvaluationClient } from '../evaluationClient'; import { AbstractEvaluationHandler } from './abstractEvaluationHandler'; -export function elligibleInputDescriptorsForWrappedVc( +export function eligibleInputDescriptorsForWrappedVc( inputDescriptors: Array, vcIndex: number, results: HandlerCheckResult[], diff --git a/lib/signing/types.ts b/lib/signing/types.ts index a962e8ed..4d296645 100644 --- a/lib/signing/types.ts +++ b/lib/signing/types.ts @@ -9,7 +9,7 @@ import { SdJwtDecodedVerifiableCredential, SdJwtVcKbJwtPayload, W3CVerifiablePresentation, - SdJwtVcKbJwtHeader + SdJwtVcKbJwtHeader, } from '@sphereon/ssi-types'; import { PresentationEvaluationResults } from '../evaluation'; diff --git a/package.json b/package.json index 6c171885..73c41160 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sphereon/pex", - "version": "5.0.0-unstable.1", + "version": "5.0.0-unstable.2", "description": "A Typescript implementation of the v1 and v2 DIF Presentation Exchange specification", "main": "dist/main/index.js", "module": "dist/module/index.js", From f15f0af4634270c5de1260d51142782e62ee4370 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Mon, 23 Sep 2024 10:13:19 +0200 Subject: [PATCH 03/47] chore: Added Northern Block pd/vcs --- .../pdV2/pd-multi-sd-jwt-vp.json | 122 ++++++++++++++++++ .../vc/vc-iata-epassport-sd.jwt | 1 + test/dif_pe_examples/vc/vc-iata-order-sd.jwt | 1 + test/evaluation/selectFrom.spec.ts | 25 +++- 4 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json create mode 100644 test/dif_pe_examples/vc/vc-iata-epassport-sd.jwt create mode 100644 test/dif_pe_examples/vc/vc-iata-order-sd.jwt diff --git a/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json b/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json new file mode 100644 index 00000000..45178287 --- /dev/null +++ b/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json @@ -0,0 +1,122 @@ +{ + "presentation_definition": { + "id": "Order and ePassport", + "name": "IATA Order / ePassport SD-JWT", + "purpose": "Multi-presentation test for order & ePassport SD-JWT", + "submission_requirements": [ + { + "name": "Order and epass", + "rule": "all", + "count": 2, + "from": "A" + } + ], + "input_descriptors": [ + { + "id": "order", + "group": [ + "A" + ], + "format": { + "vc+sd-jwt": { + "sd-jwt_alg_values": [ + "ES256", + "ES384", + "ES512", + "EdDSA" + ] + } + }, + "constraints": { + "fields": [ + { + "path": [ + "$.vct" + ], + "filter": { + "type": "string", + "pattern": "Order" + } + }, + { + "path": [ + "$.paxSegments.operatingCarrierFlightNumber" + ] + }, + { + "path": [ + "$.paxSegments.scheduledArrivalTime" + ] + }, + { + "path": [ + "$.paxSegments.scheduledDepartureTime" + ] + } + ] + } + }, + { + "id": "passport credential", + "group": [ + "A" + ], + "format": { + "jwt_vc_json": { + "alg": [ + "RS256" + ] + } + }, + "constraints": { + "fields": [ + { + "path": [ + "$.vct" + ], + "filter": { + "type": "string", + "pattern": "ePassport" + } + }, + { + "path": [ + "$.electronicPassport.dataGroup1.holdersName" + ] + }, + { + "path": [ + "$.electronicPassport.dataGroup1.sexCode" + ] + }, + { + "path": [ + "$.electronicPassport.dataGroup1.birthdate" + ] + }, + { + "path": [ + "$.electronicPassport.dataGroup1.natlCode" + ] + }, + { + "path": [ + "$.electronicPassport.dataGroup1.passportNumberIdentifier" + ] + }, + { + "path": [ + "$.electronicPassport.dataGroup1.issuerCode" + ] + }, + { + "path": [ + "$.electronicPassport.dataGroup1.expiryDate" + ] + } + ] + } + } + ] + } +} diff --git a/test/dif_pe_examples/vc/vc-iata-epassport-sd.jwt b/test/dif_pe_examples/vc/vc-iata-epassport-sd.jwt new file mode 100644 index 00000000..ace75c96 --- /dev/null +++ b/test/dif_pe_examples/vc/vc-iata-epassport-sd.jwt @@ -0,0 +1 @@ +eyJ0eXAiOiJ2YytzZC1qd3QiLCJraWQiOiIwMmQxYzZkNjlkYWNiNDFlNjA4OTlhN2U4Y2RhMzlmMTJhMjY2NmZjOWMzNGM0MzdiMWY3NGY2MWNmNTBkOTVjNjAiLCJhbGciOiJFUzI1NiJ9.eyJ0eXBlIjoiZVBhc3Nwb3J0IiwidmN0IjoiZVBhc3Nwb3J0IiwiZWxlY3Ryb25pY1Bhc3Nwb3J0Ijp7ImRhdGFHcm91cDEiOnsiYmlydGhkYXRlIjoiMTk3My0xMi0xNSIsImRvY1R5cGVDb2RlIjoiUCIsImV4cGlyeURhdGUiOiIyMDI3LTA5LTA1VDA5OjIwOjA3Ljc1M1oiLCJzZXhDb2RlIjoiTSIsImhvbGRlcnNOYW1lIjoiVGVzdE5hbWUiLCJpc3N1ZXJDb2RlIjoiTkIiLCJuYXRsQ29kZSI6Ik5MIiwicGFzc3BvcnROdW1iZXJJZGVudGlmaWVyIjoiTkwzNjM3MjY3NDY3ODIifSwiZGF0YUdyb3VwMTUiOnsiYWN0aXZlQXV0aGVudGljYXRpb24iOnsicHVibGljS2V5QmluYXJ5T2JqZWN0IjoiY0hWaWJHbGpTMlY1UW1sdVlYSjVUMkpxWldOMGNIVmliR2xqUzJWNVFtbHVZWEo1VDJKcVpXTkdGRjBSZWZTYyJ9fSwiZGF0YUdyb3VwMkVuY29kZWRGYWNlQmlvbWV0cmljcyI6eyJmYWNlQmlvbWV0cmljRGF0YUVuY29kZWRQaWN0dXJlIjoiaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUswQUFBRGRDQVlBQUFESmpmS0NBQUFCaFdsRFExQkpRME1nY0hKdlptbHNaUUFBS0pGOWtUMUl3MEFZaHQrbWlqKzBPTmhCUkRCRGRiS0xpb2hUcVdJUkxKUzJRcXNPSnBmK1FaT0dKTVhGVVhBdE9QaXpXSFZ3Y2RiVndWVVFCSDlBbkIyY0ZGMmt4TytTUW9zWTd6anU0YjN2ZmJuN0RoQWFGYWFhWFZGQTFTd2pGWStKMmR5cTJQT0tQZ1Jwem1GVVlxYWVTQzltNERtKzd1SGorMTJFWjNuWC9UbUNTdDVrZ0U4a2pqTGRzSWczaUdjMkxaM3pQbkdJbFNTRitKeDR3cUFMRWo5eVhYYjVqWFBSWVlGbmhveE1hcDQ0UkN3V08xanVZRll5Vk9KcDRyQ2lhcFF2WkYxV09HOXhWaXMxMXJvbmYyRWdyNjJrdVU1ckJIRXNJWUVrUk1pb29Zd0tMRVJvMTBneGthTHptSWQvMlBFbnlTV1Rxd3hHamdWVW9VSnkvT0IvOEx1M1ptRnEwazBLeElEdUY5ditHQU42ZG9GbTNiYS9qMjI3ZVFMNG40RXJyZTJ2Tm9EWlQ5THJiUzE4QkF4c0F4ZlhiVTNlQXk1M2dLRW5YVElrUi9MVEVnb0Y0UDJNdmlrSERONEMvV3R1MzFybk9IMEFNdFNyNVJ2ZzRCQVlMMUwydXNlN2V6djc5bTlOcTM4Lzg0WnkydThtVzBJQUFBQUdZa3RIUkFCRkFBNEE2MVFXZXJ3QUFBQUpjRWhaY3dBQUxpTUFBQzRqQVhpbFAzWUFBQUFIZEVsTlJRZm9DUTBOT3cyRFlvazFBQUFBR1hSRldIUkRiMjF0Wlc1MEFFTnlaV0YwWldRZ2QybDBhQ0JIU1UxUVY0RU9Gd0FBSUFCSlJFRlVlTnJzblhkNFhIZVYvai8zM3VsRjBxajMzbTNMdmNaMjdCamI2YjFBQ0NSQXFBR1dzTURTTnl3LzJpNTlzeUcwVU5JZ3BKTWVKN2JqM21WYmttWDFYa1pkbzlIVWUrL3ZqNUdWT0phdE5xck0renp6UEhJeWQrYVdkODczblBNOTV6MkNxcW9xSVlRd2h5Q0dia0VJSWRLR0VFS0l0Q0dFRUNKdENDSFNoaEJDaUxRaGhCQWliUWdoMG9ZUVFvaTBJWVF3SG1oQ3QrRFNVRlVWdDhlTHorZkg2L1hqODh2SXNreHYzd0JOTFIzNC9mSUZ4MlNtSnhKbU5hR1JKTFJhRFJxTmhFNm5SYWZUSUlraE94RWk3UlRBNWZMUTB0WkphM3MzSFoyOWxGYzIwTnpTU1ZPem5UWjdEOTA5L2FNdllhSkFaSVNWcE1RWVlxSWpTRXVKSXkwbG52aTRTS0tqd29teWhSRVRIWUZHSTRWdStEZ2hoR29QM2tWTFd4ZDc5cCtpdEx5V3l1b202aHZiNmV6cXUrQjlVWkZoV014R1RFWURrWkZoaUlJdy9QOTYraHc0SElQSXNrSlhUejh1bCtjOElsc3RKaExpbzRpUGpTUWxLWmJzekNRSzh0SW95RTFEcjllR0hrS0l0R05EZVdVRFR6MjNrOE5IejlCbTcyYkE2VUpSQXJjbFBNek1ndngwRmkzSUlpOG5oZVRFR0F4NkhScU5oRVlqb2RkckVYaVh0RjZ2RDUvUGo2S3FlTHcrQmdmZDFEZTEwOVRjUVVWVkkyY3JHMmx0NzBhV1pRUkJ3R0kyRWhGdUlUNHVrc1VMczdqcmptMGt4a2VGbUJraTdjam82M2Z5Njk4K3c3UC8zSVBUNlJyKzcxYXJpWTNyRm5QemRSdFl2MllSSVBBZVl6cHgvempnSk5QVTBzSHhrNVhzMmx2TWdjT2w1N2tiWC96MExYeitVemVGbUJraTdmbm83T3BqeCs1alBQeklpN1MwZHFMUlNNUkVSNUNSR3M5Vlc5ZXc3WW9WMkNLczAzSXV6a0UzcDB0cjJMSHJHQ2RMcXZuSjl6NUZabnBpaUpraDBnYmc5OHVVbmEzakwwKzh6c3R2SEFBRWtwTmlXTDltRWR1M3JHUnBVUzZHT2VCWDF0UzFjT2pvR1RJekVsbVFuNDdGYkF4bEQrWWpaRmxoMzhIVC9QSTNUM08yc2hGRlVibnV5clhjZXNQbEZDM013bXd5ekpscitjMGZYK0RsMXcrU25CUkRZWDQ2MTJ4ZHc4YjFpOUhydENIU3ppZnMySFdNSC83OE1kcmF1ekhvZGZ6Z3UvZXk1ZkpsV0MwbWhHQTRyTk1JeDRBTHZ5eFQxOUJHUTFNNyt3K1dzTEF3ZzAvZWZTMHJsK1hQK3pUYXZIY1BGRVhoVkVrMUgvLzhUM0FPZWtoTmp1V0JyOS9EdXRVTDV4eFpoek1VUGorNzlwemdEMzk5aGNycVJnWmRIbFJWUmFmVnNIbmpNcjcrcFR1SmpZbEFxOVdFU0R2M0NLdHk4RWdwWC8vZTcyaTM5NUNkbWNSWHZuQUhsMSsyR0hFZTdFeDVmWDcySHlyaDZSZDJVVkpXUzV1OUIwVlJzRVZZdWZ0RDI5bCt4VXJTVXVQbm5lV2QxNlN0cUc3aWV6LytNOGVLejJLTHNQS0Q3MzZTeTljdFJwTG0xMWFxMitQbHdLRlMzbjduT0cvdU9rWjNUeitTSkxKNFlSWjMzSHdGV3pldm1GZkIycndsN1lEVHhXLysrQUovZWZKMXZGNGZQL3ZCNTdoNjI1cDV1L2V2cWlyOWprRk9ucTdpNFVkZTRHaHhCWUlnRUdrTFk5TmxpN24vYzdjUkcyc0xrWFkyNDhqeGNyN3dINyttdTd1ZkQ5KzJsZTk4N2FPSW9zQjhoNnFxZUwwK252M25Ibjc4aThkeHViMklva2gwVkJpLy9ORVhXTEUwYjg1ZjQ3dzBPNHFpOHRqZjM2Uzd1NStNOUFUdSs5U04veEtFQlJBRUFiMWV4d2R2dVlLL1BQeE5WcThvUUt2VllPL281Yk5mL2ptUC91ME5CdDZ6K3pjWElUM3d3QU1QekxjSFYxdmZ5czhlZkFxTkpQS0ZUOTNNc3NXNTh5THdHaTk1NCtNaVdiMjhBSUM2eGpaNit3WW9QbDJKeSswbE55dDVUdVdtNTcybGZlSWZPM0FNREpLVGxjeXl4VG4vMHVWL1NZa3gzSGZ2VFh6N0t4OGhJeTJCZnNjZ2ovOWpCei80NmFPMDI3dERwSjBOY0xrOVBQdlNIaVJKWlBtU1hETFNFdmhYaDhWaTVKcHRhL2poZHo5SmZrNHFnNE51WG52ckNQZC80MEhhMnVjZWNlZGRJSGJ3U0JrZi9jd1BpWXUxOGIxdmZJd3JOaTRqaEhkUjE5REdkMy93Q0llT25RRmd6WW9DZnZ5OVQ1TVFGOXh5U0ZWVmFXN3Q1Rmh4QmMwdG5ad3NxU0k5UFFHejJZaTl2WnVQM1hVVldSTXNESnAzbHZiNHlRb0FJbTFoTENqSUNMSDBmVWhQamVmYlgvMElLNWZsb2FvcWg0K1g4Nk9mUFU1OVF4dkJ0Rjgrbjh4Zi8vWTZSUXV6K09BZFcvbmhEKzdqVTUrOG1WdHYyUUtTaUhOZzRzSGd2Q1B0NmJJYUFGS1RZb21Mc1lWWU9nSnlzMVA0ejYvZncvcTFpNUJsaFIyN2p2Ry92M3VPZnNkZ01HMHRPcTJXeE1RWUJPbmRtR0xRNWNGc05HQTA2a09rQmVqdEhhQ3gyWTRnQ0N4YmtodGk1eVdRazVuTWQ3OTJONnVXRitDWFpWNTc2ekFQL3U3WllLWXZNT2gxK0JVVjVYMFdYS3VWSnBYTm1WZWs3WE00OGZrQ2JTeUZlZWtoWm82Q3RKUjQ3di9jYmFTbHh1UDErbmppNmJmNHpSOWZDTXBubnlxdEpqNHU4Z0tYbzY5dkFFa1VRNWIySE93ZFBYaTl2a0FuYktRMXhNclJqU0ZMRm1Yem1ZOWRUM1JVT0Q2Zm56OC84UnE3OWhhaktNb2tmVnIvaU5aVVVSUkVVVHl2R1hTOG1GZTFhK21wOFd6L3dDcnM5bTV5TXBORHJCd0RKRW5rK3Fzdm82dTduNGYrK0R5OWZRUDg5azh2RWh0am95QTNkUkxsbXdJNjNZWDA4dnRsckJZamVvTXVaR2tCWXFJaitQZjdidWUvdnZXSkVCdkhBYTFHNGtPM1hzRk4xNjVIVlZWT2xsVHo1Tk52MGRmdm5EaXhSSUg0dUtnTC9GbW4wNDNQTDZPVnBCQnAzM1h5TmY5eVBWUEJnTlZpNG91ZnZvVkZoWm40L1RLdnZIR1FmWWRLSnZ4NW5WMjlJL3F0aXFwZ011alJhRU9rRFNFSXNFVlkrY0YzN3NWbXMrSVlHT1RIdjNoaXdwOVZWOStPeWxEYi9Idmdkbmt4NkxVWTlDSDNJSVFnSVRNOWdVL2VmUzE2dlpaMmV6Y1AvT2pQRXcvS1ZQV0M3SUhiNDJYd1BhbzdJZEtHTUdub2RGcTJiVjdKcW1VRkNJTEFjeSs5UTNsRlk5QSszMlRVWTUyayt4WWliUWdYSURreGhsdXUzMGlrTFF5WDI4dWpmM3VkUVpkNy9JWVdVTlR6TXdjT2h4UFRKRXNpUTZRTlljVElmOHVtNVN6SVR3ZGc3NkVTOWg4cW5ZaDNjSjU3b0NoS1VBclFRNlFOWVVUb2RWcSs4c1U3MEdnazJ1M2Q3TnBiak1mam0vVG5obGxOUkVXR3pXL1NlbjErcW1xYWFXaXlJOHRLaUUzVGlQeWNWRzYrZGdNQXg0c3JLSzlzR0tkN2NINFFKc3NLVHFkNzBub01zNXEwblYxOS9PbnhWL25HOTM3SGYvM2t6L1QwT2tKTW1tWjg1aE0zWURZWnFHMW81Y2p4Y253Ky81aVBWWlQzazFhbVp3eUMxSE9XdEVlT2wvT0ZyLzJLaC83d1BDZExxcW1wYThYcjg0VllOQU5CMmZZUHJFS1dGZDdhZlF6SHdPVEtGNjBXMDZRVktXY2RhZjErbVdkZTNNMi9mL3NoamhWWDRISjVXSkNmenM5KzhEbmk0MEppd3pPQmE3ZXZSYS9YY3VKVUZYVU5iV002Smo0dWNrVExLeXZLcElYeVpoVnBuWU51bm5wK0Z6LzU1Wk8wdFhkak1obTQ4ZG9OL1A3WFgyVnBVYzZrS29OQ21EalNVK05aVkppSm9paTgvdmFSc1Zub3BKZ0xZaENmMzA5clc5ZjhjUS82SFlNOC9NZ0wvUENuajlMYk4wQnlZZ3ozZis1V3Z2L05qeE1kRlI1aXpnd2l5aGJHNG9WWkFMeTE2eGkrRVNiNlhHQlZWWlhXOXE0UnN4S1RxYVdGV1ZLYTJOTTd3UC8rN2huKy91eE9mRDQvQ3dzeitQVEhybWZiNWhWelZ0bHdPdUR6eTVTVjErRnllMWhXbER0aUtXQXdZRFRxS2NoTEk4eHFvcUhKVG1WMUU0VjVhYU9rRGxRR1J1Z0RzNWdOaEllWjU3YWxIUngwOCtEdm51RWZ6Ky9DNS9PVGs1bkVWNy93UWJaY3ZpeEUyRkhRYnUvbUo3OThncTk5OTJFZS9QMXplTDMrS2Z1dXdEaXBRRXl4OThDcGlmM0lmSDZhV3pybnRudmc5OHM4KzlJZW5uOTVIeDZQajZqSU1CNzR4c2RZdTJvQkdpazBYMnZVU054c0JGV2xyYjJidno3NUduOTg5T1VwSTI3S2V4cEZpMDlYamZyK2tReU9xcXI0dkw2NVMxcFZWVGx3dUpSSEhuMEZ4OEFnOGJHUi9QTEhYMkRsc3Z3UUc4ZUk4SEFMUC92QmZWeTJaaUdLb3ZMSFIxL2g4WCs4aWN2dENmcDNSZHFzeE1YYUVFV0JFNmNxUjkwZEs4aE51NkNhUzZ2UkVCT0VEdWtaSTIxVFN3ZS8rTTAvYUdycElERStpbTk5NWE1aDNha1F4bzZFK0NnZSt1bjkzSHJqSnZ5eXpFTi9lSjduWHRvN0pkK1ZsWkdFWHFmRDc1ZHBhR3EvdEI5czBOSFViRC9mK3FvcVlSYlQzQ1N0MitQbHg3OTRncEt5V3F3V0UzZmZlVlZJQ1dhU2dkS243cm1XTFJ1WE1lQjA4ZUJ2bitXVk53OEcvWHRpaDhhaUJraHJIOTFGZU4rL0c4ZHd6S3dsN1d0dkh1YnRkNDRqU1NKYk55L24rcXZXemR2NUFKTkY4ZWtxV2xwSEQxN2lZbXg4NmJPM3NtN1ZBcnA2K3ZudlgvNk5NMmZyZzNvdU9kbko2UFZhVkZVOWIzenF4U2hyZkYvejRrVEtHMmNGYWV2cVczbnc5ODhoeXdwWjZZbmNlZHZXU1ZmOXpEYmM4dEh2c3VuYUwxRlozVFNwenlrNVU4dnQ5enpBWFovNkFYc1BuQjQxOEVsSmp1VXJYL3dnaVFsUnRIZDA4OGZIWHNYcGRBZnR1dlE2TGFJZzRQUExZN2cyRlpmYmU5NS9rVVFSaThVNHQwanI4ZnA0NXNWM2FMZDNJMGtpSDc1OUswVUxNdWVkZGJSMzlPQjB1amxUMFRDcHowbE9qQ0VtS3B6VzlpN2VmdWM0ampIb1h4WGtwdkhsejkyT1Zxdmh5UEV6SER4YUZqU05ycVNFbUhHdGlGcU5oUFFlTVd1OVRrdDhiT1RjSW0xbGRSTjdEcDdHNC9XeGFsa0JOMTZ6Zmw0dTZVc1dadU1jZEZGZU1ibmxPU0xjd3AyM2IwV1dGWGJ2TzBsZGZldVlqdHYrZ1ZWY3UzMHQ3Zlp1WG5ueklGM2QvVUc1THAxT00rYmN1U0FJaEllYjZlMGJlSmRzUVVxN1R4dHBQVjRmZXcrY3BySzZDYU5CeHpmLy9hNUpiK2ZOVmhRdHpNTHZsMm16ZCtOKzN4STVYdHgwelhyQ3c4dzB0M1p3OU1UWk1kVVU2N1FhUG5uM3RTVEdSL1AyN3VPVWxOVXczWUt1Z2lDZzErbk9xd3FyckdtZVc2VHQ2dXJqaFZmMjR2UDUrY0NtRmVUbHBNemI0R2xKVVRZUW1LellQOGxTdnNqSU1EYXVXNHlpcU93NWNHck05YXhKQ2RIY2ROMEduSU51bm5qNkxXUkZubmJTaGxsTk9CenZ1alRPSU0xNm1EYlNGcCt1b3JxMkJZTkJ4KzAzYlpyWEVYOXNWQVFBYnJjSDl5VGJwWFU2TFpzM0xFR1NSSTRXbjZYUDRSenpjWnN1VzBKV1JpSUhqNWJSMU53eHphUUZxOVZFMzN2Y2cyQmgya2o3OTJkM0FyQnlhZjY4SHcyZmxob2ZzTFFPMTZTTHBrVkJJRFU1am9TNEtOeHVMN3Yzbmh6enNWa1ppYXhkdVFDZno4OWpUNzA1NmV2cTYzY2lEMmtnU0JweFZFdHJNdXB4RERqbkptbmIycnM0Y2JvU1NSSlp0M29CRVJFaFJjUHhJQ1k2Z3B5c2dLRGU0U0haK2JIQVpES3dlbVVoa2JZd1huaDVMLzJPeVJHb282c1h2MTlHSTRtalpnRUVRY0FXYnFHM2Q0NWEyamQzSHNQdDloSWZGMFYrVGhyYU9USnRwcTZoYmRKcUtNRkFlTGlGcElUb1lRTXdIaXhmbkVOY3JJMitmaWVIanA2WjFIbjA5UTBneXdHcHpramI2TGwxVVJUUlRjR3puaGJTN3R4ekFnaFV3R2VrejQxcE0vVU5iZHo2MGYva1F4Ly8zcmp6bk9ka2hBUlJDRXA1cGNtb3gyYXpJZ2dDaDQrWGordlk2S2dJTWxJVEVBU0JnMGZMSm5VZTlvNWUvSDQvR28xRStwQUxkQ2xvTlJJdXR3Zkh3Q0N5ckZ5Z29EaHJTZXNjZEhQOFZDV1NLSktabGtCaS9Oem84eW81VTRmUDc2ZmZNVGh1Z1lsem13clJVZUZFUjBjRUo3aUxqcGl3R3VUaWhWbUlnc0RwMGhyOC9vbG5FUnFhMnZGNi9lajFPbEtTWWtkOWY1alZUR1NFRlh0N056dmVPa3hyYStla2hPZW1qYlFuVGxVaSsyVk1aZ01GbzFXN3p5SlUxN1hnOThza0prUmpIV2RsVXVOUWRaTkJyd3ZLUXdwWUxjM3dNR3F2YjN3MXN6blp5UWlpUUZkUC81Z2JFMGRDUzJzWFByK2ZyUFFFOVByUm14TnRFVlpXTDh2SFpqRmlNUVN5R1FYNWsrZkFsRmVwMU5TMW9pZ0JUZEtzakxtVE5haXViY2J2bDFsV2xEUHVZeXVybWdJUytqWnJVUGJhMzQveFRsTFB6VXBCRUFRR0J6M1VOYlNSblprMDd1L3M2WFhRM05xQkxDc3NYeksyb2RCNnZYYllqY2lad0hmT21LVnRhKzlDVVZVTUJoMXB5WEZ6Z3JDdDdkMjAyN3RSVlpYQ0lUMnI4YmtXdGVoMVdwSVNvcWVrZzFpU3h2ZllJbTFXd2l4RzNHNFB6UzBUeTljMk50dHB0L2NBc0hiVmduRWQ2NU1WWEQ0L2ZrV1pHNlE5YzdZZVdWYXdtSTFFenBGcXJ0YTJUbnI3bklpaU1DekNObFo0Zlg0T0hTM0RaREtTbHgyOFhUKy9MQ01yQ2luSnNlTStWaEFFOG5QVGhsUU1KeFlNTlRUYWFlL29JU295YkZ6ZEpRNm5tNWZlUE1RbnYvQS8vUERuVDlEVU9zdDd4QVlIM2NQK1Z6QWY0SFNrdWpxNyswaUlpeUkxWlh5cnc5SGo1Y2l5Z3Nta0p6c3JPTU5LL0g2WitzWjJIQU9EeEFVcHNCc1BQQjR2RmRXTjlQWU5zSEhkNGpFZkZ4aXNkNVRqeFdmNTNuZnVKVDh2amI4KytkcmtOMXltOG1LN2V4M0QvVXFKUTNuRzJRNnYxMGR0ZlNzREE0T3NXSm8zN3VQM0hEaU5YNWJKejBrZHpxMU9GZ05PRngyZHZRQ2t6SUNMMWRNM1FObFFRZm5tRFV2SGNaeURxcHBtTm0xY1JuaTRsYlZyRmhGaEM1OTB5ZWEwYmVQT2xVTHZucjZCb2VCUlpjTzZvbkVISzZkS3E1RmxoYTJiVndUdG5IcjdCbWdlV2xZbjhrTUtoZzl0ME90SVNZcGhVZUhZNXcyN1hWNUVVY1FXWVVVUUFtMUJXWmxKOVBSTVRraHdTck1IVGMwZDlQV2QyenFjR3hvRzNUMzkxTlMxWURMcDJiQjJmS1E5V1ZKTlUwc0hZVllUV3pjRmo3UmQzZjNVMXJjaUNIRFo2a1dUK3F5SlBJV1lxQWdlL0o5L0d6KzVOQktvQ3JJdmtCdFdmREpOalcxa3BDYk1YdExPTlV1cnF0RFczazFqazUyVnkvTFJqVU1vemVYMnNQOVFDZmFPSGo3eGtXc3dtdzFCT1NkWlZpZ3JyNk96cTQ4RkJlbEVSRmdtOURtMURXMFk5VG9TNHFmUFRZdUpqaUE5TllFbi8vNDYwWkhoK0dVWnM5bkE0a2tXLzA4YmFlZUNUeXZMTWdlUGx1SDErVm0xdkdCY01rTU5qZTBjUGw1T2VKaUZqOXl4TlhoQmtOZkhqdDNIQUxoODNXSzZlL281VzlrNzZuRUxDakxRRGJYR2RQWDAwOUhaUzNSVU9ESFIwNmVMSmtraTEyNWZTM3BxSEpYVnpTUWxSck44U1M0bW8yRnVrSFl1d09lWDJYdmdORmFyaWNMOHRER3IzUGo4ZnQ3WmY0cUtxa1krZE9zV29pS0RSNHl6VlkwY0w2NEFZUGUra3h3N1dVbjNHTnBudnY3bE80ZmRtOUl6ZGFpcWl0bGttUGF5VUwxZXkvSWxlV1Bla0FpUmRweW9xbTZpdXJhRmxjdnlTQjhxTWhrTDJ1MjkvT254VjBsS2lPYjZxeTRMK0hKQndrTy9mdzdQa0pSUWFYbmRtSTlyYmU4ZS92dFVTUldLb3BLWm5qaHA4YmZaZ0dramJXdGIxNnp2dk4yNXR4aFZWU25JVFNNKzFqYms1NnA0UEQ0OFhoOCtueDlWVlpFa2FVaXlVb2RmVnZqVmIvNUJUNitEMjIvY1JFRnVhdERPNThDUlVuYnZPNG5Cb01OcU1lTDErdEhwdE9pMEdySXprOGpKVEI1UkJ0VmtNbkROdGpWQVlGT2krSFFWaXFLd2Nsbit2QkQxbTFMUzZuWGFZYXZUMmRVN3EyK0VjOUROYy85OGgwaWJsYUtGV1dnMEd1b2EyamhiMmNDQnc2V2NLcXVob3FvSnI5ZEhRbndVSzVmbGMrOUhyK0hBb1ZKZWZIVS95NWZrY3UyVjY4WVZ2RjBLOW80ZWZ2M3dNd2lDd0pvVmhkejN5WnZRYUNRS2NsTkhIRWwvTVpTVTFkTFFaRWVqa1ZpN2NnSHpBVk5LMnNoSTY1enB1TjEzOERUTnJaMFVMY3dpTnp1RnA1N2J5U3R2SHFMNFZDVm1zNEcwbEhoV3ZNY3YwMGdpYis4K3ptTlB2WW5Sb09NamQyeWJVQ0hLaUprSWw0ZkgvdjRtSldmcUNBOHo4NkZidHd5TEdvOEhpcUpRZkxxS2pxNWVWaXpOSXpjN09VVGEwYU5IQ1ZHY0c4dlJ5MjhjUkpKRTFxNWNnRllqOGR4TGUyaHM3dURUSDd1TzFTc0tpWW1PT0svam9yUzhqdi85N2JOMGRmZnp4Yy9jSERRdE1rVlJlT2ZBS1o1L2VTOGVqNWQ3N3J5UzlXc21scHZ0NnU3bitNa0tCZ2M5M1BlSkcrZE43REZ0UG0xdGZkdXN2UW5sRlEyY1BGMkZWcXZocXEyclNFK041N0hmZlF1VlFJTDgvYVdBamMxMkhubnNWU3FxbS9qQXB1Vjg1dU0zakx0YzhGTDM2Y2UvZUlJMmV6ZUxDalA1MG1kdkhYZFYxM3N6RC9zUGw1S1huY0t5SmJraDBvNEZvaWdPTy80RGt5eVNtQ29vaXNJNyswL1MwemZBa2tYWkZPYWxBNHpvbXlxS1NrTlRPOS84cno5UWVxYVdxN2V0NFlHdjN4TTB3dG83ZXZqdUR4K2h1YVdEeElSb3Z2ZU5leVpNV0tmVHhUTXY3TWJsOHZDUkQyNExha1pqZnZ1MEVSYU1odG5oMDNxOWZsUlZRZisrVGdKN1J5K0hqcDdCNy9QenhVL2Zja2svOCtEUk1oNzQwWi9wN3Uxbis1YVZmT216dHdVdGhkVGExc1Uzdi84SGpod3ZKeTdXeHI5OTloYnlKcEdKa0pXQUFOeUd0WXRZdTNMQnZCb0ZNS1drTlJqMHM2Yno5azlQdkVwVHM1MWJiOWcwSE5Rb3FzcUowNVdVbmEyak1ELzlvc0ZPUjJjdi8zaCtGOCs4K0E2dDdWM2NjdjFHUHZlSkcwbE9pZ25LdVpXZHJlZTNmM3FSL1lkT1k0dXc4cG1QMzhDMlRTdlFhaWIrZU13bVBmLzJtVnZRYUtRUlozcUZTRHNHTkxaMHpPaUY3dHB6Z3VMVFZXU21KdzZUMCtsMGNmQklHZDA5RHI3N3RZK09xQWpZNzNEeXN3ZWY0clVkaHdENDhuMjM4Y0ZidGhBUmJnbktlVlZVTmZLam56L09zZUt6cUNyOCsrZHY1L3FyTDV0MGI1a2tTWE9xSjI5V2tkWmlOaUlJd296UHRWVVVGVmxXenV0R2JXbnI0cFUzRDVHZG1jVGlSU1AzZ2prR1hPemFlNExZR0J2LzhhVTcyWEo1Y0JYTGErdmJPSEdxZ2pDcmlXOTgrY1BjY1BYc1ZaTDArMlZVVloxeEFld3AvL2JrcEpoWm0vWjY3Tzl2NG5LNXVmN3F5eTVhaFJZZkc4a3pqMzQvb0Qwd0JjbzRpeGRsOFpNSFBrMW1ldUtzdG93dWw0Y25uMzZMdXNZMjd2L2M3ZGdpTFBPWHRMTVZGVldOdlBUNkFYS3lVdGl3WnRGRjU3VktraGkwRG9TTC9TaXUyYjUyVHR5em84Vm4yYkhyR01zVzU4Nm90dkMwNnRPMjJidG54YzMzZUh6ODlNR244UHY5YkZpN0tHZzdXZk1aUnFPZTlOUjR0RnJOdVBURTVpUnBBeWt2QVVWV1pvVXVGc0NiTzQreS85QnBZcUlqdUhaNzhPb0ZwaHYyamg0K2Z0OVBXTHYxYzN6ciszOFk3aU9iS21SbkpLSFhhVGx4cW5KK2t6WTFKZTQ4M2YyWndya2IzZHpTd1IvK0dwaHNlT1dXVlhONlA3N3NiRDFucXhycDZ1NW4zOEVTemxZMVR1bjN4Y1ZHb3RGSzlQUTY2SGNNemwvU3ppWklra2hQM3dCYXJjVGloVmw4NW1QWGovc3pHcHZ0bkNxdG9jM2VqYUtvOCtiZURBNjZPVk5SUCtJUTVtRkxtNW1FUWFmRDU1ZXBxV3NKQldMVEFiUEp3UElsdWR4eDAyWmlZMnlFalhNM3E3Uzhqdi81OWQvbzdPeGoxZko4UHZXeDY0SXlyV1UyWVBlK2t6enkyQ3RjdTMwdGQ5OTU1VVVzclkxSVd4aDkvVTZxYTF0WXNpZzdSTnFwdDdRU2tSRmhyRnU5Y0VMSGw1K3RaLytoa3VIQXBMOS9jTjZRdHJhK2xiS3o5VmdzcG91U0ZpQTNPNW1xbXFZeERlU2I4KzZCeSsybHRyWmxUajlZZVI2NUErOUhTbElzR2ttOFlKN3QrN0VnUHdPdnp6K3UxcCtRVHpzQlRIWXMwbFRDNS9QenlHT3Y4SjMvOThlZ0RhbWJVSkFWWjBPVVJEeGUzeVdIaWl3c1RBZWdyMytBdHZidUVHbW5DalZEUStORVVaaHdxZDlVb2FXdGkxMTdpNmx2YkdjR09VdHlZaXlTR0JqVzNOVno4VzdmM0t3VWRGb05QYjBEdExSMWhrZzdWVGpYeldvMkdZTlc2QklzZEhYMzBkcldSVnBxUEROWlBSZ1hZME9TUlB4KytaTDlmRmFyaWJ5Y1ZIcDZIVFMxaEVnNzVkQnFwRm0za2VEenlYaThQakpuV0hCYWtrVE1aZ09xeXFoVElaY1c1ZERYUDBCRFUvdVlKa2lHU0RzQnpLU3ZPT1lITVZreks0QXdTYjIwL094VVBCNHYxYU1FekpldFdZaWlxRFMzZEV4YXRuTWkrSmRJZVhWMEJKWTdVUkluMVhaaUM3ZGdNT2p3ZW4yRVdVMWptanN3NmdQUVNPaTBXc3JPamo4YXQwVll5VWlOeDJJMmtwWWFUOXlRVmtOUWZ1aGNYS3h1OGNJc2pBWTlOYlV0OVBRNnB0M2xtamJTaXFJd1krM2tyVzFkUXo2dGdmRHdpYmZIckZxZXozOTg2VTRHQjkwVTVLVUZwU01nT2pLTWhQZ29qaGRYNEhaN3gzV1BGdVNuODQwdjM0WEw3Y0VXWVEzcVRBdFpVUkFGWWNRVlFLdlJrSitiU25WdE16MjlEakxTRXVZbmFYVmF6WWhxS05ONnNVTldiYUlJRDdmdzRkcytFTlJ6aW8yeGtab2N5OUVUNVJ3NFVqcXVWblNOUm1KQlFmcVUzQ3RGRFJCWFA4TEtwTk5wS0ZxUXlZbFRsVFEyMlZsYWxET3RQV2pUNXRNS2dvQkdHNUlPZXorTVJqMUxGbVZqTVJ2NTBTK2VtRlhuNXZhTlBITk1vOVdRa3hrb05EbzVKQ0lkQ3NTQ2pJcnFRUFdUeWFnblloWUtzSzFmdTRqMDFIanFHOXI0L1Y5ZW1wR0lmQ1NuVmxGVmZDT2NpeVNLcEtYR1k3TlpPVjVjRVNMdFZHQncwQTJBWHEvRFpETE11dk5MaUl2aTV1czJJZ2dDei83ekhVclAxTTRDenFxb2w3QzJzVEVSWktVblVuYTJudmFPbnZsRldwL1hqMG9JbytHNks5ZHgyZXFGMURlMjg5aFRiMDU1UWZlb3BGVUQxUFhKOG9oam5HSmpiR1JsQkRvK1huL3I4UHdpYldPTGZYakE4VXlob2NtT0pFbEJUUWtGR3hhTGtlOTg3VzdpWW0yOC92WVJYdHR4R044NHg0bE9GazZYRzBFVXprdmxxWUIzaE9YZlpOU1RrWmFBMGFCbng2NWo4OHpTRHQxNFVSSXh6WkRhVEhkUFA1SW9FRzZkM1lMQ0dXbngvTWUvM1lrb0NQejBmLy9HemowbnBuV1ZLcTlvUUtmVmtwd1lnNktxdzdVUVByOHlZbUJkbUpkR2RGUTRKMDVWMHRiZU5mOThXcjFPT3lOS0o0cWlCQjY4SUtEUnpQN3N4Zm8xaTdqenRnK0FJUERWNy95R1l5Zk9Jay9EU3VYeGVGRlZGVUVBalVZejVORUdJS3ZLaUdXWitibXB3NnZYL3NPbG9VQXNXT2pzNmtQMnkyZ2tjVmE3Qis5MUUrNjg3UU5jdVdVVnNxenczUjgrTWx4NFBwVm9idTFDVmhTMFdnMHgwZUhuVlp3cEtpUE90WTBJdDVDWEV4QjVmdVB0SStjSm9jeHAwamExZE14b0wxV2ZZeEJaVVJBRUFkTWNFWGhPU29qbU14Ky9nY3lNSkt3V0U4KzgrTTZVZjJkcmV4ZUtyQ0JKSW1GVzgzbjFHcXFxWHJRQWZzUGFJalNTU0dWMTgvQ0F2amxQMm9FQkY2cXFFaDBWTVNNRWNMdUhsajFSd0dEUU1WZnd6cjVpbXBydFZOZTFjTjJWVXkvbTBkUGpRRkVVZEZvdENRblJ2Sitqc3FxTW1FVllzVFFQU1JMcGR6Z3BQbDAxdjl5RHhCbndaMlZab2I2aERaL1BqMVlqa1p3VU8rdkpxaWdLYis0OHhwK2VlQTJmMzg5SDd0akdsc3VYVC9uM2xwYlg0dlBMNUdRbkl3ckNlVDR0QkZxTlJsb3h3NndtcnQ2MkJzZUFpK0pUbGRPU0tacmFLZVF1RHo2L2YwWWUvb0RUeGN0dkhHRFgzaE40ZlRLQ0lGeFUrbWcyb2ZoMEZiLzk4NHYwOURyNHlCM2IrYmZQM0RJdFA1U0dKanV5ckpBVUg0VXk1TWVlL3g1MVJFc0xjTTIyTlNpS1FtMURHNjF0VTkrQ002WGhkSGRQLzdDcVROUTBGOHUwdG5YeDBPK2ZIMjYxQ2JPYWlJdVozWUZZdTcySEgvL2lDVXJQMUhMckRadTQ5NlBYVEUrdzJ0MVBkMDgvcXFxeWJIRnVJT1B5UG9LcWdId1IwaTR0eWlFcU1venFtbWFxYXB0SVNwemE2WnpUNWg3RVRYT3J0ZGxzSUNFK2F2amZnakM3ZmRyVzlpN3UvK2FEbkNxdDRmTExGdlBKdTY4aDBtYWRsdTl1YnVtZ3QzY0FnTUw4OUl1UzA2K29JL2F4bWMxR0xsdTlpSTZ1UG1ycldxYzhpekNscE8zbzdNWHBET3o3VDdjMFVuUmtPRVVMM2xYMnpzbWF2U0p6Ym8rWG4vL2ZQemhXZkphMGxEais0LzRQazVvY04yM2YzOURZVGxkUFAxYUxrZFNVdUl0bUNtUkZ1Y0RYUFljUGJGb2VHQUZWVWozbDNReFRTbHBCUjJZdEFBQWdBRWxFUVZTUHh6ZjhxOHZKbWw3TkxKMU9TMEZlMnZDY1dxdlpPR3RKMjlzM1FGZDNIMmtwOGZ6Z3UvZVNrUm8vcmNGcWJYMGJ2WDBEckY5YmhLb0dMT3JJcEZVdjJqRmNrSmRHZkd3a1pXZnJwbHpuYTBwOTJnR25DNjh2MEFscm1JRXQzTXlNSkJJU291anE3cHZWdm14OGJDUmYrZndkU0pKRVhrN0t0SDUzWjNjZmxUVk5BS3haVVlpc0twZnNxZk1yQ3BKNFlXRzQxV0prWVdFR08zWWRvNktxaWJTVXFWc3B4S20ySU9lRU1sS1Rwei9kWkRUcTBlc0NmbXhOWFNzRFR0ZXNKVzVoZnZxMEUvWmM4SGRPTFdiVjhvSVI2d3plYjIxSGdzVmlZbEZoWVBieG52MG41NjU3NFBYNmhndUVaMEp2b0tPcmw3NytRSURSMU5MQkcyOGRJWVQzWkFSVWxjYW1kdHJhdThsSVN5QTJPbUxFaXE3M1c5b1IzVEd0aHNLOE5PSmliZXliNG0zbktTV3R2YU9IQWFkcnhnUXlmRDcvc0U4OTZQTHd5bzVEczBiWWVUYkE1NWZaZDZnRVJWRllzN0lRUVpJdW1vc2R6ZEpDWUw1R1VrSU1qYzEyU3NwcTVoNXBmWDQvYmsvQW44M09TSm9CS3hLWURYc3VrcFVraWFycUpnNGVLWjBUT2dqVGtyVndlOWk5N3lRYVRVQ3ZWeGxEYzJLZ1pISGsrNWVjR0VOMlppS2lLUEw4eS92bUhtbWRUdmV3SmxSaVF2UU1QQklWeDhBZ3JpSEx1bVJ4RG0zMkh0NSs1d1I5L2M0UVk0R1NNN1YwZFBhU2xCQk5aa2JTUmZPekYxamJpN3hQcjlkUm1KZU95YVRuclhlT0Q3YzV6Um5TdWx5ZVlYSWt2aWZKUDMyVWhYNUhnTFRwNlFsODdLUFhvTkZJN054emdxcWE1aEJqZ1JkZkNWakRySXdrSW14aFkxNkIvUExGMzFlME1Jc3dpNG1Pemw3S0t4dm1GbWs5WGgvT29XaDlTVkhPdEQ4UWw5dUx2YU1IVlZXeG1JMFU1R2V3WmZNS09qcDdlZkxwdC9ETDhyODBZVHM2ZW5qeGxmMW9KSWxGaFJsRVJvV1B1VXRDdmNRN0MvUFNpWXUxSWN2eWxBVmtVMFpheDhEZ2NIT2UyVHo5SGJCZXI0OSt4NUNsVDRqQlpESnczVFhyaVk2SzRKK3Y3ZWVkZlNmbkJMbmNIaThPeDJEUS9mQlgzenFDWDVaSlRJaGljVkhPcUFIWStSbUVpNzlYRkFVMnJWK0tvaWljS3FtZWtvS3BLU1B0b010RFgxOGczYlN3SUdQYUgvYmdvSHRZOURkeHFJQWpKenVGTFZlc1FLZlQ4cE5mUGtsRGszMTZyYi9MUTc5amNOU2llRVZSNk83cDUraUpzL3oya1JmNXc2TXZCMVVZMmpFd3lJdXY3RU1RQkZLVDQ4akpTUjJYeXZsb1A2RFZ5d3RRVldodTZhU3lxaW5vOTNGS2RzUlVOYkN4ME5NM1FIeHM1T1FWQVNmaW5uaDg5UFFFNXZFbUpRWTJOaXdXRTFkZmRSa25paXVvcUd6ZzRVZGU0TnRmL2VpMGREVDQvVEkvK2RXVDlQUTZTRTJPSXo3V1JtTDhoUUZxWjNjL2pjM3RWTlUwMDloc0o5eHE1bzZiTjA5S09PLzlPRlpjUVZOTEJ4cEpZdDJhUlJoTmhoRkZPU2FTOW9KM3QzUTd1L3NvcjJ5a01EOTk5cE5XbG1XYWh3UjMwOVBpRWNYcGIwWHorZnc0bklORGx2YmRFZmRabVVuY2RQM2wvUFNYai9QVzd1T3NXSkxIemRkdm5Qb1RFc0NnMTFKU1ZzT3VQY1ZJR2hIakNKUEdSVW1pTURlVmd2eDBQdjJ4NjRtTHNSRWRIWTVHQ2c1cFhTNFBiN3g5aEw2K0FTSWpyVnkxYlEzK0lDdkVHSTE2MXExZXlQTXY3NldtcmdXL0xBZnQvS2VPdElwQ2EzdUF0QW14VVRNeTBMblA0YVM1dVFNQnpwdHRLNGtpTjk1d09Yc1BuR1RmL2xNOCt2YzN5TTFPWVdIaDFMb3dHa25pNi9kL21LL2YvMkVnVU96OWZuOHZMenVWTUt0cFNzK2pzcWFaa2pPMXlJckM5aTJyQ1l1dzRwMkNVc0pycjFyTHMvOThoNHFxUnV3ZFBTT3VLclBLcDVWbG1hYm1BR2t6TWhKbXhOS2UyOWlJam81QUdtRnAvZjUvZnBxc3pHUkt5K3Y0ODVPdjBUN05jM3VYTE1wbTVkTDg4MTVUVFZpUHg4ZmVBNmVvcW1uR0ZtSGxVeCsvZmx4dXdidlpnOUZkaEpWTDhvaU9DcWUydnBXT3p1QVdMRTBKbS93K21jb2gwYmVVcE5ocHQ3U3FHbENwQnJCWVRTUFc4aHFOZXI3d3VkdElUb3JsMVRjTzh2Q2Yvb25YT3pPdFFkT0Z1b1pXWG4zekVINi96RWMrdUEyVHhUeGx1NE9pSkxGcWVUN05MWjNVTjdRRnRTTjdhaXl0b3RCbTd5RXN6RXg4Yk9TMGFwY09CelJEd3k3aVlpTXZHc1FzWFpMTGgrN1lodGxpNHVrWGR2SHdJeS9NYTlJKzgrSTdWTlUyazVXUnlKYk5LL0ZOWWE1YUVrVldMeS9FTDhzY1AxV0pkMmhZeTZ3bDdhblNHcnhlSDlHUllUT2lOYUNxRERmWW1VMEdoSXU0SnpxZGxpdTNyV0h6eG1YSXNzSWpqNy9LazArL05TOEpXM3k2aWllZmZndFJGTG5oNnZWRVRYRy9uQ2dLNUdRbFk3V1lPSEM0RkxmSE83dEplN0lrMFArZUVCK05kWXI5dEl0R3lVTTNLU0VoR3UwbDBrVW1rNEdQMzNNZFJRdXpHUngwODZmSFgrWFEwYkxab1JFYkpBeTZQUHpuai82RTErZWphRUVXYTljVkJUV0ZkakhFeHRnb3lFdWp0cjQxcUhLZ1UwTGEwNlVCZmRYVTVGZ2l3cWEvTEZGRnBhWTJVRitnMSt0R2RVK2lveVA0OHBmdUpDODNqYnFHTm43eXF5YzVmUHpNaktzOUJpZjQ4dkxiUDczSTJjcEdMQllUMTF5NWp0VFVoR2tSdG91MFdZZmJySGJ0TFo3dDdrRTFvaWdTRXhXTzBUZ0RIYkRxdTltRHFNZ3dwREhrQ0xNeWsvakcxKzVtMmRJOFNzcHErZTlmUHNuUkUyZm5OR0VWUldIZm9SS2VmM2t2aXFLd2FmMVNMcjk4MmJpMmJDY0RpOWxJYmxZeVJxT2VIVHVQelY3U1Z0VUVKcDZFV1Uya0pNZU5pVEJUa1Qxb0djb2VoSWRieGp4YU5EY25oVS9mZXhONXVXbVVsdGZ4amYvNlBZZVBuWm16cEsycWFlSDNmM21aZG5zUGFTbHhmT3p1YXpGTmM0Tm5lbW84TVZIaG5LbW9wL3NTNDB0bmxMUUhoaVFmSThJdE0xS1NDSUdXRUkvWGgxYXJHZGRPakNBSUZDM0s1b3YzM1U1S2NoeU5UWGJ1LzhiL2NmUkUrWndqckdOZ2tGODg5QlRIaTg5aU1HaDU0RHYza3ZDZW5jSHBRbHBxSE5GUkVYaTlQbzRjTDUrZHBEMVZWajI4TEtlbXhNM0lBMnRvYkFmQVpndWJVQ0M0YkdrZUQzem5Yakl6a3VqbzZ1V3IzM21ZbDE0N01LdW5tYjhYL2YxT0h2ejljN3kxK3pnR281NVAzSE1EdWJucE0zSXVpZkhSSk1RRjBwNkhqcDZaZmFUMWVMeVVsTlVpQ0FKeHNaRkUyY0ptNUVZRkkxSXRMTWpnTzkvOE9NdVc1dEZtNytGbi8vY1VqLzc5amVFYTRkbUs1dFpPZnY3UVAvalRZNjlpTWhtNC9wb05YSDNsMnVCdjhJemo0NG9XWktIVGFUbDlwallvNmpOQkpXMXRmUnY5amtHMFdnMExDekttSmEweUVucUhTaUxEdzh5VG1tYVRuNWZHVisrL2k2MWJWdEhXM3Mxdi92Z0NEL3o0ejhNcHZkbUdzNVdOL1Bldm51UWZ6KzlDa2lRMlhMYVlEMzlvT3hFUjFxRHpkVHlWZS9tNXFlaTBHbHJidXJCMzlzd3UwcGFXMStGeWU5QnBOU3hlbURWakQ2K21MaUE2WnpEb0pqMTFQQzB0bmkvZWR6dTMzcndabjkvUFAxODd3RmUvOHpCUFB2M1dySElYeXNycitlNFBIK0hOblVmeCtmeGN0WDB0OTMveFE4Uk0wU2JDZU94Mlpub0NHbzJFeCtQbHpObUcyVU5hVlZVNVZueVd3VUUzZXIxdVJncS96OEVYeEtvbFFSQ3cyYXg4NlFzZjVEKys4bEdNQmgwTlRlMzg1NC8reEplKzhTQm5xeHJ4K21hbVprRlZBMjFOTzNZZDR4TmYvRzlPbktwRUZBU3V1ZW95dnZYMWV3aWZvZGI5OXlQZ0tscnhlSDNVMUxWTSt2T0NWcHJZYnUraHVhVVRSVkZadmlSM3hvWTNCd0tSZ0h0Z01oa3c2SU9YSjc1cSsxcUtGbVh6aDBkZTRNalJNbmJ1T2NHQnd5WGNkdU5tcnJ0eUxha3BjVVNFVzZhbDFzTGw5bkRtYkFQUHZMQ2JmN3l3QzFFVVNJaVA1b08zYitYRzZhZ1BIaWVXRk9WUVU5OFdsRzZSb0pHMnJyR05sclpBT2VLR3RVVXplb01xcWdJVlpoYUxFVU9RZnp4SmlURjg3Y3QzOGZJcmUzbjBpZGV3ZC9ieTZOL2ZZTWV1WTZ4WldjamFsWVdzV2JsZ1NvZVNIRDlaeWR2dkhPZU50NDlRMzlpT0lBaXNYYjJJbTI3WXhNb1ZCWk4yaVViRFJCUXdWeTByNE9rWGRnOEx1Rmdta1M4T0Nta1ZSYUd5dW9tV29SSDFXemV2bUZIU1R2VitqOWxzWk9uaVhQNzV5ajdzbmIyQnpZeTJUcDUvZVErNzloYVRsaEpMZm00YW05WXZZZVd5L0VrOW9IUG82M2R5OEVncHIrMDR6Sm1LZWhxYk8vRDUvS1FreDNIRDlSdTVZdE55NG1JanA2VjJlU0lyeVRtaFpjZkFJTDI5QXpOUDJyNStKNmRMYS9ENS9LeGVVVEJ0WXNBWDg2M2IyM3VHM0FOalVOMkRkMzhVS2hxTmRFRjJSRkZVdW5zQ3F0b25TMnA0N3A5N3NGaU1MRm1VellaMWkxbStPSWZjN0xHTHpOWFd0M0x5ZEJYdjdEL0ZzWk1WZFBjNDhIcDlxS3FLelJiR3JUZHY1b1pyTnhJUllSM3pybDh3TUpIczJiTEZ1UUhYelRGSVYwOC95VWt4TTB2YW5sNEhwMG9EMmszYlp0akt5cXBLUyt0UUFialpPR1crZFZKQ05IRXhOc3FHRkFkSFduM2NIaTl1ajVjZHU0NmRONG96UFRXZWNLdVo4SEF6cWNubmE5RlcxalRoY0RocGJPNjRRSnhZRkFVSzhsSzVZdE5LdG05Zk0yTVRneWJTcUNwSklucTlGcjlmbnZUNDFLQ1F0cjZ4bmNabU95YWpudVZMOHBqL0VBZ1BzNUNhSEl0R0k0MDdZVjdYMFBhZWY1MGFkU21PaTQxRXA5WGdjbnQ0N0hmZkJvMEdqMy9teEVha0NRYWFCYmxwTkRiWjZlenFtM25TdnIzN09ENmZueFZMODRpUGk1cFJPcDJyN3BwcUYwUlJWV3hEeS9KVXpSZ0lzNXJaZHNVS05tMVl5dTY5eFpSWE5DQ0tJdjRaRnRDVHhKa2Q5RGxwMGpvSDNienk1aUVBMXExYWdNVXlzekx4alUyQnVnT2pVVCtsRWJ5S1NwalZQRlRGRnR3ZlNwUXRqSnV1MjhEVlc5ZVFNaVJHL2ZZN3gwbE9qRUVTUlh3elRscGhicFAydFIySGNBd01FaFVaUmtGZU9qcnR6QTVOUHRlY0tJa2lXdTNVcG41aW9pTXUyUlV4TGo5UkZCQUZrWS9kZFJXMzM3VDVQUG4zTm5zM2ZYMU9MQ1pEWUN0cUJqbXJFV2QrblBLa0dPYnorWWZudGhZdHpDSXZPMlhHTDJqYXRHZlZkNFhZSkVraU9UR2FscmF1Y1FVWm9pQVFhUXNqSlRtV2pldUt1UDNHVFNOdXU3cmRYdnI3QjBoT2pBNEVRZXJNZFZUTWhGcFFVRWxiWHRIQTBSTm4wZXUwTE1oUEp6bzZmTVl2cUdlb1dFYVV4Q2xOc2lzd1BPbEZyOU55eDgxWFVGUFh3dXR2SFJsMUpKSFZZaUl2SjRYOG5GUldMTTFqMWZJQ29pOHhITkR0OXRMbkdDUTIxb1lvQ3NnemFHa2xhWTZUOXZraGZkUG9xSERXckNpY2NRY2RHQmJkME90MTJDS21ObCtzMDJvUWh1Ykl4c2RHY3RPMUc3aHM5VUtlZm1IM0JUS1hacE9CaFlVWkxGMlVROUhDTERMVEUwaE1pQjVUSHRuN0h0blVhVjFOUm9CMkxyc0hUUzBkSEJscVJjbkpUaGxPSHM4MHpuWFJpcUtBUmp1MXBaR0ppZEZvdFJvODNuZjcwYTdhdXByMWE0c29QbFhKemowblNFbUtaV0ZoQnVtcENSZ01XZ3g2UFRxZFprYTBJQ1lMUVJCbVJPSXFLS1JWZ1VOSHo5QTJaTld1MmJabXhtcG5MeUN0TWoxV1NGVlZSRkc4b0VSUEZFWEN3OHhjdm40Smw2OWZFdVR2RE54N1NSUlJWSVhwTnJpU0lEQnB5Z293MmQvcmhHeTl3ekhJL2tNbDlQWU5FQnRqWTNPUUg4NWs0Qm5TT3hCRkVhMUd3M3hDZDNjL3FxSVNidFJoMFduUmF5UzZ1L3RvYSsrYXBzeUJ3R1JvMjljM2dOR2d4MnlhWEZwMFFrKzFzcnFKVTZXQlhyQTdiOXRDV0poNTFqelljdzlRcjlNR3ZXTC92Y3VrVGlOTld5U3QwMmt4bTQxMGR2V2hxQ29Db05OSWVGd2UvdnlYbDJodTYyTDl1c1ZjdHJhSTJDbk1UVXVpT0NrcldkdlFSazVXOHFSeitlTW1yZGZuNS9pcFNwcGFPb2dJdDNMbnJSK1lWZGJvM0p3d1NSTFI2YWZHMGhxMUVucEpZcnJjVW9OQlI3alZoTDJ6NXp3QkVVRVU2T2pvWWYrQlU1dzZWY25yYng1azgrWEx1WHpqMHFEdlRJcUNNS2xOaFdET2J4djNVeDBZY1BIT3ZwUElzc0oxVjYyZHNjRjJGL1ZucDlqUDAyc2tqTk84Z1dJdzZBZ0xNOVBjMG9uNkhwL2RZamJ5ME0vdTU4Q1JVaDc2dy9NY0s2N2dkRWsxLy9mdzAyeTVZaVZYYjEvTGtzVTVRZGxra1VSaFVpdkwyYUVhNTBpYmRkSTdsZU8rKzVVMVRSdzZXa1o0bUptcnQ2NlpkWDZmK3A0bGZLVEJ3NU54Q2ZTU2lNL3Q0ZUhIWHlVbU9vTDgzTlJwdVNhenlVQ2tMWXkzZGgvSDdmR2UxNnlwMFVoc1dGdkVtaFdGSEQxeGxxZWUyMGxKZVIxNzl4YnoydXNIaUkyeHNXYjFRamFzWDBwYWFoeGhWak5tczNIY2diTW9DRXdtY1hCdXBwZ2tTV2dtR1d1TSsrakhuOW9Cd01wbCtUTXlwSGswOVBZRjVpd0VNMDhyQ2dKR3JVUlhaeSsvZnZnWm5udHBEMWR0WFUxY3JHMWFKSWJNSmdPeE1ZR05oY3JxWmxhdnVMQTFYNnZWc0hiVkF0YXVXa0JWVFRQN0Q1ZFFmS3FLaGlZN08zY2Q1Y1dYOXBDU0hFZGhRUWJaV2Nta3B5ZXdmdDNpc1FiOGFFUnhVbW02MDBPbHExYUxDVnVFWmZwSVc5L1l6dTY5eFZqTVJqYXVLNXJSWXUrTEJtSkQzUk1hU2NKZzBBV0hzRG9OOXJaT2Z2blEwN3owK2dHaUlzTzQvTExGREE2NnA2ekM2LzFwdEppb2NJd0dQYWRLcWxtOW91Q1M3OC9PVENJckk0bWJyOXNZRURWdWJLT3lwcGtUSnlzcHFXemtTRU1udHJCSzhwY3RRQklnVENkZHN0eFFtS1EvQzlEUTFJNUdJNUVZSHpYcCtRdmpJdTFqZjM4RGw5dkRndngwRmkvTW5oR2Rya3NoMkZaUEVrVXNlZzJWVlUzOCtCZVBjL1I0UUpEdTN6OS9COWRzVzhPdXZTZW5iWGNxTFNVT1c0U1ZBNGRMK2VROTE0N0JuUW40dkhrNUtlVGxwTkRYNzhRV1llR2VHei9BVVk4R2g5ZlBIODkwREZuUndFNVhyRkdEUlNzUlo5SmkwMnVJTjJvd2F5VWtVVUF6eWM2STAyVTE2TFNhU1hVc2pKdTA3Zlp1WG5obEg1SW9VclFnazRLOHRGbnJ6NTZMckNlVlp0SklHQ1NSOHZKNnZ2THRoNmh0YUVXbjAvS3o3MzJPNjY1Y0YvaVJLSUVFdjFhaklUYzdlVXF2TFRFaG12QXdNM3NQblI3Ny9WQlZIQU11SG5uc0ZSNSs1RVdpSXNNSVg3UUFmM1FpQmdQMGVmM25iVkMwT0MvVWNZalFhMGcwNnlpS05wTnJNeEZsMEtBUkJUU0NNT2JzU1dkbkx4MmR2V2cwR3VLQ29NTXdadEsrK09wK0JsMGV3c1BNWExWMU5iTVJBUktwQ0FJVDFoR1RCQUc5VnNMUk44QnpPdzd6cy8vOUcyNlBqOHowUkw3NDZWdk91L2JtMWs1OFB0K1VsMEFDeE1YWWlJbU9JSHlNT1hGRlVUaFQwY0Fqajc3Q0d6dVBCRnAxY3RPNG9paURUcDBKcjZMUzU1RnhlUDM0RkJXdm91S1JGZnlLaXN1djRKWVZaRVdsMStPbjErT25yRHRRQkJScDBKQVZicVFvMmt5Q1dVZWtJV0NkTHgyOE4rUHp5UmlOT2dyeTBxZUh0TDE5QXh3OFVvclA1eU0zSjRmRkM3Tm5KV243ZWdlR2hETUU5UHJ4RWVsY3dsNEN5cy9VOHZoVE8zajF6WU1vcXNxeXhUbDgvcE0zc1hwRjRYbkhPQWZkeUlxS1RtREtkUjVNSmdNZnVuVUwyNjlZT2VwN3ZWNC9iK3c4d3FOL2UyTllLL2lETjEvQlhYZHNKVE05OGNMSTNxOHc2Sk54K0dUY2ZvVmVqNTgrcjB5UDI0L0Q1NmZiNWFmZDVjUHBrK2wyKytsMk96aHVIeURhcUNFanpFQldoSkU4bTVGNDA4Z3h4S25TYWp4ZUh3bnhVY1RIUlU0UGFVdkthcWl0YjBOVjRlYnJOczZvRU1lbDRCeDBJVThnTU5KS0lnYU5oQUE4OWR4Ty92N00yMVRWTk9PWFpXNjZkZ09mdXVjNk10SVNMaWdXYWJkMzQvZjVrY3hHNG1JanAvejZObTlZT3VwN1d0cTYrTjJmLzhtT25VZXhkL1lTRXhYQnZYZGZ3eTNYWDM3UmtVOG1qWWhKSXhKdFBQK0g3cEVWUExLQzA2ZlE3NVZwRy9SUzIrZm1iSStMTHJlUDlzSEFxN2pUU1lKWng4SW9NK3NTd29neXZFc3JuMSttckx3ZW44L1A0b1ZaUVNtYUg1VzBzcXh3NG5RVkxhMmRXTXdHcnQyK2x0a0tSVlhIdGJjZ2lnSW1yUWFkSkZMZjJNNFBmL1lZQnc2WDR2WDZzTm5DK05aWDdtTHI1aFVYTFI5MHU3MG9xb3JWWXB6eGpnMVpWamgwdEl6LytmWGZLSzlzUUpZVmtwTmkrUFpYUHNMR2RZc25WTkNrbDBUMGtraVlEaExNa0JOaFpGMUNHRjVab2M3aFlWZFRIMlZkVHR4K2hkbytOdzM5SGc2MDluTk5laVNYSlFiU2NxMXRuYlMyZDZHcUt1dFdMUWpLdFk1NnB6czZleWs5VTR1aXF0eHgweFd6cHBwcjVNRGozYjlUVStJdm5yNFJCQXhhQ1dTWjVxWjJYbnhsUDMvOTIrc01PRjJZVFFiV3J5M2lTNSs5bGR6czVJdm1KdHZzM1hRTktWdm41NlRPS0ZrN3UvdDQ1c1hkL1BHdnIrQVlHTVJvMEZPME5KUHZmK3NUcEtmR0J5LzFKZ1JTZ0ZwUllrR2tpUVdSSmxxZFhnNjFPVGpRMW8vREs5UHA4dkdYTSswY3N3OXdlMjRNWlJXTnRMWjFvWkdrVVZOMVFTTnRTMXNucFdmcTBPdTFYSGZWT3VZQ0JEZ3ZSM3R1MzF3U0JMUWFpWjd1UGtwcm16bGVYTUVMcis2bnZxRU5nMEhIaXFWNVhMMXREVmR2WFUza0tOcTZmcjg4bktPTmk0dWM5bXRVRkpWMmV6Y0hqNWJ4MXlkZnA3UzhEbEVVeWMxTzV0cnQ2N2pudzFkT2lWREorNUZnMW5GalZoVHJFc1BZM2RUSHFjNEJPbHgrU3JxYzJJdTl5UFZkOUx1OUxDak1DSnBPZzJiVUNQUnNBKzBkUGF4WW1rZHFjdHlzSm10UGIwQ0JCUUUwZ29oZUk2RVJSU1JSUUZFVVRwZFVVM3k2aXVNbkt5ZzVVMHRiZXplU0pGS1lsODYxVjYxank4YWxaS1Fsak9tNzNCNHZYbCtnK0h2OW1rWFRlcDBlajQrMzl4em5wZGNPY09ob0dmMk9RYXdXRTFkdFhjM04xMjBZeXFGUGI0ZEJyRkhMRFpsUkxJNDJzNmU1ajBQdER1d3VIOTZJR09KV3IrQzJkY0ZyRXRDTXR2UVVuNjRFWU9PNnhlZ04ybGxOMmtHbmE5ajY2VFFTZ2l4VGVxYUdveWNxMkxQL0pNMnRuZlQwT25DNXZhaXFTazUyQ2grOVl5c3JsK1dUbkJnenJwNnlsTVFZN3J2M0pueGVIMnRXRms3Yk5lNDVjSW8vUC9FYVo4N1cwOTNqUUZFVWlnb3p1ZStUTjdGc1NTNWhWdE9NZFVYb0pJRmNtNUVFczQ2TWNBUFBWblZDbUpXVXk5ZmlUYkZORDJuOWZwbDloMHF3V2sxRGtkL3NMcW9XaGw2cUNydjJudUMvZi9VRWZmM084L3haUVJCWXNUU1B1ejkwSmR1dW1MaUVrMTZ2WTlNMEZMK3JLdmo4ZnZZZkt1SG4vL2NVWnlzYmgzTFJBcllJS3grLzZ5bytkYzkxcytvNVdIVVNtMU1paURacWVhemNUaS93am4wUWZXVW50K1pFVDdyN1FUTmErcVN6cTI5SU9TYVN1WVIrcC9zOHdzYkcyTGp4bXZWY3UzMHRPVm5KMDc1OGpvK29LZ05PRjIzdDNadzRWY25mbjkifSwiZGlnaXRhbFRyYXZlbENyZWRlbnRpYWwiOnsiZFRDQ29udGVudEluZm8iOiJNSUlEU0RDQ3h4eHh4eHh4eHh4eD09In0sImRvY1NlY3VyaXR5T2JqZWN0Ijp7ImRpZ2VzdEhhc2hBbGdvcml0aG1JZGVudGlmaWVyIjoic2hhMjU2IiwidmVyc2lvbk51bWJlciI6IjEiLCJkYXRhR3JvdXBIYXNoIjp7Iml0ZW1zIjpbeyJkYXRhR3JvdXBOdW1iZXIiOiIxIiwidmFsdWVCaW5hcnlPYmplY3QiOiJaR1E1T0dNNFpEVmxOVGRsWmpWallqWm1PVE5oTURBMlpUTTBOVGc0TWpObE16STRNV1ppWVdWak9UVTRNakkzT0RoalpqQmxOVGszTnpRek5qYzRPQT09In1dfX19LCJfc2QiOlsiZWxlY3Ryb25pY1Bhc3Nwb3J0LmRhdGFHcm91cDEuYmlydGhkYXRlIiwiZWxlY3Ryb25pY1Bhc3Nwb3J0LmRhdGFHcm91cDEuZG9jVHlwZUNvZGUiLCJlbGVjdHJvbmljUGFzc3BvcnQuZGF0YUdyb3VwMS5leHBpcnlEYXRlIiwiZWxlY3Ryb25pY1Bhc3Nwb3J0LmRhdGFHcm91cDEuc2V4Q29kZSIsImVsZWN0cm9uaWNQYXNzcG9ydC5kYXRhR3JvdXAxLmhvbGRlcnNOYW1lIiwiZWxlY3Ryb25pY1Bhc3Nwb3J0LmRhdGFHcm91cDEuaXNzdWVyQ29kZSIsImVsZWN0cm9uaWNQYXNzcG9ydC5kYXRhR3JvdXAxLm5hdGxDb2RlIiwiZWxlY3Ryb25pY1Bhc3Nwb3J0LmRhdGFHcm91cDEucGFzc3BvcnROdW1iZXJJZGVudGlmaWVyIiwiZWxlY3Ryb25pY1Bhc3Nwb3J0LmRhdGFHcm91cDJFbmNvZGVkRmFjZUJpb21ldHJpY3MuZmFjZUJpb21ldHJpY0RhdGFFbmNvZGVkUGljdHVyZSIsImVsZWN0cm9uaWNQYXNzcG9ydC5kaWdpdGFsVHJhdmVsQ3JlZGVudGlhbC5kVENDb250ZW50SW5mbyJdLCJjbmYiOnsia2lkIjoiZGlkOmp3azpleUpoYkdjaU9pSkZVekkxTmlJc0luVnpaU0k2SW5OcFp5SXNJbXQwZVNJNklrVkRJaXdpWTNKMklqb2lVQzB5TlRZaUxDSjRJam9pY0hsd2IzSXhWa3RDVFdaNFVuSnpUM1J2Tm5KZmIybFpNMVp1UWxZNVNXdElZWFIyZFVsQlJrOUdkeUlzSW5raU9pSlRjV2RCWlhwWlozYzFkRVl6YlZOeVFVNHljMlI1VUZreGVGSjNXa2RHUzNaUWQzTTVNR1p1TlhWVkluMCMwIn0sImlzcyI6ImRpZDp3ZWI6YWdlbnQubmIuZGV2LnNwaGVyZW9uLmNvbSIsImlhdCI6MTcyNjgyNDAwNy43NzYsIl9zZF9hbGciOiJTSEEtMjU2In0.Lykk_21xf1jfaWyeFyPMABSJzcNfzMvLhwxD6VmhHhlDccMl1WA1xZ_qHXbWa4Ky43X9DE3Mqa7aKENESoMUzg~ diff --git a/test/dif_pe_examples/vc/vc-iata-order-sd.jwt b/test/dif_pe_examples/vc/vc-iata-order-sd.jwt new file mode 100644 index 00000000..f555e426 --- /dev/null +++ b/test/dif_pe_examples/vc/vc-iata-order-sd.jwt @@ -0,0 +1 @@ +eyJ0eXAiOiJ2YytzZC1qd3QiLCJraWQiOiIwMmQxYzZkNjlkYWNiNDFlNjA4OTlhN2U4Y2RhMzlmMTJhMjY2NmZjOWMzNGM0MzdiMWY3NGY2MWNmNTBkOTVjNjAiLCJhbGciOiJFUzI1NiJ9.eyJ2Y3QiOiJPcmRlciIsIm9yZGVyIjp7ImdpdmVuTmFtZSI6IlRlc3ROYW1lIiwic3VybmFtZSI6IlRlc3RTdXJuYW1lIiwidGl0bGVOYW1lIjoiVGl0bGUiLCJvcmRlcklkZW50aWZpZXIiOiIxMjM0NSIsInBheFNlZ21lbnRzIjpbeyJkZXN0U3RhdGlvbklBVEFMb2NhdGlvbkNvZGUiOiJITkwiLCJmbGlnaHRJZGVudGlmaWVyRGF0ZSI6IjIwMjQtMTAtMDEiLCJvcGVyYXRpbmdDYXJyaWVyQWlybGluZURlc2lnQ29kZSI6IktMIiwib3BlcmF0aW5nQ2FycmllckZsaWdodE51bWJlciI6Ijc3NyIsIm9yaWdpblN0YXRpb25JQVRBTG9jYXRpb25Db2RlIjoiQU1TIiwiYm9va2luZ1N0YXR1c0NvZGUiOiJDb25maXJtZWQiLCJzY2hlZHVsZWRBcnJpdmFsVGltZSI6IjIwMjUtMDEtMDEiLCJzY2hlZHVsZWREZXBhcnR1cmVUaW1lIjoiMjAyNC0xMC0wMSJ9XX0sIl9zZCI6WyJvcmRlci5naXZlbk5hbWUiLCJvcmRlci5zdXJuYW1lIiwib3JkZXIudGl0bGVOYW1lIiwib3JkZXIub3JkZXJJZGVudGlmaWVyIiwicGF4U2VnbWVudHMub3BlcmF0aW5nQ2FycmllckZsaWdodE51bWJlciIsInBheFNlZ21lbnRzLnNjaGVkdWxlZEFycml2YWxUaW1lIiwicGF4U2VnbWVudHMuc2NoZWR1bGVkRGVwYXJ0dXJlVGltZSJdLCJjbmYiOnsia2lkIjoiZGlkOmp3azpleUpoYkdjaU9pSkZVekkxTmlJc0luVnpaU0k2SW5OcFp5SXNJbXQwZVNJNklrVkRJaXdpWTNKMklqb2lVQzB5TlRZaUxDSjRJam9pY0hsd2IzSXhWa3RDVFdaNFVuSnpUM1J2Tm5KZmIybFpNMVp1UWxZNVNXdElZWFIyZFVsQlJrOUdkeUlzSW5raU9pSlRjV2RCWlhwWlozYzFkRVl6YlZOeVFVNHljMlI1VUZreGVGSjNXa2RHUzNaUWQzTTVNR1p1TlhWVkluMCMwIn0sImlzcyI6ImRpZDp3ZWI6YWdlbnQubmIuZGV2LnNwaGVyZW9uLmNvbSIsImlhdCI6MTcyNjgyMzk2NC4yMiwiX3NkX2FsZyI6IlNIQS0yNTYifQ.mCwhA-JV368G_f2FkAOO3DCixx3Nk-sq1jAu-tph-KMHboyvEIQwB7UJdHR38ZKbhWHLNsY0uFdVFCelTTPY1w~ diff --git a/test/evaluation/selectFrom.spec.ts b/test/evaluation/selectFrom.spec.ts index 149aaae7..d2b9d0e4 100644 --- a/test/evaluation/selectFrom.spec.ts +++ b/test/evaluation/selectFrom.spec.ts @@ -6,13 +6,17 @@ import { IVerifiableCredential, WrappedVerifiableCredential } from '@sphereon/ss import { Status } from '../../lib'; import { EvaluationClientWrapper } from '../../lib/evaluation'; import { SubmissionRequirementMatchType } from '../../lib/evaluation/core'; -import { InternalPresentationDefinitionV1, SSITypesBuilder } from '../../lib/types'; +import { InternalPresentationDefinitionV1, InternalPresentationDefinitionV2, SSITypesBuilder } from '../../lib/types'; import PexMessages from '../../lib/types/Messages'; function getFile(path: string) { return JSON.parse(fs.readFileSync(path, 'utf-8')); } +function getFileAsJson(path: string) { + return JSON.parse(getFile(path)); +} + const dids = ['did:example:ebfeb1f712ebc6f1c276e12ec21']; const LIMIT_DISCLOSURE_SIGNATURE_SUITES = ['BbsBlsSignatureProof2020']; @@ -995,4 +999,23 @@ describe('selectFrom tests', () => { expect(result!.errors!.length).toEqual(0); expect(result!.matches![0]!.name).toEqual("Name on driver's license"); }); + + + it('iata test1', function () { + const pdSchema: InternalPresentationDefinitionV2 = getFileAsJson( + './test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json', + ).presentation_definition; + const vcs: string[] = [] + vcs.push(getFile('test/dif_pe_examples/vc/vc-iata-order-sd.jwt').replace('\r\n', '')) + vcs.push(getFile('test/dif_pe_examples/vc/vc-iata-epassport-sd.jwt').replace('\r\n', '')) + const pd = SSITypesBuilder.modelEntityInternalPresentationDefinitionV2(pdSchema); + const evaluationClientWrapper: EvaluationClientWrapper = new EvaluationClientWrapper(); + const wvcs: WrappedVerifiableCredential[] = SSITypesBuilder.mapExternalVerifiableCredentialsToWrappedVcs(vcs); + const result = evaluationClientWrapper.selectFrom(pd, wvcs, { + holderDIDs: ['FAsYneKJhWBP2n5E21ZzdY'], + limitDisclosureSignatureSuites: LIMIT_DISCLOSURE_SIGNATURE_SUITES, + }); + // TODO expects + expect(result).toBeDefined() + }); }); From 9165816d59a66c863aa8655e7886bbf687ed2c24 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Mon, 23 Sep 2024 10:13:34 +0200 Subject: [PATCH 04/47] chore: version up --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6c171885..1bcf6385 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sphereon/pex", - "version": "5.0.0-unstable.1", + "version": "5.0.0-unstable.3", "description": "A Typescript implementation of the v1 and v2 DIF Presentation Exchange specification", "main": "dist/main/index.js", "module": "dist/module/index.js", From 9fbec915f908e6c14b058355efbf98154ab0271f Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Mon, 23 Sep 2024 12:48:45 +0200 Subject: [PATCH 05/47] chore: fixed VP array and VC possibilities in vcResult.value --- lib/evaluation/evaluationClientWrapper.ts | 119 ++++++++++++++++------ lib/signing/types.ts | 2 +- 2 files changed, 89 insertions(+), 32 deletions(-) diff --git a/lib/evaluation/evaluationClientWrapper.ts b/lib/evaluation/evaluationClientWrapper.ts index 4c16c280..42382687 100644 --- a/lib/evaluation/evaluationClientWrapper.ts +++ b/lib/evaluation/evaluationClientWrapper.ts @@ -4,6 +4,7 @@ import type { SubmissionRequirement } from '@sphereon/pex-models'; import { CredentialMapper, IVerifiableCredential, + IVerifiablePresentation, OriginalVerifiableCredential, SdJwtDecodedVerifiableCredential, WrappedVerifiableCredential, @@ -460,7 +461,7 @@ export class EvaluationClientWrapper { ): { error: Checked; wvc: undefined } | { wvc: WrappedVerifiableCredential; error: undefined } { // Decoded won't work for sd-jwt or jwt?!?! const [vcResult] = JsonPathUtils.extractInputField(wvp.decoded, [descriptor.path]) as Array<{ - value: string | IVerifiableCredential; + value: string | IVerifiablePresentation[] | IVerifiableCredential; }>; if (!vcResult) { @@ -474,16 +475,41 @@ export class EvaluationClientWrapper { }; } - // Find the wrapped VC based on the original VC - const originalVc = vcResult.value; - const wvc = wvp.vcs.find((wvc) => CredentialMapper.areOriginalVerifiableCredentialsEqual(wvc.original, originalVc)); + // Check if vcResult.value contains the 'verifiableCredential' array + if ( + !vcResult.value || + typeof vcResult.value === 'string' || + (!('verifiableCredential' in vcResult.value) && !CredentialMapper.isCredential(vcResult.value as OriginalVerifiableCredential)) // FIXME + ) { + return { + error: { + status: Status.ERROR, + tag: 'NoVerifiableCredentials', + message: `No verifiable credentials found at path "${descriptor.path}" for submission.descriptor_path[${descriptorIndex}]`, + }, + wvc: undefined, + }; + } + + // When result is an array, extract the first Verifiable Credential from the array + let originalVc; + if (CredentialMapper.isCredential(vcResult.value as OriginalVerifiableCredential)) { + originalVc = vcResult.value; + } else if ('verifiableCredential' in vcResult.value) { + originalVc = Array.isArray(vcResult.value.verifiableCredential) ? vcResult.value.verifiableCredential[0] : vcResult.value.verifiableCredential; + } else { + throw Error('Could not deduced original VC from evaluation result'); + } + + // Find the corresponding Wrapped Verifiable Credential (wvc) based on the original VC + const wvc = wvp.vcs.find((wrappedVc) => CredentialMapper.areOriginalVerifiableCredentialsEqual(wrappedVc.original, originalVc)); if (!wvc) { return { error: { status: Status.ERROR, tag: 'SubmissionPathNotFound', - message: `Unable to find wrapped vc`, + message: `Unable to find wrapped VC for the extracted credential at path "${descriptor.path}" in descriptor_path[${descriptorIndex}]`, }, wvc: undefined, }; @@ -517,45 +543,65 @@ export class EvaluationClientWrapper { // If only a single VP is passed that is not w3c and no presentationSubmissionLocation, we set the default location to presentation. Otherwise we assume it's external const presentationSubmissionLocation = opts?.presentationSubmissionLocation ?? - (Array.isArray(wvps) || !CredentialMapper.isW3cPresentation(wvps.presentation) + (Array.isArray(wvps) || !CredentialMapper.isW3cPresentation(Array.isArray(wvps) ? wvps[0].presentation : wvps.presentation) ? PresentationSubmissionLocation.EXTERNAL : PresentationSubmissionLocation.PRESENTATION); - // We loop over all the descriptors in the submission - for (const descriptorIndex in submission.descriptor_map) { - const descriptor = submission.descriptor_map[descriptorIndex]; - - let vp: WrappedVerifiablePresentation; - let vc: WrappedVerifiableCredential; - let vcPath: string; + // Iterate over each descriptor in the submission + for (const [descriptorIndex, descriptor] of submission.descriptor_map.entries()) { + let matchingVps: WrappedVerifiablePresentation[] = []; if (presentationSubmissionLocation === PresentationSubmissionLocation.EXTERNAL) { - // Extract the VP from the wrapped VPs - const [vpResult] = JsonPathUtils.extractInputField(wvps, [descriptor.path]) as Array<{ value: WrappedVerifiablePresentation }>; - if (!vpResult) { + // Extract VPs matching the descriptor path + const vpResults = JsonPathUtils.extractInputField(wvps, [descriptor.path]) as Array<{ value: WrappedVerifiablePresentation[] }>; + + if (!vpResults.length) { result.areRequiredCredentialsPresent = Status.ERROR; result.errors?.push({ status: Status.ERROR, tag: 'SubmissionPathNotFound', - message: `Unable to extract path ${descriptor.path} for submission.descriptor_path[${descriptorIndex}] from presentation(s)`, + message: `Unable to extract path ${descriptor.path} for submission.descriptor_map[${descriptorIndex}] from presentation(s)`, }); continue; } - vp = vpResult.value; - vcPath = `presentation ${descriptor.path}`; - if (vp.format !== descriptor.format) { + // Flatten the array of VPs + const allVps = vpResults.flatMap((vpResult) => vpResult.value); + + // Filter VPs that match the required format + matchingVps = allVps.filter((vp) => vp.format === descriptor.format); + + if (!matchingVps.length) { result.areRequiredCredentialsPresent = Status.ERROR; result.errors?.push({ status: Status.ERROR, tag: 'SubmissionFormatNoMatch', - message: `VP at path ${descriptor.path} has format ${vp.format}, while submission.descriptor_path[${descriptorIndex}] has format ${descriptor.format}`, + message: `No VP at path ${descriptor.path} matches the required format ${descriptor.format}`, }); continue; } + // Log a warning if multiple VPs match the descriptor + if (matchingVps.length > 1) { + result.warnings?.push({ + status: Status.WARN, + tag: 'MultipleVpsMatched', + message: `Multiple VPs matched for descriptor_path[${descriptorIndex}]. Using the first matching VP.`, + }); + } + } else { + // When submission location is PRESENTATION, assume a single VP + matchingVps = Array.isArray(wvps) ? [wvps[0]] : [wvps]; + } + + // Process the first matching VP + const vp = matchingVps[0]; + let vc: WrappedVerifiableCredential; + let vcPath: string = `presentation ${descriptor.path}`; + + if (presentationSubmissionLocation === PresentationSubmissionLocation.EXTERNAL) { if (descriptor.path_nested) { - const extractionResult = this.extractWrappedVcFromWrappedVp(descriptor.path_nested, descriptorIndex, vp); + const extractionResult = this.extractWrappedVcFromWrappedVp(descriptor, descriptorIndex.toString(), vp); if (extractionResult.error) { result.areRequiredCredentialsPresent = Status.ERROR; result.errors?.push(extractionResult.error); @@ -565,6 +611,15 @@ export class EvaluationClientWrapper { vc = extractionResult.wvc; vcPath += ` with nested credential ${descriptor.path_nested.path}`; } else if (descriptor.format === 'vc+sd-jwt') { + if (!vp.vcs || !vp.vcs.length) { + result.areRequiredCredentialsPresent = Status.ERROR; + result.errors?.push({ + status: Status.ERROR, + tag: 'NoCredentialsFound', + message: `No credentials found in VP at path ${descriptor.path}`, + }); + continue; + } vc = vp.vcs[0]; } else { result.areRequiredCredentialsPresent = Status.ERROR; @@ -576,11 +631,7 @@ export class EvaluationClientWrapper { continue; } } else { - // TODO: check that not longer than 0 - vp = Array.isArray(wvps) ? wvps[0] : wvps; - vcPath = `credential ${descriptor.path}`; - - const extractionResult = this.extractWrappedVcFromWrappedVp(descriptor, descriptorIndex, vp); + const extractionResult = this.extractWrappedVcFromWrappedVp(descriptor, descriptorIndex.toString(), vp); if (extractionResult.error) { result.areRequiredCredentialsPresent = Status.ERROR; result.errors?.push(extractionResult.error); @@ -588,16 +639,20 @@ export class EvaluationClientWrapper { } vc = extractionResult.wvc; + vcPath = `credential ${descriptor.path}`; } // TODO: we should probably add support for holder dids in the kb-jwt of an SD-JWT. We can extract this from the // `wrappedPresentation.original.compactKbJwt`, but as HAIP doesn't use dids, we'll leave it for now. - const holderDIDs = CredentialMapper.isW3cPresentation(vp.presentation) && vp.presentation.holder ? [vp.presentation.holder] : []; - // Get the presentation definition only for this descriptor, so we can evaluate it separately + // Determine holder DIDs + const holderDIDs = + CredentialMapper.isW3cPresentation(vp.presentation) && vp.presentation.holder ? [vp.presentation.holder] : opts?.holderDIDs || []; + + // Get the presentation definition specific to the current descriptor const pdForDescriptor = this.internalPresentationDefinitionForDescriptor(pd, descriptor.id); - // Reset the client on each iteration. + // Reset and configure the evaluation client this._client = new EvaluationClient(); this._client.evaluate(pdForDescriptor, [vc], { ...opts, @@ -606,6 +661,7 @@ export class EvaluationClientWrapper { generatePresentationSubmission: undefined, }); + // Check if the evaluation resulted in exactly one descriptor map entry if (this._client.presentationSubmission.descriptor_map.length !== 1) { const submissionDescriptor = `submission.descriptor_map[${descriptorIndex}]`; result.areRequiredCredentialsPresent = Status.ERROR; @@ -614,7 +670,7 @@ export class EvaluationClientWrapper { } } - // Output submission is same as input presentation submission, it's just that if it doesn't match, we return Error. + // Validate if the submission satisfies the presentation definition const submissionAgainstDefinitionResult = this.validateIfSubmissionSatisfiesDefinition(pd, submission); if (!submissionAgainstDefinitionResult.doesSubmissionSatisfyDefinition) { result.errors?.push({ @@ -622,6 +678,7 @@ export class EvaluationClientWrapper { tag: 'SubmissionDoesNotSatisfyDefinition', // TODO: it would be nice to add the nested errors here for beter understanding WHY the submission // does not satisfy the definition, as we have that info, but we can only include one message here + message: submissionAgainstDefinitionResult.error, }); result.areRequiredCredentialsPresent = Status.ERROR; diff --git a/lib/signing/types.ts b/lib/signing/types.ts index a962e8ed..b77ccdd3 100644 --- a/lib/signing/types.ts +++ b/lib/signing/types.ts @@ -7,9 +7,9 @@ import { IProofType, OriginalVerifiableCredential, SdJwtDecodedVerifiableCredential, + SdJwtVcKbJwtHeader, SdJwtVcKbJwtPayload, W3CVerifiablePresentation, - SdJwtVcKbJwtHeader } from '@sphereon/ssi-types'; import { PresentationEvaluationResults } from '../evaluation'; From edfac4da91ecf277da0745f67a1df3b554590fc3 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Mon, 23 Sep 2024 12:49:12 +0200 Subject: [PATCH 06/47] chore: version up --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1bcf6385..5b181934 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sphereon/pex", - "version": "5.0.0-unstable.3", + "version": "5.0.0-unstable.4", "description": "A Typescript implementation of the v1 and v2 DIF Presentation Exchange specification", "main": "dist/main/index.js", "module": "dist/module/index.js", From afebb9b2cb45b02f44a90dbe5829bc2a2146a93a Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Mon, 23 Sep 2024 13:12:47 +0200 Subject: [PATCH 07/47] chore: handled vcResult.value.vp.* case --- lib/evaluation/evaluationClientWrapper.ts | 10 ++++++++-- package.json | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/evaluation/evaluationClientWrapper.ts b/lib/evaluation/evaluationClientWrapper.ts index 42382687..6440088f 100644 --- a/lib/evaluation/evaluationClientWrapper.ts +++ b/lib/evaluation/evaluationClientWrapper.ts @@ -479,7 +479,9 @@ export class EvaluationClientWrapper { if ( !vcResult.value || typeof vcResult.value === 'string' || - (!('verifiableCredential' in vcResult.value) && !CredentialMapper.isCredential(vcResult.value as OriginalVerifiableCredential)) // FIXME + (!('verifiableCredential' in vcResult.value) && + !('vp' in vcResult.value) && + !CredentialMapper.isCredential(vcResult.value as OriginalVerifiableCredential)) // FIXME ) { return { error: { @@ -491,12 +493,16 @@ export class EvaluationClientWrapper { }; } - // When result is an array, extract the first Verifiable Credential from the array + // When result is an array, extract the first Verifiable Credential from the array FIXME figure out proper types, can't see that in debug mode... let originalVc; if (CredentialMapper.isCredential(vcResult.value as OriginalVerifiableCredential)) { originalVc = vcResult.value; } else if ('verifiableCredential' in vcResult.value) { originalVc = Array.isArray(vcResult.value.verifiableCredential) ? vcResult.value.verifiableCredential[0] : vcResult.value.verifiableCredential; + } else if ('vp' in vcResult.value) { + originalVc = Array.isArray(vcResult.value.vp.verifiableCredential) + ? vcResult.value.vp.verifiableCredential[0] + : vcResult.value.vp.verifiableCredential; } else { throw Error('Could not deduced original VC from evaluation result'); } diff --git a/package.json b/package.json index 5b181934..d01abdb2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sphereon/pex", - "version": "5.0.0-unstable.4", + "version": "5.0.0-unstable.5", "description": "A Typescript implementation of the v1 and v2 DIF Presentation Exchange specification", "main": "dist/main/index.js", "module": "dist/module/index.js", From 8378479bf28edd43866cb248b4c20df94f333bab Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Mon, 23 Sep 2024 13:54:17 +0200 Subject: [PATCH 08/47] chore: handled CompactJWT case --- lib/evaluation/evaluationClientWrapper.ts | 43 +++++++++++++++-------- package.json | 2 +- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/lib/evaluation/evaluationClientWrapper.ts b/lib/evaluation/evaluationClientWrapper.ts index 6440088f..0924c037 100644 --- a/lib/evaluation/evaluationClientWrapper.ts +++ b/lib/evaluation/evaluationClientWrapper.ts @@ -97,7 +97,11 @@ export class EvaluationClientWrapper { marked, ); } catch (e) { - const matchingError: Checked = { status: Status.ERROR, message: JSON.stringify(e), tag: 'matchSubmissionRequirements' }; + const matchingError: Checked = { + status: Status.ERROR, + message: JSON.stringify(e), + tag: 'matchSubmissionRequirements', + }; return { errors: errors ? [...errors, matchingError] : [matchingError], warnings: warnings, @@ -430,7 +434,9 @@ export class EvaluationClientWrapper { if (this._client.generatePresentationSubmission && result.value && useExternalSubmission) { // we map the descriptors of the generated submisison to take into account the nexted values result.value.descriptor_map = result.value.descriptor_map.map((descriptor) => { - const [wvcResult] = JsonPathUtils.extractInputField(allWvcs, [descriptor.path]) as Array<{ value: WrappedVerifiableCredential }>; + const [wvcResult] = JsonPathUtils.extractInputField(allWvcs, [descriptor.path]) as Array<{ + value: WrappedVerifiableCredential; + }>; if (!wvcResult) { throw new Error(`Could not find descriptor path ${descriptor.path} in wrapped verifiable credentials`); } @@ -475,13 +481,12 @@ export class EvaluationClientWrapper { }; } - // Check if vcResult.value contains the 'verifiableCredential' array + // FIXME figure out possible types, can't see that in debug mode... + const isCredential = CredentialMapper.isCredential(vcResult.value as OriginalVerifiableCredential); if ( !vcResult.value || - typeof vcResult.value === 'string' || - (!('verifiableCredential' in vcResult.value) && - !('vp' in vcResult.value) && - !CredentialMapper.isCredential(vcResult.value as OriginalVerifiableCredential)) // FIXME + !isCredential || + (typeof vcResult.value !== 'string' && !isCredential && !('verifiableCredential' in vcResult.value || 'vp' in vcResult.value)) ) { return { error: { @@ -495,14 +500,20 @@ export class EvaluationClientWrapper { // When result is an array, extract the first Verifiable Credential from the array FIXME figure out proper types, can't see that in debug mode... let originalVc; - if (CredentialMapper.isCredential(vcResult.value as OriginalVerifiableCredential)) { + if (isCredential) { originalVc = vcResult.value; - } else if ('verifiableCredential' in vcResult.value) { - originalVc = Array.isArray(vcResult.value.verifiableCredential) ? vcResult.value.verifiableCredential[0] : vcResult.value.verifiableCredential; - } else if ('vp' in vcResult.value) { - originalVc = Array.isArray(vcResult.value.vp.verifiableCredential) - ? vcResult.value.vp.verifiableCredential[0] - : vcResult.value.vp.verifiableCredential; + } else if (typeof vcResult.value !== 'string') { + if ('verifiableCredential' in vcResult.value) { + originalVc = Array.isArray(vcResult.value.verifiableCredential) + ? vcResult.value.verifiableCredential[0] + : vcResult.value.verifiableCredential; + } else if ('vp' in vcResult.value) { + originalVc = Array.isArray(vcResult.value.vp.verifiableCredential) + ? vcResult.value.vp.verifiableCredential[0] + : vcResult.value.vp.verifiableCredential; + } else { + throw Error('Could not deduced original VC from evaluation result'); + } } else { throw Error('Could not deduced original VC from evaluation result'); } @@ -559,7 +570,9 @@ export class EvaluationClientWrapper { if (presentationSubmissionLocation === PresentationSubmissionLocation.EXTERNAL) { // Extract VPs matching the descriptor path - const vpResults = JsonPathUtils.extractInputField(wvps, [descriptor.path]) as Array<{ value: WrappedVerifiablePresentation[] }>; + const vpResults = JsonPathUtils.extractInputField(wvps, [descriptor.path]) as Array<{ + value: WrappedVerifiablePresentation[]; + }>; if (!vpResults.length) { result.areRequiredCredentialsPresent = Status.ERROR; diff --git a/package.json b/package.json index d01abdb2..bcdf23ab 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sphereon/pex", - "version": "5.0.0-unstable.5", + "version": "5.0.0-unstable.6", "description": "A Typescript implementation of the v1 and v2 DIF Presentation Exchange specification", "main": "dist/main/index.js", "module": "dist/module/index.js", From ac1f4fe718fad5fc52fecaf2e0f4cb0f82ab9f12 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Mon, 23 Sep 2024 14:08:38 +0200 Subject: [PATCH 09/47] chore: handled CompactJWT case --- lib/evaluation/evaluationClientWrapper.ts | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/evaluation/evaluationClientWrapper.ts b/lib/evaluation/evaluationClientWrapper.ts index 0924c037..6d0b1349 100644 --- a/lib/evaluation/evaluationClientWrapper.ts +++ b/lib/evaluation/evaluationClientWrapper.ts @@ -485,7 +485,7 @@ export class EvaluationClientWrapper { const isCredential = CredentialMapper.isCredential(vcResult.value as OriginalVerifiableCredential); if ( !vcResult.value || - !isCredential || + (typeof vcResult.value === 'string' && !isCredential) || (typeof vcResult.value !== 'string' && !isCredential && !('verifiableCredential' in vcResult.value || 'vp' in vcResult.value)) ) { return { diff --git a/package.json b/package.json index bcdf23ab..c590c4e9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sphereon/pex", - "version": "5.0.0-unstable.6", + "version": "5.0.0-unstable.7", "description": "A Typescript implementation of the v1 and v2 DIF Presentation Exchange specification", "main": "dist/main/index.js", "module": "dist/module/index.js", From 97c59fdf6e433e2257d30bb581f795a47c755463 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Tue, 24 Sep 2024 14:56:36 +0200 Subject: [PATCH 10/47] chore: comment --- lib/evaluation/evaluationClientWrapper.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/evaluation/evaluationClientWrapper.ts b/lib/evaluation/evaluationClientWrapper.ts index 6d0b1349..b8541008 100644 --- a/lib/evaluation/evaluationClientWrapper.ts +++ b/lib/evaluation/evaluationClientWrapper.ts @@ -507,6 +507,7 @@ export class EvaluationClientWrapper { originalVc = Array.isArray(vcResult.value.verifiableCredential) ? vcResult.value.verifiableCredential[0] : vcResult.value.verifiableCredential; + // FIXME this may be too lenient } else if ('vp' in vcResult.value) { originalVc = Array.isArray(vcResult.value.vp.verifiableCredential) ? vcResult.value.vp.verifiableCredential[0] From 01b81ace450be0cae693c1986f78e484b5269ad2 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Tue, 24 Sep 2024 17:33:04 +0200 Subject: [PATCH 11/47] fix: fixed iat in kn-jwt --- lib/PEX.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/PEX.ts b/lib/PEX.ts index 6c391965..f55c3e25 100644 --- a/lib/PEX.ts +++ b/lib/PEX.ts @@ -358,7 +358,7 @@ export class PEX { // aud MUST be set by the signer or provided by e.g. SIOP/OpenID4VP lib }, payload: { - iat: new Date().getTime(), + iat: Math.floor(new Date().getTime() / 1000), sd_hash: sdHash, }, } satisfies PartialSdJwtKbJwt; @@ -549,7 +549,7 @@ export class PEX { }, // aud MUST be set by the signer or provided by e.g. SIOP/OpenID4VP lib payload: { - iat: new Date().getTime(), + iat: Math.floor(new Date().getTime() / 1000), nonce: proofOptions?.nonce, sd_hash: sdHash, }, From 54f115a92f2e43cb5413157c52d0f6ae106c3f76 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Tue, 24 Sep 2024 17:34:52 +0200 Subject: [PATCH 12/47] chore: version up --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c590c4e9..04533389 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sphereon/pex", - "version": "5.0.0-unstable.7", + "version": "5.0.0-unstable.8", "description": "A Typescript implementation of the v1 and v2 DIF Presentation Exchange specification", "main": "dist/main/index.js", "module": "dist/module/index.js", From 4a1bc265d294bfcb92fee2e40b72b3ba2dde2217 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Mon, 30 Sep 2024 23:04:07 +0200 Subject: [PATCH 13/47] chore: fix to get multi-vp working --- lib/evaluation/evaluationClientWrapper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/evaluation/evaluationClientWrapper.ts b/lib/evaluation/evaluationClientWrapper.ts index b8541008..01830876 100644 --- a/lib/evaluation/evaluationClientWrapper.ts +++ b/lib/evaluation/evaluationClientWrapper.ts @@ -621,7 +621,7 @@ export class EvaluationClientWrapper { if (presentationSubmissionLocation === PresentationSubmissionLocation.EXTERNAL) { if (descriptor.path_nested) { - const extractionResult = this.extractWrappedVcFromWrappedVp(descriptor, descriptorIndex.toString(), vp); + const extractionResult = this.extractWrappedVcFromWrappedVp(descriptor.path_nested, descriptorIndex.toString(), vp); if (extractionResult.error) { result.areRequiredCredentialsPresent = Status.ERROR; result.errors?.push(extractionResult.error); From 09d4a98c5301d4272abf0fdc2fa864fb605be360 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Mon, 30 Sep 2024 23:45:44 +0200 Subject: [PATCH 14/47] chore: prettier & lint --- .../pdV2/pd-multi-sd-jwt-vp.json | 6 +- test/evaluation/selectFrom.spec.ts | 88 ++++++++++--------- 2 files changed, 48 insertions(+), 46 deletions(-) diff --git a/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json b/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json index 45178287..a34b0d7f 100644 --- a/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json +++ b/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json @@ -62,10 +62,8 @@ "A" ], "format": { - "jwt_vc_json": { - "alg": [ - "RS256" - ] + "vc+sd-jwt": { + "sd-jwt_alg_values": ["ES256", "ES384", "ES512", "EdDSA"] } }, "constraints": { diff --git a/test/evaluation/selectFrom.spec.ts b/test/evaluation/selectFrom.spec.ts index d2b9d0e4..acc1fe5f 100644 --- a/test/evaluation/selectFrom.spec.ts +++ b/test/evaluation/selectFrom.spec.ts @@ -1,3 +1,4 @@ +import { createHash } from 'crypto'; import fs from 'fs'; import { Rules } from '@sphereon/pex-models'; @@ -9,8 +10,10 @@ import { SubmissionRequirementMatchType } from '../../lib/evaluation/core'; import { InternalPresentationDefinitionV1, InternalPresentationDefinitionV2, SSITypesBuilder } from '../../lib/types'; import PexMessages from '../../lib/types/Messages'; +export const hasher = (data: string) => createHash('sha256').update(data).digest(); + function getFile(path: string) { - return JSON.parse(fs.readFileSync(path, 'utf-8')); + return fs.readFileSync(path, 'utf-8'); } function getFileAsJson(path: string) { @@ -23,8 +26,8 @@ const LIMIT_DISCLOSURE_SIGNATURE_SUITES = ['BbsBlsSignatureProof2020']; describe('selectFrom tests', () => { it('Evaluate submission requirements all from group A', () => { - const pdSchema: InternalPresentationDefinitionV1 = getFile('./test/resources/sr_rules.json').presentation_definition; - const vpSimple = getFile('./test/dif_pe_examples/vp/vp_general.json'); + const pdSchema: InternalPresentationDefinitionV1 = getFileAsJson('./test/resources/sr_rules.json').presentation_definition; + const vpSimple = getFileAsJson('./test/dif_pe_examples/vp/vp_general.json'); const wvcs: WrappedVerifiableCredential[] = SSITypesBuilder.mapExternalVerifiableCredentialsToWrappedVcs([ vpSimple.verifiableCredential[0], vpSimple.verifiableCredential[1], @@ -126,9 +129,9 @@ describe('selectFrom tests', () => { }); it('Evaluate without submission requirements', () => { - const pdSchema: InternalPresentationDefinitionV1 = getFile('./test/resources/sr_rules.json').presentation_definition; + const pdSchema: InternalPresentationDefinitionV1 = getFileAsJson('./test/resources/sr_rules.json').presentation_definition; delete pdSchema.submission_requirements; - const vpSimple = getFile('./test/dif_pe_examples/vp/vp_general.json'); + const vpSimple = getFileAsJson('./test/dif_pe_examples/vp/vp_general.json'); const wvcs: WrappedVerifiableCredential[] = SSITypesBuilder.mapExternalVerifiableCredentialsToWrappedVcs([ vpSimple.verifiableCredential[0], vpSimple.verifiableCredential[1], @@ -145,8 +148,8 @@ describe('selectFrom tests', () => { }); it('Evaluate submission requirements min 2 from group B', () => { - const pdSchema: InternalPresentationDefinitionV1 = getFile('./test/resources/sr_rules.json').presentation_definition; - const vpSimple = getFile('./test/dif_pe_examples/vp/vp_general.json'); + const pdSchema: InternalPresentationDefinitionV1 = getFileAsJson('./test/resources/sr_rules.json').presentation_definition; + const vpSimple = getFileAsJson('./test/dif_pe_examples/vp/vp_general.json'); pdSchema!.submission_requirements = [pdSchema!.submission_requirements![1]]; const pd = SSITypesBuilder.modelEntityToInternalPresentationDefinitionV1(pdSchema); const evaluationClientWrapper: EvaluationClientWrapper = new EvaluationClientWrapper(); @@ -218,8 +221,8 @@ describe('selectFrom tests', () => { }); it('Evaluate submission requirements either all from group A or 2 from group B', () => { - const pdSchema: InternalPresentationDefinitionV1 = getFile('./test/resources/sr_rules.json').presentation_definition; - const vpSimple = getFile('./test/dif_pe_examples/vp/vp_general.json'); + const pdSchema: InternalPresentationDefinitionV1 = getFileAsJson('./test/resources/sr_rules.json').presentation_definition; + const vpSimple = getFileAsJson('./test/dif_pe_examples/vp/vp_general.json'); pdSchema!.submission_requirements = [pdSchema!.submission_requirements![2]]; const pd = SSITypesBuilder.modelEntityToInternalPresentationDefinitionV1(pdSchema); const evaluationClientWrapper: EvaluationClientWrapper = new EvaluationClientWrapper(); @@ -237,8 +240,8 @@ describe('selectFrom tests', () => { }); it('Evaluate submission requirements max 2 from group B', () => { - const pdSchema: InternalPresentationDefinitionV1 = getFile('./test/resources/sr_rules.json').presentation_definition; - const vpSimple = getFile('./test/dif_pe_examples/vp/vp_general.json'); + const pdSchema: InternalPresentationDefinitionV1 = getFileAsJson('./test/resources/sr_rules.json').presentation_definition; + const vpSimple = getFileAsJson('./test/dif_pe_examples/vp/vp_general.json'); pdSchema!.submission_requirements = [pdSchema!.submission_requirements![3]]; const pd = SSITypesBuilder.modelEntityToInternalPresentationDefinitionV1(pdSchema); const evaluationClientWrapper: EvaluationClientWrapper = new EvaluationClientWrapper(); @@ -310,8 +313,8 @@ describe('selectFrom tests', () => { }); it('Evaluate submission requirements all from group A and 2 from group B', () => { - const pdSchema: InternalPresentationDefinitionV1 = getFile('./test/resources/sr_rules.json').presentation_definition; - const vpSimple = getFile('./test/dif_pe_examples/vp/vp_general.json'); + const pdSchema: InternalPresentationDefinitionV1 = getFileAsJson('./test/resources/sr_rules.json').presentation_definition; + const vpSimple = getFileAsJson('./test/dif_pe_examples/vp/vp_general.json'); pdSchema!.submission_requirements = [pdSchema!.submission_requirements![8]]; const pd = SSITypesBuilder.modelEntityToInternalPresentationDefinitionV1(pdSchema); const evaluationClientWrapper: EvaluationClientWrapper = new EvaluationClientWrapper(); @@ -433,8 +436,8 @@ describe('selectFrom tests', () => { }); it('Evaluate submission requirements min 1: (all from group A or 2 from group B)', () => { - const pdSchema: InternalPresentationDefinitionV1 = getFile('./test/resources/sr_rules.json').presentation_definition; - const vpSimple = getFile('./test/dif_pe_examples/vp/vp_general.json'); + const pdSchema: InternalPresentationDefinitionV1 = getFileAsJson('./test/resources/sr_rules.json').presentation_definition; + const vpSimple = getFileAsJson('./test/dif_pe_examples/vp/vp_general.json'); pdSchema!.submission_requirements = [pdSchema!.submission_requirements![9]]; const pd = SSITypesBuilder.modelEntityToInternalPresentationDefinitionV1(pdSchema); const evaluationClientWrapper: EvaluationClientWrapper = new EvaluationClientWrapper(); @@ -557,8 +560,8 @@ describe('selectFrom tests', () => { }); it('Evaluate submission requirements max 2: (all from group A and 2 from group B)', () => { - const pdSchema: InternalPresentationDefinitionV1 = getFile('./test/resources/sr_rules.json').presentation_definition; - const vpSimple = getFile('./test/dif_pe_examples/vp/vp_general.json'); + const pdSchema: InternalPresentationDefinitionV1 = getFileAsJson('./test/resources/sr_rules.json').presentation_definition; + const vpSimple = getFileAsJson('./test/dif_pe_examples/vp/vp_general.json'); pdSchema!.submission_requirements = [pdSchema!.submission_requirements![10]]; const pd = SSITypesBuilder.modelEntityToInternalPresentationDefinitionV1(pdSchema); const evaluationClientWrapper: EvaluationClientWrapper = new EvaluationClientWrapper(); @@ -681,8 +684,8 @@ describe('selectFrom tests', () => { }); it('Evaluate submission requirements min 3 from group B', () => { - const pdSchema: InternalPresentationDefinitionV1 = getFile('./test/resources/sr_rules.json').presentation_definition; - const vpSimple = getFile('./test/dif_pe_examples/vp/vp_general.json'); + const pdSchema: InternalPresentationDefinitionV1 = getFileAsJson('./test/resources/sr_rules.json').presentation_definition; + const vpSimple = getFileAsJson('./test/dif_pe_examples/vp/vp_general.json'); pdSchema!.submission_requirements = [pdSchema!.submission_requirements![4]]; const pd = SSITypesBuilder.modelEntityToInternalPresentationDefinitionV1(pdSchema); const evaluationClientWrapper: EvaluationClientWrapper = new EvaluationClientWrapper(); @@ -792,8 +795,8 @@ describe('selectFrom tests', () => { }); it('Evaluate submission requirements max 1 from group B', () => { - const pdSchema: InternalPresentationDefinitionV1 = getFile('./test/resources/sr_rules.json').presentation_definition; - const vpSimple = getFile('./test/dif_pe_examples/vp/vp_general.json'); + const pdSchema: InternalPresentationDefinitionV1 = getFileAsJson('./test/resources/sr_rules.json').presentation_definition; + const vpSimple = getFileAsJson('./test/dif_pe_examples/vp/vp_general.json'); pdSchema!.submission_requirements = [pdSchema!.submission_requirements![5]]; const pd = SSITypesBuilder.modelEntityToInternalPresentationDefinitionV1(pdSchema); const evaluationClientWrapper: EvaluationClientWrapper = new EvaluationClientWrapper(); @@ -823,8 +826,8 @@ describe('selectFrom tests', () => { }); it('Evaluate submission requirements exactly 1 from group B', () => { - const pdSchema: InternalPresentationDefinitionV1 = getFile('./test/resources/sr_rules.json').presentation_definition; - const vpSimple = getFile('./test/dif_pe_examples/vp/vp_general.json'); + const pdSchema: InternalPresentationDefinitionV1 = getFileAsJson('./test/resources/sr_rules.json').presentation_definition; + const vpSimple = getFileAsJson('./test/dif_pe_examples/vp/vp_general.json'); pdSchema!.submission_requirements = [pdSchema!.submission_requirements![6]]; const pd = SSITypesBuilder.modelEntityToInternalPresentationDefinitionV1(pdSchema); const evaluationClientWrapper: EvaluationClientWrapper = new EvaluationClientWrapper(); @@ -844,8 +847,8 @@ describe('selectFrom tests', () => { }); it('Evaluate submission requirements all from group B', () => { - const pdSchema: InternalPresentationDefinitionV1 = getFile('./test/resources/sr_rules.json').presentation_definition; - const vpSimple = getFile('./test/dif_pe_examples/vp/vp_general.json'); + const pdSchema: InternalPresentationDefinitionV1 = getFileAsJson('./test/resources/sr_rules.json').presentation_definition; + const vpSimple = getFileAsJson('./test/dif_pe_examples/vp/vp_general.json'); pdSchema!.submission_requirements = [pdSchema!.submission_requirements![7]]; const pd = SSITypesBuilder.modelEntityToInternalPresentationDefinitionV1(pdSchema); const evaluationClientWrapper: EvaluationClientWrapper = new EvaluationClientWrapper(); @@ -865,8 +868,8 @@ describe('selectFrom tests', () => { }); it('Evaluate submission requirements min 3: (all from group A or 2 from group B + unexistent)', () => { - const pdSchema: InternalPresentationDefinitionV1 = getFile('./test/resources/sr_rules.json').presentation_definition; - const vpSimple = getFile('./test/dif_pe_examples/vp/vp_general.json'); + const pdSchema: InternalPresentationDefinitionV1 = getFileAsJson('./test/resources/sr_rules.json').presentation_definition; + const vpSimple = getFileAsJson('./test/dif_pe_examples/vp/vp_general.json'); pdSchema!.submission_requirements = [pdSchema!.submission_requirements![11]]; const pd = SSITypesBuilder.modelEntityToInternalPresentationDefinitionV1(pdSchema); pd.submission_requirements![0].min = 1; @@ -914,8 +917,8 @@ describe('selectFrom tests', () => { }); it('Evaluate submission requirements max 1: (all from group A and 2 from group B)', () => { - const pdSchema: InternalPresentationDefinitionV1 = getFile('./test/resources/sr_rules.json').presentation_definition; - const vpSimple = getFile('./test/dif_pe_examples/vp/vp_general.json'); + const pdSchema: InternalPresentationDefinitionV1 = getFileAsJson('./test/resources/sr_rules.json').presentation_definition; + const vpSimple = getFileAsJson('./test/dif_pe_examples/vp/vp_general.json'); pdSchema!.submission_requirements = [pdSchema!.submission_requirements![12]]; const pd = SSITypesBuilder.modelEntityToInternalPresentationDefinitionV1(pdSchema); const evaluationClientWrapper: EvaluationClientWrapper = new EvaluationClientWrapper(); @@ -965,9 +968,11 @@ describe('selectFrom tests', () => { }); it('Evaluate case without presentation submission', () => { - const pdSchema: InternalPresentationDefinitionV1 = getFile('./test/dif_pe_examples/pdV1/pd-PermanentResidentCard.json').presentation_definition; + const pdSchema: InternalPresentationDefinitionV1 = getFileAsJson( + './test/dif_pe_examples/pdV1/pd-PermanentResidentCard.json', + ).presentation_definition; const pd = SSITypesBuilder.modelEntityToInternalPresentationDefinitionV1(pdSchema); - const verifiableCredential = getFile('./test/dif_pe_examples/vc/vc-PermanentResidentCard.json'); + const verifiableCredential = getFileAsJson('./test/dif_pe_examples/vc/vc-PermanentResidentCard.json'); const wvcs: WrappedVerifiableCredential[] = SSITypesBuilder.mapExternalVerifiableCredentialsToWrappedVcs([verifiableCredential]); const evaluationClientWrapper: EvaluationClientWrapper = new EvaluationClientWrapper(); const result = evaluationClientWrapper.selectFrom(pd, wvcs, { @@ -986,10 +991,12 @@ describe('selectFrom tests', () => { }); it('Evaluate driver license name result', () => { - const pdSchema: InternalPresentationDefinitionV1 = getFile('./test/dif_pe_examples/pdV1/pd_driver_license_name.json') + const pdSchema: InternalPresentationDefinitionV1 = getFileAsJson('./test/dif_pe_examples/pdV1/pd_driver_license_name.json') .presentation_definition as InternalPresentationDefinitionV1; const pd = SSITypesBuilder.modelEntityToInternalPresentationDefinitionV1(pdSchema); - const verifiableCredential: IVerifiableCredential = getFile('./test/dif_pe_examples/vc/vc-PermanentResidentCard.json') as IVerifiableCredential; + const verifiableCredential: IVerifiableCredential = getFileAsJson( + './test/dif_pe_examples/vc/vc-PermanentResidentCard.json', + ) as IVerifiableCredential; const wvcs: WrappedVerifiableCredential[] = SSITypesBuilder.mapExternalVerifiableCredentialsToWrappedVcs([verifiableCredential]); const evaluationClientWrapper: EvaluationClientWrapper = new EvaluationClientWrapper(); const result = evaluationClientWrapper.selectFrom(pd, wvcs, { @@ -1000,22 +1007,19 @@ describe('selectFrom tests', () => { expect(result!.matches![0]!.name).toEqual("Name on driver's license"); }); - it('iata test1', function () { - const pdSchema: InternalPresentationDefinitionV2 = getFileAsJson( - './test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json', - ).presentation_definition; - const vcs: string[] = [] - vcs.push(getFile('test/dif_pe_examples/vc/vc-iata-order-sd.jwt').replace('\r\n', '')) - vcs.push(getFile('test/dif_pe_examples/vc/vc-iata-epassport-sd.jwt').replace('\r\n', '')) + const pdSchema: InternalPresentationDefinitionV2 = getFileAsJson('./test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json').presentation_definition; + const vcs: string[] = []; + vcs.push(getFile('test/dif_pe_examples/vc/vc-iata-order-sd.jwt').replace('\r\n', '')); + vcs.push(getFile('test/dif_pe_examples/vc/vc-iata-epassport-sd.jwt').replace('\r\n', '')); const pd = SSITypesBuilder.modelEntityInternalPresentationDefinitionV2(pdSchema); const evaluationClientWrapper: EvaluationClientWrapper = new EvaluationClientWrapper(); - const wvcs: WrappedVerifiableCredential[] = SSITypesBuilder.mapExternalVerifiableCredentialsToWrappedVcs(vcs); + const wvcs: WrappedVerifiableCredential[] = SSITypesBuilder.mapExternalVerifiableCredentialsToWrappedVcs(vcs, hasher); const result = evaluationClientWrapper.selectFrom(pd, wvcs, { holderDIDs: ['FAsYneKJhWBP2n5E21ZzdY'], limitDisclosureSignatureSuites: LIMIT_DISCLOSURE_SIGNATURE_SUITES, }); // TODO expects - expect(result).toBeDefined() + expect(result).toBeDefined(); }); }); From 39289eca84e821e59c4094e920ee8fc2d50e8751 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Wed, 2 Oct 2024 11:18:21 +0200 Subject: [PATCH 15/47] chore: paxSegments array --- test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json b/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json index a34b0d7f..c3bedea7 100644 --- a/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json +++ b/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json @@ -40,17 +40,17 @@ }, { "path": [ - "$.paxSegments.operatingCarrierFlightNumber" + "$.paxSegments[*].operatingCarrierFlightNumber" ] }, { "path": [ - "$.paxSegments.scheduledArrivalTime" + "$.paxSegments[*].scheduledArrivalTime" ] }, { "path": [ - "$.paxSegments.scheduledDepartureTime" + "$.paxSegments[*].scheduledDepartureTime" ] } ] From 2ee82616a0b57f6ebc010d18103107ec791c7983 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Wed, 2 Oct 2024 13:22:09 +0200 Subject: [PATCH 16/47] chore: paxSegments array --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 56e081e3..e4415c91 100644 --- a/package.json +++ b/package.json @@ -43,9 +43,9 @@ }, "dependencies": { "@astronautlabs/jsonpath": "^1.1.2", - "@sd-jwt/decode": "^0.6.1", - "@sd-jwt/present": "^0.6.1", - "@sd-jwt/types": "^0.6.1", + "@sd-jwt/decode": "^0.7.2", + "@sd-jwt/present": "^0.7.2", + "@sd-jwt/types": "^0.7.2", "@sphereon/pex-models": "^2.3.1", "@sphereon/ssi-types": "0.29.1-unstable.121", "ajv": "^8.12.0", From 8f142fac4a3f00d574881f6402e003d24c767446 Mon Sep 17 00:00:00 2001 From: Sadjad Khoshkhou Date: Wed, 2 Oct 2024 13:55:18 +0200 Subject: [PATCH 17/47] chore: fixed the replacing of the new lines to be platform-agnostic --- test/evaluation/selectFrom.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/evaluation/selectFrom.spec.ts b/test/evaluation/selectFrom.spec.ts index acc1fe5f..c7796ecf 100644 --- a/test/evaluation/selectFrom.spec.ts +++ b/test/evaluation/selectFrom.spec.ts @@ -1010,8 +1010,8 @@ describe('selectFrom tests', () => { it('iata test1', function () { const pdSchema: InternalPresentationDefinitionV2 = getFileAsJson('./test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json').presentation_definition; const vcs: string[] = []; - vcs.push(getFile('test/dif_pe_examples/vc/vc-iata-order-sd.jwt').replace('\r\n', '')); - vcs.push(getFile('test/dif_pe_examples/vc/vc-iata-epassport-sd.jwt').replace('\r\n', '')); + vcs.push(getFile('test/dif_pe_examples/vc/vc-iata-order-sd.jwt').replace(/(\r\n|\n|\r)/gm, '')); + vcs.push(getFile('test/dif_pe_examples/vc/vc-iata-epassport-sd.jwt').replace(/(\r\n|\n|\r)/gm, '')); const pd = SSITypesBuilder.modelEntityInternalPresentationDefinitionV2(pdSchema); const evaluationClientWrapper: EvaluationClientWrapper = new EvaluationClientWrapper(); const wvcs: WrappedVerifiableCredential[] = SSITypesBuilder.mapExternalVerifiableCredentialsToWrappedVcs(vcs, hasher); From 39e952ff1ab9c9c3691c10eb39d9e2e97da3e682 Mon Sep 17 00:00:00 2001 From: Sadjad Khoshkhou Date: Wed, 2 Oct 2024 14:05:22 +0200 Subject: [PATCH 18/47] chore: changed the presentation definition for iata to query the correct path for information --- test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json b/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json index c3bedea7..a819e48d 100644 --- a/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json +++ b/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json @@ -40,17 +40,17 @@ }, { "path": [ - "$.paxSegments[*].operatingCarrierFlightNumber" + "$.order.paxSegments[*].operatingCarrierFlightNumber" ] }, { "path": [ - "$.paxSegments[*].scheduledArrivalTime" + "$.order.paxSegments[*].scheduledArrivalTime" ] }, { "path": [ - "$.paxSegments[*].scheduledDepartureTime" + "$.order.paxSegments[*].scheduledDepartureTime" ] } ] From 9bd14f6561f3e349a555293e04ab9b50a3b167c2 Mon Sep 17 00:00:00 2001 From: Sadjad Khoshkhou Date: Wed, 2 Oct 2024 14:06:36 +0200 Subject: [PATCH 19/47] chore: changed the expect for iata test --- test/evaluation/selectFrom.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/evaluation/selectFrom.spec.ts b/test/evaluation/selectFrom.spec.ts index c7796ecf..8b124d00 100644 --- a/test/evaluation/selectFrom.spec.ts +++ b/test/evaluation/selectFrom.spec.ts @@ -1020,6 +1020,6 @@ describe('selectFrom tests', () => { limitDisclosureSignatureSuites: LIMIT_DISCLOSURE_SIGNATURE_SUITES, }); // TODO expects - expect(result).toBeDefined(); + expect(result.areRequiredCredentialsPresent).toBe(Status.INFO); }); }); From fdbcdb50c379a3d0c4e5d3cecc4dcfd1212d1e41 Mon Sep 17 00:00:00 2001 From: Sadjad Khoshkhou Date: Wed, 2 Oct 2024 14:07:29 +0200 Subject: [PATCH 20/47] chore: updated the dependencies --- package.json | 2 +- pnpm-lock.yaml | 213 +++++++++++++++++-------------------------------- 2 files changed, 74 insertions(+), 141 deletions(-) diff --git a/package.json b/package.json index e4415c91..d90a6bc3 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "@sd-jwt/present": "^0.7.2", "@sd-jwt/types": "^0.7.2", "@sphereon/pex-models": "^2.3.1", - "@sphereon/ssi-types": "0.29.1-unstable.121", + "@sphereon/ssi-types": "0.30.2-next.4", "ajv": "^8.12.0", "ajv-formats": "^2.1.1", "jwt-decode": "^3.1.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 632b5529..dd92e24c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,20 +9,20 @@ dependencies: specifier: ^1.1.2 version: 1.1.2 '@sd-jwt/decode': - specifier: ^0.6.1 - version: 0.6.1 + specifier: ^0.7.2 + version: 0.7.2 '@sd-jwt/present': - specifier: ^0.6.1 - version: 0.6.1 + specifier: ^0.7.2 + version: 0.7.2 '@sd-jwt/types': - specifier: ^0.6.1 - version: 0.6.1 + specifier: ^0.7.2 + version: 0.7.2 '@sphereon/pex-models': specifier: ^2.3.1 version: 2.3.1 '@sphereon/ssi-types': - specifier: 0.29.1-unstable.121 - version: 0.29.1-unstable.121(ts-node@10.9.2) + specifier: 0.30.2-next.4 + version: 0.30.2-next.4(ts-node@10.9.2) ajv: specifier: ^8.12.0 version: 8.12.0 @@ -961,13 +961,21 @@ packages: '@sd-jwt/utils': 0.6.1 dev: false - /@sd-jwt/present@0.6.1: - resolution: {integrity: sha512-QRD3TUDLj4PqQNZ70bBxh8FLLrOE9mY8V9qiZrJSsaDOLFs2p1CtZG+v9ig62fxFYJZMf4bWKwYjz+qqGAtxCg==} - engines: {node: '>=16'} + /@sd-jwt/decode@0.7.2: + resolution: {integrity: sha512-dan2LSvK63SKwb62031G4r7TE4TaiI0EK1KbPXqS+LCXNkNDUHqhtYp9uOpj+grXceCsMtMa2f8VnUfsjmwHHg==} + engines: {node: '>=18'} dependencies: - '@sd-jwt/decode': 0.6.1 - '@sd-jwt/types': 0.6.1 - '@sd-jwt/utils': 0.6.1 + '@sd-jwt/types': 0.7.2 + '@sd-jwt/utils': 0.7.2 + dev: false + + /@sd-jwt/present@0.7.2: + resolution: {integrity: sha512-mQV85u2+mLLy2VZ9Wx2zpaB6yTDnbhCfWkP7eeCrzJQHBKAAHko8GrylEFmLKewFIcajS/r4lT/zHOsCkp5pZw==} + engines: {node: '>=18'} + dependencies: + '@sd-jwt/decode': 0.7.2 + '@sd-jwt/types': 0.7.2 + '@sd-jwt/utils': 0.7.2 dev: false /@sd-jwt/types@0.6.1: @@ -975,6 +983,11 @@ packages: engines: {node: '>=16'} dev: false + /@sd-jwt/types@0.7.2: + resolution: {integrity: sha512-1NRKowiW0ZiB9SGLApLPBH4Xk8gDQJ+nA9NdZ+uy6MmJKLEwjuJxO7yTvRIv/jX/0/Ebh339S7Kq4RD2AiFuRg==} + engines: {node: '>=18'} + dev: false + /@sd-jwt/utils@0.6.1: resolution: {integrity: sha512-1NHZ//+GecGQJb+gSdDicnrHG0DvACUk9jTnXA5yLZhlRjgkjyfJLNsCZesYeCyVp/SiyvIC9B+JwoY4kI0TwQ==} engines: {node: '>=16'} @@ -983,6 +996,14 @@ packages: js-base64: 3.7.7 dev: false + /@sd-jwt/utils@0.7.2: + resolution: {integrity: sha512-aMPY7uHRMgyI5PlDvEiIc+eBFGC1EM8OCQRiEjJ8HGN0pajWMYj0qwSw7pS90A49/DsYU1a5Zpvb7nyjgGH0Yg==} + engines: {node: '>=18'} + dependencies: + '@sd-jwt/types': 0.7.2 + js-base64: 3.7.7 + dev: false + /@sinclair/typebox@0.27.8: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} dev: true @@ -1020,54 +1041,14 @@ packages: resolution: {integrity: sha512-SByU4cJ0XYA6VZQ/L6lsSiRcFtBPHbFioCeQ4GP7/W/jQ+PSBD7uK2oTnKQ9/0iEiMK/6JYqhKgLs4a9UX3UTQ==} dev: false - /@sphereon/ssi-sdk-ext.did-utils@0.24.1-next.112(ts-node@10.9.2): - resolution: {integrity: sha512-/qwAk5ivJBF8uRgsA66RK1nBYpDLvoE7ma05HHxENHfQFvrtoE29m/gjcyIFxvlew+HQhI3OHwzOZXGeadLGGw==} - dependencies: - '@ethersproject/networks': 5.7.1 - '@ethersproject/transactions': 5.7.0 - '@sphereon/did-uni-client': 0.6.3 - '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-next.112 - '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-next.112 - '@sphereon/ssi-sdk.agent-config': 0.29.1-unstable.161(ts-node@10.9.2) - '@sphereon/ssi-sdk.core': 0.29.1-unstable.161 - '@sphereon/ssi-types': 0.29.1-unstable.161 - '@stablelib/ed25519': 1.0.3 - '@veramo/core': 4.2.0 - '@veramo/utils': 4.2.0 - did-jwt: 6.11.6 - did-resolver: 4.1.0 - elliptic: 6.5.7 - uint8arrays: 3.1.1 - transitivePeerDependencies: - - '@google-cloud/spanner' - - '@sap/hana-client' - - better-sqlite3 - - encoding - - hdb-pool - - ioredis - - mongodb - - mssql - - mysql2 - - oracledb - - pg - - pg-native - - pg-query-stream - - redis - - sql.js - - sqlite3 - - supports-color - - ts-node - - typeorm-aurora-data-api-driver - dev: false - - /@sphereon/ssi-sdk-ext.did-utils@0.24.1-unstable.112(ts-node@10.9.2): - resolution: {integrity: sha512-nc0jFPOWg0H20S8m83aQUpNym0Wx0rJCGkgpH6GdK8gBtgza8Y9DvAap1AYZug18WbqPcF6rBjvtIJqAKsSvlQ==} + /@sphereon/ssi-sdk-ext.did-utils@0.24.1-unstable.130(ts-node@10.9.2): + resolution: {integrity: sha512-I+0VjitRjisABWm8RtTPQG57tFwfUS13Wud30OvBoADRxnaA0guUrkS82AYtV6YD0TBHdrd0D6a0RCJwK9SvDg==} dependencies: '@ethersproject/networks': 5.7.1 '@ethersproject/transactions': 5.7.0 '@sphereon/did-uni-client': 0.6.3 - '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-unstable.112 - '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.112 + '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-unstable.130 + '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.130 '@sphereon/ssi-sdk.agent-config': 0.29.1-unstable.161(ts-node@10.9.2) '@sphereon/ssi-sdk.core': 0.29.1-unstable.161 '@sphereon/ssi-types': 0.29.1-unstable.161 @@ -1100,12 +1081,12 @@ packages: - typeorm-aurora-data-api-driver dev: false - /@sphereon/ssi-sdk-ext.identifier-resolution@0.24.1-unstable.112(ts-node@10.9.2): - resolution: {integrity: sha512-VBkJjHokFNsQ0wsHUbyCysMuShTOEuK6yrvyW64uOFcB2hzq1J/wi9CewI+YRHv7mnejBlu46uYNycvOKKRcsQ==} + /@sphereon/ssi-sdk-ext.identifier-resolution@0.24.1-unstable.130(ts-node@10.9.2): + resolution: {integrity: sha512-9mY+qgXmbZCC8aic99R7B3vKBHBakDiC6Sktgd7Q9AknR8cCmvdrmTgnOETrLng9L43uNOJnNTMG/4T6LqmtsA==} dependencies: - '@sphereon/ssi-sdk-ext.did-utils': 0.24.1-unstable.112(ts-node@10.9.2) - '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-unstable.112 - '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.112 + '@sphereon/ssi-sdk-ext.did-utils': 0.24.1-unstable.130(ts-node@10.9.2) + '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-unstable.130 + '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.130 '@sphereon/ssi-sdk.agent-config': 0.29.1-unstable.161(ts-node@10.9.2) '@sphereon/ssi-types': 0.29.1-unstable.161 '@veramo/core': 4.2.0 @@ -1135,16 +1116,16 @@ packages: - typeorm-aurora-data-api-driver dev: false - /@sphereon/ssi-sdk-ext.jwt-service@0.24.1-unstable.112(ts-node@10.9.2): - resolution: {integrity: sha512-OrBaSg5wLSehkJ4MyuyDWKD4CRIBERnJqRT0o/y5DbaCF3k02+/lN/rWP+4qwk2w192fIEAExG4L2GwZM/5PLQ==} + /@sphereon/ssi-sdk-ext.jwt-service@0.24.1-unstable.130(ts-node@10.9.2): + resolution: {integrity: sha512-MHLGRmJODEYJyFoXKwlKMYzf48vS5JcUkGk0W4sqmrY1wwcw+ro3l8adIprG37mNuknXBs9Mv0x/tvibE9wwCQ==} dependencies: - '@sphereon/ssi-sdk-ext.did-utils': 0.24.1-next.112(ts-node@10.9.2) - '@sphereon/ssi-sdk-ext.identifier-resolution': 0.24.1-unstable.112(ts-node@10.9.2) - '@sphereon/ssi-sdk-ext.key-manager': 0.24.1-unstable.112 - '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-next.112 - '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.112 + '@sphereon/ssi-sdk-ext.did-utils': 0.24.1-unstable.130(ts-node@10.9.2) + '@sphereon/ssi-sdk-ext.identifier-resolution': 0.24.1-unstable.130(ts-node@10.9.2) + '@sphereon/ssi-sdk-ext.key-manager': 0.24.1-unstable.130 + '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-unstable.130 + '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.130 '@sphereon/ssi-sdk.agent-config': 0.29.1-unstable.161(ts-node@10.9.2) - '@sphereon/ssi-types': 0.29.1-unstable.237 + '@sphereon/ssi-types': 0.29.1-unstable.161 '@veramo/core': 4.2.0 '@veramo/utils': 4.2.0 debug: 4.3.6 @@ -1172,8 +1153,8 @@ packages: - typeorm-aurora-data-api-driver dev: false - /@sphereon/ssi-sdk-ext.key-manager@0.24.1-unstable.112: - resolution: {integrity: sha512-XdXV4qj+BYTZWyGHduWQxl0mxCYt5CF0Q93p4Thbm2/hjfaAC6aJi2WAXFGTIri95QVbKW1Uscob0CjNCVkWdg==} + /@sphereon/ssi-sdk-ext.key-manager@0.24.1-unstable.130: + resolution: {integrity: sha512-O/6NlKmlYRnEyP/mAI2Diu0qptMSqZfVwqog8KAOG/G8JUmktfSQmclBW8RoJ6AD9uY65BGzNk1oAVuuMv4Dog==} dependencies: '@veramo/core': 4.2.0 '@veramo/key-manager': 4.2.0 @@ -1182,35 +1163,11 @@ packages: - supports-color dev: false - /@sphereon/ssi-sdk-ext.key-utils@0.24.1-next.112: - resolution: {integrity: sha512-pySpFqfKn4fJ1wJMWRiVMh6zDyEQFs7adkyxlO5uDTKEYJ/9hQ++MD2t+seDpYjq5x2Wh+g60OzD1uiVdbL2aA==} - dependencies: - '@ethersproject/random': 5.7.0 - '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-next.112 - '@sphereon/ssi-types': 0.29.1-unstable.161 - '@stablelib/ed25519': 1.0.3 - '@stablelib/sha256': 1.0.1 - '@stablelib/sha512': 1.0.1 - '@trust/keyto': 1.0.1 - '@veramo/core': 4.2.0 - base64url: 3.0.1 - debug: 4.3.6 - did-resolver: 4.1.0 - elliptic: 6.5.7 - lodash.isplainobject: 4.0.6 - multiformats: 9.9.0 - uint8arrays: 3.1.1 - varint: 6.0.0 - web-encoding: 1.1.5 - transitivePeerDependencies: - - supports-color - dev: false - - /@sphereon/ssi-sdk-ext.key-utils@0.24.1-unstable.112: - resolution: {integrity: sha512-er6TwGUWxlao2lSP97r1DTFlUXcPSMsIToULOWQJp6wKbvCuvV6pN5luS0qKB/W0/TOUE5kXzFwNx086BPnPRA==} + /@sphereon/ssi-sdk-ext.key-utils@0.24.1-unstable.130: + resolution: {integrity: sha512-DCyXW18g1OAuZ+aFHzQGrbZSx793DX94LSFnrWlOTMnYeILmrizuFksUlWSb3lTqQGAqWBC48NoR3I1H6lSMEQ==} dependencies: '@ethersproject/random': 5.7.0 - '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.112 + '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.130 '@sphereon/ssi-types': 0.29.1-unstable.161 '@stablelib/ed25519': 1.0.3 '@stablelib/sha256': 1.0.1 @@ -1230,20 +1187,8 @@ packages: - supports-color dev: false - /@sphereon/ssi-sdk-ext.x509-utils@0.24.1-next.112: - resolution: {integrity: sha512-D15Kqh1oH620dMuPkImfNmVOpXtperQm6dGbo3jiJ9lvafjJzuVM9nHIeDoSI/uh/LkUXB7xuqD+4sATE/RO9g==} - dependencies: - '@trust/keyto': 1.0.1 - debug: 4.3.6 - js-x509-utils: 1.0.7 - pkijs: 3.2.4 - uint8arrays: 3.1.1 - transitivePeerDependencies: - - supports-color - dev: false - - /@sphereon/ssi-sdk-ext.x509-utils@0.24.1-unstable.112: - resolution: {integrity: sha512-bbx2jFoqWhW/xYABVwg3HiUo15yztPt3s+9bJtdB8n4PCjin4Nq3+vFvaHsmu70yAGkbWfsBcBVW6Y3oFtvpAA==} + /@sphereon/ssi-sdk-ext.x509-utils@0.24.1-unstable.130: + resolution: {integrity: sha512-JDX8i0WrwONaOivZXB+OxJQGkln7vuSLS61tOYl7M1RyPGixdBYuEuACsdvWf6egYOpaWmhmXZzaAOj18eDddw==} dependencies: '@trust/keyto': 1.0.1 debug: 4.3.6 @@ -1298,12 +1243,23 @@ packages: - supports-color dev: false - /@sphereon/ssi-types@0.29.1-unstable.121(ts-node@10.9.2): - resolution: {integrity: sha512-g5qt2cRa/9t3WrBWMneGOrwjyU2Mqdh4LlKeO6japli5bgl5D6lim91F++m1iIIhOYP4dqPpk5PLjy9XQlLyEw==} + /@sphereon/ssi-types@0.29.1-unstable.161: + resolution: {integrity: sha512-ifMADjk6k0f97/isK/4Qw/PX6n4k+qS5k6mmmH47MTD3KMDddVghoXycsvNw7wObJdLUalHBX630ghr+u21oMg==} dependencies: '@sd-jwt/decode': 0.6.1 + debug: 4.3.6 + events: 3.3.0 + jwt-decode: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: false + + /@sphereon/ssi-types@0.30.2-next.4(ts-node@10.9.2): + resolution: {integrity: sha512-v8z+qNAS/EWp7t7xT+JS4Fbn/rALmwz4swqFLjDuroXufJ+uz/nfzh2Qh6dNTKcXslRiG2lCN7CkP2C0FkJzQg==} + dependencies: + '@sd-jwt/decode': 0.7.2 '@sphereon/kmp-mdl-mdoc': 0.2.0-SNAPSHOT.22 - '@sphereon/ssi-sdk-ext.jwt-service': 0.24.1-unstable.112(ts-node@10.9.2) + '@sphereon/ssi-sdk-ext.jwt-service': 0.24.1-unstable.130(ts-node@10.9.2) debug: 4.3.6 events: 3.3.0 jwt-decode: 3.1.2 @@ -1329,29 +1285,6 @@ packages: - typeorm-aurora-data-api-driver dev: false - /@sphereon/ssi-types@0.29.1-unstable.161: - resolution: {integrity: sha512-ifMADjk6k0f97/isK/4Qw/PX6n4k+qS5k6mmmH47MTD3KMDddVghoXycsvNw7wObJdLUalHBX630ghr+u21oMg==} - dependencies: - '@sd-jwt/decode': 0.6.1 - debug: 4.3.6 - events: 3.3.0 - jwt-decode: 3.1.2 - transitivePeerDependencies: - - supports-color - dev: false - - /@sphereon/ssi-types@0.29.1-unstable.237: - resolution: {integrity: sha512-H9vqaFbCwbZpPUk5x84Cn1GeIFvwi7EZAsLN4h6EkXDwm55yOT76dvcSVUnL6obC2AzGr+Bjyv4R2cZSwKkguw==} - dependencies: - '@sd-jwt/decode': 0.6.1 - '@sphereon/kmp-mdl-mdoc': 0.2.0-SNAPSHOT.22 - debug: 4.3.6 - events: 3.3.0 - jwt-decode: 3.1.2 - transitivePeerDependencies: - - supports-color - dev: false - /@sqltools/formatter@1.2.5: resolution: {integrity: sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==} dev: false From 7ecc88cb22539b325f3230e67d072571ab2b2308 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Wed, 2 Oct 2024 14:19:04 +0200 Subject: [PATCH 21/47] chore: lockfile --- pnpm-lock.yaml | 140 +++++++++++++------------------------------------ 1 file changed, 37 insertions(+), 103 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 632b5529..c18a640f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,14 +9,14 @@ dependencies: specifier: ^1.1.2 version: 1.1.2 '@sd-jwt/decode': - specifier: ^0.6.1 - version: 0.6.1 + specifier: ^0.7.2 + version: 0.7.2 '@sd-jwt/present': - specifier: ^0.6.1 - version: 0.6.1 + specifier: ^0.7.2 + version: 0.7.2 '@sd-jwt/types': - specifier: ^0.6.1 - version: 0.6.1 + specifier: ^0.7.2 + version: 0.7.2 '@sphereon/pex-models': specifier: ^2.3.1 version: 2.3.1 @@ -961,13 +961,21 @@ packages: '@sd-jwt/utils': 0.6.1 dev: false - /@sd-jwt/present@0.6.1: - resolution: {integrity: sha512-QRD3TUDLj4PqQNZ70bBxh8FLLrOE9mY8V9qiZrJSsaDOLFs2p1CtZG+v9ig62fxFYJZMf4bWKwYjz+qqGAtxCg==} - engines: {node: '>=16'} + /@sd-jwt/decode@0.7.2: + resolution: {integrity: sha512-dan2LSvK63SKwb62031G4r7TE4TaiI0EK1KbPXqS+LCXNkNDUHqhtYp9uOpj+grXceCsMtMa2f8VnUfsjmwHHg==} + engines: {node: '>=18'} dependencies: - '@sd-jwt/decode': 0.6.1 - '@sd-jwt/types': 0.6.1 - '@sd-jwt/utils': 0.6.1 + '@sd-jwt/types': 0.7.2 + '@sd-jwt/utils': 0.7.2 + dev: false + + /@sd-jwt/present@0.7.2: + resolution: {integrity: sha512-mQV85u2+mLLy2VZ9Wx2zpaB6yTDnbhCfWkP7eeCrzJQHBKAAHko8GrylEFmLKewFIcajS/r4lT/zHOsCkp5pZw==} + engines: {node: '>=18'} + dependencies: + '@sd-jwt/decode': 0.7.2 + '@sd-jwt/types': 0.7.2 + '@sd-jwt/utils': 0.7.2 dev: false /@sd-jwt/types@0.6.1: @@ -975,6 +983,11 @@ packages: engines: {node: '>=16'} dev: false + /@sd-jwt/types@0.7.2: + resolution: {integrity: sha512-1NRKowiW0ZiB9SGLApLPBH4Xk8gDQJ+nA9NdZ+uy6MmJKLEwjuJxO7yTvRIv/jX/0/Ebh339S7Kq4RD2AiFuRg==} + engines: {node: '>=18'} + dev: false + /@sd-jwt/utils@0.6.1: resolution: {integrity: sha512-1NHZ//+GecGQJb+gSdDicnrHG0DvACUk9jTnXA5yLZhlRjgkjyfJLNsCZesYeCyVp/SiyvIC9B+JwoY4kI0TwQ==} engines: {node: '>=16'} @@ -983,6 +996,14 @@ packages: js-base64: 3.7.7 dev: false + /@sd-jwt/utils@0.7.2: + resolution: {integrity: sha512-aMPY7uHRMgyI5PlDvEiIc+eBFGC1EM8OCQRiEjJ8HGN0pajWMYj0qwSw7pS90A49/DsYU1a5Zpvb7nyjgGH0Yg==} + engines: {node: '>=18'} + dependencies: + '@sd-jwt/types': 0.7.2 + js-base64: 3.7.7 + dev: false + /@sinclair/typebox@0.27.8: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} dev: true @@ -1015,51 +1036,12 @@ packages: '@js-joda/timezone': 2.3.0(@js-joda/core@5.6.3) format-util: 1.0.5 dev: false + bundledDependencies: [] /@sphereon/pex-models@2.3.1: resolution: {integrity: sha512-SByU4cJ0XYA6VZQ/L6lsSiRcFtBPHbFioCeQ4GP7/W/jQ+PSBD7uK2oTnKQ9/0iEiMK/6JYqhKgLs4a9UX3UTQ==} dev: false - /@sphereon/ssi-sdk-ext.did-utils@0.24.1-next.112(ts-node@10.9.2): - resolution: {integrity: sha512-/qwAk5ivJBF8uRgsA66RK1nBYpDLvoE7ma05HHxENHfQFvrtoE29m/gjcyIFxvlew+HQhI3OHwzOZXGeadLGGw==} - dependencies: - '@ethersproject/networks': 5.7.1 - '@ethersproject/transactions': 5.7.0 - '@sphereon/did-uni-client': 0.6.3 - '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-next.112 - '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-next.112 - '@sphereon/ssi-sdk.agent-config': 0.29.1-unstable.161(ts-node@10.9.2) - '@sphereon/ssi-sdk.core': 0.29.1-unstable.161 - '@sphereon/ssi-types': 0.29.1-unstable.161 - '@stablelib/ed25519': 1.0.3 - '@veramo/core': 4.2.0 - '@veramo/utils': 4.2.0 - did-jwt: 6.11.6 - did-resolver: 4.1.0 - elliptic: 6.5.7 - uint8arrays: 3.1.1 - transitivePeerDependencies: - - '@google-cloud/spanner' - - '@sap/hana-client' - - better-sqlite3 - - encoding - - hdb-pool - - ioredis - - mongodb - - mssql - - mysql2 - - oracledb - - pg - - pg-native - - pg-query-stream - - redis - - sql.js - - sqlite3 - - supports-color - - ts-node - - typeorm-aurora-data-api-driver - dev: false - /@sphereon/ssi-sdk-ext.did-utils@0.24.1-unstable.112(ts-node@10.9.2): resolution: {integrity: sha512-nc0jFPOWg0H20S8m83aQUpNym0Wx0rJCGkgpH6GdK8gBtgza8Y9DvAap1AYZug18WbqPcF6rBjvtIJqAKsSvlQ==} dependencies: @@ -1138,13 +1120,13 @@ packages: /@sphereon/ssi-sdk-ext.jwt-service@0.24.1-unstable.112(ts-node@10.9.2): resolution: {integrity: sha512-OrBaSg5wLSehkJ4MyuyDWKD4CRIBERnJqRT0o/y5DbaCF3k02+/lN/rWP+4qwk2w192fIEAExG4L2GwZM/5PLQ==} dependencies: - '@sphereon/ssi-sdk-ext.did-utils': 0.24.1-next.112(ts-node@10.9.2) + '@sphereon/ssi-sdk-ext.did-utils': 0.24.1-unstable.112(ts-node@10.9.2) '@sphereon/ssi-sdk-ext.identifier-resolution': 0.24.1-unstable.112(ts-node@10.9.2) '@sphereon/ssi-sdk-ext.key-manager': 0.24.1-unstable.112 - '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-next.112 + '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-unstable.112 '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.112 '@sphereon/ssi-sdk.agent-config': 0.29.1-unstable.161(ts-node@10.9.2) - '@sphereon/ssi-types': 0.29.1-unstable.237 + '@sphereon/ssi-types': 0.29.1-unstable.161 '@veramo/core': 4.2.0 '@veramo/utils': 4.2.0 debug: 4.3.6 @@ -1182,30 +1164,6 @@ packages: - supports-color dev: false - /@sphereon/ssi-sdk-ext.key-utils@0.24.1-next.112: - resolution: {integrity: sha512-pySpFqfKn4fJ1wJMWRiVMh6zDyEQFs7adkyxlO5uDTKEYJ/9hQ++MD2t+seDpYjq5x2Wh+g60OzD1uiVdbL2aA==} - dependencies: - '@ethersproject/random': 5.7.0 - '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-next.112 - '@sphereon/ssi-types': 0.29.1-unstable.161 - '@stablelib/ed25519': 1.0.3 - '@stablelib/sha256': 1.0.1 - '@stablelib/sha512': 1.0.1 - '@trust/keyto': 1.0.1 - '@veramo/core': 4.2.0 - base64url: 3.0.1 - debug: 4.3.6 - did-resolver: 4.1.0 - elliptic: 6.5.7 - lodash.isplainobject: 4.0.6 - multiformats: 9.9.0 - uint8arrays: 3.1.1 - varint: 6.0.0 - web-encoding: 1.1.5 - transitivePeerDependencies: - - supports-color - dev: false - /@sphereon/ssi-sdk-ext.key-utils@0.24.1-unstable.112: resolution: {integrity: sha512-er6TwGUWxlao2lSP97r1DTFlUXcPSMsIToULOWQJp6wKbvCuvV6pN5luS0qKB/W0/TOUE5kXzFwNx086BPnPRA==} dependencies: @@ -1230,18 +1188,6 @@ packages: - supports-color dev: false - /@sphereon/ssi-sdk-ext.x509-utils@0.24.1-next.112: - resolution: {integrity: sha512-D15Kqh1oH620dMuPkImfNmVOpXtperQm6dGbo3jiJ9lvafjJzuVM9nHIeDoSI/uh/LkUXB7xuqD+4sATE/RO9g==} - dependencies: - '@trust/keyto': 1.0.1 - debug: 4.3.6 - js-x509-utils: 1.0.7 - pkijs: 3.2.4 - uint8arrays: 3.1.1 - transitivePeerDependencies: - - supports-color - dev: false - /@sphereon/ssi-sdk-ext.x509-utils@0.24.1-unstable.112: resolution: {integrity: sha512-bbx2jFoqWhW/xYABVwg3HiUo15yztPt3s+9bJtdB8n4PCjin4Nq3+vFvaHsmu70yAGkbWfsBcBVW6Y3oFtvpAA==} dependencies: @@ -1340,18 +1286,6 @@ packages: - supports-color dev: false - /@sphereon/ssi-types@0.29.1-unstable.237: - resolution: {integrity: sha512-H9vqaFbCwbZpPUk5x84Cn1GeIFvwi7EZAsLN4h6EkXDwm55yOT76dvcSVUnL6obC2AzGr+Bjyv4R2cZSwKkguw==} - dependencies: - '@sd-jwt/decode': 0.6.1 - '@sphereon/kmp-mdl-mdoc': 0.2.0-SNAPSHOT.22 - debug: 4.3.6 - events: 3.3.0 - jwt-decode: 3.1.2 - transitivePeerDependencies: - - supports-color - dev: false - /@sqltools/formatter@1.2.5: resolution: {integrity: sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==} dev: false From 57deb6b983a727b8e95ad729f8a14747414b906f Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Wed, 2 Oct 2024 14:55:46 +0200 Subject: [PATCH 22/47] chore: ssi-types main release --- package.json | 2 +- pnpm-lock.yaml | 291 +++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 260 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index d90a6bc3..990a0e5c 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "@sd-jwt/present": "^0.7.2", "@sd-jwt/types": "^0.7.2", "@sphereon/pex-models": "^2.3.1", - "@sphereon/ssi-types": "0.30.2-next.4", + "@sphereon/ssi-types": "0.30.1", "ajv": "^8.12.0", "ajv-formats": "^2.1.1", "jwt-decode": "^3.1.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c18a640f..a7052f92 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21,8 +21,8 @@ dependencies: specifier: ^2.3.1 version: 2.3.1 '@sphereon/ssi-types': - specifier: 0.29.1-unstable.121 - version: 0.29.1-unstable.121(ts-node@10.9.2) + specifier: 0.30.1 + version: 0.30.1(ts-node@10.9.2) ajv: specifier: ^8.12.0 version: 8.12.0 @@ -1036,20 +1036,19 @@ packages: '@js-joda/timezone': 2.3.0(@js-joda/core@5.6.3) format-util: 1.0.5 dev: false - bundledDependencies: [] /@sphereon/pex-models@2.3.1: resolution: {integrity: sha512-SByU4cJ0XYA6VZQ/L6lsSiRcFtBPHbFioCeQ4GP7/W/jQ+PSBD7uK2oTnKQ9/0iEiMK/6JYqhKgLs4a9UX3UTQ==} dev: false - /@sphereon/ssi-sdk-ext.did-utils@0.24.1-unstable.112(ts-node@10.9.2): - resolution: {integrity: sha512-nc0jFPOWg0H20S8m83aQUpNym0Wx0rJCGkgpH6GdK8gBtgza8Y9DvAap1AYZug18WbqPcF6rBjvtIJqAKsSvlQ==} + /@sphereon/ssi-sdk-ext.did-utils@0.24.1-unstable.124(ts-node@10.9.2): + resolution: {integrity: sha512-LA6xwRL21dfiAnzqCxWXp5Ew+YWOXZXNgDK01ti3q06aRLJCxUAvydEHPy0DAtGMOI2fQwe7+UJXWkx0dVFQNw==} dependencies: '@ethersproject/networks': 5.7.1 '@ethersproject/transactions': 5.7.0 '@sphereon/did-uni-client': 0.6.3 - '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-unstable.112 - '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.112 + '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-unstable.124 + '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.124 '@sphereon/ssi-sdk.agent-config': 0.29.1-unstable.161(ts-node@10.9.2) '@sphereon/ssi-sdk.core': 0.29.1-unstable.161 '@sphereon/ssi-types': 0.29.1-unstable.161 @@ -1082,12 +1081,87 @@ packages: - typeorm-aurora-data-api-driver dev: false - /@sphereon/ssi-sdk-ext.identifier-resolution@0.24.1-unstable.112(ts-node@10.9.2): - resolution: {integrity: sha512-VBkJjHokFNsQ0wsHUbyCysMuShTOEuK6yrvyW64uOFcB2hzq1J/wi9CewI+YRHv7mnejBlu46uYNycvOKKRcsQ==} + /@sphereon/ssi-sdk-ext.did-utils@0.24.1-unstable.130(ts-node@10.9.2): + resolution: {integrity: sha512-I+0VjitRjisABWm8RtTPQG57tFwfUS13Wud30OvBoADRxnaA0guUrkS82AYtV6YD0TBHdrd0D6a0RCJwK9SvDg==} dependencies: - '@sphereon/ssi-sdk-ext.did-utils': 0.24.1-unstable.112(ts-node@10.9.2) - '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-unstable.112 - '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.112 + '@ethersproject/networks': 5.7.1 + '@ethersproject/transactions': 5.7.0 + '@sphereon/did-uni-client': 0.6.3 + '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-unstable.130 + '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.130 + '@sphereon/ssi-sdk.agent-config': 0.29.1-unstable.161(ts-node@10.9.2) + '@sphereon/ssi-sdk.core': 0.30.1-unstable.5(ts-node@10.9.2) + '@sphereon/ssi-types': 0.30.1-unstable.5(ts-node@10.9.2) + '@stablelib/ed25519': 1.0.3 + '@veramo/core': 4.2.0 + '@veramo/utils': 4.2.0 + did-jwt: 6.11.6 + did-resolver: 4.1.0 + elliptic: 6.5.7 + uint8arrays: 3.1.1 + transitivePeerDependencies: + - '@google-cloud/spanner' + - '@sap/hana-client' + - better-sqlite3 + - encoding + - hdb-pool + - ioredis + - mongodb + - mssql + - mysql2 + - oracledb + - pg + - pg-native + - pg-query-stream + - redis + - sql.js + - sqlite3 + - supports-color + - ts-node + - typeorm-aurora-data-api-driver + dev: false + + /@sphereon/ssi-sdk-ext.identifier-resolution@0.24.1-unstable.124(ts-node@10.9.2): + resolution: {integrity: sha512-PXutE4aYBcZI0BtCsWoUvv7hSRoBkeMqYOcvhERtLFqCCempRKN+Ue6P1JMadRvMp3YBuc0C/xHzdeNN/KPaHw==} + dependencies: + '@sphereon/ssi-sdk-ext.did-utils': 0.24.1-unstable.124(ts-node@10.9.2) + '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-unstable.124 + '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.124 + '@sphereon/ssi-sdk.agent-config': 0.29.1-unstable.161(ts-node@10.9.2) + '@sphereon/ssi-types': 0.29.1-unstable.161 + '@veramo/core': 4.2.0 + '@veramo/utils': 4.2.0 + debug: 4.3.6 + pkijs: 3.2.4 + uint8arrays: 3.1.1 + transitivePeerDependencies: + - '@google-cloud/spanner' + - '@sap/hana-client' + - better-sqlite3 + - encoding + - hdb-pool + - ioredis + - mongodb + - mssql + - mysql2 + - oracledb + - pg + - pg-native + - pg-query-stream + - redis + - sql.js + - sqlite3 + - supports-color + - ts-node + - typeorm-aurora-data-api-driver + dev: false + + /@sphereon/ssi-sdk-ext.identifier-resolution@0.24.1-unstable.130(ts-node@10.9.2): + resolution: {integrity: sha512-9mY+qgXmbZCC8aic99R7B3vKBHBakDiC6Sktgd7Q9AknR8cCmvdrmTgnOETrLng9L43uNOJnNTMG/4T6LqmtsA==} + dependencies: + '@sphereon/ssi-sdk-ext.did-utils': 0.24.1-unstable.130(ts-node@10.9.2) + '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-unstable.130 + '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.130 '@sphereon/ssi-sdk.agent-config': 0.29.1-unstable.161(ts-node@10.9.2) '@sphereon/ssi-types': 0.29.1-unstable.161 '@veramo/core': 4.2.0 @@ -1117,14 +1191,14 @@ packages: - typeorm-aurora-data-api-driver dev: false - /@sphereon/ssi-sdk-ext.jwt-service@0.24.1-unstable.112(ts-node@10.9.2): - resolution: {integrity: sha512-OrBaSg5wLSehkJ4MyuyDWKD4CRIBERnJqRT0o/y5DbaCF3k02+/lN/rWP+4qwk2w192fIEAExG4L2GwZM/5PLQ==} + /@sphereon/ssi-sdk-ext.jwt-service@0.24.1-unstable.124(ts-node@10.9.2): + resolution: {integrity: sha512-U1feY1ZMZR/ETLdoW5dYH1X0JpL2Y6X+qzMSV2a8/O9hd16qNlOJ+T6uhXw1SqC/ihVHB7fE6VF+SvtziOgI/w==} dependencies: - '@sphereon/ssi-sdk-ext.did-utils': 0.24.1-unstable.112(ts-node@10.9.2) - '@sphereon/ssi-sdk-ext.identifier-resolution': 0.24.1-unstable.112(ts-node@10.9.2) - '@sphereon/ssi-sdk-ext.key-manager': 0.24.1-unstable.112 - '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-unstable.112 - '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.112 + '@sphereon/ssi-sdk-ext.did-utils': 0.24.1-unstable.124(ts-node@10.9.2) + '@sphereon/ssi-sdk-ext.identifier-resolution': 0.24.1-unstable.124(ts-node@10.9.2) + '@sphereon/ssi-sdk-ext.key-manager': 0.24.1-unstable.124 + '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-unstable.124 + '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.124 '@sphereon/ssi-sdk.agent-config': 0.29.1-unstable.161(ts-node@10.9.2) '@sphereon/ssi-types': 0.29.1-unstable.161 '@veramo/core': 4.2.0 @@ -1154,8 +1228,45 @@ packages: - typeorm-aurora-data-api-driver dev: false - /@sphereon/ssi-sdk-ext.key-manager@0.24.1-unstable.112: - resolution: {integrity: sha512-XdXV4qj+BYTZWyGHduWQxl0mxCYt5CF0Q93p4Thbm2/hjfaAC6aJi2WAXFGTIri95QVbKW1Uscob0CjNCVkWdg==} + /@sphereon/ssi-sdk-ext.jwt-service@0.24.1-unstable.130(ts-node@10.9.2): + resolution: {integrity: sha512-MHLGRmJODEYJyFoXKwlKMYzf48vS5JcUkGk0W4sqmrY1wwcw+ro3l8adIprG37mNuknXBs9Mv0x/tvibE9wwCQ==} + dependencies: + '@sphereon/ssi-sdk-ext.did-utils': 0.24.1-unstable.130(ts-node@10.9.2) + '@sphereon/ssi-sdk-ext.identifier-resolution': 0.24.1-unstable.130(ts-node@10.9.2) + '@sphereon/ssi-sdk-ext.key-manager': 0.24.1-unstable.130 + '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-unstable.130 + '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.130 + '@sphereon/ssi-sdk.agent-config': 0.29.1-unstable.161(ts-node@10.9.2) + '@sphereon/ssi-types': 0.30.1-unstable.5(ts-node@10.9.2) + '@veramo/core': 4.2.0 + '@veramo/utils': 4.2.0 + debug: 4.3.6 + jwt-decode: 4.0.0 + uint8arrays: 3.1.1 + transitivePeerDependencies: + - '@google-cloud/spanner' + - '@sap/hana-client' + - better-sqlite3 + - encoding + - hdb-pool + - ioredis + - mongodb + - mssql + - mysql2 + - oracledb + - pg + - pg-native + - pg-query-stream + - redis + - sql.js + - sqlite3 + - supports-color + - ts-node + - typeorm-aurora-data-api-driver + dev: false + + /@sphereon/ssi-sdk-ext.key-manager@0.24.1-unstable.124: + resolution: {integrity: sha512-5eURqsVPOKGXrA3hRiAyJ6bMhMQmFrVNPEy78zd8BhBZ+4OLxJw4Dwcd0vfG+sddH6tRNzKnxv24mzIo6cyl+Q==} dependencies: '@veramo/core': 4.2.0 '@veramo/key-manager': 4.2.0 @@ -1164,11 +1275,21 @@ packages: - supports-color dev: false - /@sphereon/ssi-sdk-ext.key-utils@0.24.1-unstable.112: - resolution: {integrity: sha512-er6TwGUWxlao2lSP97r1DTFlUXcPSMsIToULOWQJp6wKbvCuvV6pN5luS0qKB/W0/TOUE5kXzFwNx086BPnPRA==} + /@sphereon/ssi-sdk-ext.key-manager@0.24.1-unstable.130: + resolution: {integrity: sha512-O/6NlKmlYRnEyP/mAI2Diu0qptMSqZfVwqog8KAOG/G8JUmktfSQmclBW8RoJ6AD9uY65BGzNk1oAVuuMv4Dog==} + dependencies: + '@veramo/core': 4.2.0 + '@veramo/key-manager': 4.2.0 + uint8arrays: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: false + + /@sphereon/ssi-sdk-ext.key-utils@0.24.1-unstable.124: + resolution: {integrity: sha512-I5E4SzHwBOQviR8W5muCorAhzUWaX8XK5JXUdiMuJfVfF3UW3V4YriOr1Ar6HbNT2TxRWIaPdcLGrVEDZn0VGQ==} dependencies: '@ethersproject/random': 5.7.0 - '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.112 + '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.124 '@sphereon/ssi-types': 0.29.1-unstable.161 '@stablelib/ed25519': 1.0.3 '@stablelib/sha256': 1.0.1 @@ -1188,8 +1309,44 @@ packages: - supports-color dev: false - /@sphereon/ssi-sdk-ext.x509-utils@0.24.1-unstable.112: - resolution: {integrity: sha512-bbx2jFoqWhW/xYABVwg3HiUo15yztPt3s+9bJtdB8n4PCjin4Nq3+vFvaHsmu70yAGkbWfsBcBVW6Y3oFtvpAA==} + /@sphereon/ssi-sdk-ext.key-utils@0.24.1-unstable.130: + resolution: {integrity: sha512-DCyXW18g1OAuZ+aFHzQGrbZSx793DX94LSFnrWlOTMnYeILmrizuFksUlWSb3lTqQGAqWBC48NoR3I1H6lSMEQ==} + dependencies: + '@ethersproject/random': 5.7.0 + '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.130 + '@sphereon/ssi-types': 0.29.1-unstable.161 + '@stablelib/ed25519': 1.0.3 + '@stablelib/sha256': 1.0.1 + '@stablelib/sha512': 1.0.1 + '@trust/keyto': 1.0.1 + '@veramo/core': 4.2.0 + base64url: 3.0.1 + debug: 4.3.6 + did-resolver: 4.1.0 + elliptic: 6.5.7 + lodash.isplainobject: 4.0.6 + multiformats: 9.9.0 + uint8arrays: 3.1.1 + varint: 6.0.0 + web-encoding: 1.1.5 + transitivePeerDependencies: + - supports-color + dev: false + + /@sphereon/ssi-sdk-ext.x509-utils@0.24.1-unstable.124: + resolution: {integrity: sha512-JPY5xQ/7EttUHsXmK/kj5/tmpYunneE6/ctBk4P+gZGwpqRnLMdDX6cvnxYdwBbFyCpOI+lyDc3USsp52UupKg==} + dependencies: + '@trust/keyto': 1.0.1 + debug: 4.3.6 + js-x509-utils: 1.0.7 + pkijs: 3.2.4 + uint8arrays: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: false + + /@sphereon/ssi-sdk-ext.x509-utils@0.24.1-unstable.130: + resolution: {integrity: sha512-JDX8i0WrwONaOivZXB+OxJQGkln7vuSLS61tOYl7M1RyPGixdBYuEuACsdvWf6egYOpaWmhmXZzaAOj18eDddw==} dependencies: '@trust/keyto': 1.0.1 debug: 4.3.6 @@ -1244,12 +1401,54 @@ packages: - supports-color dev: false - /@sphereon/ssi-types@0.29.1-unstable.121(ts-node@10.9.2): - resolution: {integrity: sha512-g5qt2cRa/9t3WrBWMneGOrwjyU2Mqdh4LlKeO6japli5bgl5D6lim91F++m1iIIhOYP4dqPpk5PLjy9XQlLyEw==} + /@sphereon/ssi-sdk.core@0.30.1-unstable.5(ts-node@10.9.2): + resolution: {integrity: sha512-Ein4RLmPto1MYp65i7y31mQInsL5F6suFwYIpB5SPRWBy8WIMzKIuPWcH8vCyNYUdxa21c/X57MkhEssYhvWlg==} + dependencies: + '@sphereon/ssi-types': 0.30.1-unstable.5(ts-node@10.9.2) + '@veramo/core': 4.2.0 + cross-fetch: 3.1.8 + debug: 4.3.6 + image-size: 2.0.0-beta.2 + uint8arrays: 3.1.1 + transitivePeerDependencies: + - '@google-cloud/spanner' + - '@sap/hana-client' + - better-sqlite3 + - encoding + - hdb-pool + - ioredis + - mongodb + - mssql + - mysql2 + - oracledb + - pg + - pg-native + - pg-query-stream + - redis + - sql.js + - sqlite3 + - supports-color + - ts-node + - typeorm-aurora-data-api-driver + dev: false + + /@sphereon/ssi-types@0.29.1-unstable.161: + resolution: {integrity: sha512-ifMADjk6k0f97/isK/4Qw/PX6n4k+qS5k6mmmH47MTD3KMDddVghoXycsvNw7wObJdLUalHBX630ghr+u21oMg==} dependencies: '@sd-jwt/decode': 0.6.1 + debug: 4.3.6 + events: 3.3.0 + jwt-decode: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: false + + /@sphereon/ssi-types@0.30.1(ts-node@10.9.2): + resolution: {integrity: sha512-vbYaxQXb71sOPwDj7TRDlUGfIHKVVs8PiHfImPBgSBshrD7VpEHOrB+EwwavMm5MAQvWK/yblGmzk7FHds7SHA==} + dependencies: + '@sd-jwt/decode': 0.7.2 '@sphereon/kmp-mdl-mdoc': 0.2.0-SNAPSHOT.22 - '@sphereon/ssi-sdk-ext.jwt-service': 0.24.1-unstable.112(ts-node@10.9.2) + '@sphereon/ssi-sdk-ext.jwt-service': 0.24.1-unstable.130(ts-node@10.9.2) debug: 4.3.6 events: 3.3.0 jwt-decode: 3.1.2 @@ -1275,15 +1474,35 @@ packages: - typeorm-aurora-data-api-driver dev: false - /@sphereon/ssi-types@0.29.1-unstable.161: - resolution: {integrity: sha512-ifMADjk6k0f97/isK/4Qw/PX6n4k+qS5k6mmmH47MTD3KMDddVghoXycsvNw7wObJdLUalHBX630ghr+u21oMg==} + /@sphereon/ssi-types@0.30.1-unstable.5(ts-node@10.9.2): + resolution: {integrity: sha512-z9MTLvOKpTJPP3UmhCIGXntWbZ0Uvrei6W72AXuZ0x3ko4w8p4gbSatECq6D2tHbucSvSzC+URpr8FtwP/fMPQ==} dependencies: '@sd-jwt/decode': 0.6.1 + '@sphereon/kmp-mdl-mdoc': 0.2.0-SNAPSHOT.22 + '@sphereon/ssi-sdk-ext.jwt-service': 0.24.1-unstable.124(ts-node@10.9.2) debug: 4.3.6 events: 3.3.0 jwt-decode: 3.1.2 transitivePeerDependencies: + - '@google-cloud/spanner' + - '@sap/hana-client' + - better-sqlite3 + - encoding + - hdb-pool + - ioredis + - mongodb + - mssql + - mysql2 + - oracledb + - pg + - pg-native + - pg-query-stream + - redis + - sql.js + - sqlite3 - supports-color + - ts-node + - typeorm-aurora-data-api-driver dev: false /@sqltools/formatter@1.2.5: @@ -1700,7 +1919,7 @@ packages: cross-fetch: 3.1.8 debug: 4.3.6 did-jwt: 6.11.6 - did-jwt-vc: 3.2.15 + did-jwt-vc: 3.1.3 did-resolver: 4.1.0 elliptic: 6.5.7 multiformats: 9.7.1 @@ -2482,6 +2701,14 @@ packages: engines: {node: '>=8'} dev: true + /did-jwt-vc@3.1.3: + resolution: {integrity: sha512-qB1FiQ0sT/FUR5+mQ//P5lS0Gllrtes2OxC3WVMOt8ND0LolF92ohozv50ukyOvB2zBzgfm5durcIPqQcoI+LA==} + engines: {node: '>=14'} + dependencies: + did-jwt: 6.11.6 + did-resolver: 4.1.0 + dev: false + /did-jwt-vc@3.2.15: resolution: {integrity: sha512-M/WPiL34CQUiN4bvWnZ0OFHJ3usPtstfQfbNbHAWHvwjeCGi7nAdv62VXHgy2xIhJMc790hH7PsMN3i6SCGEyg==} engines: {node: '>=18'} From 21e61f30f4bb89a0b5a511556f0a076c46820fec Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Wed, 2 Oct 2024 14:57:03 +0200 Subject: [PATCH 23/47] chore: do jot fail CI on codecov --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ca1cddee..e2112633 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -36,7 +36,7 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos name: codecove # optional flags: unittest - fail_ci_if_error: true # optional (default = false) + fail_ci_if_error: false # optional (default = false) #directory: ./coverage/reports/ #files: ./coverage1.xml,./coverage2.xml verbose: true # optional (default = false) From 88eb3f91c0dedc05ce5be521188beb3759eca65c Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Wed, 2 Oct 2024 14:59:25 +0200 Subject: [PATCH 24/47] chore: release unstable.11 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 990a0e5c..a4903e57 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sphereon/pex", - "version": "5.0.0-unstable.9", + "version": "5.0.0-unstable.11", "description": "A Typescript implementation of the v1 and v2 DIF Presentation Exchange specification", "main": "dist/main/index.js", "module": "dist/module/index.js", From 057899fa4554f5c54374b44c61783e381b49bb87 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Wed, 2 Oct 2024 21:30:22 +0200 Subject: [PATCH 25/47] chore: multi-vp fixes --- lib/PEX.ts | 267 +++++++++++----------- lib/PEXv1.ts | 4 +- lib/PEXv2.ts | 4 +- lib/evaluation/core/evaluationResults.ts | 2 +- lib/evaluation/evaluationClientWrapper.ts | 8 +- lib/signing/types.ts | 4 +- package.json | 2 +- test/PEX.spec.ts | 24 +- test/PEXv1.spec.ts | 4 +- test/PEXv2.spec.ts | 4 +- test/SdJwt.spec.ts | 18 +- test/evaluation/check-scenario-1.spec.ts | 2 +- test/evaluation/selectFrom.spec.ts | 11 +- test/thirdParty/Gataca.spec.ts | 4 +- test/thirdParty/JGiter.spec.ts | 4 +- 15 files changed, 180 insertions(+), 182 deletions(-) diff --git a/lib/PEX.ts b/lib/PEX.ts index f55c3e25..0635d386 100644 --- a/lib/PEX.ts +++ b/lib/PEX.ts @@ -106,7 +106,7 @@ export class PEX { let presentationSubmission = opts?.presentationSubmission; let presentationSubmissionLocation = opts?.presentationSubmissionLocation ?? - (Array.isArray(presentations) || !CredentialMapper.isW3cPresentation(wrappedPresentations[0].presentation) + ((Array.isArray(presentations) && presentations.length > 1) || !CredentialMapper.isW3cPresentation(wrappedPresentations[0].presentation) ? PresentationSubmissionLocation.EXTERNAL : PresentationSubmissionLocation.PRESENTATION); @@ -290,21 +290,21 @@ export class PEX { opts?.presentationSubmissionLocation ?? (hasSdJwtCredentials ? PresentationSubmissionLocation.EXTERNAL : PresentationSubmissionLocation.PRESENTATION); - const presentation = PEX.constructPresentation(selectedCredentials, { + const presentations = this.constructPresentations(selectedCredentials, { ...opts, // We only pass in the submission in case it needs to be included in the presentation presentationSubmission: presentationSubmissionLocation === PresentationSubmissionLocation.PRESENTATION ? presentationSubmission : undefined, hasher: this.options?.hasher, }); - + this.updateSdJwtCredentials(presentations); return { - presentation, + presentations, presentationSubmissionLocation, presentationSubmission, }; } - public static constructPresentation( + public constructPresentations( selectedCredentials: OriginalVerifiableCredential | OriginalVerifiableCredential[], opts?: { presentationSubmission?: PresentationSubmission; @@ -315,108 +315,89 @@ export class PEX { */ hasher?: Hasher; }, - ): IPresentation | PartialSdJwtDecodedVerifiableCredential { - const credentials = Array.isArray(selectedCredentials) ? selectedCredentials : [selectedCredentials]; - - // for SD-JWT we want to return the SD-JWT with only the needed disclosures (so filter disclosures array, and update the compactSdJwt) - // in addition we want to create the KB-JWT payload as well. - // FIXME: include the KB-JWT payload? - if (credentials.some((c) => CredentialMapper.isSdJwtDecodedCredential(c) || CredentialMapper.isSdJwtEncoded(c))) { - if (credentials.length > 1) { - // Until there's some consensus around the following issue, we'll only support a single - // SD-JWT credential in a presentation - // https://github.com/decentralized-identity/presentation-exchange/issues/462 - throw new Error('Only a single credential is supported when creating a presentation with an SD-JWT VC'); - } - - if (opts?.presentationSubmission) { - throw new Error('Presentation submission cannot be included in the presentation when creating a presentation with an SD-JWT VC'); - } - - if (opts?.basePresentationPayload) { - throw new Error('Base presentation payload cannot be when creating a presentation from an SD-JWT VC'); - } - - // NOTE: we assume the credential already has selective disclosure applied, even if it is encoded. Is - // that a valid assumption? It seems to be this way for BBS SD as well - const decoded = ( - CredentialMapper.isSdJwtEncoded(credentials[0]) ? CredentialMapper.decodeVerifiableCredential(credentials[0], opts?.hasher) : credentials[0] - ) as SdJwtDecodedVerifiableCredential; - - if (!opts?.hasher) { + ): Array { + 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[]; + if (verifiableCredential.some((c) => CredentialMapper.isSdJwtDecodedCredential(c) || CredentialMapper.isSdJwtEncoded(c))) { + if (!this.options?.hasher) { throw new Error('Hasher must be provided when creating a presentation with an SD-JWT VC'); } + } - // extract sd_alg or default to sha-256 - const hashAlg = decoded.signedPayload._sd_alg ?? 'sha-256'; - const sdHash = calculateSdHash(decoded.compactSdJwtVc, hashAlg, opts.hasher); - - const kbJwt = { - // alg MUST be set by the signer - header: { - typ: 'kb+jwt', - // aud MUST be set by the signer or provided by e.g. SIOP/OpenID4VP lib - }, - payload: { - iat: Math.floor(new Date().getTime() / 1000), - sd_hash: sdHash, - }, - } satisfies PartialSdJwtKbJwt; + const wVCs = verifiableCredential.map((vc) => CredentialMapper.toWrappedVerifiableCredential(vc, { hasher: this.options?.hasher })); + const holders = Array.from(new Set(wVCs.flatMap((wvc) => getSubjectIdsAsString(wvc.credential as ICredential)))); + 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 sdJwtDecodedPresentation: PartialSdJwtDecodedVerifiableCredential = { - ...decoded, - kbJwt, - }; - return sdJwtDecodedPresentation; - } else { - 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 as ICredential)))); - 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'] + : [opts.basePresentationPayload['@context']] + : []; + if (!context.includes('https://www.w3.org/2018/credentials/v1')) { + context.push('https://www.w3.org/2018/credentials/v1'); + } - const context = opts?.basePresentationPayload?.['@context'] - ? Array.isArray(opts.basePresentationPayload['@context']) - ? opts.basePresentationPayload['@context'] - : [opts.basePresentationPayload['@context']] - : []; - if (!context.includes('https://www.w3.org/2018/credentials/v1')) { - context.push('https://www.w3.org/2018/credentials/v1'); + if (opts?.presentationSubmission) { + if (!type.includes('PresentationSubmission')) { + type.push('PresentationSubmission'); } - - if (opts?.presentationSubmission) { - if (!type.includes('PresentationSubmission')) { - type.push('PresentationSubmission'); - } - if (!context.includes('https://identity.foundation/presentation-exchange/submission/v1')) { - context.push('https://identity.foundation/presentation-exchange/submission/v1'); - } + if (!context.includes('https://identity.foundation/presentation-exchange/submission/v1')) { + context.push('https://identity.foundation/presentation-exchange/submission/v1'); } - return { + } + const result: Array = []; + if (PEX.allowMultipleVCsPerPresentation(verifiableCredential)) { + result.push({ ...opts?.basePresentationPayload, '@context': context, type, holder, ...(!!opts?.presentationSubmission && { presentation_submission: opts.presentationSubmission }), verifiableCredential, - }; + }); + } else { + verifiableCredential.forEach((vc) => { + if (CredentialMapper.isSdJwtDecodedCredential(vc)) { + result.push(vc as PartialSdJwtDecodedVerifiableCredential); + } else if (CredentialMapper.isSdJwtEncoded(vc)) { + const decoded = CredentialMapper.decodeVerifiableCredential(vc, opts?.hasher); + result.push(decoded as PartialSdJwtDecodedVerifiableCredential); + } else { + // This should be plain jwt only + result.push({ + ...opts?.basePresentationPayload, + '@context': context, + type, + holder, + ...(!!opts?.presentationSubmission && { presentation_submission: opts.presentationSubmission }), + verifiableCredential: [vc], + }); + } + }); } + return result; + } + + private static allowMultipleVCsPerPresentation(verifiableCredential: Array) { + return !verifiableCredential.some( + (c) => CredentialMapper.isJwtEncoded(c) || CredentialMapper.isSdJwtEncoded(c) || CredentialMapper.isSdJwtDecodedCredential(c), + ); } /** @@ -504,7 +485,8 @@ export class PEX { }); const presentationResult = this.presentationFrom(presentationDefinition, evaluationResult.verifiableCredential, opts); - const evaluationResults = this.evaluatePresentation(presentationDefinition, presentationResult.presentation, { + const presentations = presentationResult.presentations; + const evaluationResults = this.evaluatePresentation(presentationDefinition, presentations, { limitDisclosureSignatureSuites, ...(presentationResult.presentationSubmissionLocation === PresentationSubmissionLocation.EXTERNAL && { presentationSubmission: presentationResult.presentationSubmission, @@ -529,59 +511,68 @@ export class PEX { domain: proofOptions?.domain, }; - let presentation = presentationResult.presentation; + this.updateSdJwtCredentials(presentations, proofOptions?.nonce); - // Select type without kbJwt as isSdJwtDecodedCredential and won't accept the partial sdvc type - if (CredentialMapper.isSdJwtDecodedCredential(presentationResult.presentation as SdJwtDecodedVerifiableCredential)) { - const sdJwtPresentation = presentation as SdJwtDecodedVerifiableCredential; - if (!this.options?.hasher) { - throw new Error('Hasher must be provided when creating a presentation with an SD-JWT VC'); - } - - // extract sd_alg or default to sha-256 - const hashAlg = presentationResult.presentation.signedPayload._sd_alg ?? 'sha-256'; - const sdHash = calculateSdHash(presentationResult.presentation.compactSdJwtVc, hashAlg, this.options.hasher); - - const kbJwt = { - // alg MUST be set by the signer - header: { - typ: 'kb+jwt', - }, - // aud MUST be set by the signer or provided by e.g. SIOP/OpenID4VP lib - payload: { - iat: Math.floor(new Date().getTime() / 1000), - nonce: proofOptions?.nonce, - sd_hash: sdHash, + const verifiablePresentations: Array = []; + for (const presentation of presentations) { + const callBackParams: PresentationSignCallBackParams = { + options: { + ...opts, + presentationSubmissionLocation: presentationResult.presentationSubmissionLocation, }, - } satisfies PartialSdJwtKbJwt; - - presentation = { - ...sdJwtPresentation, - kbJwt, - } satisfies PartialSdJwtDecodedVerifiableCredential; + presentation, + presentationDefinition, + selectedCredentials, + proof, + presentationSubmission: evaluationResults.value, + evaluationResults, + }; + verifiablePresentations.push(await signingCallBack(callBackParams)); } - - const callBackParams: PresentationSignCallBackParams = { - options: { - ...opts, - presentationSubmissionLocation: presentationResult.presentationSubmissionLocation, - }, - presentation, - presentationDefinition, - selectedCredentials, - proof, - presentationSubmission: evaluationResults.value, - evaluationResults, - }; - const verifiablePresentation = await signingCallBack(callBackParams); - return { - verifiablePresentation, + verifiablePresentations, presentationSubmissionLocation: presentationResult.presentationSubmissionLocation, presentationSubmission: evaluationResults.value, }; } + private updateSdJwtCredentials( + presentations: Array, + nonce?: string, + ) { + presentations.forEach((presentation, index) => { + // Select type without kbJwt as isSdJwtDecodedCredential and won't accept the partial sdvc type + if (CredentialMapper.isSdJwtDecodedCredential(presentation as SdJwtDecodedVerifiableCredential)) { + const sdJwtCredential = presentation as SdJwtDecodedVerifiableCredential; + if (!this.options?.hasher) { + throw new Error('Hasher must be provided when creating a presentation with an SD-JWT VC'); + } + + // extract sd_alg or default to sha-256 + const hashAlg = sdJwtCredential.signedPayload._sd_alg ?? 'sha-256'; + const sdHash = calculateSdHash(sdJwtCredential.compactSdJwtVc, hashAlg, this.options.hasher); + + const kbJwt = { + // alg MUST be set by the signer + header: { + typ: 'kb+jwt', + }, + // aud MUST be set by the signer or provided by e.g. SIOP/OpenID4VP lib + payload: { + iat: Math.floor(new Date().getTime() / 1000), + nonce: nonce, + sd_hash: sdHash, + }, + } satisfies PartialSdJwtKbJwt; + + presentations[index] = { + ...sdJwtCredential, + kbJwt, + } satisfies PartialSdJwtDecodedVerifiableCredential; + } + }); + } + public static definitionVersionDiscovery(presentationDefinition: IPresentationDefinition): DiscoveredVersion { return definitionVersionDiscovery(presentationDefinition); } diff --git a/lib/PEXv1.ts b/lib/PEXv1.ts index 6853eb8c..5969b45f 100644 --- a/lib/PEXv1.ts +++ b/lib/PEXv1.ts @@ -124,13 +124,13 @@ export class PEXv1 extends PEX { opts?.presentationSubmissionLocation ?? (hasSdJwtCredentials ? PresentationSubmissionLocation.EXTERNAL : PresentationSubmissionLocation.PRESENTATION); - const presentation = PEX.constructPresentation(selectedCredentials, { + const presentation = this.constructPresentations(selectedCredentials, { ...opts, presentationSubmission: presentationSubmissionLocation === PresentationSubmissionLocation.PRESENTATION ? presentationSubmission : undefined, }); return { - presentation, + presentations: presentation, presentationSubmissionLocation, presentationSubmission, }; diff --git a/lib/PEXv2.ts b/lib/PEXv2.ts index 03e9d45b..78cd2302 100644 --- a/lib/PEXv2.ts +++ b/lib/PEXv2.ts @@ -120,13 +120,13 @@ export class PEXv2 extends PEX { opts?.presentationSubmissionLocation ?? (hasSdJwtCredentials ? PresentationSubmissionLocation.EXTERNAL : PresentationSubmissionLocation.PRESENTATION); - const presentation = PEX.constructPresentation(selectedCredentials, { + const presentation = this.constructPresentations(selectedCredentials, { ...opts, presentationSubmission: presentationSubmissionLocation === PresentationSubmissionLocation.PRESENTATION ? presentationSubmission : undefined, }); return { - presentation, + presentations: presentation, presentationSubmissionLocation, presentationSubmission, }; diff --git a/lib/evaluation/core/evaluationResults.ts b/lib/evaluation/core/evaluationResults.ts index 43b84a6d..d4961eda 100644 --- a/lib/evaluation/core/evaluationResults.ts +++ b/lib/evaluation/core/evaluationResults.ts @@ -5,7 +5,7 @@ import { Checked, Status } from '../../ConstraintUtils'; import { OrArray } from '../../types'; export interface PresentationEvaluationResults extends Omit { - presentation: OrArray; + presentations: OrArray; } export interface EvaluationResults { diff --git a/lib/evaluation/evaluationClientWrapper.ts b/lib/evaluation/evaluationClientWrapper.ts index 01830876..2a5c82e3 100644 --- a/lib/evaluation/evaluationClientWrapper.ts +++ b/lib/evaluation/evaluationClientWrapper.ts @@ -411,7 +411,7 @@ export class EvaluationClientWrapper { const result: PresentationEvaluationResults = { areRequiredCredentialsPresent: Status.INFO, - presentation: Array.isArray(wvps) ? wvps.map((wvp) => wvp.original) : wvps.original, + presentations: Array.isArray(wvps) ? wvps.map((wvp) => wvp.original) : wvps.original, errors: [], warnings: [], }; @@ -552,7 +552,7 @@ export class EvaluationClientWrapper { ): PresentationEvaluationResults { const result: PresentationEvaluationResults = { areRequiredCredentialsPresent: Status.INFO, - presentation: Array.isArray(wvps) ? wvps.map((wvp) => wvp.original) : wvps.original, + presentations: Array.isArray(wvps) ? wvps.map((wvp) => wvp.original) : wvps.original, errors: [], warnings: [], value: submission, @@ -874,7 +874,7 @@ export class EvaluationClientWrapper { presentationSubmissionLocation?: PresentationSubmissionLocation; }, ): PresentationSubmission { - if (!this._client.results) { + if (!this._client.results || this._client.results.length === 0) { throw Error('You need to call evaluate() before pex.presentationFrom()'); } if (!this._client.generatePresentationSubmission) { @@ -1232,7 +1232,7 @@ export class EvaluationClientWrapper { // See https://github.com/decentralized-identity/presentation-exchange/issues/462 // Also see: https://github.com/openid/OpenID4VP/issues/69 if (d.format === 'vc+sd-jwt') { - d.path = '$'; + //d.path = '$'; we do return multiple presentations now } else { this.replacePathWithAlias(d, 'verifiableCredential'); } diff --git a/lib/signing/types.ts b/lib/signing/types.ts index b77ccdd3..e46c4c6b 100644 --- a/lib/signing/types.ts +++ b/lib/signing/types.ts @@ -100,7 +100,7 @@ export interface PresentationResult { /** * The resulting presentation, can have an embedded submission data depending on the location parameter */ - presentation: IPresentation | SdJwtDecodedVerifiableCredential | PartialSdJwtDecodedVerifiableCredential; + presentations: Array; /** * The resulting location of the presentation submission. @@ -122,7 +122,7 @@ export interface VerifiablePresentationResult { /** * The resulting VP, can have an embedded submission data depending on the location parameter */ - verifiablePresentation: W3CVerifiablePresentation | CompactSdJwtVc; + verifiablePresentations: Array; /** * The resulting location of the presentation submission. diff --git a/package.json b/package.json index a4903e57..48560145 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sphereon/pex", - "version": "5.0.0-unstable.11", + "version": "5.0.0-unstable.12", "description": "A Typescript implementation of the v1 and v2 DIF Presentation Exchange specification", "main": "dist/main/index.js", "module": "dist/module/index.js", diff --git a/test/PEX.spec.ts b/test/PEX.spec.ts index daa2d451..fc9070f0 100644 --- a/test/PEX.spec.ts +++ b/test/PEX.spec.ts @@ -208,7 +208,7 @@ describe('evaluate', () => { // Should correctly generate the presentation submission with nested values expect(evaluationResults).toEqual({ areRequiredCredentialsPresent: Status.INFO, - presentation: vps, + presentations: vps, errors: [], warnings: [], value: { @@ -325,7 +325,7 @@ describe('evaluate', () => { expect(evaluationResults).toEqual({ areRequiredCredentialsPresent: Status.INFO, - presentation: vps, + presentations: vps, errors: [], warnings: [], // Should return the same presentation submission if provided @@ -366,7 +366,7 @@ describe('evaluate', () => { expect(evaluationResults).toEqual({ areRequiredCredentialsPresent: Status.INFO, - presentation: vps, + presentations: vps, errors: [], warnings: [], // Should return the same presentation submission if provided @@ -510,7 +510,7 @@ describe('evaluate', () => { expect(evaluationResults).toEqual({ areRequiredCredentialsPresent: Status.ERROR, - presentation: vps, + presentations: vps, errors: [ { message: @@ -606,7 +606,7 @@ describe('evaluate', () => { expect(evaluationResults).toEqual({ areRequiredCredentialsPresent: Status.ERROR, - presentation: vps, + presentations: vps, errors: [ { message: 'Expected all input descriptors (4) to be satisfifed in submission, but found 3. Missing ddc4a62f-73d4-4410-a3d7-b20720a113ed', @@ -684,7 +684,7 @@ describe('evaluate', () => { expect(evaluationResults).toEqual({ areRequiredCredentialsPresent: Status.ERROR, - presentation: vps, + presentations: vps, errors: [ { message: 'Expected all submission requirements (1) to be satisfifed in submission, but found 0.', @@ -742,7 +742,7 @@ describe('evaluate', () => { limitDisclosureSignatureSuites: LIMIT_DISCLOSURE_SIGNATURE_SUITES, }); const result = pex.presentationFrom(pdSchema, vpSimple.verifiableCredential!, { holderDID: HOLDER_DID }); - const presentation = result.presentation as IPresentation; + const presentation = result.presentations[0] as IPresentation; expect(presentation.presentation_submission).toEqual( expect.objectContaining({ definition_id: '32f54163-7166-48f1-93d8-ff217bdb0653', @@ -827,7 +827,7 @@ describe('evaluate', () => { holderDID: 'did:ethr:0x8D0E24509b79AfaB3A74Be1700ebF9769796B489', }, ); - const vp = vpr.verifiablePresentation as IVerifiablePresentation; + const vp = vpr.verifiablePresentations[0] as IVerifiablePresentation; const proof = Array.isArray(vp.proof) ? vp.proof[0] : vp.proof; expect(proof.created).toEqual('2021-12-01T20:10:45.000Z'); expect(proof.proofValue).toEqual('fake'); @@ -844,7 +844,7 @@ describe('evaluate', () => { signatureOptions: getSingatureOptionsMock(), holderDID: 'did:ethr:0x8D0E24509b79AfaB3A74Be1700ebF9769796B489', }); - const vp = vpr.verifiablePresentation as IVerifiablePresentation; + const vp = vpr.verifiablePresentations[0] as IVerifiablePresentation; const proof = Array.isArray(vp.proof) ? vp.proof[0] : vp.proof; expect(proof.created).toEqual('2021-12-01T20:10:45.000Z'); expect(proof.proofValue).toEqual('fake'); @@ -1052,7 +1052,7 @@ describe('evaluate', () => { }); }); - it('when array of presentations is passed, submission is always constructed as external', function () { + it('when array > 1 of presentations is passed, submission is always constructed as external', function () { const pdSchema: PresentationDefinitionV2 = { id: '49768857', input_descriptors: [ @@ -1076,7 +1076,7 @@ describe('evaluate', () => { }; const pex: PEX = new PEX(); const jwtEncodedVp = getFile('./test/dif_pe_examples/vp/vp_permanentResidentCard.jwt'); - const evalResult: PresentationEvaluationResults = pex.evaluatePresentation(pdSchema, [jwtEncodedVp]); + const evalResult: PresentationEvaluationResults = pex.evaluatePresentation(pdSchema, [jwtEncodedVp, jwtEncodedVp]); expect(evalResult.errors).toEqual([]); expect(evalResult.value?.descriptor_map[0]).toEqual({ id: 'prc_type', @@ -1225,7 +1225,7 @@ describe('evaluate', () => { proofOptions: getProofOptionsMock(), signatureOptions: getSingatureOptionsMock(), }); - const vp = vpr.verifiablePresentation as IVerifiablePresentation; + const vp = vpr.verifiablePresentations[0] as IVerifiablePresentation; expect(vp.verifiableCredential?.length).toEqual(1); expect(vp.presentation_submission?.descriptor_map).toEqual([ { diff --git a/test/PEXv1.spec.ts b/test/PEXv1.spec.ts index 75e971bd..b6f45e4a 100644 --- a/test/PEXv1.spec.ts +++ b/test/PEXv1.spec.ts @@ -72,7 +72,7 @@ describe('evaluate', () => { limitDisclosureSignatureSuites: LIMIT_DISCLOSURE_SIGNATURE_SUITES, }); const result = pex.presentationFrom(pdSchema, vpSimple.verifiableCredential!, { holderDID: HOLDER_DID }); - const presentation = result.presentation as IPresentation; + const presentation = result.presentations[0] as IPresentation; expect(presentation.presentation_submission).toEqual( expect.objectContaining({ definition_id: '32f54163-7166-48f1-93d8-ff217bdb0653', @@ -120,7 +120,7 @@ describe('evaluate', () => { signatureOptions: getSingatureOptionsMock(), holderDID: 'did:ethr:0x8D0E24509b79AfaB3A74Be1700ebF9769796B489', }); - const vp = vpr.verifiablePresentation as IVerifiablePresentation; + const vp = vpr.verifiablePresentations[0] as IVerifiablePresentation; const proof = Array.isArray(vp.proof) ? vp.proof[0] : vp.proof; expect(proof.created).toEqual('2021-12-01T20:10:45.000Z'); expect(proof.proofValue).toEqual('fake'); diff --git a/test/PEXv2.spec.ts b/test/PEXv2.spec.ts index 3c384559..edf31ef0 100644 --- a/test/PEXv2.spec.ts +++ b/test/PEXv2.spec.ts @@ -278,7 +278,7 @@ describe('evaluate', () => { signatureOptions: getSingatureOptionsMock(), holderDID: 'did:ethr:0x8D0E24509b79AfaB3A74Be1700ebF9769796B489', }); - const vp = vpr.verifiablePresentation as IVerifiablePresentation; + const vp = vpr.verifiablePresentations[0] as IVerifiablePresentation; const proof = Array.isArray(vp.proof) ? vp.proof[0] : vp.proof; expect(proof.created).toEqual('2021-12-01T20:10:45.000Z'); expect(proof.proofValue).toEqual('fake'); @@ -651,7 +651,7 @@ describe('evaluate', () => { }); expect(vpr.presentationSubmission.descriptor_map).toHaveLength(1); expect(vpr.presentationSubmission.descriptor_map[0].format).toEqual('di_vc'); - const vp = vpr.verifiablePresentation as IVerifiablePresentation; + const vp = vpr.verifiablePresentations[0] as IVerifiablePresentation; const proof = Array.isArray(vp.proof) ? vp.proof[0] : vp.proof; expect(proof.created).toEqual('2021-12-01T20:10:45.000Z'); expect(proof.proofValue).toEqual('fake'); diff --git a/test/SdJwt.spec.ts b/test/SdJwt.spec.ts index 7cc00d46..bf5b4d3d 100644 --- a/test/SdJwt.spec.ts +++ b/test/SdJwt.spec.ts @@ -223,7 +223,7 @@ describe('evaluate', () => { { format: 'vc+sd-jwt', id: 'wa_driver_license', - path: '$', + path: '$[0]', }, ], id: expect.any(String), @@ -231,7 +231,7 @@ describe('evaluate', () => { // Must be external for SD-JWT expect(presentationResult.presentationSubmissionLocation).toEqual(PresentationSubmissionLocation.EXTERNAL); - expect(presentationResult.presentation).toEqual({ + expect(presentationResult.presentations[0]).toEqual({ ...decodedSdJwtVcWithDisclosuresRemoved, kbJwt: { header: { @@ -255,22 +255,22 @@ describe('evaluate', () => { presentationDefinition, selectResults.verifiableCredential!, async (options) => { - const presentation = options.presentation as SdJwtDecodedVerifiableCredential; + const sdJwtCredential = options.presentation as SdJwtDecodedVerifiableCredential; kbJwt = `${Buffer.from( JSON.stringify({ - ...presentation.kbJwt?.header, + ...sdJwtCredential.kbJwt?.header, alg: 'EdDSA', }), ).toString('base64url')}.${Buffer.from( JSON.stringify({ - ...presentation.kbJwt?.payload, + ...sdJwtCredential.kbJwt?.payload, nonce: 'nonce-from-request', // verifier identifier url (not clear yet in HAIP what this should be, but it MUST be present) aud: 'did:web:something', }), ).toString('base64url')}.signature`; - return `${presentation.compactSdJwtVc}${kbJwt}`; + return `${sdJwtCredential.compactSdJwtVc}${kbJwt}`; }, { presentationSubmissionLocation: PresentationSubmissionLocation.EXTERNAL, @@ -294,15 +294,15 @@ describe('evaluate', () => { // Must be external for SD-JWT expect(presentationResult.presentationSubmissionLocation).toEqual(PresentationSubmissionLocation.EXTERNAL); // Expect the KB-JWT to be appended - expect(presentationResult.verifiablePresentation).toEqual(decodedSdJwtVcWithDisclosuresRemoved.compactSdJwtVc + kbJwt); + expect(presentationResult.verifiablePresentations[0]).toEqual(decodedSdJwtVcWithDisclosuresRemoved.compactSdJwtVc + kbJwt); - const evaluateResults = pex.evaluatePresentation(presentationDefinition, presentationResult.verifiablePresentation, { + const evaluateResults = pex.evaluatePresentation(presentationDefinition, presentationResult.verifiablePresentations, { presentationSubmission: presentationResult.presentationSubmission, }); expect(evaluateResults).toEqual({ // Do we want to return the compact variant here? Or the decoded/pretty variant? - presentation: decodedSdJwtVcWithDisclosuresRemoved.compactSdJwtVc + kbJwt, + presentations: [decodedSdJwtVcWithDisclosuresRemoved.compactSdJwtVc + kbJwt], areRequiredCredentialsPresent: Status.INFO, warnings: [], errors: [], diff --git a/test/evaluation/check-scenario-1.spec.ts b/test/evaluation/check-scenario-1.spec.ts index fad513eb..01928b3d 100644 --- a/test/evaluation/check-scenario-1.spec.ts +++ b/test/evaluation/check-scenario-1.spec.ts @@ -244,7 +244,7 @@ describe('1st scenario', () => { which is wrong in the case of our example, because the index of our verifiableCredential is no longer #2, but it's "1" */ const presentationResult = pex.presentationFrom(pd, [holderWallet.verifiableCredentials[2]], { holderDID: 'did:didMethod:2021112400' }); - const presentation = presentationResult.presentation as IPresentation; + const presentation = presentationResult.presentations[0] as IPresentation; expect(presentation!.presentation_submission!.definition_id).toEqual('31e2f0f1-6b70-411d-b239-56aed5321884'); expect(presentation!.presentation_submission!.descriptor_map.map((dm) => dm.id).sort()).toEqual([ '867bfe7a-5b91-46b2-9ba4-70028b8d9cc8', diff --git a/test/evaluation/selectFrom.spec.ts b/test/evaluation/selectFrom.spec.ts index 8b124d00..d4462101 100644 --- a/test/evaluation/selectFrom.spec.ts +++ b/test/evaluation/selectFrom.spec.ts @@ -4,7 +4,7 @@ import fs from 'fs'; import { Rules } from '@sphereon/pex-models'; import { IVerifiableCredential, WrappedVerifiableCredential } from '@sphereon/ssi-types'; -import { Status } from '../../lib'; +import { PEX, Status } from '../../lib'; import { EvaluationClientWrapper } from '../../lib/evaluation'; import { SubmissionRequirementMatchType } from '../../lib/evaluation/core'; import { InternalPresentationDefinitionV1, InternalPresentationDefinitionV2, SSITypesBuilder } from '../../lib/types'; @@ -24,6 +24,10 @@ const dids = ['did:example:ebfeb1f712ebc6f1c276e12ec21']; const LIMIT_DISCLOSURE_SIGNATURE_SUITES = ['BbsBlsSignatureProof2020']; +const pex = new PEX({ + hasher, +}); + describe('selectFrom tests', () => { it('Evaluate submission requirements all from group A', () => { const pdSchema: InternalPresentationDefinitionV1 = getFileAsJson('./test/resources/sr_rules.json').presentation_definition; @@ -1019,7 +1023,10 @@ describe('selectFrom tests', () => { holderDIDs: ['FAsYneKJhWBP2n5E21ZzdY'], limitDisclosureSignatureSuites: LIMIT_DISCLOSURE_SIGNATURE_SUITES, }); - // TODO expects expect(result.areRequiredCredentialsPresent).toBe(Status.INFO); + + pex.evaluateCredentials(pd, result.verifiableCredential!); + const presentationResult = pex.presentationFrom(pd, result.verifiableCredential!); + expect(presentationResult).toBeDefined(); }); }); diff --git a/test/thirdParty/Gataca.spec.ts b/test/thirdParty/Gataca.spec.ts index 1e72d86d..aa431b9f 100644 --- a/test/thirdParty/Gataca.spec.ts +++ b/test/thirdParty/Gataca.spec.ts @@ -60,7 +60,7 @@ describe('evaluate gataca tests', () => { selectFromResult.verifiableCredential as IVerifiableCredential[], undefined, ); - const presentation = presentationFromResult.presentation as IPresentation; + const presentation = presentationFromResult.presentations[0] as IPresentation; expect(presentation.presentation_submission?.descriptor_map).toEqual([ { format: 'ldp_vc', @@ -136,7 +136,7 @@ describe('evaluate gataca tests', () => { selectFromResult.verifiableCredential as IVerifiableCredential[], undefined, ); - const presentation = presentationFromResult.presentation as IPresentation; + const presentation = presentationFromResult.presentations[0] as IPresentation; expect(presentation.presentation_submission?.descriptor_map).toEqual([ { format: 'ldp_vc', diff --git a/test/thirdParty/JGiter.spec.ts b/test/thirdParty/JGiter.spec.ts index db7cb210..c21cf142 100644 --- a/test/thirdParty/JGiter.spec.ts +++ b/test/thirdParty/JGiter.spec.ts @@ -504,7 +504,7 @@ describe('evaluate JGiter tests', () => { expect(selectFrom.matches![1]?.from).toEqual('B'); expect(selectFrom.matches![1]?.vc_path).toEqual(['$.verifiableCredential[1]']); const presentationResult = pex.presentationFrom(pdSchema, selectFrom.verifiableCredential as IVerifiableCredential[]); - const presentation = presentationResult.presentation as IPresentation; + const presentation = presentationResult.presentations[0] as IPresentation; expect(presentation.presentation_submission?.descriptor_map).toEqual([ { id: 'identity_input', @@ -544,7 +544,7 @@ describe('evaluate JGiter tests', () => { expect(resultEvaluation.errors?.length).toEqual(0); expect(resultEvaluation.areRequiredCredentialsPresent).toEqual(Status.INFO); const presentationResult = pex.presentationFrom(pdSchema, [resultEvaluation.verifiableCredential[0]]); - const presentation = presentationResult.presentation as IPresentation; + const presentation = presentationResult.presentations[0] as IPresentation; expect(presentation.presentation_submission?.descriptor_map).toEqual([ { id: 'identity_input', From f634b51f06dfe592155bb73a0dc9315dd3e8d7e7 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Wed, 2 Oct 2024 22:25:26 +0200 Subject: [PATCH 26/47] chore: multi-vp fixes --- lib/PEXv2.ts | 2 +- lib/evaluation/core/evaluationResults.ts | 3 +-- lib/evaluation/evaluationClientWrapper.ts | 4 ++-- package.json | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/PEXv2.ts b/lib/PEXv2.ts index 78cd2302..126e9114 100644 --- a/lib/PEXv2.ts +++ b/lib/PEXv2.ts @@ -15,7 +15,7 @@ export class PEXv2 extends PEX { * The evaluatePresentationV2 compares what is expected from a presentation with a presentationDefinitionV2. * * @param presentationDefinition the definition of what is expected in the presentation. - * @param presentation the presentation which has to be evaluated in comparison of the definition. + * @param presentations the presentation which has to be evaluated in comparison of the definition. * @param opts - limitDisclosureSignatureSuites the credential signature suites that support limit disclosure * * @return the evaluation results specify what was expected and was fulfilled and also specifies which requirements described in the input descriptors diff --git a/lib/evaluation/core/evaluationResults.ts b/lib/evaluation/core/evaluationResults.ts index d4961eda..95928bf6 100644 --- a/lib/evaluation/core/evaluationResults.ts +++ b/lib/evaluation/core/evaluationResults.ts @@ -2,10 +2,9 @@ import { PresentationSubmission } from '@sphereon/pex-models'; import { IPresentation, IVerifiableCredential, OriginalVerifiablePresentation, SdJwtDecodedVerifiableCredential } from '@sphereon/ssi-types'; import { Checked, Status } from '../../ConstraintUtils'; -import { OrArray } from '../../types'; export interface PresentationEvaluationResults extends Omit { - presentations: OrArray; + presentations: Array; } export interface EvaluationResults { diff --git a/lib/evaluation/evaluationClientWrapper.ts b/lib/evaluation/evaluationClientWrapper.ts index 2a5c82e3..66c5dbac 100644 --- a/lib/evaluation/evaluationClientWrapper.ts +++ b/lib/evaluation/evaluationClientWrapper.ts @@ -411,7 +411,7 @@ export class EvaluationClientWrapper { const result: PresentationEvaluationResults = { areRequiredCredentialsPresent: Status.INFO, - presentations: Array.isArray(wvps) ? wvps.map((wvp) => wvp.original) : wvps.original, + presentations: Array.isArray(wvps) ? wvps.map((wvp) => wvp.original) : [wvps.original], errors: [], warnings: [], }; @@ -552,7 +552,7 @@ export class EvaluationClientWrapper { ): PresentationEvaluationResults { const result: PresentationEvaluationResults = { areRequiredCredentialsPresent: Status.INFO, - presentations: Array.isArray(wvps) ? wvps.map((wvp) => wvp.original) : wvps.original, + presentations: Array.isArray(wvps) ? wvps.map((wvp) => wvp.original) : [wvps.original], errors: [], warnings: [], value: submission, diff --git a/package.json b/package.json index 48560145..f01a022f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sphereon/pex", - "version": "5.0.0-unstable.12", + "version": "5.0.0-unstable.13", "description": "A Typescript implementation of the v1 and v2 DIF Presentation Exchange specification", "main": "dist/main/index.js", "module": "dist/module/index.js", From 7a5f71c5dba75cca9cc554c3ee3a5db6a64efb47 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Thu, 3 Oct 2024 00:59:59 +0200 Subject: [PATCH 27/47] chore: multi-vp fixes --- lib/evaluation/evaluationClientWrapper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/evaluation/evaluationClientWrapper.ts b/lib/evaluation/evaluationClientWrapper.ts index 66c5dbac..4630d9ac 100644 --- a/lib/evaluation/evaluationClientWrapper.ts +++ b/lib/evaluation/evaluationClientWrapper.ts @@ -940,7 +940,7 @@ export class EvaluationClientWrapper { private updatePresentationSubmissionToExternal(presentationSubmission?: PresentationSubmission): PresentationSubmission { const descriptors = presentationSubmission?.descriptor_map ?? this._client.presentationSubmission.descriptor_map; - const updatedDescriptors = descriptors.map((d) => this.updateDescriptorToExternal(d)); + const updatedDescriptors = descriptors.map((d,index) => this.updateDescriptorToExternal(d,{vpIndex: index})); if (presentationSubmission) { return { From 546e01c6859f69afc212ecfdacdd0e1aa4168437 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Thu, 3 Oct 2024 01:05:43 +0200 Subject: [PATCH 28/47] chore: multi-vp fixes --- lib/evaluation/evaluationClientWrapper.ts | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/evaluation/evaluationClientWrapper.ts b/lib/evaluation/evaluationClientWrapper.ts index 4630d9ac..0e1f4a5f 100644 --- a/lib/evaluation/evaluationClientWrapper.ts +++ b/lib/evaluation/evaluationClientWrapper.ts @@ -940,7 +940,7 @@ export class EvaluationClientWrapper { private updatePresentationSubmissionToExternal(presentationSubmission?: PresentationSubmission): PresentationSubmission { const descriptors = presentationSubmission?.descriptor_map ?? this._client.presentationSubmission.descriptor_map; - const updatedDescriptors = descriptors.map((d,index) => this.updateDescriptorToExternal(d,{vpIndex: index})); + const updatedDescriptors = descriptors.map((d, index) => this.updateDescriptorToExternal(d, { vpIndex: index })); if (presentationSubmission) { return { diff --git a/package.json b/package.json index f01a022f..2cd095ba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sphereon/pex", - "version": "5.0.0-unstable.13", + "version": "5.0.0-unstable.14", "description": "A Typescript implementation of the v1 and v2 DIF Presentation Exchange specification", "main": "dist/main/index.js", "module": "dist/module/index.js", From f0c86f4e7ed58e75ccb20425b814e7726b4836aa Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Thu, 3 Oct 2024 10:18:48 +0200 Subject: [PATCH 29/47] chore: multi-vp fixes --- test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json b/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json index a819e48d..df9ed3d4 100644 --- a/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json +++ b/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json @@ -28,6 +28,7 @@ } }, "constraints": { + "limit_disclosure": "required", "fields": [ { "path": [ @@ -67,6 +68,7 @@ } }, "constraints": { + "limit_disclosure": "required", "fields": [ { "path": [ From 6fafdb7224c4e3d06cc4c83e34210ed7b9186fe8 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Mon, 7 Oct 2024 09:39:44 +0200 Subject: [PATCH 30/47] chore: iata test fixes --- package.json | 1 + pnpm-lock.yaml | 245 ++---------------- .../pdV2/pd-multi-sd-jwt-vp.json | 5 +- .../vc/vc-iata-epassport-sd.jwt | 2 +- test/dif_pe_examples/vc/vc-iata-order-sd.jwt | 2 +- test/evaluation/selectFrom.spec.ts | 7 +- 6 files changed, 28 insertions(+), 234 deletions(-) diff --git a/package.json b/package.json index 2cd095ba..6ea27e3e 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "@types/node": "^18.19.26", "@typescript-eslint/eslint-plugin": "^7.3.1", "@typescript-eslint/parser": "^7.3.1", + "@sd-jwt/core": "^0.7.2", "ajv-cli": "^5.0.0", "codecov": "^3.8.3", "eslint": "^8.57.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a7052f92..8fc8ab31 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -43,6 +43,9 @@ dependencies: version: 3.1.1 devDependencies: + '@sd-jwt/core': + specifier: ^0.7.2 + version: 0.7.2 '@types/jest': specifier: ^29.5.12 version: 29.5.12 @@ -953,6 +956,16 @@ packages: resolution: {integrity: sha512-6CyAclxj3Nb0XT7GHK6K4zK6k2xJm6E4Ft0Ohjt4WgegiFUHEtFb2CGzmPmGBwoIhrLsqNLYfLr04Y1GePrzZg==} dev: false + /@sd-jwt/core@0.7.2: + resolution: {integrity: sha512-vix1GplUFc1A9H42r/yXkg7cKYthggyqZEwlFdsBbn4xdZNE+AHVF4N7kPa1pPxipwN3UIHd4XnQ5MJV15mhsQ==} + engines: {node: '>=18'} + dependencies: + '@sd-jwt/decode': 0.7.2 + '@sd-jwt/present': 0.7.2 + '@sd-jwt/types': 0.7.2 + '@sd-jwt/utils': 0.7.2 + dev: true + /@sd-jwt/decode@0.6.1: resolution: {integrity: sha512-QgTIoYd5zyKKLgXB4xEYJTrvumVwtsj5Dog0v0L9UH9ZvHekDaeexS247X7A4iSdzTvmZzUpGskgABOa4D8NmQ==} engines: {node: '>=16'} @@ -967,7 +980,6 @@ packages: dependencies: '@sd-jwt/types': 0.7.2 '@sd-jwt/utils': 0.7.2 - dev: false /@sd-jwt/present@0.7.2: resolution: {integrity: sha512-mQV85u2+mLLy2VZ9Wx2zpaB6yTDnbhCfWkP7eeCrzJQHBKAAHko8GrylEFmLKewFIcajS/r4lT/zHOsCkp5pZw==} @@ -976,7 +988,6 @@ packages: '@sd-jwt/decode': 0.7.2 '@sd-jwt/types': 0.7.2 '@sd-jwt/utils': 0.7.2 - dev: false /@sd-jwt/types@0.6.1: resolution: {integrity: sha512-LKpABZJGT77jNhOLvAHIkNNmGqXzyfwBT+6r+DN9zNzMx1CzuNR0qXk1GMUbast9iCfPkGbnEpUv/jHTBvlIvg==} @@ -986,7 +997,6 @@ packages: /@sd-jwt/types@0.7.2: resolution: {integrity: sha512-1NRKowiW0ZiB9SGLApLPBH4Xk8gDQJ+nA9NdZ+uy6MmJKLEwjuJxO7yTvRIv/jX/0/Ebh339S7Kq4RD2AiFuRg==} engines: {node: '>=18'} - dev: false /@sd-jwt/utils@0.6.1: resolution: {integrity: sha512-1NHZ//+GecGQJb+gSdDicnrHG0DvACUk9jTnXA5yLZhlRjgkjyfJLNsCZesYeCyVp/SiyvIC9B+JwoY4kI0TwQ==} @@ -1002,7 +1012,6 @@ packages: dependencies: '@sd-jwt/types': 0.7.2 js-base64: 3.7.7 - dev: false /@sinclair/typebox@0.27.8: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} @@ -1036,51 +1045,12 @@ packages: '@js-joda/timezone': 2.3.0(@js-joda/core@5.6.3) format-util: 1.0.5 dev: false + bundledDependencies: [] /@sphereon/pex-models@2.3.1: resolution: {integrity: sha512-SByU4cJ0XYA6VZQ/L6lsSiRcFtBPHbFioCeQ4GP7/W/jQ+PSBD7uK2oTnKQ9/0iEiMK/6JYqhKgLs4a9UX3UTQ==} dev: false - /@sphereon/ssi-sdk-ext.did-utils@0.24.1-unstable.124(ts-node@10.9.2): - resolution: {integrity: sha512-LA6xwRL21dfiAnzqCxWXp5Ew+YWOXZXNgDK01ti3q06aRLJCxUAvydEHPy0DAtGMOI2fQwe7+UJXWkx0dVFQNw==} - dependencies: - '@ethersproject/networks': 5.7.1 - '@ethersproject/transactions': 5.7.0 - '@sphereon/did-uni-client': 0.6.3 - '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-unstable.124 - '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.124 - '@sphereon/ssi-sdk.agent-config': 0.29.1-unstable.161(ts-node@10.9.2) - '@sphereon/ssi-sdk.core': 0.29.1-unstable.161 - '@sphereon/ssi-types': 0.29.1-unstable.161 - '@stablelib/ed25519': 1.0.3 - '@veramo/core': 4.2.0 - '@veramo/utils': 4.2.0 - did-jwt: 6.11.6 - did-resolver: 4.1.0 - elliptic: 6.5.7 - uint8arrays: 3.1.1 - transitivePeerDependencies: - - '@google-cloud/spanner' - - '@sap/hana-client' - - better-sqlite3 - - encoding - - hdb-pool - - ioredis - - mongodb - - mssql - - mysql2 - - oracledb - - pg - - pg-native - - pg-query-stream - - redis - - sql.js - - sqlite3 - - supports-color - - ts-node - - typeorm-aurora-data-api-driver - dev: false - /@sphereon/ssi-sdk-ext.did-utils@0.24.1-unstable.130(ts-node@10.9.2): resolution: {integrity: sha512-I+0VjitRjisABWm8RtTPQG57tFwfUS13Wud30OvBoADRxnaA0guUrkS82AYtV6YD0TBHdrd0D6a0RCJwK9SvDg==} dependencies: @@ -1090,8 +1060,8 @@ packages: '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-unstable.130 '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.130 '@sphereon/ssi-sdk.agent-config': 0.29.1-unstable.161(ts-node@10.9.2) - '@sphereon/ssi-sdk.core': 0.30.1-unstable.5(ts-node@10.9.2) - '@sphereon/ssi-types': 0.30.1-unstable.5(ts-node@10.9.2) + '@sphereon/ssi-sdk.core': 0.29.1-unstable.161 + '@sphereon/ssi-types': 0.29.1-unstable.161 '@stablelib/ed25519': 1.0.3 '@veramo/core': 4.2.0 '@veramo/utils': 4.2.0 @@ -1121,41 +1091,6 @@ packages: - typeorm-aurora-data-api-driver dev: false - /@sphereon/ssi-sdk-ext.identifier-resolution@0.24.1-unstable.124(ts-node@10.9.2): - resolution: {integrity: sha512-PXutE4aYBcZI0BtCsWoUvv7hSRoBkeMqYOcvhERtLFqCCempRKN+Ue6P1JMadRvMp3YBuc0C/xHzdeNN/KPaHw==} - dependencies: - '@sphereon/ssi-sdk-ext.did-utils': 0.24.1-unstable.124(ts-node@10.9.2) - '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-unstable.124 - '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.124 - '@sphereon/ssi-sdk.agent-config': 0.29.1-unstable.161(ts-node@10.9.2) - '@sphereon/ssi-types': 0.29.1-unstable.161 - '@veramo/core': 4.2.0 - '@veramo/utils': 4.2.0 - debug: 4.3.6 - pkijs: 3.2.4 - uint8arrays: 3.1.1 - transitivePeerDependencies: - - '@google-cloud/spanner' - - '@sap/hana-client' - - better-sqlite3 - - encoding - - hdb-pool - - ioredis - - mongodb - - mssql - - mysql2 - - oracledb - - pg - - pg-native - - pg-query-stream - - redis - - sql.js - - sqlite3 - - supports-color - - ts-node - - typeorm-aurora-data-api-driver - dev: false - /@sphereon/ssi-sdk-ext.identifier-resolution@0.24.1-unstable.130(ts-node@10.9.2): resolution: {integrity: sha512-9mY+qgXmbZCC8aic99R7B3vKBHBakDiC6Sktgd7Q9AknR8cCmvdrmTgnOETrLng9L43uNOJnNTMG/4T6LqmtsA==} dependencies: @@ -1191,43 +1126,6 @@ packages: - typeorm-aurora-data-api-driver dev: false - /@sphereon/ssi-sdk-ext.jwt-service@0.24.1-unstable.124(ts-node@10.9.2): - resolution: {integrity: sha512-U1feY1ZMZR/ETLdoW5dYH1X0JpL2Y6X+qzMSV2a8/O9hd16qNlOJ+T6uhXw1SqC/ihVHB7fE6VF+SvtziOgI/w==} - dependencies: - '@sphereon/ssi-sdk-ext.did-utils': 0.24.1-unstable.124(ts-node@10.9.2) - '@sphereon/ssi-sdk-ext.identifier-resolution': 0.24.1-unstable.124(ts-node@10.9.2) - '@sphereon/ssi-sdk-ext.key-manager': 0.24.1-unstable.124 - '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-unstable.124 - '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.124 - '@sphereon/ssi-sdk.agent-config': 0.29.1-unstable.161(ts-node@10.9.2) - '@sphereon/ssi-types': 0.29.1-unstable.161 - '@veramo/core': 4.2.0 - '@veramo/utils': 4.2.0 - debug: 4.3.6 - jwt-decode: 4.0.0 - uint8arrays: 3.1.1 - transitivePeerDependencies: - - '@google-cloud/spanner' - - '@sap/hana-client' - - better-sqlite3 - - encoding - - hdb-pool - - ioredis - - mongodb - - mssql - - mysql2 - - oracledb - - pg - - pg-native - - pg-query-stream - - redis - - sql.js - - sqlite3 - - supports-color - - ts-node - - typeorm-aurora-data-api-driver - dev: false - /@sphereon/ssi-sdk-ext.jwt-service@0.24.1-unstable.130(ts-node@10.9.2): resolution: {integrity: sha512-MHLGRmJODEYJyFoXKwlKMYzf48vS5JcUkGk0W4sqmrY1wwcw+ro3l8adIprG37mNuknXBs9Mv0x/tvibE9wwCQ==} dependencies: @@ -1237,7 +1135,7 @@ packages: '@sphereon/ssi-sdk-ext.key-utils': 0.24.1-unstable.130 '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.130 '@sphereon/ssi-sdk.agent-config': 0.29.1-unstable.161(ts-node@10.9.2) - '@sphereon/ssi-types': 0.30.1-unstable.5(ts-node@10.9.2) + '@sphereon/ssi-types': 0.29.1-unstable.161 '@veramo/core': 4.2.0 '@veramo/utils': 4.2.0 debug: 4.3.6 @@ -1265,16 +1163,6 @@ packages: - typeorm-aurora-data-api-driver dev: false - /@sphereon/ssi-sdk-ext.key-manager@0.24.1-unstable.124: - resolution: {integrity: sha512-5eURqsVPOKGXrA3hRiAyJ6bMhMQmFrVNPEy78zd8BhBZ+4OLxJw4Dwcd0vfG+sddH6tRNzKnxv24mzIo6cyl+Q==} - dependencies: - '@veramo/core': 4.2.0 - '@veramo/key-manager': 4.2.0 - uint8arrays: 3.1.1 - transitivePeerDependencies: - - supports-color - dev: false - /@sphereon/ssi-sdk-ext.key-manager@0.24.1-unstable.130: resolution: {integrity: sha512-O/6NlKmlYRnEyP/mAI2Diu0qptMSqZfVwqog8KAOG/G8JUmktfSQmclBW8RoJ6AD9uY65BGzNk1oAVuuMv4Dog==} dependencies: @@ -1285,30 +1173,6 @@ packages: - supports-color dev: false - /@sphereon/ssi-sdk-ext.key-utils@0.24.1-unstable.124: - resolution: {integrity: sha512-I5E4SzHwBOQviR8W5muCorAhzUWaX8XK5JXUdiMuJfVfF3UW3V4YriOr1Ar6HbNT2TxRWIaPdcLGrVEDZn0VGQ==} - dependencies: - '@ethersproject/random': 5.7.0 - '@sphereon/ssi-sdk-ext.x509-utils': 0.24.1-unstable.124 - '@sphereon/ssi-types': 0.29.1-unstable.161 - '@stablelib/ed25519': 1.0.3 - '@stablelib/sha256': 1.0.1 - '@stablelib/sha512': 1.0.1 - '@trust/keyto': 1.0.1 - '@veramo/core': 4.2.0 - base64url: 3.0.1 - debug: 4.3.6 - did-resolver: 4.1.0 - elliptic: 6.5.7 - lodash.isplainobject: 4.0.6 - multiformats: 9.9.0 - uint8arrays: 3.1.1 - varint: 6.0.0 - web-encoding: 1.1.5 - transitivePeerDependencies: - - supports-color - dev: false - /@sphereon/ssi-sdk-ext.key-utils@0.24.1-unstable.130: resolution: {integrity: sha512-DCyXW18g1OAuZ+aFHzQGrbZSx793DX94LSFnrWlOTMnYeILmrizuFksUlWSb3lTqQGAqWBC48NoR3I1H6lSMEQ==} dependencies: @@ -1333,18 +1197,6 @@ packages: - supports-color dev: false - /@sphereon/ssi-sdk-ext.x509-utils@0.24.1-unstable.124: - resolution: {integrity: sha512-JPY5xQ/7EttUHsXmK/kj5/tmpYunneE6/ctBk4P+gZGwpqRnLMdDX6cvnxYdwBbFyCpOI+lyDc3USsp52UupKg==} - dependencies: - '@trust/keyto': 1.0.1 - debug: 4.3.6 - js-x509-utils: 1.0.7 - pkijs: 3.2.4 - uint8arrays: 3.1.1 - transitivePeerDependencies: - - supports-color - dev: false - /@sphereon/ssi-sdk-ext.x509-utils@0.24.1-unstable.130: resolution: {integrity: sha512-JDX8i0WrwONaOivZXB+OxJQGkln7vuSLS61tOYl7M1RyPGixdBYuEuACsdvWf6egYOpaWmhmXZzaAOj18eDddw==} dependencies: @@ -1401,37 +1253,6 @@ packages: - supports-color dev: false - /@sphereon/ssi-sdk.core@0.30.1-unstable.5(ts-node@10.9.2): - resolution: {integrity: sha512-Ein4RLmPto1MYp65i7y31mQInsL5F6suFwYIpB5SPRWBy8WIMzKIuPWcH8vCyNYUdxa21c/X57MkhEssYhvWlg==} - dependencies: - '@sphereon/ssi-types': 0.30.1-unstable.5(ts-node@10.9.2) - '@veramo/core': 4.2.0 - cross-fetch: 3.1.8 - debug: 4.3.6 - image-size: 2.0.0-beta.2 - uint8arrays: 3.1.1 - transitivePeerDependencies: - - '@google-cloud/spanner' - - '@sap/hana-client' - - better-sqlite3 - - encoding - - hdb-pool - - ioredis - - mongodb - - mssql - - mysql2 - - oracledb - - pg - - pg-native - - pg-query-stream - - redis - - sql.js - - sqlite3 - - supports-color - - ts-node - - typeorm-aurora-data-api-driver - dev: false - /@sphereon/ssi-types@0.29.1-unstable.161: resolution: {integrity: sha512-ifMADjk6k0f97/isK/4Qw/PX6n4k+qS5k6mmmH47MTD3KMDddVghoXycsvNw7wObJdLUalHBX630ghr+u21oMg==} dependencies: @@ -1474,37 +1295,6 @@ packages: - typeorm-aurora-data-api-driver dev: false - /@sphereon/ssi-types@0.30.1-unstable.5(ts-node@10.9.2): - resolution: {integrity: sha512-z9MTLvOKpTJPP3UmhCIGXntWbZ0Uvrei6W72AXuZ0x3ko4w8p4gbSatECq6D2tHbucSvSzC+URpr8FtwP/fMPQ==} - dependencies: - '@sd-jwt/decode': 0.6.1 - '@sphereon/kmp-mdl-mdoc': 0.2.0-SNAPSHOT.22 - '@sphereon/ssi-sdk-ext.jwt-service': 0.24.1-unstable.124(ts-node@10.9.2) - debug: 4.3.6 - events: 3.3.0 - jwt-decode: 3.1.2 - transitivePeerDependencies: - - '@google-cloud/spanner' - - '@sap/hana-client' - - better-sqlite3 - - encoding - - hdb-pool - - ioredis - - mongodb - - mssql - - mysql2 - - oracledb - - pg - - pg-native - - pg-query-stream - - redis - - sql.js - - sqlite3 - - supports-color - - ts-node - - typeorm-aurora-data-api-driver - dev: false - /@sqltools/formatter@1.2.5: resolution: {integrity: sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==} dev: false @@ -4319,7 +4109,6 @@ packages: /js-base64@3.7.7: resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} - dev: false /js-crypto-aes@1.0.6: resolution: {integrity: sha512-E2hu9z5+YtpDg9Un/bDfmH+I5dv/8aN+ozxv9L0ybZldcQ9T5iYDbBKdlKGBUKI3IvzoWSBSdnZnhwZaRIN46w==} diff --git a/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json b/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json index df9ed3d4..93863921 100644 --- a/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json +++ b/test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json @@ -7,7 +7,6 @@ { "name": "Order and epass", "rule": "all", - "count": 2, "from": "A" } ], @@ -36,7 +35,7 @@ ], "filter": { "type": "string", - "pattern": "Order" + "pattern": "order_id_vc" } }, { @@ -76,7 +75,7 @@ ], "filter": { "type": "string", - "pattern": "ePassport" + "pattern": "epassport_copy_vc" } }, { diff --git a/test/dif_pe_examples/vc/vc-iata-epassport-sd.jwt b/test/dif_pe_examples/vc/vc-iata-epassport-sd.jwt index ace75c96..bc623aa6 100644 --- a/test/dif_pe_examples/vc/vc-iata-epassport-sd.jwt +++ b/test/dif_pe_examples/vc/vc-iata-epassport-sd.jwt @@ -1 +1 @@ -eyJ0eXAiOiJ2YytzZC1qd3QiLCJraWQiOiIwMmQxYzZkNjlkYWNiNDFlNjA4OTlhN2U4Y2RhMzlmMTJhMjY2NmZjOWMzNGM0MzdiMWY3NGY2MWNmNTBkOTVjNjAiLCJhbGciOiJFUzI1NiJ9.eyJ0eXBlIjoiZVBhc3Nwb3J0IiwidmN0IjoiZVBhc3Nwb3J0IiwiZWxlY3Ryb25pY1Bhc3Nwb3J0Ijp7ImRhdGFHcm91cDEiOnsiYmlydGhkYXRlIjoiMTk3My0xMi0xNSIsImRvY1R5cGVDb2RlIjoiUCIsImV4cGlyeURhdGUiOiIyMDI3LTA5LTA1VDA5OjIwOjA3Ljc1M1oiLCJzZXhDb2RlIjoiTSIsImhvbGRlcnNOYW1lIjoiVGVzdE5hbWUiLCJpc3N1ZXJDb2RlIjoiTkIiLCJuYXRsQ29kZSI6Ik5MIiwicGFzc3BvcnROdW1iZXJJZGVudGlmaWVyIjoiTkwzNjM3MjY3NDY3ODIifSwiZGF0YUdyb3VwMTUiOnsiYWN0aXZlQXV0aGVudGljYXRpb24iOnsicHVibGljS2V5QmluYXJ5T2JqZWN0IjoiY0hWaWJHbGpTMlY1UW1sdVlYSjVUMkpxWldOMGNIVmliR2xqUzJWNVFtbHVZWEo1VDJKcVpXTkdGRjBSZWZTYyJ9fSwiZGF0YUdyb3VwMkVuY29kZWRGYWNlQmlvbWV0cmljcyI6eyJmYWNlQmlvbWV0cmljRGF0YUVuY29kZWRQaWN0dXJlIjoiaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUswQUFBRGRDQVlBQUFESmpmS0NBQUFCaFdsRFExQkpRME1nY0hKdlptbHNaUUFBS0pGOWtUMUl3MEFZaHQrbWlqKzBPTmhCUkRCRGRiS0xpb2hUcVdJUkxKUzJRcXNPSnBmK1FaT0dKTVhGVVhBdE9QaXpXSFZ3Y2RiVndWVVFCSDlBbkIyY0ZGMmt4TytTUW9zWTd6anU0YjN2ZmJuN0RoQWFGYWFhWFZGQTFTd2pGWStKMmR5cTJQT0tQZ1Jwem1GVVlxYWVTQzltNERtKzd1SGorMTJFWjNuWC9UbUNTdDVrZ0U4a2pqTGRzSWczaUdjMkxaM3pQbkdJbFNTRitKeDR3cUFMRWo5eVhYYjVqWFBSWVlGbmhveE1hcDQ0UkN3V08xanVZRll5Vk9KcDRyQ2lhcFF2WkYxV09HOXhWaXMxMXJvbmYyRWdyNjJrdVU1ckJIRXNJWUVrUk1pb29Zd0tMRVJvMTBneGthTHptSWQvMlBFbnlTV1Rxd3hHamdWVW9VSnkvT0IvOEx1M1ptRnEwazBLeElEdUY5ditHQU42ZG9GbTNiYS9qMjI3ZVFMNG40RXJyZTJ2Tm9EWlQ5THJiUzE4QkF4c0F4ZlhiVTNlQXk1M2dLRW5YVElrUi9MVEVnb0Y0UDJNdmlrSERONEMvV3R1MzFybk9IMEFNdFNyNVJ2ZzRCQVlMMUwydXNlN2V6djc5bTlOcTM4Lzg0WnkydThtVzBJQUFBQUdZa3RIUkFCRkFBNEE2MVFXZXJ3QUFBQUpjRWhaY3dBQUxpTUFBQzRqQVhpbFAzWUFBQUFIZEVsTlJRZm9DUTBOT3cyRFlvazFBQUFBR1hSRldIUkRiMjF0Wlc1MEFFTnlaV0YwWldRZ2QybDBhQ0JIU1UxUVY0RU9Gd0FBSUFCSlJFRlVlTnJzblhkNFhIZVYvai8zM3VsRjBxajMzbTNMdmNaMjdCamI2YjFBQ0NSQXFBR1dzTURTTnl3LzJpNTlzeUcwVU5JZ3BKTWVKN2JqM21WYmttWDFYa1pkbzlIVWUrL3ZqNUdWT0phdE5xck0renp6UEhJeWQrYVdkODczblBNOTV6MkNxcW9xSVlRd2h5Q0dia0VJSWRLR0VFS0l0Q0dFRUNKdENDSFNoaEJDaUxRaGhCQWliUWdoMG9ZUVFvaTBJWVF3SG1oQ3QrRFNVRlVWdDhlTHorZkg2L1hqODh2SXNreHYzd0JOTFIzNC9mSUZ4MlNtSnhKbU5hR1JKTFJhRFJxTmhFNm5SYWZUSUlraE94RWk3UlRBNWZMUTB0WkphM3MzSFoyOWxGYzIwTnpTU1ZPem5UWjdEOTA5L2FNdllhSkFaSVNWcE1RWVlxSWpTRXVKSXkwbG52aTRTS0tqd29teWhSRVRIWUZHSTRWdStEZ2hoR29QM2tWTFd4ZDc5cCtpdEx5V3l1b202aHZiNmV6cXUrQjlVWkZoV014R1RFWURrWkZoaUlJdy9QOTYraHc0SElQSXNrSlhUejh1bCtjOElsc3RKaExpbzRpUGpTUWxLWmJzekNRSzh0SW95RTFEcjllR0hrS0l0R05EZVdVRFR6MjNrOE5IejlCbTcyYkE2VUpSQXJjbFBNek1ndngwRmkzSUlpOG5oZVRFR0F4NkhScU5oRVlqb2RkckVYaVh0RjZ2RDUvUGo2S3FlTHcrQmdmZDFEZTEwOVRjUVVWVkkyY3JHMmx0NzBhV1pRUkJ3R0kyRWhGdUlUNHVrc1VMczdqcmptMGt4a2VGbUJraTdjam82M2Z5Njk4K3c3UC8zSVBUNlJyKzcxYXJpWTNyRm5QemRSdFl2MllSSVBBZVl6cHgvempnSk5QVTBzSHhrNVhzMmx2TWdjT2w1N2tiWC96MExYeitVemVGbUJraTdmbm83T3BqeCs1alBQeklpN1MwZHFMUlNNUkVSNUNSR3M5Vlc5ZXc3WW9WMkNLczAzSXV6a0UzcDB0cjJMSHJHQ2RMcXZuSjl6NUZabnBpaUpraDBnYmc5OHVVbmEzakwwKzh6c3R2SEFBRWtwTmlXTDltRWR1M3JHUnBVUzZHT2VCWDF0UzFjT2pvR1RJekVsbVFuNDdGYkF4bEQrWWpaRmxoMzhIVC9QSTNUM08yc2hGRlVibnV5clhjZXNQbEZDM013bXd5ekpscitjMGZYK0RsMXcrU25CUkRZWDQ2MTJ4ZHc4YjFpOUhydENIU3ppZnMySFdNSC83OE1kcmF1ekhvZGZ6Z3UvZXk1ZkpsV0MwbWhHQTRyTk1JeDRBTHZ5eFQxOUJHUTFNNyt3K1dzTEF3ZzAvZWZTMHJsK1hQK3pUYXZIY1BGRVhoVkVrMUgvLzhUM0FPZWtoTmp1V0JyOS9EdXRVTDV4eFpoek1VUGorNzlwemdEMzk5aGNycVJnWmRIbFJWUmFmVnNIbmpNcjcrcFR1SmpZbEFxOVdFU0R2M0NLdHk4RWdwWC8vZTcyaTM5NUNkbWNSWHZuQUhsMSsyR0hFZTdFeDVmWDcySHlyaDZSZDJVVkpXUzV1OUIwVlJzRVZZdWZ0RDI5bCt4VXJTVXVQbm5lV2QxNlN0cUc3aWV6LytNOGVLejJLTHNQS0Q3MzZTeTljdFJwTG0xMWFxMitQbHdLRlMzbjduT0cvdU9rWjNUeitTSkxKNFlSWjMzSHdGV3pldm1GZkIycndsN1lEVHhXLysrQUovZWZKMXZGNGZQL3ZCNTdoNjI1cDV1L2V2cWlyOWprRk9ucTdpNFVkZTRHaHhCWUlnRUdrTFk5TmxpN24vYzdjUkcyc0xrWFkyNDhqeGNyN3dINyttdTd1ZkQ5KzJsZTk4N2FPSW9zQjhoNnFxZUwwK252M25Ibjc4aThkeHViMklva2gwVkJpLy9ORVhXTEUwYjg1ZjQ3dzBPNHFpOHRqZjM2Uzd1NStNOUFUdSs5U04veEtFQlJBRUFiMWV4d2R2dVlLL1BQeE5WcThvUUt2VllPL281Yk5mL2ptUC91ME5CdDZ6K3pjWElUM3d3QU1QekxjSFYxdmZ5czhlZkFxTkpQS0ZUOTNNc3NXNTh5THdHaTk1NCtNaVdiMjhBSUM2eGpaNit3WW9QbDJKeSswbE55dDVUdVdtNTcybGZlSWZPM0FNREpLVGxjeXl4VG4vMHVWL1NZa3gzSGZ2VFh6N0t4OGhJeTJCZnNjZ2ovOWpCei80NmFPMDI3dERwSjBOY0xrOVBQdlNIaVJKWlBtU1hETFNFdmhYaDhWaTVKcHRhL2poZHo5SmZrNHFnNE51WG52ckNQZC80MEhhMnVjZWNlZGRJSGJ3U0JrZi9jd1BpWXUxOGIxdmZJd3JOaTRqaEhkUjE5REdkMy93Q0llT25RRmd6WW9DZnZ5OVQ1TVFGOXh5U0ZWVmFXN3Q1Rmh4QmMwdG5ad3NxU0k5UFFHejJZaTl2WnVQM1hVVldSTXNESnAzbHZiNHlRb0FJbTFoTENqSUNMSDBmVWhQamVmYlgvMElLNWZsb2FvcWg0K1g4Nk9mUFU1OVF4dkJ0Rjgrbjh4Zi8vWTZSUXV6K09BZFcvbmhEKzdqVTUrOG1WdHYyUUtTaUhOZzRzSGd2Q1B0NmJJYUFGS1RZb21Mc1lWWU9nSnlzMVA0ejYvZncvcTFpNUJsaFIyN2p2Ry92M3VPZnNkZ01HMHRPcTJXeE1RWUJPbmRtR0xRNWNGc05HQTA2a09rQmVqdEhhQ3gyWTRnQ0N4YmtodGk1eVdRazVuTWQ3OTJONnVXRitDWFpWNTc2ekFQL3U3WllLWXZNT2gxK0JVVjVYMFdYS3VWSnBYTm1WZWs3WE00OGZrQ2JTeUZlZWtoWm82Q3RKUjQ3di9jYmFTbHh1UDErbmppNmJmNHpSOWZDTXBubnlxdEpqNHU4Z0tYbzY5dkFFa1VRNWIySE93ZFBYaTl2a0FuYktRMXhNclJqU0ZMRm1Yem1ZOWRUM1JVT0Q2Zm56OC84UnE3OWhhaktNb2tmVnIvaU5aVVVSUkVVVHl2R1hTOG1GZTFhK21wOFd6L3dDcnM5bTV5TXBORHJCd0RKRW5rK3Fzdm82dTduNGYrK0R5OWZRUDg5azh2RWh0am95QTNkUkxsbXdJNjNZWDA4dnRsckJZamVvTXVaR2tCWXFJaitQZjdidWUvdnZXSkVCdkhBYTFHNGtPM1hzRk4xNjVIVlZWT2xsVHo1Tk52MGRmdm5EaXhSSUg0dUtnTC9GbW4wNDNQTDZPVnBCQnAzM1h5TmY5eVBWUEJnTlZpNG91ZnZvVkZoWm40L1RLdnZIR1FmWWRLSnZ4NW5WMjlJL3F0aXFwZ011alJhRU9rRFNFSXNFVlkrY0YzN3NWbXMrSVlHT1RIdjNoaXdwOVZWOStPeWxEYi9Idmdkbmt4NkxVWTlDSDNJSVFnSVRNOWdVL2VmUzE2dlpaMmV6Y1AvT2pQRXcvS1ZQV0M3SUhiNDJYd1BhbzdJZEtHTUdub2RGcTJiVjdKcW1VRkNJTEFjeSs5UTNsRlk5QSszMlRVWTUyayt4WWliUWdYSURreGhsdXUzMGlrTFF5WDI4dWpmM3VkUVpkNy9JWVdVTlR6TXdjT2h4UFRKRXNpUTZRTlljVElmOHVtNVN6SVR3ZGc3NkVTOWg4cW5ZaDNjSjU3b0NoS1VBclFRNlFOWVVUb2RWcSs4c1U3MEdnazJ1M2Q3TnBiak1mam0vVG5obGxOUkVXR3pXL1NlbjErcW1xYWFXaXlJOHRLaUUzVGlQeWNWRzYrZGdNQXg0c3JLSzlzR0tkN2NINFFKc3NLVHFkNzBub01zNXEwblYxOS9PbnhWL25HOTM3SGYvM2t6L1QwT2tKTW1tWjg1aE0zWURZWnFHMW81Y2p4Y253Ky81aVBWWlQzazFhbVp3eUMxSE9XdEVlT2wvT0ZyLzJLaC83d1BDZExxcW1wYThYcjg0VllOQU5CMmZZUHJFS1dGZDdhZlF6SHdPVEtGNjBXMDZRVktXY2RhZjErbVdkZTNNMi9mL3NoamhWWDRISjVXSkNmenM5KzhEbmk0MEppd3pPQmE3ZXZSYS9YY3VKVUZYVU5iV002Smo0dWNrVExLeXZLcElYeVpoVnBuWU51bm5wK0Z6LzU1Wk8wdFhkak1obTQ4ZG9OL1A3WFgyVnBVYzZrS29OQ21EalNVK05aVkppSm9paTgvdmFSc1Zub3BKZ0xZaENmMzA5clc5ZjhjUS82SFlNOC9NZ0wvUENuajlMYk4wQnlZZ3ozZis1V3Z2L05qeE1kRlI1aXpnd2l5aGJHNG9WWkFMeTE2eGkrRVNiNlhHQlZWWlhXOXE0UnN4S1RxYVdGV1ZLYTJOTTd3UC8rN2huKy91eE9mRDQvQ3dzeitQVEhybWZiNWhWelZ0bHdPdUR6eTVTVjErRnllMWhXbER0aUtXQXdZRFRxS2NoTEk4eHFvcUhKVG1WMUU0VjVhYU9rRGxRR1J1Z0RzNWdOaEllWjU3YWxIUngwOCtEdm51RWZ6Ky9DNS9PVGs1bkVWNy93UWJaY3ZpeEUyRkhRYnUvbUo3OThncTk5OTJFZS9QMXplTDMrS2Z1dXdEaXBRRXl4OThDcGlmM0lmSDZhV3pybnRudmc5OHM4KzlJZW5uOTVIeDZQajZqSU1CNzR4c2RZdTJvQkdpazBYMnZVU054c0JGV2xyYjJidno3NUduOTg5T1VwSTI3S2V4cEZpMDlYamZyK2tReU9xcXI0dkw2NVMxcFZWVGx3dUpSSEhuMEZ4OEFnOGJHUi9QTEhYMkRsc3Z3UUc4ZUk4SEFMUC92QmZWeTJaaUdLb3ZMSFIxL2g4WCs4aWN2dENmcDNSZHFzeE1YYUVFV0JFNmNxUjkwZEs4aE51NkNhUzZ2UkVCT0VEdWtaSTIxVFN3ZS8rTTAvYUdycElERStpbTk5NWE1aDNha1F4bzZFK0NnZSt1bjkzSHJqSnZ5eXpFTi9lSjduWHRvN0pkK1ZsWkdFWHFmRDc1ZHBhR3EvdEI5czBOSFViRC9mK3FvcVlSYlQzQ1N0MitQbHg3OTRncEt5V3F3V0UzZmZlVlZJQ1dhU2dkS243cm1XTFJ1WE1lQjA4ZUJ2bitXVk53OEcvWHRpaDhhaUJraHJIOTFGZU4rL0c4ZHd6S3dsN1d0dkh1YnRkNDRqU1NKYk55L24rcXZXemR2NUFKTkY4ZWtxV2xwSEQxN2lZbXg4NmJPM3NtN1ZBcnA2K3ZudlgvNk5NMmZyZzNvdU9kbko2UFZhVkZVOWIzenF4U2hyZkYvejRrVEtHMmNGYWV2cVczbnc5ODhoeXdwWjZZbmNlZHZXU1ZmOXpEYmM4dEh2c3VuYUwxRlozVFNwenlrNVU4dnQ5enpBWFovNkFYc1BuQjQxOEVsSmp1VXJYL3dnaVFsUnRIZDA4OGZIWHNYcGRBZnR1dlE2TGFJZzRQUExZN2cyRlpmYmU5NS9rVVFSaThVNHQwanI4ZnA0NXNWM2FMZDNJMGtpSDc1OUswVUxNdWVkZGJSMzlPQjB1amxUMFRDcHowbE9qQ0VtS3B6VzlpN2VmdWM0ampIb1h4WGtwdkhsejkyT1Zxdmh5UEV6SER4YUZqU05ycVNFbUhHdGlGcU5oUFFlTVd1OVRrdDhiT1RjSW0xbGRSTjdEcDdHNC9XeGFsa0JOMTZ6Zmw0dTZVc1dadU1jZEZGZU1ibmxPU0xjd3AyM2IwV1dGWGJ2TzBsZGZldVlqdHYrZ1ZWY3UzMHQ3Zlp1WG5ueklGM2QvVUc1THAxT00rYmN1U0FJaEllYjZlMGJlSmRzUVVxN1R4dHBQVjRmZXcrY3BySzZDYU5CeHpmLy9hNUpiK2ZOVmhRdHpNTHZsMm16ZCtOKzN4STVYdHgwelhyQ3c4dzB0M1p3OU1UWk1kVVU2N1FhUG5uM3RTVEdSL1AyN3VPVWxOVXczWUt1Z2lDZzErbk9xd3FyckdtZVc2VHQ2dXJqaFZmMjR2UDUrY0NtRmVUbHBNemI0R2xKVVRZUW1LellQOGxTdnNqSU1EYXVXNHlpcU93NWNHck05YXhKQ2RIY2ROMEduSU51bm5qNkxXUkZubmJTaGxsTk9CenZ1alRPSU0xNm1EYlNGcCt1b3JxMkJZTkJ4KzAzYlpyWEVYOXNWQVFBYnJjSDl5VGJwWFU2TFpzM0xFR1NSSTRXbjZYUDRSenpjWnN1VzBKV1JpSUhqNWJSMU53eHphUUZxOVZFMzN2Y2cyQmgya2o3OTJkM0FyQnlhZjY4SHcyZmxob2ZzTFFPMTZTTHBrVkJJRFU1am9TNEtOeHVMN3Yzbmh6enNWa1ppYXhkdVFDZno4OWpUNzA1NmV2cTYzY2lEMmtnU0JweFZFdHJNdXB4RERqbkptbmIycnM0Y2JvU1NSSlp0M29CRVJFaFJjUHhJQ1k2Z3B5c2dLRGU0U0haK2JIQVpES3dlbVVoa2JZd1huaDVMLzJPeVJHb282c1h2MTlHSTRtalpnRUVRY0FXYnFHM2Q0NWEyamQzSHNQdDloSWZGMFYrVGhyYU9USnRwcTZoYmRKcUtNRkFlTGlGcElUb1lRTXdIaXhmbkVOY3JJMitmaWVIanA2WjFIbjA5UTBneXdHcHpramI2TGwxVVJUUlRjR3puaGJTN3R4ekFnaFV3R2VrejQxcE0vVU5iZHo2MGYva1F4Ly8zcmp6bk9ka2hBUlJDRXA1cGNtb3gyYXpJZ2dDaDQrWGordlk2S2dJTWxJVEVBU0JnMGZMSm5VZTlvNWUvSDQvR28xRStwQUxkQ2xvTlJJdXR3Zkh3Q0N5ckZ5Z29EaHJTZXNjZEhQOFZDV1NLSktabGtCaS9Oem84eW81VTRmUDc2ZmZNVGh1Z1lsem13clJVZUZFUjBjRUo3aUxqcGl3R3VUaWhWbUlnc0RwMGhyOC9vbG5FUnFhMnZGNi9lajFPbEtTWWtkOWY1alZUR1NFRlh0N056dmVPa3hyYStla2hPZW1qYlFuVGxVaSsyVk1aZ01GbzFXN3p5SlUxN1hnOThza0prUmpIV2RsVXVOUWRaTkJyd3ZLUXdwWUxjM3dNR3F2YjN3MXN6blp5UWlpUUZkUC81Z2JFMGRDUzJzWFByK2ZyUFFFOVByUm14TnRFVlpXTDh2SFpqRmlNUVN5R1FYNWsrZkFsRmVwMU5TMW9pZ0JUZEtzakxtVE5haXViY2J2bDFsV2xEUHVZeXVybWdJUytqWnJVUGJhMzQveFRsTFB6VXBCRUFRR0J6M1VOYlNSblprMDd1L3M2WFhRM05xQkxDc3NYeksyb2RCNnZYYllqY2lad0hmT21LVnRhKzlDVVZVTUJoMXB5WEZ6Z3JDdDdkMjAyN3RSVlpYQ0lUMnI4YmtXdGVoMVdwSVNvcWVrZzFpU3h2ZllJbTFXd2l4RzNHNFB6UzBUeTljMk50dHB0L2NBc0hiVmduRWQ2NU1WWEQ0L2ZrV1pHNlE5YzdZZVdWYXdtSTFFenBGcXJ0YTJUbnI3bklpaU1DekNObFo0Zlg0T0hTM0RaREtTbHgyOFhUKy9MQ01yQ2luSnNlTStWaEFFOG5QVGhsUU1KeFlNTlRUYWFlL29JU295YkZ6ZEpRNm5tNWZlUE1RbnYvQS8vUERuVDlEVU9zdDd4QVlIM2NQK1Z6QWY0SFNrdWpxNyswaUlpeUkxWlh5cnc5SGo1Y2l5Z3Nta0p6c3JPTU5LL0g2WitzWjJIQU9EeEFVcHNCc1BQQjR2RmRXTjlQWU5zSEhkNGpFZkZ4aXNkNVRqeFdmNTNuZnVKVDh2amI4KytkcmtOMXltOG1LN2V4M0QvVXFKUTNuRzJRNnYxMGR0ZlNzREE0T3NXSm8zN3VQM0hEaU5YNWJKejBrZHpxMU9GZ05PRngyZHZRQ2t6SUNMMWRNM1FObFFRZm5tRFV2SGNaeURxcHBtTm0xY1JuaTRsYlZyRmhGaEM1OTB5ZWEwYmVQT2xVTHZucjZCb2VCUlpjTzZvbkVISzZkS3E1RmxoYTJiVndUdG5IcjdCbWdlV2xZbjhrTUtoZzl0ME90SVNZcGhVZUhZNXcyN1hWNUVVY1FXWVVVUUFtMUJXWmxKOVBSTVRraHdTck1IVGMwZDlQV2QyenFjR3hvRzNUMzkxTlMxWURMcDJiQjJmS1E5V1ZKTlUwc0hZVllUV3pjRmo3UmQzZjNVMXJjaUNIRFo2a1dUK3F5SlBJV1lxQWdlL0o5L0d6KzVOQktvQ3JJdmtCdFdmREpOalcxa3BDYk1YdExPTlV1cnF0RFczazFqazUyVnkvTFJqVU1vemVYMnNQOVFDZmFPSGo3eGtXc3dtdzFCT1NkWlZpZ3JyNk96cTQ4RkJlbEVSRmdtOURtMURXMFk5VG9TNHFmUFRZdUpqaUE5TllFbi8vNDYwWkhoK0dVWnM5bkE0a2tXLzA4YmFlZUNUeXZMTWdlUGx1SDErVm0xdkdCY01rTU5qZTBjUGw1T2VKaUZqOXl4TlhoQmtOZkhqdDNIQUxoODNXSzZlL281VzlrNzZuRUxDakxRRGJYR2RQWDAwOUhaUzNSVU9ESFIwNmVMSmtraTEyNWZTM3BxSEpYVnpTUWxSck44U1M0bW8yRnVrSFl1d09lWDJYdmdORmFyaWNMOHRER3IzUGo4ZnQ3WmY0cUtxa1krZE9zV29pS0RSNHl6VlkwY0w2NEFZUGUra3h3N1dVbjNHTnBudnY3bE80ZmRtOUl6ZGFpcWl0bGttUGF5VUwxZXkvSWxlV1Bla0FpUmRweW9xbTZpdXJhRmxjdnlTQjhxTWhrTDJ1MjkvT254VjBsS2lPYjZxeTRMK0hKQndrTy9mdzdQa0pSUWFYbmRtSTlyYmU4ZS92dFVTUldLb3BLWm5qaHA4YmZaZ0dramJXdGIxNnp2dk4yNXR4aFZWU25JVFNNKzFqYms1NnA0UEQ0OFhoOCtueDlWVlpFa2FVaXlVb2RmVnZqVmIvNUJUNitEMjIvY1JFRnVhdERPNThDUlVuYnZPNG5Cb01OcU1lTDErdEhwdE9pMEdySXprOGpKVEI1UkJ0VmtNbkROdGpWQVlGT2krSFFWaXFLd2Nsbit2QkQxbTFMUzZuWGFZYXZUMmRVN3EyK0VjOUROYy85OGgwaWJsYUtGV1dnMEd1b2EyamhiMmNDQnc2V2NLcXVob3FvSnI5ZEhRbndVSzVmbGMrOUhyK0hBb1ZKZWZIVS95NWZrY3UyVjY4WVZ2RjBLOW80ZWZ2M3dNd2lDd0pvVmhkejN5WnZRYUNRS2NsTkhIRWwvTVpTVTFkTFFaRWVqa1ZpN2NnSHpBVk5LMnNoSTY1enB1TjEzOERUTnJaMFVMY3dpTnp1RnA1N2J5U3R2SHFMNFZDVm1zNEcwbEhoV3ZNY3YwMGdpYis4K3ptTlB2WW5Sb09NamQyeWJVQ0hLaUprSWw0ZkgvdjRtSldmcUNBOHo4NkZidHd5TEdvOEhpcUpRZkxxS2pxNWVWaXpOSXpjN09VVGEwYU5IQ1ZHY0c4dlJ5MjhjUkpKRTFxNWNnRllqOGR4TGUyaHM3dURUSDd1TzFTc0tpWW1PT0svam9yUzhqdi85N2JOMGRmZnp4Yy9jSERRdE1rVlJlT2ZBS1o1L2VTOGVqNWQ3N3J5UzlXc21scHZ0NnU3bitNa0tCZ2M5M1BlSkcrZE43REZ0UG0xdGZkdXN2UW5sRlEyY1BGMkZWcXZocXEyclNFK041N0hmZlF1VlFJTDgvYVdBamMxMkhubnNWU3FxbS9qQXB1Vjg1dU0zakx0YzhGTDM2Y2UvZUlJMmV6ZUxDalA1MG1kdkhYZFYxM3N6RC9zUGw1S1huY0t5SmJraDBvNEZvaWdPTy80RGt5eVNtQ29vaXNJNyswL1MwemZBa2tYWkZPYWxBNHpvbXlxS1NrTlRPOS84cno5UWVxYVdxN2V0NFlHdjN4TTB3dG83ZXZqdUR4K2h1YVdEeElSb3Z2ZU5leVpNV0tmVHhUTXY3TWJsOHZDUkQyNExha1pqZnZ1MEVSYU1odG5oMDNxOWZsUlZRZisrVGdKN1J5K0hqcDdCNy9QenhVL2Zja2svOCtEUk1oNzQwWi9wN3Uxbis1YVZmT216dHdVdGhkVGExc1Uzdi84SGpod3ZKeTdXeHI5OTloYnlKcEdKa0pXQUFOeUd0WXRZdTNMQnZCb0ZNS1drTlJqMHM2Yno5azlQdkVwVHM1MWJiOWcwSE5Rb3FzcUowNVdVbmEyak1ELzlvc0ZPUjJjdi8zaCtGOCs4K0E2dDdWM2NjdjFHUHZlSkcwbE9pZ25LdVpXZHJlZTNmM3FSL1lkT1k0dXc4cG1QMzhDMlRTdlFhaWIrZU13bVBmLzJtVnZRYUtRUlozcUZTRHNHTkxaMHpPaUY3dHB6Z3VMVFZXU21KdzZUMCtsMGNmQklHZDA5RHI3N3RZK09xQWpZNzNEeXN3ZWY0clVkaHdENDhuMjM4Y0ZidGhBUmJnbktlVlZVTmZLam56L09zZUt6cUNyOCsrZHY1L3FyTDV0MGI1a2tTWE9xSjI5V2tkWmlOaUlJd296UHRWVVVGVmxXenV0R2JXbnI0cFUzRDVHZG1jVGlSU1AzZ2prR1hPemFlNExZR0J2LzhhVTcyWEo1Y0JYTGErdmJPSEdxZ2pDcmlXOTgrY1BjY1BYc1ZaTDArMlZVVloxeEFld3AvL2JrcEpoWm0vWjY3Tzl2NG5LNXVmN3F5eTVhaFJZZkc4a3pqMzQvb0Qwd0JjbzRpeGRsOFpNSFBrMW1ldUtzdG93dWw0Y25uMzZMdXNZMjd2L2M3ZGdpTFBPWHRMTVZGVldOdlBUNkFYS3lVdGl3WnRGRjU3VktraGkwRG9TTC9TaXUyYjUyVHR5em84Vm4yYkhyR01zVzU4Nm90dkMwNnRPMjJidG54YzMzZUh6ODlNR244UHY5YkZpN0tHZzdXZk1aUnFPZTlOUjR0RnJOdVBURTVpUnBBeWt2QVVWV1pvVXVGc0NiTzQreS85QnBZcUlqdUhaNzhPb0ZwaHYyamg0K2Z0OVBXTHYxYzN6ciszOFk3aU9iS21SbkpLSFhhVGx4cW5KK2t6WTFKZTQ4M2YyWndya2IzZHpTd1IvK0dwaHNlT1dXVlhONlA3N3NiRDFucXhycDZ1NW4zOEVTemxZMVR1bjN4Y1ZHb3RGSzlQUTY2SGNNemwvU3ppWklra2hQM3dCYXJjVGloVmw4NW1QWGovc3pHcHZ0bkNxdG9jM2VqYUtvOCtiZURBNjZPVk5SUCtJUTVtRkxtNW1FUWFmRDU1ZXBxV3NKQldMVEFiUEp3UElsdWR4eDAyWmlZMnlFalhNM3E3Uzhqdi81OWQvbzdPeGoxZko4UHZXeDY0SXlyV1UyWVBlK2t6enkyQ3RjdTMwdGQ5OTU1VVVzclkxSVd4aDkvVTZxYTF0WXNpZzdSTnFwdDdRU2tSRmhyRnU5Y0VMSGw1K3RaLytoa3VIQXBMOS9jTjZRdHJhK2xiS3o5VmdzcG91U0ZpQTNPNW1xbXFZeERlU2I4KzZCeSsybHRyWmxUajlZZVI2NUErOUhTbElzR2ttOFlKN3QrN0VnUHdPdnp6K3UxcCtRVHpzQlRIWXMwbFRDNS9QenlHT3Y4SjMvOThlZ0RhbWJVSkFWWjBPVVJEeGUzeVdIaWl3c1RBZWdyMytBdHZidUVHbW5DalZEUStORVVaaHdxZDlVb2FXdGkxMTdpNmx2YkdjR09VdHlZaXlTR0JqVzNOVno4VzdmM0t3VWRGb05QYjBEdExSMWhrZzdWVGpYeldvMkdZTlc2QklzZEhYMzBkcldSVnBxUEROWlBSZ1hZME9TUlB4KytaTDlmRmFyaWJ5Y1ZIcDZIVFMxaEVnNzVkQnFwRm0za2VEenlYaThQakpuV0hCYWtrVE1aZ09xeXFoVElaY1c1ZERYUDBCRFUvdVlKa2lHU0RzQnpLU3ZPT1lITVZreks0QXdTYjIwL094VVBCNHYxYU1FekpldFdZaWlxRFMzZEV4YXRuTWkrSmRJZVhWMEJKWTdVUkluMVhaaUM3ZGdNT2p3ZW4yRVdVMWptanN3NmdQUVNPaTBXc3JPamo4YXQwVll5VWlOeDJJMmtwWWFUOXlRVmtOUWZ1aGNYS3h1OGNJc2pBWTlOYlV0OVBRNnB0M2xtamJTaXFJd1krM2tyVzFkUXo2dGdmRHdpYmZIckZxZXozOTg2VTRHQjkwVTVLVUZwU01nT2pLTWhQZ29qaGRYNEhaN3gzV1BGdVNuODQwdjM0WEw3Y0VXWVEzcVRBdFpVUkFGWWNRVlFLdlJrSitiU25WdE16MjlEakxTRXVZbmFYVmF6WWhxS05ONnNVTldiYUlJRDdmdzRkcytFTlJ6aW8yeGtab2N5OUVUNVJ3NFVqcXVWblNOUm1KQlFmcVUzQ3RGRFJCWFA4TEtwTk5wS0ZxUXlZbFRsVFEyMlZsYWxET3RQV2pUNXRNS2dvQkdHNUlPZXorTVJqMUxGbVZqTVJ2NTBTK2VtRlhuNXZhTlBITk1vOVdRa3hrb05EbzVKQ0lkQ3NTQ2pJcnFRUFdUeWFnblloWUtzSzFmdTRqMDFIanFHOXI0L1Y5ZW1wR0lmQ1NuVmxGVmZDT2NpeVNLcEtYR1k3TlpPVjVjRVNMdFZHQncwQTJBWHEvRFpETE11dk5MaUl2aTV1czJJZ2dDei83ekhVclAxTTRDenFxb2w3QzJzVEVSWktVblVuYTJudmFPbnZsRldwL1hqMG9JbytHNks5ZHgyZXFGMURlMjg5aFRiMDU1UWZlb3BGVUQxUFhKOG9oam5HSmpiR1JsQkRvK1huL3I4UHdpYldPTGZYakE4VXlob2NtT0pFbEJUUWtGR3hhTGtlOTg3VzdpWW0yOC92WVJYdHR4R044NHg0bE9GazZYRzBFVXprdmxxWUIzaE9YZlpOU1RrWmFBMGFCbng2NWo4OHpTRHQxNFVSSXh6WkRhVEhkUFA1SW9FRzZkM1lMQ0dXbngvTWUvM1lrb0NQejBmLy9HemowbnBuV1ZLcTlvUUtmVmtwd1lnNktxdzdVUVByOHlZbUJkbUpkR2RGUTRKMDVWMHRiZU5mOThXcjFPT3lOS0o0cWlCQjY4SUtEUnpQN3N4Zm8xaTdqenRnK0FJUERWNy95R1l5Zk9Jay9EU3VYeGVGRlZGVUVBalVZejVORUdJS3ZLaUdXWitibXB3NnZYL3NPbG9VQXNXT2pzNmtQMnkyZ2tjVmE3Qis5MUUrNjg3UU5jdVdVVnNxenczUjgrTWx4NFBwVm9idTFDVmhTMFdnMHgwZUhuVlp3cEtpUE90WTBJdDVDWEV4QjVmdVB0SStjSm9jeHAwamExZE14b0wxV2ZZeEJaVVJBRUFkTWNFWGhPU29qbU14Ky9nY3lNSkt3V0U4KzgrTTZVZjJkcmV4ZUtyQ0JKSW1GVzgzbjFHcXFxWHJRQWZzUGFJalNTU0dWMTgvQ0F2amxQMm9FQkY2cXFFaDBWTVNNRWNMdUhsajFSd0dEUU1WZnd6cjVpbXBydFZOZTFjTjJWVXkvbTBkUGpRRkVVZEZvdENRblJ2Sitqc3FxTW1FVllzVFFQU1JMcGR6Z3BQbDAxdjl5RHhCbndaMlZab2I2aERaL1BqMVlqa1p3VU8rdkpxaWdLYis0OHhwK2VlQTJmMzg5SDd0akdsc3VYVC9uM2xwYlg0dlBMNUdRbkl3ckNlVDR0QkZxTlJsb3h3NndtcnQ2MkJzZUFpK0pUbGRPU0tacmFLZVF1RHo2L2YwWWUvb0RUeGN0dkhHRFgzaE40ZlRLQ0lGeFUrbWcyb2ZoMEZiLzk4NHYwOURyNHlCM2IrYmZQM0RJdFA1U0dKanV5ckpBVUg0VXk1TWVlL3g1MVJFc0xjTTIyTlNpS1FtMURHNjF0VTkrQ002WGhkSGRQLzdDcVROUTBGOHUwdG5YeDBPK2ZIMjYxQ2JPYWlJdVozWUZZdTcySEgvL2lDVXJQMUhMckRadTQ5NlBYVEUrdzJ0MVBkMDgvcXFxeWJIRnVJT1B5UG9LcWdId1IwaTR0eWlFcU1venFtbWFxYXB0SVNwemE2WnpUNWg3RVRYT3J0ZGxzSUNFK2F2amZnakM3ZmRyVzlpN3UvK2FEbkNxdDRmTExGdlBKdTY4aDBtYWRsdTl1YnVtZ3QzY0FnTUw4OUl1UzA2K29JL2F4bWMxR0xsdTlpSTZ1UG1ycldxYzhpekNscE8zbzdNWHBET3o3VDdjMFVuUmtPRVVMM2xYMnpzbWF2U0p6Ym8rWG4vL2ZQemhXZkphMGxEais0LzRQazVvY04yM2YzOURZVGxkUFAxYUxrZFNVdUl0bUNtUkZ1Y0RYUFljUGJGb2VHQUZWVWozbDNReFRTbHBCUjJZdEFBQWdBRWxFUVZTUHh6ZjhxOHZKbWw3TkxKMU9TMEZlMnZDY1dxdlpPR3RKMjlzM1FGZDNIMmtwOGZ6Z3UvZVNrUm8vcmNGcWJYMGJ2WDBEckY5YmhLb0dMT3JJcEZVdjJqRmNrSmRHZkd3a1pXZnJwbHpuYTBwOTJnR25DNjh2MEFscm1JRXQzTXlNSkJJU291anE3cHZWdm14OGJDUmYrZndkU0pKRVhrN0t0SDUzWjNjZmxUVk5BS3haVVlpc0twZnNxZk1yQ3BKNFlXRzQxV0prWVdFR08zWWRvNktxaWJTVXFWc3B4S20ySU9lRU1sS1Rwei9kWkRUcTBlc0NmbXhOWFNzRFR0ZXNKVzVoZnZxMEUvWmM4SGRPTFdiVjhvSVI2d3plYjIxSGdzVmlZbEZoWVBieG52MG41NjU3NFBYNmhndUVaMEp2b0tPcmw3NytRSURSMU5MQkcyOGRJWVQzWkFSVWxjYW1kdHJhdThsSVN5QTJPbUxFaXE3M1c5b1IzVEd0aHNLOE5PSmliZXliNG0zbktTV3R2YU9IQWFkcnhnUXlmRDcvc0U4OTZQTHd5bzVEczBiWWVUYkE1NWZaZDZnRVJWRllzN0lRUVpJdW1vc2R6ZEpDWUw1R1VrSU1qYzEyU3NwcTVoNXBmWDQvYmsvQW44M09TSm9CS3hLWURYc3VrcFVraWFycUpnNGVLWjBUT2dqVGtyVndlOWk5N3lRYVRVQ3ZWeGxEYzJLZ1pISGsrNWVjR0VOMlppS2lLUEw4eS92bUhtbWRUdmV3SmxSaVF2UU1QQklWeDhBZ3JpSEx1bVJ4RG0zMkh0NSs1d1I5L2M0UVk0R1NNN1YwZFBhU2xCQk5aa2JTUmZPekYxamJpN3hQcjlkUm1KZU95YVRuclhlT0Q3YzV6Um5TdWx5ZVlYSWt2aWZKUDMyVWhYNUhnTFRwNlFsODdLUFhvTkZJN054emdxcWE1aEJqZ1JkZkNWakRySXdrSW14aFkxNkIvUExGMzFlME1Jc3dpNG1Pemw3S0t4dm1GbWs5WGgvT29XaDlTVkhPdEQ4UWw5dUx2YU1IVlZXeG1JMFU1R2V3WmZNS09qcDdlZkxwdC9ETDhyODBZVHM2ZW5qeGxmMW9KSWxGaFJsRVJvV1B1VXRDdmNRN0MvUFNpWXUxSWN2eWxBVmtVMFpheDhEZ2NIT2UyVHo5SGJCZXI0OSt4NUNsVDRqQlpESnczVFhyaVk2SzRKK3Y3ZWVkZlNmbkJMbmNIaThPeDJEUS9mQlgzenFDWDVaSlRJaGljVkhPcUFIWStSbUVpNzlYRkFVMnJWK0tvaWljS3FtZWtvS3BLU1B0b010RFgxOGczYlN3SUdQYUgvYmdvSHRZOURkeHFJQWpKenVGTFZlc1FLZlQ4cE5mUGtsRGszMTZyYi9MUTc5amNOU2llRVZSNk83cDUraUpzL3oya1JmNXc2TXZCMVVZMmpFd3lJdXY3RU1RQkZLVDQ4akpTUjJYeXZsb1A2RFZ5d3RRVldodTZhU3lxaW5vOTNGS2RzUlVOYkN4ME5NM1FIeHM1T1FWQVNmaW5uaDg5UFFFNXZFbUpRWTJOaXdXRTFkZmRSa25paXVvcUd6ZzRVZGU0TnRmL2VpMGREVDQvVEkvK2RXVDlQUTZTRTJPSXo3V1JtTDhoUUZxWjNjL2pjM3RWTlUwMDloc0o5eHE1bzZiTjA5S09PLzlPRlpjUVZOTEJ4cEpZdDJhUlJoTmhoRkZPU2FTOW9KM3QzUTd1L3NvcjJ5a01EOTk5cE5XbG1XYWh3UjMwOVBpRWNYcGIwWHorZnc0bklORGx2YmRFZmRabVVuY2RQM2wvUFNYai9QVzd1T3NXSkxIemRkdm5Qb1RFc0NnMTFKU1ZzT3VQY1ZJR2hIakNKUEdSVW1pTURlVmd2eDBQdjJ4NjRtTHNSRWRIWTVHQ2c1cFhTNFBiN3g5aEw2K0FTSWpyVnkxYlEzK0lDdkVHSTE2MXExZXlQTXY3NldtcmdXL0xBZnQvS2VPdElwQ2EzdUF0QW14VVRNeTBMblA0YVM1dVFNQnpwdHRLNGtpTjk1d09Yc1BuR1RmL2xNOCt2YzN5TTFPWVdIaDFMb3dHa25pNi9kL21LL2YvMkVnVU96OWZuOHZMenVWTUt0cFNzK2pzcWFaa2pPMXlJckM5aTJyQ1l1dzRwMkNVc0pycjFyTHMvOThoNHFxUnV3ZFBTT3VLclBLcDVWbG1hYm1BR2t6TWhKbXhOS2UyOWlJam81QUdtRnAvZjUvZnBxc3pHUkt5K3Y0ODVPdjBUN05jM3VYTE1wbTVkTDg4MTVUVFZpUHg4ZmVBNmVvcW1uR0ZtSGxVeCsvZmx4dXdidlpnOUZkaEpWTDhvaU9DcWUydnBXT3p1QVdMRTBKbS93K21jb2gwYmVVcE5ocHQ3U3FHbENwQnJCWVRTUFc4aHFOZXI3d3VkdElUb3JsMVRjTzh2Q2Yvb25YT3pPdFFkT0Z1b1pXWG4zekVINi96RWMrdUEyVHhUeGx1NE9pSkxGcWVUN05MWjNVTjdRRnRTTjdhaXl0b3RCbTd5RXN6RXg4Yk9TMGFwY09CelJEd3k3aVlpTXZHc1FzWFpMTGgrN1lodGxpNHVrWGR2SHdJeS9NYTlJKzgrSTdWTlUyazVXUnlKYk5LL0ZOWWE1YUVrVldMeS9FTDhzY1AxV0pkMmhZeTZ3bDdhblNHcnhlSDlHUllUT2lOYUNxRERmWW1VMEdoSXU0SnpxZGxpdTNyV0h6eG1YSXNzSWpqNy9LazArL05TOEpXM3k2aWllZmZndFJGTG5oNnZWRVRYRy9uQ2dLNUdRbFk3V1lPSEM0RkxmSE83dEplN0lrMFArZUVCK05kWXI5dEl0R3lVTTNLU0VoR3UwbDBrVW1rNEdQMzNNZFJRdXpHUngwODZmSFgrWFEwYkxab1JFYkpBeTZQUHpuai82RTErZWphRUVXYTljVkJUV0ZkakhFeHRnb3lFdWp0cjQxcUhLZ1UwTGEwNlVCZmRYVTVGZ2l3cWEvTEZGRnBhWTJVRitnMSt0R2RVK2lveVA0OHBmdUpDODNqYnFHTm43eXF5YzVmUHpNaktzOUJpZjQ4dkxiUDczSTJjcEdMQllUMTF5NWp0VFVoR2tSdG91MFdZZmJySGJ0TFo3dDdrRTFvaWdTRXhXTzBUZ0RIYkRxdTltRHFNZ3dwREhrQ0xNeWsvakcxKzVtMmRJOFNzcHErZTlmUHNuUkUyZm5OR0VWUldIZm9SS2VmM2t2aXFLd2FmMVNMcjk4MmJpMmJDY0RpOWxJYmxZeVJxT2VIVHVQelY3U1Z0VUVKcDZFV1Uya0pNZU5pVEJUa1Qxb0djb2VoSWRieGp4YU5EY25oVS9mZXhONXVXbVVsdGZ4amYvNlBZZVBuWm16cEsycWFlSDNmM21aZG5zUGFTbHhmT3p1YXpGTmM0Tm5lbW84TVZIaG5LbW9wL3NTNDB0bmxMUUhoaVFmSThJdE0xS1NDSUdXRUkvWGgxYXJHZGRPakNBSUZDM0s1b3YzM1U1S2NoeU5UWGJ1LzhiL2NmUkUrWndqckdOZ2tGODg5QlRIaTg5aU1HaDU0RHYza3ZDZW5jSHBRbHBxSE5GUkVYaTlQbzRjTDUrZHBEMVZWajI4TEtlbXhNM0lBMnRvYkFmQVpndWJVQ0M0YkdrZUQzem5Yakl6a3VqbzZ1V3IzM21ZbDE0N01LdW5tYjhYL2YxT0h2ejljN3kxK3pnR281NVAzSE1EdWJucE0zSXVpZkhSSk1RRjBwNkhqcDZaZmFUMWVMeVVsTlVpQ0FKeHNaRkUyY0ptNUVZRkkxSXRMTWpnTzkvOE9NdVc1dEZtNytGbi8vY1VqLzc5amVFYTRkbUs1dFpPZnY3UVAvalRZNjlpTWhtNC9wb05YSDNsMnVCdjhJemo0NG9XWktIVGFUbDlwallvNmpOQkpXMXRmUnY5amtHMFdnMExDekttSmEweUVucUhTaUxEdzh5VG1tYVRuNWZHVisrL2k2MWJWdEhXM3Mxdi92Z0NEL3o0ejhNcHZkbUdzNVdOL1Bldm51UWZ6KzlDa2lRMlhMYVlEMzlvT3hFUjFxRHpkVHlWZS9tNXFlaTBHbHJidXJCMzlzd3UwcGFXMStGeWU5QnBOU3hlbURWakQ2K21MaUE2WnpEb0pqMTFQQzB0bmkvZWR6dTMzcndabjkvUFAxODd3RmUvOHpCUFB2M1dySElYeXNycitlNFBIK0hOblVmeCtmeGN0WDB0OTMveFE4Uk0wU2JDZU94Mlpub0NHbzJFeCtQbHpObUcyVU5hVlZVNVZueVd3VUUzZXIxdVJncS96OEVYeEtvbFFSQ3cyYXg4NlFzZjVEKys4bEdNQmgwTlRlMzg1NC8reEplKzhTQm5xeHJ4K21hbVprRlZBMjFOTzNZZDR4TmYvRzlPbktwRUZBU3V1ZW95dnZYMWV3aWZvZGI5OXlQZ0tscnhlSDNVMUxWTSt2T0NWcHJZYnUraHVhVVRSVkZadmlSM3hvWTNCd0tSZ0h0Z01oa3c2SU9YSjc1cSsxcUtGbVh6aDBkZTRNalJNbmJ1T2NHQnd5WGNkdU5tcnJ0eUxha3BjVVNFVzZhbDFzTGw5bkRtYkFQUHZMQ2JmN3l3QzFFVVNJaVA1b08zYitYRzZhZ1BIaWVXRk9WUVU5OFdsRzZSb0pHMnJyR05sclpBT2VLR3RVVXplb01xcWdJVlpoYUxFVU9RZnp4SmlURjg3Y3QzOGZJcmUzbjBpZGV3ZC9ieTZOL2ZZTWV1WTZ4WldjamFsWVdzV2JsZ1NvZVNIRDlaeWR2dkhPZU50NDlRMzlpT0lBaXNYYjJJbTI3WXhNb1ZCWk4yaVViRFJCUXdWeTByNE9rWGRnOEx1Rmdta1M4T0Nta1ZSYUd5dW9tV29SSDFXemV2bUZIU1R2VitqOWxzWk9uaVhQNzV5ajdzbmIyQnpZeTJUcDUvZVErNzloYVRsaEpMZm00YW05WXZZZVd5L0VrOW9IUG82M2R5OEVncHIrMDR6Sm1LZWhxYk8vRDUvS1FreDNIRDlSdTVZdE55NG1JanA2VjJlU0lyeVRtaFpjZkFJTDI5QXpOUDJyNStKNmRMYS9ENS9LeGVVVEJ0WXNBWDg2M2IyM3VHM0FOalVOMkRkMzhVS2hxTmRFRjJSRkZVdW5zQ3F0b25TMnA0N3A5N3NGaU1MRm1VellaMWkxbStPSWZjN0xHTHpOWFd0M0x5ZEJYdjdEL0ZzWk1WZFBjNDhIcDlxS3FLelJiR3JUZHY1b1pyTnhJUllSM3pybDh3TUpIczJiTEZ1UUhYelRGSVYwOC95VWt4TTB2YW5sNEhwMG9EMmszYlp0akt5cXBLUyt0UUFialpPR1crZFZKQ05IRXhOc3FHRkFkSFduM2NIaTl1ajVjZHU0NmRONG96UFRXZWNLdVo4SEF6cWNubmE5RlcxalRoY0RocGJPNjRRSnhZRkFVSzhsSzVZdE5LdG05Zk0yTVRneWJTcUNwSklucTlGcjlmbnZUNDFLQ1F0cjZ4bmNabU95YWpudVZMOHBqL0VBZ1BzNUNhSEl0R0k0MDdZVjdYMFBhZWY1MGFkU21PaTQxRXA5WGdjbnQ0N0hmZkJvMEdqMy9teEVha0NRYWFCYmxwTkRiWjZlenFtM25TdnIzN09ENmZueFZMODRpUGk1cFJPcDJyN3BwcUYwUlJWV3hEeS9KVXpSZ0lzNXJaZHNVS05tMVl5dTY5eFpSWE5DQ0tJdjRaRnRDVHhKa2Q5RGxwMGpvSDNienk1aUVBMXExYWdNVXlzekx4alUyQnVnT2pVVCtsRWJ5S1NwalZQRlRGRnR3ZlNwUXRqSnV1MjhEVlc5ZVFNaVJHL2ZZN3gwbE9qRUVTUlh3elRscGhicFAydFIySGNBd01FaFVaUmtGZU9qcnR6QTVOUHRlY0tJa2lXdTNVcG41aW9pTXUyUlV4TGo5UkZCQUZrWS9kZFJXMzM3VDVQUG4zTm5zM2ZYMU9MQ1pEWUN0cUJqbXJFV2QrblBLa0dPYnorWWZudGhZdHpDSXZPMlhHTDJqYXRHZlZkNFhZSkVraU9UR2FscmF1Y1FVWm9pQVFhUXNqSlRtV2pldUt1UDNHVFNOdXU3cmRYdnI3QjBoT2pBNEVRZXJNZFZUTWhGcFFVRWxiWHRIQTBSTm4wZXUwTE1oUEp6bzZmTVl2cUdlb1dFYVV4Q2xOc2lzd1BPbEZyOU55eDgxWFVGUFh3dXR2SFJsMUpKSFZZaUl2SjRYOG5GUldMTTFqMWZJQ29pOHhITkR0OXRMbkdDUTIxb1lvQ3NnemFHa2xhWTZUOXZraGZkUG9xSERXckNpY2NRY2RHQmJkME90MTJDS21ObCtzMDJvUWh1Ykl4c2RHY3RPMUc3aHM5VUtlZm1IM0JUS1hacE9CaFlVWkxGMlVROUhDTERMVEUwaE1pQjVUSHRuN0h0blVhVjFOUm9CMkxyc0hUUzBkSEJscVJjbkpUaGxPSHM4MHpuWFJpcUtBUmp1MXBaR0ppZEZvdFJvODNuZjcwYTdhdXByMWE0c29QbFhKemowblNFbUtaV0ZoQnVtcENSZ01XZ3g2UFRxZFprYTBJQ1lMUVJCbVJPSXFLS1JWZ1VOSHo5QTJaTld1MmJabXhtcG5MeUN0TWoxV1NGVlZSRkc4b0VSUEZFWEN3OHhjdm40Smw2OWZFdVR2RE54N1NSUlJWSVhwTnJpU0lEQnB5Z293MmQvcmhHeTl3ekhJL2tNbDlQWU5FQnRqWTNPUUg4NWs0Qm5TT3hCRkVhMUd3M3hDZDNjL3FxSVNidFJoMFduUmF5UzZ1L3RvYSsrYXBzeUJ3R1JvMjljM2dOR2d4MnlhWEZwMFFrKzFzcnFKVTZXQlhyQTdiOXRDV0poNTFqelljdzlRcjlNR3ZXTC92Y3VrVGlOTld5U3QwMmt4bTQxMGR2V2hxQ29Db05OSWVGd2UvdnlYbDJodTYyTDl1c1ZjdHJhSTJDbk1UVXVpT0NrcldkdlFSazVXOHFSeitlTW1yZGZuNS9pcFNwcGFPb2dJdDNMbnJSK1lWZGJvM0p3d1NSTFI2YWZHMGhxMUVucEpZcnJjVW9OQlI3alZoTDJ6NXp3QkVVRVU2T2pvWWYrQlU1dzZWY25yYng1azgrWEx1WHpqMHFEdlRJcUNNS2xOaFdET2J4djNVeDBZY1BIT3ZwUElzc0oxVjYyZHNjRjJGL1ZucDlqUDAyc2tqTk84Z1dJdzZBZ0xNOVBjMG9uNkhwL2RZamJ5ME0vdTU4Q1JVaDc2dy9NY0s2N2dkRWsxLy9mdzAyeTVZaVZYYjEvTGtzVTVRZGxra1VSaFVpdkwyYUVhNTBpYmRkSTdsZU8rKzVVMVRSdzZXa1o0bUptcnQ2NlpkWDZmK3A0bGZLVEJ3NU54Q2ZTU2lNL3Q0ZUhIWHlVbU9vTDgzTlJwdVNhenlVQ2tMWXkzZGgvSDdmR2UxNnlwMFVoc1dGdkVtaFdGSEQxeGxxZWUyMGxKZVIxNzl4YnoydXNIaUkyeHNXYjFRamFzWDBwYWFoeGhWak5tczNIY2diTW9DRXdtY1hCdXBwZ2tTV2dtR1d1TSsrakhuOW9Cd01wbCtUTXlwSGswOVBZRjVpd0VNMDhyQ2dKR3JVUlhaeSsvZnZnWm5udHBEMWR0WFUxY3JHMWFKSWJNSmdPeE1ZR05oY3JxWmxhdnVMQTFYNnZWc0hiVkF0YXVXa0JWVFRQN0Q1ZFFmS3FLaGlZN08zY2Q1Y1dYOXBDU0hFZGhRUWJaV2Nta3B5ZXdmdDNpc1FiOGFFUnhVbW02MDBPbHExYUxDVnVFWmZwSVc5L1l6dTY5eFZqTVJqYXVLNXJSWXUrTEJtSkQzUk1hU2NKZzBBV0hzRG9OOXJaT2Z2blEwN3owK2dHaUlzTzQvTExGREE2NnA2ekM2LzFwdEppb2NJd0dQYWRLcWxtOW91Q1M3OC9PVENJckk0bWJyOXNZRURWdWJLT3lwcGtUSnlzcHFXemtTRU1udHJCSzhwY3RRQklnVENkZHN0eFFtS1EvQzlEUTFJNUdJNUVZSHpYcCtRdmpJdTFqZjM4RGw5dkRndngwRmkvTW5oR2Rya3NoMkZaUEVrVXNlZzJWVlUzOCtCZVBjL1I0UUpEdTN6OS9COWRzVzhPdXZTZW5iWGNxTFNVT1c0U1ZBNGRMK2VROTE0N0JuUW40dkhrNUtlVGxwTkRYNzhRV1llR2VHei9BVVk4R2g5ZlBIODkwREZuUndFNVhyRkdEUlNzUlo5SmkwMnVJTjJvd2F5VWtVVUF6eWM2STAyVTE2TFNhU1hVc2pKdTA3Zlp1WG5obEg1SW9VclFnazRLOHRGbnJ6NTZMckNlVlp0SklHQ1NSOHZKNnZ2THRoNmh0YUVXbjAvS3o3MzJPNjY1Y0YvaVJLSUVFdjFhaklUYzdlVXF2TFRFaG12QXdNM3NQblI3Ny9WQlZIQU11SG5uc0ZSNSs1RVdpSXNNSVg3UUFmM1FpQmdQMGVmM25iVkMwT0MvVWNZalFhMGcwNnlpS05wTnJNeEZsMEtBUkJUU0NNT2JzU1dkbkx4MmR2V2cwR3VLQ29NTXdadEsrK09wK0JsMGV3c1BNWExWMU5iTVJBUktwQ0FJVDFoR1RCQUc5VnNMUk44QnpPdzd6cy8vOUcyNlBqOHowUkw3NDZWdk91L2JtMWs1OFB0K1VsMEFDeE1YWWlJbU9JSHlNT1hGRlVUaFQwY0Fqajc3Q0d6dVBCRnAxY3RPNG9paURUcDBKcjZMUzU1RnhlUDM0RkJXdm91S1JGZnlLaXN1djRKWVZaRVdsMStPbjErT25yRHRRQkJScDBKQVZicVFvMmt5Q1dVZWtJV0NkTHgyOE4rUHp5UmlOT2dyeTBxZUh0TDE5QXh3OFVvclA1eU0zSjRmRkM3Tm5KV243ZWdlR2hETUU5UHJ4RWVsY3dsNEN5cy9VOHZoVE8zajF6WU1vcXNxeXhUbDgvcE0zc1hwRjRYbkhPQWZkeUlxS1RtREtkUjVNSmdNZnVuVUwyNjlZT2VwN3ZWNC9iK3c4d3FOL2UyTllLL2lETjEvQlhYZHNKVE05OGNMSTNxOHc2Sk54K0dUY2ZvVmVqNTgrcjB5UDI0L0Q1NmZiNWFmZDVjUHBrK2wyKytsMk96aHVIeURhcUNFanpFQldoSkU4bTVGNDA4Z3h4S25TYWp4ZUh3bnhVY1RIUlU0UGFVdkthcWl0YjBOVjRlYnJOczZvRU1lbDRCeDBJVThnTU5KS0lnYU5oQUE4OWR4Ty92N00yMVRWTk9PWFpXNjZkZ09mdXVjNk10SVNMaWdXYWJkMzQvZjVrY3hHNG1JanAvejZObTlZT3VwN1d0cTYrTjJmLzhtT25VZXhkL1lTRXhYQnZYZGZ3eTNYWDM3UmtVOG1qWWhKSXhKdFBQK0g3cEVWUExLQzA2ZlE3NVZwRy9SUzIrZm1iSStMTHJlUDlzSEFxN2pUU1lKWng4SW9NK3NTd29neXZFc3JuMSttckx3ZW44L1A0b1ZaUVNtYUg1VzBzcXh3NG5RVkxhMmRXTXdHcnQyK2x0a0tSVlhIdGJjZ2lnSW1yUWFkSkZMZjJNNFBmL1lZQnc2WDR2WDZzTm5DK05aWDdtTHI1aFVYTFI5MHU3MG9xb3JWWXB6eGpnMVpWamgwdEl6LytmWGZLSzlzUUpZVmtwTmkrUFpYUHNMR2RZc25WTkNrbDBUMGtraVlEaExNa0JOaFpGMUNHRjVab2M3aFlWZFRIMlZkVHR4K2hkbytOdzM5SGc2MDluTk5laVNYSlFiU2NxMXRuYlMyZDZHcUt1dFdMUWpLdFk1NnB6czZleWs5VTR1aXF0eHgweFd6cHBwcjVNRGozYjlUVStJdm5yNFJCQXhhQ1dTWjVxWjJYbnhsUDMvOTIrc01PRjJZVFFiV3J5M2lTNSs5bGR6czVJdm1KdHZzM1hRTktWdm41NlRPS0ZrN3UvdDQ1c1hkL1BHdnIrQVlHTVJvMEZPME5KUHZmK3NUcEtmR0J5LzFKZ1JTZ0ZwUllrR2tpUVdSSmxxZFhnNjFPVGpRMW8vREs5UHA4dkdYTSswY3N3OXdlMjRNWlJXTnRMWjFvWkdrVVZOMVFTTnRTMXNucFdmcTBPdTFYSGZWT3VZQ0JEZ3ZSM3R1MzF3U0JMUWFpWjd1UGtwcm16bGVYTUVMcis2bnZxRU5nMEhIaXFWNVhMMXREVmR2WFUza0tOcTZmcjg4bktPTmk0dWM5bXRVRkpWMmV6Y0hqNWJ4MXlkZnA3UzhEbEVVeWMxTzV0cnQ2N2pudzFkT2lWREorNUZnMW5GalZoVHJFc1BZM2RUSHFjNEJPbHgrU3JxYzJJdTl5UFZkOUx1OUxDak1DSnBPZzJiVUNQUnNBKzBkUGF4WW1rZHFjdHlzSm10UGIwQ0JCUUUwZ29oZUk2RVJSU1JSUUZFVVRwZFVVM3k2aXVNbkt5ZzVVMHRiZXplU0pGS1lsODYxVjYxank4YWxaS1Fsak9tNzNCNHZYbCtnK0h2OW1rWFRlcDBlajQrMzl4em5wZGNPY09ob0dmMk9RYXdXRTFkdFhjM04xMjBZeXFGUGI0ZEJyRkhMRFpsUkxJNDJzNmU1ajBQdER1d3VIOTZJR09KV3IrQzJkY0ZyRXRDTXR2UVVuNjRFWU9PNnhlZ04ybGxOMmtHbmE5ajY2VFFTZ2l4VGVxYUdveWNxMkxQL0pNMnRuZlQwT25DNXZhaXFTazUyQ2grOVl5c3JsK1dUbkJnenJwNnlsTVFZN3J2M0pueGVIMnRXRms3Yk5lNDVjSW8vUC9FYVo4N1cwOTNqUUZFVWlnb3p1ZStUTjdGc1NTNWhWdE9NZFVYb0pJRmNtNUVFczQ2TWNBUFBWblZDbUpXVXk5ZmlUYkZORDJuOWZwbDloMHF3V2sxRGtkL3NMcW9XaGw2cUNydjJudUMvZi9VRWZmM084L3haUVJCWXNUU1B1ejkwSmR1dW1MaUVrMTZ2WTlNMEZMK3JLdmo4ZnZZZkt1SG4vL2NVWnlzYmgzTFJBcllJS3grLzZ5bytkYzkxcytvNVdIVVNtMU1paURacWVhemNUaS93am4wUWZXVW50K1pFVDdyN1FUTmErcVN6cTI5SU9TYVN1WVIrcC9zOHdzYkcyTGp4bXZWY3UzMHRPVm5KMDc1OGpvK29LZ05PRjIzdDNadzRWY25mbjkifSwiZGlnaXRhbFRyYXZlbENyZWRlbnRpYWwiOnsiZFRDQ29udGVudEluZm8iOiJNSUlEU0RDQ3h4eHh4eHh4eHh4eD09In0sImRvY1NlY3VyaXR5T2JqZWN0Ijp7ImRpZ2VzdEhhc2hBbGdvcml0aG1JZGVudGlmaWVyIjoic2hhMjU2IiwidmVyc2lvbk51bWJlciI6IjEiLCJkYXRhR3JvdXBIYXNoIjp7Iml0ZW1zIjpbeyJkYXRhR3JvdXBOdW1iZXIiOiIxIiwidmFsdWVCaW5hcnlPYmplY3QiOiJaR1E1T0dNNFpEVmxOVGRsWmpWallqWm1PVE5oTURBMlpUTTBOVGc0TWpObE16STRNV1ppWVdWak9UVTRNakkzT0RoalpqQmxOVGszTnpRek5qYzRPQT09In1dfX19LCJfc2QiOlsiZWxlY3Ryb25pY1Bhc3Nwb3J0LmRhdGFHcm91cDEuYmlydGhkYXRlIiwiZWxlY3Ryb25pY1Bhc3Nwb3J0LmRhdGFHcm91cDEuZG9jVHlwZUNvZGUiLCJlbGVjdHJvbmljUGFzc3BvcnQuZGF0YUdyb3VwMS5leHBpcnlEYXRlIiwiZWxlY3Ryb25pY1Bhc3Nwb3J0LmRhdGFHcm91cDEuc2V4Q29kZSIsImVsZWN0cm9uaWNQYXNzcG9ydC5kYXRhR3JvdXAxLmhvbGRlcnNOYW1lIiwiZWxlY3Ryb25pY1Bhc3Nwb3J0LmRhdGFHcm91cDEuaXNzdWVyQ29kZSIsImVsZWN0cm9uaWNQYXNzcG9ydC5kYXRhR3JvdXAxLm5hdGxDb2RlIiwiZWxlY3Ryb25pY1Bhc3Nwb3J0LmRhdGFHcm91cDEucGFzc3BvcnROdW1iZXJJZGVudGlmaWVyIiwiZWxlY3Ryb25pY1Bhc3Nwb3J0LmRhdGFHcm91cDJFbmNvZGVkRmFjZUJpb21ldHJpY3MuZmFjZUJpb21ldHJpY0RhdGFFbmNvZGVkUGljdHVyZSIsImVsZWN0cm9uaWNQYXNzcG9ydC5kaWdpdGFsVHJhdmVsQ3JlZGVudGlhbC5kVENDb250ZW50SW5mbyJdLCJjbmYiOnsia2lkIjoiZGlkOmp3azpleUpoYkdjaU9pSkZVekkxTmlJc0luVnpaU0k2SW5OcFp5SXNJbXQwZVNJNklrVkRJaXdpWTNKMklqb2lVQzB5TlRZaUxDSjRJam9pY0hsd2IzSXhWa3RDVFdaNFVuSnpUM1J2Tm5KZmIybFpNMVp1UWxZNVNXdElZWFIyZFVsQlJrOUdkeUlzSW5raU9pSlRjV2RCWlhwWlozYzFkRVl6YlZOeVFVNHljMlI1VUZreGVGSjNXa2RHUzNaUWQzTTVNR1p1TlhWVkluMCMwIn0sImlzcyI6ImRpZDp3ZWI6YWdlbnQubmIuZGV2LnNwaGVyZW9uLmNvbSIsImlhdCI6MTcyNjgyNDAwNy43NzYsIl9zZF9hbGciOiJTSEEtMjU2In0.Lykk_21xf1jfaWyeFyPMABSJzcNfzMvLhwxD6VmhHhlDccMl1WA1xZ_qHXbWa4Ky43X9DE3Mqa7aKENESoMUzg~ +eyJ0eXAiOiJ2YytzZC1qd3QiLCJraWQiOiJkaWQ6d2ViOmFnZW50Lm5iLmRldi5zcGhlcmVvbi5jb20jMDJkMWM2ZDY5ZGFjYjQxZTYwODk5YTdlOGNkYTM5ZjEyYTI2NjZmYzljMzRjNDM3YjFmNzRmNjFjZjUwZDk1YzYwIiwiYWxnIjoiRVMyNTYifQ.eyJlbGVjdHJvbmljUGFzc3BvcnQiOnsiZGF0YUdyb3VwMSI6eyJfc2QiOlsiQm12YXloQ3ExeUJWZ0tWbi1IRURVYnM2SnhZcDQ2RXpYRFFjeTU0TklwWSIsIkRaRjk5S3c2UWFILVBCdUtkRThiNVRpeDZGckpDcURLRHd3UjFOM0lYRFkiLCJGNy1vZm1MbjJIRmQzblNPLTlyRzZEQ0dJYWMwNUQ3Zmh0cDZoYWUzYzBVIiwiTG55ajhWcUJWdU5XWU5jWFJZaXpZRUE2c0J0TDdsY3ZXMFJkeWFXLWh0YyIsIk5LdkZOTWdwSDRrdnp6TzJQRkYyWURwZWpuUWJ0ZWdSeGFSYTJZbS1ZZWMiLCJicXVYTWF0Y2lOeEJCMXl0Wlk0WWtwSEhYZ1QxN1dKM2NCbndxYXFKY0hZIiwibDYwV3l6YVVpU0NoblRuaGZFdHVWUjM1WWJOdUJldDg3WnFkeWtOeXAtcyIsIm9PV1JPT2pfMVR1S1FJR3VGSzJoVzN1WFhBalpGZDVpb2VxWlRZS1NrakUiXX0sImRhdGFHcm91cDJFbmNvZGVkRmFjZUJpb21ldHJpY3MiOnsiX3NkIjpbInh2bHBRdTlIQlJPaWJGV2JNOVZST3BBOGRJaVFIT3lnYm1TOTlXLTQ5bUkiXX0sImRvY1NlY3VyaXR5T2JqZWN0Ijp7Il9zZCI6WyItQy1aQzltaXBmcU8yNTlCLTc5Uk44WVNEQnY4LTQyM0xseFZJWHBGWjJRIiwiRDlLUWdEQ29WNDctY0dVUzlzU1BsajFxem5WMnJ2MF9KYlJYSF9BTGszSSIsIkc0cC1tTnRWYkhXTHdGRkhldW04YkpiXzVadkRlWjBxYzhZcXJDbVU1aVkiXX0sImRhdGFHcm91cDE1Ijp7ImFjdGl2ZUF1dGhlbnRpY2F0aW9uIjp7Il9zZCI6WyJTbUxHdEVEZDgyOUo0NGk0ZnJwRU1nMldUTzY2MmRoNHNRdWw1VGVzNHVnIl19fSwiZGlnaXRhbFRyYXZlbENyZWRlbnRpYWwiOnsiX3NkIjpbIlJGNVI2ODVfc0pQYzFhSTQxUktHYllZRkROcy1ZaUJNenZOTUNNakkwZHciXX19LCJ2Y3QiOiJlcGFzc3BvcnRfY29weV92YyIsInR5cGUiOiJlcGFzc3BvcnRfY29weV92YyIsImV4cGlyYXRpb25EYXRlIjoiMjAyNS0wOS0yNlQxNjowMDozMi44MjRaIiwiY25mIjp7ImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGVXpJMU5pSXNJblZ6WlNJNkluTnBaeUlzSW10MGVTSTZJa1ZESWl3aVkzSjJJam9pVUMweU5UWWlMQ0o0SWpvaVdVTTVhRTFrZVVOU1ZYQndibXB6V25sUGJIbDJkbXBDWTJKTmRXNU5iM1p4ZFMxSlZVSlBkMVZoWXlJc0lua2lPaUptZVc5WFJFOVpNR1pYUkhSaVduTjRlRXMwVlhKTVpHYzVjMkpMUlhscWExZDNVMDk2ZFVReExVdG5JbjAjMCJ9LCJpc3MiOiJkaWQ6d2ViOmFnZW50Lm5iLmRldi5zcGhlcmVvbi5jb20iLCJpYXQiOjE3Mjc3OTg0MzIsIl9zZF9hbGciOiJTSEEtMjU2In0.8qEexTgk2grLk8sC01SS6wid7nKPoDdOxQHbalazTo3F83PE2alcJWOHyJSa2cIXEAqMGgcqCXd_XljuWKYG8Q~WyIwMDY0NDUzNS03YWM3LTRmZDctYmZlMi01MmQ1MTRmZTAzYmYiLCJiaXJ0aGRhdGUiLCIyMDI0LTEwLTA5Il0~WyI0ZmNiOTA5Ny1kOGI2LTQzODEtYTM5Yi1lYjgxZjBkOWUxNDgiLCJleHBpcnlEYXRlIiwiMjAyNC0xMC0xMCJd~WyIzODY4ZjNlMS02NzY4LTQ0OTAtYjI2NS03NGI4N2IxNmRiZWUiLCJzZXhDb2RlIiwiZGQiXQ~WyIyZDc4NGVhZC03ODM3LTQ2NmItOTczMS02MTMwYmNiMmIyOTEiLCJob2xkZXJzTmFtZSIsImRkIl0~WyJmZTY3YmU4YS1iNmZmLTQ1MTAtYWRlZi0yMDMyMmRjMjdkZWUiLCJpc3N1ZXJDb2RlIiwiZCJd~WyI4MTYyODBiMC1hNTE3LTQwZjYtYjk4Yi02N2M1ZTBiZDlhMTIiLCJuYXRsQ29kZSIsImQiXQ~WyJjZWQ2OWEwMS0wNjhjLTRlZmUtYTM3Ni0yOTYyMjgxMGIxZTkiLCJwYXNzcG9ydE51bWJlcklkZW50aWZpZXIiLCJkIl0~ diff --git a/test/dif_pe_examples/vc/vc-iata-order-sd.jwt b/test/dif_pe_examples/vc/vc-iata-order-sd.jwt index f555e426..71f4c30e 100644 --- a/test/dif_pe_examples/vc/vc-iata-order-sd.jwt +++ b/test/dif_pe_examples/vc/vc-iata-order-sd.jwt @@ -1 +1 @@ -eyJ0eXAiOiJ2YytzZC1qd3QiLCJraWQiOiIwMmQxYzZkNjlkYWNiNDFlNjA4OTlhN2U4Y2RhMzlmMTJhMjY2NmZjOWMzNGM0MzdiMWY3NGY2MWNmNTBkOTVjNjAiLCJhbGciOiJFUzI1NiJ9.eyJ2Y3QiOiJPcmRlciIsIm9yZGVyIjp7ImdpdmVuTmFtZSI6IlRlc3ROYW1lIiwic3VybmFtZSI6IlRlc3RTdXJuYW1lIiwidGl0bGVOYW1lIjoiVGl0bGUiLCJvcmRlcklkZW50aWZpZXIiOiIxMjM0NSIsInBheFNlZ21lbnRzIjpbeyJkZXN0U3RhdGlvbklBVEFMb2NhdGlvbkNvZGUiOiJITkwiLCJmbGlnaHRJZGVudGlmaWVyRGF0ZSI6IjIwMjQtMTAtMDEiLCJvcGVyYXRpbmdDYXJyaWVyQWlybGluZURlc2lnQ29kZSI6IktMIiwib3BlcmF0aW5nQ2FycmllckZsaWdodE51bWJlciI6Ijc3NyIsIm9yaWdpblN0YXRpb25JQVRBTG9jYXRpb25Db2RlIjoiQU1TIiwiYm9va2luZ1N0YXR1c0NvZGUiOiJDb25maXJtZWQiLCJzY2hlZHVsZWRBcnJpdmFsVGltZSI6IjIwMjUtMDEtMDEiLCJzY2hlZHVsZWREZXBhcnR1cmVUaW1lIjoiMjAyNC0xMC0wMSJ9XX0sIl9zZCI6WyJvcmRlci5naXZlbk5hbWUiLCJvcmRlci5zdXJuYW1lIiwib3JkZXIudGl0bGVOYW1lIiwib3JkZXIub3JkZXJJZGVudGlmaWVyIiwicGF4U2VnbWVudHMub3BlcmF0aW5nQ2FycmllckZsaWdodE51bWJlciIsInBheFNlZ21lbnRzLnNjaGVkdWxlZEFycml2YWxUaW1lIiwicGF4U2VnbWVudHMuc2NoZWR1bGVkRGVwYXJ0dXJlVGltZSJdLCJjbmYiOnsia2lkIjoiZGlkOmp3azpleUpoYkdjaU9pSkZVekkxTmlJc0luVnpaU0k2SW5OcFp5SXNJbXQwZVNJNklrVkRJaXdpWTNKMklqb2lVQzB5TlRZaUxDSjRJam9pY0hsd2IzSXhWa3RDVFdaNFVuSnpUM1J2Tm5KZmIybFpNMVp1UWxZNVNXdElZWFIyZFVsQlJrOUdkeUlzSW5raU9pSlRjV2RCWlhwWlozYzFkRVl6YlZOeVFVNHljMlI1VUZreGVGSjNXa2RHUzNaUWQzTTVNR1p1TlhWVkluMCMwIn0sImlzcyI6ImRpZDp3ZWI6YWdlbnQubmIuZGV2LnNwaGVyZW9uLmNvbSIsImlhdCI6MTcyNjgyMzk2NC4yMiwiX3NkX2FsZyI6IlNIQS0yNTYifQ.mCwhA-JV368G_f2FkAOO3DCixx3Nk-sq1jAu-tph-KMHboyvEIQwB7UJdHR38ZKbhWHLNsY0uFdVFCelTTPY1w~ +eyJ0eXAiOiJ2YytzZC1qd3QiLCJraWQiOiJkaWQ6d2ViOmFnZW50Lm5iLmRldi5zcGhlcmVvbi5jb20jMDJkMWM2ZDY5ZGFjYjQxZTYwODk5YTdlOGNkYTM5ZjEyYTI2NjZmYzljMzRjNDM3YjFmNzRmNjFjZjUwZDk1YzYwIiwiYWxnIjoiRVMyNTYifQ.eyJvcmRlciI6eyJfc2QiOlsiWjhWVGlZd2tTa3lHaC1yMWNQSVlwRTJjNVpfS1dtU0pnQlJjUkNpVlJJVSIsImJBRFQtRFZTam5HZnVvdnItRHFVYUxPaGVvOUpKMWxDUDBKMjh2dkRoU0EiLCJmQmVzN2lIRU85VUxMSGRQRnpyRHBYenExbzdpSXhYOVBzNTViS3lCN0h3IiwiaDlablNxU2FkbGxmWEcxaHhWOFRsMEdqdkFBM1lEMzItaHg4MHZhSW9UMCIsInNKWWxiMmQ1czdaLTBpTG1FSUdPTERaODhVeC1hd2lGeThzU0M1OWk4NUUiXX0sInZjdCI6Im9yZGVyX2lkX3ZjIiwidHlwZSI6Im9yZGVyX2lkX3ZjIiwiZXhwaXJhdGlvbkRhdGUiOiIyMDI1LTA5LTI4VDAyOjExOjMzLjQ1NloiLCJjbmYiOnsia2lkIjoiZGlkOmp3azpleUpoYkdjaU9pSkZVekkxTmlJc0luVnpaU0k2SW5OcFp5SXNJbXQwZVNJNklrVkRJaXdpWTNKMklqb2lVQzB5TlRZaUxDSjRJam9pV1VNNWFFMWtlVU5TVlhCd2JtcHpXbmxQYkhsMmRtcENZMkpOZFc1TmIzWnhkUzFKVlVKUGQxVmhZeUlzSW5raU9pSm1lVzlYUkU5Wk1HWlhSSFJpV25ONGVFczBWWEpNWkdjNWMySkxSWGxxYTFkM1UwOTZkVVF4TFV0bkluMCMwIn0sImlzcyI6ImRpZDp3ZWI6YWdlbnQubmIuZGV2LnNwaGVyZW9uLmNvbSIsImlhdCI6MTcyNzkyMTQ5MywiX3NkX2FsZyI6IlNIQS0yNTYifQ.2J_jrFZcuITiAYlAwDx_KmBoSHIwyIl-sy0B6-lt5kJpyZBaEjDS5fKeufiLFL30abiqKT1W03Y5tyDoNuDgjQ~WyJiZDZhMjRjMi01ZjZlLTQ1MjItODdiZC0zYjk4NTA5OWNiNWUiLCJwYXhTZWdtZW50cyIsW3siZGVzdFN0YXRpb25JQVRBTG9jYXRpb25Db2RlIjoiSUFUQTMyNjIzNiIsImZsaWdodElkZW50aWZpZXJEYXRlIjoiMzAxMDIwMDAiLCJvcGVyYXRpbmdDYXJyaWVyQWlybGluZURlc2lnQ29kZSI6IklBVEE0Mzc2NDU4NDU4Iiwib3BlcmF0aW5nQ2FycmllckZsaWdodE51bWJlciI6IjIzNjUiLCJvcmlnaW5TdGF0aW9uSUFUQUxvY2F0aW9uQ29kZSI6IklOMzQ2NzciLCJib29raW5nU3RhdHVzQ29kZSI6IkNORiIsInNjaGVkdWxlZEFycml2YWxUaW1lIjoiMzAxMDIwMDAiLCJzY2hlZHVsZWREZXBhcnR1cmVUaW1lIjoiVEVTVDMyNjM0NjcifV1d~ diff --git a/test/evaluation/selectFrom.spec.ts b/test/evaluation/selectFrom.spec.ts index d4462101..d153fab1 100644 --- a/test/evaluation/selectFrom.spec.ts +++ b/test/evaluation/selectFrom.spec.ts @@ -1,3 +1,4 @@ +import { SDJwt } from '@sd-jwt/core' import { createHash } from 'crypto'; import fs from 'fs'; @@ -1011,7 +1012,7 @@ describe('selectFrom tests', () => { expect(result!.matches![0]!.name).toEqual("Name on driver's license"); }); - it('iata test1', function () { + it('iata test1', async function () { const pdSchema: InternalPresentationDefinitionV2 = getFileAsJson('./test/dif_pe_examples/pdV2/pd-multi-sd-jwt-vp.json').presentation_definition; const vcs: string[] = []; vcs.push(getFile('test/dif_pe_examples/vc/vc-iata-order-sd.jwt').replace(/(\r\n|\n|\r)/gm, '')); @@ -1027,6 +1028,10 @@ describe('selectFrom tests', () => { pex.evaluateCredentials(pd, result.verifiableCredential!); const presentationResult = pex.presentationFrom(pd, result.verifiableCredential!); + const cred = await SDJwt.fromEncode(presentationResult.presentations[1].compactSdJwtVc, hasher) + const claims = await cred.getClaims(hasher) + console.log(claims) expect(presentationResult).toBeDefined(); + // TODO finish test }); }); From fe717b8d615391771bcca7fc35a1fb4887d8e158 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Mon, 7 Oct 2024 10:37:04 +0200 Subject: [PATCH 31/47] chore: reverted to 'fixes' --- lib/evaluation/evaluationClientWrapper.ts | 4 ++-- test/SdJwt.spec.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/evaluation/evaluationClientWrapper.ts b/lib/evaluation/evaluationClientWrapper.ts index 0e1f4a5f..44a07a2d 100644 --- a/lib/evaluation/evaluationClientWrapper.ts +++ b/lib/evaluation/evaluationClientWrapper.ts @@ -940,7 +940,7 @@ export class EvaluationClientWrapper { private updatePresentationSubmissionToExternal(presentationSubmission?: PresentationSubmission): PresentationSubmission { const descriptors = presentationSubmission?.descriptor_map ?? this._client.presentationSubmission.descriptor_map; - const updatedDescriptors = descriptors.map((d, index) => this.updateDescriptorToExternal(d, { vpIndex: index })); + const updatedDescriptors = descriptors.map((d) => this.updateDescriptorToExternal(d)); if (presentationSubmission) { return { @@ -1232,7 +1232,7 @@ export class EvaluationClientWrapper { // See https://github.com/decentralized-identity/presentation-exchange/issues/462 // Also see: https://github.com/openid/OpenID4VP/issues/69 if (d.format === 'vc+sd-jwt') { - //d.path = '$'; we do return multiple presentations now + d.path = '$'; } else { this.replacePathWithAlias(d, 'verifiableCredential'); } diff --git a/test/SdJwt.spec.ts b/test/SdJwt.spec.ts index bf5b4d3d..45a9c714 100644 --- a/test/SdJwt.spec.ts +++ b/test/SdJwt.spec.ts @@ -223,7 +223,7 @@ describe('evaluate', () => { { format: 'vc+sd-jwt', id: 'wa_driver_license', - path: '$[0]', + path: '$', }, ], id: expect.any(String), @@ -246,7 +246,7 @@ describe('evaluate', () => { }); }); - it('verifiablePresentationFrom and evalutePresentation with vc+sd-jwt format', async () => { + it('verifiablePresentationFrom and evaluatePresentation with vc+sd-jwt format', async () => { const presentationDefinition = getPresentationDefinitionV2(); const selectResults = pex.selectFrom(presentationDefinition, [decodedSdJwtVc]); let kbJwt: string | undefined = undefined; From 5d548f5d97a8b8d6d5480e65901983b077db360a Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Mon, 7 Oct 2024 10:38:24 +0200 Subject: [PATCH 32/47] chore: prettier --- test/evaluation/selectFrom.spec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/evaluation/selectFrom.spec.ts b/test/evaluation/selectFrom.spec.ts index d153fab1..3c44f9b0 100644 --- a/test/evaluation/selectFrom.spec.ts +++ b/test/evaluation/selectFrom.spec.ts @@ -1,7 +1,7 @@ -import { SDJwt } from '@sd-jwt/core' import { createHash } from 'crypto'; import fs from 'fs'; +import { SDJwt } from '@sd-jwt/core'; import { Rules } from '@sphereon/pex-models'; import { IVerifiableCredential, WrappedVerifiableCredential } from '@sphereon/ssi-types'; @@ -1028,9 +1028,9 @@ describe('selectFrom tests', () => { pex.evaluateCredentials(pd, result.verifiableCredential!); const presentationResult = pex.presentationFrom(pd, result.verifiableCredential!); - const cred = await SDJwt.fromEncode(presentationResult.presentations[1].compactSdJwtVc, hasher) - const claims = await cred.getClaims(hasher) - console.log(claims) + const cred = await SDJwt.fromEncode(presentationResult.presentations[1].compactSdJwtVc, hasher); + const claims = await cred.getClaims(hasher); + console.log(claims); expect(presentationResult).toBeDefined(); // TODO finish test }); From 5a9876933d0667fc7a8884e6cdc0c44bf87a97ab Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Mon, 7 Oct 2024 10:38:46 +0200 Subject: [PATCH 33/47] chore: version up --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6ea27e3e..23b8ac97 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sphereon/pex", - "version": "5.0.0-unstable.14", + "version": "5.0.0-unstable.15", "description": "A Typescript implementation of the v1 and v2 DIF Presentation Exchange specification", "main": "dist/main/index.js", "module": "dist/module/index.js", From f31ed177dcc467a6626754ee3982bf3938cc13a5 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Mon, 7 Oct 2024 10:54:38 +0200 Subject: [PATCH 34/47] chore: version up --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 23b8ac97..775c9666 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sphereon/pex", - "version": "5.0.0-unstable.15", + "version": "5.0.0-unstable.16", "description": "A Typescript implementation of the v1 and v2 DIF Presentation Exchange specification", "main": "dist/main/index.js", "module": "dist/module/index.js", From 8d6b394ec2d91aa9a5bf64d2df65d25a364ef0c8 Mon Sep 17 00:00:00 2001 From: Niels Klomp Date: Tue, 8 Oct 2024 02:25:55 +0200 Subject: [PATCH 35/47] fix: Remove matchAll polyfil as it has issues when running RN in debug mode. It was included only since RN did not have a proper matchAll function some time ago. --- .../handlers/uriEvaluationHandler.ts | 6 +- lib/utils/jsonPathUtils.ts | 5 +- package.json | 5 +- pnpm-lock.yaml | 64 ++++++++++++++----- 4 files changed, 53 insertions(+), 27 deletions(-) diff --git a/lib/evaluation/handlers/uriEvaluationHandler.ts b/lib/evaluation/handlers/uriEvaluationHandler.ts index f4c07f88..c42dcaa3 100644 --- a/lib/evaluation/handlers/uriEvaluationHandler.ts +++ b/lib/evaluation/handlers/uriEvaluationHandler.ts @@ -19,8 +19,6 @@ import { EvaluationClient } from '../evaluationClient'; import { AbstractEvaluationHandler } from './abstractEvaluationHandler'; export class UriEvaluationHandler extends AbstractEvaluationHandler { - static matchAll = require('string.prototype.matchall'); - constructor(client: EvaluationClient) { super(client); } @@ -220,8 +218,8 @@ export class UriEvaluationHandler extends AbstractEvaluationHandler { private static containsHashlink(url: string): boolean { return !( - this.matchAll(url, UriEvaluationHandler.HASHLINK_QUERY_URL_REGEX).next().done && - this.matchAll(url, UriEvaluationHandler.HASHLINK_URL_ENCODED_REGEX).next().done + url.matchAll(UriEvaluationHandler.HASHLINK_QUERY_URL_REGEX).next().done && + url.matchAll(UriEvaluationHandler.HASHLINK_URL_ENCODED_REGEX).next().done ); } } diff --git a/lib/utils/jsonPathUtils.ts b/lib/utils/jsonPathUtils.ts index 18296c71..bcd2f19e 100644 --- a/lib/utils/jsonPathUtils.ts +++ b/lib/utils/jsonPathUtils.ts @@ -4,7 +4,6 @@ import { PresentationDefinitionV1, PresentationDefinitionV2 } from '@sphereon/pe import { InputFieldType, IPresentationDefinition, PathComponent } from '../types'; export class JsonPathUtils { - static matchAll = require('string.prototype.matchall'); static REGEX_PATH = /@\w+/g; /** * @param obj: any object can be found in verifiablePresentation.verifiableCredential[i] @@ -121,7 +120,7 @@ export class JsonPathUtils { } private static modifyPathWithSpecialCharacter(path: string): string { - const matches = this.matchAll(path, this.REGEX_PATH); + const matches = path.matchAll(JsonPathUtils.REGEX_PATH); path = this.modifyPathRecursive(matches, path); return path; } @@ -139,7 +138,7 @@ export class JsonPathUtils { if (path.substring(atIdx - 2, atIdx) === '..') { path = path.substring(0, atIdx - 2) + "..['" + next.value[0] + "']" + path.substring(atIdx + next.value[0].length); indexChanged = true; - const matches = this.matchAll(path, this.REGEX_PATH); + const matches = path.matchAll(JsonPathUtils.REGEX_PATH); this.modifyPathRecursive(matches, path); } else if (path.charAt(atIdx - 1) === '.') { path = path.substring(0, atIdx - 1) + "['" + next.value[0] + "']" + path.substring(atIdx + next.value[0].length); diff --git a/package.json b/package.json index 6ea27e3e..d27c3d2b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sphereon/pex", - "version": "5.0.0-unstable.14", + "version": "5.0.0-unstable.17", "description": "A Typescript implementation of the v1 and v2 DIF Presentation Exchange specification", "main": "dist/main/index.js", "module": "dist/module/index.js", @@ -52,8 +52,7 @@ "ajv-formats": "^2.1.1", "jwt-decode": "^3.1.2", "uint8arrays": "^3.1.1", - "nanoid": "^3.3.7", - "string.prototype.matchall": "^4.0.10" + "nanoid": "^3.3.7" }, "devDependencies": { "@types/jest": "^29.5.12", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8fc8ab31..4ffa80fe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,9 +35,6 @@ dependencies: nanoid: specifier: ^3.3.7 version: 3.3.7 - string.prototype.matchall: - specifier: ^4.0.10 - version: 4.0.10 uint8arrays: specifier: ^3.1.1 version: 3.1.1 @@ -1877,6 +1874,7 @@ packages: dependencies: call-bind: 1.0.7 is-array-buffer: 3.0.4 + dev: true /array-includes@3.1.7: resolution: {integrity: sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==} @@ -1938,6 +1936,7 @@ packages: get-intrinsic: 1.2.4 is-array-buffer: 3.0.4 is-shared-array-buffer: 1.0.3 + dev: true /asn1.js-rfc5280@3.0.0: resolution: {integrity: sha512-Y2LZPOWeZ6qehv698ZgOGGCZXBQShObWnGthTrIFlIQjuV1gg2B8QOhWFRExq/MR1VnPpIIe7P9vX2vElxv+Pg==} @@ -2373,6 +2372,7 @@ packages: call-bind: 1.0.7 es-errors: 1.3.0 is-data-view: 1.0.1 + dev: true /data-view-byte-length@1.0.1: resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} @@ -2381,6 +2381,7 @@ packages: call-bind: 1.0.7 es-errors: 1.3.0 is-data-view: 1.0.1 + dev: true /data-view-byte-offset@1.0.0: resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} @@ -2389,6 +2390,7 @@ packages: call-bind: 1.0.7 es-errors: 1.3.0 is-data-view: 1.0.1 + dev: true /dayjs@1.11.13: resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} @@ -2478,6 +2480,7 @@ packages: define-data-property: 1.1.4 has-property-descriptors: 1.0.2 object-keys: 1.1.1 + dev: true /des.js@1.1.0: resolution: {integrity: sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==} @@ -2670,6 +2673,7 @@ packages: typed-array-length: 1.0.5 unbox-primitive: 1.0.2 which-typed-array: 1.1.15 + dev: true /es-abstract@1.23.2: resolution: {integrity: sha512-60s3Xv2T2p1ICykc7c+DNDPLDMm9t4QxCOUU0K9JxiLjM3C1zB9YVdN7tjxrFd4+AkZ8CdX1ovUga4P2+1e+/w==} @@ -2721,6 +2725,7 @@ packages: typed-array-length: 1.0.5 unbox-primitive: 1.0.2 which-typed-array: 1.1.15 + dev: true /es-define-property@1.0.0: resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} @@ -2737,6 +2742,7 @@ packages: engines: {node: '>= 0.4'} dependencies: es-errors: 1.3.0 + dev: true /es-set-tostringtag@2.0.3: resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} @@ -2745,6 +2751,7 @@ packages: get-intrinsic: 1.2.4 has-tostringtag: 1.0.2 hasown: 2.0.2 + dev: true /es-shim-unscopables@1.0.2: resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} @@ -2759,6 +2766,7 @@ packages: is-callable: 1.2.7 is-date-object: 1.0.5 is-symbol: 1.0.4 + dev: true /escalade@3.1.2: resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} @@ -3165,9 +3173,11 @@ packages: define-properties: 1.2.1 es-abstract: 1.22.5 functions-have-names: 1.2.3 + dev: true /functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true /gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} @@ -3210,6 +3220,7 @@ packages: call-bind: 1.0.7 es-errors: 1.3.0 get-intrinsic: 1.2.4 + dev: true /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} @@ -3275,6 +3286,7 @@ packages: engines: {node: '>= 0.4'} dependencies: define-properties: 1.2.1 + dev: true /globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} @@ -3303,6 +3315,7 @@ packages: /has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true /has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} @@ -3450,6 +3463,7 @@ packages: es-errors: 1.3.0 hasown: 2.0.2 side-channel: 1.0.6 + dev: true /is-arguments@1.1.1: resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} @@ -3465,6 +3479,7 @@ packages: dependencies: call-bind: 1.0.7 get-intrinsic: 1.2.4 + dev: true /is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} @@ -3474,6 +3489,7 @@ packages: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} dependencies: has-bigints: 1.0.2 + dev: true /is-boolean-object@1.1.2: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} @@ -3481,6 +3497,7 @@ packages: dependencies: call-bind: 1.0.7 has-tostringtag: 1.0.2 + dev: true /is-buffer@1.1.6: resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} @@ -3501,12 +3518,14 @@ packages: engines: {node: '>= 0.4'} dependencies: is-typed-array: 1.1.13 + dev: true /is-date-object@1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.2 + dev: true /is-docker@3.0.0: resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} @@ -3553,12 +3572,14 @@ packages: /is-negative-zero@2.0.3: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} + dev: true /is-number-object@1.0.7: resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.2 + dev: true /is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} @@ -3576,12 +3597,14 @@ packages: dependencies: call-bind: 1.0.7 has-tostringtag: 1.0.2 + dev: true /is-shared-array-buffer@1.0.3: resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.7 + dev: true /is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} @@ -3598,12 +3621,14 @@ packages: engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.2 + dev: true /is-symbol@1.0.4: resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} engines: {node: '>= 0.4'} dependencies: has-symbols: 1.0.3 + dev: true /is-typed-array@1.1.13: resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} @@ -3615,6 +3640,7 @@ packages: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: call-bind: 1.0.7 + dev: true /is-wsl@3.1.0: resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} @@ -3625,6 +3651,7 @@ packages: /isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -4600,10 +4627,12 @@ packages: /object-inspect@1.13.1: resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + dev: true /object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} + dev: true /object.assign@4.1.5: resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} @@ -4613,6 +4642,7 @@ packages: define-properties: 1.2.1 has-symbols: 1.0.3 object-keys: 1.1.1 + dev: true /object.fromentries@2.0.8: resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} @@ -4973,6 +5003,7 @@ packages: define-properties: 1.2.1 es-errors: 1.3.0 set-function-name: 2.0.2 + dev: true /require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} @@ -5056,6 +5087,7 @@ packages: get-intrinsic: 1.2.4 has-symbols: 1.0.3 isarray: 2.0.5 + dev: true /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -5067,6 +5099,7 @@ packages: call-bind: 1.0.7 es-errors: 1.3.0 is-regex: 1.1.4 + dev: true /safe-stable-stringify@2.4.3: resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} @@ -5114,6 +5147,7 @@ packages: es-errors: 1.3.0 functions-have-names: 1.2.3 has-property-descriptors: 1.0.2 + dev: true /sha.js@2.4.11: resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} @@ -5163,6 +5197,7 @@ packages: es-errors: 1.3.0 get-intrinsic: 1.2.4 object-inspect: 1.13.1 + dev: true /signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -5261,20 +5296,6 @@ packages: emoji-regex: 9.2.2 strip-ansi: 7.1.0 - /string.prototype.matchall@4.0.10: - resolution: {integrity: sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.22.5 - get-intrinsic: 1.2.4 - has-symbols: 1.0.3 - internal-slot: 1.0.7 - regexp.prototype.flags: 1.5.2 - set-function-name: 2.0.2 - side-channel: 1.0.6 - dev: false - /string.prototype.padend@3.1.5: resolution: {integrity: sha512-DOB27b/2UTTD+4myKUFh+/fXWcu/UDyASIXfg+7VzoCNNGOfWvoyU/x5pvVHr++ztyt/oSYI1BcWBBG/hmlNjA==} engines: {node: '>= 0.4'} @@ -5292,6 +5313,7 @@ packages: define-properties: 1.2.1 es-abstract: 1.23.2 es-object-atoms: 1.0.0 + dev: true /string.prototype.trimend@1.0.8: resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} @@ -5299,6 +5321,7 @@ packages: call-bind: 1.0.7 define-properties: 1.2.1 es-object-atoms: 1.0.0 + dev: true /string.prototype.trimstart@1.0.7: resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} @@ -5306,6 +5329,7 @@ packages: call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.22.5 + dev: true /string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -5610,6 +5634,7 @@ packages: call-bind: 1.0.7 es-errors: 1.3.0 is-typed-array: 1.1.13 + dev: true /typed-array-byte-length@1.0.1: resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} @@ -5620,6 +5645,7 @@ packages: gopd: 1.0.1 has-proto: 1.0.3 is-typed-array: 1.1.13 + dev: true /typed-array-byte-offset@1.0.2: resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} @@ -5631,6 +5657,7 @@ packages: gopd: 1.0.1 has-proto: 1.0.3 is-typed-array: 1.1.13 + dev: true /typed-array-length@1.0.5: resolution: {integrity: sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==} @@ -5642,6 +5669,7 @@ packages: has-proto: 1.0.3 is-typed-array: 1.1.13 possible-typed-array-names: 1.0.0 + dev: true /typeorm@0.3.20(ts-node@10.9.2): resolution: {integrity: sha512-sJ0T08dV5eoZroaq9uPKBoNcGslHBR4E4y+EBHs//SiGbblGe7IeduP/IH4ddCcj0qp3PHwDwGnuvqEAnKlq/Q==} @@ -5745,6 +5773,7 @@ packages: has-bigints: 1.0.2 has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 + dev: true /undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} @@ -5868,6 +5897,7 @@ packages: is-number-object: 1.0.7 is-string: 1.0.7 is-symbol: 1.0.4 + dev: true /which-typed-array@1.1.15: resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} From bfff5d46c13c310138d565ac38e040c4e0b88482 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Wed, 9 Oct 2024 09:49:19 +0200 Subject: [PATCH 36/47] chore: typo --- lib/evaluation/evaluationClientWrapper.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/evaluation/evaluationClientWrapper.ts b/lib/evaluation/evaluationClientWrapper.ts index 44a07a2d..a32fbae1 100644 --- a/lib/evaluation/evaluationClientWrapper.ts +++ b/lib/evaluation/evaluationClientWrapper.ts @@ -513,10 +513,10 @@ export class EvaluationClientWrapper { ? vcResult.value.vp.verifiableCredential[0] : vcResult.value.vp.verifiableCredential; } else { - throw Error('Could not deduced original VC from evaluation result'); + throw Error('Could not deduce original VC from evaluation result'); } } else { - throw Error('Could not deduced original VC from evaluation result'); + throw Error('Could not deduce original VC from evaluation result'); } // Find the corresponding Wrapped Verifiable Credential (wvc) based on the original VC From 1e37b8ac7f9b528c37da29cc86688f2d229fddf8 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Wed, 9 Oct 2024 16:36:29 +0200 Subject: [PATCH 37/47] chore: PR feedback --- .github/workflows/main.yml | 2 +- lib/PEX.ts | 79 +++++++++++++++++++---- lib/PEXv1.ts | 4 +- lib/PEXv2.ts | 4 +- lib/evaluation/evaluationClientWrapper.ts | 9 +-- 5 files changed, 73 insertions(+), 25 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e2112633..ca1cddee 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -36,7 +36,7 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos name: codecove # optional flags: unittest - fail_ci_if_error: false # optional (default = false) + fail_ci_if_error: true # optional (default = false) #directory: ./coverage/reports/ #files: ./coverage1.xml,./coverage2.xml verbose: true # optional (default = false) diff --git a/lib/PEX.ts b/lib/PEX.ts index 0635d386..7437a431 100644 --- a/lib/PEX.ts +++ b/lib/PEX.ts @@ -1,4 +1,9 @@ -import { Format, PresentationDefinitionV1, PresentationDefinitionV2, PresentationSubmission } from '@sphereon/pex-models'; +import { + Format, + PresentationDefinitionV1, + PresentationDefinitionV2, + PresentationSubmission +} from '@sphereon/pex-models'; import { CompactSdJwtVc, CredentialMapper, @@ -6,6 +11,7 @@ import { ICredential, IPresentation, IProof, + JwtDecodedVerifiableCredential, OriginalVerifiableCredential, OriginalVerifiablePresentation, OrPromise, @@ -13,12 +19,11 @@ import { W3CVerifiableCredential, W3CVerifiablePresentation, WrappedVerifiableCredential, - WrappedVerifiablePresentation, + WrappedVerifiablePresentation } from '@sphereon/ssi-types'; import { Status } from './ConstraintUtils'; -import { EvaluationClientWrapper, EvaluationResults, SelectResults } from './evaluation'; -import { PresentationEvaluationResults } from './evaluation'; +import { EvaluationClientWrapper, EvaluationResults, PresentationEvaluationResults, SelectResults } from './evaluation'; import { PartialSdJwtDecodedVerifiableCredential, PartialSdJwtKbJwt, @@ -27,11 +32,24 @@ import { PresentationSignCallBackParams, PresentationSubmissionLocation, VerifiablePresentationFromOpts, - VerifiablePresentationResult, + VerifiablePresentationResult } from './signing'; -import { DiscoveredVersion, IInternalPresentationDefinition, IPresentationDefinition, OrArray, PEVersion, SSITypesBuilder } from './types'; +import { + DiscoveredVersion, + IInternalPresentationDefinition, + IPresentationDefinition, + OrArray, + PEVersion, + SSITypesBuilder +} from './types'; import { calculateSdHash, definitionVersionDiscovery, getSubjectIdsAsString } from './utils'; -import { PresentationDefinitionV1VB, PresentationDefinitionV2VB, PresentationSubmissionVB, Validated, ValidationEngine } from './validation'; +import { + PresentationDefinitionV1VB, + PresentationDefinitionV2VB, + PresentationSubmissionVB, + Validated, + ValidationEngine +} from './validation'; export interface PEXOptions { /** @@ -379,7 +397,7 @@ export class PEX { const decoded = CredentialMapper.decodeVerifiableCredential(vc, opts?.hasher); result.push(decoded as PartialSdJwtDecodedVerifiableCredential); } else { - // This should be plain jwt only + // This should be jwt or json-ld result.push({ ...opts?.basePresentationPayload, '@context': context, @@ -394,12 +412,47 @@ export class PEX { return result; } - private static allowMultipleVCsPerPresentation(verifiableCredential: Array) { - return !verifiableCredential.some( - (c) => CredentialMapper.isJwtEncoded(c) || CredentialMapper.isSdJwtEncoded(c) || CredentialMapper.isSdJwtDecodedCredential(c), - ); - } + private static allowMultipleVCsPerPresentation(verifiableCredentials: Array): boolean { + const jwtCredentials = verifiableCredentials.filter( + (c) => CredentialMapper.isJwtEncoded(c) || CredentialMapper.isJwtDecodedCredential(c) + ) + + if (jwtCredentials.length > 0) { + const subjects = new Set() + const verificationMethods = new Set() + + for (const credential of jwtCredentials) { + const decodedCredential = CredentialMapper.isJwtEncoded(credential) + ? CredentialMapper.decodeVerifiableCredential(credential) as JwtDecodedVerifiableCredential + : credential as JwtDecodedVerifiableCredential + + const subject = decodedCredential.sub || (decodedCredential.vc && 'id' in decodedCredential.vc.credentialSubject && decodedCredential.vc.credentialSubject.id); + if (subject) { + subjects.add(subject); + } + const vcProof = decodedCredential.proof ?? decodedCredential.vc.proof; + const proofs = Array.isArray(vcProof) ? vcProof : [vcProof]; + proofs.filter((proof: IProof) => proof.verificationMethod) + .forEach((proof: IProof) => verificationMethods.add(proof.verificationMethod)); + } + + // If there's more than one unique subject or verification method, we can't allow multiple VCs in a single presentation + if (subjects.size > 1 || verificationMethods.size > 1) { + return false + } + } + + if (verifiableCredentials.some( + (c) => CredentialMapper.isSdJwtEncoded(c) || CredentialMapper.isSdJwtDecodedCredential(c) + )) { + return false; + } + + return true + } + + /** * This method validates whether an object is usable as a presentation definition or not. * diff --git a/lib/PEXv1.ts b/lib/PEXv1.ts index 5969b45f..b0175682 100644 --- a/lib/PEXv1.ts +++ b/lib/PEXv1.ts @@ -124,13 +124,13 @@ export class PEXv1 extends PEX { opts?.presentationSubmissionLocation ?? (hasSdJwtCredentials ? PresentationSubmissionLocation.EXTERNAL : PresentationSubmissionLocation.PRESENTATION); - const presentation = this.constructPresentations(selectedCredentials, { + const presentations = this.constructPresentations(selectedCredentials, { ...opts, presentationSubmission: presentationSubmissionLocation === PresentationSubmissionLocation.PRESENTATION ? presentationSubmission : undefined, }); return { - presentations: presentation, + presentations, presentationSubmissionLocation, presentationSubmission, }; diff --git a/lib/PEXv2.ts b/lib/PEXv2.ts index 126e9114..13795883 100644 --- a/lib/PEXv2.ts +++ b/lib/PEXv2.ts @@ -120,13 +120,13 @@ export class PEXv2 extends PEX { opts?.presentationSubmissionLocation ?? (hasSdJwtCredentials ? PresentationSubmissionLocation.EXTERNAL : PresentationSubmissionLocation.PRESENTATION); - const presentation = this.constructPresentations(selectedCredentials, { + const presentations = this.constructPresentations(selectedCredentials, { ...opts, presentationSubmission: presentationSubmissionLocation === PresentationSubmissionLocation.PRESENTATION ? presentationSubmission : undefined, }); return { - presentations: presentation, + presentations, presentationSubmissionLocation, presentationSubmission, }; diff --git a/lib/evaluation/evaluationClientWrapper.ts b/lib/evaluation/evaluationClientWrapper.ts index a32fbae1..bb590f59 100644 --- a/lib/evaluation/evaluationClientWrapper.ts +++ b/lib/evaluation/evaluationClientWrapper.ts @@ -507,11 +507,6 @@ export class EvaluationClientWrapper { originalVc = Array.isArray(vcResult.value.verifiableCredential) ? vcResult.value.verifiableCredential[0] : vcResult.value.verifiableCredential; - // FIXME this may be too lenient - } else if ('vp' in vcResult.value) { - originalVc = Array.isArray(vcResult.value.vp.verifiableCredential) - ? vcResult.value.vp.verifiableCredential[0] - : vcResult.value.vp.verifiableCredential; } else { throw Error('Could not deduce original VC from evaluation result'); } @@ -672,7 +667,7 @@ export class EvaluationClientWrapper { // Get the presentation definition specific to the current descriptor const pdForDescriptor = this.internalPresentationDefinitionForDescriptor(pd, descriptor.id); - // Reset and configure the evaluation client + // Reset and configure the evaluation client on each iteration this._client = new EvaluationClient(); this._client.evaluate(pdForDescriptor, [vc], { ...opts, @@ -690,7 +685,7 @@ export class EvaluationClientWrapper { } } - // Validate if the submission satisfies the presentation definition + // Output submission is same as input presentation submission, it's just that if it doesn't match, we return Error. const submissionAgainstDefinitionResult = this.validateIfSubmissionSatisfiesDefinition(pd, submission); if (!submissionAgainstDefinitionResult.doesSubmissionSatisfyDefinition) { result.errors?.push({ From 6b61f3a77abaf534588139fc33012036fc300ce5 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Wed, 9 Oct 2024 16:39:46 +0200 Subject: [PATCH 38/47] chore: prettier & lint --- lib/PEX.ts | 60 +++++++++++++++++------------------------------------- 1 file changed, 19 insertions(+), 41 deletions(-) diff --git a/lib/PEX.ts b/lib/PEX.ts index 7437a431..2a294f86 100644 --- a/lib/PEX.ts +++ b/lib/PEX.ts @@ -1,9 +1,4 @@ -import { - Format, - PresentationDefinitionV1, - PresentationDefinitionV2, - PresentationSubmission -} from '@sphereon/pex-models'; +import { Format, PresentationDefinitionV1, PresentationDefinitionV2, PresentationSubmission } from '@sphereon/pex-models'; import { CompactSdJwtVc, CredentialMapper, @@ -19,7 +14,7 @@ import { W3CVerifiableCredential, W3CVerifiablePresentation, WrappedVerifiableCredential, - WrappedVerifiablePresentation + WrappedVerifiablePresentation, } from '@sphereon/ssi-types'; import { Status } from './ConstraintUtils'; @@ -32,24 +27,11 @@ import { PresentationSignCallBackParams, PresentationSubmissionLocation, VerifiablePresentationFromOpts, - VerifiablePresentationResult + VerifiablePresentationResult, } from './signing'; -import { - DiscoveredVersion, - IInternalPresentationDefinition, - IPresentationDefinition, - OrArray, - PEVersion, - SSITypesBuilder -} from './types'; +import { DiscoveredVersion, IInternalPresentationDefinition, IPresentationDefinition, OrArray, PEVersion, SSITypesBuilder } from './types'; import { calculateSdHash, definitionVersionDiscovery, getSubjectIdsAsString } from './utils'; -import { - PresentationDefinitionV1VB, - PresentationDefinitionV2VB, - PresentationSubmissionVB, - Validated, - ValidationEngine -} from './validation'; +import { PresentationDefinitionV1VB, PresentationDefinitionV2VB, PresentationSubmissionVB, Validated, ValidationEngine } from './validation'; export interface PEXOptions { /** @@ -413,46 +395,42 @@ export class PEX { } private static allowMultipleVCsPerPresentation(verifiableCredentials: Array): boolean { - const jwtCredentials = verifiableCredentials.filter( - (c) => CredentialMapper.isJwtEncoded(c) || CredentialMapper.isJwtDecodedCredential(c) - ) + const jwtCredentials = verifiableCredentials.filter((c) => CredentialMapper.isJwtEncoded(c) || CredentialMapper.isJwtDecodedCredential(c)); if (jwtCredentials.length > 0) { - const subjects = new Set() - const verificationMethods = new Set() + const subjects = new Set(); + const verificationMethods = new Set(); for (const credential of jwtCredentials) { - const decodedCredential = CredentialMapper.isJwtEncoded(credential) - ? CredentialMapper.decodeVerifiableCredential(credential) as JwtDecodedVerifiableCredential - : credential as JwtDecodedVerifiableCredential + const decodedCredential = CredentialMapper.isJwtEncoded(credential) + ? (CredentialMapper.decodeVerifiableCredential(credential) as JwtDecodedVerifiableCredential) + : (credential as JwtDecodedVerifiableCredential); - const subject = decodedCredential.sub || (decodedCredential.vc && 'id' in decodedCredential.vc.credentialSubject && decodedCredential.vc.credentialSubject.id); + const subject = + decodedCredential.sub || + (decodedCredential.vc && 'id' in decodedCredential.vc.credentialSubject && decodedCredential.vc.credentialSubject.id); if (subject) { subjects.add(subject); } const vcProof = decodedCredential.proof ?? decodedCredential.vc.proof; const proofs = Array.isArray(vcProof) ? vcProof : [vcProof]; - proofs.filter((proof: IProof) => proof.verificationMethod) - .forEach((proof: IProof) => verificationMethods.add(proof.verificationMethod)); + proofs.filter((proof: IProof) => proof.verificationMethod).forEach((proof: IProof) => verificationMethods.add(proof.verificationMethod)); } // If there's more than one unique subject or verification method, we can't allow multiple VCs in a single presentation if (subjects.size > 1 || verificationMethods.size > 1) { - return false + return false; } } - if (verifiableCredentials.some( - (c) => CredentialMapper.isSdJwtEncoded(c) || CredentialMapper.isSdJwtDecodedCredential(c) - )) { + if (verifiableCredentials.some((c) => CredentialMapper.isSdJwtEncoded(c) || CredentialMapper.isSdJwtDecodedCredential(c))) { return false; } - return true + return true; } - - + /** * This method validates whether an object is usable as a presentation definition or not. * From 9d37a75d0fe96fc9b29c7902019ce0193317da05 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Wed, 9 Oct 2024 16:44:50 +0200 Subject: [PATCH 39/47] chore: codecov fix --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ca1cddee..b0b36b8b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -31,10 +31,10 @@ jobs: - name: pnpm test run: pnpm test - name: codecov - uses: codecov/codecov-action@v2 + uses: codecov/codecov-action@v4 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos - name: codecove # optional + name: codecove-umbrella # optional flags: unittest fail_ci_if_error: true # optional (default = false) #directory: ./coverage/reports/ From def0fdc09f942d6aad0fb0c40f018cf4d24caac9 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Wed, 9 Oct 2024 17:07:02 +0200 Subject: [PATCH 40/47] chore: added TODO --- lib/PEX.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/PEX.ts b/lib/PEX.ts index 2a294f86..37cce6d4 100644 --- a/lib/PEX.ts +++ b/lib/PEX.ts @@ -394,6 +394,9 @@ export class PEX { return result; } + /* + TODO SDK-37 refinement needed + */ private static allowMultipleVCsPerPresentation(verifiableCredentials: Array): boolean { const jwtCredentials = verifiableCredentials.filter((c) => CredentialMapper.isJwtEncoded(c) || CredentialMapper.isJwtDecodedCredential(c)); From 3fb888379f4fbd717ab48e816d2a7cc2167e8800 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Wed, 9 Oct 2024 17:22:23 +0200 Subject: [PATCH 41/47] chore: removed test:cov script --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index d27c3d2b..092aaedb 100644 --- a/package.json +++ b/package.json @@ -35,8 +35,7 @@ "test": "run-s test:*", "test:lint": "eslint . --ext .ts", "test:prettier": "prettier \"{lib,test}/**/*.ts\" --list-different", - "test:unit": "jest", - "test:cov": "jest --ci --coverage && codecov" + "test:unit": "jest" }, "engines": { "node": ">=18" From 7c9c934aaf6e03ec0085b204962a810cfaf5b552 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Wed, 9 Oct 2024 17:25:43 +0200 Subject: [PATCH 42/47] chore: restart workflow --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 092aaedb..5f4d264b 100644 --- a/package.json +++ b/package.json @@ -88,4 +88,4 @@ "singleQuote": true, "printWidth": 150 } -} +} From 4065f49f96ab885146517e8ae839a9707f8b6beb Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Wed, 9 Oct 2024 17:30:36 +0200 Subject: [PATCH 43/47] chore: reverted codecov name --- .github/workflows/main.yml | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b0b36b8b..40d2baa6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -34,7 +34,7 @@ jobs: uses: codecov/codecov-action@v4 with: token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos - name: codecove-umbrella # optional + name: codecove # optional flags: unittest fail_ci_if_error: true # optional (default = false) #directory: ./coverage/reports/ diff --git a/package.json b/package.json index 5f4d264b..092aaedb 100644 --- a/package.json +++ b/package.json @@ -88,4 +88,4 @@ "singleQuote": true, "printWidth": 150 } -} +} From 0474cfec53b6ab0efc643353be53b29d2a4a5471 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Wed, 9 Oct 2024 17:59:18 +0200 Subject: [PATCH 44/47] chore: extra error state The WrappedVerifiableCredentials input array is empty --- lib/evaluation/evaluationClientWrapper.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/evaluation/evaluationClientWrapper.ts b/lib/evaluation/evaluationClientWrapper.ts index bb590f59..c16410a3 100644 --- a/lib/evaluation/evaluationClientWrapper.ts +++ b/lib/evaluation/evaluationClientWrapper.ts @@ -870,6 +870,9 @@ export class EvaluationClientWrapper { }, ): PresentationSubmission { if (!this._client.results || this._client.results.length === 0) { + if(vcs.length === 0) { + throw Error('The WrappedVerifiableCredentials input array is empty'); + } throw Error('You need to call evaluate() before pex.presentationFrom()'); } if (!this._client.generatePresentationSubmission) { From 7a710927641d3e30a904457078277b663bf4a4b6 Mon Sep 17 00:00:00 2001 From: Niels Klomp Date: Wed, 9 Oct 2024 21:24:51 +0200 Subject: [PATCH 45/47] chore: up version --- lib/evaluation/evaluationClientWrapper.ts | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/evaluation/evaluationClientWrapper.ts b/lib/evaluation/evaluationClientWrapper.ts index c16410a3..0e2cf9d2 100644 --- a/lib/evaluation/evaluationClientWrapper.ts +++ b/lib/evaluation/evaluationClientWrapper.ts @@ -870,7 +870,7 @@ export class EvaluationClientWrapper { }, ): PresentationSubmission { if (!this._client.results || this._client.results.length === 0) { - if(vcs.length === 0) { + if (vcs.length === 0) { throw Error('The WrappedVerifiableCredentials input array is empty'); } throw Error('You need to call evaluate() before pex.presentationFrom()'); diff --git a/package.json b/package.json index 092aaedb..11a5537c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sphereon/pex", - "version": "5.0.0-unstable.17", + "version": "5.0.0-unstable.18", "description": "A Typescript implementation of the v1 and v2 DIF Presentation Exchange specification", "main": "dist/main/index.js", "module": "dist/module/index.js", From 5ac9a6622d47a6aea7da4f88706d516a27b8f2f2 Mon Sep 17 00:00:00 2001 From: Niels Klomp Date: Wed, 9 Oct 2024 21:39:01 +0200 Subject: [PATCH 46/47] chore: codecov fixes --- .github/workflows/main.yml | 6 +++--- package.json | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 40d2baa6..f40e6144 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,14 +12,14 @@ jobs: name: build runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: pnpm/action-setup@v2 + - uses: pnpm/action-setup@v4 with: version: 8 - name: Use Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: '18.x' cache: 'pnpm' diff --git a/package.json b/package.json index 11a5537c..5c4af225 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "test": "run-s test:*", "test:lint": "eslint . --ext .ts", "test:prettier": "prettier \"{lib,test}/**/*.ts\" --list-different", + "test:cov": "jest --ci --coverage && codecov", "test:unit": "jest" }, "engines": { From dd98f3175723bb605a2f3c5770ee2f2d2334b07a Mon Sep 17 00:00:00 2001 From: Niels Klomp Date: Wed, 9 Oct 2024 21:52:23 +0200 Subject: [PATCH 47/47] fix: codecov fixes --- package.json | 3 +- pnpm-lock.yaml | 115 ++----------------------------------------------- 2 files changed, 5 insertions(+), 113 deletions(-) diff --git a/package.json b/package.json index 5c4af225..8aa442f9 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "test": "run-s test:*", "test:lint": "eslint . --ext .ts", "test:prettier": "prettier \"{lib,test}/**/*.ts\" --list-different", - "test:cov": "jest --ci --coverage && codecov", + "test:cov": "jest --ci --coverage", "test:unit": "jest" }, "engines": { @@ -61,7 +61,6 @@ "@typescript-eslint/parser": "^7.3.1", "@sd-jwt/core": "^0.7.2", "ajv-cli": "^5.0.0", - "codecov": "^3.8.3", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-eslint-comments": "^3.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4ffa80fe..32d774c0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -58,9 +58,6 @@ devDependencies: ajv-cli: specifier: ^5.0.0 version: 5.0.0(ts-node@10.9.2) - codecov: - specifier: ^3.8.3 - version: 3.8.3 eslint: specifier: ^8.57.0 version: 8.57.0 @@ -1418,11 +1415,6 @@ packages: resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} dev: true - /@tootallnate/once@1.1.2: - resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} - engines: {node: '>= 6'} - dev: true - /@trust/keyto@1.0.1: resolution: {integrity: sha512-OXTmKkrnkwktCX86XA7eWs1TQ6u64enm0syzAfNhjigbuGLy5aLhbhRYWtjt4zzdG/irWudluheRZ9Ic9pCwsA==} dependencies: @@ -1739,15 +1731,6 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - /agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} - dependencies: - debug: 4.3.6 - transitivePeerDependencies: - - supports-color - dev: true - /ajv-cli@5.0.0(ts-node@10.9.2): resolution: {integrity: sha512-LY4m6dUv44HTyhV+u2z5uX4EhPYTM38Iv1jdgDJJJCyOOuqB8KtZEGjPZ2T+sh5ZIJrXUfgErYx/j3gLd3+PlQ==} hasBin: true @@ -1862,12 +1845,6 @@ packages: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true - /argv@0.0.2: - resolution: {integrity: sha512-dEamhpPEwRUBpLNHeuCm/v+g0anFByHahxodVO/BbAarHVBBg2MccCwf9K+o1Pof+2btdnkJelYVUWjW/VrATw==} - engines: {node: '>=0.6.10'} - deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - dev: true - /array-buffer-byte-length@1.0.1: resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} engines: {node: '>= 0.4'} @@ -2239,22 +2216,6 @@ packages: engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} dev: true - /codecov@3.8.3: - resolution: {integrity: sha512-Y8Hw+V3HgR7V71xWH2vQ9lyS358CbGCldWlJFR0JirqoGtOoas3R3/OclRTvgUYFK29mmJICDPauVKmpqbwhOA==} - engines: {node: '>=4.0'} - deprecated: https://about.codecov.io/blog/codecov-uploader-deprecation-plan/ - hasBin: true - dependencies: - argv: 0.0.2 - ignore-walk: 3.0.4 - js-yaml: 3.14.1 - teeny-request: 7.1.1 - urlgrey: 1.0.0 - transitivePeerDependencies: - - encoding - - supports-color - dev: true - /collect-v8-coverage@1.0.2: resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} dev: true @@ -3064,12 +3025,6 @@ packages: /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - /fast-url-parser@1.1.3: - resolution: {integrity: sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==} - dependencies: - punycode: 1.4.1 - dev: true - /fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} dependencies: @@ -3378,27 +3333,6 @@ packages: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} dev: true - /http-proxy-agent@4.0.1: - resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==} - engines: {node: '>= 6'} - dependencies: - '@tootallnate/once': 1.1.2 - agent-base: 6.0.2 - debug: 4.3.6 - transitivePeerDependencies: - - supports-color - dev: true - - /https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} - dependencies: - agent-base: 6.0.2 - debug: 4.3.6 - transitivePeerDependencies: - - supports-color - dev: true - /human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} @@ -3407,12 +3341,6 @@ packages: /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - /ignore-walk@3.0.4: - resolution: {integrity: sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==} - dependencies: - minimatch: 3.1.2 - dev: true - /ignore@5.3.1: resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} engines: {node: '>= 4'} @@ -4574,6 +4502,7 @@ packages: optional: true dependencies: whatwg-url: 5.0.0 + dev: false /node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} @@ -4931,10 +4860,6 @@ packages: sisteransi: 1.0.5 dev: true - /punycode@1.4.1: - resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} - dev: true - /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -5266,12 +5191,6 @@ packages: escodegen: 1.14.3 dev: false - /stream-events@1.0.5: - resolution: {integrity: sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==} - dependencies: - stubs: 3.0.0 - dev: true - /string-length@4.0.2: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} engines: {node: '>=10'} @@ -5377,10 +5296,6 @@ packages: peek-readable: 5.0.0 dev: true - /stubs@3.0.0: - resolution: {integrity: sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==} - dev: true - /supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -5406,20 +5321,6 @@ packages: engines: {node: '>= 0.4'} dev: true - /teeny-request@7.1.1: - resolution: {integrity: sha512-iwY6rkW5DDGq8hE2YgNQlKbptYpY5Nn2xecjQiNjOXWbKzPGUfmeUBCSQbbr306d7Z7U2N0TPl+/SwYRfua1Dg==} - engines: {node: '>=10'} - dependencies: - http-proxy-agent: 4.0.1 - https-proxy-agent: 5.0.1 - node-fetch: 2.7.0 - stream-events: 1.0.5 - uuid: 8.3.2 - transitivePeerDependencies: - - encoding - - supports-color - dev: true - /temp-dir@3.0.0: resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==} engines: {node: '>=14.16'} @@ -5487,6 +5388,7 @@ packages: /tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: false /ts-api-utils@1.3.0(typescript@5.4.2): resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} @@ -5808,12 +5710,6 @@ packages: requires-port: 1.0.0 dev: false - /urlgrey@1.0.0: - resolution: {integrity: sha512-hJfIzMPJmI9IlLkby8QrsCykQ+SXDeO2W5Q9QTW3QpqZVTx4a/K7p8/5q+/isD8vsbVaFgql/gvAoQCRQ2Cb5w==} - dependencies: - fast-url-parser: 1.1.3 - dev: true - /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: true @@ -5828,11 +5724,6 @@ packages: which-typed-array: 1.1.15 dev: false - /uuid@8.3.2: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - hasBin: true - dev: true - /uuid@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true @@ -5882,12 +5773,14 @@ packages: /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: false /whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} dependencies: tr46: 0.0.3 webidl-conversions: 3.0.1 + dev: false /which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}