@interop/zcap 10.0.2 → 11.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.
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 +372 -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 -672
  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 -304
  48. package/types/lib/utils.d.ts.map +0 -1
package/README.md CHANGED
@@ -12,6 +12,7 @@
12
12
  - [Security](#security)
13
13
  - [Install](#install)
14
14
  - [Usage](#usage)
15
+ - [Develop](#develop)
15
16
  - [Contribute](#contribute)
16
17
  - [Commercial Support](#commercial-support)
17
18
  - [License](#license)
@@ -26,7 +27,10 @@ TBD
26
27
 
27
28
  ## Install
28
29
 
29
- - Browsers and Node.js 14+ are supported.
30
+ - Modern browsers and Node.js >= 24 are supported.
31
+
32
+ This is an ESM-only package (`"type": "module"`); the published build lives in
33
+ `dist/` (compiled JS + `.d.ts` type declarations).
30
34
 
31
35
  To install from NPM:
32
36
 
@@ -39,16 +43,30 @@ To install locally (for development):
39
43
  ```sh
40
44
  git clone https://github.com/interop-alliance/zcap.git
41
45
  cd zcap
42
- npm install
46
+ pnpm install
43
47
  ```
44
48
 
45
49
  ## Usage
46
50
 
47
51
  TBD
48
52
 
53
+ ## Develop
54
+
55
+ The source is TypeScript under `src/`; tests use [Vitest](https://vitest.dev)
56
+ (Node) and [Playwright](https://playwright.dev) (browser).
57
+
58
+ ```sh
59
+ pnpm run build # compile src/ -> dist/ (JS + .d.ts)
60
+ pnpm run lint # ESLint (flat config) over src + test
61
+ pnpm run format # Prettier
62
+ pnpm run test-node # Vitest (Node)
63
+ pnpm run test-browser # Playwright (Chromium) — run `pnpm exec playwright install chromium` once
64
+ pnpm test # lint + test-node + test-browser
65
+ ```
66
+
49
67
  ## Contribute
50
68
 
51
- See [the contribute file](https://github.com/interop-alliance/bedrock/blob/master/CONTRIBUTING.md)!
69
+ See [the contribute file](./CONTRIBUTING.md)!
52
70
 
53
71
  PRs accepted.
54
72
 
@@ -0,0 +1,173 @@
1
+ import { CapabilityProofPurpose, type CapabilityDelegationConstructor } from './CapabilityProofPurpose.js';
2
+ import type { IProofDescription } from '@interop/jsonld-signatures';
3
+ import type { IDelegatedZcap, IZcap } from '@interop/data-integrity-core/zcap';
4
+ import type { CapabilityDelegationOptions, CapabilityMeta, CapabilityValidateResult, ValidateOptions } from './types.js';
5
+ /**
6
+ * The proof purpose for *delegating* an authorization capability (zcap).
7
+ *
8
+ * Instantiated in one of two mutually exclusive modes:
9
+ * - **Create-proof mode** — pass `{parentCapability}` (the capability chain is
10
+ * auto-computed from the parent).
11
+ * - **Verify-proof mode** — pass `{expectedRootCapability, suite, ...}`.
12
+ *
13
+ * Passing parameters from both modes together throws.
14
+ */
15
+ export declare class CapabilityDelegation extends CapabilityProofPurpose {
16
+ parentCapability?: string | IZcap;
17
+ _verifiedParentCapability?: IZcap;
18
+ _capabilityChain?: Array<string | IDelegatedZcap>;
19
+ _skipLocalValidationForTesting?: boolean;
20
+ /**
21
+ * @param options - The options.
22
+ * @param options.parentCapability - An alternative to passing
23
+ * `capabilityChain` when creating a proof; passing `parentCapability` will
24
+ * enable the capability chain to be auto-computed. Pass a root zcap ID
25
+ * string, or a full root or delegated zcap object.
26
+ * @param options.allowTargetAttenuation - Allow the invocationTarget of a
27
+ * delegation chain to be increasingly restrictive based on a hierarchical
28
+ * RESTful URL structure.
29
+ * @param options.date - Used during proof verification as the expected date
30
+ * for the creation of the proof (within a maximum timestamp delta) and for
31
+ * checking to see if a capability has expired; if not passed the current
32
+ * date will be used.
33
+ * @param options.expectedRootCapability - The expected root capability for
34
+ * the delegation chain (a single root capability ID string, or an array of
35
+ * acceptable root capability ID strings).
36
+ * @param options.controller - The description of the controller, if it is not
37
+ * to be dereferenced via a `documentLoader`.
38
+ * @param options.inspectCapabilityChain - An async function that can be used
39
+ * to check for revocations related to any of verified capabilities.
40
+ * @param options.maxChainLength - The maximum length of the capability
41
+ * delegation chain.
42
+ * @param options.maxClockSkew - A maximum number of seconds that clocks may
43
+ * be skewed when checking capability expiration date-times against `date`.
44
+ * @param options.maxDelegationTtl - The maximum milliseconds to live for a
45
+ * delegated zcap as measured by the time difference between `expires` and
46
+ * `created` on the delegation proof.
47
+ * @param options.suite - The jsonld-signature suite(s) to use to verify the
48
+ * capability chain. Required only in verify-proof mode; unused (and
49
+ * omitted) when creating a delegation proof.
50
+ * @param options._verifiedParentCapability - Private.
51
+ * @param options._capabilityChain - Private.
52
+ * @param options._skipLocalValidationForTesting - Private.
53
+ */
54
+ constructor({ parentCapability, allowTargetAttenuation, controller, date, expectedRootCapability, inspectCapabilityChain, maxChainLength, maxClockSkew, maxDelegationTtl, suite, _verifiedParentCapability, _capabilityChain, _skipLocalValidationForTesting }?: CapabilityDelegationOptions);
55
+ /**
56
+ * Adds the capability delegation terms (`proofPurpose`, `capabilityChain`) to
57
+ * a proof being created, then validates the resulting delegated capability
58
+ * against its parent (data model, expiry, `allowedAction` and `expires`
59
+ * attenuation, and delegation ordering). Used in create-proof mode.
60
+ *
61
+ * @param proof - The proof under construction.
62
+ * @param options - The options.
63
+ * @param options.document - The capability being delegated (without its
64
+ * proof).
65
+ *
66
+ * @returns Resolves to the updated proof.
67
+ */
68
+ update(proof: IProofDescription, { document }: {
69
+ document: object;
70
+ }): Promise<IProofDescription>;
71
+ /**
72
+ * Determines whether the given proof matches this proof purpose: it must
73
+ * carry the zcap context and satisfy the base `capabilityDelegation` match.
74
+ * Used in verify-proof mode.
75
+ *
76
+ * @param proof - The proof to test.
77
+ * @param options - The options.
78
+ * @param options.document - The document the proof is attached to.
79
+ * @param options.documentLoader - A configured document loader.
80
+ *
81
+ * @returns Resolves to `true` if the proof matches.
82
+ */
83
+ match(proof: IProofDescription, { document, documentLoader }: ValidateOptions): Promise<boolean>;
84
+ /** @returns The `CapabilityDelegation` class. */
85
+ _getCapabilityDelegationClass(): CapabilityDelegationConstructor;
86
+ /**
87
+ * Resolves the delegated (tail) capability by reattaching the proof to the
88
+ * document; the proof carries the `capabilityChain` that must be dereferenced
89
+ * and verified.
90
+ *
91
+ * @param options - The options.
92
+ * @param options.document - The delegated capability (without its proof).
93
+ * @param options.proof - The capability delegation proof.
94
+ *
95
+ * @returns The delegated capability with its proof reattached.
96
+ */
97
+ _getTailCapability({ document, proof }: {
98
+ document?: object;
99
+ proof: IProofDescription;
100
+ }): {
101
+ capability: IZcap;
102
+ };
103
+ /**
104
+ * Signals to `_verifyCapabilityChain` that the tail's delegation proof has
105
+ * already been verified (its full `verifyResult` is computed later, in
106
+ * `_runChecksAfterChainVerification`, once the parent is verified).
107
+ *
108
+ * @returns A `capabilityChainMeta` with a single placeholder result for the
109
+ * tail.
110
+ */
111
+ _runChecksBeforeChainVerification(): Promise<{
112
+ capabilityChainMeta: CapabilityMeta[];
113
+ }>;
114
+ /**
115
+ * Validates the tail delegation proof against its now-verified parent (the
116
+ * second-to-last entry in the chain) and builds the tail's full
117
+ * `verifyResult` in `capabilityChainMeta`.
118
+ *
119
+ * @param options - The options.
120
+ * @param options.capabilityChainMeta - The chain meta array; its last entry's
121
+ * placeholder `verifyResult` is populated here.
122
+ * @param options.dereferencedChain - The dereferenced chain (root to tail).
123
+ * @param options.proof - The capability delegation proof.
124
+ * @param options.validateOptions - The validation options passed through from
125
+ * `jsigs` (including `verificationMethod`).
126
+ *
127
+ * @returns Resolves to the proof purpose validation result.
128
+ */
129
+ _runChecksAfterChainVerification({ capabilityChainMeta, dereferencedChain, proof, validateOptions }: {
130
+ capabilityChainMeta: CapabilityMeta[];
131
+ dereferencedChain: IZcap[];
132
+ proof: IProofDescription;
133
+ validateOptions: ValidateOptions;
134
+ }): Promise<CapabilityValidateResult>;
135
+ /**
136
+ * Short-circuits proof validation when a verified parent capability is
137
+ * already available (i.e., this purpose was created from within a chain
138
+ * verification with `_verifiedParentCapability`): it validates the proof
139
+ * directly against that parent. Otherwise returns nothing so full validation
140
+ * from root to tail proceeds.
141
+ *
142
+ * @param options - The options.
143
+ * @param options.proof - The capability delegation proof.
144
+ * @param options.validateOptions - The validation options passed through from
145
+ * `jsigs`.
146
+ *
147
+ * @returns The validation result if short-circuited, otherwise nothing.
148
+ */
149
+ _shortCircuitValidate({ proof, validateOptions }: {
150
+ proof: IProofDescription;
151
+ validateOptions: ValidateOptions;
152
+ }): Promise<CapabilityValidateResult | void>;
153
+ /**
154
+ * Validates a capability delegation proof against its verified parent: the
155
+ * delegating verification method (or its controller) must be the parent's
156
+ * controller. Sets `result.delegator` to the proof controller.
157
+ *
158
+ * @param options - The options.
159
+ * @param options.proof - The capability delegation proof.
160
+ * @param options.verifiedParentCapability - The already-verified parent
161
+ * capability.
162
+ * @param options.validateOptions - The validation options passed through from
163
+ * `jsigs` (including `verificationMethod`).
164
+ *
165
+ * @returns Resolves to the validation result with an added `delegator`.
166
+ */
167
+ _validateAgainstParent({ proof, verifiedParentCapability, validateOptions }: {
168
+ proof: IProofDescription;
169
+ verifiedParentCapability: IZcap;
170
+ validateOptions: ValidateOptions;
171
+ }): Promise<CapabilityValidateResult>;
172
+ }
173
+ //# sourceMappingURL=CapabilityDelegation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CapabilityDelegation.d.ts","sourceRoot":"","sources":["../src/CapabilityDelegation.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,sBAAsB,EACtB,KAAK,+BAA+B,EACrC,MAAM,6BAA6B,CAAA;AACpC,OAAO,KAAK,EACV,iBAAiB,EAElB,MAAM,4BAA4B,CAAA;AACnC,OAAO,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAA;AAC9E,OAAO,KAAK,EACV,2BAA2B,EAC3B,cAAc,EACd,wBAAwB,EACxB,eAAe,EAChB,MAAM,YAAY,CAAA;AAEnB;;;;;;;;;GASG;AACH,qBAAa,oBAAqB,SAAQ,sBAAsB;IAC9D,gBAAgB,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;IACjC,yBAAyB,CAAC,EAAE,KAAK,CAAA;IACjC,gBAAgB,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,cAAc,CAAC,CAAA;IACjD,8BAA8B,CAAC,EAAE,OAAO,CAAA;IAExC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;gBACS,EAEV,gBAAgB,EAEhB,sBAAsB,EACtB,UAAU,EACV,IAAI,EACJ,sBAAsB,EACtB,sBAAsB,EACtB,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,KAAK,EACL,yBAAyB,EAEzB,gBAAgB,EAChB,8BAAsC,EACvC,GAAE,2BAAgC;IAuEnC;;;;;;;;;;;;OAYG;IACG,MAAM,CACV,KAAK,EAAE,iBAAiB,EACxB,EAAE,QAAQ,EAAE,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GACjC,OAAO,CAAC,iBAAiB,CAAC;IA+F7B;;;;;;;;;;;OAWG;IACG,KAAK,CACT,KAAK,EAAE,iBAAiB,EACxB,EAAE,QAAQ,EAAE,cAAc,EAAE,EAAE,eAAe,GAC5C,OAAO,CAAC,OAAO,CAAC;IAYnB,iDAAiD;IACjD,6BAA6B,IAAI,+BAA+B;IAIhE;;;;;;;;;;OAUG;IACH,kBAAkB,CAAC,EACjB,QAAQ,EACR,KAAK,EACN,EAAE;QACD,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,KAAK,EAAE,iBAAiB,CAAA;KACzB,GAAG;QAAE,UAAU,EAAE,KAAK,CAAA;KAAE;IAMzB;;;;;;;OAOG;IACG,iCAAiC,IAAI,OAAO,CAAC;QACjD,mBAAmB,EAAE,cAAc,EAAE,CAAA;KACtC,CAAC;IASF;;;;;;;;;;;;;;OAcG;IACG,gCAAgC,CAAC,EACrC,mBAAmB,EACnB,iBAAiB,EACjB,KAAK,EACL,eAAe,EAChB,EAAE;QACD,mBAAmB,EAAE,cAAc,EAAE,CAAA;QACrC,iBAAiB,EAAE,KAAK,EAAE,CAAA;QAC1B,KAAK,EAAE,iBAAiB,CAAA;QACxB,eAAe,EAAE,eAAe,CAAA;KACjC,GAAG,OAAO,CAAC,wBAAwB,CAAC;IA8BrC;;;;;;;;;;;;;OAaG;IACG,qBAAqB,CAAC,EAC1B,KAAK,EACL,eAAe,EAChB,EAAE;QACD,KAAK,EAAE,iBAAiB,CAAA;QACxB,eAAe,EAAE,eAAe,CAAA;KACjC,GAAG,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC;IAkB5C;;;;;;;;;;;;;OAaG;IACG,sBAAsB,CAAC,EAC3B,KAAK,EACL,wBAAwB,EACxB,eAAe,EAChB,EAAE;QACD,KAAK,EAAE,iBAAiB,CAAA;QACxB,wBAAwB,EAAE,KAAK,CAAA;QAC/B,eAAe,EAAE,eAAe,CAAA;KACjC,GAAG,OAAO,CAAC,wBAAwB,CAAC;CAiCtC"}
@@ -0,0 +1,372 @@
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
+ * The proof purpose for *delegating* an authorization capability (zcap).
8
+ *
9
+ * Instantiated in one of two mutually exclusive modes:
10
+ * - **Create-proof mode** — pass `{parentCapability}` (the capability chain is
11
+ * auto-computed from the parent).
12
+ * - **Verify-proof mode** — pass `{expectedRootCapability, suite, ...}`.
13
+ *
14
+ * Passing parameters from both modes together throws.
15
+ */
16
+ export class CapabilityDelegation extends CapabilityProofPurpose {
17
+ parentCapability;
18
+ _verifiedParentCapability;
19
+ _capabilityChain;
20
+ _skipLocalValidationForTesting;
21
+ /**
22
+ * @param options - The options.
23
+ * @param options.parentCapability - An alternative to passing
24
+ * `capabilityChain` when creating a proof; passing `parentCapability` will
25
+ * enable the capability chain to be auto-computed. Pass a root zcap ID
26
+ * string, or a full root or delegated zcap object.
27
+ * @param options.allowTargetAttenuation - Allow the invocationTarget of a
28
+ * delegation chain to be increasingly restrictive based on a hierarchical
29
+ * RESTful URL structure.
30
+ * @param options.date - Used during proof verification as the expected date
31
+ * for the creation of the proof (within a maximum timestamp delta) and for
32
+ * checking to see if a capability has expired; if not passed the current
33
+ * date will be used.
34
+ * @param options.expectedRootCapability - The expected root capability for
35
+ * the delegation chain (a single root capability ID string, or an array of
36
+ * acceptable root capability ID strings).
37
+ * @param options.controller - The description of the controller, if it is not
38
+ * to be dereferenced via a `documentLoader`.
39
+ * @param options.inspectCapabilityChain - An async function that can be used
40
+ * to check for revocations related to any of verified capabilities.
41
+ * @param options.maxChainLength - The maximum length of the capability
42
+ * delegation chain.
43
+ * @param options.maxClockSkew - A maximum number of seconds that clocks may
44
+ * be skewed when checking capability expiration date-times against `date`.
45
+ * @param options.maxDelegationTtl - The maximum milliseconds to live for a
46
+ * delegated zcap as measured by the time difference between `expires` and
47
+ * `created` on the delegation proof.
48
+ * @param options.suite - The jsonld-signature suite(s) to use to verify the
49
+ * capability chain. Required only in verify-proof mode; unused (and
50
+ * omitted) when creating a delegation proof.
51
+ * @param options._verifiedParentCapability - Private.
52
+ * @param options._capabilityChain - Private.
53
+ * @param options._skipLocalValidationForTesting - Private.
54
+ */
55
+ constructor({
56
+ // proof creation params
57
+ parentCapability,
58
+ // proof verification params
59
+ allowTargetAttenuation, controller, date, expectedRootCapability, inspectCapabilityChain, maxChainLength, maxClockSkew, maxDelegationTtl, suite, _verifiedParentCapability,
60
+ // for testing purposes only, not documented intentionally
61
+ _capabilityChain, _skipLocalValidationForTesting = false } = {}) {
62
+ // parameters used to create a proof
63
+ const hasCreateProofParams = parentCapability || _capabilityChain;
64
+ // params used to verify a proof
65
+ const hasVerifyProofParams = controller ||
66
+ date ||
67
+ expectedRootCapability ||
68
+ inspectCapabilityChain ||
69
+ suite ||
70
+ _verifiedParentCapability;
71
+ if (hasCreateProofParams && hasVerifyProofParams) {
72
+ // cannot provide both create and verify params
73
+ throw new Error('Parameters for both creating and verifying a proof must not be ' +
74
+ 'provided together.');
75
+ }
76
+ super({
77
+ allowTargetAttenuation,
78
+ controller,
79
+ date,
80
+ expectedRootCapability,
81
+ inspectCapabilityChain,
82
+ maxChainLength,
83
+ maxClockSkew,
84
+ maxDelegationTtl,
85
+ // always `Infinity` for capability delegation proofs, as their "created"
86
+ // values are not checked for liveness, rather "expires" is used instead
87
+ maxTimestampDelta: Infinity,
88
+ suite,
89
+ term: 'capabilityDelegation'
90
+ });
91
+ // validate `CapabilityDelegation` specific params, the base class will
92
+ // have already handled validating common ones...
93
+ // use negative conditional to cover case where neither create nor
94
+ // verify params were provided and default to proof creation case to
95
+ // avoid creating bad proofs
96
+ if (!hasVerifyProofParams) {
97
+ if (!(typeof parentCapability === 'string' ||
98
+ (typeof parentCapability === 'object' &&
99
+ typeof parentCapability.id === 'string'))) {
100
+ throw new TypeError('"parentCapability" must be a string expressing the ID of a root ' +
101
+ 'capability or an object expressing the full parent capability.');
102
+ }
103
+ this.parentCapability = parentCapability;
104
+ if (_capabilityChain) {
105
+ if (!Array.isArray(_capabilityChain)) {
106
+ throw new TypeError('"_capabilityChain" must be an array.');
107
+ }
108
+ this._capabilityChain = _capabilityChain;
109
+ }
110
+ if (_skipLocalValidationForTesting !== undefined) {
111
+ this._skipLocalValidationForTesting = _skipLocalValidationForTesting;
112
+ }
113
+ }
114
+ else {
115
+ this._verifiedParentCapability = _verifiedParentCapability;
116
+ }
117
+ }
118
+ /**
119
+ * Adds the capability delegation terms (`proofPurpose`, `capabilityChain`) to
120
+ * a proof being created, then validates the resulting delegated capability
121
+ * against its parent (data model, expiry, `allowedAction` and `expires`
122
+ * attenuation, and delegation ordering). Used in create-proof mode.
123
+ *
124
+ * @param proof - The proof under construction.
125
+ * @param options - The options.
126
+ * @param options.document - The capability being delegated (without its
127
+ * proof).
128
+ *
129
+ * @returns Resolves to the updated proof.
130
+ */
131
+ async update(proof, { document }) {
132
+ // if no capability chain given (*for testing purposes only*), then
133
+ // compute from parent
134
+ let capabilityChain;
135
+ const { parentCapability, term, _capabilityChain, _skipLocalValidationForTesting } = this;
136
+ if (_capabilityChain) {
137
+ // use chain override from tests
138
+ capabilityChain = _capabilityChain;
139
+ }
140
+ else {
141
+ capabilityChain = utils.computeCapabilityChain({
142
+ parentCapability: parentCapability,
143
+ _skipLocalValidationForTesting
144
+ });
145
+ }
146
+ proof.proofPurpose = term;
147
+ proof.capabilityChain = capabilityChain;
148
+ if (!_skipLocalValidationForTesting) {
149
+ // check capability data model
150
+ const capability = { ...document, proof };
151
+ utils.checkCapability({ capability, expectRoot: false });
152
+ // ensure proof will not be created after it expires
153
+ const created = Date.parse(proof.created);
154
+ const expires = Date.parse('expires' in capability ? capability.expires : '');
155
+ /* Note: Intentionally do not use `utils.compareTime` as there is no
156
+ clock drift issue here. We are not comparing against any live values
157
+ but against date-time values expressed in the chain. */
158
+ if (created > expires) {
159
+ throw new Error('Cannot delegate an expired capability.');
160
+ }
161
+ // ensure `allowedAction`, if present, is not less restrictive
162
+ const parent = parentCapability;
163
+ const parentAllowedAction = 'allowedAction' in parent ? parent.allowedAction : undefined;
164
+ const allowedAction = document
165
+ .allowedAction;
166
+ if (!utils.hasValidAllowedAction({ allowedAction, parentAllowedAction })) {
167
+ throw new Error('The "allowedAction" in a delegated capability ' +
168
+ 'must not be less restrictive than its parent.');
169
+ }
170
+ // ensure `expires` is not less restrictive
171
+ const parentExpires = 'expires' in parent ? parent.expires : undefined;
172
+ if (parentExpires !== undefined) {
173
+ // handle case where `expires` is set in the parent, but the child
174
+ // has an expiration date greater than the parent;
175
+ /* Note: Intentionally do not use `utils.compareTime` as there is no
176
+ clock drift issue here. We are not comparing against any live values
177
+ but against date-time values expressed in the chain. Additionally,
178
+ allowing skew here could introduce vulnerabilities where the expires
179
+ time drift could aggregate with each new capability in the chain. */
180
+ if (expires > Date.parse(parentExpires)) {
181
+ throw new Error('The `expires` property in a delegated capability must not be ' +
182
+ 'less restrictive than its parent.');
183
+ }
184
+ }
185
+ // ensure capability won't be delegated before its parent was delegated
186
+ // (if that parent is non-root)
187
+ if (capabilityChain.length > 1) {
188
+ // get delegated date-time (note: `computeCapabilityChain` has already
189
+ // validated that there is a single delegation proof in
190
+ // `parentCapability`)
191
+ const [parentProof] = utils.getDelegationProofs({ capability: parent });
192
+ const parentDelegationTime = Date.parse(parentProof.created);
193
+ const childDelegationTime = Date.parse(proof.created);
194
+ // verify parent capability was not delegated after child
195
+ if (parentDelegationTime > childDelegationTime) {
196
+ throw new Error('A capability in the delegation chain was delegated before ' +
197
+ 'its parent.');
198
+ }
199
+ }
200
+ }
201
+ return proof;
202
+ }
203
+ /**
204
+ * Determines whether the given proof matches this proof purpose: it must
205
+ * carry the zcap context and satisfy the base `capabilityDelegation` match.
206
+ * Used in verify-proof mode.
207
+ *
208
+ * @param proof - The proof to test.
209
+ * @param options - The options.
210
+ * @param options.document - The document the proof is attached to.
211
+ * @param options.documentLoader - A configured document loader.
212
+ *
213
+ * @returns Resolves to `true` if the proof matches.
214
+ */
215
+ async match(proof, { document, documentLoader }) {
216
+ try {
217
+ // check the `proof` context before using its terms
218
+ utils.checkProofContext({ proof });
219
+ }
220
+ catch {
221
+ // context does not match, so proof does not match
222
+ return false;
223
+ }
224
+ return super.match(proof, { document, documentLoader });
225
+ }
226
+ /** @returns The `CapabilityDelegation` class. */
227
+ _getCapabilityDelegationClass() {
228
+ return CapabilityDelegation;
229
+ }
230
+ /**
231
+ * Resolves the delegated (tail) capability by reattaching the proof to the
232
+ * document; the proof carries the `capabilityChain` that must be dereferenced
233
+ * and verified.
234
+ *
235
+ * @param options - The options.
236
+ * @param options.document - The delegated capability (without its proof).
237
+ * @param options.proof - The capability delegation proof.
238
+ *
239
+ * @returns The delegated capability with its proof reattached.
240
+ */
241
+ _getTailCapability({ document, proof }) {
242
+ // `proof` must be reattached to the capability because it contains
243
+ // the `capabilityChain` that must be dereferenced and verified
244
+ return { capability: { ...document, proof } };
245
+ }
246
+ /**
247
+ * Signals to `_verifyCapabilityChain` that the tail's delegation proof has
248
+ * already been verified (its full `verifyResult` is computed later, in
249
+ * `_runChecksAfterChainVerification`, once the parent is verified).
250
+ *
251
+ * @returns A `capabilityChainMeta` with a single placeholder result for the
252
+ * tail.
253
+ */
254
+ async _runChecksBeforeChainVerification() {
255
+ /* Note: Here we create a signal to be sent to `_verifyCapabilityChain`
256
+ that the capability delegation proof for the tail has already been
257
+ verified (to avoid it being reverified). We will compute the full
258
+ `verifyResult` in `_runChecksAfterChainVerification` once we have verified
259
+ the parent capability. */
260
+ return { capabilityChainMeta: [{ verifyResult: {} }] };
261
+ }
262
+ /**
263
+ * Validates the tail delegation proof against its now-verified parent (the
264
+ * second-to-last entry in the chain) and builds the tail's full
265
+ * `verifyResult` in `capabilityChainMeta`.
266
+ *
267
+ * @param options - The options.
268
+ * @param options.capabilityChainMeta - The chain meta array; its last entry's
269
+ * placeholder `verifyResult` is populated here.
270
+ * @param options.dereferencedChain - The dereferenced chain (root to tail).
271
+ * @param options.proof - The capability delegation proof.
272
+ * @param options.validateOptions - The validation options passed through from
273
+ * `jsigs` (including `verificationMethod`).
274
+ *
275
+ * @returns Resolves to the proof purpose validation result.
276
+ */
277
+ async _runChecksAfterChainVerification({ capabilityChainMeta, dereferencedChain, proof, validateOptions }) {
278
+ // verified parent is second to last in the chain (i.e., it is the parent
279
+ // of the last in the chain)
280
+ const verifiedParentCapability = dereferencedChain[dereferencedChain.length - 2];
281
+ // get purpose result which needs to be used to build `verifyResult`
282
+ const purposeResult = await this._validateAgainstParent({
283
+ proof,
284
+ verifiedParentCapability,
285
+ validateOptions
286
+ });
287
+ // build verify result
288
+ const { verificationMethod } = validateOptions;
289
+ const meta = capabilityChainMeta[capabilityChainMeta.length - 1];
290
+ const verifyResult = meta.verifyResult;
291
+ verifyResult.verified = purposeResult.valid;
292
+ verifyResult.results = [
293
+ {
294
+ proof,
295
+ verified: true,
296
+ verificationMethod: verificationMethod,
297
+ purposeResult
298
+ }
299
+ ];
300
+ return purposeResult;
301
+ }
302
+ /**
303
+ * Short-circuits proof validation when a verified parent capability is
304
+ * already available (i.e., this purpose was created from within a chain
305
+ * verification with `_verifiedParentCapability`): it validates the proof
306
+ * directly against that parent. Otherwise returns nothing so full validation
307
+ * from root to tail proceeds.
308
+ *
309
+ * @param options - The options.
310
+ * @param options.proof - The capability delegation proof.
311
+ * @param options.validateOptions - The validation options passed through from
312
+ * `jsigs`.
313
+ *
314
+ * @returns The validation result if short-circuited, otherwise nothing.
315
+ */
316
+ async _shortCircuitValidate({ proof, validateOptions }) {
317
+ // see if the parent capability has already been verified
318
+ const { _verifiedParentCapability: verifiedParentCapability } = this;
319
+ if (verifiedParentCapability) {
320
+ // simple case, just validate against parent and return, we have been
321
+ // called from within a chain verification and can short circuit proof
322
+ // validation
323
+ return this._validateAgainstParent({
324
+ proof,
325
+ verifiedParentCapability,
326
+ validateOptions
327
+ });
328
+ }
329
+ // no short-circuit possible, we've just started validating the proof
330
+ // from root => tail
331
+ }
332
+ /**
333
+ * Validates a capability delegation proof against its verified parent: the
334
+ * delegating verification method (or its controller) must be the parent's
335
+ * controller. Sets `result.delegator` to the proof controller.
336
+ *
337
+ * @param options - The options.
338
+ * @param options.proof - The capability delegation proof.
339
+ * @param options.verifiedParentCapability - The already-verified parent
340
+ * capability.
341
+ * @param options.validateOptions - The validation options passed through from
342
+ * `jsigs` (including `verificationMethod`).
343
+ *
344
+ * @returns Resolves to the validation result with an added `delegator`.
345
+ */
346
+ async _validateAgainstParent({ proof, verifiedParentCapability, validateOptions }) {
347
+ // ensure proof created by authorized delegator...
348
+ // parent zcap controller must match the delegating verification method
349
+ // (or its controller)
350
+ const { verificationMethod } = validateOptions;
351
+ if (!utils.isController({
352
+ capability: verifiedParentCapability,
353
+ verificationMethod: verificationMethod
354
+ })) {
355
+ throw utils.createDetailedError('The capability controller does not match the verification ' +
356
+ 'method (or its controller) used to delegate.', { capability: verifiedParentCapability, verificationMethod });
357
+ }
358
+ // run base level validation checks
359
+ const result = await this._runBaseProofValidation({
360
+ proof,
361
+ validateOptions
362
+ });
363
+ if (!result.valid) {
364
+ throw result.error;
365
+ }
366
+ // the controller of the proof is the delegator of the capability
367
+ result.delegator = result.controller;
368
+ // `result` includes meta data about the proof controller
369
+ return result;
370
+ }
371
+ }
372
+ //# sourceMappingURL=CapabilityDelegation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CapabilityDelegation.js","sourceRoot":"","sources":["../src/CapabilityDelegation.ts"],"names":[],"mappings":"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"}