@embedpdf/core 2.1.2 → 2.3.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 (43) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +165 -7
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/base/base-plugin.d.ts +24 -1
  6. package/dist/lib/index.d.ts +1 -0
  7. package/dist/lib/store/actions.d.ts +15 -3
  8. package/dist/lib/store/initial-state.d.ts +4 -0
  9. package/dist/lib/store/selectors.d.ts +20 -0
  10. package/dist/lib/types/permissions.d.ts +55 -0
  11. package/dist/lib/types/plugin.d.ts +6 -0
  12. package/dist/preact/index.cjs +1 -1
  13. package/dist/preact/index.cjs.map +1 -1
  14. package/dist/preact/index.js +113 -1
  15. package/dist/preact/index.js.map +1 -1
  16. package/dist/react/index.cjs +1 -1
  17. package/dist/react/index.cjs.map +1 -1
  18. package/dist/react/index.js +113 -1
  19. package/dist/react/index.js.map +1 -1
  20. package/dist/shared/components/embed-pdf.d.ts +7 -3
  21. package/dist/shared/hooks/index.d.ts +1 -0
  22. package/dist/shared/hooks/use-document-permissions.d.ts +35 -0
  23. package/dist/shared-preact/components/embed-pdf.d.ts +7 -3
  24. package/dist/shared-preact/hooks/index.d.ts +1 -0
  25. package/dist/shared-preact/hooks/use-document-permissions.d.ts +35 -0
  26. package/dist/shared-react/components/embed-pdf.d.ts +7 -3
  27. package/dist/shared-react/hooks/index.d.ts +1 -0
  28. package/dist/shared-react/hooks/use-document-permissions.d.ts +35 -0
  29. package/dist/svelte/components/EmbedPDF.svelte.d.ts +6 -2
  30. package/dist/svelte/hooks/index.d.ts +1 -0
  31. package/dist/svelte/hooks/use-document-permissions.svelte.d.ts +35 -0
  32. package/dist/svelte/index.cjs +1 -1
  33. package/dist/svelte/index.cjs.map +1 -1
  34. package/dist/svelte/index.js +118 -1
  35. package/dist/svelte/index.js.map +1 -1
  36. package/dist/vue/components/embed-pdf.vue.d.ts +48 -1
  37. package/dist/vue/composables/index.d.ts +1 -0
  38. package/dist/vue/composables/use-document-permissions.d.ts +36 -0
  39. package/dist/vue/index.cjs +1 -1
  40. package/dist/vue/index.cjs.map +1 -1
  41. package/dist/vue/index.js +116 -3
  42. package/dist/vue/index.js.map +1 -1
  43. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Rotation, NoopLogger } from "@embedpdf/models";
1
+ import { Rotation, PdfPermissionFlag, NoopLogger, PermissionDeniedError } from "@embedpdf/models";
2
2
  class DependencyResolver {
3
3
  constructor() {
4
4
  this.dependencyGraph = /* @__PURE__ */ new Map();
@@ -170,6 +170,7 @@ const CLOSE_DOCUMENT = "CLOSE_DOCUMENT";
170
170
  const SET_ACTIVE_DOCUMENT = "SET_ACTIVE_DOCUMENT";
171
171
  const REORDER_DOCUMENTS = "REORDER_DOCUMENTS";
172
172
  const MOVE_DOCUMENT = "MOVE_DOCUMENT";
173
+ const UPDATE_DOCUMENT_SECURITY = "UPDATE_DOCUMENT_SECURITY";
173
174
  const REFRESH_DOCUMENT = "REFRESH_DOCUMENT";
174
175
  const REFRESH_PAGES = "REFRESH_PAGES";
175
176
  const SET_PAGES = "SET_PAGES";
@@ -193,11 +194,12 @@ const CORE_ACTION_TYPES = [
193
194
  SET_DEFAULT_SCALE,
194
195
  SET_DEFAULT_ROTATION,
195
196
  REORDER_DOCUMENTS,
196
- MOVE_DOCUMENT
197
+ MOVE_DOCUMENT,
198
+ UPDATE_DOCUMENT_SECURITY
197
199
  ];
198
- const startLoadingDocument = (documentId, name, scale, rotation, passwordProvided, autoActivate) => ({
200
+ const startLoadingDocument = (documentId, name, scale, rotation, passwordProvided, autoActivate, permissions) => ({
199
201
  type: START_LOADING_DOCUMENT,
200
- payload: { documentId, name, scale, rotation, passwordProvided, autoActivate }
202
+ payload: { documentId, name, scale, rotation, passwordProvided, autoActivate, permissions }
201
203
  });
202
204
  const updateDocumentLoadingProgress = (documentId, progress) => ({
203
205
  type: UPDATE_DOCUMENT_LOADING_PROGRESS,
@@ -259,6 +261,10 @@ const moveDocument = (documentId, toIndex) => ({
259
261
  type: MOVE_DOCUMENT,
260
262
  payload: { documentId, toIndex }
261
263
  });
264
+ const updateDocumentSecurity = (documentId, permissions, isOwnerUnlocked) => ({
265
+ type: UPDATE_DOCUMENT_SECURITY,
266
+ payload: { documentId, permissions, isOwnerUnlocked }
267
+ });
262
268
  class Store {
263
269
  /**
264
270
  * Initializes the store with the provided core state.
@@ -519,8 +525,60 @@ const initialCoreState = (config) => ({
519
525
  documentOrder: [],
520
526
  activeDocumentId: null,
521
527
  defaultScale: (config == null ? void 0 : config.defaultScale) ?? 1,
522
- defaultRotation: (config == null ? void 0 : config.defaultRotation) ?? Rotation.Degree0
528
+ defaultRotation: (config == null ? void 0 : config.defaultRotation) ?? Rotation.Degree0,
529
+ globalPermissions: config == null ? void 0 : config.permissions
523
530
  });
531
+ const PERMISSION_NAME_TO_FLAG = {
532
+ print: PdfPermissionFlag.Print,
533
+ modifyContents: PdfPermissionFlag.ModifyContents,
534
+ copyContents: PdfPermissionFlag.CopyContents,
535
+ modifyAnnotations: PdfPermissionFlag.ModifyAnnotations,
536
+ fillForms: PdfPermissionFlag.FillForms,
537
+ extractForAccessibility: PdfPermissionFlag.ExtractForAccessibility,
538
+ assembleDocument: PdfPermissionFlag.AssembleDocument,
539
+ printHighQuality: PdfPermissionFlag.PrintHighQuality
540
+ };
541
+ const ALL_PERMISSION_FLAGS = [
542
+ PdfPermissionFlag.Print,
543
+ PdfPermissionFlag.ModifyContents,
544
+ PdfPermissionFlag.CopyContents,
545
+ PdfPermissionFlag.ModifyAnnotations,
546
+ PdfPermissionFlag.FillForms,
547
+ PdfPermissionFlag.ExtractForAccessibility,
548
+ PdfPermissionFlag.AssembleDocument,
549
+ PdfPermissionFlag.PrintHighQuality
550
+ ];
551
+ const ALL_PERMISSION_NAMES = [
552
+ "print",
553
+ "modifyContents",
554
+ "copyContents",
555
+ "modifyAnnotations",
556
+ "fillForms",
557
+ "extractForAccessibility",
558
+ "assembleDocument",
559
+ "printHighQuality"
560
+ ];
561
+ const PERMISSION_FLAG_TO_NAME = {
562
+ [PdfPermissionFlag.Print]: "print",
563
+ [PdfPermissionFlag.ModifyContents]: "modifyContents",
564
+ [PdfPermissionFlag.CopyContents]: "copyContents",
565
+ [PdfPermissionFlag.ModifyAnnotations]: "modifyAnnotations",
566
+ [PdfPermissionFlag.FillForms]: "fillForms",
567
+ [PdfPermissionFlag.ExtractForAccessibility]: "extractForAccessibility",
568
+ [PdfPermissionFlag.AssembleDocument]: "assembleDocument",
569
+ [PdfPermissionFlag.PrintHighQuality]: "printHighQuality"
570
+ };
571
+ function getPermissionOverride(overrides, flag) {
572
+ if (!overrides) return void 0;
573
+ if (flag in overrides) {
574
+ return overrides[flag];
575
+ }
576
+ const name = PERMISSION_FLAG_TO_NAME[flag];
577
+ if (name && name in overrides) {
578
+ return overrides[name];
579
+ }
580
+ return void 0;
581
+ }
524
582
  const getActiveDocumentState = (state) => {
525
583
  if (!state.activeDocumentId) return null;
526
584
  return state.documents[state.activeDocumentId] ?? null;
@@ -537,6 +595,29 @@ const isDocumentLoaded = (state, documentId) => {
537
595
  const getDocumentCount = (state) => {
538
596
  return Object.keys(state.documents).length;
539
597
  };
598
+ function getEffectivePermission(state, documentId, flag) {
599
+ var _a;
600
+ const docState = state.documents[documentId];
601
+ const docConfig = docState == null ? void 0 : docState.permissions;
602
+ const globalConfig = state.globalPermissions;
603
+ const pdfPermissions = ((_a = docState == null ? void 0 : docState.document) == null ? void 0 : _a.permissions) ?? PdfPermissionFlag.AllowAll;
604
+ const docOverride = getPermissionOverride(docConfig == null ? void 0 : docConfig.overrides, flag);
605
+ if (docOverride !== void 0) {
606
+ return docOverride;
607
+ }
608
+ const globalOverride = getPermissionOverride(globalConfig == null ? void 0 : globalConfig.overrides, flag);
609
+ if (globalOverride !== void 0) {
610
+ return globalOverride;
611
+ }
612
+ const enforce = (docConfig == null ? void 0 : docConfig.enforceDocumentPermissions) ?? (globalConfig == null ? void 0 : globalConfig.enforceDocumentPermissions) ?? true;
613
+ if (!enforce) return true;
614
+ return (pdfPermissions & flag) !== 0;
615
+ }
616
+ function getEffectivePermissions(state, documentId) {
617
+ return ALL_PERMISSION_FLAGS.reduce((acc, flag) => {
618
+ return getEffectivePermission(state, documentId, flag) ? acc | flag : acc;
619
+ }, 0);
620
+ }
540
621
  function calculateNextActiveDocument(state, closingDocumentId, explicitNext) {
541
622
  const currentActiveId = state.activeDocumentId;
542
623
  if (currentActiveId !== closingDocumentId) {
@@ -576,7 +657,8 @@ const coreReducer = (state, action) => {
576
657
  scale,
577
658
  rotation,
578
659
  passwordProvided,
579
- autoActivate = true
660
+ autoActivate = true,
661
+ permissions
580
662
  } = action.payload;
581
663
  const newDocState = {
582
664
  id: documentId,
@@ -589,6 +671,7 @@ const coreReducer = (state, action) => {
589
671
  rotation: rotation ?? state.defaultRotation,
590
672
  passwordProvided: passwordProvided ?? false,
591
673
  pageRefreshVersions: {},
674
+ permissions,
592
675
  loadStartedAt: Date.now()
593
676
  };
594
677
  return {
@@ -761,6 +844,25 @@ const coreReducer = (state, action) => {
761
844
  }
762
845
  };
763
846
  }
847
+ case UPDATE_DOCUMENT_SECURITY: {
848
+ const { documentId, permissions, isOwnerUnlocked } = action.payload;
849
+ const docState = state.documents[documentId];
850
+ if (!(docState == null ? void 0 : docState.document)) return state;
851
+ return {
852
+ ...state,
853
+ documents: {
854
+ ...state.documents,
855
+ [documentId]: {
856
+ ...docState,
857
+ document: {
858
+ ...docState.document,
859
+ permissions,
860
+ isOwnerUnlocked
861
+ }
862
+ }
863
+ }
864
+ };
865
+ }
764
866
  default:
765
867
  return state;
766
868
  }
@@ -1474,6 +1576,53 @@ class BasePlugin {
1474
1576
  }
1475
1577
  return doc;
1476
1578
  }
1579
+ // ─────────────────────────────────────────────────────────
1580
+ // Permission Helpers
1581
+ // ─────────────────────────────────────────────────────────
1582
+ /**
1583
+ * Get the effective permission flags for a document.
1584
+ * Applies layered resolution: per-document override → global override → PDF permission.
1585
+ * Returns AllowAll if document not found.
1586
+ * @param documentId Document ID (optional, defaults to active document)
1587
+ */
1588
+ getDocumentPermissions(documentId) {
1589
+ const docId = documentId ?? this.coreState.core.activeDocumentId;
1590
+ if (!docId) return PdfPermissionFlag.AllowAll;
1591
+ return getEffectivePermissions(this.coreState.core, docId);
1592
+ }
1593
+ /**
1594
+ * Check if a document has the required permissions (returns boolean).
1595
+ * Applies layered resolution: per-document override → global override → PDF permission.
1596
+ * Useful for conditional UI logic.
1597
+ * @param documentId Document ID (optional, defaults to active document)
1598
+ * @param flags Permission flags to check
1599
+ */
1600
+ checkPermission(documentId, ...flags) {
1601
+ const docId = documentId ?? this.coreState.core.activeDocumentId;
1602
+ if (!docId) return true;
1603
+ return flags.every((flag) => getEffectivePermission(this.coreState.core, docId, flag));
1604
+ }
1605
+ /**
1606
+ * Assert that a document has the required permissions.
1607
+ * Applies layered resolution: per-document override → global override → PDF permission.
1608
+ * Throws PermissionDeniedError if any flag is missing.
1609
+ * @param documentId Document ID (optional, defaults to active document)
1610
+ * @param flags Permission flags to require
1611
+ */
1612
+ requirePermission(documentId, ...flags) {
1613
+ const docId = documentId ?? this.coreState.core.activeDocumentId;
1614
+ if (!docId) return;
1615
+ const missingFlags = [];
1616
+ for (const flag of flags) {
1617
+ if (!getEffectivePermission(this.coreState.core, docId, flag)) {
1618
+ missingFlags.push(flag);
1619
+ }
1620
+ }
1621
+ if (missingFlags.length > 0) {
1622
+ const effectivePermissions = getEffectivePermissions(this.coreState.core, docId);
1623
+ throw new PermissionDeniedError(missingFlags, effectivePermissions);
1624
+ }
1625
+ }
1477
1626
  }
1478
1627
  class EventControl {
1479
1628
  constructor(handler, options) {
@@ -1902,6 +2051,8 @@ function createPluginPackage(basePackage) {
1902
2051
  return new PluginPackageBuilder(basePackage);
1903
2052
  }
1904
2053
  export {
2054
+ ALL_PERMISSION_FLAGS,
2055
+ ALL_PERMISSION_NAMES,
1905
2056
  BasePlugin,
1906
2057
  CLOSE_DOCUMENT,
1907
2058
  CORE_ACTION_TYPES,
@@ -1912,6 +2063,8 @@ export {
1912
2063
  EventControl,
1913
2064
  KeyedEventControl,
1914
2065
  MOVE_DOCUMENT,
2066
+ PERMISSION_FLAG_TO_NAME,
2067
+ PERMISSION_NAME_TO_FLAG,
1915
2068
  PluginConfigurationError,
1916
2069
  PluginInitializationError,
1917
2070
  PluginNotFoundError,
@@ -1932,6 +2085,7 @@ export {
1932
2085
  SET_SCALE,
1933
2086
  START_LOADING_DOCUMENT,
1934
2087
  UPDATE_DOCUMENT_LOADING_PROGRESS,
2088
+ UPDATE_DOCUMENT_SECURITY,
1935
2089
  arePropsEqual,
1936
2090
  clamp,
1937
2091
  closeDocument,
@@ -1945,6 +2099,9 @@ export {
1945
2099
  getDocumentCount,
1946
2100
  getDocumentIds,
1947
2101
  getDocumentState,
2102
+ getEffectivePermission,
2103
+ getEffectivePermissions,
2104
+ getPermissionOverride,
1948
2105
  hasAutoMountElements,
1949
2106
  initialCoreState,
1950
2107
  isDocumentLoaded,
@@ -1963,6 +2120,7 @@ export {
1963
2120
  setRotation,
1964
2121
  setScale,
1965
2122
  startLoadingDocument,
1966
- updateDocumentLoadingProgress
2123
+ updateDocumentLoadingProgress,
2124
+ updateDocumentSecurity
1967
2125
  };
1968
2126
  //# sourceMappingURL=index.js.map