@embedpdf/engine-core 3.0.0-next.13 → 3.0.0-next.15
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/dist/AnnotationList-CkijRHet.d.cts +27163 -0
- package/dist/AnnotationList-CkijRHet.d.ts +27163 -0
- package/dist/Change-CKoxfTNY.js +889 -0
- package/dist/Change-CKoxfTNY.js.map +1 -0
- package/dist/Change-CjImsrN0.cjs +1020 -0
- package/dist/Change-CjImsrN0.cjs.map +1 -0
- package/dist/DocumentRenderService-BfFdFSwI.cjs +120 -0
- package/dist/DocumentRenderService-BfFdFSwI.cjs.map +1 -0
- package/dist/DocumentRenderService-DV3J9lMz.js +85 -0
- package/dist/DocumentRenderService-DV3J9lMz.js.map +1 -0
- package/dist/{DocumentSecurityService-_JRjqvoI.d.ts → DocumentSecurityService-CU1M6Q7m.d.ts} +100 -112
- package/dist/{DocumentSecurityService-ClTZc0zO.d.cts → DocumentSecurityService-e6vp2de8.d.cts} +100 -112
- package/dist/LocalDocumentHandle-D02FMm-Z.cjs +53 -0
- package/dist/LocalDocumentHandle-D02FMm-Z.cjs.map +1 -0
- package/dist/LocalDocumentHandle-DAPdaOt_.js +30 -0
- package/dist/LocalDocumentHandle-DAPdaOt_.js.map +1 -0
- package/dist/LocalEngine-DFoBm4B3.d.cts +1565 -0
- package/dist/LocalEngine-DPriFujS.d.ts +1565 -0
- package/dist/PageInsertBlankInput-CXHAM7l6.cjs +17 -0
- package/dist/PageInsertBlankInput-CXHAM7l6.cjs.map +1 -0
- package/dist/PageInsertBlankInput-DhVYVJ_S.js +12 -0
- package/dist/PageInsertBlankInput-DhVYVJ_S.js.map +1 -0
- package/dist/authority-B3BklsB4.js +2239 -0
- package/dist/authority-B3BklsB4.js.map +1 -0
- package/dist/authority-DLMNR7ff.cjs +2676 -0
- package/dist/authority-DLMNR7ff.cjs.map +1 -0
- package/dist/builders-CNj0POeY.js +161 -0
- package/dist/builders-CNj0POeY.js.map +1 -0
- package/dist/builders-Cgdp_YCn.cjs +184 -0
- package/dist/builders-Cgdp_YCn.cjs.map +1 -0
- package/dist/calibrate-7T3fnP8-.js +2404 -0
- package/dist/calibrate-7T3fnP8-.js.map +1 -0
- package/dist/calibrate-DJBXnhLE.cjs +2919 -0
- package/dist/calibrate-DJBXnhLE.cjs.map +1 -0
- package/dist/charmap-Cprti1ta.js +239 -0
- package/dist/charmap-Cprti1ta.js.map +1 -0
- package/dist/charmap-aYlefQP9.cjs +304 -0
- package/dist/charmap-aYlefQP9.cjs.map +1 -0
- package/dist/conformance.cjs +16753 -5247
- package/dist/conformance.cjs.map +1 -1
- package/dist/conformance.d.cts +928 -165
- package/dist/conformance.d.ts +928 -165
- package/dist/conformance.js +16731 -5268
- package/dist/conformance.js.map +1 -1
- package/dist/format-Bp3QFSH1.cjs +574 -0
- package/dist/format-Bp3QFSH1.cjs.map +1 -0
- package/dist/format-Dgg428Kb.js +461 -0
- package/dist/format-Dgg428Kb.js.map +1 -0
- package/dist/index.cjs +330 -103
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +14 -5
- package/dist/pageRefs-B3ur7Ckm.cjs +51 -0
- package/dist/pageRefs-B3ur7Ckm.cjs.map +1 -0
- package/dist/pageRefs-DkbuxSCV.js +40 -0
- package/dist/pageRefs-DkbuxSCV.js.map +1 -0
- package/dist/public.cjs +57 -0
- package/dist/public.d.cts +5 -0
- package/dist/public.d.ts +5 -0
- package/dist/public.js +9 -0
- package/dist/resolveAnnotationDraft-7Ke4nV7F.cjs +3646 -0
- package/dist/resolveAnnotationDraft-7Ke4nV7F.cjs.map +1 -0
- package/dist/resolveAnnotationDraft-CUpf0SMh.js +3167 -0
- package/dist/resolveAnnotationDraft-CUpf0SMh.js.map +1 -0
- package/dist/{resolver-inAVzsWt.js → resolver-CzxmD9Ck.js} +294 -144
- package/dist/resolver-CzxmD9Ck.js.map +1 -0
- package/dist/{resolver-CYVNV4hn.cjs → resolver-D2OCtE8F.cjs} +347 -143
- package/dist/resolver-D2OCtE8F.cjs.map +1 -0
- package/dist/runtime-Cl0v56mm.d.ts +2032 -0
- package/dist/runtime-p1WDzDo4.d.cts +2032 -0
- package/dist/runtime.cjs +733 -284
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.d.cts +5 -1348
- package/dist/runtime.d.ts +5 -1348
- package/dist/runtime.js +396 -179
- package/dist/runtime.js.map +1 -1
- package/dist/schema-C-gU4vj7.cjs +3034 -0
- package/dist/schema-C-gU4vj7.cjs.map +1 -0
- package/dist/schema-DzlUNk38.js +2081 -0
- package/dist/schema-DzlUNk38.js.map +1 -0
- package/dist/schemas-Berf1swF.cjs +2481 -0
- package/dist/schemas-Berf1swF.cjs.map +1 -0
- package/dist/schemas-D6xOGjqg.js +1654 -0
- package/dist/schemas-D6xOGjqg.js.map +1 -0
- package/dist/subtype-CG4WpIRj.js +129 -0
- package/dist/subtype-CG4WpIRj.js.map +1 -0
- package/dist/subtype-aDt5TFmK.cjs +158 -0
- package/dist/subtype-aDt5TFmK.cjs.map +1 -0
- package/dist/validation.cjs +578 -0
- package/dist/validation.cjs.map +1 -0
- package/dist/validation.d.cts +174 -0
- package/dist/validation.d.ts +174 -0
- package/dist/validation.js +571 -0
- package/dist/validation.js.map +1 -0
- package/dist/value-BFS1R8ek.cjs +435 -0
- package/dist/value-BFS1R8ek.cjs.map +1 -0
- package/dist/value-Dhc8eYcx.js +340 -0
- package/dist/value-Dhc8eYcx.js.map +1 -0
- package/dist/viewport-BJW13EGZ.js +540 -0
- package/dist/viewport-BJW13EGZ.js.map +1 -0
- package/dist/viewport-DlL5Bxbg.cjs +671 -0
- package/dist/viewport-DlL5Bxbg.cjs.map +1 -0
- package/dist/wire.cjs +1056 -379
- package/dist/wire.cjs.map +1 -1
- package/dist/wire.d.cts +15069 -725
- package/dist/wire.d.ts +15069 -725
- package/dist/wire.js +825 -239
- package/dist/wire.js.map +1 -1
- package/package.json +10 -1
- package/dist/AbortError-Cq2igpZ6.cjs +0 -38
- package/dist/AbortError-Cq2igpZ6.cjs.map +0 -1
- package/dist/AbortError-DHqPBnYc.js +0 -27
- package/dist/AbortError-DHqPBnYc.js.map +0 -1
- package/dist/AnnotationListSnapshot-D3mFut1e.d.cts +0 -6871
- package/dist/AnnotationListSnapshot-D3mFut1e.d.ts +0 -6871
- package/dist/Engine-Bx0NOfmd.d.cts +0 -1264
- package/dist/Engine-DxtpCYcP.d.ts +0 -1264
- package/dist/PageInsertBlankInput-CqXBmFhN.cjs +0 -449
- package/dist/PageInsertBlankInput-CqXBmFhN.cjs.map +0 -1
- package/dist/PageInsertBlankInput-cHq9-i-z.js +0 -378
- package/dist/PageInsertBlankInput-cHq9-i-z.js.map +0 -1
- package/dist/builders-Bqm8yTpi.cjs +0 -3564
- package/dist/builders-Bqm8yTpi.cjs.map +0 -1
- package/dist/builders-Dqo2X-dt.js +0 -3121
- package/dist/builders-Dqo2X-dt.js.map +0 -1
- package/dist/fold-2V29cxCV.cjs +0 -447
- package/dist/fold-2V29cxCV.cjs.map +0 -1
- package/dist/fold-CdEJTBTn.js +0 -334
- package/dist/fold-CdEJTBTn.js.map +0 -1
- package/dist/resolver-CYVNV4hn.cjs.map +0 -1
- package/dist/resolver-inAVzsWt.js.map +0 -1
- package/dist/schemas-BLARNCgx.js +0 -3113
- package/dist/schemas-BLARNCgx.js.map +0 -1
- package/dist/schemas-DIqFMmrC.cjs +0 -4468
- package/dist/schemas-DIqFMmrC.cjs.map +0 -1
|
@@ -1,8 +1,115 @@
|
|
|
1
|
+
const require_format = require("./format-Bp3QFSH1.cjs");
|
|
2
|
+
const require_builders = require("./builders-Cgdp_YCn.cjs");
|
|
3
|
+
//#region src/auth/scope/errors.ts
|
|
4
|
+
/**
|
|
5
|
+
* Thrown by {@link parseScope} / {@link validateScopeArray} when a scope
|
|
6
|
+
* string does not match any known grammar (capability, collab, virtual,
|
|
7
|
+
* or wildcard). An `EngineError` with code `InvalidArg`.
|
|
8
|
+
*
|
|
9
|
+
* Carries the offending scope verbatim so route/JWT-layer error
|
|
10
|
+
* handlers can echo it to the customer.
|
|
11
|
+
*/
|
|
12
|
+
var InvalidScope = class extends require_format.EngineError {
|
|
13
|
+
constructor(scope, reason) {
|
|
14
|
+
super(require_format.EngineErrorCode.InvalidArg, `invalid scope "${scope}": ${reason}`, { details: {
|
|
15
|
+
scope,
|
|
16
|
+
reason
|
|
17
|
+
} });
|
|
18
|
+
this.scope = scope;
|
|
19
|
+
require_format._defineProperty(this, "name", "InvalidScope");
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Thrown by route guards and engine-local enforcement when a capability
|
|
24
|
+
* or collab action is denied for the current request/handle. An
|
|
25
|
+
* `EngineError` with code `Forbidden`, on both engines.
|
|
26
|
+
*
|
|
27
|
+
* `required` (also `details.required`) names what the caller needed (e.g.
|
|
28
|
+
* "doc.render" or "annotations:update"). When any of several would have
|
|
29
|
+
* done, `anyOf` (also `details.anyOf`) lists them and `required` is the
|
|
30
|
+
* first. `context` is an optional label such as "engine-local" or a route.
|
|
31
|
+
*/
|
|
32
|
+
var PermissionDenied = class extends require_format.EngineError {
|
|
33
|
+
constructor(required, context, anyOf, refs) {
|
|
34
|
+
super(require_format.EngineErrorCode.Forbidden, `permission denied${context ? ` (${context})` : ""}: ${anyOf ? `one of ${anyOf.join(", ")}` : required}${refs ? ` for ${refs.length} annotation${refs.length === 1 ? "" : "s"}` : ""}`, { details: {
|
|
35
|
+
required,
|
|
36
|
+
...context === void 0 ? {} : { context },
|
|
37
|
+
...anyOf === void 0 ? {} : { anyOf: [...anyOf] },
|
|
38
|
+
...refs === void 0 ? {} : { refs: [...refs] }
|
|
39
|
+
} });
|
|
40
|
+
this.required = required;
|
|
41
|
+
this.context = context;
|
|
42
|
+
this.anyOf = anyOf;
|
|
43
|
+
this.refs = refs;
|
|
44
|
+
require_format._defineProperty(this, "name", "PermissionDenied");
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Thrown at engine-local open time when the supplied scope includes
|
|
49
|
+
* collab filters (`:self`, `:group=...`) but the identity claims needed
|
|
50
|
+
* to resolve them are missing. Fails loudly at open so the configuration
|
|
51
|
+
* mistake is visible immediately instead of producing silent denies at
|
|
52
|
+
* every annotation mutation. An `EngineError` with code `InvalidArg`.
|
|
53
|
+
*/
|
|
54
|
+
var MissingIdentity = class extends require_format.EngineError {
|
|
55
|
+
constructor(scope) {
|
|
56
|
+
super(require_format.EngineErrorCode.InvalidArg, `scope "${scope}" requires an identity (userId and/or groups)`, { details: { scope } });
|
|
57
|
+
this.scope = scope;
|
|
58
|
+
require_format._defineProperty(this, "name", "MissingIdentity");
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
//#endregion
|
|
62
|
+
//#region src/identity/AnnotationRef.ts
|
|
63
|
+
/**
|
|
64
|
+
* URL-safe encoding of a ref without its page, used by the cloud HTTP
|
|
65
|
+
* surface as the `:annotKey` route parameter beside `:pageKey`
|
|
66
|
+
* (`encodePageKey`). Decoded by `decodeAnnotKey`.
|
|
67
|
+
*
|
|
68
|
+
* `{ kind: 'objectNumber', objectNumber: 42 }` -> `'obj:42'`
|
|
69
|
+
* `{ kind: 'baseIndex', baseIndex: 2 }` -> `'base:2'`
|
|
70
|
+
*/
|
|
71
|
+
function encodeAnnotKey(ref) {
|
|
72
|
+
if (ref.kind === "objectNumber") {
|
|
73
|
+
if (!Number.isInteger(ref.objectNumber) || ref.objectNumber <= 0) throw new RangeError(`encodeAnnotKey: objectNumber must be a positive integer, got ${ref.objectNumber}`);
|
|
74
|
+
return `obj:${ref.objectNumber}`;
|
|
75
|
+
}
|
|
76
|
+
if (!Number.isInteger(ref.baseIndex) || ref.baseIndex < 0) throw new RangeError(`encodeAnnotKey: baseIndex must be a non-negative integer, got ${ref.baseIndex}`);
|
|
77
|
+
return `base:${ref.baseIndex}`;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Inverse of `encodeAnnotKey`, on the page the route names. Returns `null`
|
|
81
|
+
* for malformed input so the server can answer 400 InvalidArg with a useful
|
|
82
|
+
* message instead of throwing. The input is the already-`decodeURIComponent`-ed
|
|
83
|
+
* segment from the route path.
|
|
84
|
+
*/
|
|
85
|
+
function decodeAnnotKey(page, key) {
|
|
86
|
+
const number = (prefix, min) => {
|
|
87
|
+
if (!key.startsWith(prefix)) return null;
|
|
88
|
+
const rest = key.slice(prefix.length);
|
|
89
|
+
const n = Number.parseInt(rest, 10);
|
|
90
|
+
return Number.isInteger(n) && n >= min && String(n) === rest ? n : null;
|
|
91
|
+
};
|
|
92
|
+
const objectNumber = number("obj:", 1);
|
|
93
|
+
if (objectNumber !== null) return {
|
|
94
|
+
kind: "objectNumber",
|
|
95
|
+
page,
|
|
96
|
+
objectNumber
|
|
97
|
+
};
|
|
98
|
+
const baseIndex = number("base:", 0);
|
|
99
|
+
if (baseIndex !== null) return {
|
|
100
|
+
kind: "baseIndex",
|
|
101
|
+
page,
|
|
102
|
+
baseIndex
|
|
103
|
+
};
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
//#endregion
|
|
1
107
|
//#region src/signature/protection.ts
|
|
2
108
|
/**
|
|
3
109
|
* Bumped whenever the derivation below (or a judgement rule) changes meaning.
|
|
4
110
|
* Rides every protection and every analysis, and keys the cloud's immutable
|
|
5
|
-
* analysis URLs.
|
|
111
|
+
* analysis URLs. The current policy is calibrated on the 91 Acrobat
|
|
112
|
+
* observations in `packages/engine/main/test/fixtures/signature-compat`:
|
|
6
113
|
* each signature is judged on the net state of the document against the
|
|
7
114
|
* revision it sealed; an object written again with the sealed value is not
|
|
8
115
|
* a modification; an approval signature permits commenting; field
|
|
@@ -15,8 +122,8 @@ const SIGNATURE_POLICY_VERSION = 4;
|
|
|
15
122
|
* changes only for certification signatures; Acrobat reads an approval
|
|
16
123
|
* signature as "Form Fill-in, Signing and Commenting are allowed" (its own
|
|
17
124
|
* permission text under every such signature) and keeps it valid through a
|
|
18
|
-
* Square annotation added, deleted or recoloured afterwards (
|
|
19
|
-
* `signature-compat
|
|
125
|
+
* Square annotation added, deleted or recoloured afterwards (fixtures
|
|
126
|
+
* `signature-compat/v3/88`, `/90` and `/91`: "Annotations Created/Deleted/
|
|
20
127
|
* Modified", signature valid). pyHanko judges stricter (fill only); Acrobat
|
|
21
128
|
* is the validator recipients use, so the baseline is `annotate`.
|
|
22
129
|
*/
|
|
@@ -64,7 +171,7 @@ function lockCovers(spec, fieldName) {
|
|
|
64
171
|
* did allow annotations.
|
|
65
172
|
* fieldLocks = every signed signature's FieldMDP and the /Lock of every
|
|
66
173
|
* signed field. Unsigned fields' /Lock entries describe a
|
|
67
|
-
*
|
|
174
|
+
* future signature and lock nothing yet.
|
|
68
175
|
*/
|
|
69
176
|
function deriveProtection(signatures) {
|
|
70
177
|
let signed = false;
|
|
@@ -109,15 +216,37 @@ function fieldLockFor(protection, fieldName) {
|
|
|
109
216
|
return null;
|
|
110
217
|
}
|
|
111
218
|
/**
|
|
219
|
+
* Every capability a protection can remove: the most it ever takes away.
|
|
220
|
+
* A check of any other capability never needs the document's protection.
|
|
221
|
+
*/
|
|
222
|
+
const PROTECTABLE_CAPABILITIES = [
|
|
223
|
+
"doc.download.flattened",
|
|
224
|
+
"doc.pages.modify",
|
|
225
|
+
"doc.pages.assemble",
|
|
226
|
+
"doc.redact",
|
|
227
|
+
"doc.attachments.modify",
|
|
228
|
+
"doc.forms.modify",
|
|
229
|
+
"doc.forms.script",
|
|
230
|
+
"doc.annotate.modify",
|
|
231
|
+
"doc.annotate.import",
|
|
232
|
+
"doc.forms.fill",
|
|
233
|
+
"doc.forms.import"
|
|
234
|
+
];
|
|
235
|
+
const PROTECTABLE = new Set(PROTECTABLE_CAPABILITIES);
|
|
236
|
+
/** Whether a protection can ever remove `capability`. */
|
|
237
|
+
function isProtectableCapability(capability) {
|
|
238
|
+
return PROTECTABLE.has(capability);
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
112
241
|
* The capabilities a protection removes from every caller, admin scope
|
|
113
242
|
* included — document-derived authority, exactly like encryption bits.
|
|
114
243
|
*
|
|
115
|
-
* Only what was
|
|
244
|
+
* Only what was declared is refused: a refusal is a promise a signer made,
|
|
116
245
|
* never a guess about a validator. A certification (or a lock with /P)
|
|
117
246
|
* declares what may follow, and everything outside that — page edits,
|
|
118
247
|
* redaction, field authoring, attachments, and below P=3 annotations, below
|
|
119
248
|
* P=2 form fill — is refused. A plain approval signature declares nothing:
|
|
120
|
-
* the same edits stay possible and are then
|
|
249
|
+
* the same edits stay possible and are then judged, the verdict saying the
|
|
121
250
|
* signature no longer holds, exactly as Acrobat does. The one exception is a
|
|
122
251
|
* rewrite: it does not invalidate signatures, it erases them, so any signed
|
|
123
252
|
* document refuses it. Per-field locks are enforced by the form mutator.
|
|
@@ -132,62 +261,27 @@ function protectedCapabilities(protection) {
|
|
|
132
261
|
out.add("doc.redact");
|
|
133
262
|
out.add("doc.attachments.modify");
|
|
134
263
|
out.add("doc.forms.modify");
|
|
135
|
-
|
|
136
|
-
if (!levelAllows(protection.enforced, "
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
//#endregion
|
|
140
|
-
//#region src/auth/scope/errors.ts
|
|
141
|
-
/**
|
|
142
|
-
* Thrown by {@link parseScope} / {@link validateScopeArray} when a scope
|
|
143
|
-
* string does not match any known grammar (capability, collab, virtual,
|
|
144
|
-
* or wildcard).
|
|
145
|
-
*
|
|
146
|
-
* Carries the offending scope verbatim so route/JWT-layer error
|
|
147
|
-
* handlers can echo it to the customer.
|
|
148
|
-
*/
|
|
149
|
-
var InvalidScope = class extends Error {
|
|
150
|
-
constructor(scope, reason) {
|
|
151
|
-
super(`invalid scope "${scope}": ${reason}`);
|
|
152
|
-
this.scope = scope;
|
|
153
|
-
this.name = "InvalidScope";
|
|
264
|
+
out.add("doc.forms.script");
|
|
265
|
+
if (!levelAllows(protection.enforced, "annotate")) {
|
|
266
|
+
out.add("doc.annotate.modify");
|
|
267
|
+
out.add("doc.annotate.import");
|
|
154
268
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
* or collab action is denied for the current request/handle.
|
|
159
|
-
*
|
|
160
|
-
* `required` names what the caller needed (e.g., "doc.render" or
|
|
161
|
-
* "annotations:update"). `context` is an optional label such as "local"
|
|
162
|
-
* or "/v1/docs/.../pages/2/render".
|
|
163
|
-
*/
|
|
164
|
-
var PermissionDenied = class extends Error {
|
|
165
|
-
constructor(required, context) {
|
|
166
|
-
super(`permission denied${context ? ` (${context})` : ""}: ${required}`);
|
|
167
|
-
this.required = required;
|
|
168
|
-
this.context = context;
|
|
169
|
-
this.name = "PermissionDenied";
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
/**
|
|
173
|
-
* Thrown at engine-local open time when the supplied scope includes
|
|
174
|
-
* collab filters (`:self`, `:group=...`) but the identity claims needed
|
|
175
|
-
* to resolve them are missing. Fails loudly at open so the configuration
|
|
176
|
-
* mistake is visible immediately instead of producing silent denies at
|
|
177
|
-
* every annotation mutation.
|
|
178
|
-
*/
|
|
179
|
-
var MissingIdentity = class extends Error {
|
|
180
|
-
constructor(scope) {
|
|
181
|
-
super(`scope "${scope}" requires identity claims (user_id and/or groups)`);
|
|
182
|
-
this.name = "MissingIdentity";
|
|
269
|
+
if (!levelAllows(protection.enforced, "fill")) {
|
|
270
|
+
out.add("doc.forms.fill");
|
|
271
|
+
out.add("doc.forms.import");
|
|
183
272
|
}
|
|
184
|
-
|
|
273
|
+
return out;
|
|
274
|
+
}
|
|
275
|
+
/** Why `protection` refuses `capability`: the message of a `ProtectedDocument` refusal. */
|
|
276
|
+
function describeProtection(capability, protection) {
|
|
277
|
+
return `the document is signed: ${protection.certification ? `certification signature ${protection.certification.signatureIndex} (permission ${protection.certification.permission})` : `an existing signature (declared level '${protection.enforced ?? "none declared"}')`} forbids '${capability}'`;
|
|
278
|
+
}
|
|
185
279
|
//#endregion
|
|
186
280
|
//#region src/auth/scope/parser.ts
|
|
187
281
|
/**
|
|
188
282
|
* Closed set of recognized capability strings. Membership is the
|
|
189
283
|
* authoritative source of truth — adding a new capability requires
|
|
190
|
-
* extending the `DocCapability` union
|
|
284
|
+
* extending the `DocCapability` union and adding it here. The parser
|
|
191
285
|
* rejects anything outside this set.
|
|
192
286
|
*
|
|
193
287
|
* Removed legacy names (e.g., `doc.read`, `doc.edit-pages`, `doc.save`)
|
|
@@ -210,9 +304,12 @@ const KNOWN_CAPABILITIES = /* @__PURE__ */ new Set([
|
|
|
210
304
|
"doc.forms.read",
|
|
211
305
|
"doc.forms.fill",
|
|
212
306
|
"doc.forms.modify",
|
|
307
|
+
"doc.forms.import",
|
|
308
|
+
"doc.forms.script",
|
|
213
309
|
"doc.forms.submit",
|
|
214
310
|
"doc.annotate.read",
|
|
215
311
|
"doc.annotate.modify",
|
|
312
|
+
"doc.annotate.import",
|
|
216
313
|
"doc.metadata.modify",
|
|
217
314
|
"doc.attachments.modify",
|
|
218
315
|
"doc.redact",
|
|
@@ -257,6 +354,7 @@ function parseCollab(raw) {
|
|
|
257
354
|
const entity = raw.slice(0, idx1);
|
|
258
355
|
const action = raw.slice(idx1 + 1, idx2);
|
|
259
356
|
const filterStr = raw.slice(idx2 + 1);
|
|
357
|
+
if (entity === "fields") return parseFieldScope(raw, action, filterStr);
|
|
260
358
|
if (entity !== "annotations") throw new InvalidScope(raw, `unknown collab entity: ${entity}`);
|
|
261
359
|
if (action !== "create" && action !== "update" && action !== "delete" && action !== "set-group" && action !== "*") throw new InvalidScope(raw, `unknown collab action: ${action}`);
|
|
262
360
|
const filter = parseFilter(filterStr, raw);
|
|
@@ -268,6 +366,22 @@ function parseCollab(raw) {
|
|
|
268
366
|
filter
|
|
269
367
|
};
|
|
270
368
|
}
|
|
369
|
+
/**
|
|
370
|
+
* `fields:<fill|sign|set-group|*>:<all|group=NAME>`. A field's group is who
|
|
371
|
+
* fills it, and a field records no creator, so `self` and `createdBy=` are
|
|
372
|
+
* refused.
|
|
373
|
+
*/
|
|
374
|
+
function parseFieldScope(raw, action, filterStr) {
|
|
375
|
+
if (action !== "fill" && action !== "sign" && action !== "set-group" && action !== "*") throw new InvalidScope(raw, `unknown fields action: ${action}`);
|
|
376
|
+
const filter = parseFilter(filterStr, raw);
|
|
377
|
+
if (filter.kind !== "all" && filter.kind !== "group") throw new InvalidScope(raw, `fields only support :all or :group=<id> filters (got :${filter.kind})`);
|
|
378
|
+
return {
|
|
379
|
+
kind: "collab",
|
|
380
|
+
entity: "fields",
|
|
381
|
+
action,
|
|
382
|
+
filter
|
|
383
|
+
};
|
|
384
|
+
}
|
|
271
385
|
function parseFilter(s, raw) {
|
|
272
386
|
if (s === "all") return { kind: "all" };
|
|
273
387
|
if (s === "self") return { kind: "self" };
|
|
@@ -300,6 +414,13 @@ function parseCapability(raw) {
|
|
|
300
414
|
}
|
|
301
415
|
//#endregion
|
|
302
416
|
//#region src/auth/scope/resolver.ts
|
|
417
|
+
/** The collab target of a record read with nullable owner fields (an annotation). */
|
|
418
|
+
function collabTargetOf(owner) {
|
|
419
|
+
return {
|
|
420
|
+
...owner.userId ? { userId: owner.userId } : {},
|
|
421
|
+
...owner.groupId ? { groupId: owner.groupId } : {}
|
|
422
|
+
};
|
|
423
|
+
}
|
|
303
424
|
/**
|
|
304
425
|
* True iff the given capability is granted by the scope array plus the
|
|
305
426
|
* PDF bits visible via `pdf.permissions` expansion.
|
|
@@ -314,9 +435,9 @@ function checkCapability(capability, rawScope, pdfBits, protection = null) {
|
|
|
314
435
|
return expandedCapabilities(parsed, pdfBits, protection).has(capability);
|
|
315
436
|
}
|
|
316
437
|
/**
|
|
317
|
-
* True iff the scope grants
|
|
318
|
-
* for routes like `/text` (`doc.text.copy`
|
|
319
|
-
* `/geometry` (`doc.text.select`
|
|
438
|
+
* True iff the scope grants at least one of `capabilities`. Convenience
|
|
439
|
+
* for routes like `/text` (`doc.text.copy` or `doc.text.search`) and
|
|
440
|
+
* `/geometry` (`doc.text.select` or `doc.text.search`).
|
|
320
441
|
*/
|
|
321
442
|
function checkAnyCapability(capabilities, rawScope, pdfBits, protection = null) {
|
|
322
443
|
return capabilities.some((c) => checkCapability(c, rawScope, pdfBits, protection));
|
|
@@ -326,7 +447,7 @@ function checkAnyCapability(capabilities, rawScope, pdfBits, protection = null)
|
|
|
326
447
|
*
|
|
327
448
|
* Narrowing model. For each action independently:
|
|
328
449
|
* 1. wildcard `*` → allow (global escape hatch)
|
|
329
|
-
* 2. if any collab scope applies to this action →
|
|
450
|
+
* 2. if any collab scope applies to this action → narrow: only those
|
|
330
451
|
* collab filters decide. If none match the target, deny — even if
|
|
331
452
|
* `doc.annotate.modify` is also present. This is what makes
|
|
332
453
|
* `[modify, update:self]` correctly mean "edit own only" rather
|
|
@@ -337,7 +458,7 @@ function checkAnyCapability(capabilities, rawScope, pdfBits, protection = null)
|
|
|
337
458
|
* 4. otherwise → deny.
|
|
338
459
|
*
|
|
339
460
|
* For create: `target` should be built by the caller from JWT identity
|
|
340
|
-
* (`{ userId: caller.
|
|
461
|
+
* (`{ userId: caller.userId, groupId: caller.groupId }`). `:self` and
|
|
341
462
|
* `:all` then trivially pass; `:group=X` is the meaningful filter (only
|
|
342
463
|
* matches when the caller's default group is X).
|
|
343
464
|
*
|
|
@@ -362,17 +483,22 @@ function checkCollab(action, target, rawScope, identity, pdfBits) {
|
|
|
362
483
|
* - any annotation collab scope implies `doc.annotate.read`, because
|
|
363
484
|
* mutation routes need to see the target row to evaluate the
|
|
364
485
|
* collab filter against its current owner.
|
|
486
|
+
* - any field collab scope implies `doc.forms.read`: filling in or
|
|
487
|
+
* signing a field means seeing the form. Groups limit writes, never
|
|
488
|
+
* reads.
|
|
365
489
|
*
|
|
366
|
-
* Does
|
|
490
|
+
* Does not short-circuit on wildcard — callers do that themselves
|
|
367
491
|
* before calling this. Returning the expanded set is useful for the
|
|
368
492
|
* `/access` response's `effectiveScope` and for advisory UI surfacing.
|
|
369
493
|
*/
|
|
370
494
|
function expandedCapabilities(parsed, pdfBits, protection = null) {
|
|
371
495
|
const out = /* @__PURE__ */ new Set();
|
|
372
496
|
let hasAnnotationCollab = false;
|
|
497
|
+
let hasFieldCollab = false;
|
|
373
498
|
for (const s of parsed) if (s.kind === "capability") out.add(s.name);
|
|
374
499
|
else if (s.kind === "virtual" && s.name === "pdf.permissions") addPdfPermissions(out, pdfBits);
|
|
375
500
|
else if (s.kind === "collab" && s.entity === "annotations") hasAnnotationCollab = true;
|
|
501
|
+
else if (s.kind === "collab" && s.entity === "fields") hasFieldCollab = true;
|
|
376
502
|
if (out.has("doc.annotate.modify")) out.add("doc.annotate.read");
|
|
377
503
|
if (out.has("doc.forms.modify")) {
|
|
378
504
|
out.add("doc.forms.fill");
|
|
@@ -380,6 +506,7 @@ function expandedCapabilities(parsed, pdfBits, protection = null) {
|
|
|
380
506
|
}
|
|
381
507
|
if (out.has("doc.forms.fill")) out.add("doc.forms.read");
|
|
382
508
|
if (hasAnnotationCollab) out.add("doc.annotate.read");
|
|
509
|
+
if (hasFieldCollab) out.add("doc.forms.read");
|
|
383
510
|
for (const removed of protectedCapabilities(protection)) out.delete(removed);
|
|
384
511
|
return out;
|
|
385
512
|
}
|
|
@@ -392,117 +519,140 @@ function expandRawScope(rawScope, pdfBits, protection = null) {
|
|
|
392
519
|
return expandedCapabilities(rawScope.map(parseScope), pdfBits, protection);
|
|
393
520
|
}
|
|
394
521
|
/**
|
|
395
|
-
*
|
|
396
|
-
*
|
|
522
|
+
* Authority to put a record of `entity` in a specific group: an annotation,
|
|
523
|
+
* or a form field.
|
|
397
524
|
*
|
|
398
|
-
*
|
|
399
|
-
*
|
|
400
|
-
*
|
|
401
|
-
*
|
|
402
|
-
*
|
|
403
|
-
*
|
|
404
|
-
* The group-membership check on `group=X` prevents a token from
|
|
405
|
-
* matching annotations in a group it doesn't belong to, even if the
|
|
406
|
-
* target row carries that groupId.
|
|
407
|
-
*/
|
|
408
|
-
/**
|
|
409
|
-
* Authority to assign a specific groupId to an annotation.
|
|
410
|
-
*
|
|
411
|
-
* Set-group is decoupled from `doc.annotate.modify`. The reasoning:
|
|
412
|
-
* capabilities like `modify` describe row access — what kind of write
|
|
413
|
-
* you can do to which existing rows — and map to PDF permission bits.
|
|
414
|
-
* Set-group is a cloud-only *assignment authority*: which destination
|
|
415
|
-
* group can you put an annotation into? There is no PDF-bit
|
|
416
|
-
* counterpart, so it doesn't inherit from `modify`.
|
|
525
|
+
* Set-group is decoupled from the write capabilities (`doc.annotate.modify`,
|
|
526
|
+
* `doc.forms.modify`). The reasoning: those describe row access — what kind
|
|
527
|
+
* of write you can do to which existing rows — and map to PDF permission
|
|
528
|
+
* bits. Set-group is a cloud-only *assignment authority*: which destination
|
|
529
|
+
* group can you put a record into? There is no PDF-bit counterpart, so it
|
|
530
|
+
* doesn't inherit from them.
|
|
417
531
|
*
|
|
418
532
|
* Resolution order:
|
|
419
533
|
* 1. newGroupId === callerDefaultGroupId → true (no real reassignment
|
|
420
|
-
* is happening; the
|
|
534
|
+
* is happening; the record gets the caller's default group)
|
|
421
535
|
* 2. wildcard `*` → true (global escape hatch)
|
|
422
|
-
* 3.
|
|
423
|
-
* 4.
|
|
424
|
-
* 5.
|
|
536
|
+
* 3. `<entity>:set-group:all` → true
|
|
537
|
+
* 4. `<entity>:set-group:group=<newGroupId>` → true
|
|
538
|
+
* 5. `<entity>:*:all` or `<entity>:*:group=<newGroupId>` → true
|
|
425
539
|
* (action wildcard includes set-group)
|
|
426
540
|
* 6. otherwise → false
|
|
427
541
|
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
* even if they're not a member — that's the whole point.
|
|
542
|
+
* A user with `set-group:group=legal` can put records in the legal group
|
|
543
|
+
* whatever their own group is — that's the whole point.
|
|
431
544
|
*/
|
|
432
|
-
function checkSetGroup(newGroupId, callerDefaultGroupId, rawScope
|
|
545
|
+
function checkSetGroup(entity, newGroupId, callerDefaultGroupId, rawScope) {
|
|
433
546
|
if (newGroupId === callerDefaultGroupId) return true;
|
|
434
547
|
const parsed = rawScope.map(parseScope);
|
|
435
548
|
if (parsed.some((s) => s.kind === "wildcard")) return true;
|
|
436
549
|
for (const s of parsed) {
|
|
437
550
|
if (s.kind !== "collab") continue;
|
|
438
|
-
if (s.entity !==
|
|
551
|
+
if (s.entity !== entity) continue;
|
|
439
552
|
if (s.action !== "set-group" && s.action !== "*") continue;
|
|
440
553
|
if (s.filter.kind === "all") return true;
|
|
441
554
|
if (s.filter.kind === "group" && s.filter.groupId === newGroupId) return true;
|
|
442
555
|
}
|
|
443
556
|
return false;
|
|
444
557
|
}
|
|
558
|
+
/**
|
|
559
|
+
* True iff the scope lets the caller `action` (fill in, or sign) a form
|
|
560
|
+
* field in `groupId` (`null` for a field in no group).
|
|
561
|
+
*
|
|
562
|
+
* Narrowing, per action, as for annotations:
|
|
563
|
+
* 1. wildcard `*` → allow;
|
|
564
|
+
* 2. if any `fields:<action>` scope exists (or `fields:*`) → only those
|
|
565
|
+
* decide: the field must match one of their filters, even when the
|
|
566
|
+
* broad capability is also present. A field in no group then matches
|
|
567
|
+
* only `:all`;
|
|
568
|
+
* 3. otherwise the broad capability decides, for every field:
|
|
569
|
+
* `doc.forms.fill` to fill, `doc.sign` to sign.
|
|
570
|
+
*
|
|
571
|
+
* Nothing here narrows form design (`doc.forms.modify`).
|
|
572
|
+
*/
|
|
573
|
+
function checkFieldAction(action, groupId, rawScope, pdfBits, protection = null) {
|
|
574
|
+
const broad = action === "fill" ? "doc.forms.fill" : "doc.sign";
|
|
575
|
+
if (protectedCapabilities(protection).has(broad)) return false;
|
|
576
|
+
const parsed = rawScope.map(parseScope);
|
|
577
|
+
if (parsed.some((s) => s.kind === "wildcard")) return true;
|
|
578
|
+
const applicable = parsed.filter((s) => s.kind === "collab" && s.entity === "fields" && (s.action === action || s.action === "*"));
|
|
579
|
+
if (applicable.length > 0) return applicable.some((s) => s.filter.kind === "all" || groupId !== null && s.filter.groupId === groupId);
|
|
580
|
+
return expandedCapabilities(parsed, pdfBits, protection).has(broad);
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* {@link checkFieldAction} and {@link checkSetGroup} as lists: for each
|
|
584
|
+
* action, every field or the groups the scope names, so a designer can
|
|
585
|
+
* offer exactly the groups a field may go in, and a filler see whose fields
|
|
586
|
+
* are theirs. The same rules, read the other way round.
|
|
587
|
+
*/
|
|
588
|
+
function fieldRightsOf(rawScope, pdfBits, protection, callerDefaultGroupId) {
|
|
589
|
+
const parsed = rawScope.map(parseScope);
|
|
590
|
+
const wildcard = parsed.some((s) => s.kind === "wildcard");
|
|
591
|
+
const fieldScopes = (action) => parsed.filter((s) => s.kind === "collab" && s.entity === "fields" && (s.action === action || s.action === "*"));
|
|
592
|
+
const fromScopes = (scopes, extra = []) => {
|
|
593
|
+
if (scopes.some((s) => s.filter.kind === "all")) return { all: true };
|
|
594
|
+
const groups = scopes.flatMap((s) => s.filter.kind === "group" ? [s.filter.groupId] : []);
|
|
595
|
+
return {
|
|
596
|
+
all: false,
|
|
597
|
+
groups: [.../* @__PURE__ */ new Set([...groups, ...extra])]
|
|
598
|
+
};
|
|
599
|
+
};
|
|
600
|
+
const NONE = {
|
|
601
|
+
all: false,
|
|
602
|
+
groups: []
|
|
603
|
+
};
|
|
604
|
+
const writing = (action) => {
|
|
605
|
+
const broad = action === "fill" ? "doc.forms.fill" : "doc.sign";
|
|
606
|
+
if (protectedCapabilities(protection).has(broad)) return NONE;
|
|
607
|
+
if (wildcard) return { all: true };
|
|
608
|
+
const scopes = fieldScopes(action);
|
|
609
|
+
if (scopes.length > 0) return fromScopes(scopes);
|
|
610
|
+
return expandedCapabilities(parsed, pdfBits, protection).has(broad) ? { all: true } : NONE;
|
|
611
|
+
};
|
|
612
|
+
const own = callerDefaultGroupId !== void 0 ? [callerDefaultGroupId] : [];
|
|
613
|
+
return {
|
|
614
|
+
fill: writing("fill"),
|
|
615
|
+
sign: writing("sign"),
|
|
616
|
+
setGroup: wildcard ? { all: true } : fromScopes(fieldScopes("set-group"), own)
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
/**
|
|
620
|
+
* Whether the scope lets the caller `action` some form field: the broad
|
|
621
|
+
* capability, or any `fields:<action>` scope. What a form verb checks
|
|
622
|
+
* before its fields are known; each field is checked in the write.
|
|
623
|
+
*/
|
|
624
|
+
function checkAnyFieldAction(action, rawScope, pdfBits, protection = null) {
|
|
625
|
+
const broad = action === "fill" ? "doc.forms.fill" : "doc.sign";
|
|
626
|
+
if (protectedCapabilities(protection).has(broad)) return false;
|
|
627
|
+
const parsed = rawScope.map(parseScope);
|
|
628
|
+
if (parsed.some((s) => s.kind === "wildcard")) return true;
|
|
629
|
+
if (parsed.some((s) => s.kind === "collab" && s.entity === "fields" && (s.action === action || s.action === "*"))) return true;
|
|
630
|
+
return expandedCapabilities(parsed, pdfBits, protection).has(broad);
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Test a single collab filter against a target record. Every filter but
|
|
634
|
+
* `self` compares one fact on the record with the value the scope names:
|
|
635
|
+
*
|
|
636
|
+
* all → always matches
|
|
637
|
+
* self → matches if identity.userId === target.userId
|
|
638
|
+
* createdBy=<X> → matches if target.userId === X
|
|
639
|
+
* group=<X> → matches if target.groupId === X
|
|
640
|
+
*/
|
|
445
641
|
function filterMatches(filter, target, id) {
|
|
446
642
|
switch (filter.kind) {
|
|
447
643
|
case "all": return true;
|
|
448
|
-
case "self": return !!id.
|
|
644
|
+
case "self": return !!id.userId && target.userId === id.userId;
|
|
449
645
|
case "createdBy": return target.userId === filter.userId;
|
|
450
|
-
case "group": return target.groupId === filter.groupId
|
|
646
|
+
case "group": return target.groupId === filter.groupId;
|
|
451
647
|
}
|
|
452
648
|
}
|
|
453
649
|
/**
|
|
454
650
|
* Translate `pdf.permissions` (virtual scope) into the concrete
|
|
455
|
-
* capabilities it represents under the current PDF bit configuration
|
|
456
|
-
*
|
|
457
|
-
* Always adds `doc.open` and `doc.render` — these are cloud-only
|
|
458
|
-
* capabilities with no PDF bit, but `pdf.permissions` is meant to be
|
|
459
|
-
* the "give the user a working session" shorthand. Without them, a
|
|
460
|
-
* token with just `['pdf.permissions']` would be useless.
|
|
461
|
-
*
|
|
462
|
-
* Reads are unconditional: ISO 32000 / Acrobat let any reader see
|
|
463
|
-
* existing annotations and form values regardless of permission bits.
|
|
464
|
-
* Bit 6 governs *writing*, not visibility.
|
|
465
|
-
*
|
|
466
|
-
* Bit-derived expansions follow ISO 32000:
|
|
467
|
-
* bit 5 → doc.text.{select, copy, search}, doc.content.copy
|
|
468
|
-
* bit 3 → doc.print
|
|
469
|
-
* bit 12 → doc.print.high (requires bit 3 also set)
|
|
470
|
-
* bit 4 → doc.pages.modify, doc.redact, doc.metadata.modify, doc.attachments.modify
|
|
471
|
-
* bit 11 → doc.pages.assemble
|
|
472
|
-
* bit 6 → doc.annotate.modify
|
|
473
|
-
* bit 6/9 → doc.forms.fill
|
|
474
|
-
* bit 6+4 → doc.forms.modify
|
|
475
|
-
*
|
|
476
|
-
* Note: this same expansion lives in builders.ts as
|
|
477
|
-
* `materializePdfPermissions` for SDK-side use. The two MUST stay in
|
|
478
|
-
* sync; a test in resolver.test.ts pins them together.
|
|
651
|
+
* capabilities it represents under the current PDF bit configuration:
|
|
652
|
+
* {@link materializePdfPermissions}, the one reading of the bits.
|
|
479
653
|
*/
|
|
480
654
|
function addPdfPermissions(out, b) {
|
|
481
|
-
out.add(
|
|
482
|
-
out.add("doc.render");
|
|
483
|
-
out.add("doc.annotate.read");
|
|
484
|
-
out.add("doc.forms.read");
|
|
485
|
-
if (b.bit5) {
|
|
486
|
-
out.add("doc.text.select");
|
|
487
|
-
out.add("doc.text.copy");
|
|
488
|
-
out.add("doc.text.search");
|
|
489
|
-
out.add("doc.content.copy");
|
|
490
|
-
}
|
|
491
|
-
if (b.bit3) out.add("doc.print");
|
|
492
|
-
if (b.bit12 && b.bit3) out.add("doc.print.high");
|
|
493
|
-
if (b.bit4) {
|
|
494
|
-
out.add("doc.pages.modify");
|
|
495
|
-
out.add("doc.redact");
|
|
496
|
-
out.add("doc.metadata.modify");
|
|
497
|
-
out.add("doc.attachments.modify");
|
|
498
|
-
}
|
|
499
|
-
if (b.bit11) out.add("doc.pages.assemble");
|
|
500
|
-
if (b.bit6) out.add("doc.annotate.modify");
|
|
501
|
-
if (b.bit6 || b.bit9) {
|
|
502
|
-
out.add("doc.forms.fill");
|
|
503
|
-
out.add("doc.sign");
|
|
504
|
-
}
|
|
505
|
-
if (b.bit6 && b.bit4) out.add("doc.forms.modify");
|
|
655
|
+
for (const capability of require_builders.materializePdfPermissions(b)) out.add(capability);
|
|
506
656
|
}
|
|
507
657
|
//#endregion
|
|
508
658
|
Object.defineProperty(exports, "APPROVAL_BASELINE", {
|
|
@@ -523,6 +673,12 @@ Object.defineProperty(exports, "MissingIdentity", {
|
|
|
523
673
|
return MissingIdentity;
|
|
524
674
|
}
|
|
525
675
|
});
|
|
676
|
+
Object.defineProperty(exports, "PROTECTABLE_CAPABILITIES", {
|
|
677
|
+
enumerable: true,
|
|
678
|
+
get: function() {
|
|
679
|
+
return PROTECTABLE_CAPABILITIES;
|
|
680
|
+
}
|
|
681
|
+
});
|
|
526
682
|
Object.defineProperty(exports, "PermissionDenied", {
|
|
527
683
|
enumerable: true,
|
|
528
684
|
get: function() {
|
|
@@ -541,6 +697,12 @@ Object.defineProperty(exports, "checkAnyCapability", {
|
|
|
541
697
|
return checkAnyCapability;
|
|
542
698
|
}
|
|
543
699
|
});
|
|
700
|
+
Object.defineProperty(exports, "checkAnyFieldAction", {
|
|
701
|
+
enumerable: true,
|
|
702
|
+
get: function() {
|
|
703
|
+
return checkAnyFieldAction;
|
|
704
|
+
}
|
|
705
|
+
});
|
|
544
706
|
Object.defineProperty(exports, "checkCapability", {
|
|
545
707
|
enumerable: true,
|
|
546
708
|
get: function() {
|
|
@@ -553,18 +715,48 @@ Object.defineProperty(exports, "checkCollab", {
|
|
|
553
715
|
return checkCollab;
|
|
554
716
|
}
|
|
555
717
|
});
|
|
718
|
+
Object.defineProperty(exports, "checkFieldAction", {
|
|
719
|
+
enumerable: true,
|
|
720
|
+
get: function() {
|
|
721
|
+
return checkFieldAction;
|
|
722
|
+
}
|
|
723
|
+
});
|
|
556
724
|
Object.defineProperty(exports, "checkSetGroup", {
|
|
557
725
|
enumerable: true,
|
|
558
726
|
get: function() {
|
|
559
727
|
return checkSetGroup;
|
|
560
728
|
}
|
|
561
729
|
});
|
|
730
|
+
Object.defineProperty(exports, "collabTargetOf", {
|
|
731
|
+
enumerable: true,
|
|
732
|
+
get: function() {
|
|
733
|
+
return collabTargetOf;
|
|
734
|
+
}
|
|
735
|
+
});
|
|
736
|
+
Object.defineProperty(exports, "decodeAnnotKey", {
|
|
737
|
+
enumerable: true,
|
|
738
|
+
get: function() {
|
|
739
|
+
return decodeAnnotKey;
|
|
740
|
+
}
|
|
741
|
+
});
|
|
562
742
|
Object.defineProperty(exports, "deriveProtection", {
|
|
563
743
|
enumerable: true,
|
|
564
744
|
get: function() {
|
|
565
745
|
return deriveProtection;
|
|
566
746
|
}
|
|
567
747
|
});
|
|
748
|
+
Object.defineProperty(exports, "describeProtection", {
|
|
749
|
+
enumerable: true,
|
|
750
|
+
get: function() {
|
|
751
|
+
return describeProtection;
|
|
752
|
+
}
|
|
753
|
+
});
|
|
754
|
+
Object.defineProperty(exports, "encodeAnnotKey", {
|
|
755
|
+
enumerable: true,
|
|
756
|
+
get: function() {
|
|
757
|
+
return encodeAnnotKey;
|
|
758
|
+
}
|
|
759
|
+
});
|
|
568
760
|
Object.defineProperty(exports, "expandRawScope", {
|
|
569
761
|
enumerable: true,
|
|
570
762
|
get: function() {
|
|
@@ -583,12 +775,24 @@ Object.defineProperty(exports, "fieldLockFor", {
|
|
|
583
775
|
return fieldLockFor;
|
|
584
776
|
}
|
|
585
777
|
});
|
|
778
|
+
Object.defineProperty(exports, "fieldRightsOf", {
|
|
779
|
+
enumerable: true,
|
|
780
|
+
get: function() {
|
|
781
|
+
return fieldRightsOf;
|
|
782
|
+
}
|
|
783
|
+
});
|
|
586
784
|
Object.defineProperty(exports, "filterMatches", {
|
|
587
785
|
enumerable: true,
|
|
588
786
|
get: function() {
|
|
589
787
|
return filterMatches;
|
|
590
788
|
}
|
|
591
789
|
});
|
|
790
|
+
Object.defineProperty(exports, "isProtectableCapability", {
|
|
791
|
+
enumerable: true,
|
|
792
|
+
get: function() {
|
|
793
|
+
return isProtectableCapability;
|
|
794
|
+
}
|
|
795
|
+
});
|
|
592
796
|
Object.defineProperty(exports, "levelAllows", {
|
|
593
797
|
enumerable: true,
|
|
594
798
|
get: function() {
|
|
@@ -638,4 +842,4 @@ Object.defineProperty(exports, "validateScopeArray", {
|
|
|
638
842
|
}
|
|
639
843
|
});
|
|
640
844
|
|
|
641
|
-
//# sourceMappingURL=resolver-
|
|
845
|
+
//# sourceMappingURL=resolver-D2OCtE8F.cjs.map
|