@jmruthers/pace-core 0.5.110 → 0.5.112

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 (236) hide show
  1. package/dist/{AuthService-DrHrvXNZ.d.ts → AuthService-CVgsgtaZ.d.ts} +8 -0
  2. package/dist/{DataTable-D3BK2FCN.js → DataTable-3D3BUZDV.js} +8 -8
  3. package/dist/{UnifiedAuthProvider-A7I23UCN.js → UnifiedAuthProvider-KZZUO27W.js} +3 -3
  4. package/dist/{api-PIE4JRFS.js → api-QPMBZZUZ.js} +5 -3
  5. package/dist/{audit-65VNHEV2.js → audit-H4YJJF7R.js} +2 -2
  6. package/dist/{chunk-Q7APDV6H.js → chunk-3OGQLOJM.js} +23 -7
  7. package/dist/chunk-3OGQLOJM.js.map +1 -0
  8. package/dist/{chunk-EYSXQ756.js → chunk-7H75SHXZ.js} +2 -2
  9. package/dist/{chunk-D6MEKC27.js → chunk-BUN7NMV7.js} +2 -2
  10. package/dist/{chunk-AWK2FAUN.js → chunk-C5RN4TE5.js} +7 -7
  11. package/dist/{chunk-3J5N2T2N.js → chunk-EKVVTPIF.js} +183 -127
  12. package/dist/chunk-EKVVTPIF.js.map +1 -0
  13. package/dist/{chunk-2W4WKJVF.js → chunk-F6QB26OS.js} +290 -255
  14. package/dist/chunk-F6QB26OS.js.map +1 -0
  15. package/dist/{chunk-HADXAZT3.js → chunk-I7JC7PTJ.js} +54 -92
  16. package/dist/chunk-I7JC7PTJ.js.map +1 -0
  17. package/dist/{chunk-EZ64QG2I.js → chunk-L36JW4KV.js} +2 -2
  18. package/dist/{chunk-7GBEBJLR.js → chunk-MNSGWRPB.js} +45 -37
  19. package/dist/chunk-MNSGWRPB.js.map +1 -0
  20. package/dist/{chunk-YFMENCR4.js → chunk-NEONKMTU.js} +3 -3
  21. package/dist/{chunk-AUXS7XSO.js → chunk-OO3V7W4H.js} +35 -11
  22. package/dist/chunk-OO3V7W4H.js.map +1 -0
  23. package/dist/{chunk-XRSP3H52.js → chunk-TAJRS6YB.js} +57 -23
  24. package/dist/chunk-TAJRS6YB.js.map +1 -0
  25. package/dist/{chunk-HGZSO43Y.js → chunk-WMPZY26G.js} +8 -4
  26. package/dist/{chunk-HGZSO43Y.js.map → chunk-WMPZY26G.js.map} +1 -1
  27. package/dist/components.js +10 -10
  28. package/dist/hooks.d.ts +11 -1
  29. package/dist/hooks.js +9 -7
  30. package/dist/hooks.js.map +1 -1
  31. package/dist/index.d.ts +2 -2
  32. package/dist/index.js +13 -13
  33. package/dist/providers.d.ts +2 -2
  34. package/dist/providers.js +2 -2
  35. package/dist/rbac/index.d.ts +13 -8
  36. package/dist/rbac/index.js +9 -9
  37. package/dist/utils.js +1 -1
  38. package/docs/api/classes/ColumnFactory.md +1 -1
  39. package/docs/api/classes/ErrorBoundary.md +1 -1
  40. package/docs/api/classes/InvalidScopeError.md +4 -4
  41. package/docs/api/classes/MissingUserContextError.md +4 -4
  42. package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
  43. package/docs/api/classes/PermissionDeniedError.md +4 -4
  44. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  45. package/docs/api/classes/RBACAuditManager.md +8 -8
  46. package/docs/api/classes/RBACCache.md +8 -8
  47. package/docs/api/classes/RBACEngine.md +4 -4
  48. package/docs/api/classes/RBACError.md +4 -4
  49. package/docs/api/classes/RBACNotInitializedError.md +4 -4
  50. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  51. package/docs/api/classes/StorageUtils.md +1 -1
  52. package/docs/api/enums/FileCategory.md +1 -1
  53. package/docs/api/interfaces/AggregateConfig.md +1 -1
  54. package/docs/api/interfaces/ButtonProps.md +1 -1
  55. package/docs/api/interfaces/CardProps.md +1 -1
  56. package/docs/api/interfaces/ColorPalette.md +1 -1
  57. package/docs/api/interfaces/ColorShade.md +1 -1
  58. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  59. package/docs/api/interfaces/DataRecord.md +1 -1
  60. package/docs/api/interfaces/DataTableAction.md +1 -1
  61. package/docs/api/interfaces/DataTableColumn.md +1 -1
  62. package/docs/api/interfaces/DataTableProps.md +1 -1
  63. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  64. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  65. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  66. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  67. package/docs/api/interfaces/FileMetadata.md +1 -1
  68. package/docs/api/interfaces/FileReference.md +1 -1
  69. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  70. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  71. package/docs/api/interfaces/FileUploadProps.md +1 -1
  72. package/docs/api/interfaces/FooterProps.md +1 -1
  73. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  74. package/docs/api/interfaces/InputProps.md +1 -1
  75. package/docs/api/interfaces/LabelProps.md +1 -1
  76. package/docs/api/interfaces/LoginFormProps.md +1 -1
  77. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  78. package/docs/api/interfaces/NavigationContextType.md +1 -1
  79. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  80. package/docs/api/interfaces/NavigationItem.md +1 -1
  81. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  82. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  83. package/docs/api/interfaces/Organisation.md +1 -1
  84. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  85. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  86. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  87. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  88. package/docs/api/interfaces/PaceAppLayoutProps.md +27 -27
  89. package/docs/api/interfaces/PaceLoginPageProps.md +4 -4
  90. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  91. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  92. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  93. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  94. package/docs/api/interfaces/PaletteData.md +1 -1
  95. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  96. package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
  97. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  98. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  99. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  100. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  101. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  102. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  103. package/docs/api/interfaces/RBACConfig.md +1 -1
  104. package/docs/api/interfaces/RBACLogger.md +1 -1
  105. package/docs/api/interfaces/RoleBasedRouterContextType.md +8 -8
  106. package/docs/api/interfaces/RoleBasedRouterProps.md +10 -10
  107. package/docs/api/interfaces/RouteAccessRecord.md +10 -10
  108. package/docs/api/interfaces/RouteConfig.md +19 -6
  109. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  110. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  111. package/docs/api/interfaces/StorageConfig.md +1 -1
  112. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  113. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  114. package/docs/api/interfaces/StorageListOptions.md +1 -1
  115. package/docs/api/interfaces/StorageListResult.md +1 -1
  116. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  117. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  118. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  119. package/docs/api/interfaces/StyleImport.md +1 -1
  120. package/docs/api/interfaces/SwitchProps.md +1 -1
  121. package/docs/api/interfaces/ToastActionElement.md +1 -1
  122. package/docs/api/interfaces/ToastProps.md +1 -1
  123. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  124. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  125. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  126. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  127. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  128. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  129. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +1 -1
  130. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  131. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  132. package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
  133. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  134. package/docs/api/interfaces/UserEventAccess.md +1 -1
  135. package/docs/api/interfaces/UserMenuProps.md +1 -1
  136. package/docs/api/interfaces/UserProfile.md +1 -1
  137. package/docs/api/modules.md +36 -36
  138. package/docs/api-reference/hooks.md +8 -4
  139. package/docs/architecture/rpc-function-standards.md +3 -1
  140. package/docs/best-practices/common-patterns.md +3 -3
  141. package/docs/best-practices/deployment.md +10 -4
  142. package/docs/best-practices/performance.md +11 -3
  143. package/docs/core-concepts/organisations.md +8 -8
  144. package/docs/core-concepts/permissions.md +133 -72
  145. package/docs/migration/rbac-migration.md +65 -66
  146. package/docs/rbac/advanced-patterns.md +15 -22
  147. package/docs/rbac/examples.md +12 -12
  148. package/docs/rbac/getting-started.md +3 -3
  149. package/docs/rbac/troubleshooting.md +2 -1
  150. package/package.json +1 -1
  151. package/src/components/DataTable/DataTable.test.tsx +405 -154
  152. package/src/components/DataTable/components/DataTableCore.tsx +6 -1
  153. package/src/components/DataTable/components/__tests__/ActionButtons.test.tsx +913 -0
  154. package/src/components/DataTable/components/__tests__/ColumnFilter.test.tsx +609 -0
  155. package/src/components/DataTable/components/__tests__/EmptyState.test.tsx +434 -0
  156. package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +120 -0
  157. package/src/components/DataTable/components/__tests__/PaginationControls.test.tsx +519 -0
  158. package/src/components/DataTable/examples/__tests__/HierarchicalActionsExample.test.tsx +316 -0
  159. package/src/components/DataTable/examples/__tests__/InitialPageSizeExample.test.tsx +211 -0
  160. package/src/components/EventSelector/EventSelector.tsx +32 -2
  161. package/src/components/FileUpload/FileUpload.tsx +2 -8
  162. package/src/components/NavigationMenu/NavigationMenu.test.tsx +56 -8
  163. package/src/components/NavigationMenu/NavigationMenu.tsx +75 -12
  164. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +193 -63
  165. package/src/components/PaceAppLayout/PaceAppLayout.tsx +102 -135
  166. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.accessibility.test.tsx +41 -2
  167. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +61 -6
  168. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.performance.test.tsx +71 -21
  169. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +113 -41
  170. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.unit.test.tsx +155 -45
  171. package/src/components/PaceLoginPage/PaceLoginPage.tsx +30 -1
  172. package/src/hooks/__tests__/usePermissionCache.simple.test.ts +63 -5
  173. package/src/hooks/__tests__/usePermissionCache.unit.test.ts +156 -72
  174. package/src/hooks/__tests__/useRBAC.unit.test.ts +4 -38
  175. package/src/hooks/index.ts +1 -1
  176. package/src/hooks/useFileDisplay.ts +51 -0
  177. package/src/hooks/usePermissionCache.test.ts +112 -68
  178. package/src/hooks/usePermissionCache.ts +55 -15
  179. package/src/rbac/README.md +81 -39
  180. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +3 -3
  181. package/src/rbac/__tests__/engine.comprehensive.test.ts +15 -6
  182. package/src/rbac/__tests__/rbac-core.test.tsx +1 -1
  183. package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +57 -4
  184. package/src/rbac/__tests__/rbac-engine-simplified.test.ts +3 -2
  185. package/src/rbac/adapters.tsx +4 -4
  186. package/src/rbac/api.test.ts +37 -13
  187. package/src/rbac/api.ts +25 -8
  188. package/src/rbac/audit-enhanced.ts +14 -2
  189. package/src/rbac/audit.test.ts +18 -8
  190. package/src/rbac/audit.ts +25 -6
  191. package/src/rbac/cache.test.ts +12 -0
  192. package/src/rbac/cache.ts +29 -9
  193. package/src/rbac/components/EnhancedNavigationMenu.test.tsx +1 -1
  194. package/src/rbac/components/NavigationGuard.tsx +14 -14
  195. package/src/rbac/components/NavigationProvider.test.tsx +1 -1
  196. package/src/rbac/components/PagePermissionGuard.tsx +4 -3
  197. package/src/rbac/components/PagePermissionProvider.test.tsx +1 -1
  198. package/src/rbac/components/PermissionEnforcer.tsx +19 -15
  199. package/src/rbac/components/RoleBasedRouter.tsx +16 -9
  200. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +123 -107
  201. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +1 -1
  202. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +121 -103
  203. package/src/rbac/docs/event-based-apps.md +6 -6
  204. package/src/rbac/engine.ts +12 -2
  205. package/src/rbac/hooks/useCan.test.ts +29 -2
  206. package/src/rbac/hooks/usePermissions.test.ts +25 -25
  207. package/src/rbac/hooks/usePermissions.ts +65 -25
  208. package/src/rbac/hooks/useRBAC.simple.test.ts +1 -8
  209. package/src/rbac/hooks/useRBAC.test.ts +3 -40
  210. package/src/rbac/hooks/useRBAC.ts +0 -55
  211. package/src/rbac/hooks/useResolvedScope.ts +23 -31
  212. package/src/rbac/permissions.test.ts +11 -7
  213. package/src/rbac/security.test.ts +2 -2
  214. package/src/rbac/security.ts +22 -7
  215. package/src/rbac/types.test.ts +2 -2
  216. package/src/rbac/types.ts +1 -2
  217. package/src/services/EventService.ts +42 -13
  218. package/src/services/__tests__/EventService.test.ts +25 -4
  219. package/src/services/interfaces/IEventService.ts +1 -0
  220. package/src/utils/file-reference.ts +9 -0
  221. package/dist/chunk-2W4WKJVF.js.map +0 -1
  222. package/dist/chunk-3J5N2T2N.js.map +0 -1
  223. package/dist/chunk-7GBEBJLR.js.map +0 -1
  224. package/dist/chunk-AUXS7XSO.js.map +0 -1
  225. package/dist/chunk-HADXAZT3.js.map +0 -1
  226. package/dist/chunk-Q7APDV6H.js.map +0 -1
  227. package/dist/chunk-XRSP3H52.js.map +0 -1
  228. /package/dist/{DataTable-D3BK2FCN.js.map → DataTable-3D3BUZDV.js.map} +0 -0
  229. /package/dist/{UnifiedAuthProvider-A7I23UCN.js.map → UnifiedAuthProvider-KZZUO27W.js.map} +0 -0
  230. /package/dist/{api-PIE4JRFS.js.map → api-QPMBZZUZ.js.map} +0 -0
  231. /package/dist/{audit-65VNHEV2.js.map → audit-H4YJJF7R.js.map} +0 -0
  232. /package/dist/{chunk-EYSXQ756.js.map → chunk-7H75SHXZ.js.map} +0 -0
  233. /package/dist/{chunk-D6MEKC27.js.map → chunk-BUN7NMV7.js.map} +0 -0
  234. /package/dist/{chunk-AWK2FAUN.js.map → chunk-C5RN4TE5.js.map} +0 -0
  235. /package/dist/{chunk-EZ64QG2I.js.map → chunk-L36JW4KV.js.map} +0 -0
  236. /package/dist/{chunk-YFMENCR4.js.map → chunk-NEONKMTU.js.map} +0 -0
@@ -76,6 +76,7 @@ interface IEventService {
76
76
  setSelectedEvent(event: Event | null): void;
77
77
  refreshEvents(): Promise<void>;
78
78
  loadPersistedEvent(events: Event[]): Promise<boolean>;
79
+ restorePersistedEvent(): Promise<boolean>;
79
80
  persistEventSelection(eventId: string): void;
80
81
  autoSelectNextEvent(events: Event[]): void;
81
82
  initialize(): Promise<void>;
@@ -116,6 +117,13 @@ declare class EventService extends BaseService implements IEventService {
116
117
  setSelectedEvent(event: Event | null): void;
117
118
  refreshEvents(): Promise<void>;
118
119
  loadPersistedEvent(events: Event[]): Promise<boolean>;
120
+ /**
121
+ * Restore persisted event after login screen has rendered
122
+ * This should be called explicitly from login page component
123
+ *
124
+ * @returns Promise<boolean> - true if event was successfully restored, false otherwise
125
+ */
126
+ restorePersistedEvent(): Promise<boolean>;
119
127
  persistEventSelection(eventId: string): void;
120
128
  clearEventSelection(): void;
121
129
  autoSelectNextEvent(events: Event[]): void;
@@ -54,10 +54,10 @@ import {
54
54
  sortHierarchicalDataWithSorting,
55
55
  validateHierarchicalData,
56
56
  validatePaginationConfig
57
- } from "./chunk-HGZSO43Y.js";
58
- import "./chunk-HADXAZT3.js";
59
- import "./chunk-XRSP3H52.js";
60
- import "./chunk-Q7APDV6H.js";
57
+ } from "./chunk-WMPZY26G.js";
58
+ import "./chunk-I7JC7PTJ.js";
59
+ import "./chunk-TAJRS6YB.js";
60
+ import "./chunk-3OGQLOJM.js";
61
61
  import {
62
62
  CircuitBreaker,
63
63
  DEFAULT_FALLBACK_CONFIG,
@@ -76,9 +76,9 @@ import {
76
76
  throttle,
77
77
  useDataTablePerformance
78
78
  } from "./chunk-4OX5PXHX.js";
79
- import "./chunk-EZ64QG2I.js";
80
- import "./chunk-EYSXQ756.js";
81
- import "./chunk-AUXS7XSO.js";
79
+ import "./chunk-L36JW4KV.js";
80
+ import "./chunk-7H75SHXZ.js";
81
+ import "./chunk-OO3V7W4H.js";
82
82
  import "./chunk-PYUXFQJ3.js";
83
83
  import "./chunk-JCQZ6LA7.js";
84
84
  import "./chunk-BDZUMRBD.js";
@@ -157,4 +157,4 @@ export {
157
157
  validateHierarchicalData,
158
158
  validatePaginationConfig
159
159
  };
160
- //# sourceMappingURL=DataTable-D3BK2FCN.js.map
160
+ //# sourceMappingURL=DataTable-3D3BUZDV.js.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  init_UnifiedAuthProvider
3
- } from "./chunk-EYSXQ756.js";
3
+ } from "./chunk-7H75SHXZ.js";
4
4
  import {
5
5
  UnifiedAuthProvider,
6
6
  useUnifiedAuth
7
- } from "./chunk-AUXS7XSO.js";
7
+ } from "./chunk-OO3V7W4H.js";
8
8
  import "./chunk-BDZUMRBD.js";
9
9
  import "./chunk-SMJZMKYN.js";
10
10
  import "./chunk-PLDDJCW6.js";
@@ -13,4 +13,4 @@ export {
13
13
  UnifiedAuthProvider,
14
14
  useUnifiedAuth
15
15
  };
16
- //# sourceMappingURL=UnifiedAuthProvider-A7I23UCN.js.map
16
+ //# sourceMappingURL=UnifiedAuthProvider-KZZUO27W.js.map
@@ -1,4 +1,5 @@
1
1
  import {
2
+ OrganisationContextRequiredError,
2
3
  clearCache,
3
4
  getAccessLevel,
4
5
  getAppConfig,
@@ -19,10 +20,11 @@ import {
19
20
  isSuperAdmin,
20
21
  resolveAppContext,
21
22
  setupRBAC
22
- } from "./chunk-XRSP3H52.js";
23
- import "./chunk-Q7APDV6H.js";
23
+ } from "./chunk-TAJRS6YB.js";
24
+ import "./chunk-3OGQLOJM.js";
24
25
  import "./chunk-PLDDJCW6.js";
25
26
  export {
27
+ OrganisationContextRequiredError,
26
28
  clearCache,
27
29
  getAccessLevel,
28
30
  getAppConfig,
@@ -44,4 +46,4 @@ export {
44
46
  resolveAppContext,
45
47
  setupRBAC
46
48
  };
47
- //# sourceMappingURL=api-PIE4JRFS.js.map
49
+ //# sourceMappingURL=api-QPMBZZUZ.js.map
@@ -4,7 +4,7 @@ import {
4
4
  emitAuditEvent,
5
5
  getGlobalAuditManager,
6
6
  setGlobalAuditManager
7
- } from "./chunk-Q7APDV6H.js";
7
+ } from "./chunk-3OGQLOJM.js";
8
8
  import "./chunk-PLDDJCW6.js";
9
9
  export {
10
10
  RBACAuditManager,
@@ -13,4 +13,4 @@ export {
13
13
  getGlobalAuditManager,
14
14
  setGlobalAuditManager
15
15
  };
16
- //# sourceMappingURL=audit-65VNHEV2.js.map
16
+ //# sourceMappingURL=audit-H4YJJF7R.js.map
@@ -45,15 +45,29 @@ var RBACAuditManager = class {
45
45
  });
46
46
  }
47
47
  try {
48
+ if (!event.organisationId) {
49
+ console.warn("[RBAC Audit] Audit event without organisation context - this should be investigated:", {
50
+ userId: event.userId,
51
+ eventType: event.type,
52
+ note: "Organisation context is required for RBAC operations. This may indicate a security issue or missing context derivation."
53
+ });
54
+ }
55
+ const rawPageId = "pageId" in event ? event.pageId : void 0;
56
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
57
+ const isValidPageIdUuid = rawPageId && uuidRegex.test(rawPageId);
58
+ const pageIdUuid = isValidPageIdUuid ? rawPageId : void 0;
59
+ const pageIdName = rawPageId && !isValidPageIdUuid ? rawPageId : void 0;
48
60
  const auditEvent = {
49
61
  event_type: event.type,
50
62
  user_id: event.userId,
51
- // CRITICAL: Store organisationId even if null for auditing
52
- // Use a fallback UUID if organisation context is missing (for database constraint)
53
- organisation_id: event.organisationId || "00000000-0000-0000-0000-000000000000",
63
+ // Store organisationId - nullable to properly track missing context cases
64
+ // Do NOT use fallback UUID as it masks security issues
65
+ organisation_id: event.organisationId || null,
66
+ // Explicitly null if missing
54
67
  event_id: "eventId" in event ? event.eventId : void 0,
55
68
  app_id: "appId" in event ? event.appId : void 0,
56
- page_id: "pageId" in event ? event.pageId : void 0,
69
+ page_id: pageIdUuid,
70
+ // Only set if it's a valid UUID
57
71
  permission: "permission" in event ? event.permission : void 0,
58
72
  decision: "decision" in event ? event.decision : void 0,
59
73
  source: "source" in event ? event.source : "api",
@@ -64,8 +78,10 @@ var RBACAuditManager = class {
64
78
  ...event.metadata,
65
79
  cache_hit: "cache_hit" in event ? event.cache_hit : void 0,
66
80
  cache_source: "cache_source" in event ? event.cache_source : void 0,
67
- // Store a flag indicating this event had no organisation context
68
- no_organisation_context: !event.organisationId
81
+ // Explicit flag indicating this event had no organisation context
82
+ no_organisation_context: !event.organisationId,
83
+ // Store page name/identifier in metadata if it's not a UUID
84
+ page_name: pageIdName
69
85
  }
70
86
  };
71
87
  const { error } = await this.supabase.from("rbac_audit_events").insert([auditEvent]);
@@ -189,4 +205,4 @@ export {
189
205
  getGlobalAuditManager,
190
206
  emitAuditEvent
191
207
  };
192
- //# sourceMappingURL=chunk-Q7APDV6H.js.map
208
+ //# sourceMappingURL=chunk-3OGQLOJM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/rbac/audit.ts"],"sourcesContent":["/**\n * RBAC Audit Events System\n * @package @jmruthers/pace-core\n * @module RBAC/Audit\n * @since 1.0.0\n * \n * This module provides structured audit event emission for all RBAC operations.\n */\n\nimport { SupabaseClient } from '@supabase/supabase-js';\nimport { Database } from '../types/database';\nimport { \n UUID, \n AuditEventSource, \n RBACAuditEvent \n} from './types';\n\n/**\n * Audit event payload for permission checks\n */\nexport interface PermissionCheckAuditEvent {\n type: 'permission_check';\n userId: UUID;\n organisationId: UUID;\n eventId?: string;\n appId?: UUID;\n pageId?: UUID;\n permission: string;\n decision: boolean;\n source: AuditEventSource;\n bypass?: boolean;\n duration_ms: number;\n cache_hit?: boolean;\n cache_source?: 'memory' | 'database' | 'rpc';\n metadata?: Record<string, any>;\n}\n\n/**\n * Audit event payload for permission denied\n */\nexport interface PermissionDeniedAuditEvent {\n type: 'permission_denied';\n userId: UUID;\n organisationId: UUID;\n eventId?: string;\n appId?: UUID;\n pageId?: UUID;\n permission: string;\n source: AuditEventSource;\n metadata?: Record<string, any>;\n}\n\n/**\n * Audit event payload for role granted\n */\nexport interface RoleGrantedAuditEvent {\n type: 'role_granted';\n userId: UUID;\n organisationId: UUID;\n eventId?: string;\n appId?: UUID;\n role: string;\n grantedBy: UUID;\n metadata?: Record<string, any>;\n}\n\n/**\n * Audit event payload for role revoked\n */\nexport interface RoleRevokedAuditEvent {\n type: 'role_denied';\n userId: UUID;\n organisationId: UUID;\n eventId?: string;\n appId?: UUID;\n role: string;\n revokedBy: UUID;\n metadata?: Record<string, any>;\n}\n\n/**\n * Audit event payload for RLS denied\n */\nexport interface RLSDeniedAuditEvent {\n type: 'rls_denied';\n userId: UUID;\n organisationId: UUID;\n table: string;\n operation: string;\n metadata?: Record<string, any>;\n}\n\n/**\n * Union type for all audit events\n */\nexport type AuditEventPayload = \n | PermissionCheckAuditEvent\n | PermissionDeniedAuditEvent\n | RoleGrantedAuditEvent\n | RoleRevokedAuditEvent\n | RLSDeniedAuditEvent;\n\n/**\n * RBAC Audit Manager\n * \n * Handles emission of structured audit events for all RBAC operations.\n */\nexport class RBACAuditManager {\n private supabase: SupabaseClient<Database>;\n private enabled: boolean = true;\n\n constructor(supabase: SupabaseClient<Database>) {\n this.supabase = supabase;\n }\n\n /**\n * Enable or disable audit logging\n * \n * @param enabled - Whether to enable audit logging\n */\n setEnabled(enabled: boolean): void {\n this.enabled = enabled;\n }\n\n /**\n * Check if audit logging is enabled\n * \n * @returns True if audit logging is enabled\n */\n isEnabled(): boolean {\n return this.enabled;\n }\n\n /**\n * Emit an audit event\n * \n * @param event - Audit event payload\n * @returns Promise that resolves when event is logged\n */\n async emitEvent(event: AuditEventPayload): Promise<void> {\n if (!this.enabled) {\n return;\n }\n\n // Validate required fields before attempting to insert\n // MANDATORY: All audit events must have userId\n if (!event.userId) {\n console.error('[RBAC Audit] CRITICAL: Cannot log audit event without userId:', {\n eventType: event.type,\n organisationId: event.organisationId\n });\n return;\n }\n\n // WARNING: Some audit events may not have organisationId (e.g., global admin operations)\n // Log these for security monitoring even if organisationId is missing\n if (!event.organisationId) {\n console.warn('[RBAC Audit] Audit event without organisation context:', {\n userId: event.userId,\n eventType: event.type,\n note: 'This should be investigated for security compliance'\n });\n }\n\n try {\n // Since organisationId is now required in SecurityContext, this should rarely happen\n // But we still handle the edge case properly without masking it\n if (!event.organisationId) {\n console.warn('[RBAC Audit] Audit event without organisation context - this should be investigated:', {\n userId: event.userId,\n eventType: event.type,\n note: 'Organisation context is required for RBAC operations. This may indicate a security issue or missing context derivation.'\n });\n }\n\n // Validate pageId: only include in page_id column if it's a valid UUID\n // Otherwise, store it in metadata to avoid database errors\n const rawPageId = 'pageId' in event ? event.pageId : undefined;\n const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n const isValidPageIdUuid = rawPageId && uuidRegex.test(rawPageId);\n const pageIdUuid: UUID | undefined = isValidPageIdUuid ? (rawPageId as UUID) : undefined;\n const pageIdName: string | undefined = rawPageId && !isValidPageIdUuid ? rawPageId : undefined;\n\n const auditEvent: Omit<RBACAuditEvent, 'id' | 'created_at'> = {\n event_type: event.type,\n user_id: event.userId,\n // Store organisationId - nullable to properly track missing context cases\n // Do NOT use fallback UUID as it masks security issues\n organisation_id: event.organisationId || null, // Explicitly null if missing\n event_id: 'eventId' in event ? event.eventId : undefined,\n app_id: 'appId' in event ? event.appId : undefined,\n page_id: pageIdUuid, // Only set if it's a valid UUID\n permission: 'permission' in event ? event.permission : undefined,\n decision: 'decision' in event ? event.decision : undefined,\n source: 'source' in event ? event.source : 'api', // Default to 'api' if not provided\n bypass: 'bypass' in event ? event.bypass : undefined,\n duration_ms: 'duration_ms' in event ? event.duration_ms : undefined,\n metadata: {\n ...event.metadata,\n cache_hit: 'cache_hit' in event ? event.cache_hit : undefined,\n cache_source: 'cache_source' in event ? event.cache_source : undefined,\n // Explicit flag indicating this event had no organisation context\n no_organisation_context: !event.organisationId,\n // Store page name/identifier in metadata if it's not a UUID\n page_name: pageIdName,\n },\n };\n\n const { error } = await (this.supabase as any)\n .from('rbac_audit_events')\n .insert([auditEvent]);\n\n if (error) {\n // Log the error for debugging but don't throw\n console.warn('[RBAC Audit] Failed to insert audit event:', {\n error: error.message,\n code: error.code,\n details: error.details,\n hint: error.hint,\n event: auditEvent\n });\n }\n } catch (error) {\n // Log unexpected errors but don't throw\n console.error('[RBAC Audit] Unexpected error during audit logging:', error);\n }\n }\n\n /**\n * Emit a permission check audit event\n * \n * @param event - Permission check event data\n */\n async emitPermissionCheck(event: Omit<PermissionCheckAuditEvent, 'type'>): Promise<void> {\n await this.emitEvent({\n type: 'permission_check',\n ...event,\n });\n }\n\n /**\n * Emit a permission denied audit event\n * \n * @param event - Permission denied event data\n */\n async emitPermissionDenied(event: Omit<PermissionDeniedAuditEvent, 'type'>): Promise<void> {\n await this.emitEvent({\n type: 'permission_denied',\n ...event,\n });\n }\n\n /**\n * Emit a role granted audit event\n * \n * @param event - Role granted event data\n */\n async emitRoleGranted(event: Omit<RoleGrantedAuditEvent, 'type'>): Promise<void> {\n await this.emitEvent({\n type: 'role_granted',\n ...event,\n });\n }\n\n /**\n * Emit a role revoked audit event\n * \n * @param event - Role revoked event data\n */\n async emitRoleRevoked(event: Omit<RoleRevokedAuditEvent, 'type'>): Promise<void> {\n await this.emitEvent({\n type: 'role_denied',\n ...event,\n });\n }\n\n /**\n * Emit an RLS denied audit event\n * \n * @param event - RLS denied event data\n */\n async emitRLSDenied(event: Omit<RLSDeniedAuditEvent, 'type'>): Promise<void> {\n await this.emitEvent({\n type: 'rls_denied',\n ...event,\n });\n }\n\n /**\n * Get audit events for a user\n * \n * @param userId - User ID\n * @param limit - Maximum number of events to return\n * @returns Promise resolving to audit events\n */\n async getUserAuditEvents(userId: UUID, limit: number = 100): Promise<RBACAuditEvent[]> {\n const { data, error } = await this.supabase\n .from('rbac_audit_events')\n .select('*')\n .eq('user_id', userId)\n .order('created_at', { ascending: false })\n .limit(limit);\n\n if (error) {\n throw new Error(`Failed to get audit events: ${error.message}`);\n }\n\n return data || [];\n }\n\n /**\n * Get audit events for an organisation\n * \n * @param organisationId - Organisation ID\n * @param limit - Maximum number of events to return\n * @returns Promise resolving to audit events\n */\n async getOrganisationAuditEvents(organisationId: UUID, limit: number = 100): Promise<RBACAuditEvent[]> {\n const { data, error } = await this.supabase\n .from('rbac_audit_events')\n .select('*')\n .eq('organisation_id', organisationId)\n .order('created_at', { ascending: false })\n .limit(limit);\n\n if (error) {\n throw new Error(`Failed to get audit events: ${error.message}`);\n }\n\n return data || [];\n }\n}\n\n/**\n * Create an audit manager instance\n * \n * @param supabase - Supabase client\n * @returns RBACAuditManager instance\n */\nexport function createAuditManager(supabase: SupabaseClient<Database>): RBACAuditManager {\n return new RBACAuditManager(supabase);\n}\n\n/**\n * Global audit manager instance\n * \n * This is set by the RBAC engine when it initializes.\n */\nlet globalAuditManager: RBACAuditManager | null = null;\n\n/**\n * Set the global audit manager\n * \n * @param manager - Audit manager instance\n */\nexport function setGlobalAuditManager(manager: RBACAuditManager): void {\n globalAuditManager = manager;\n}\n\n/**\n * Get the global audit manager\n * \n * @returns Global audit manager or null if not set\n */\nexport function getGlobalAuditManager(): RBACAuditManager | null {\n return globalAuditManager;\n}\n\n/**\n * Emit an audit event using the global audit manager\n * \n * @param event - Audit event payload\n */\nexport async function emitAuditEvent(event: AuditEventPayload): Promise<void> {\n if (globalAuditManager) {\n await globalAuditManager.emitEvent(event);\n }\n}\n"],"mappings":"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","names":[]}
@@ -2,7 +2,7 @@ import {
2
2
  UnifiedAuthProvider,
3
3
  init_UnifiedAuthProvider,
4
4
  useUnifiedAuth
5
- } from "./chunk-AUXS7XSO.js";
5
+ } from "./chunk-OO3V7W4H.js";
6
6
  import {
7
7
  __esm,
8
8
  __export
@@ -24,4 +24,4 @@ export {
24
24
  UnifiedAuthProvider_exports,
25
25
  init_UnifiedAuthProvider2 as init_UnifiedAuthProvider
26
26
  };
27
- //# sourceMappingURL=chunk-EYSXQ756.js.map
27
+ //# sourceMappingURL=chunk-7H75SHXZ.js.map
@@ -4,7 +4,7 @@ import {
4
4
  init_InactivityServiceProvider,
5
5
  init_OrganisationServiceProvider,
6
6
  init_UnifiedAuthProvider
7
- } from "./chunk-AUXS7XSO.js";
7
+ } from "./chunk-OO3V7W4H.js";
8
8
 
9
9
  // src/providers/index.ts
10
10
  init_UnifiedAuthProvider();
@@ -12,4 +12,4 @@ init_EventServiceProvider();
12
12
  init_OrganisationServiceProvider();
13
13
  init_InactivityServiceProvider();
14
14
  init_AuthServiceProvider();
15
- //# sourceMappingURL=chunk-D6MEKC27.js.map
15
+ //# sourceMappingURL=chunk-BUN7NMV7.js.map
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  init_OrganisationProvider,
3
3
  usePublicPageContext
4
- } from "./chunk-2W4WKJVF.js";
4
+ } from "./chunk-F6QB26OS.js";
5
5
  import {
6
6
  init_useOrganisations,
7
7
  useEvents,
8
8
  useOrganisations
9
- } from "./chunk-EZ64QG2I.js";
9
+ } from "./chunk-L36JW4KV.js";
10
10
  import {
11
11
  useUnifiedAuth
12
- } from "./chunk-AUXS7XSO.js";
12
+ } from "./chunk-OO3V7W4H.js";
13
13
  import {
14
14
  applyPalette,
15
15
  clearPalette,
@@ -96,7 +96,7 @@ var useOrganisationSecurity = () => {
96
96
  const targetOrgId = orgId || selectedOrganisation?.id;
97
97
  if (!targetOrgId || !user) return false;
98
98
  try {
99
- const { isPermitted } = await import("./api-PIE4JRFS.js");
99
+ const { isPermitted } = await import("./api-QPMBZZUZ.js");
100
100
  const scope = {
101
101
  organisationId: targetOrgId,
102
102
  eventId: user.user_metadata?.eventId || user.app_metadata?.eventId,
@@ -119,7 +119,7 @@ var useOrganisationSecurity = () => {
119
119
  const targetOrgId = orgId || selectedOrganisation?.id;
120
120
  if (!targetOrgId || !user) return [];
121
121
  try {
122
- const { getPermissionMap } = await import("./api-PIE4JRFS.js");
122
+ const { getPermissionMap } = await import("./api-QPMBZZUZ.js");
123
123
  const scope = {
124
124
  organisationId: targetOrgId,
125
125
  eventId: user.user_metadata?.eventId || user.app_metadata?.eventId,
@@ -140,7 +140,7 @@ var useOrganisationSecurity = () => {
140
140
  if (!user || !selectedOrganisation) return;
141
141
  try {
142
142
  if (selectedOrganisation.id) {
143
- const { emitAuditEvent } = await import("./audit-65VNHEV2.js");
143
+ const { emitAuditEvent } = await import("./audit-H4YJJF7R.js");
144
144
  await emitAuditEvent({
145
145
  type: "permission_check",
146
146
  userId: user.id,
@@ -706,4 +706,4 @@ export {
706
706
  generatePublicRoutePath,
707
707
  extractEventCodeFromPath
708
708
  };
709
- //# sourceMappingURL=chunk-AWK2FAUN.js.map
709
+ //# sourceMappingURL=chunk-C5RN4TE5.js.map