diff --git a/lib/evaluation/evaluationClientWrapper.ts b/lib/evaluation/evaluationClientWrapper.ts index 214aa2a..237905e 100644 --- a/lib/evaluation/evaluationClientWrapper.ts +++ b/lib/evaluation/evaluationClientWrapper.ts @@ -7,6 +7,7 @@ import { IVerifiablePresentation, OriginalVerifiableCredential, SdJwtDecodedVerifiableCredential, + WrappedMdocCredential, WrappedVerifiableCredential, WrappedVerifiablePresentation, } from '@sphereon/ssi-types'; @@ -416,6 +417,8 @@ export class EvaluationClientWrapper { warnings: [], }; + // Reset and configure the evaluation client on each iteration + this._client = new EvaluationClient(); this._client.evaluate(pd, allWvcs, opts); result.warnings = this.formatNotInfo(Status.WARN); result.errors = this.formatNotInfo(Status.ERROR); @@ -645,7 +648,7 @@ export class EvaluationClientWrapper { vc = extractionResult.wvc; vcPath += ` with nested credential ${descriptor.path_nested.path}`; - } else if (descriptor.format === 'vc+sd-jwt' || descriptor.format === 'mso_mdoc') { + } else if (descriptor.format === 'vc+sd-jwt') { if (!matchingVp.vcs || !matchingVp.vcs.length) { result.areRequiredCredentialsPresent = Status.ERROR; result.errors?.push({ @@ -656,6 +659,25 @@ export class EvaluationClientWrapper { continue; } vc = matchingVp.vcs[0]; + } else if (descriptor.format === 'mso_mdoc') { + // We already know the format is mso_mdoc so this cast is safe + const vcs = matchingVp.vcs as WrappedMdocCredential[]; + vcPath += ` with nested mdoc with doctype ${descriptor.id}`; + + const matchingVc = vcs.find((vc) => descriptor.id === vc.credential.docType.asStr); + + if (!matchingVc) { + const allDoctypes = vcs.map((vc) => `'${vc.credential.docType.asStr}'`).join(', '); + result.areRequiredCredentialsPresent = Status.ERROR; + result.errors?.push({ + status: Status.ERROR, + tag: 'NoCredentialsFound', + message: `No mdoc credential with doctype '${descriptor.id}' found in mdoc vp. Available documents are ${allDoctypes}`, + }); + continue; + } + + vc = matchingVc; } else { result.areRequiredCredentialsPresent = Status.ERROR; result.errors?.push({ diff --git a/package.json b/package.json index 70846eb..4d1f79a 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.129", + "@sphereon/ssi-types": "0.30.2-next.135", "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 6a02b7b..a1949e1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,8 +24,8 @@ importers: specifier: ^2.3.1 version: 2.3.1 '@sphereon/ssi-types': - specifier: 0.30.2-next.129 - version: 0.30.2-next.129 + specifier: 0.30.2-next.135 + version: 0.30.2-next.135 ajv: specifier: ^8.12.0 version: 8.12.0 @@ -471,8 +471,8 @@ packages: '@sphereon/pex-models@2.3.1': resolution: {integrity: sha512-SByU4cJ0XYA6VZQ/L6lsSiRcFtBPHbFioCeQ4GP7/W/jQ+PSBD7uK2oTnKQ9/0iEiMK/6JYqhKgLs4a9UX3UTQ==} - '@sphereon/ssi-types@0.30.2-next.129': - resolution: {integrity: sha512-F1TDy9S5ajDJDp21cINXseGSux9kGA+x0KScAS+5+B/RdMGRp7bLOM+3YpQw1QGPqKxVc7JAd2gAn7AI0pAkZA==} + '@sphereon/ssi-types@0.30.2-next.135': + resolution: {integrity: sha512-YLQfFMPUlOJUxHbOS9v01nG3cgLwTk3d95/rTnOmEQx9kXgXjoXdvt7D0uGcMRL3RHeQ9biT/jWY//mDvCirVQ==} '@tokenizer/token@0.3.0': resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} @@ -2984,7 +2984,7 @@ snapshots: '@sphereon/pex-models@2.3.1': {} - '@sphereon/ssi-types@0.30.2-next.129': + '@sphereon/ssi-types@0.30.2-next.135': dependencies: '@sd-jwt/decode': 0.7.2 '@sphereon/kmp-mdl-mdoc': 0.2.0-SNAPSHOT.22 diff --git a/test/Mdoc.spec.ts b/test/Mdoc.spec.ts index 7ee8c60..7129350 100644 --- a/test/Mdoc.spec.ts +++ b/test/Mdoc.spec.ts @@ -7,6 +7,9 @@ import { SubmissionRequirementMatchType } from '../lib/evaluation/core'; export const hasher = (data: string) => createHash('sha256').update(data).digest(); +const mdocBase64UrlMultipleDocumentsPresentation = + 'uQADZ3ZlcnNpb25jMS4waWRvY3VtZW50c4KjZ2RvY1R5cGV1b3JnLmlzby4xODAxMy41LjEubURMbGlzc3VlclNpZ25lZLkAAmpuYW1lU3BhY2VzoXFvcmcuaXNvLjE4MDEzLjUuMYHYGFhipGhkaWdlc3RJRAFxZWxlbWVudElkZW50aWZpZXJqZ2l2ZW5fbmFtZWxlbGVtZW50VmFsdWVjQXZhZnJhbmRvbVggKtvEv2_zGjeiQxMF6Qr_ubn_R7oUADdffjsLaAleH_VqaXNzdWVyQXV0aIRDoQEmogRYMXpEbmFlcnR6VllXOFJFenplZzl0QUVEN3E1UFhTV2lpUFZkQnFodVZpRVdUdW84TGEYIYFZAi4wggIqMIIB0KADAgECAhRXxszTCL3kPso3RPKocTjau7iE6DAKBggqhkjOPQQDAjBTMQswCQYDVQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxDzANBgNVBAcMBkFsYmFueTEPMA0GA1UECgwGTlkgRE1WMQ8wDQYDVQQLDAZOWSBETVYwHhcNMjMwOTE0MTQ1NTE4WhcNMzMwOTExMTQ1NTE4WjBTMQswCQYDVQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxDzANBgNVBAcMBkFsYmFueTEPMA0GA1UECgwGTlkgRE1WMQ8wDQYDVQQLDAZOWSBETVYwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASJPC2DR5Btxs1pt_Y2r0v9Uz-WGE8KrazRCDDaRHHb22CsFw0c_FNPri2dzUiPd0f9-XjZJeox6ekIPDgrqe1To4GBMH8wHQYDVR0OBBYEFKttLgO5HUkiQDOPvMre_ZMz6vbHMB8GA1UdIwQYMBaAFKttLgO5HUkiQDOPvMre_ZMz6vbHMA8GA1UdEwEB_wQFMAMBAf8wLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMAoGCCqGSM49BAMCA0gAMEUCIAn9DKuXsD549k5019zuiGaMR2oK_Fqizr_-B9O-dy6pAiEA2jiryYoID0nyT_7OH__Ips3VssC12o_Ht2esOpXcuD5ZBJjYGFkEk7kABmd2ZXJzaW9uYzEuMG9kaWdlc3RBbGdvcml0aG1nU0hBLTI1Nmx2YWx1ZURpZ2VzdHOhcW9yZy5pc28uMTgwMTMuNS4xuBgAWCCbhqm6X1E0NzApTQbm806eplorHKwV1j97TVuIvlHcIgFYIDVFLRh8V5cYmighiiOv6deYv_L8TsUBru1rL75aNJd7AlggD2Z1ozETPthnxZgrNEmQ_v9KWeeNDIduTp5uLnjVGIwDWCDp1Ll490dE-v3H_UbC5lN9Cg71m3awpdc_x2YGPuR1nQRYIHJ2yhtpIJWWdRUdV9oI6thFN2Whfld5Gxxe540WmFgrBVgg62E26LqOHli6OXczPaQEt44_jRFNksmt9j_OXnHlp2wGWCA1C_FRU_BFvHnKPWnDrswG-CjzW9pSe-XVfN40gYSBFQdYIAFk-KqrP_fpvMNhGtReBkf0ag9AzMQCqtUgF4ADsoOzCFggUGLIURDcD_MFlVPsukIX58xzxfwnmc7WmpTNlQIhJ74JWCC-R-QqQyqc6tFDepghyhm3j_wSCARrAa6o0DDJg-2evQpYIAY-QMinqw69wWEISG0bcYGiLx5AOadHoV0bKyN2Dks6C1gg_71wnC-37xSXHLVtgY-vAmRiEjUa8d3EzdiZFCEHG4EMWCA-TAbVFGvwy5AXWS6FHEX3RIys3q6F9Z372ei0UN0JRw1YIEOi-MwtUJ2l_ixrk2cy3O1mRTBcAIM5uIJx2eUUWx89Dlggd-ab0Cuj2yC_k6Fur3_1Ihw692ETl1ZAkaB35LXd1qoPWCCIUclY01QUZkGAFsAnhvpomj41LToq5VEAhi3EP17maBBYIJuBcjlWhR5hUzjMsPeR3gveLqJAMfpVwjBvuGXIZE8CEVgg97JhkE0VdgjaeJRMdGRgLZkUkafO0La7go_4SY3TKZASWCDBeESPPAwGCecC2NO5fOK9EKHmLb0qwo1xtHgR8OgH3RNYIMc3W8dbiJfha69dWm13wqGPViKcGGKX8pMn0KEw5FseFFggJnQlhJ5hQMKE2LWtXUhc3RlB1Q-CXx4nURpUQQWac1UVWCDzG025GiQJK11hBSbVvJqaWYYHCDcbIczVuvGk6JH55hZYIGHapaMrTh5UV5vq0YKWgm4Yn3Sa_g4Sk1WAZMa9LGOdF1ggAAU91pJ-GWSAPAftY-gyIjQdUdI4qIEwslpm4yXkU4ltZGV2aWNlS2V5SW5mb7kAAWlkZXZpY2VLZXmkAQIgASFYIIgYecp6I4sZvw9MH4wA6aLhm6em9z6ukrhR1N4bUIVZIlggoxS1OAORJ7XNUHNfVFGeM8E0RQVFxWA62fJj-sxW03dnZG9jVHlwZXVvcmcuaXNvLjE4MDEzLjUuMS5tRExsdmFsaWRpdHlJbmZvuQAEZnNpZ25lZMB0MjAyMy0xMC0yNFQwMDowMDowMFppdmFsaWRGcm9twHQyMDIzLTEwLTI0VDAwOjAwOjAwWmp2YWxpZFVudGlswHQyMDUwLTEwLTI0VDAwOjAwOjAwWm5leHBlY3RlZFVwZGF0ZfdYQCuk_3TNOL-d7XCpcWK62Xd7j7nBVKettDLfYovq0UGxJmmiLcbGESoHNK_t7Eem1NM5nbxVby6e97wC-vOa9QpsZGV2aWNlU2lnbmVkuQACam5hbWVTcGFjZXPYGFgguQABcWNvbS5mb29iYXItZGV2aWNluQABZHRlc3QZBNJqZGV2aWNlQXV0aLkAAm9kZXZpY2VTaWduYXR1cmWEQ6EBJqD3WED1J2uMcDM9U4ueL9jHIDYeOlKWfWo2hcnTCBMbd4K5gsc9WoeefXiD-m_kOg_Z1HQr2J6S2Rkq6tLj8Vt0hFlUaWRldmljZU1hY_ejZ2RvY1R5cGV2b3JnLmlzby4xODAxMy41LjEubURMMmxpc3N1ZXJTaWduZWS5AAJqbmFtZVNwYWNlc6Fxb3JnLmlzby4xODAxMy41LjGB2BhYZaRoZGlnZXN0SUQAcWVsZW1lbnRJZGVudGlmaWVya2ZhbWlseV9uYW1lbGVsZW1lbnRWYWx1ZWVKb25lc2ZyYW5kb21YICjmHbyr5i-QHqN7DrJ_a7n13KdAoXcSMry4Eg4w5fgzamlzc3VlckF1dGiEQ6EBJqIEWDF6RG5hZXJ0elZZVzhSRXp6ZWc5dEFFRDdxNVBYU1dpaVBWZEJxaHVWaUVXVHVvOExhGCGBWQIuMIICKjCCAdCgAwIBAgIUV8bM0wi95D7KN0TyqHE42ru4hOgwCgYIKoZIzj0EAwIwUzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMQ8wDQYDVQQHDAZBbGJhbnkxDzANBgNVBAoMBk5ZIERNVjEPMA0GA1UECwwGTlkgRE1WMB4XDTIzMDkxNDE0NTUxOFoXDTMzMDkxMTE0NTUxOFowUzELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMQ8wDQYDVQQHDAZBbGJhbnkxDzANBgNVBAoMBk5ZIERNVjEPMA0GA1UECwwGTlkgRE1WMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEiTwtg0eQbcbNabf2Nq9L_VM_lhhPCq2s0Qgw2kRx29tgrBcNHPxTT64tnc1Ij3dH_fl42SXqMenpCDw4K6ntU6OBgTB_MB0GA1UdDgQWBBSrbS4DuR1JIkAzj7zK3v2TM-r2xzAfBgNVHSMEGDAWgBSrbS4DuR1JIkAzj7zK3v2TM-r2xzAPBgNVHRMBAf8EBTADAQH_MCwGCWCGSAGG-EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAKBggqhkjOPQQDAgNIADBFAiAJ_Qyrl7A-ePZOdNfc7ohmjEdqCvxaos6__gfTvncuqQIhANo4q8mKCA9J8k_-zh__yKbN1bLAtdqPx7dnrDqV3Lg-WQRS2BhZBE25AAZndmVyc2lvbmMxLjBvZGlnZXN0QWxnb3JpdGhtZ1NIQS0yNTZsdmFsdWVEaWdlc3RzoXFvcmcuaXNvLjE4MDEzLjUuMbYAWCBspl7DfYDOvpurPt2i7bECpR_CxWkc0ftjJb3IWQKizAFYINJd2OxXubpYtP1fQuq_m5qj1WZfggyxQJB176PKesjZAlgg2fpl2GcK-NiHunbydaPffpIEBsk0azuhsCMDtF0sGUMDWCB7dncdX3bhyUgGEH-Nt_0XDdxnTDhm7MD1LN3N_9UG2gRYIPD0bJr8et4oN_yE-v4OVgLmQXBncX2h74iwKfQwwnjmBVggO91tvX3RnpbOKiK2uWxG0afEarBFyuokHfLpZHQNRXEGWCA7R0deBjGLG6gDIXiLiluD9QAyX-kU3ZivuE3CHMc-jQdYIJicukNkihAFdmr2hkU_Yn-1IybmkSGG4fRkV5fbtOEjCFgg65A7sq2OzMZkOwLx3G2wRrWvLXvAN-aqgFGkblUiGOEJWCDtuAgjFwjiC5uqQNVX5oPWBCi0Su_rKRaElw3I7MyKZQpYIIwZrXczzPMQx4qWLY5gaj7k6FG62XUCO-HbXDyI-P9VC1ggJQGFWrCOV4UoXa-djAkWtMKfb4qyvcWSuwx87VtgCpMMWCCXDoaqc3ujqRNNxt-57hKXe5XnCV5MxKXGDyay8ld8_g1YIPr06swH7rUA6RJn9xqQz8zsg1ZVL8qljqAqx7XqmJ9XDlggjOyvASBPEZ9rowf-9Do8JCD17tDJH7i-PkhikRRyCwMPWCBmxeurMT_vkKplQN4wXHXnJ_Qt4My1-gQHstZ3ZLJuuBBYIJ-V_3fPcn4YEGlWBHorbYplnLHOudZj86bh-nAQ2NjREVggYI5T0DZ5D6F2pk5vBPQYA1FFCKqrYfZYTFUqdjH3aG4SWCDZZ61yZ36JdMPOzfxTYc37jZRXEUWCX62s6U6RGOjXuRNYIDNsxIZpiBHzPLpOHZ5BWPfB1SNbOWuEkpNwmE1BCHoBFFggFiDdelk38QU9OYNQc6-runF9lQ6SMWXa_mpDezO3OpYVWCCGzVNBY_K1t1Z5jMRhCkBF0M1F_KlYCpFe8-FiCtTvf21kZXZpY2VLZXlJbmZvuQABaWRldmljZUtleaQBAiABIVggiBh5ynojixm_D0wfjADpouGbp6b3Pq6SuFHU3htQhVkiWCCjFLU4A5Entc1Qc19UUZ4zwTRFBUXFYDrZ8mP6zFbTd2dkb2NUeXBldm9yZy5pc28uMTgwMTMuNS4xLm1ETDJsdmFsaWRpdHlJbmZvuQAEZnNpZ25lZMB0MjAyMy0xMC0yNFQwMDowMDowMFppdmFsaWRGcm9twHQyMDIzLTEwLTI0VDAwOjAwOjAwWmp2YWxpZFVudGlswHQyMDUwLTEwLTI0VDAwOjAwOjAwWm5leHBlY3RlZFVwZGF0ZfdYQDCYDNssyMNy_WCG58n1hWFNMWvVFbDxBkKmyroaku2P6Esbgc2tAq2--QdqQD1719lO_8a_Ksy_rNQimT_x2ZNsZGV2aWNlU2lnbmVkuQACam5hbWVTcGFjZXPYGFgguQABcWNvbS5mb29iYXItZGV2aWNluQABZHRlc3QZBNJqZGV2aWNlQXV0aLkAAm9kZXZpY2VTaWduYXR1cmWEQ6EBJqD3WEDNmpI321UjyotZjGVsv4NUNVdXGVVxfgyjLiMqp4ukNWJ53psdhfY3LlP4CIJcmo8vAu9Voko0-VcU1Z-PcBCNaWRldmljZU1hY_dmc3RhdHVzAA'; + const mdocBase64UrlUniversityCustomNamespace = 'uQACam5hbWVTcGFjZXOhanVuaXZlcnNpdHmE2BhYZqRoZGlnZXN0SUQAcWVsZW1lbnRJZGVudGlmaWVyaGxvY2F0aW9ubGVsZW1lbnRWYWx1ZWlpbm5zYnJ1Y2tmcmFuZG9tWCAw6CXtd4ubXAr6uLB1GnfRyHVqhjH1_73iDASmcZefQtgYWGOkaGRpZ2VzdElEAXFlbGVtZW50SWRlbnRpZmllcmZkZWdyZWVsZWxlbWVudFZhbHVlaGJhY2hlbG9yZnJhbmRvbVgglzuY8jgQd7y_wuH47AYfzlEfzz827RRjo4k845nK5DLYGFhhpGhkaWdlc3RJRAJxZWxlbWVudElkZW50aWZpZXJkbmFtZWxlbGVtZW50VmFsdWVoSm9obiBEb2VmcmFuZG9tWCDtU0gwjxNPz1q2AjgYWkAGWSHDq7BsXzns_aMMNeVkE9gYWGGkaGRpZ2VzdElEA3FlbGVtZW50SWRlbnRpZmllcmNub3RsZWxlbWVudFZhbHVlaWRpc2Nsb3NlZGZyYW5kb21YICSQ7u_6OBRr8V3c5hmIeL-NKBPEaUGWPxkv8TwTPdTbamlzc3VlckF1dGiEQ6EBJqIEWDF6RG5hZWRydmd5bXpvZnhvYTRWb1VDOFJRemdwMVJnZnBCTkw1SFZuV1NKb1oyeXJhGCGBWPwwgfkwgaCgAwIBAgIQTWQTeD9zo_1knyJtFXU2hzAKBggqhkjOPQQDAjANMQswCQYDVQQGEwJERTAeFw0yNDEwMzAxNDA5MDRaFw0yNTEwMzAxNDA5MDRaMA0xCzAJBgNVBAYTAkRFMDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgACx4zJR4xIci9iFJPsMUX-mu4Khh63a_hjQKef7NyM2cOjAjAAMAoGCCqGSM49BAMCA0gAMEUCIQCRXFKtPshVsgBYMjH1-VA2sU2bphzWRLYrYvALfGTBdQIgLHF1n5J7KAiDhPTjmx3xxBlCVMYan_SKqXKxZVuO1M1ZAdDYGFkBy7kABmd2ZXJzaW9uYzEuMG9kaWdlc3RBbGdvcml0aG1nU0hBLTI1Nmx2YWx1ZURpZ2VzdHOhanVuaXZlcnNpdHmkAFggkN_ol8cnR2iCh3YLAYSt_-gt_hUT9ZIlm1LCS2kHW3gBWCAz2zbutIrJdbeAGi1T64jyst4PtE9WwjJK2-py9dyafQJYIHoRBZqOeV9IhNcbYsK46RaA95WyT7mq6-yqoh6j6Ds-A1ggwzOqmOGhsmiCMaEugAowlgUkzNxl0tD4CgbIx5u1Xx9tZGV2aWNlS2V5SW5mb7kAAWlkZXZpY2VLZXmkAQIgASFYIHhQ3snZrFRdtxGAB4HPsgmtZXHpzztrXjQXPRurqHtwIlggG9V2VQ1XAa9BRwxpgguzfhtP0gz8M52TWYDLwbe0P4ZnZG9jVHlwZXFvcmcuZXUudW5pdmVyc2l0eWx2YWxpZGl0eUluZm-5AARmc2lnbmVkwHQyMDI0LTEwLTMwVDE0OjA5OjA0Wml2YWxpZEZyb23AdDIwMjQtMTAtMzBUMTQ6MDk6MDRaanZhbGlkVW50aWzAdDIwMjUtMTAtMzBUMTQ6MDk6MDRabmV4cGVjdGVkVXBkYXRl91hAjkeOGOUm0CToTYOf0x3mtHFIzwT_LTHUYvcWaWrksmBOuUgZekkHAo9Bl9UTI0NKhEBIbKv9mGWHwJUgQ_1AIw'; @@ -159,6 +162,53 @@ describe('evaluate mdoc', () => { }); }); + it('evaluatePresentation with mso_mdoc format where mdoc device response contains multiple documents', async () => { + const definition: PresentationDefinitionV2 = { + id: 'mDL-sample-req', + input_descriptors: [ + { + id: 'org.iso.18013.5.1.mDL2', + format: { + mso_mdoc: { + alg: ['ES256', 'ES384', 'ES512', 'EdDSA', 'ESB256', 'ESB320', 'ESB384', 'ESB512'], + }, + }, + constraints: { + fields: [ + { + path: ["$['org.iso.18013.5.1']['family_name']"], + intent_to_retain: false, + }, + ], + limit_disclosure: 'required', + }, + }, + ], + }; + const submission = { + definition_id: definition.id, + descriptor_map: [ + { + format: 'mso_mdoc', + id: 'org.iso.18013.5.1.mDL2', + path: '$[0]', + }, + ], + id: '2d0b0be7-9d91-4760-ad58-f204f9f39de7', + }; + const evaluateResults = pex.evaluatePresentation(definition, [mdocBase64UrlMultipleDocumentsPresentation], { + presentationSubmission: submission, + }); + + expect(evaluateResults).toEqual({ + presentations: [mdocBase64UrlMultipleDocumentsPresentation], + areRequiredCredentialsPresent: Status.INFO, + warnings: [], + errors: [], + value: submission, + }); + }); + it('evaluatePresentation with mso_mdoc format generating a submission', async () => { const presentationDefinition = getPresentationDefinitionV2(); const evaluateResults = pex.evaluatePresentation(presentationDefinition, [mdocBase64UrlUniversityPresentation], {