@bedrock/vc-verifier 22.2.1 → 23.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/di.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * Copyright (c) 2018-2025 Digital Bazaar, Inc. All rights reserved.
3
3
  */
4
4
  import * as vc from '@digitalbazaar/vc';
5
- import {checkStatus as _checkStatus} from './status.js';
5
+ import {createCheckStatus} from './status.js';
6
6
  import {createDocumentLoader} from './documentLoader.js';
7
7
  import {createSuites} from './suites.js';
8
8
 
@@ -14,7 +14,7 @@ export async function verifyCredential({
14
14
 
15
15
  // only check credential status when option is set
16
16
  const checkStatus = checks.includes('credentialStatus') ?
17
- _checkStatus : () => ({verified: true});
17
+ createCheckStatus({config}) : () => ({verified: true});
18
18
 
19
19
  const result = await vc.verifyCredential({
20
20
  credential,
@@ -59,7 +59,7 @@ export async function verifyPresentation({
59
59
  documentLoader: await createDocumentLoader({config}),
60
60
  suite: createSuites(),
61
61
  unsignedPresentation: !checks.includes('proof'),
62
- checkStatus: _checkStatus,
62
+ checkStatus: createCheckStatus({config}),
63
63
  includeCredentials: true
64
64
  };
65
65
  return vc.verify(verifyOptions);
@@ -46,10 +46,12 @@ bedrock.events.on('bedrock.init', () => {
46
46
  *
47
47
  * @param {object} options - The options to use.
48
48
  * @param {object} options.config - The verifier instance config.
49
+ * @param {Set} [options.remoteUrlAllowList] - Remote URLs that are
50
+ * specifically allowed to be loaded (used for status list checks).
49
51
  *
50
52
  * @returns {Promise<Function>} The document loader.
51
53
  */
52
- export async function createDocumentLoader({config} = {}) {
54
+ export async function createDocumentLoader({config, remoteUrlAllowList} = {}) {
53
55
  const contextDocumentLoader = await createContextDocumentLoader(
54
56
  {config, serviceType});
55
57
 
@@ -84,10 +86,12 @@ export async function createDocumentLoader({config} = {}) {
84
86
  // try to resolve URL through context doc loader
85
87
  return await contextDocumentLoader(url);
86
88
  } catch(e) {
87
- // use web loader if configured and instance config allows it and
88
- // the url starts with `http`, and the core config allows it
89
+ // use web loader if configured and instance config allows it (or it is
90
+ // allowed by an allow list) and the url starts with `http` (and the core
91
+ // config allows it, i.e., `webLoader` exists)
89
92
  const allowRemoteContexts = !config.verifyOptions?.documentLoader ||
90
- config.verifyOptions.documentLoader.allowRemoteContexts;
93
+ config.verifyOptions.documentLoader.allowRemoteContexts ||
94
+ remoteUrlAllowList?.has(url);
91
95
  if(allowRemoteContexts &&
92
96
  url.startsWith('http') && e.name === 'NotFoundError' && webLoader) {
93
97
  return webLoader(url);
package/lib/index.js CHANGED
@@ -21,7 +21,6 @@ bedrock.events.on('bedrock.init', async () => {
21
21
  const updateConfigBody = structuredClone(schemas.updateConfigBody);
22
22
  const schemasToUpdate = [createConfigBody, updateConfigBody];
23
23
  for(const schema of schemasToUpdate) {
24
- // verify options
25
24
  schema.properties.verifyOptions = verifyOptions;
26
25
  }
27
26
 
@@ -36,6 +35,7 @@ bedrock.events.on('bedrock.init', async () => {
36
35
  validation: {
37
36
  createConfigBody,
38
37
  updateConfigBody,
38
+ validateConfigFn,
39
39
  // require these zcaps (by reference ID)
40
40
  zcapReferenceIds: [{
41
41
  referenceId: 'edv',
@@ -66,3 +66,20 @@ bedrock.events.on('bedrock.init', async () => {
66
66
  await initializeServiceAgent({serviceType});
67
67
  });
68
68
  });
69
+
70
+ async function validateConfigFn({config} = {}) {
71
+ try {
72
+ // set default `verifyOptions` if not given
73
+ const {verifyOptions} = config;
74
+ if(verifyOptions === undefined) {
75
+ config.verifyOptions = {
76
+ documentLoader: {
77
+ allowRemoteContexts: false
78
+ }
79
+ };
80
+ }
81
+ } catch(error) {
82
+ return {valid: false, error};
83
+ }
84
+ return {valid: true};
85
+ }
package/lib/status.js CHANGED
@@ -14,6 +14,7 @@ import {
14
14
  statusTypeMatches as statusList2020StatusTypeMatches
15
15
  } from '@digitalbazaar/vc-status-list';
16
16
  import assert from 'assert-plus';
17
+ import {createDocumentLoader} from './documentLoader.js';
17
18
 
18
19
  const handlerMap = new Map();
19
20
  handlerMap.set('BitstringStatusListEntry', {
@@ -29,26 +30,41 @@ handlerMap.set('StatusList2021Entry', {
29
30
  statusTypeMatches: statusList2020StatusTypeMatches
30
31
  });
31
32
 
32
- export async function checkStatus(options = {}) {
33
- assert.object(options, 'options');
34
- assert.object(options.credential, 'options.credential');
33
+ export function createCheckStatus({config} = {}) {
34
+ return async function checkStatus(options = {}) {
35
+ assert.object(options, 'options');
36
+ assert.object(options.credential, 'options.credential');
35
37
 
36
- try {
37
- const {credential} = options;
38
- const {credentialStatus} = credential;
39
- if(!credentialStatus) {
40
- // no status to check
41
- return {verified: true};
42
- }
38
+ try {
39
+ const {credential} = options;
40
+ const {credentialStatus} = credential;
41
+ if(!credentialStatus) {
42
+ // no status to check
43
+ return {verified: true};
44
+ }
43
45
 
44
- const handlers = handlerMap.get(credentialStatus.type);
45
- if(!(handlers && handlers.statusTypeMatches({credential}))) {
46
- throw new Error(
47
- `Unsupported credentialStatus type "${credentialStatus.type}".`);
48
- }
46
+ const handlers = handlerMap.get(credentialStatus.type);
47
+ if(!(handlers && handlers.statusTypeMatches({credential}))) {
48
+ throw new Error(
49
+ `Unsupported credentialStatus type "${credentialStatus.type}".`);
50
+ }
49
51
 
50
- return await handlers.checkStatus(options);
51
- } catch(error) {
52
- return {verified: false, error};
53
- }
52
+ // document loader needs to only allow web loading of status
53
+ // list VCs, nothing else
54
+ const documentLoader = await createDocumentLoader({
55
+ config,
56
+ remoteUrlAllowList: new Set([
57
+ credentialStatus.statusListCredential ??
58
+ credentialStatus.revocationListCredential
59
+ ])
60
+ });
61
+ options = {
62
+ ...options,
63
+ documentLoader
64
+ };
65
+ return await handlers.checkStatus(options);
66
+ } catch(error) {
67
+ return {verified: false, error};
68
+ }
69
+ };
54
70
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bedrock/vc-verifier",
3
- "version": "22.2.1",
3
+ "version": "23.0.0",
4
4
  "type": "module",
5
5
  "description": "Bedrock VC Verifier",
6
6
  "main": "./lib/index.js",
@@ -26,7 +26,7 @@
26
26
  "homepage": "https://github.com/digitalbazaar/bedrock-vc-verifier",
27
27
  "dependencies": {
28
28
  "@digitalbazaar/bbs-2023-cryptosuite": "^2.0.1",
29
- "@digitalbazaar/cborld": "^7.2.0",
29
+ "@digitalbazaar/cborld": "^8.0.0",
30
30
  "@digitalbazaar/data-integrity": "^2.5.0",
31
31
  "@digitalbazaar/ecdsa-2019-cryptosuite": "^2.0.0",
32
32
  "@digitalbazaar/ecdsa-jcs-2019-cryptosuite": "^1.0.0",
@@ -45,7 +45,7 @@
45
45
  "@digitalbazaar/vc-bitstring-status-list": "^2.0.1",
46
46
  "@digitalbazaar/vc-revocation-list": "^7.0.0",
47
47
  "@digitalbazaar/vc-status-list": "^8.0.1",
48
- "@digitalbazaar/vpqr": "^5.1.0",
48
+ "@digitalbazaar/vpqr": "^6.0.0",
49
49
  "assert-plus": "^1.0.0",
50
50
  "bnid": "^3.0.0",
51
51
  "body-parser": "^1.20.3",