From a86995ec92cc7e1dabd458ced0e47a93d43f94c5 Mon Sep 17 00:00:00 2001 From: James Chartrand Date: Wed, 9 Oct 2024 12:21:35 -0400 Subject: [PATCH 1/7] adjust for VC-API spec --- src/app.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/app.js b/src/app.js index de8b483..e2643fa 100644 --- a/src/app.js +++ b/src/app.js @@ -86,8 +86,9 @@ export async function build (opts = {}) { try { const tenantName = req.params.tenantName // the issuer instance/tenant with which to sign const authHeader = req.headers.authorization - const unSignedVC = req.body - + const body = req.body + const unSignedVC = body.credential ? body.credential : body + await verifyAuthHeader(authHeader, tenantName) // NOTE: we throw the error here which will then be caught by middleware errorhandler if (!unSignedVC || !Object.keys(unSignedVC).length) throw new IssuingException(400, 'A verifiable credential must be provided in the body') @@ -95,7 +96,7 @@ export async function build (opts = {}) { ? await callService(`http://${statusService}/credentials/status/allocate`, unSignedVC) : unSignedVC const signedVC = await callService(`http://${signingService}/instance/${tenantName}/credentials/sign`, vcWithStatus) - return res.json(signedVC) + return res.status(201).json(signedVC) } catch (error) { // have to catch async errors and forward error handling // middleware From 755dc4fb72d654b1ee425244f7bc34043240c2d5 Mon Sep 17 00:00:00 2001 From: James Chartrand Date: Mon, 21 Oct 2024 17:49:27 -0400 Subject: [PATCH 2/7] fix check on vc posted to issue endpoint --- src/app.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/app.js b/src/app.js index e2643fa..f56afd2 100644 --- a/src/app.js +++ b/src/app.js @@ -22,6 +22,10 @@ async function callService (endpoint, body) { return data } +function isNotValidVC(unSignedVC) { + return !unSignedVC || !Object.keys(unSignedVC).length || !unSignedVC.credentialSubject +} + export async function build (opts = {}) { const { enableStatusService, @@ -88,10 +92,10 @@ export async function build (opts = {}) { const authHeader = req.headers.authorization const body = req.body const unSignedVC = body.credential ? body.credential : body - + 422 await verifyAuthHeader(authHeader, tenantName) // NOTE: we throw the error here which will then be caught by middleware errorhandler - if (!unSignedVC || !Object.keys(unSignedVC).length) throw new IssuingException(400, 'A verifiable credential must be provided in the body') + if (isNotValidVC(unSignedVC)) throw new IssuingException(422, 'A verifiable credential must be provided in the body') const vcWithStatus = enableStatusService ? await callService(`http://${statusService}/credentials/status/allocate`, unSignedVC) : unSignedVC From 9750713c1adcbdeca74f154221a3f45d6f565613 Mon Sep 17 00:00:00 2001 From: James Chartrand Date: Tue, 22 Oct 2024 09:25:02 -0400 Subject: [PATCH 3/7] fix testing/lint errors --- src/app.js | 3 +-- src/app.test.js | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/app.js b/src/app.js index f56afd2..f5c41c1 100644 --- a/src/app.js +++ b/src/app.js @@ -22,7 +22,7 @@ async function callService (endpoint, body) { return data } -function isNotValidVC(unSignedVC) { +function isNotValidVC (unSignedVC) { return !unSignedVC || !Object.keys(unSignedVC).length || !unSignedVC.credentialSubject } @@ -92,7 +92,6 @@ export async function build (opts = {}) { const authHeader = req.headers.authorization const body = req.body const unSignedVC = body.credential ? body.credential : body - 422 await verifyAuthHeader(authHeader, tenantName) // NOTE: we throw the error here which will then be caught by middleware errorhandler if (isNotValidVC(unSignedVC)) throw new IssuingException(422, 'A verifiable credential must be provided in the body') diff --git a/src/app.test.js b/src/app.test.js index 6fe222b..7271845 100644 --- a/src/app.test.js +++ b/src/app.test.js @@ -64,12 +64,12 @@ describe('api', () => { }) describe('POST /instance/:instanceId/credentials/issue', () => { - it('returns 400 if no body', done => { + it('returns 422 if no body', done => { request(app) .post('/instance/protected_test/credentials/issue') .set('Authorization', `Bearer ${testTenantToken}`) .expect('Content-Type', /json/) - .expect(400, done) + .expect(422, done) }) it('returns 401 if tenant token is missing from auth header', done => { @@ -88,7 +88,7 @@ describe('api', () => { .send(getUnsignedVC()) expect(response.header['content-type']).to.have.string('json') - expect(response.status).to.equal(200) + expect(response.status).to.equal(201) expect(response.body) }) @@ -137,7 +137,7 @@ describe('api', () => { .send(sentCred) expect(response.header['content-type']).to.have.string('json') - expect(response.status).to.equal(200) + expect(response.status).to.equal(201) const returnedCred = JSON.parse(JSON.stringify(response.body)) // this proof value comes from the nock: From 52e86f72cc40f0f5e6470fd7e912dbdaf76493f9 Mon Sep 17 00:00:00 2001 From: James Chartrand Date: Tue, 22 Oct 2024 11:51:31 -0400 Subject: [PATCH 4/7] more vc-api conformance test fixes --- src/app.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/app.js b/src/app.js index f5c41c1..fd7f3bb 100644 --- a/src/app.js +++ b/src/app.js @@ -22,8 +22,15 @@ async function callService (endpoint, body) { return data } +function isArrayOfStrings(arrayToCheck) { + return arrayToCheck && Array.isArray(arrayToCheck) && arrayToCheck.length && arrayToCheck.every(item=> {return (item && typeof item == "string")}) +} + function isNotValidVC (unSignedVC) { - return !unSignedVC || !Object.keys(unSignedVC).length || !unSignedVC.credentialSubject + if (!unSignedVC) return true; + const isContextPropertyValid = isArrayOfStrings(unSignedVC['@context']) + const isTypePropertyValid = isArrayOfStrings(unSignedVC.type) + return ! (isContextPropertyValid && isTypePropertyValid) } export async function build (opts = {}) { @@ -94,7 +101,7 @@ export async function build (opts = {}) { const unSignedVC = body.credential ? body.credential : body await verifyAuthHeader(authHeader, tenantName) // NOTE: we throw the error here which will then be caught by middleware errorhandler - if (isNotValidVC(unSignedVC)) throw new IssuingException(422, 'A verifiable credential must be provided in the body') + if (isNotValidVC(unSignedVC)) throw new IssuingException(422, 'A valid verifiable credential must be provided') const vcWithStatus = enableStatusService ? await callService(`http://${statusService}/credentials/status/allocate`, unSignedVC) : unSignedVC From 56e93fc9c658b3950aa69bf796abdc818084111e Mon Sep 17 00:00:00 2001 From: James Chartrand Date: Tue, 22 Oct 2024 13:48:26 -0400 Subject: [PATCH 5/7] fix linting errors --- src/app.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app.js b/src/app.js index fd7f3bb..16b5614 100644 --- a/src/app.js +++ b/src/app.js @@ -22,15 +22,15 @@ async function callService (endpoint, body) { return data } -function isArrayOfStrings(arrayToCheck) { - return arrayToCheck && Array.isArray(arrayToCheck) && arrayToCheck.length && arrayToCheck.every(item=> {return (item && typeof item == "string")}) +function isArrayOfStrings (arrayToCheck) { + return arrayToCheck && Array.isArray(arrayToCheck) && arrayToCheck.length && arrayToCheck.every(item => { return (item && typeof item === 'string') }) } function isNotValidVC (unSignedVC) { - if (!unSignedVC) return true; + if (!unSignedVC) return true const isContextPropertyValid = isArrayOfStrings(unSignedVC['@context']) const isTypePropertyValid = isArrayOfStrings(unSignedVC.type) - return ! (isContextPropertyValid && isTypePropertyValid) + return !(isContextPropertyValid && isTypePropertyValid) } export async function build (opts = {}) { From d6d6904ce2a2a50059548c9ac6a6a7e58c11fd41 Mon Sep 17 00:00:00 2001 From: James Chartrand Date: Tue, 22 Oct 2024 15:51:57 -0400 Subject: [PATCH 6/7] fix issuer property check for existence --- src/app.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/app.js b/src/app.js index 16b5614..cb9d9ab 100644 --- a/src/app.js +++ b/src/app.js @@ -23,14 +23,15 @@ async function callService (endpoint, body) { } function isArrayOfStrings (arrayToCheck) { - return arrayToCheck && Array.isArray(arrayToCheck) && arrayToCheck.length && arrayToCheck.every(item => { return (item && typeof item === 'string') }) + return (arrayToCheck != null) && Array.isArray(arrayToCheck) && arrayToCheck.length && arrayToCheck.every(item => { return (item && typeof item === 'string') }) } -function isNotValidVC (unSignedVC) { - if (!unSignedVC) return true +function isValidVC (unSignedVC) { + if (!unSignedVC) return false const isContextPropertyValid = isArrayOfStrings(unSignedVC['@context']) const isTypePropertyValid = isArrayOfStrings(unSignedVC.type) - return !(isContextPropertyValid && isTypePropertyValid) + const isIssuerPropertyValid = (unSignedVC.issuer != null) && !Array.isArray(unSignedVC.issuer) && (typeof unSignedVC.issuer === 'string' || typeof unSignedVC.issuer === 'object') + return (isContextPropertyValid && isTypePropertyValid && isIssuerPropertyValid) } export async function build (opts = {}) { @@ -101,7 +102,7 @@ export async function build (opts = {}) { const unSignedVC = body.credential ? body.credential : body await verifyAuthHeader(authHeader, tenantName) // NOTE: we throw the error here which will then be caught by middleware errorhandler - if (isNotValidVC(unSignedVC)) throw new IssuingException(422, 'A valid verifiable credential must be provided') + if (!isValidVC(unSignedVC)) throw new IssuingException(422, 'A valid verifiable credential must be provided') const vcWithStatus = enableStatusService ? await callService(`http://${statusService}/credentials/status/allocate`, unSignedVC) : unSignedVC From 96f8dcf32fe1c355e970eb9b57d3f39f5c122509 Mon Sep 17 00:00:00 2001 From: James Chartrand Date: Wed, 23 Oct 2024 10:48:29 -0400 Subject: [PATCH 7/7] add checks for credentialSubject --- src/app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app.js b/src/app.js index cb9d9ab..365a774 100644 --- a/src/app.js +++ b/src/app.js @@ -31,7 +31,8 @@ function isValidVC (unSignedVC) { const isContextPropertyValid = isArrayOfStrings(unSignedVC['@context']) const isTypePropertyValid = isArrayOfStrings(unSignedVC.type) const isIssuerPropertyValid = (unSignedVC.issuer != null) && !Array.isArray(unSignedVC.issuer) && (typeof unSignedVC.issuer === 'string' || typeof unSignedVC.issuer === 'object') - return (isContextPropertyValid && isTypePropertyValid && isIssuerPropertyValid) + const isCredentialSubjectPropertyValid = (unSignedVC.credentialSubject != null) && !Array.isArray(unSignedVC.credentialSubject) && (typeof unSignedVC.credentialSubject === 'object') + return (isContextPropertyValid && isTypePropertyValid && isIssuerPropertyValid && isCredentialSubjectPropertyValid) } export async function build (opts = {}) {