From be2aa3cc2d238ccf973ce527debe095b0ff96ceb Mon Sep 17 00:00:00 2001 From: Dave Longley Date: Mon, 14 Apr 2025 21:21:13 -0400 Subject: [PATCH] Add `includeCredentials` option. --- CHANGELOG.md | 6 +++++ lib/index.js | 12 ++++++--- test/10-verify.spec.js | 55 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 69 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04264b85..829f8e73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # @digitalbazaar/vc ChangeLog +## 7.2.0 - 2025-mm-dd + +### Added +- Add `includeCredentials` option to be passed to `verify()` to include + each `credential` in `credentialResults` when verifying a presentation. + ## 7.1.2 - 2025-03-17 ### Changed diff --git a/lib/index.js b/lib/index.js index 08c98de3..60a0ccdf 100644 --- a/lib/index.js +++ b/lib/index.js @@ -5,7 +5,7 @@ * @author David I. Lehn * * @license BSD 3-Clause License - * Copyright (c) 2017-2023 Digital Bazaar, Inc. + * Copyright (c) 2017-2025 Digital Bazaar, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -229,6 +229,8 @@ export async function derive({ * that clocks may be skewed when checking capability expiration date-times * against `date` and when comparing invocation proof creation time against * delegation proof creation time. + * @param {boolean} [options.includeCredentials=false] - Set to `true` to + * include the credentials in the credential results. * * @returns {Promise} The verification result. */ @@ -488,7 +490,7 @@ export async function signPresentation(options = {}) { * @returns {Promise} The verification result. */ async function _verifyPresentation(options = {}) { - const {presentation, unsignedPresentation} = options; + const {presentation, unsignedPresentation, includeCredentials} = options; _checkPresentation(presentation); @@ -508,7 +510,11 @@ async function _verifyPresentation(options = {}) { })); for(const [i, credentialResult] of credentialResults.entries()) { - credentialResult.credentialId = credentials[i].id; + const credential = credentials[i]; + credentialResult.credentialId = credential.id; + if(includeCredentials) { + credentialResult.credential = credential; + } } const allCredentialsVerified = credentialResults.every(r => r.verified); diff --git a/test/10-verify.spec.js b/test/10-verify.spec.js index 968f36df..b8501db8 100644 --- a/test/10-verify.spec.js +++ b/test/10-verify.spec.js @@ -1,5 +1,5 @@ /*! - * Copyright (c) 2019-2024 Digital Bazaar, Inc. All rights reserved. + * Copyright (c) 2019-2025 Digital Bazaar, Inc. All rights reserved. */ import * as bbs2023Cryptosuite from '@digitalbazaar/bbs-2023-cryptosuite'; import * as Bls12381Multikey from '@digitalbazaar/bls12-381-multikey'; @@ -806,6 +806,30 @@ for(const [version, mockCredential] of versionedCredentials) { result.verified.should.be.a('boolean'); result.verified.should.be.true; }); + it('includes credentials in verification results', async () => { + const challenge = uuid(); + + const {presentation, suite, documentLoader} = + await _generatePresentation({challenge, mockCredential, version}); + + const result = await vc.verify({ + challenge, + suite, + documentLoader, + presentation, + includeCredentials: true + }); + + if(result.error) { + const firstError = [].concat(result.error)[0]; + throw firstError; + } + result.verified.should.be.a('boolean'); + result.verified.should.be.true; + result.credentialResults.length.should.equal(1); + result.credentialResults[0].credential.should.deep.equal( + presentation.verifiableCredential[0]); + }); it('verifies an unsigned presentation', async () => { const { presentation, @@ -831,6 +855,35 @@ for(const [version, mockCredential] of versionedCredentials) { result.verified.should.be.a('boolean'); result.verified.should.be.true; }); + it('includes credentials in unsigned presentation results', async () => { + const { + presentation, + suite: vcSuite, + documentLoader, + } = await _generatePresentation({ + unsigned: true, + mockCredential, + version + }); + + const result = await vc.verify({ + documentLoader, + presentation, + suite: vcSuite, + unsignedPresentation: true, + includeCredentials: true + }); + + if(result.error) { + const firstError = [].concat(result.error)[0]; + throw firstError; + } + result.verified.should.be.a('boolean'); + result.verified.should.be.true; + result.credentialResults.length.should.equal(1); + result.credentialResults[0].credential.should.deep.equal( + presentation.verifiableCredential[0]); + }); }); describe(`VerifiablePresentations Version ${version} w/ multiple VCs`,