diff --git a/lib/openId.js b/lib/openId.js index cb521be..b03f6dd 100644 --- a/lib/openId.js +++ b/lib/openId.js @@ -916,6 +916,23 @@ async function _processAuthorizationResponse({ const {authorizationRequest, step} = arRequest; ({exchange} = arRequest); + // FIXME: if the VP is enveloped, remove the envelope to validate or + // run validation code after verification if necessary + + // FIXME: check the VP against the presentation submission if requested + // FIXME: check the VP against "trustedIssuer" in VPR, if provided + const {presentationSchema} = step; + if(presentationSchema) { + // validate the received VP + console.log('run presentation schema'); + const {jsonSchema: schema} = presentationSchema; + const validate = compile({schema}); + const {valid, error} = validate(presentation); + if(!valid) { + throw error; + } + } + // verify the received VP const {verifiablePresentationRequest} = await oid4vp.toVpr( {authorizationRequest}); @@ -928,9 +945,6 @@ async function _processAuthorizationResponse({ expectedChallenge: authorizationRequest.nonce }); - // FIXME: check the VP against the presentation submission if requested - // FIXME: check the VP against "trustedIssuer" in VPR, if provided - // store VP results in variables associated with current step const currentStep = exchange.step; if(!exchange.variables.results) { diff --git a/lib/vcapi.js b/lib/vcapi.js index 282c767..1289959 100644 --- a/lib/vcapi.js +++ b/lib/vcapi.js @@ -96,6 +96,9 @@ export async function processExchange({req, res, workflow, exchange}) { return; } + // FIXME: if the VP is enveloped, remove the envelope to validate or + // run validation code after verification if necessary + const {presentationSchema} = step; if(presentationSchema) { // validate the received VP diff --git a/test/mocha/35-oid4vci-oid4vp.js b/test/mocha/35-oid4vci-oid4vp.js index 284dc4e..46bcdbf 100644 --- a/test/mocha/35-oid4vci-oid4vp.js +++ b/test/mocha/35-oid4vci-oid4vp.js @@ -7,10 +7,13 @@ import { } from '@digitalbazaar/oid4-client'; import {agent} from '@bedrock/https-agent'; import {httpClient} from '@digitalbazaar/http-client'; +import {klona} from 'klona'; import {mockData} from './mock.data.js'; import {v4 as uuid} from 'uuid'; -const {baseUrl, didAuthnCredentialTemplate} = mockData; +const { + baseUrl, didAuthnCredentialTemplate, strictDegreePresentationSchema +} = mockData; describe('exchange w/OID4VCI delivery + OID4VP VC requirement', () => { let capabilityAgent; @@ -126,6 +129,7 @@ describe('exchange w/OID4VCI delivery + OID4VP VC requirement', () => { { "createChallenge": true, "verifiablePresentationRequest": verifiablePresentationRequest, + "presentationSchema": presentationSchema, "openId": { "createAuthorizationRequest": "authorizationRequest", "client_id_scheme": "redirect_uri", @@ -148,6 +152,8 @@ describe('exchange w/OID4VCI delivery + OID4VP VC requirement', () => { workflowRootZcap = `urn:zcap:root:${encodeURIComponent(workflowId)}`; }); + // FIXME: add invalid issuer test that will fail against `presentationSchema` + it('should pass w/ pre-authorized code flow', async () => { // pre-authorized flow, issuer-initiated const credentialId = `urn:uuid:${uuid()}`; @@ -171,6 +177,12 @@ describe('exchange w/OID4VCI delivery + OID4VP VC requirement', () => { }], domain: baseUrl }; + const jsonSchema = klona(strictDegreePresentationSchema); + // FIXME: create a function to inject required `issuer` value + jsonSchema.properties.verifiableCredential.oneOf[0] + .properties.issuer = {const: verifiableCredential.issuer}; + jsonSchema.properties.verifiableCredential.oneOf[1].items + .properties.issuer = {const: verifiableCredential.issuer}; const { exchangeId, openIdUrl: issuanceUrl @@ -187,6 +199,10 @@ describe('exchange w/OID4VCI delivery + OID4VP VC requirement', () => { variables: { credentialId, verifiablePresentationRequest: vpr, + presentationSchema: { + type: 'JsonSchema', + jsonSchema + }, openId: { createAuthorizationRequest: 'authorizationRequest' }