@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.
Files changed (135) hide show
  1. package/dist/AnnotationList-CkijRHet.d.cts +27163 -0
  2. package/dist/AnnotationList-CkijRHet.d.ts +27163 -0
  3. package/dist/Change-CKoxfTNY.js +889 -0
  4. package/dist/Change-CKoxfTNY.js.map +1 -0
  5. package/dist/Change-CjImsrN0.cjs +1020 -0
  6. package/dist/Change-CjImsrN0.cjs.map +1 -0
  7. package/dist/DocumentRenderService-BfFdFSwI.cjs +120 -0
  8. package/dist/DocumentRenderService-BfFdFSwI.cjs.map +1 -0
  9. package/dist/DocumentRenderService-DV3J9lMz.js +85 -0
  10. package/dist/DocumentRenderService-DV3J9lMz.js.map +1 -0
  11. package/dist/{DocumentSecurityService-_JRjqvoI.d.ts → DocumentSecurityService-CU1M6Q7m.d.ts} +100 -112
  12. package/dist/{DocumentSecurityService-ClTZc0zO.d.cts → DocumentSecurityService-e6vp2de8.d.cts} +100 -112
  13. package/dist/LocalDocumentHandle-D02FMm-Z.cjs +53 -0
  14. package/dist/LocalDocumentHandle-D02FMm-Z.cjs.map +1 -0
  15. package/dist/LocalDocumentHandle-DAPdaOt_.js +30 -0
  16. package/dist/LocalDocumentHandle-DAPdaOt_.js.map +1 -0
  17. package/dist/LocalEngine-DFoBm4B3.d.cts +1565 -0
  18. package/dist/LocalEngine-DPriFujS.d.ts +1565 -0
  19. package/dist/PageInsertBlankInput-CXHAM7l6.cjs +17 -0
  20. package/dist/PageInsertBlankInput-CXHAM7l6.cjs.map +1 -0
  21. package/dist/PageInsertBlankInput-DhVYVJ_S.js +12 -0
  22. package/dist/PageInsertBlankInput-DhVYVJ_S.js.map +1 -0
  23. package/dist/authority-B3BklsB4.js +2239 -0
  24. package/dist/authority-B3BklsB4.js.map +1 -0
  25. package/dist/authority-DLMNR7ff.cjs +2676 -0
  26. package/dist/authority-DLMNR7ff.cjs.map +1 -0
  27. package/dist/builders-CNj0POeY.js +161 -0
  28. package/dist/builders-CNj0POeY.js.map +1 -0
  29. package/dist/builders-Cgdp_YCn.cjs +184 -0
  30. package/dist/builders-Cgdp_YCn.cjs.map +1 -0
  31. package/dist/calibrate-7T3fnP8-.js +2404 -0
  32. package/dist/calibrate-7T3fnP8-.js.map +1 -0
  33. package/dist/calibrate-DJBXnhLE.cjs +2919 -0
  34. package/dist/calibrate-DJBXnhLE.cjs.map +1 -0
  35. package/dist/charmap-Cprti1ta.js +239 -0
  36. package/dist/charmap-Cprti1ta.js.map +1 -0
  37. package/dist/charmap-aYlefQP9.cjs +304 -0
  38. package/dist/charmap-aYlefQP9.cjs.map +1 -0
  39. package/dist/conformance.cjs +16753 -5247
  40. package/dist/conformance.cjs.map +1 -1
  41. package/dist/conformance.d.cts +928 -165
  42. package/dist/conformance.d.ts +928 -165
  43. package/dist/conformance.js +16731 -5268
  44. package/dist/conformance.js.map +1 -1
  45. package/dist/format-Bp3QFSH1.cjs +574 -0
  46. package/dist/format-Bp3QFSH1.cjs.map +1 -0
  47. package/dist/format-Dgg428Kb.js +461 -0
  48. package/dist/format-Dgg428Kb.js.map +1 -0
  49. package/dist/index.cjs +330 -103
  50. package/dist/index.d.cts +2 -2
  51. package/dist/index.d.ts +2 -2
  52. package/dist/index.js +14 -5
  53. package/dist/pageRefs-B3ur7Ckm.cjs +51 -0
  54. package/dist/pageRefs-B3ur7Ckm.cjs.map +1 -0
  55. package/dist/pageRefs-DkbuxSCV.js +40 -0
  56. package/dist/pageRefs-DkbuxSCV.js.map +1 -0
  57. package/dist/public.cjs +57 -0
  58. package/dist/public.d.cts +5 -0
  59. package/dist/public.d.ts +5 -0
  60. package/dist/public.js +9 -0
  61. package/dist/resolveAnnotationDraft-7Ke4nV7F.cjs +3646 -0
  62. package/dist/resolveAnnotationDraft-7Ke4nV7F.cjs.map +1 -0
  63. package/dist/resolveAnnotationDraft-CUpf0SMh.js +3167 -0
  64. package/dist/resolveAnnotationDraft-CUpf0SMh.js.map +1 -0
  65. package/dist/{resolver-inAVzsWt.js → resolver-CzxmD9Ck.js} +294 -144
  66. package/dist/resolver-CzxmD9Ck.js.map +1 -0
  67. package/dist/{resolver-CYVNV4hn.cjs → resolver-D2OCtE8F.cjs} +347 -143
  68. package/dist/resolver-D2OCtE8F.cjs.map +1 -0
  69. package/dist/runtime-Cl0v56mm.d.ts +2032 -0
  70. package/dist/runtime-p1WDzDo4.d.cts +2032 -0
  71. package/dist/runtime.cjs +733 -284
  72. package/dist/runtime.cjs.map +1 -1
  73. package/dist/runtime.d.cts +5 -1348
  74. package/dist/runtime.d.ts +5 -1348
  75. package/dist/runtime.js +396 -179
  76. package/dist/runtime.js.map +1 -1
  77. package/dist/schema-C-gU4vj7.cjs +3034 -0
  78. package/dist/schema-C-gU4vj7.cjs.map +1 -0
  79. package/dist/schema-DzlUNk38.js +2081 -0
  80. package/dist/schema-DzlUNk38.js.map +1 -0
  81. package/dist/schemas-Berf1swF.cjs +2481 -0
  82. package/dist/schemas-Berf1swF.cjs.map +1 -0
  83. package/dist/schemas-D6xOGjqg.js +1654 -0
  84. package/dist/schemas-D6xOGjqg.js.map +1 -0
  85. package/dist/subtype-CG4WpIRj.js +129 -0
  86. package/dist/subtype-CG4WpIRj.js.map +1 -0
  87. package/dist/subtype-aDt5TFmK.cjs +158 -0
  88. package/dist/subtype-aDt5TFmK.cjs.map +1 -0
  89. package/dist/validation.cjs +578 -0
  90. package/dist/validation.cjs.map +1 -0
  91. package/dist/validation.d.cts +174 -0
  92. package/dist/validation.d.ts +174 -0
  93. package/dist/validation.js +571 -0
  94. package/dist/validation.js.map +1 -0
  95. package/dist/value-BFS1R8ek.cjs +435 -0
  96. package/dist/value-BFS1R8ek.cjs.map +1 -0
  97. package/dist/value-Dhc8eYcx.js +340 -0
  98. package/dist/value-Dhc8eYcx.js.map +1 -0
  99. package/dist/viewport-BJW13EGZ.js +540 -0
  100. package/dist/viewport-BJW13EGZ.js.map +1 -0
  101. package/dist/viewport-DlL5Bxbg.cjs +671 -0
  102. package/dist/viewport-DlL5Bxbg.cjs.map +1 -0
  103. package/dist/wire.cjs +1056 -379
  104. package/dist/wire.cjs.map +1 -1
  105. package/dist/wire.d.cts +15069 -725
  106. package/dist/wire.d.ts +15069 -725
  107. package/dist/wire.js +825 -239
  108. package/dist/wire.js.map +1 -1
  109. package/package.json +10 -1
  110. package/dist/AbortError-Cq2igpZ6.cjs +0 -38
  111. package/dist/AbortError-Cq2igpZ6.cjs.map +0 -1
  112. package/dist/AbortError-DHqPBnYc.js +0 -27
  113. package/dist/AbortError-DHqPBnYc.js.map +0 -1
  114. package/dist/AnnotationListSnapshot-D3mFut1e.d.cts +0 -6871
  115. package/dist/AnnotationListSnapshot-D3mFut1e.d.ts +0 -6871
  116. package/dist/Engine-Bx0NOfmd.d.cts +0 -1264
  117. package/dist/Engine-DxtpCYcP.d.ts +0 -1264
  118. package/dist/PageInsertBlankInput-CqXBmFhN.cjs +0 -449
  119. package/dist/PageInsertBlankInput-CqXBmFhN.cjs.map +0 -1
  120. package/dist/PageInsertBlankInput-cHq9-i-z.js +0 -378
  121. package/dist/PageInsertBlankInput-cHq9-i-z.js.map +0 -1
  122. package/dist/builders-Bqm8yTpi.cjs +0 -3564
  123. package/dist/builders-Bqm8yTpi.cjs.map +0 -1
  124. package/dist/builders-Dqo2X-dt.js +0 -3121
  125. package/dist/builders-Dqo2X-dt.js.map +0 -1
  126. package/dist/fold-2V29cxCV.cjs +0 -447
  127. package/dist/fold-2V29cxCV.cjs.map +0 -1
  128. package/dist/fold-CdEJTBTn.js +0 -334
  129. package/dist/fold-CdEJTBTn.js.map +0 -1
  130. package/dist/resolver-CYVNV4hn.cjs.map +0 -1
  131. package/dist/resolver-inAVzsWt.js.map +0 -1
  132. package/dist/schemas-BLARNCgx.js +0 -3113
  133. package/dist/schemas-BLARNCgx.js.map +0 -1
  134. package/dist/schemas-DIqFMmrC.cjs +0 -4468
  135. package/dist/schemas-DIqFMmrC.cjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver-CzxmD9Ck.js","names":[],"sources":["../src/auth/scope/errors.ts","../src/identity/AnnotationRef.ts","../src/signature/protection.ts","../src/auth/scope/parser.ts","../src/auth/scope/resolver.ts"],"sourcesContent":["import { EngineError } from '../../errors/EngineError';\nimport { EngineErrorCode } from '../../errors/EngineErrorCode';\nimport type { AnnotationRef } from '../../identity/AnnotationRef';\n\n/**\n * Thrown by {@link parseScope} / {@link validateScopeArray} when a scope\n * string does not match any known grammar (capability, collab, virtual,\n * or wildcard). An `EngineError` with code `InvalidArg`.\n *\n * Carries the offending scope verbatim so route/JWT-layer error\n * handlers can echo it to the customer.\n */\nexport class InvalidScope extends EngineError {\n override readonly name: string = 'InvalidScope';\n\n constructor(\n public readonly scope: string,\n reason: string,\n ) {\n super(EngineErrorCode.InvalidArg, `invalid scope \"${scope}\": ${reason}`, {\n details: { scope, reason },\n });\n }\n}\n\n/**\n * Thrown by route guards and engine-local enforcement when a capability\n * or collab action is denied for the current request/handle. An\n * `EngineError` with code `Forbidden`, on both engines.\n *\n * `required` (also `details.required`) names what the caller needed (e.g.\n * \"doc.render\" or \"annotations:update\"). When any of several would have\n * done, `anyOf` (also `details.anyOf`) lists them and `required` is the\n * first. `context` is an optional label such as \"engine-local\" or a route.\n */\nexport class PermissionDenied extends EngineError {\n override readonly name: string = 'PermissionDenied';\n\n constructor(\n public readonly required: string,\n public readonly context?: string,\n public readonly anyOf?: readonly string[],\n /** The annotations it was refused for, when one write covers several (a thread's delete). */\n public readonly refs?: readonly AnnotationRef[],\n ) {\n super(\n EngineErrorCode.Forbidden,\n `permission denied${context ? ` (${context})` : ''}: ${anyOf ? `one of ${anyOf.join(', ')}` : required}${refs ? ` for ${refs.length} annotation${refs.length === 1 ? '' : 's'}` : ''}`,\n {\n details: {\n required,\n ...(context === undefined ? {} : { context }),\n ...(anyOf === undefined ? {} : { anyOf: [...anyOf] }),\n ...(refs === undefined ? {} : { refs: [...refs] }),\n },\n },\n );\n }\n}\n\n/**\n * Thrown at engine-local open time when the supplied scope includes\n * collab filters (`:self`, `:group=...`) but the identity claims needed\n * to resolve them are missing. Fails loudly at open so the configuration\n * mistake is visible immediately instead of producing silent denies at\n * every annotation mutation. An `EngineError` with code `InvalidArg`.\n */\nexport class MissingIdentity extends EngineError {\n override readonly name: string = 'MissingIdentity';\n\n constructor(public readonly scope: string) {\n super(\n EngineErrorCode.InvalidArg,\n `scope \"${scope}\" requires an identity (userId and/or groups)`,\n {\n details: { scope },\n },\n );\n }\n}\n","import type { PageRef } from './PageRef';\n\n/**\n * How callers address an annotation, and how the engine names one. Every\n * annotation has one name for life:\n *\n * - `objectNumber`: an annotation born as a PDF object, in the uploaded\n * file or written later. Object numbers are never reused.\n * - `baseIndex`: an annotation born inline in the uploaded file (a\n * dictionary in the page's `/Annots`, with no object number of its own).\n * Its name is its position in that page's `/Annots` in the uploaded\n * file, which never changes. It keeps this name after a write gives it\n * an object number.\n *\n * An annotation's `/NM` is data, not a name: files can carry the same one\n * twice. A ref that names no annotation on its page fails with `NotFound`.\n */\nexport type AnnotationRef =\n | {\n kind: 'objectNumber';\n page: PageRef;\n objectNumber: number;\n }\n | {\n kind: 'baseIndex';\n page: PageRef;\n baseIndex: number;\n };\n\n/**\n * URL-safe encoding of a ref without its page, used by the cloud HTTP\n * surface as the `:annotKey` route parameter beside `:pageKey`\n * (`encodePageKey`). Decoded by `decodeAnnotKey`.\n *\n * `{ kind: 'objectNumber', objectNumber: 42 }` -> `'obj:42'`\n * `{ kind: 'baseIndex', baseIndex: 2 }` -> `'base:2'`\n */\nexport function encodeAnnotKey(ref: AnnotationRef): string {\n if (ref.kind === 'objectNumber') {\n if (!Number.isInteger(ref.objectNumber) || ref.objectNumber <= 0) {\n throw new RangeError(\n `encodeAnnotKey: objectNumber must be a positive integer, got ${ref.objectNumber}`,\n );\n }\n return `obj:${ref.objectNumber}`;\n }\n if (!Number.isInteger(ref.baseIndex) || ref.baseIndex < 0) {\n throw new RangeError(\n `encodeAnnotKey: baseIndex must be a non-negative integer, got ${ref.baseIndex}`,\n );\n }\n return `base:${ref.baseIndex}`;\n}\n\n/**\n * Inverse of `encodeAnnotKey`, on the page the route names. Returns `null`\n * for malformed input so the server can answer 400 InvalidArg with a useful\n * message instead of throwing. The input is the already-`decodeURIComponent`-ed\n * segment from the route path.\n */\nexport function decodeAnnotKey(page: PageRef, key: string): AnnotationRef | null {\n const number = (prefix: string, min: number): number | null => {\n if (!key.startsWith(prefix)) return null;\n const rest = key.slice(prefix.length);\n const n = Number.parseInt(rest, 10);\n return Number.isInteger(n) && n >= min && String(n) === rest ? n : null;\n };\n const objectNumber = number('obj:', 1);\n if (objectNumber !== null) return { kind: 'objectNumber', page, objectNumber };\n const baseIndex = number('base:', 0);\n if (baseIndex !== null) return { kind: 'baseIndex', page, baseIndex };\n return null;\n}\n","import type { Coordinates } from '../pageSpace/coordinates';\nimport type { DocCapability } from '../auth/scope/types';\nimport type {\n DocMdpPermission,\n DocumentFieldLock,\n DocumentProtection,\n FieldLockSpec,\n ModificationLevel,\n SignatureDTO,\n} from './types';\n\n/**\n * Bumped whenever the derivation below (or a judgement rule) changes meaning.\n * Rides every protection and every analysis, and keys the cloud's immutable\n * analysis URLs. The current policy is calibrated on the 91 Acrobat\n * observations in `packages/engine/main/test/fixtures/signature-compat`:\n * each signature is judged on the net state of the document against the\n * revision it sealed; an object written again with the sealed value is not\n * a modification; an approval signature permits commenting; field\n * properties are judged per level; a lock binds only the signature that\n * declares it; a changed shared resource must be allowed by every use.\n */\nexport const SIGNATURE_POLICY_VERSION = 4;\n\n/**\n * How a validator reads an approval signature. ISO 32000 defines permitted\n * changes only for certification signatures; Acrobat reads an approval\n * signature as \"Form Fill-in, Signing and Commenting are allowed\" (its own\n * permission text under every such signature) and keeps it valid through a\n * Square annotation added, deleted or recoloured afterwards (fixtures\n * `signature-compat/v3/88`, `/90` and `/91`: \"Annotations Created/Deleted/\n * Modified\", signature valid). pyHanko judges stricter (fill only); Acrobat\n * is the validator recipients use, so the baseline is `annotate`.\n */\nexport const APPROVAL_BASELINE: ModificationLevel = 'annotate';\n\nconst LEVEL_RANK: Record<ModificationLevel, number> = { none: 0, lta: 1, fill: 2, annotate: 3 };\n\n/** DocMDP `/P` → the modification level it permits. */\nexport function levelFromPermission(permission: DocMdpPermission): ModificationLevel {\n return permission === 1 ? 'lta' : permission === 2 ? 'fill' : 'annotate';\n}\n\nexport function minLevel(a: ModificationLevel, b: ModificationLevel): ModificationLevel {\n return LEVEL_RANK[a] <= LEVEL_RANK[b] ? a : b;\n}\n\n/** Whether `level` (null = unsigned, everything allowed) permits changes of kind `needed`. */\nexport function levelAllows(level: ModificationLevel | null, needed: ModificationLevel): boolean {\n return level === null || LEVEL_RANK[level] >= LEVEL_RANK[needed];\n}\n\n/** Hierarchical name match: `group` covers `group.total`. */\nexport function lockNameCovers(lockedName: string, fieldName: string): boolean {\n return fieldName === lockedName || fieldName.startsWith(`${lockedName}.`);\n}\n\nexport function lockCovers(spec: FieldLockSpec, fieldName: string): boolean {\n switch (spec.action) {\n case 'all':\n return true;\n case 'include':\n return spec.fields.some((name) => lockNameCovers(name, fieldName));\n case 'exclude':\n return !spec.fields.some((name) => lockNameCovers(name, fieldName));\n }\n}\n\n/**\n * Derive what the signatures already in a document mean for what comes\n * after. Pure and versioned (`SIGNATURE_POLICY_VERSION`); the same function\n * runs in the browser worker, on the native server, and in the conformance\n * suite.\n *\n * enforced = min(certification P, every signed field's /Lock /P), or null\n * when nothing was declared. What the engine refuses.\n * judged = enforced, or the approval baseline when signatures exist\n * without a declaration, or null when nothing is signed. What\n * the revision analysis judges later changes against. A\n * declaration governs the judgement too: a P=3 certifier really\n * did allow annotations.\n * fieldLocks = every signed signature's FieldMDP and the /Lock of every\n * signed field. Unsigned fields' /Lock entries describe a\n * future signature and lock nothing yet.\n */\nexport function deriveProtection(signatures: ReadonlyArray<SignatureDTO>): DocumentProtection {\n let signed = false;\n let enforced: ModificationLevel | null = null;\n let certification: DocumentProtection['certification'] = null;\n const fieldLocks: DocumentFieldLock[] = [];\n\n for (const sig of signatures) {\n if (!sig.signed) continue;\n signed = true;\n if (sig.catalogCertification && sig.docMdp !== null && certification === null) {\n certification = { signatureIndex: sig.index, permission: sig.docMdp };\n enforced = minLevel(enforced ?? 'annotate', levelFromPermission(sig.docMdp));\n }\n if (sig.fieldMdp) {\n fieldLocks.push({ signatureIndex: sig.index, source: 'fieldmdp', spec: sig.fieldMdp });\n }\n if (sig.lock) {\n fieldLocks.push({ signatureIndex: sig.index, source: 'lock', spec: sig.lock });\n if (sig.lock.permission !== undefined) {\n enforced = minLevel(enforced ?? 'annotate', levelFromPermission(sig.lock.permission));\n }\n }\n }\n\n const judged = signed ? (enforced ?? APPROVAL_BASELINE) : null;\n return { enforced, judged, certification, fieldLocks, policyVersion: SIGNATURE_POLICY_VERSION };\n}\n\n/** The lock that freezes `fieldName`, if any. */\nexport function fieldLockFor(\n protection: DocumentProtection,\n fieldName: string,\n): DocumentFieldLock | null {\n for (const lock of protection.fieldLocks) {\n if (lockCovers(lock.spec, fieldName)) return lock;\n }\n return null;\n}\n\n/**\n * Every capability a protection can remove: the most it ever takes away.\n * A check of any other capability never needs the document's protection.\n */\nexport const PROTECTABLE_CAPABILITIES = [\n 'doc.download.flattened',\n 'doc.pages.modify',\n 'doc.pages.assemble',\n 'doc.redact',\n 'doc.attachments.modify',\n 'doc.forms.modify',\n 'doc.forms.script',\n 'doc.annotate.modify',\n 'doc.annotate.import',\n 'doc.forms.fill',\n 'doc.forms.import',\n] as const satisfies readonly DocCapability[];\n\nexport type ProtectableCapability = (typeof PROTECTABLE_CAPABILITIES)[number];\n\nconst PROTECTABLE: ReadonlySet<DocCapability> = new Set(PROTECTABLE_CAPABILITIES);\n\n/** Whether a protection can ever remove `capability`. */\nexport function isProtectableCapability(\n capability: DocCapability,\n): capability is ProtectableCapability {\n return PROTECTABLE.has(capability);\n}\n\n/**\n * The capabilities a protection removes from every caller, admin scope\n * included — document-derived authority, exactly like encryption bits.\n *\n * Only what was declared is refused: a refusal is a promise a signer made,\n * never a guess about a validator. A certification (or a lock with /P)\n * declares what may follow, and everything outside that — page edits,\n * redaction, field authoring, attachments, and below P=3 annotations, below\n * P=2 form fill — is refused. A plain approval signature declares nothing:\n * the same edits stay possible and are then judged, the verdict saying the\n * signature no longer holds, exactly as Acrobat does. The one exception is a\n * rewrite: it does not invalidate signatures, it erases them, so any signed\n * document refuses it. Per-field locks are enforced by the form mutator.\n */\nexport function protectedCapabilities(protection: DocumentProtection | null): Set<DocCapability> {\n const out = new Set<DocCapability>();\n if (!protection || protection.judged === null) return out;\n out.add('doc.download.flattened');\n if (protection.enforced === null) return out; // nothing declared: judged, not refused\n out.add('doc.pages.modify');\n out.add('doc.pages.assemble');\n out.add('doc.redact');\n out.add('doc.attachments.modify');\n out.add('doc.forms.modify');\n out.add('doc.forms.script');\n if (!levelAllows(protection.enforced, 'annotate')) {\n out.add('doc.annotate.modify');\n out.add('doc.annotate.import');\n }\n if (!levelAllows(protection.enforced, 'fill')) {\n out.add('doc.forms.fill');\n out.add('doc.forms.import');\n }\n return out;\n}\n\n/** Why `protection` refuses `capability`: the message of a `ProtectedDocument` refusal. */\nexport function describeProtection(\n capability: DocCapability,\n protection: DocumentProtection,\n): string {\n const cause = protection.certification\n ? `certification signature ${protection.certification.signatureIndex} (permission ${protection.certification.permission})`\n : `an existing signature (declared level '${protection.enforced ?? 'none declared'}')`;\n return `the document is signed: ${cause} forbids '${capability}'`;\n}\n","import { InvalidScope } from './errors';\nimport type { CollabAction, CollabFilter, DocCapability, FieldAction, ParsedScope } from './types';\n\n/**\n * Closed set of recognized capability strings. Membership is the\n * authoritative source of truth — adding a new capability requires\n * extending the `DocCapability` union and adding it here. The parser\n * rejects anything outside this set.\n *\n * Removed legacy names (e.g., `doc.read`, `doc.edit-pages`, `doc.save`)\n * are deliberately absent so any JWT carrying them fails at verify\n * time with a clear error.\n */\nconst KNOWN_CAPABILITIES: ReadonlySet<DocCapability> = new Set([\n 'doc.open',\n 'doc.render',\n 'doc.text.select',\n 'doc.text.copy',\n 'doc.text.search',\n 'doc.content.copy',\n 'doc.download',\n 'doc.download.flattened',\n 'doc.print',\n 'doc.print.high',\n 'doc.pages.modify',\n 'doc.pages.assemble',\n 'doc.forms.read',\n 'doc.forms.fill',\n 'doc.forms.modify',\n 'doc.forms.import',\n 'doc.forms.script',\n 'doc.forms.submit',\n 'doc.annotate.read',\n 'doc.annotate.modify',\n 'doc.annotate.import',\n 'doc.metadata.modify',\n 'doc.attachments.modify',\n 'doc.redact',\n 'doc.sign',\n 'doc.sign.certify',\n]);\n\n/**\n * Parse a single scope string into a structured `ParsedScope`.\n *\n * Recognised shapes:\n * - `\"*\"` → wildcard\n * - `\"pdf.permissions\"` → virtual (expands at resolve time)\n * - `\"a.b.c...\"` (dotted) → capability\n * - `\"entity:action:filter\"` (colons) → collab\n *\n * Throws {@link InvalidScope} for any string that fails to match one of\n * those shapes, or whose capability/entity/action/filter is not in the\n * closed enum.\n */\nexport function parseScope(raw: string): ParsedScope {\n if (raw === '*') return { kind: 'wildcard' };\n if (raw === 'pdf.permissions') return { kind: 'virtual', name: 'pdf.permissions' };\n if (raw.includes(':')) return parseCollab(raw);\n return parseCapability(raw);\n}\n\n/**\n * Validate every entry in a scope array by attempting to parse it.\n * Throws on the first invalid string. Discards the parse output —\n * callers re-parse at resolution time to keep the array as the\n * authoritative payload.\n */\nexport function validateScopeArray(raw: ReadonlyArray<string>): void {\n for (const s of raw) parseScope(s);\n}\n\nfunction parseCollab(raw: string): ParsedScope {\n // Split on the first two colons only. Filter values may contain\n // colons (UUIDs with `urn:uuid:...`, subject ids like `auth0|user:1`).\n const idx1 = raw.indexOf(':');\n const idx2 = raw.indexOf(':', idx1 + 1);\n if (idx1 === -1 || idx2 === -1) {\n throw new InvalidScope(raw, 'collab scope requires entity:action:filter');\n }\n const entity = raw.slice(0, idx1);\n const action = raw.slice(idx1 + 1, idx2);\n const filterStr = raw.slice(idx2 + 1);\n\n if (entity === 'fields') return parseFieldScope(raw, action, filterStr);\n if (entity !== 'annotations') {\n throw new InvalidScope(raw, `unknown collab entity: ${entity}`);\n }\n if (\n action !== 'create' &&\n action !== 'update' &&\n action !== 'delete' &&\n action !== 'set-group' &&\n action !== '*'\n ) {\n throw new InvalidScope(raw, `unknown collab action: ${action}`);\n }\n const filter = parseFilter(filterStr, raw);\n\n // `set-group` is a group-assignment authority, not a per-record collab\n // filter. The only meaningful filter values are `all` (assign to any\n // group) and `group=X` (assign to group X). `:self` and `:createdBy=Y`\n // can't be sensibly applied to \"what group is this annotation in\", so\n // we reject them at parse time rather than silently always-denying.\n if (action === 'set-group' && (filter.kind === 'self' || filter.kind === 'createdBy')) {\n throw new InvalidScope(\n raw,\n `set-group only supports :all or :group=<id> filters (got :${filter.kind})`,\n );\n }\n\n return {\n kind: 'collab',\n entity,\n action: action as CollabAction | '*',\n filter,\n };\n}\n\n/**\n * `fields:<fill|sign|set-group|*>:<all|group=NAME>`. A field's group is who\n * fills it, and a field records no creator, so `self` and `createdBy=` are\n * refused.\n */\nfunction parseFieldScope(raw: string, action: string, filterStr: string): ParsedScope {\n if (action !== 'fill' && action !== 'sign' && action !== 'set-group' && action !== '*') {\n throw new InvalidScope(raw, `unknown fields action: ${action}`);\n }\n const filter = parseFilter(filterStr, raw);\n if (filter.kind !== 'all' && filter.kind !== 'group') {\n throw new InvalidScope(\n raw,\n `fields only support :all or :group=<id> filters (got :${filter.kind})`,\n );\n }\n return { kind: 'collab', entity: 'fields', action: action as FieldAction | '*', filter };\n}\n\nfunction parseFilter(s: string, raw: string): CollabFilter {\n if (s === 'all') return { kind: 'all' };\n if (s === 'self') return { kind: 'self' };\n if (s.startsWith('createdBy=')) {\n const v = s.slice('createdBy='.length);\n if (!v) throw new InvalidScope(raw, 'createdBy= requires a value');\n return { kind: 'createdBy', userId: v };\n }\n if (s.startsWith('group=')) {\n const v = s.slice('group='.length);\n if (!v) throw new InvalidScope(raw, 'group= requires a value');\n return { kind: 'group', groupId: v };\n }\n throw new InvalidScope(raw, `unknown filter: ${s}`);\n}\n\n// Capability shape: lowercase dotted segments, e.g. \"doc.text.copy\".\n// Validates shape first, then membership in the closed set.\nconst CAPABILITY_SHAPE = /^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$/;\n\nfunction parseCapability(raw: string): ParsedScope {\n if (!CAPABILITY_SHAPE.test(raw)) {\n throw new InvalidScope(raw, 'invalid capability name shape');\n }\n if (!KNOWN_CAPABILITIES.has(raw as DocCapability)) {\n throw new InvalidScope(raw, `unknown capability: ${raw}`);\n }\n return { kind: 'capability', name: raw as DocCapability };\n}\n","import { materializePdfPermissions } from './builders';\nimport { parseScope } from './parser';\nimport type {\n CollabAction,\n CollabEntity,\n CollabFilter,\n DocCapability,\n Identity,\n ParsedScope,\n PdfBits,\n} from './types';\nimport { protectedCapabilities } from '../../signature/protection';\nimport type { DocumentProtection } from '../../signature/types';\n\n/**\n * Resolved collab subject — the per-record identity bits that collab\n * filters are tested against. Sourced from the target record's stored\n * `/EMBD_Metadata/UserID` and `/GroupID` at mutation time.\n */\nexport interface CollabTarget {\n userId?: string;\n groupId?: string;\n}\n\n/** The collab target of a record read with nullable owner fields (an annotation). */\nexport function collabTargetOf(owner: {\n userId?: string | null;\n groupId?: string | null;\n}): CollabTarget {\n return {\n ...(owner.userId ? { userId: owner.userId } : {}),\n ...(owner.groupId ? { groupId: owner.groupId } : {}),\n };\n}\n\n/**\n * True iff the given capability is granted by the scope array plus the\n * PDF bits visible via `pdf.permissions` expansion.\n *\n * Wildcard `*` short-circuits to true. Anything not explicitly granted\n * (or expanded from `pdf.permissions`) is denied.\n */\nexport function checkCapability(\n capability: DocCapability,\n rawScope: ReadonlyArray<string>,\n pdfBits: PdfBits,\n protection: DocumentProtection | null = null,\n): boolean {\n // Document-derived authority comes first: what the signatures in the\n // file forbid, no scope grants — the wildcard included.\n if (protectedCapabilities(protection).has(capability)) return false;\n const parsed = rawScope.map(parseScope);\n if (parsed.some((s) => s.kind === 'wildcard')) return true;\n return expandedCapabilities(parsed, pdfBits, protection).has(capability);\n}\n\n/**\n * True iff the scope grants at least one of `capabilities`. Convenience\n * for routes like `/text` (`doc.text.copy` or `doc.text.search`) and\n * `/geometry` (`doc.text.select` or `doc.text.search`).\n */\nexport function checkAnyCapability(\n capabilities: ReadonlyArray<DocCapability>,\n rawScope: ReadonlyArray<string>,\n pdfBits: PdfBits,\n protection: DocumentProtection | null = null,\n): boolean {\n return capabilities.some((c) => checkCapability(c, rawScope, pdfBits, protection));\n}\n\n/**\n * True iff the scope grants the collab action against the target record.\n *\n * Narrowing model. For each action independently:\n * 1. wildcard `*` → allow (global escape hatch)\n * 2. if any collab scope applies to this action → narrow: only those\n * collab filters decide. If none match the target, deny — even if\n * `doc.annotate.modify` is also present. This is what makes\n * `[modify, update:self]` correctly mean \"edit own only\" rather\n * than \"edit anyone via modify-bypass.\"\n * 3. otherwise, if `doc.annotate.modify` is present → allow. This is\n * the broad PDF-bit-derived default for create/update/delete when\n * no per-action collab filter has been written.\n * 4. otherwise → deny.\n *\n * For create: `target` should be built by the caller from JWT identity\n * (`{ userId: caller.userId, groupId: caller.groupId }`). `:self` and\n * `:all` then trivially pass; `:group=X` is the meaningful filter (only\n * matches when the caller's default group is X).\n *\n * For update / delete: `target` is the existing row's owner.\n */\nexport function checkCollab(\n action: CollabAction,\n target: CollabTarget,\n rawScope: ReadonlyArray<string>,\n identity: Identity,\n pdfBits: PdfBits,\n): boolean {\n const parsed = rawScope.map(parseScope);\n if (parsed.some((s) => s.kind === 'wildcard')) return true;\n\n const applicableCollab = parsed.filter(\n (s): s is Extract<ParsedScope, { entity: 'annotations' }> =>\n s.kind === 'collab' &&\n s.entity === 'annotations' &&\n (s.action === action || s.action === '*'),\n );\n\n if (applicableCollab.length > 0) {\n // Narrow: presence of any applicable collab scope shadows\n // `modify`-as-default for this action.\n return applicableCollab.some((s) => filterMatches(s.filter, target, identity));\n }\n\n // No collab scope for this action — fall back to the broad default.\n return expandedCapabilities(parsed, pdfBits).has('doc.annotate.modify');\n}\n\n/**\n * Compute the full set of granted capabilities after expanding\n * `pdf.permissions` and applying implication rules.\n *\n * Implications applied:\n * - `doc.annotate.modify` implies `doc.annotate.read` (you can't\n * sensibly modify what you can't see).\n * - `doc.forms.modify` implies `doc.forms.fill` and `doc.forms.read`.\n * - `doc.forms.fill` implies `doc.forms.read`.\n * - any annotation collab scope implies `doc.annotate.read`, because\n * mutation routes need to see the target row to evaluate the\n * collab filter against its current owner.\n * - any field collab scope implies `doc.forms.read`: filling in or\n * signing a field means seeing the form. Groups limit writes, never\n * reads.\n *\n * Does not short-circuit on wildcard — callers do that themselves\n * before calling this. Returning the expanded set is useful for the\n * `/access` response's `effectiveScope` and for advisory UI surfacing.\n */\nexport function expandedCapabilities(\n parsed: ReadonlyArray<ParsedScope>,\n pdfBits: PdfBits,\n protection: DocumentProtection | null = null,\n): Set<DocCapability> {\n const out = new Set<DocCapability>();\n let hasAnnotationCollab = false;\n let hasFieldCollab = false;\n\n for (const s of parsed) {\n if (s.kind === 'capability') {\n out.add(s.name);\n } else if (s.kind === 'virtual' && s.name === 'pdf.permissions') {\n addPdfPermissions(out, pdfBits);\n } else if (s.kind === 'collab' && s.entity === 'annotations') {\n hasAnnotationCollab = true;\n } else if (s.kind === 'collab' && s.entity === 'fields') {\n hasFieldCollab = true;\n }\n }\n\n // Implications (apply after the explicit additions above)\n if (out.has('doc.annotate.modify')) out.add('doc.annotate.read');\n if (out.has('doc.forms.modify')) {\n out.add('doc.forms.fill');\n out.add('doc.forms.read');\n }\n if (out.has('doc.forms.fill')) out.add('doc.forms.read');\n if (hasAnnotationCollab) out.add('doc.annotate.read');\n if (hasFieldCollab) out.add('doc.forms.read');\n\n // Subtraction last: a signed document's own restrictions win over any\n // grant or implication.\n for (const removed of protectedCapabilities(protection)) out.delete(removed);\n\n return out;\n}\n\n/**\n * Convenience wrapper: takes the raw scope array, parses each entry,\n * returns the expanded capability set. Exposed for the `/access`\n * endpoint and for the SDK helper that surfaces `effectiveScope`.\n */\nexport function expandRawScope(\n rawScope: ReadonlyArray<string>,\n pdfBits: PdfBits,\n protection: DocumentProtection | null = null,\n): Set<DocCapability> {\n return expandedCapabilities(rawScope.map(parseScope), pdfBits, protection);\n}\n\n/**\n * Authority to put a record of `entity` in a specific group: an annotation,\n * or a form field.\n *\n * Set-group is decoupled from the write capabilities (`doc.annotate.modify`,\n * `doc.forms.modify`). The reasoning: those describe row access — what kind\n * of write you can do to which existing rows — and map to PDF permission\n * bits. Set-group is a cloud-only *assignment authority*: which destination\n * group can you put a record into? There is no PDF-bit counterpart, so it\n * doesn't inherit from them.\n *\n * Resolution order:\n * 1. newGroupId === callerDefaultGroupId → true (no real reassignment\n * is happening; the record gets the caller's default group)\n * 2. wildcard `*` → true (global escape hatch)\n * 3. `<entity>:set-group:all` → true\n * 4. `<entity>:set-group:group=<newGroupId>` → true\n * 5. `<entity>:*:all` or `<entity>:*:group=<newGroupId>` → true\n * (action wildcard includes set-group)\n * 6. otherwise → false\n *\n * A user with `set-group:group=legal` can put records in the legal group\n * whatever their own group is — that's the whole point.\n */\nexport function checkSetGroup(\n entity: CollabEntity,\n newGroupId: string,\n callerDefaultGroupId: string | undefined,\n rawScope: ReadonlyArray<string>,\n): boolean {\n // No authority needed when the caller is assigning their default group.\n if (newGroupId === callerDefaultGroupId) return true;\n\n const parsed = rawScope.map(parseScope);\n if (parsed.some((s) => s.kind === 'wildcard')) return true;\n\n for (const s of parsed) {\n if (s.kind !== 'collab') continue;\n if (s.entity !== entity) continue;\n if (s.action !== 'set-group' && s.action !== '*') continue;\n if (s.filter.kind === 'all') return true;\n if (s.filter.kind === 'group' && s.filter.groupId === newGroupId) return true;\n // :self and :createdBy are rejected at parse time for set-group, so\n // they never appear here. The action-wildcard path could carry those\n // filters legitimately for other actions — silently skip those, they\n // can't satisfy a set-group check.\n }\n return false;\n}\n\n/**\n * True iff the scope lets the caller `action` (fill in, or sign) a form\n * field in `groupId` (`null` for a field in no group).\n *\n * Narrowing, per action, as for annotations:\n * 1. wildcard `*` → allow;\n * 2. if any `fields:<action>` scope exists (or `fields:*`) → only those\n * decide: the field must match one of their filters, even when the\n * broad capability is also present. A field in no group then matches\n * only `:all`;\n * 3. otherwise the broad capability decides, for every field:\n * `doc.forms.fill` to fill, `doc.sign` to sign.\n *\n * Nothing here narrows form design (`doc.forms.modify`).\n */\nexport function checkFieldAction(\n action: 'fill' | 'sign',\n groupId: string | null,\n rawScope: ReadonlyArray<string>,\n pdfBits: PdfBits,\n protection: DocumentProtection | null = null,\n): boolean {\n const broad: DocCapability = action === 'fill' ? 'doc.forms.fill' : 'doc.sign';\n if (protectedCapabilities(protection).has(broad)) return false;\n const parsed = rawScope.map(parseScope);\n if (parsed.some((s) => s.kind === 'wildcard')) return true;\n\n const applicable = parsed.filter(\n (s) =>\n s.kind === 'collab' && s.entity === 'fields' && (s.action === action || s.action === '*'),\n ) as Extract<ParsedScope, { entity: 'fields' }>[];\n if (applicable.length > 0) {\n return applicable.some(\n (s) => s.filter.kind === 'all' || (groupId !== null && s.filter.groupId === groupId),\n );\n }\n return expandedCapabilities(parsed, pdfBits, protection).has(broad);\n}\n\n/**\n * The form fields a session may act on, by group: every field (`all`), or\n * only the fields of `groups` (none when the list is empty). A field in no\n * group counts only under `all`.\n */\nexport type FieldGroupRight =\n | { readonly all: true }\n | { readonly all: false; readonly groups: readonly string[] };\n\n/** What a session may do with form fields, per action, as group lists a viewer can show. */\nexport interface FieldRights {\n /** The fields it may fill in. */\n readonly fill: FieldGroupRight;\n /** The fields it may sign. */\n readonly sign: FieldGroupRight;\n /** The groups it may put a field in: its own default group always among them. */\n readonly setGroup: FieldGroupRight;\n}\n\n/**\n * {@link checkFieldAction} and {@link checkSetGroup} as lists: for each\n * action, every field or the groups the scope names, so a designer can\n * offer exactly the groups a field may go in, and a filler see whose fields\n * are theirs. The same rules, read the other way round.\n */\nexport function fieldRightsOf(\n rawScope: ReadonlyArray<string>,\n pdfBits: PdfBits,\n protection: DocumentProtection | null,\n callerDefaultGroupId: string | undefined,\n): FieldRights {\n const parsed = rawScope.map(parseScope);\n const wildcard = parsed.some((s) => s.kind === 'wildcard');\n const fieldScopes = (action: 'fill' | 'sign' | 'set-group') =>\n parsed.filter(\n (s) =>\n s.kind === 'collab' && s.entity === 'fields' && (s.action === action || s.action === '*'),\n ) as Extract<ParsedScope, { entity: 'fields' }>[];\n const fromScopes = (\n scopes: Extract<ParsedScope, { entity: 'fields' }>[],\n extra: readonly string[] = [],\n ): FieldGroupRight => {\n if (scopes.some((s) => s.filter.kind === 'all')) return { all: true };\n const groups = scopes.flatMap((s) => (s.filter.kind === 'group' ? [s.filter.groupId] : []));\n return { all: false, groups: [...new Set([...groups, ...extra])] };\n };\n const NONE: FieldGroupRight = { all: false, groups: [] };\n\n const writing = (action: 'fill' | 'sign'): FieldGroupRight => {\n const broad: DocCapability = action === 'fill' ? 'doc.forms.fill' : 'doc.sign';\n if (protectedCapabilities(protection).has(broad)) return NONE;\n if (wildcard) return { all: true };\n const scopes = fieldScopes(action);\n if (scopes.length > 0) return fromScopes(scopes);\n return expandedCapabilities(parsed, pdfBits, protection).has(broad) ? { all: true } : NONE;\n };\n\n const own = callerDefaultGroupId !== undefined ? [callerDefaultGroupId] : [];\n return {\n fill: writing('fill'),\n sign: writing('sign'),\n setGroup: wildcard ? { all: true } : fromScopes(fieldScopes('set-group'), own),\n };\n}\n\n/**\n * Whether the scope lets the caller `action` some form field: the broad\n * capability, or any `fields:<action>` scope. What a form verb checks\n * before its fields are known; each field is checked in the write.\n */\nexport function checkAnyFieldAction(\n action: 'fill' | 'sign',\n rawScope: ReadonlyArray<string>,\n pdfBits: PdfBits,\n protection: DocumentProtection | null = null,\n): boolean {\n const broad: DocCapability = action === 'fill' ? 'doc.forms.fill' : 'doc.sign';\n if (protectedCapabilities(protection).has(broad)) return false;\n const parsed = rawScope.map(parseScope);\n if (parsed.some((s) => s.kind === 'wildcard')) return true;\n if (\n parsed.some(\n (s) =>\n s.kind === 'collab' && s.entity === 'fields' && (s.action === action || s.action === '*'),\n )\n ) {\n return true;\n }\n return expandedCapabilities(parsed, pdfBits, protection).has(broad);\n}\n\n/**\n * Test a single collab filter against a target record. Every filter but\n * `self` compares one fact on the record with the value the scope names:\n *\n * all → always matches\n * self → matches if identity.userId === target.userId\n * createdBy=<X> → matches if target.userId === X\n * group=<X> → matches if target.groupId === X\n */\nexport function filterMatches(filter: CollabFilter, target: CollabTarget, id: Identity): boolean {\n switch (filter.kind) {\n case 'all':\n return true;\n case 'self':\n return !!id.userId && target.userId === id.userId;\n case 'createdBy':\n return target.userId === filter.userId;\n case 'group':\n return target.groupId === filter.groupId;\n }\n}\n\n/**\n * Translate `pdf.permissions` (virtual scope) into the concrete\n * capabilities it represents under the current PDF bit configuration:\n * {@link materializePdfPermissions}, the one reading of the bits.\n */\nfunction addPdfPermissions(out: Set<DocCapability>, b: PdfBits): void {\n for (const capability of materializePdfPermissions(b)) out.add(capability);\n}\n"],"mappings":"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"}