@interop/zcap 10.1.0 → 11.0.1

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.
Files changed (48) hide show
  1. package/README.md +21 -3
  2. package/dist/CapabilityDelegation.d.ts +173 -0
  3. package/dist/CapabilityDelegation.d.ts.map +1 -0
  4. package/dist/CapabilityDelegation.js +376 -0
  5. package/dist/CapabilityDelegation.js.map +1 -0
  6. package/dist/CapabilityInvocation.d.ts +151 -0
  7. package/dist/CapabilityInvocation.d.ts.map +1 -0
  8. package/dist/CapabilityInvocation.js +365 -0
  9. package/dist/CapabilityInvocation.js.map +1 -0
  10. package/dist/CapabilityProofPurpose.d.ts +203 -0
  11. package/dist/CapabilityProofPurpose.d.ts.map +1 -0
  12. package/dist/CapabilityProofPurpose.js +531 -0
  13. package/dist/CapabilityProofPurpose.js.map +1 -0
  14. package/dist/constants.d.ts +11 -0
  15. package/dist/constants.d.ts.map +1 -0
  16. package/dist/constants.js +23 -0
  17. package/dist/constants.js.map +1 -0
  18. package/dist/index.d.ts +25 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +40 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/types.d.ts +224 -0
  23. package/dist/types.d.ts.map +1 -0
  24. package/dist/types.js +2 -0
  25. package/dist/types.js.map +1 -0
  26. package/dist/utils.d.ts +250 -0
  27. package/dist/utils.d.ts.map +1 -0
  28. package/dist/utils.js +591 -0
  29. package/dist/utils.js.map +1 -0
  30. package/package.json +47 -34
  31. package/lib/CapabilityDelegation.js +0 -312
  32. package/lib/CapabilityInvocation.js +0 -343
  33. package/lib/CapabilityProofPurpose.js +0 -538
  34. package/lib/constants.js +0 -32
  35. package/lib/index.js +0 -55
  36. package/lib/utils.js +0 -673
  37. package/types/lib/CapabilityDelegation.d.ts +0 -101
  38. package/types/lib/CapabilityDelegation.d.ts.map +0 -1
  39. package/types/lib/CapabilityInvocation.d.ts +0 -100
  40. package/types/lib/CapabilityInvocation.d.ts.map +0 -1
  41. package/types/lib/CapabilityProofPurpose.d.ts +0 -126
  42. package/types/lib/CapabilityProofPurpose.d.ts.map +0 -1
  43. package/types/lib/constants.d.ts +0 -15
  44. package/types/lib/constants.d.ts.map +0 -1
  45. package/types/lib/index.d.ts +0 -42
  46. package/types/lib/index.d.ts.map +0 -1
  47. package/types/lib/utils.d.ts +0 -308
  48. package/types/lib/utils.d.ts.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@interop/zcap",
3
- "version": "10.1.0",
3
+ "version": "11.0.1",
4
4
  "description": "Authorization Capabilities reference implementation.",
5
5
  "homepage": "https://github.com/interop-alliance/zcap",
6
6
  "author": {
@@ -19,51 +19,64 @@
19
19
  "type": "module",
20
20
  "exports": {
21
21
  ".": {
22
- "types": "./types/lib/index.d.ts",
23
- "default": "./lib/index.js"
22
+ "types": "./dist/index.d.ts",
23
+ "react-native": "./dist/index.js",
24
+ "import": "./dist/index.js"
24
25
  }
25
26
  },
26
- "types": "./types/lib/index.d.ts",
27
+ "module": "dist/index.js",
28
+ "browser": "dist/index.js",
29
+ "types": "dist/index.d.ts",
30
+ "sideEffects": false,
27
31
  "files": [
28
- "lib/**/*.js",
29
- "lib/**/*.d.ts",
30
- "types/**/*.d.ts",
31
- "types/**/*.d.ts.map"
32
+ "dist",
33
+ "README.md",
34
+ "LICENSE"
32
35
  ],
33
36
  "dependencies": {
34
37
  "@digitalbazaar/zcap-context": "^2.0.1",
35
- "@interop/data-integrity-core": "^6.1.0",
36
- "@interop/jsonld-signatures": "^11.6.2"
38
+ "@interop/data-integrity-core": "^6.1.1",
39
+ "@interop/jsonld-signatures": "^11.6.7"
37
40
  },
38
41
  "devDependencies": {
39
- "@digitalbazaar/ed25519-signature-2020": "^5.4.0",
40
- "@digitalcredentials/ed25519-verification-key-2020": "^5.0.0",
41
- "chai": "^4.3.6",
42
- "cross-env": "^7.0.3",
43
- "eslint": "^8.17.0",
44
- "eslint-config-digitalbazaar": "^5.0.1",
45
- "eslint-plugin-jsdoc": "^48.2.2",
46
- "eslint-plugin-unicorn": "^51.0.1",
47
- "karma": "^6.3.20",
48
- "karma-chrome-launcher": "^3.1.1",
49
- "karma-mocha": "^2.0.1",
50
- "karma-mocha-reporter": "^2.2.5",
51
- "karma-sourcemap-loader": "^0.4.0",
52
- "karma-webpack": "^5.0.0",
53
- "mocha": "^10.0.0",
54
- "typescript": "^6.0.3",
55
- "webpack": "^5.73.0"
42
+ "@eslint/js": "^10.0.1",
43
+ "@interop/did-method-key": "^7.1.0",
44
+ "@interop/ed25519-signature": "^7.0.1",
45
+ "@interop/ed25519-verification-key": "^7.0.1",
46
+ "@interop/security-document-loader": "^9.2.1",
47
+ "@playwright/test": "^1.60.0",
48
+ "@types/node": "^25.9.1",
49
+ "@vitest/coverage-v8": "^4.1.7",
50
+ "eslint": "^10.4.0",
51
+ "eslint-config-prettier": "^10.1.8",
52
+ "globals": "^17.6.0",
53
+ "prettier": "^3.8.3",
54
+ "rimraf": "^6.1.3",
55
+ "typescript": "^5.9.3",
56
+ "typescript-eslint": "^8.60.0",
57
+ "vite": "^8.0.14",
58
+ "vitest": "^4.1.7"
56
59
  },
57
60
  "scripts": {
58
- "test": "npm run test-node",
59
- "__test-node": "cross-env NODE_ENV=test mocha --delay -t 30000 -A -R ${REPORTER:-spec} tests/test.js",
60
- "test-node": "cross-env NODE_ENV=test mocha -t 30000 -A -R ${REPORTER:-spec} tests/test.js",
61
- "test-karma": "cross-env NODE_ENV=test karma start karma.conf.cjs",
62
- "build:types": "tsc",
63
- "lint": "eslint ."
61
+ "build": "pnpm run clear && tsc",
62
+ "clear": "rimraf dist/*",
63
+ "dev": "vite",
64
+ "fix": "eslint --fix src test && pnpm run format",
65
+ "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\" \"*.md\"",
66
+ "lint": "eslint src test",
67
+ "prepare": "pnpm run build",
68
+ "rebuild": "pnpm run clear && pnpm run build",
69
+ "test": "pnpm run lint && pnpm run test-node && pnpm run test-browser",
70
+ "test-browser": "playwright test",
71
+ "test-node": "vitest run",
72
+ "test-coverage": "vitest run --coverage"
73
+ },
74
+ "publishConfig": {
75
+ "access": "public",
76
+ "provenance": true
64
77
  },
65
78
  "engines": {
66
- "node": ">=18"
79
+ "node": ">=24.0"
67
80
  },
68
81
  "packageManager": "pnpm@11.3.0",
69
82
  "keywords": [
@@ -1,312 +0,0 @@
1
- /*!
2
- * Copyright (c) 2018-2024 Digital Bazaar, Inc. All rights reserved.
3
- */
4
- import * as utils from './utils.js';
5
- import {CapabilityProofPurpose} from './CapabilityProofPurpose.js';
6
-
7
- /**
8
- * @typedef {import('./utils.js').InspectCapabilityChain} InspectCapabilityChain
9
- * @typedef {import('./utils.js').IZcap} IZcap
10
- * @typedef {import('./utils.js').IDelegatedZcap} IDelegatedZcap
11
- */
12
-
13
- export class CapabilityDelegation extends CapabilityProofPurpose {
14
- /**
15
- * @param {object} options - The options.
16
- * @param {string|IZcap} [options.parentCapability] - An alternative to
17
- * passing `capabilityChain` when creating a proof; passing
18
- * `parentCapability` will enable the capability chain to be auto-computed.
19
- * Pass a root zcap ID string, or a full root or delegated zcap object.
20
- * @param {boolean} [options.allowTargetAttenuation=false] - Allow the
21
- * invocationTarget of a delegation chain to be increasingly restrictive
22
- * based on a hierarchical RESTful URL structure.
23
- * @param {string|Date|number} [options.date] - Used during proof
24
- * verification as the expected date for the creation of the proof
25
- * (within a maximum timestamp delta) and for checking to see if a
26
- * capability has expired; if not passed the current date will be used.
27
- * @param {string|string[]} [options.expectedRootCapability] - The expected
28
- * root capability for the delegation chain (a single root capability ID
29
- * string, or an array of acceptable root capability ID strings).
30
- * @param {object} [options.controller] - The description of the controller,
31
- * if it is not to be dereferenced via a `documentLoader`.
32
- * @param {InspectCapabilityChain} [options.inspectCapabilityChain] - An
33
- * async function that can be used to check for revocations related to any
34
- * of verified capabilities.
35
- * @param {number} [options.maxChainLength=10] - The maximum length of the
36
- * capability delegation chain.
37
- * @param {number} [options.maxClockSkew=300] - A maximum number of seconds
38
- * that clocks may be skewed when checking capability expiration date-times
39
- * against `date`.
40
- * @param {number} [options.maxDelegationTtl=Infinity] - The maximum
41
- * milliseconds to live for a delegated zcap as measured by the time
42
- * difference between `expires` and `created` on the delegation proof.
43
- * @param {object|object[]} [options.suite] - The jsonld-signature suite(s) to
44
- * use to verify the capability chain. Required only in verify-proof mode;
45
- * unused (and omitted) when creating a delegation proof.
46
- * @param {IZcap} [options._verifiedParentCapability] - Private.
47
- * @param {Array<string|IDelegatedZcap>} [options._capabilityChain] - Private.
48
- * @param {boolean} [options._skipLocalValidationForTesting] - Private.
49
- */
50
- constructor({
51
- // proof creation params
52
- parentCapability,
53
- // proof verification params
54
- allowTargetAttenuation,
55
- controller,
56
- date,
57
- expectedRootCapability,
58
- inspectCapabilityChain,
59
- maxChainLength,
60
- maxClockSkew,
61
- maxDelegationTtl,
62
- suite,
63
- _verifiedParentCapability,
64
- // for testing purposes only, not documented intentionally
65
- _capabilityChain,
66
- _skipLocalValidationForTesting = false
67
- } = {}) {
68
- // parameters used to create a proof
69
- const hasCreateProofParams = parentCapability || _capabilityChain;
70
- // params used to verify a proof
71
- const hasVerifyProofParams = controller || date ||
72
- expectedRootCapability ||
73
- inspectCapabilityChain || suite ||
74
- _verifiedParentCapability;
75
-
76
- if(hasCreateProofParams && hasVerifyProofParams) {
77
- // cannot provide both create and verify params
78
- throw new Error(
79
- 'Parameters for both creating and verifying a proof must not be ' +
80
- 'provided together.');
81
- }
82
-
83
- super({
84
- allowTargetAttenuation,
85
- controller, date,
86
- expectedRootCapability, inspectCapabilityChain,
87
- maxChainLength, maxClockSkew, maxDelegationTtl,
88
- // always `Infinity` for capability delegation proofs, as their "created"
89
- // values are not checked for liveness, rather "expires" is used instead
90
- maxTimestampDelta: Infinity,
91
- suite,
92
- term: 'capabilityDelegation'
93
- });
94
-
95
- // validate `CapabilityDelegation` specific params, the base class will
96
- // have already handled validating common ones...
97
-
98
- // use negative conditional to cover case where neither create nor
99
- // verify params were provided and default to proof creation case to
100
- // avoid creating bad proofs
101
- if(!hasVerifyProofParams) {
102
- if(!(typeof parentCapability === 'string' ||
103
- (typeof parentCapability === 'object' &&
104
- typeof parentCapability.id === 'string'))) {
105
- throw new TypeError(
106
- '"parentCapability" must be a string expressing the ID of a root ' +
107
- 'capability or an object expressing the full parent capability.');
108
- }
109
-
110
- this.parentCapability = parentCapability;
111
- if(_capabilityChain) {
112
- if(!Array.isArray(_capabilityChain)) {
113
- throw new TypeError('"_capabilityChain" must be an array.');
114
- }
115
- this._capabilityChain = _capabilityChain;
116
- }
117
- if(_skipLocalValidationForTesting !== undefined) {
118
- this._skipLocalValidationForTesting = _skipLocalValidationForTesting;
119
- }
120
- } else {
121
- this._verifiedParentCapability = _verifiedParentCapability;
122
- }
123
- }
124
-
125
- async update(proof, {document}) {
126
- // if no capability chain given (*for testing purposes only*), then
127
- // compute from parent
128
- let capabilityChain;
129
- const {
130
- parentCapability, term,
131
- _capabilityChain, _skipLocalValidationForTesting
132
- } = this;
133
- if(_capabilityChain) {
134
- // use chain override from tests
135
- capabilityChain = _capabilityChain;
136
- } else {
137
- capabilityChain = utils.computeCapabilityChain({
138
- parentCapability, _skipLocalValidationForTesting
139
- });
140
- }
141
-
142
- proof.proofPurpose = term;
143
- proof.capabilityChain = capabilityChain;
144
-
145
- if(!_skipLocalValidationForTesting) {
146
- // check capability data model
147
- const capability = {...document, proof};
148
- utils.checkCapability({capability, expectRoot: false});
149
-
150
- // ensure proof will not be created after it expires
151
- const created = Date.parse(proof.created);
152
- const expires = Date.parse(capability.expires);
153
- /* Note: Intentionally do not use `utils.compareTime` as there is no
154
- clock drift issue here. We are not comparing against any live values
155
- but against date-time values expressed in the chain. */
156
- if(created > expires) {
157
- throw new Error('Cannot delegate an expired capability.');
158
- }
159
-
160
- // ensure `allowedAction`, if present, is not less restrictive
161
- const {allowedAction: parentAllowedAction} = parentCapability;
162
- const {allowedAction} = document;
163
- if(!utils.hasValidAllowedAction({allowedAction, parentAllowedAction})) {
164
- throw new Error(
165
- 'The "allowedAction" in a delegated capability ' +
166
- 'must not be less restrictive than its parent.');
167
- }
168
-
169
- // ensure `expires` is not less restrictive
170
- const {expires: parentExpires} = parentCapability;
171
- if(parentExpires !== undefined) {
172
- // handle case where `expires` is set in the parent, but the child
173
- // has an expiration date greater than the parent;
174
- /* Note: Intentionally do not use `utils.compareTime` as there is no
175
- clock drift issue here. We are not comparing against any live values
176
- but against date-time values expressed in the chain. Additionally,
177
- allowing skew here could introduce vulnerabilities where the expires
178
- time drift could aggregate with each new capability in the chain. */
179
- if(expires > Date.parse(parentExpires)) {
180
- throw new Error(
181
- 'The `expires` property in a delegated capability must not be ' +
182
- 'less restrictive than its parent.');
183
- }
184
- }
185
-
186
- // ensure capability won't be delegated before its parent was delegated
187
- // (if that parent is non-root)
188
- if(capabilityChain.length > 1) {
189
- // get delegated date-time (note: `computeCapabilityChain` has already
190
- // validated that there is a single delegation proof in
191
- // `parentCapability`)
192
- const [parentProof] = utils.getDelegationProofs(
193
- {capability: parentCapability});
194
- const parentDelegationTime = Date.parse(parentProof.created);
195
- const childDelegationTime = Date.parse(proof.created);
196
- // verify parent capability was not delegated after child
197
- if(parentDelegationTime > childDelegationTime) {
198
- throw new Error(
199
- 'A capability in the delegation chain was delegated before ' +
200
- 'its parent.');
201
- }
202
- }
203
- }
204
-
205
- return proof;
206
- }
207
-
208
- async match(proof, {document, documentLoader}) {
209
- try {
210
- // check the `proof` context before using its terms
211
- utils.checkProofContext({proof});
212
- } catch(e) {
213
- // context does not match, so proof does not match
214
- return false;
215
- }
216
-
217
- return super.match(proof, {document, documentLoader});
218
- }
219
-
220
- _getCapabilityDelegationClass() {
221
- return CapabilityDelegation;
222
- }
223
-
224
- _getTailCapability({document, proof}) {
225
- // `proof` must be reattached to the capability because it contains
226
- // the `capabilityChain` that must be dereferenced and verified
227
- return {capability: {...document, proof}};
228
- }
229
-
230
- async _runChecksBeforeChainVerification() {
231
- /* Note: Here we create a signal to be sent to `_verifyCapabilityChain`
232
- that the capability delegation proof for the tail has already been
233
- verified (to avoid it being reverified). We will compute the full
234
- `verifyResult` in `_runChecksAfterChainVerification` once we have verified
235
- the parent capability. */
236
- return {capabilityChainMeta: [{verifyResult: {}}]};
237
- }
238
-
239
- async _runChecksAfterChainVerification({
240
- capabilityChainMeta, dereferencedChain, proof, validateOptions
241
- }) {
242
- // verified parent is second to last in the chain (i.e., it is the parent
243
- // of the last in the chain)
244
- const verifiedParentCapability = dereferencedChain[
245
- dereferencedChain.length - 2];
246
-
247
- // get purpose result which needs to be used to build `verifyResult`
248
- const purposeResult = await this._validateAgainstParent({
249
- proof, verifiedParentCapability, validateOptions
250
- });
251
-
252
- // build verify result
253
- const {verificationMethod} = validateOptions;
254
- const {verifyResult} = capabilityChainMeta[capabilityChainMeta.length - 1];
255
- verifyResult.verified = purposeResult.valid;
256
- verifyResult.results = [{
257
- proof, verified: true, verificationMethod, purposeResult
258
- }];
259
-
260
- return purposeResult;
261
- }
262
-
263
- async _shortCircuitValidate({proof, validateOptions}) {
264
- // see if the parent capability has already been verified
265
- const {
266
- _verifiedParentCapability: verifiedParentCapability
267
- } = this;
268
- if(verifiedParentCapability) {
269
- // simple case, just validate against parent and return, we have been
270
- // called from within a chain verification and can short circuit proof
271
- // validation
272
- return this._validateAgainstParent({
273
- proof, verifiedParentCapability, validateOptions
274
- });
275
- }
276
-
277
- // no short-circuit possible, we've just started validating the proof
278
- // from root => tail
279
- }
280
-
281
- async _validateAgainstParent({
282
- proof, verifiedParentCapability, validateOptions
283
- }) {
284
- // ensure proof created by authorized delegator...
285
- // parent zcap controller must match the delegating verification method
286
- // (or its controller)
287
- const {verificationMethod} = validateOptions;
288
- if(!utils.isController(
289
- {capability: verifiedParentCapability, verificationMethod})) {
290
- const error = new Error(
291
- 'The capability controller does not match the verification ' +
292
- 'method (or its controller) used to delegate.');
293
- error.details = {
294
- capability: verifiedParentCapability,
295
- verificationMethod
296
- };
297
- throw error;
298
- }
299
-
300
- // run base level validation checks
301
- const result = await this._runBaseProofValidation({proof, validateOptions});
302
- if(!result.valid) {
303
- throw result.error;
304
- }
305
-
306
- // the controller of the proof is the delegator of the capability
307
- result.delegator = result.controller;
308
-
309
- // `result` includes meta data about the proof controller
310
- return result;
311
- }
312
- }