@jmruthers/pace-core 0.2.4

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 (1009) hide show
  1. package/CHANGELOG.md +202 -0
  2. package/README.md +299 -0
  3. package/dist/DataTable-BHlzyKZP.d.ts +116 -0
  4. package/dist/DataTable-GEY5U7OI.js +100 -0
  5. package/dist/DataTable-GEY5U7OI.js.map +1 -0
  6. package/dist/PublicLoadingSpinner-DztrzuJr.d.ts +3430 -0
  7. package/dist/UnifiedAuthProvider-w66zSCUf.d.ts +160 -0
  8. package/dist/api-GZHIDA4X.js +41 -0
  9. package/dist/api-GZHIDA4X.js.map +1 -0
  10. package/dist/appConfig-BVGyuvI7.d.ts +71 -0
  11. package/dist/appNameResolver-7GHF5ED2.js +22 -0
  12. package/dist/appNameResolver-7GHF5ED2.js.map +1 -0
  13. package/dist/audit-BUW3LMJB.js +16 -0
  14. package/dist/audit-BUW3LMJB.js.map +1 -0
  15. package/dist/chunk-22KLBHPS.js +29 -0
  16. package/dist/chunk-22KLBHPS.js.map +1 -0
  17. package/dist/chunk-24MKLB7U.js +81 -0
  18. package/dist/chunk-24MKLB7U.js.map +1 -0
  19. package/dist/chunk-2MKP6IYD.js +388 -0
  20. package/dist/chunk-2MKP6IYD.js.map +1 -0
  21. package/dist/chunk-2V3Y6YBC.js +114 -0
  22. package/dist/chunk-2V3Y6YBC.js.map +1 -0
  23. package/dist/chunk-5CDJCTOO.js +190 -0
  24. package/dist/chunk-5CDJCTOO.js.map +1 -0
  25. package/dist/chunk-6ZQVSHKL.js +1345 -0
  26. package/dist/chunk-6ZQVSHKL.js.map +1 -0
  27. package/dist/chunk-74C6SNEC.js +77 -0
  28. package/dist/chunk-74C6SNEC.js.map +1 -0
  29. package/dist/chunk-7BNPOCLL.js +178 -0
  30. package/dist/chunk-7BNPOCLL.js.map +1 -0
  31. package/dist/chunk-7JL3T7BO.js +3344 -0
  32. package/dist/chunk-7JL3T7BO.js.map +1 -0
  33. package/dist/chunk-CDQ3PX7L.js +18 -0
  34. package/dist/chunk-CDQ3PX7L.js.map +1 -0
  35. package/dist/chunk-DY5E3AT7.js +1734 -0
  36. package/dist/chunk-DY5E3AT7.js.map +1 -0
  37. package/dist/chunk-ETEJVKYK.js +6032 -0
  38. package/dist/chunk-ETEJVKYK.js.map +1 -0
  39. package/dist/chunk-I5Z3QH5X.js +32 -0
  40. package/dist/chunk-I5Z3QH5X.js.map +1 -0
  41. package/dist/chunk-MZBUOP4P.js +119 -0
  42. package/dist/chunk-MZBUOP4P.js.map +1 -0
  43. package/dist/chunk-N2EUGZRW.js +98 -0
  44. package/dist/chunk-N2EUGZRW.js.map +1 -0
  45. package/dist/chunk-NQ4TOOO6.js +20 -0
  46. package/dist/chunk-NQ4TOOO6.js.map +1 -0
  47. package/dist/chunk-OHXGNT3K.js +21 -0
  48. package/dist/chunk-OHXGNT3K.js.map +1 -0
  49. package/dist/chunk-OKXMUYIB.js +522 -0
  50. package/dist/chunk-OKXMUYIB.js.map +1 -0
  51. package/dist/chunk-PFRRIDYA.js +382 -0
  52. package/dist/chunk-PFRRIDYA.js.map +1 -0
  53. package/dist/chunk-PLDDJCW6.js +49 -0
  54. package/dist/chunk-PLDDJCW6.js.map +1 -0
  55. package/dist/chunk-SS3E6QLB.js +695 -0
  56. package/dist/chunk-SS3E6QLB.js.map +1 -0
  57. package/dist/chunk-TMRLB2LA.js +326 -0
  58. package/dist/chunk-TMRLB2LA.js.map +1 -0
  59. package/dist/chunk-WYB6MBZA.js +5533 -0
  60. package/dist/chunk-WYB6MBZA.js.map +1 -0
  61. package/dist/chunk-YDJW5XTN.js +84 -0
  62. package/dist/chunk-YDJW5XTN.js.map +1 -0
  63. package/dist/components.d.ts +1308 -0
  64. package/dist/components.js +3759 -0
  65. package/dist/components.js.map +1 -0
  66. package/dist/database-C3Szpi5J.d.ts +470 -0
  67. package/dist/hooks.d.ts +449 -0
  68. package/dist/hooks.js +612 -0
  69. package/dist/hooks.js.map +1 -0
  70. package/dist/index.d.ts +385 -0
  71. package/dist/index.js +569 -0
  72. package/dist/index.js.map +1 -0
  73. package/dist/organisation-CO3Sh3_D.d.ts +99 -0
  74. package/dist/providers.d.ts +45 -0
  75. package/dist/providers.js +36 -0
  76. package/dist/providers.js.map +1 -0
  77. package/dist/rbac/eslint-rules.d.ts +52 -0
  78. package/dist/rbac/eslint-rules.js +252 -0
  79. package/dist/rbac/eslint-rules.js.map +1 -0
  80. package/dist/rbac/index.d.ts +1918 -0
  81. package/dist/rbac/index.js +2212 -0
  82. package/dist/rbac/index.js.map +1 -0
  83. package/dist/styles/core.css +401 -0
  84. package/dist/styles/fonts/georama-italic.woff2 +0 -0
  85. package/dist/styles/fonts/georama.woff2 +0 -0
  86. package/dist/styles/fonts/open-sans-italic.woff2 +0 -0
  87. package/dist/styles/fonts/open-sans.woff2 +0 -0
  88. package/dist/styles/fonts/reddit-mono.woff2 +0 -0
  89. package/dist/styles/index.d.ts +36 -0
  90. package/dist/styles/index.js +24 -0
  91. package/dist/styles/index.js.map +1 -0
  92. package/dist/theming/runtime.d.ts +73 -0
  93. package/dist/theming/runtime.js +16 -0
  94. package/dist/theming/runtime.js.map +1 -0
  95. package/dist/types-CInEi-ng.d.ts +316 -0
  96. package/dist/types.d.ts +196 -0
  97. package/dist/types.js +83 -0
  98. package/dist/types.js.map +1 -0
  99. package/dist/unified-CM7T0aTK.d.ts +198 -0
  100. package/dist/useComponentPerformance-DE9l5RkL.d.ts +11 -0
  101. package/dist/usePublicRouteParams-B6i0KtXW.d.ts +477 -0
  102. package/dist/utils.d.ts +639 -0
  103. package/dist/utils.js +1103 -0
  104. package/dist/utils.js.map +1 -0
  105. package/dist/validation-PM_iOaTI.d.ts +159 -0
  106. package/dist/validation.d.ts +138 -0
  107. package/dist/validation.js +477 -0
  108. package/dist/validation.js.map +1 -0
  109. package/docs/INDEX.md +192 -0
  110. package/docs/README.md +165 -0
  111. package/docs/api/.nojekyll +1 -0
  112. package/docs/api/README.md +301 -0
  113. package/docs/api/classes/ErrorBoundary.md +144 -0
  114. package/docs/api/classes/PublicErrorBoundary.md +132 -0
  115. package/docs/api/interfaces/AggregateConfig.md +43 -0
  116. package/docs/api/interfaces/ButtonProps.md +53 -0
  117. package/docs/api/interfaces/CardProps.md +40 -0
  118. package/docs/api/interfaces/ColorPalette.md +7 -0
  119. package/docs/api/interfaces/ColorShade.md +41 -0
  120. package/docs/api/interfaces/DataTableAction.md +200 -0
  121. package/docs/api/interfaces/DataTableColumn.md +300 -0
  122. package/docs/api/interfaces/DataTableProps.md +517 -0
  123. package/docs/api/interfaces/DataTableToolbarButton.md +96 -0
  124. package/docs/api/interfaces/EmptyStateConfig.md +61 -0
  125. package/docs/api/interfaces/EventContextType.md +96 -0
  126. package/docs/api/interfaces/EventLogoProps.md +152 -0
  127. package/docs/api/interfaces/EventProviderProps.md +19 -0
  128. package/docs/api/interfaces/FileSizeLimits.md +7 -0
  129. package/docs/api/interfaces/FileUploadProps.md +154 -0
  130. package/docs/api/interfaces/FooterProps.md +105 -0
  131. package/docs/api/interfaces/InactivityWarningModalProps.md +115 -0
  132. package/docs/api/interfaces/InputProps.md +53 -0
  133. package/docs/api/interfaces/LabelProps.md +107 -0
  134. package/docs/api/interfaces/LoginFormProps.md +184 -0
  135. package/docs/api/interfaces/NavigationItem.md +176 -0
  136. package/docs/api/interfaces/NavigationMenuProps.md +236 -0
  137. package/docs/api/interfaces/Organisation.md +140 -0
  138. package/docs/api/interfaces/OrganisationContextType.md +377 -0
  139. package/docs/api/interfaces/OrganisationMembership.md +140 -0
  140. package/docs/api/interfaces/OrganisationProviderProps.md +19 -0
  141. package/docs/api/interfaces/OrganisationSecurityError.md +62 -0
  142. package/docs/api/interfaces/PaceAppLayoutProps.md +393 -0
  143. package/docs/api/interfaces/PaceLoginPageProps.md +34 -0
  144. package/docs/api/interfaces/PaletteData.md +41 -0
  145. package/docs/api/interfaces/PublicErrorBoundaryProps.md +94 -0
  146. package/docs/api/interfaces/PublicErrorBoundaryState.md +68 -0
  147. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +86 -0
  148. package/docs/api/interfaces/PublicPageFooterProps.md +112 -0
  149. package/docs/api/interfaces/PublicPageHeaderProps.md +138 -0
  150. package/docs/api/interfaces/PublicPageLayoutProps.md +138 -0
  151. package/docs/api/interfaces/StorageConfig.md +41 -0
  152. package/docs/api/interfaces/StorageFileInfo.md +74 -0
  153. package/docs/api/interfaces/StorageFileMetadata.md +140 -0
  154. package/docs/api/interfaces/StorageListOptions.md +86 -0
  155. package/docs/api/interfaces/StorageListResult.md +41 -0
  156. package/docs/api/interfaces/StorageUploadOptions.md +88 -0
  157. package/docs/api/interfaces/StorageUploadResult.md +63 -0
  158. package/docs/api/interfaces/StorageUrlOptions.md +47 -0
  159. package/docs/api/interfaces/StyleImport.md +19 -0
  160. package/docs/api/interfaces/ToastActionElement.md +9 -0
  161. package/docs/api/interfaces/ToastProps.md +9 -0
  162. package/docs/api/interfaces/UnifiedAuthContextType.md +1108 -0
  163. package/docs/api/interfaces/UnifiedAuthProviderProps.md +171 -0
  164. package/docs/api/interfaces/UseInactivityTrackerOptions.md +136 -0
  165. package/docs/api/interfaces/UseInactivityTrackerReturn.md +123 -0
  166. package/docs/api/interfaces/UsePublicEventLogoOptions.md +87 -0
  167. package/docs/api/interfaces/UsePublicEventLogoReturn.md +81 -0
  168. package/docs/api/interfaces/UsePublicEventOptions.md +34 -0
  169. package/docs/api/interfaces/UsePublicEventReturn.md +68 -0
  170. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +94 -0
  171. package/docs/api/interfaces/UserEventAccess.md +118 -0
  172. package/docs/api/interfaces/UserMenuProps.md +86 -0
  173. package/docs/api/interfaces/UserProfile.md +63 -0
  174. package/docs/api/modules.md +4153 -0
  175. package/docs/api-reference/components.md +1623 -0
  176. package/docs/api-reference/hooks.md +627 -0
  177. package/docs/api-reference/providers.md +487 -0
  178. package/docs/api-reference/types.md +1005 -0
  179. package/docs/api-reference/utilities.md +1104 -0
  180. package/docs/app.css.example +53 -0
  181. package/docs/architecture/README.md +577 -0
  182. package/docs/best-practices/README.md +400 -0
  183. package/docs/best-practices/deployment.md +1042 -0
  184. package/docs/best-practices/performance.md +789 -0
  185. package/docs/best-practices/security.md +881 -0
  186. package/docs/best-practices/testing.md +981 -0
  187. package/docs/consuming-app-example.md +290 -0
  188. package/docs/consuming-app-vite-config.md +233 -0
  189. package/docs/core-concepts/authentication.md +98 -0
  190. package/docs/core-concepts/events.md +756 -0
  191. package/docs/core-concepts/organisations.md +790 -0
  192. package/docs/core-concepts/permissions.md +729 -0
  193. package/docs/core-concepts/rbac-system.md +233 -0
  194. package/docs/database-schema-requirements.md +172 -0
  195. package/docs/documentation-style-checklist.md +294 -0
  196. package/docs/examples/navigation-menu-auth-fix.md +344 -0
  197. package/docs/getting-started/examples/README.md +106 -0
  198. package/docs/getting-started/examples/basic-auth-app.md +521 -0
  199. package/docs/getting-started/examples/full-featured-app.md +616 -0
  200. package/docs/getting-started/installation.md +269 -0
  201. package/docs/getting-started/quick-start.md +401 -0
  202. package/docs/implementation-guides/app-layout.md +983 -0
  203. package/docs/implementation-guides/data-tables.md +1898 -0
  204. package/docs/implementation-guides/dynamic-colors.md +195 -0
  205. package/docs/implementation-guides/forms.md +578 -0
  206. package/docs/implementation-guides/hierarchical-datatable.md +850 -0
  207. package/docs/implementation-guides/large-datasets.md +281 -0
  208. package/docs/implementation-guides/navigation.md +844 -0
  209. package/docs/implementation-guides/performance.md +403 -0
  210. package/docs/implementation-guides/permission-enforcement.md +764 -0
  211. package/docs/implementation-guides/public-pages.md +752 -0
  212. package/docs/migration/README.md +493 -0
  213. package/docs/migration/organisation-context-timing-fix.md +217 -0
  214. package/docs/migration/quick-migration-guide.md +320 -0
  215. package/docs/migration/rbac-migration.md +571 -0
  216. package/docs/migration/v0.4.15-tailwind-scanning.md +272 -0
  217. package/docs/migration/v0.4.16-css-first-approach.md +306 -0
  218. package/docs/migration/v0.4.17-source-path-fix.md +229 -0
  219. package/docs/migration-guide.md +168 -0
  220. package/docs/performance/README.md +551 -0
  221. package/docs/print-components/README.md +258 -0
  222. package/docs/print-components/api-reference.md +636 -0
  223. package/docs/print-components/examples/README.md +204 -0
  224. package/docs/print-components/examples/basic-report.tsx +92 -0
  225. package/docs/print-components/examples/card-catalog.tsx +149 -0
  226. package/docs/print-components/examples/cover-page-report.tsx +163 -0
  227. package/docs/print-components/quick-start.md +363 -0
  228. package/docs/quick-reference.md +576 -0
  229. package/docs/rbac/README.md +265 -0
  230. package/docs/rbac/advanced-patterns.md +776 -0
  231. package/docs/rbac/api-reference.md +1033 -0
  232. package/docs/rbac/examples.md +883 -0
  233. package/docs/rbac/getting-started.md +679 -0
  234. package/docs/rbac/quick-start.md +619 -0
  235. package/docs/rbac/super-admin-guide.md +592 -0
  236. package/docs/rbac/troubleshooting.md +316 -0
  237. package/docs/security/README.md +680 -0
  238. package/docs/security/checklist.md +343 -0
  239. package/docs/style-guide.md +522 -0
  240. package/docs/styles/README.md +319 -0
  241. package/docs/testing/README.md +874 -0
  242. package/docs/troubleshooting/README.md +497 -0
  243. package/docs/troubleshooting/common-issues.md +1563 -0
  244. package/docs/troubleshooting/database-view-compatibility.md +119 -0
  245. package/docs/troubleshooting/debugging.md +1117 -0
  246. package/docs/troubleshooting/migration.md +918 -0
  247. package/docs/troubleshooting/organisation-context-setup.md +277 -0
  248. package/docs/troubleshooting/react-hooks-issue-analysis.md +166 -0
  249. package/docs/troubleshooting/styling-issues.md +219 -0
  250. package/docs/troubleshooting/tailwind-content-scanning.md +213 -0
  251. package/docs/usage.md +175 -0
  252. package/docs/visual-testing.md +114 -0
  253. package/package.json +211 -0
  254. package/src/__mocks__/lucide-react.ts +181 -0
  255. package/src/__tests__/README.md +404 -0
  256. package/src/__tests__/debug-provider.unit.test.tsx +67 -0
  257. package/src/__tests__/e2e/workflows.test.tsx +373 -0
  258. package/src/__tests__/hybridPermissions.unit.test.tsx +474 -0
  259. package/src/__tests__/index.integration.test.ts +491 -0
  260. package/src/__tests__/mocks/MockAuthProvider-standalone.tsx +47 -0
  261. package/src/__tests__/mocks/MockAuthProvider.tsx +63 -0
  262. package/src/__tests__/mocks/enhancedSupabaseMock.ts +252 -0
  263. package/src/__tests__/mocks/index.test.ts +23 -0
  264. package/src/__tests__/mocks/index.ts +16 -0
  265. package/src/__tests__/mocks/mockAuth.ts +155 -0
  266. package/src/__tests__/mocks/mockSupabase.ts +83 -0
  267. package/src/__tests__/mocks/mockSupabaseClient.ts +63 -0
  268. package/src/__tests__/mocks/providers.tsx +22 -0
  269. package/src/__tests__/patterns/__tests__/testPatterns.test.ts +394 -0
  270. package/src/__tests__/patterns/testPatterns.ts +124 -0
  271. package/src/__tests__/performance/componentPerformance.performance.test.ts +27 -0
  272. package/src/__tests__/performance/index.ts +24 -0
  273. package/src/__tests__/performance/performanceValidation.performance.test.ts +15 -0
  274. package/src/__tests__/security/security.unit.test.tsx +7 -0
  275. package/src/__tests__/security/securityValidation.security.test.tsx +153 -0
  276. package/src/__tests__/setup.ts +259 -0
  277. package/src/__tests__/setupTests.d.ts +1 -0
  278. package/src/__tests__/shared/componentTestUtils.tsx +475 -0
  279. package/src/__tests__/shared/errorHandlingTestUtils.ts +107 -0
  280. package/src/__tests__/shared/index.ts +81 -0
  281. package/src/__tests__/shared/integrationTestUtils.tsx +375 -0
  282. package/src/__tests__/shared/performanceTestUtils.tsx +476 -0
  283. package/src/__tests__/shared/testUtils.optimized.tsx +627 -0
  284. package/src/__tests__/simple.test.tsx +20 -0
  285. package/src/__tests__/templates/accessibility.test.template.tsx +279 -0
  286. package/src/__tests__/templates/component.test.template.tsx +122 -0
  287. package/src/__tests__/templates/integration.test.template.tsx +199 -0
  288. package/src/__tests__/test-utils/dataFactories.ts +60 -0
  289. package/src/__tests__/test-utils/index.ts +6 -0
  290. package/src/__tests__/typeSafety.unit.test.ts +65 -0
  291. package/src/__tests__/unifiedAuth.unit.test.tsx +151 -0
  292. package/src/__tests__/utils/accessibilityHelpers.ts +254 -0
  293. package/src/__tests__/utils/assertions.ts +50 -0
  294. package/src/__tests__/utils/deterministicHelpers.ts +31 -0
  295. package/src/__tests__/utils/edgeCaseConfig.test.ts +75 -0
  296. package/src/__tests__/utils/edgeCaseConfig.ts +98 -0
  297. package/src/__tests__/utils/mockHelpers.ts +149 -0
  298. package/src/__tests__/utils/mockLoader.ts +101 -0
  299. package/src/__tests__/utils/performanceHelpers.ts +55 -0
  300. package/src/__tests__/utils/performanceTestHelpers.ts +68 -0
  301. package/src/__tests__/utils/testDataFactories.ts +28 -0
  302. package/src/__tests__/utils/testIsolation.ts +67 -0
  303. package/src/__tests__/utils/visualTestHelpers.ts +20 -0
  304. package/src/__tests__/visual/__snapshots__/componentSnapshots.visual.test.tsx.snap +68 -0
  305. package/src/__tests__/visual/__snapshots__/componentVisuals.visual.test.tsx.snap +14 -0
  306. package/src/__tests__/visual/__snapshots__/visualRegression.test.tsx.snap +217 -0
  307. package/src/__tests__/visual/__snapshots__/visualRegression.visual.test.tsx.snap +24 -0
  308. package/src/__tests__/visual/componentSnapshots.visual.test.tsx +33 -0
  309. package/src/__tests__/visual/componentVisuals.visual.test.tsx +12 -0
  310. package/src/__tests__/visual/visualRegression.visual.test.tsx +20 -0
  311. package/src/components/Alert/Alert.tsx +134 -0
  312. package/src/components/Alert/__tests__/Alert.unit.test.tsx +381 -0
  313. package/src/components/Alert/index.ts +2 -0
  314. package/src/components/Avatar/Avatar.tsx +84 -0
  315. package/src/components/Avatar/__tests__/Avatar.unit.test.tsx +232 -0
  316. package/src/components/Avatar/index.ts +2 -0
  317. package/src/components/Button/Button.tsx +270 -0
  318. package/src/components/Button/__tests__/Button.accessibility.test.tsx +131 -0
  319. package/src/components/Button/__tests__/Button.comprehensive.test.tsx +721 -0
  320. package/src/components/Button/__tests__/Button.unit.test.tsx +189 -0
  321. package/src/components/Button/__tests__/EventSelector.integration.test.tsx +285 -0
  322. package/src/components/Button/index.ts +2 -0
  323. package/src/components/Card/Card.tsx +271 -0
  324. package/src/components/Card/__tests__/Card.accessibility.test.tsx +394 -0
  325. package/src/components/Card/__tests__/Card.comprehensive.test.tsx +599 -0
  326. package/src/components/Card/__tests__/Card.integration.test.tsx +673 -0
  327. package/src/components/Card/__tests__/Card.performance.test.tsx +546 -0
  328. package/src/components/Card/__tests__/Card.unit.test.tsx +330 -0
  329. package/src/components/Card/__tests__/Card.visual.test.tsx +599 -0
  330. package/src/components/Card/__tests__/README.md +211 -0
  331. package/src/components/Card/index.ts +1 -0
  332. package/src/components/Checkbox/Checkbox.tsx +75 -0
  333. package/src/components/Checkbox/__mocks__/Checkbox.tsx +2 -0
  334. package/src/components/Checkbox/__tests__/Checkbox.unit.test.tsx +520 -0
  335. package/src/components/Checkbox/index.ts +2 -0
  336. package/src/components/DataTable/DataTable.tsx +440 -0
  337. package/src/components/DataTable/__tests__/DataTable.autoSizing.test.tsx +526 -0
  338. package/src/components/DataTable/__tests__/DataTable.errorHandling.test.tsx +259 -0
  339. package/src/components/DataTable/__tests__/DataTable.hierarchical.test.tsx +675 -0
  340. package/src/components/DataTable/__tests__/DataTable.infinite-loop.test.tsx +324 -0
  341. package/src/components/DataTable/__tests__/DataTable.integration.test.tsx +724 -0
  342. package/src/components/DataTable/__tests__/DataTable.performance.test.tsx +597 -0
  343. package/src/components/DataTable/__tests__/DataTable.permissions.test.tsx +306 -0
  344. package/src/components/DataTable/__tests__/DataTable.regressionFixes.test.tsx +546 -0
  345. package/src/components/DataTable/__tests__/DataTable.selection.controlled.test.tsx +386 -0
  346. package/src/components/DataTable/__tests__/DataTable.selection.test.tsx +338 -0
  347. package/src/components/DataTable/__tests__/DataTable.userWorkflows.test.tsx +310 -0
  348. package/src/components/DataTable/__tests__/DataTable.workflowValidation.test.tsx +489 -0
  349. package/src/components/DataTable/__tests__/DataTable.workflows.test.tsx +701 -0
  350. package/src/components/DataTable/__tests__/README.md +136 -0
  351. package/src/components/DataTable/__tests__/mocks/MockRBACProvider.tsx +66 -0
  352. package/src/components/DataTable/__tests__/performance-regression.test.tsx +788 -0
  353. package/src/components/DataTable/__tests__/performance.test.tsx +365 -0
  354. package/src/components/DataTable/__tests__/test-utils/dataFactories.ts +103 -0
  355. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +382 -0
  356. package/src/components/DataTable/__tests__/test-utils.ts +94 -0
  357. package/src/components/DataTable/components/ActionButtons.tsx +177 -0
  358. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +160 -0
  359. package/src/components/DataTable/components/ColumnFilter.tsx +114 -0
  360. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +100 -0
  361. package/src/components/DataTable/components/DataTableBody.tsx +462 -0
  362. package/src/components/DataTable/components/DataTableCore.tsx +869 -0
  363. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +214 -0
  364. package/src/components/DataTable/components/DataTableHeader.tsx +31 -0
  365. package/src/components/DataTable/components/DataTableModals.tsx +87 -0
  366. package/src/components/DataTable/components/DataTableToolbar.tsx +251 -0
  367. package/src/components/DataTable/components/DraggableColumnHeader.tsx +148 -0
  368. package/src/components/DataTable/components/EditableRow.tsx +160 -0
  369. package/src/components/DataTable/components/EmptyState.tsx +64 -0
  370. package/src/components/DataTable/components/ExpandButton.tsx +113 -0
  371. package/src/components/DataTable/components/FilterRow.tsx +101 -0
  372. package/src/components/DataTable/components/GroupHeader.tsx +42 -0
  373. package/src/components/DataTable/components/GroupingDropdown.tsx +96 -0
  374. package/src/components/DataTable/components/ImportModal.tsx +345 -0
  375. package/src/components/DataTable/components/LoadingState.tsx +12 -0
  376. package/src/components/DataTable/components/PaginationControls.tsx +332 -0
  377. package/src/components/DataTable/components/UnifiedTableBody.tsx +911 -0
  378. package/src/components/DataTable/components/ViewRowModal.tsx +68 -0
  379. package/src/components/DataTable/components/VirtualizedDataTable.tsx +593 -0
  380. package/src/components/DataTable/components/__tests__/ActionButtons.unit.test.tsx +150 -0
  381. package/src/components/DataTable/components/__tests__/BulkOperationsDropdown.test.tsx +224 -0
  382. package/src/components/DataTable/components/__tests__/ColumnVisibilityDropdown.unit.test.tsx +244 -0
  383. package/src/components/DataTable/components/__tests__/DataTable.accessibility.test.tsx +523 -0
  384. package/src/components/DataTable/components/__tests__/DataTable.integration.test.tsx +401 -0
  385. package/src/components/DataTable/components/__tests__/DataTable.performance.test.tsx +161 -0
  386. package/src/components/DataTable/components/__tests__/DataTable.real.test.tsx +251 -0
  387. package/src/components/DataTable/components/__tests__/DataTable.security.test.tsx +172 -0
  388. package/src/components/DataTable/components/__tests__/DataTable.unit.test.tsx +290 -0
  389. package/src/components/DataTable/components/__tests__/DataTableBody.unit.test.tsx +147 -0
  390. package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.unit.test.tsx +182 -0
  391. package/src/components/DataTable/components/__tests__/DataTableHeader.unit.test.tsx +143 -0
  392. package/src/components/DataTable/components/__tests__/DataTableModals.unit.test.tsx +123 -0
  393. package/src/components/DataTable/components/__tests__/EditableRow.unit.test.tsx +660 -0
  394. package/src/components/DataTable/components/__tests__/EmptyState.unit.test.tsx +256 -0
  395. package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +498 -0
  396. package/src/components/DataTable/components/__tests__/FilterRow.unit.test.tsx +112 -0
  397. package/src/components/DataTable/components/__tests__/FilteringToggle.unit.test.tsx +130 -0
  398. package/src/components/DataTable/components/__tests__/GroupHeader.unit.test.tsx +172 -0
  399. package/src/components/DataTable/components/__tests__/GroupingDropdown.unit.test.tsx +222 -0
  400. package/src/components/DataTable/components/__tests__/ImportModal.unit.test.tsx +780 -0
  401. package/src/components/DataTable/components/__tests__/LoadingState.unit.test.tsx +65 -0
  402. package/src/components/DataTable/components/__tests__/PaginationControls.unit.test.tsx +634 -0
  403. package/src/components/DataTable/components/__tests__/StateComponents.unit.test.tsx +48 -0
  404. package/src/components/DataTable/components/__tests__/UnifiedTableBody.hierarchical.test.tsx +541 -0
  405. package/src/components/DataTable/components/__tests__/ViewRowModal.unit.test.tsx +228 -0
  406. package/src/components/DataTable/components/__tests__/VirtualizedDataTable.unit.test.tsx +568 -0
  407. package/src/components/DataTable/components/index.ts +17 -0
  408. package/src/components/DataTable/context/DataTableContext.tsx +97 -0
  409. package/src/components/DataTable/core/ActionManager.ts +235 -0
  410. package/src/components/DataTable/core/ColumnFactory.ts +268 -0
  411. package/src/components/DataTable/core/ColumnManager.ts +205 -0
  412. package/src/components/DataTable/core/DataManager.ts +188 -0
  413. package/src/components/DataTable/core/DataTableContext.tsx +182 -0
  414. package/src/components/DataTable/core/LocalDataAdapter.ts +264 -0
  415. package/src/components/DataTable/core/PluginRegistry.ts +229 -0
  416. package/src/components/DataTable/core/StateManager.ts +311 -0
  417. package/src/components/DataTable/core/__tests__/ActionManager.unit.test.ts +405 -0
  418. package/src/components/DataTable/core/__tests__/ArchitectureIntegration.unit.test.tsx +445 -0
  419. package/src/components/DataTable/core/__tests__/ColumnFactory.unit.test.ts +288 -0
  420. package/src/components/DataTable/core/__tests__/ColumnManager.unit.test.ts +623 -0
  421. package/src/components/DataTable/core/__tests__/DataManager.unit.test.ts +431 -0
  422. package/src/components/DataTable/core/__tests__/DataTableContext.unit.test.tsx +433 -0
  423. package/src/components/DataTable/core/__tests__/LocalDataAdapter.unit.test.ts +422 -0
  424. package/src/components/DataTable/core/__tests__/PluginRegistry.unit.test.tsx +207 -0
  425. package/src/components/DataTable/core/__tests__/StateManager.unit.test.ts +278 -0
  426. package/src/components/DataTable/core/index.ts +8 -0
  427. package/src/components/DataTable/core/interfaces.ts +338 -0
  428. package/src/components/DataTable/examples/AutoSizingExample.tsx +180 -0
  429. package/src/components/DataTable/examples/ColumnSizingComparison.tsx +235 -0
  430. package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +418 -0
  431. package/src/components/DataTable/examples/HierarchicalExample.tsx +472 -0
  432. package/src/components/DataTable/examples/InitialPageSizeExample.tsx +173 -0
  433. package/src/components/DataTable/examples/PerformanceExample.tsx +502 -0
  434. package/src/components/DataTable/examples/__tests__/PerformanceExample.unit.test.tsx +281 -0
  435. package/src/components/DataTable/hooks/__tests__/useColumnOrderPersistence.unit.test.ts +407 -0
  436. package/src/components/DataTable/hooks/__tests__/useColumnReordering.unit.test.ts +679 -0
  437. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +95 -0
  438. package/src/components/DataTable/hooks/useColumnReordering.ts +110 -0
  439. package/src/components/DataTable/hooks/useDataTableState.ts +325 -0
  440. package/src/components/DataTable/hooks/useHierarchicalState.ts +174 -0
  441. package/src/components/DataTable/index.ts +70 -0
  442. package/src/components/DataTable/styles.ts +171 -0
  443. package/src/components/DataTable/types.ts +475 -0
  444. package/src/components/DataTable/utils/__tests__/columnSizing.test.ts +237 -0
  445. package/src/components/DataTable/utils/__tests__/debugTools.unit.test.ts +267 -0
  446. package/src/components/DataTable/utils/__tests__/errorHandling.unit.test.ts +467 -0
  447. package/src/components/DataTable/utils/__tests__/exportUtils.unit.test.ts +380 -0
  448. package/src/components/DataTable/utils/__tests__/flexibleImport.unit.test.ts +233 -0
  449. package/src/components/DataTable/utils/__tests__/performanceUtils.unit.test.ts +414 -0
  450. package/src/components/DataTable/utils/columnSizing.ts +125 -0
  451. package/src/components/DataTable/utils/debugTools.ts +583 -0
  452. package/src/components/DataTable/utils/errorHandling.ts +494 -0
  453. package/src/components/DataTable/utils/exportUtils.ts +126 -0
  454. package/src/components/DataTable/utils/flexibleImport.ts +510 -0
  455. package/src/components/DataTable/utils/hierarchicalSorting.ts +151 -0
  456. package/src/components/DataTable/utils/hierarchicalUtils.ts +218 -0
  457. package/src/components/DataTable/utils/index.ts +1 -0
  458. package/src/components/DataTable/utils/performanceUtils.ts +351 -0
  459. package/src/components/Dialog/Dialog.tsx +782 -0
  460. package/src/components/Dialog/README.md +804 -0
  461. package/src/components/Dialog/__tests__/Dialog.accessibility.test.tsx +521 -0
  462. package/src/components/Dialog/__tests__/Dialog.auto-size.example.tsx +157 -0
  463. package/src/components/Dialog/__tests__/Dialog.enhanced.test.tsx +538 -0
  464. package/src/components/Dialog/__tests__/Dialog.unit.test.tsx +1373 -0
  465. package/src/components/Dialog/examples/BasicHtmlTest.tsx +55 -0
  466. package/src/components/Dialog/examples/DebugHtmlExample.tsx +68 -0
  467. package/src/components/Dialog/examples/HtmlDialogExample.tsx +202 -0
  468. package/src/components/Dialog/examples/SimpleHtmlTest.tsx +61 -0
  469. package/src/components/Dialog/examples/SmartDialogExample.tsx +322 -0
  470. package/src/components/Dialog/examples/__tests__/SmartDialogExample.unit.test.tsx +151 -0
  471. package/src/components/Dialog/index.ts +12 -0
  472. package/src/components/Dialog/utils/__tests__/safeHtml.unit.test.ts +611 -0
  473. package/src/components/Dialog/utils/safeHtml.ts +185 -0
  474. package/src/components/ErrorBoundary/ErrorBoundary.tsx +312 -0
  475. package/src/components/ErrorBoundary/__tests__/ErrorBoundary.accessibility.test.tsx +517 -0
  476. package/src/components/ErrorBoundary/__tests__/ErrorBoundary.integration.test.tsx +572 -0
  477. package/src/components/ErrorBoundary/__tests__/ErrorBoundary.unit.test.tsx +579 -0
  478. package/src/components/ErrorBoundary/index.ts +8 -0
  479. package/src/components/EventSelector/EventSelector.tsx +360 -0
  480. package/src/components/EventSelector/__tests__/EventSelector.test.tsx +528 -0
  481. package/src/components/EventSelector/index.ts +3 -0
  482. package/src/components/EventSelector/types.ts +79 -0
  483. package/src/components/FileUpload/FileUpload.example.tsx +218 -0
  484. package/src/components/FileUpload/FileUpload.tsx +237 -0
  485. package/src/components/FileUpload/__tests__/FileUpload.integration.test.tsx +992 -0
  486. package/src/components/FileUpload/__tests__/FileUpload.real.test.tsx +927 -0
  487. package/src/components/FileUpload/__tests__/FileUpload.test.tsx +855 -0
  488. package/src/components/FileUpload/__tests__/FileUpload.unit.test.tsx +1311 -0
  489. package/src/components/FileUpload/__tests__/FileUpload.unmocked.test.tsx +937 -0
  490. package/src/components/FileUpload/index.ts +6 -0
  491. package/src/components/Footer/Footer.tsx +197 -0
  492. package/src/components/Footer/__tests__/Footer.accessibility.test.tsx +359 -0
  493. package/src/components/Footer/__tests__/Footer.integration.test.tsx +353 -0
  494. package/src/components/Footer/__tests__/Footer.performance.test.tsx +309 -0
  495. package/src/components/Footer/__tests__/Footer.unit.test.tsx +309 -0
  496. package/src/components/Footer/__tests__/Footer.visual.test.tsx +335 -0
  497. package/src/components/Footer/index.ts +17 -0
  498. package/src/components/Form/Form.tsx +166 -0
  499. package/src/components/Form/FormErrorSummary.tsx +113 -0
  500. package/src/components/Form/FormField.tsx +249 -0
  501. package/src/components/Form/FormFieldset.tsx +127 -0
  502. package/src/components/Form/FormLiveRegion.tsx +198 -0
  503. package/src/components/Form/__tests__/Form.accessibility.test.tsx +820 -0
  504. package/src/components/Form/__tests__/Form.unit.test.tsx +305 -0
  505. package/src/components/Form/__tests__/FormErrorSummary.unit.test.tsx +285 -0
  506. package/src/components/Form/__tests__/FormFieldset.unit.test.tsx +241 -0
  507. package/src/components/Form/index.ts +26 -0
  508. package/src/components/Header/Header.tsx +301 -0
  509. package/src/components/Header/__tests__/Header.accessibility.test.tsx +382 -0
  510. package/src/components/Header/__tests__/Header.comprehensive.test.tsx +509 -0
  511. package/src/components/Header/__tests__/Header.unit.test.tsx +335 -0
  512. package/src/components/Header/index.ts +4 -0
  513. package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +196 -0
  514. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +164 -0
  515. package/src/components/InactivityWarningModal/__tests__/InactivityWarningModal.unit.test.tsx +224 -0
  516. package/src/components/InactivityWarningModal/index.ts +9 -0
  517. package/src/components/Input/Input.tsx +201 -0
  518. package/src/components/Input/__mocks__/Input.tsx +2 -0
  519. package/src/components/Input/__tests__/Input.accessibility.test.tsx +632 -0
  520. package/src/components/Input/__tests__/Input.unit.test.tsx +1121 -0
  521. package/src/components/Input/index.ts +9 -0
  522. package/src/components/Label/Label.tsx +186 -0
  523. package/src/components/Label/__tests__/Label.accessibility.test.tsx +239 -0
  524. package/src/components/Label/__tests__/Label.unit.test.tsx +331 -0
  525. package/src/components/Label/index.ts +2 -0
  526. package/src/components/LoadingSpinner/LoadingSpinner.tsx +98 -0
  527. package/src/components/LoadingSpinner/__tests__/LoadingSpinner.accessibility.test.tsx +116 -0
  528. package/src/components/LoadingSpinner/__tests__/LoadingSpinner.unit.test.tsx +144 -0
  529. package/src/components/LoadingSpinner/index.ts +3 -0
  530. package/src/components/LoginForm/LoginForm.tsx +273 -0
  531. package/src/components/LoginForm/__tests__/LoginForm.accessibility.test.tsx +201 -0
  532. package/src/components/LoginForm/__tests__/LoginForm.unit.test.tsx +119 -0
  533. package/src/components/LoginForm/index.ts +3 -0
  534. package/src/components/NavigationMenu/NavigationMenu.tsx +698 -0
  535. package/src/components/NavigationMenu/__tests__/NavigationMenu.accessibility.test.tsx +378 -0
  536. package/src/components/NavigationMenu/__tests__/NavigationMenu.enhanced.test.tsx +768 -0
  537. package/src/components/NavigationMenu/__tests__/NavigationMenu.integration.test.tsx +576 -0
  538. package/src/components/NavigationMenu/__tests__/NavigationMenu.performance.test.tsx +585 -0
  539. package/src/components/NavigationMenu/__tests__/NavigationMenu.real.component.test.tsx +783 -0
  540. package/src/components/NavigationMenu/__tests__/NavigationMenu.security.enhanced.test.tsx +810 -0
  541. package/src/components/NavigationMenu/__tests__/NavigationMenu.security.test.tsx +494 -0
  542. package/src/components/NavigationMenu/__tests__/NavigationMenu.unit.test.tsx +331 -0
  543. package/src/components/NavigationMenu/__tests__/NavigationMenu.userWorkflows.test.tsx +347 -0
  544. package/src/components/NavigationMenu/__tests__/NavigationMenu.workflows.test.tsx +584 -0
  545. package/src/components/NavigationMenu/index.ts +10 -0
  546. package/src/components/NavigationMenu/types.ts +85 -0
  547. package/src/components/OrganisationSelector/OrganisationSelector.tsx +304 -0
  548. package/src/components/OrganisationSelector/__tests__/OrganisationSelector.unit.test.tsx +664 -0
  549. package/src/components/OrganisationSelector/index.ts +9 -0
  550. package/src/components/PaceAppLayout/PaceAppLayout.tsx +699 -0
  551. package/src/components/PaceAppLayout/README.md +278 -0
  552. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.accessibility.test.tsx +288 -0
  553. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +889 -0
  554. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.performance.test.tsx +629 -0
  555. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +782 -0
  556. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.unit.test.tsx +904 -0
  557. package/src/components/PaceAppLayout/index.ts +1 -0
  558. package/src/components/PaceLoginPage/PaceLoginPage.tsx +221 -0
  559. package/src/components/PaceLoginPage/__tests__/PaceLoginPage.accessibility.test.tsx +463 -0
  560. package/src/components/PaceLoginPage/__tests__/PaceLoginPage.integration.test.tsx +586 -0
  561. package/src/components/PaceLoginPage/__tests__/PaceLoginPage.unit.test.tsx +533 -0
  562. package/src/components/PaceLoginPage/index.ts +1 -0
  563. package/src/components/PasswordReset/PasswordChangeForm.tsx +186 -0
  564. package/src/components/PasswordReset/PasswordResetForm.tsx +201 -0
  565. package/src/components/PasswordReset/__tests__/PasswordChangeForm.accessibility.test.tsx +408 -0
  566. package/src/components/PasswordReset/__tests__/PasswordChangeForm.unit.test.tsx +561 -0
  567. package/src/components/PasswordReset/__tests__/PasswordReset.integration.test.tsx +304 -0
  568. package/src/components/PasswordReset/__tests__/PasswordResetForm.accessibility.test.tsx +20 -0
  569. package/src/components/PasswordReset/__tests__/PasswordResetForm.unit.test.tsx +523 -0
  570. package/src/components/PasswordReset/__tests__/__mocks__/UnifiedAuthProvider.ts +29 -0
  571. package/src/components/PasswordReset/index.ts +4 -0
  572. package/src/components/Print/__tests__/Print.comprehensive.test.tsx +331 -0
  573. package/src/components/PrintButton/PrintButton.tsx +321 -0
  574. package/src/components/PrintButton/PrintButtonGroup.tsx +84 -0
  575. package/src/components/PrintButton/PrintToolbar.tsx +94 -0
  576. package/src/components/PrintButton/__tests__/PrintButton.unit.test.tsx +429 -0
  577. package/src/components/PrintButton/__tests__/PrintButtonGroup.unit.test.tsx +277 -0
  578. package/src/components/PrintButton/__tests__/PrintToolbar.unit.test.tsx +264 -0
  579. package/src/components/PrintButton/examples/PrintButtonShowcase.tsx +438 -0
  580. package/src/components/PrintButton/index.ts +33 -0
  581. package/src/components/PrintButton/types.ts +173 -0
  582. package/src/components/PrintCard/PrintCard.tsx +154 -0
  583. package/src/components/PrintCard/PrintCardContent.tsx +57 -0
  584. package/src/components/PrintCard/PrintCardFooter.tsx +60 -0
  585. package/src/components/PrintCard/PrintCardGrid.tsx +91 -0
  586. package/src/components/PrintCard/PrintCardHeader.tsx +78 -0
  587. package/src/components/PrintCard/PrintCardImage.tsx +81 -0
  588. package/src/components/PrintCard/__tests__/PrintCard.unit.test.tsx +233 -0
  589. package/src/components/PrintCard/__tests__/PrintCardContent.test.tsx +284 -0
  590. package/src/components/PrintCard/__tests__/PrintCardGrid.unit.test.tsx +214 -0
  591. package/src/components/PrintCard/__tests__/PrintCardImage.unit.test.tsx +264 -0
  592. package/src/components/PrintCard/examples/PrintCardShowcase.tsx +239 -0
  593. package/src/components/PrintCard/index.ts +34 -0
  594. package/src/components/PrintCard/types.ts +171 -0
  595. package/src/components/PrintDataTable/PrintDataTable.tsx +215 -0
  596. package/src/components/PrintDataTable/PrintTableGroup.tsx +90 -0
  597. package/src/components/PrintDataTable/PrintTableRow.tsx +76 -0
  598. package/src/components/PrintDataTable/__tests__/PrintDataTable.unit.test.tsx +361 -0
  599. package/src/components/PrintDataTable/__tests__/PrintTableGroup.unit.test.tsx +314 -0
  600. package/src/components/PrintDataTable/__tests__/PrintTableRow.unit.test.tsx +362 -0
  601. package/src/components/PrintDataTable/index.ts +25 -0
  602. package/src/components/PrintDataTable/types.ts +67 -0
  603. package/src/components/PrintFooter/PrintFooter.tsx +183 -0
  604. package/src/components/PrintFooter/PrintFooterContent.tsx +71 -0
  605. package/src/components/PrintFooter/PrintFooterInfo.tsx +86 -0
  606. package/src/components/PrintFooter/PrintPageNumber.tsx +90 -0
  607. package/src/components/PrintFooter/__tests__/PrintFooter.unit.test.tsx +500 -0
  608. package/src/components/PrintFooter/__tests__/PrintFooterContent.unit.test.tsx +321 -0
  609. package/src/components/PrintFooter/__tests__/PrintFooterInfo.unit.test.tsx +335 -0
  610. package/src/components/PrintFooter/__tests__/PrintPageNumber.unit.test.tsx +340 -0
  611. package/src/components/PrintFooter/examples/PrintFooterShowcase.tsx +390 -0
  612. package/src/components/PrintFooter/index.ts +30 -0
  613. package/src/components/PrintFooter/types.ts +149 -0
  614. package/src/components/PrintGrid/PrintGrid.tsx +180 -0
  615. package/src/components/PrintGrid/PrintGridBreakpoint.tsx +109 -0
  616. package/src/components/PrintGrid/PrintGridContainer.tsx +128 -0
  617. package/src/components/PrintGrid/PrintGridItem.tsx +220 -0
  618. package/src/components/PrintGrid/__tests__/PrintGrid.unit.test.tsx +340 -0
  619. package/src/components/PrintGrid/__tests__/PrintGridBreakpoint.unit.test.tsx +261 -0
  620. package/src/components/PrintGrid/__tests__/PrintGridContainer.unit.test.tsx +338 -0
  621. package/src/components/PrintGrid/__tests__/PrintGridItem.unit.test.tsx +338 -0
  622. package/src/components/PrintGrid/examples/PrintGridShowcase.tsx +359 -0
  623. package/src/components/PrintGrid/index.ts +31 -0
  624. package/src/components/PrintGrid/types.ts +159 -0
  625. package/src/components/PrintHeader/PrintCoverHeader.tsx +230 -0
  626. package/src/components/PrintHeader/PrintHeader.tsx +150 -0
  627. package/src/components/PrintHeader/__tests__/PrintCoverHeader.unit.test.tsx +309 -0
  628. package/src/components/PrintHeader/__tests__/PrintHeader.unit.test.tsx +202 -0
  629. package/src/components/PrintHeader/index.ts +17 -0
  630. package/src/components/PrintHeader/types.ts +42 -0
  631. package/src/components/PrintLayout/PrintLayout.tsx +122 -0
  632. package/src/components/PrintLayout/PrintLayoutContext.tsx +66 -0
  633. package/src/components/PrintLayout/PrintPageBreak.tsx +52 -0
  634. package/src/components/PrintLayout/__tests__/PrintLayout.unit.test.tsx +238 -0
  635. package/src/components/PrintLayout/examples/PrintShowcase.tsx +230 -0
  636. package/src/components/PrintLayout/index.ts +19 -0
  637. package/src/components/PrintLayout/types.ts +37 -0
  638. package/src/components/PrintPageBreak/PrintPageBreak.tsx +120 -0
  639. package/src/components/PrintPageBreak/PrintPageBreakGroup.tsx +90 -0
  640. package/src/components/PrintPageBreak/PrintPageBreakIndicator.tsx +112 -0
  641. package/src/components/PrintPageBreak/__tests__/PrintPageBreak.unit.test.tsx +263 -0
  642. package/src/components/PrintPageBreak/__tests__/PrintPageBreakGroup.unit.test.tsx +239 -0
  643. package/src/components/PrintPageBreak/__tests__/PrintPageBreakIndicator.unit.test.tsx +235 -0
  644. package/src/components/PrintPageBreak/examples/PrintPageBreakShowcase.tsx +279 -0
  645. package/src/components/PrintPageBreak/index.ts +23 -0
  646. package/src/components/PrintPageBreak/types.ts +94 -0
  647. package/src/components/PrintSection/PrintColumn.tsx +104 -0
  648. package/src/components/PrintSection/PrintDivider.tsx +101 -0
  649. package/src/components/PrintSection/PrintSection.tsx +129 -0
  650. package/src/components/PrintSection/PrintSectionContent.tsx +75 -0
  651. package/src/components/PrintSection/PrintSectionHeader.tsx +97 -0
  652. package/src/components/PrintSection/__tests__/PrintColumn.unit.test.tsx +385 -0
  653. package/src/components/PrintSection/__tests__/PrintDivider.unit.test.tsx +373 -0
  654. package/src/components/PrintSection/__tests__/PrintSection.unit.test.tsx +390 -0
  655. package/src/components/PrintSection/__tests__/PrintSectionContent.unit.test.tsx +321 -0
  656. package/src/components/PrintSection/__tests__/PrintSectionHeader.unit.test.tsx +334 -0
  657. package/src/components/PrintSection/examples/PrintSectionShowcase.tsx +258 -0
  658. package/src/components/PrintSection/index.ts +33 -0
  659. package/src/components/PrintSection/types.ts +155 -0
  660. package/src/components/PrintText/PrintText.tsx +116 -0
  661. package/src/components/PrintText/__tests__/PrintText.unit.test.tsx +351 -0
  662. package/src/components/PrintText/index.ts +16 -0
  663. package/src/components/PrintText/types.ts +24 -0
  664. package/src/components/Progress/Progress.tsx +116 -0
  665. package/src/components/Progress/__tests__/Progress.accessibility.test.tsx +240 -0
  666. package/src/components/Progress/__tests__/Progress.unit.test.tsx +242 -0
  667. package/src/components/Progress/index.ts +3 -0
  668. package/src/components/PublicLayout/EventLogo.tsx +287 -0
  669. package/src/components/PublicLayout/PublicErrorBoundary.tsx +279 -0
  670. package/src/components/PublicLayout/PublicLoadingSpinner.tsx +208 -0
  671. package/src/components/PublicLayout/PublicPageContextChecker.tsx +130 -0
  672. package/src/components/PublicLayout/PublicPageDebugger.tsx +104 -0
  673. package/src/components/PublicLayout/PublicPageDiagnostic.tsx +162 -0
  674. package/src/components/PublicLayout/PublicPageFooter.tsx +124 -0
  675. package/src/components/PublicLayout/PublicPageHeader.tsx +178 -0
  676. package/src/components/PublicLayout/PublicPageLayout.tsx +232 -0
  677. package/src/components/PublicLayout/PublicPageProvider.tsx +137 -0
  678. package/src/components/PublicLayout/__tests__/EventLogo.test.tsx +761 -0
  679. package/src/components/PublicLayout/__tests__/PublicErrorBoundary.simplified.test.tsx +228 -0
  680. package/src/components/PublicLayout/__tests__/PublicErrorBoundary.test.tsx +228 -0
  681. package/src/components/PublicLayout/__tests__/PublicLoadingSpinner.test.tsx +459 -0
  682. package/src/components/PublicLayout/__tests__/PublicPageFooter.test.tsx +362 -0
  683. package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +522 -0
  684. package/src/components/PublicLayout/__tests__/PublicPageLayout.test.tsx +599 -0
  685. package/src/components/PublicLayout/__tests__/PublicPageProvider.test.tsx +513 -0
  686. package/src/components/PublicLayout/index.ts +51 -0
  687. package/src/components/RBAC/PagePermissionGuard.tsx +274 -0
  688. package/src/components/RBAC/RBACGuard.tsx +143 -0
  689. package/src/components/RBAC/RBACProvider.tsx +186 -0
  690. package/src/components/RBAC/RoleBasedContent.tsx +129 -0
  691. package/src/components/RBAC/__tests__/PagePermissionGuard.unit.test.tsx +674 -0
  692. package/src/components/RBAC/__tests__/RBAC.integration.test.tsx +573 -0
  693. package/src/components/RBAC/__tests__/RBACGuard.unit.test.tsx +467 -0
  694. package/src/components/RBAC/__tests__/RBACProvider.accessibility.test.tsx +475 -0
  695. package/src/components/RBAC/__tests__/RBACProvider.advanced.test.tsx +569 -0
  696. package/src/components/RBAC/__tests__/RBACProvider.integration.test.tsx +352 -0
  697. package/src/components/RBAC/__tests__/RBACProvider.unit.test.tsx +128 -0
  698. package/src/components/RBAC/__tests__/RoleBasedContent.unit.test.tsx +657 -0
  699. package/src/components/RBAC/index.ts +23 -0
  700. package/src/components/Select/Select.tsx +654 -0
  701. package/src/components/Select/__tests__/SearchableSelect.unit.test.tsx +437 -0
  702. package/src/components/Select/__tests__/Select.accessibility.test.tsx +1202 -0
  703. package/src/components/Select/__tests__/Select.actual.test.tsx +774 -0
  704. package/src/components/Select/__tests__/Select.comprehensive.test.tsx +837 -0
  705. package/src/components/Select/__tests__/Select.enhanced.test.tsx +1101 -0
  706. package/src/components/Select/__tests__/Select.integration.test.tsx +772 -0
  707. package/src/components/Select/__tests__/Select.performance.test.tsx +695 -0
  708. package/src/components/Select/__tests__/Select.real-world.test.tsx +1046 -0
  709. package/src/components/Select/__tests__/Select.search-algorithms.test.tsx +968 -0
  710. package/src/components/Select/__tests__/Select.unit.test.tsx +647 -0
  711. package/src/components/Select/__tests__/Select.utils.test.tsx +890 -0
  712. package/src/components/Select/index.ts +1 -0
  713. package/src/components/SuperAdminGuard.tsx +116 -0
  714. package/src/components/Table/Table.tsx +222 -0
  715. package/src/components/Table/__tests__/Table.accessibility.test.tsx +233 -0
  716. package/src/components/Table/__tests__/Table.unit.test.tsx +235 -0
  717. package/src/components/Table/index.ts +11 -0
  718. package/src/components/Toast/Toast.tsx +339 -0
  719. package/src/components/Toast/__tests__/Toast.accessibility.test.tsx +238 -0
  720. package/src/components/Toast/__tests__/Toast.integration.test.tsx +699 -0
  721. package/src/components/Toast/__tests__/Toast.unit.test.tsx +750 -0
  722. package/src/components/Toast/index.ts +14 -0
  723. package/src/components/Tooltip/Tooltip.tsx +167 -0
  724. package/src/components/Tooltip/__tests__/Tooltip.accessibility.test.tsx +121 -0
  725. package/src/components/Tooltip/__tests__/Tooltip.unit.test.tsx +185 -0
  726. package/src/components/Tooltip/index.ts +7 -0
  727. package/src/components/UserMenu/UserMenu.tsx +243 -0
  728. package/src/components/UserMenu/__tests__/UserMenu.accessibility.test.tsx +139 -0
  729. package/src/components/UserMenu/__tests__/UserMenu.integration.test.tsx +188 -0
  730. package/src/components/UserMenu/__tests__/UserMenu.unit.test.tsx +458 -0
  731. package/src/components/UserMenu/index.ts +3 -0
  732. package/src/components/__tests__/EdgeCaseTesting.enhanced.test.tsx +523 -0
  733. package/src/components/__tests__/ErrorTesting.enhanced.test.tsx +455 -0
  734. package/src/components/__tests__/SuperAdminGuard.test.tsx +456 -0
  735. package/src/components/__tests__/SuperAdminGuard.unit.test.tsx +456 -0
  736. package/src/components/examples/PermissionExample.tsx +150 -0
  737. package/src/components/examples/__tests__/PermissionExample.unit.test.tsx +360 -0
  738. package/src/components/index.ts +434 -0
  739. package/src/components.ts +19 -0
  740. package/src/constants/performance.ts +14 -0
  741. package/src/examples/CorrectPublicPageImplementation.tsx +301 -0
  742. package/src/examples/PublicEventPage.tsx +274 -0
  743. package/src/examples/PublicPageApp.tsx +308 -0
  744. package/src/examples/PublicPageUsageExample.tsx +216 -0
  745. package/src/fonts/georama-italic.woff2 +0 -0
  746. package/src/fonts/georama.woff2 +0 -0
  747. package/src/fonts/open-sans-italic.woff2 +0 -0
  748. package/src/fonts/open-sans.woff2 +0 -0
  749. package/src/fonts/reddit-mono.woff2 +0 -0
  750. package/src/hooks/__tests__/hooks.integration.test.tsx +575 -0
  751. package/src/hooks/__tests__/useApiFetch.unit.test.ts +115 -0
  752. package/src/hooks/__tests__/useComponentPerformance.unit.test.tsx +133 -0
  753. package/src/hooks/__tests__/useDebounce.unit.test.ts +82 -0
  754. package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +293 -0
  755. package/src/hooks/__tests__/useInactivityTracker.unit.test.ts +385 -0
  756. package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +286 -0
  757. package/src/hooks/__tests__/useOrganisationSecurity.unit.test.tsx +838 -0
  758. package/src/hooks/__tests__/usePermissionCache.unit.test.ts +627 -0
  759. package/src/hooks/__tests__/useRBAC.unit.test.ts +903 -0
  760. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +537 -0
  761. package/src/hooks/__tests__/useToast.unit.test.tsx +62 -0
  762. package/src/hooks/__tests__/useZodForm.unit.test.tsx +37 -0
  763. package/src/hooks/index.ts +56 -0
  764. package/src/hooks/public/__tests__/usePublicEvent.test.tsx +397 -0
  765. package/src/hooks/public/__tests__/usePublicEventLogo.test.tsx +690 -0
  766. package/src/hooks/public/__tests__/usePublicRouteParams.test.tsx +449 -0
  767. package/src/hooks/public/index.ts +34 -0
  768. package/src/hooks/public/usePublicEvent.ts +261 -0
  769. package/src/hooks/public/usePublicEventLogo.ts +285 -0
  770. package/src/hooks/public/usePublicRouteParams.ts +259 -0
  771. package/src/hooks/useAppConfig.ts +94 -0
  772. package/src/hooks/useComponentPerformance.ts +39 -0
  773. package/src/hooks/useDataTablePerformance.ts +387 -0
  774. package/src/hooks/useDataTableState.ts +110 -0
  775. package/src/hooks/useDebounce.ts +18 -0
  776. package/src/hooks/useFocusManagement.ts +161 -0
  777. package/src/hooks/useFocusTrap.ts +155 -0
  778. package/src/hooks/useInactivityTracker.ts +372 -0
  779. package/src/hooks/useIsMobile.ts +42 -0
  780. package/src/hooks/useKeyboardShortcuts.ts +237 -0
  781. package/src/hooks/useOrganisationPermissions.ts +208 -0
  782. package/src/hooks/useOrganisationSecurity.ts +262 -0
  783. package/src/hooks/usePerformanceMonitor.ts +128 -0
  784. package/src/hooks/usePermissionCache.ts +455 -0
  785. package/src/hooks/useRBAC.ts +262 -0
  786. package/src/hooks/useSecureDataAccess.ts +586 -0
  787. package/src/hooks/useStorage.ts +274 -0
  788. package/src/hooks/useToast.ts +242 -0
  789. package/src/hooks/useZodForm.ts +28 -0
  790. package/src/index.ts +200 -0
  791. package/src/providers/AuthProvider.tsx +369 -0
  792. package/src/providers/EventProvider.tsx +324 -0
  793. package/src/providers/InactivityProvider.tsx +238 -0
  794. package/src/providers/OrganisationProvider.tsx +588 -0
  795. package/src/providers/RBACProvider.tsx +622 -0
  796. package/src/providers/UnifiedAuthProvider.tsx +327 -0
  797. package/src/providers/__tests__/EventProvider.unit.test.tsx +768 -0
  798. package/src/providers/__tests__/OrganisationProvider.basic.test.tsx +116 -0
  799. package/src/providers/__tests__/OrganisationProvider.unit.test.tsx +1312 -0
  800. package/src/providers/__tests__/UnifiedAuthProvider.inactivity.test.tsx +601 -0
  801. package/src/providers/__tests__/UnifiedAuthProvider.unit.test.tsx +675 -0
  802. package/src/providers/__tests__/index.unit.test.ts +78 -0
  803. package/src/providers/index.ts +15 -0
  804. package/src/rbac/README.md +885 -0
  805. package/src/rbac/__tests__/PagePermissionGuard.test.tsx +673 -0
  806. package/src/rbac/__tests__/README.md +170 -0
  807. package/src/rbac/__tests__/RoleBasedRouter.test.tsx +709 -0
  808. package/src/rbac/__tests__/TestContext.tsx +72 -0
  809. package/src/rbac/__tests__/__mocks__/cache.ts +144 -0
  810. package/src/rbac/__tests__/__mocks__/supabase.ts +152 -0
  811. package/src/rbac/__tests__/adapters-hooks-comprehensive.test.tsx +782 -0
  812. package/src/rbac/__tests__/adapters-hooks.test.tsx +561 -0
  813. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +963 -0
  814. package/src/rbac/__tests__/adapters.test.tsx +444 -0
  815. package/src/rbac/__tests__/api.test.ts +620 -0
  816. package/src/rbac/__tests__/audit-observability-comprehensive.test.ts +792 -0
  817. package/src/rbac/__tests__/audit-observability.test.ts +549 -0
  818. package/src/rbac/__tests__/audit.test.ts +616 -0
  819. package/src/rbac/__tests__/build-contract-compliance-simple.test.ts +230 -0
  820. package/src/rbac/__tests__/cache-invalidation-comprehensive.test.ts +889 -0
  821. package/src/rbac/__tests__/cache-invalidation.test.ts +457 -0
  822. package/src/rbac/__tests__/cache.test.ts +458 -0
  823. package/src/rbac/__tests__/components-navigation-guard.enhanced.test.tsx +859 -0
  824. package/src/rbac/__tests__/components-navigation-guard.test.tsx +895 -0
  825. package/src/rbac/__tests__/components-navigation-provider.test.tsx +692 -0
  826. package/src/rbac/__tests__/components-page-permission-guard.test.tsx +673 -0
  827. package/src/rbac/__tests__/components-page-permission-provider.test.tsx +614 -0
  828. package/src/rbac/__tests__/components-permission-enforcer.enhanced.fixed.test.tsx +836 -0
  829. package/src/rbac/__tests__/components-permission-enforcer.enhanced.test.tsx +837 -0
  830. package/src/rbac/__tests__/components-permission-enforcer.test.tsx +825 -0
  831. package/src/rbac/__tests__/components-role-based-router.test.tsx +709 -0
  832. package/src/rbac/__tests__/components-secure-data-provider.test.tsx +607 -0
  833. package/src/rbac/__tests__/config.test.ts +583 -0
  834. package/src/rbac/__tests__/core-logic-unit.test.ts +190 -0
  835. package/src/rbac/__tests__/core-permission-logic-comprehensive.test.ts +1467 -0
  836. package/src/rbac/__tests__/core-permission-logic-fixed.test.ts +151 -0
  837. package/src/rbac/__tests__/core-permission-logic-simple.test.ts +968 -0
  838. package/src/rbac/__tests__/core-permission-logic.test.ts +966 -0
  839. package/src/rbac/__tests__/edge-cases-comprehensive.test.ts +988 -0
  840. package/src/rbac/__tests__/edge-cases.test.ts +654 -0
  841. package/src/rbac/__tests__/engine.test.ts +361 -0
  842. package/src/rbac/__tests__/engine.unit.test.ts +361 -0
  843. package/src/rbac/__tests__/hooks.enhanced.test.tsx +979 -0
  844. package/src/rbac/__tests__/hooks.fixed.test.tsx +475 -0
  845. package/src/rbac/__tests__/hooks.test.tsx +385 -0
  846. package/src/rbac/__tests__/index.test.ts +269 -0
  847. package/src/rbac/__tests__/integration.enhanced.test.tsx +824 -0
  848. package/src/rbac/__tests__/page-permission-guard-super-admin.test.tsx +261 -0
  849. package/src/rbac/__tests__/performance.enhanced.test.tsx +724 -0
  850. package/src/rbac/__tests__/permissions.test.ts +383 -0
  851. package/src/rbac/__tests__/requires-event.test.ts +330 -0
  852. package/src/rbac/__tests__/scope-isolation-comprehensive.test.ts +1349 -0
  853. package/src/rbac/__tests__/scope-isolation.test.ts +755 -0
  854. package/src/rbac/__tests__/secure-client-rls-comprehensive.test.ts +592 -0
  855. package/src/rbac/__tests__/secure-client-rls.test.ts +377 -0
  856. package/src/rbac/__tests__/security.test.ts +296 -0
  857. package/src/rbac/__tests__/setup.ts +228 -0
  858. package/src/rbac/__tests__/test-utils-enhanced.tsx +400 -0
  859. package/src/rbac/__tests__/types.test.ts +685 -0
  860. package/src/rbac/adapters.tsx +726 -0
  861. package/src/rbac/api.ts +337 -0
  862. package/src/rbac/audit-enhanced.ts +339 -0
  863. package/src/rbac/audit.ts +338 -0
  864. package/src/rbac/cache.ts +213 -0
  865. package/src/rbac/components/EnhancedNavigationMenu.tsx +294 -0
  866. package/src/rbac/components/NavigationGuard.tsx +294 -0
  867. package/src/rbac/components/NavigationProvider.tsx +314 -0
  868. package/src/rbac/components/PagePermissionGuard.tsx +430 -0
  869. package/src/rbac/components/PagePermissionProvider.tsx +274 -0
  870. package/src/rbac/components/PermissionEnforcer.tsx +307 -0
  871. package/src/rbac/components/RoleBasedRouter.tsx +425 -0
  872. package/src/rbac/components/SecureDataProvider.tsx +319 -0
  873. package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +631 -0
  874. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +667 -0
  875. package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +647 -0
  876. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +496 -0
  877. package/src/rbac/components/index.ts +64 -0
  878. package/src/rbac/config.ts +133 -0
  879. package/src/rbac/docs/event-based-apps.md +285 -0
  880. package/src/rbac/engine.ts +1026 -0
  881. package/src/rbac/eslint-rules.js +285 -0
  882. package/src/rbac/examples/CompleteRBACExample.tsx +323 -0
  883. package/src/rbac/examples/EventBasedApp.tsx +238 -0
  884. package/src/rbac/hooks.ts +555 -0
  885. package/src/rbac/index.ts +114 -0
  886. package/src/rbac/permissions.ts +293 -0
  887. package/src/rbac/secureClient.ts +244 -0
  888. package/src/rbac/security.ts +346 -0
  889. package/src/rbac/testing/__tests__/index.test.tsx +342 -0
  890. package/src/rbac/testing/index.tsx +340 -0
  891. package/src/rbac/types.ts +341 -0
  892. package/src/rbac/utils/__tests__/eventContext.test.ts +428 -0
  893. package/src/rbac/utils/__tests__/eventContext.unit.test.ts +428 -0
  894. package/src/rbac/utils/eventContext.ts +83 -0
  895. package/src/styles/__tests__/styles.unit.test.ts +164 -0
  896. package/src/styles/core.css +401 -0
  897. package/src/styles/index.ts +51 -0
  898. package/src/test-dom-cleanup.test.tsx +38 -0
  899. package/src/theming/__tests__/README.md +335 -0
  900. package/src/theming/__tests__/runtime.accessibility.test.ts +474 -0
  901. package/src/theming/__tests__/runtime.error.test.ts +616 -0
  902. package/src/theming/__tests__/runtime.integration.test.ts +376 -0
  903. package/src/theming/__tests__/runtime.performance.test.ts +411 -0
  904. package/src/theming/__tests__/runtime.unit.test.ts +470 -0
  905. package/src/theming/runtime.ts +187 -0
  906. package/src/types/__tests__/database.unit.test.ts +489 -0
  907. package/src/types/__tests__/guards.unit.test.ts +146 -0
  908. package/src/types/__tests__/index.unit.test.ts +77 -0
  909. package/src/types/__tests__/organisation.unit.test.ts +713 -0
  910. package/src/types/__tests__/rbac.unit.test.ts +621 -0
  911. package/src/types/__tests__/security.unit.test.ts +347 -0
  912. package/src/types/__tests__/supabase.unit.test.ts +658 -0
  913. package/src/types/__tests__/theme.unit.test.ts +218 -0
  914. package/src/types/__tests__/unified.unit.test.ts +537 -0
  915. package/src/types/__tests__/validation.unit.test.ts +616 -0
  916. package/src/types/database.ts +472 -0
  917. package/src/types/guards.ts +30 -0
  918. package/src/types/index.ts +25 -0
  919. package/src/types/organisation.ts +184 -0
  920. package/src/types/security.ts +70 -0
  921. package/src/types/supabase.ts +166 -0
  922. package/src/types/theme.ts +6 -0
  923. package/src/types/unified.ts +262 -0
  924. package/src/types/validation.ts +164 -0
  925. package/src/types/vitest-globals.d.ts +43 -0
  926. package/src/utils/__mocks__/supabaseMock.ts +75 -0
  927. package/src/utils/__mocks__/supabaseMock.tsx +198 -0
  928. package/src/utils/__tests__/appConfig.unit.test.ts +55 -0
  929. package/src/utils/__tests__/appNameResolver.unit.test.ts +137 -0
  930. package/src/utils/__tests__/audit.unit.test.ts +69 -0
  931. package/src/utils/__tests__/auth-utils.unit.test.ts +70 -0
  932. package/src/utils/__tests__/bundleAnalysis.unit.test.ts +317 -0
  933. package/src/utils/__tests__/cn.unit.test.ts +34 -0
  934. package/src/utils/__tests__/deviceFingerprint.unit.test.ts +480 -0
  935. package/src/utils/__tests__/dynamicUtils.unit.test.ts +322 -0
  936. package/src/utils/__tests__/formatDate.unit.test.ts +109 -0
  937. package/src/utils/__tests__/formatting.unit.test.ts +66 -0
  938. package/src/utils/__tests__/index.unit.test.ts +251 -0
  939. package/src/utils/__tests__/lazyLoad.unit.test.tsx +309 -0
  940. package/src/utils/__tests__/organisationContext.unit.test.ts +192 -0
  941. package/src/utils/__tests__/performanceBudgets.unit.test.ts +259 -0
  942. package/src/utils/__tests__/permissionTypes.unit.test.ts +250 -0
  943. package/src/utils/__tests__/permissionUtils.unit.test.ts +362 -0
  944. package/src/utils/__tests__/sanitization.unit.test.ts +346 -0
  945. package/src/utils/__tests__/schemaUtils.unit.test.ts +441 -0
  946. package/src/utils/__tests__/secureDataAccess.unit.test.ts +334 -0
  947. package/src/utils/__tests__/secureErrors.unit.test.ts +377 -0
  948. package/src/utils/__tests__/secureStorage.unit.test.ts +293 -0
  949. package/src/utils/__tests__/security.unit.test.ts +127 -0
  950. package/src/utils/__tests__/securityMonitor.unit.test.ts +280 -0
  951. package/src/utils/__tests__/sessionTracking.unit.test.ts +370 -0
  952. package/src/utils/__tests__/validation.unit.test.ts +84 -0
  953. package/src/utils/__tests__/validationUtils.unit.test.ts +571 -0
  954. package/src/utils/appConfig.ts +47 -0
  955. package/src/utils/appIdResolver.ts +130 -0
  956. package/src/utils/appNameResolver.ts +190 -0
  957. package/src/utils/audit.ts +127 -0
  958. package/src/utils/auth-utils.ts +96 -0
  959. package/src/utils/bundleAnalysis.ts +129 -0
  960. package/src/utils/cn.ts +7 -0
  961. package/src/utils/debugLogger.ts +46 -0
  962. package/src/utils/deviceFingerprint.ts +215 -0
  963. package/src/utils/dynamicUtils.ts +105 -0
  964. package/src/utils/formatting.ts +77 -0
  965. package/src/utils/index.ts +145 -0
  966. package/src/utils/lazyLoad.tsx +44 -0
  967. package/src/utils/organisationContext.ts +135 -0
  968. package/src/utils/performanceBenchmark.ts +64 -0
  969. package/src/utils/performanceBudgets.ts +111 -0
  970. package/src/utils/permissionTypes.ts +37 -0
  971. package/src/utils/permissionUtils.ts +31 -0
  972. package/src/utils/print/PrintDataProcessor.ts +390 -0
  973. package/src/utils/print/__tests__/PrintDataProcessor.unit.test.ts +219 -0
  974. package/src/utils/print/__tests__/usePrintOptimization.unit.test.tsx +353 -0
  975. package/src/utils/print/examples/PrintUtilitiesShowcase.tsx +397 -0
  976. package/src/utils/print/index.ts +29 -0
  977. package/src/utils/print/types.ts +196 -0
  978. package/src/utils/print/usePrintOptimization.ts +272 -0
  979. package/src/utils/sanitization.ts +264 -0
  980. package/src/utils/schemaUtils.ts +37 -0
  981. package/src/utils/secureDataAccess.ts +361 -0
  982. package/src/utils/secureErrors.ts +79 -0
  983. package/src/utils/secureStorage.ts +244 -0
  984. package/src/utils/security.ts +156 -0
  985. package/src/utils/securityMonitor.ts +45 -0
  986. package/src/utils/sessionTracking.ts +170 -0
  987. package/src/utils/storage/README.md +348 -0
  988. package/src/utils/storage/__tests__/config.unit.test.ts +206 -0
  989. package/src/utils/storage/__tests__/helpers.unit.test.ts +646 -0
  990. package/src/utils/storage/__tests__/index.unit.test.ts +167 -0
  991. package/src/utils/storage/__tests__/types.unit.test.ts +441 -0
  992. package/src/utils/storage/config.ts +100 -0
  993. package/src/utils/storage/helpers.ts +359 -0
  994. package/src/utils/storage/index.ts +36 -0
  995. package/src/utils/storage/types.ts +90 -0
  996. package/src/utils/validation.ts +111 -0
  997. package/src/utils/validationUtils.ts +120 -0
  998. package/src/validation/__tests__/common.unit.test.ts +101 -0
  999. package/src/validation/__tests__/csrf.unit.test.ts +302 -0
  1000. package/src/validation/__tests__/passwordSchema.unit.test.ts +98 -0
  1001. package/src/validation/__tests__/sqlInjectionProtection.unit.test.ts +466 -0
  1002. package/src/validation/common.ts +53 -0
  1003. package/src/validation/csrf.ts +214 -0
  1004. package/src/validation/index.ts +43 -0
  1005. package/src/validation/passwordSchema.ts +125 -0
  1006. package/src/validation/sanitization.ts +96 -0
  1007. package/src/validation/schemaUtils.ts +42 -0
  1008. package/src/validation/sqlInjectionProtection.ts +242 -0
  1009. package/src/validation/user.ts +34 -0
@@ -0,0 +1,2212 @@
1
+ import {
2
+ CACHE_PATTERNS,
3
+ OrganisationContextRequiredError,
4
+ RBACCache,
5
+ RBACEngine,
6
+ createRBACConfig,
7
+ createRBACEngine,
8
+ getAccessLevel,
9
+ getPermissionMap,
10
+ getRBACConfig,
11
+ getRBACLogger,
12
+ hasAllPermissions,
13
+ hasAnyPermission,
14
+ hasPermission,
15
+ isDebugMode,
16
+ isDevelopmentMode,
17
+ isPermitted,
18
+ isPermittedCached,
19
+ rbacCache,
20
+ setupRBAC
21
+ } from "../chunk-6ZQVSHKL.js";
22
+ import {
23
+ RBACAuditManager,
24
+ createAuditManager,
25
+ emitAuditEvent,
26
+ getGlobalAuditManager,
27
+ setGlobalAuditManager
28
+ } from "../chunk-7BNPOCLL.js";
29
+ import {
30
+ useSecureDataAccess
31
+ } from "../chunk-PFRRIDYA.js";
32
+ import {
33
+ init_UnifiedAuthProvider,
34
+ useUnifiedAuth
35
+ } from "../chunk-DY5E3AT7.js";
36
+ import "../chunk-ETEJVKYK.js";
37
+ import "../chunk-YDJW5XTN.js";
38
+ import {
39
+ getCurrentAppName,
40
+ init_appNameResolver
41
+ } from "../chunk-MZBUOP4P.js";
42
+ import "../chunk-2V3Y6YBC.js";
43
+ import "../chunk-OHXGNT3K.js";
44
+ import "../chunk-PLDDJCW6.js";
45
+
46
+ // src/rbac/secureClient.ts
47
+ import { createClient } from "@supabase/supabase-js";
48
+ var SecureSupabaseClient = class _SecureSupabaseClient {
49
+ constructor(supabaseUrl, supabaseKey, organisationId, eventId, appId) {
50
+ this.supabaseUrl = supabaseUrl;
51
+ this.supabaseKey = supabaseKey;
52
+ this.organisationId = organisationId;
53
+ this.eventId = eventId;
54
+ this.appId = appId;
55
+ this.supabase = createClient(supabaseUrl, supabaseKey, {
56
+ global: {
57
+ headers: {
58
+ "x-organisation-id": organisationId,
59
+ "x-event-id": eventId || "",
60
+ "x-app-id": appId || ""
61
+ }
62
+ }
63
+ });
64
+ this.setupContextInjection();
65
+ }
66
+ /**
67
+ * Setup context injection for all database operations
68
+ */
69
+ setupContextInjection() {
70
+ const originalFrom = this.supabase.from.bind(this.supabase);
71
+ this.supabase.from = (table) => {
72
+ this.validateContext();
73
+ const query = originalFrom(table);
74
+ return this.injectContext(query);
75
+ };
76
+ const originalRpc = this.supabase.rpc.bind(this.supabase);
77
+ this.supabase.rpc = (fn, args) => {
78
+ this.validateContext();
79
+ const contextArgs = {
80
+ ...args,
81
+ p_organisation_id: this.organisationId,
82
+ p_event_id: this.eventId,
83
+ p_app_id: this.appId
84
+ };
85
+ return originalRpc(fn, contextArgs);
86
+ };
87
+ }
88
+ /**
89
+ * Inject organisation context into a query
90
+ */
91
+ injectContext(query) {
92
+ const originalSelect = query.select.bind(query);
93
+ const originalInsert = query.insert.bind(query);
94
+ const originalUpdate = query.update.bind(query);
95
+ const originalDelete = query.delete.bind(query);
96
+ query.select = (columns) => {
97
+ const result = originalSelect(columns);
98
+ return this.addOrganisationFilter(result);
99
+ };
100
+ query.insert = (values) => {
101
+ const contextValues = Array.isArray(values) ? values.map((v) => ({ ...v, organisation_id: this.organisationId })) : { ...values, organisation_id: this.organisationId };
102
+ return originalInsert(contextValues);
103
+ };
104
+ query.update = (values) => {
105
+ const result = originalUpdate(values);
106
+ return this.addOrganisationFilter(result);
107
+ };
108
+ query.delete = () => {
109
+ const result = originalDelete();
110
+ return this.addOrganisationFilter(result);
111
+ };
112
+ return query;
113
+ }
114
+ /**
115
+ * Add organisation filter to a query
116
+ */
117
+ addOrganisationFilter(query) {
118
+ return query.eq("organisation_id", this.organisationId);
119
+ }
120
+ /**
121
+ * Validate that required context is present
122
+ */
123
+ validateContext() {
124
+ if (!this.organisationId) {
125
+ throw new OrganisationContextRequiredError();
126
+ }
127
+ }
128
+ /**
129
+ * Get the current organisation ID
130
+ */
131
+ getOrganisationId() {
132
+ return this.organisationId;
133
+ }
134
+ /**
135
+ * Get the current event ID
136
+ */
137
+ getEventId() {
138
+ return this.eventId;
139
+ }
140
+ /**
141
+ * Get the current app ID
142
+ */
143
+ getAppId() {
144
+ return this.appId;
145
+ }
146
+ /**
147
+ * Create a new client with updated context
148
+ */
149
+ withContext(updates) {
150
+ return new _SecureSupabaseClient(
151
+ this.supabaseUrl,
152
+ this.supabaseKey,
153
+ updates.organisationId || this.organisationId,
154
+ updates.eventId !== void 0 ? updates.eventId : this.eventId,
155
+ updates.appId !== void 0 ? updates.appId : this.appId
156
+ );
157
+ }
158
+ /**
159
+ * Get the underlying Supabase client (for internal use only)
160
+ * @internal
161
+ */
162
+ getClient() {
163
+ return this.supabase;
164
+ }
165
+ };
166
+ function createSecureClient(supabaseUrl, supabaseKey, organisationId, eventId, appId) {
167
+ return new SecureSupabaseClient(supabaseUrl, supabaseKey, organisationId, eventId, appId);
168
+ }
169
+ function fromSupabaseClient(client, organisationId, eventId, appId) {
170
+ throw new Error("fromSupabaseClient is not supported. Use createSecureClient instead.");
171
+ }
172
+
173
+ // src/rbac/hooks.ts
174
+ import { useState, useEffect, useCallback, useMemo } from "react";
175
+ function usePermissions(userId, scope) {
176
+ const [permissions, setPermissions] = useState({});
177
+ const [isLoading, setIsLoading] = useState(true);
178
+ const [error, setError] = useState(null);
179
+ const fetchPermissions = useCallback(async () => {
180
+ if (!userId) {
181
+ setPermissions({});
182
+ setIsLoading(false);
183
+ return;
184
+ }
185
+ try {
186
+ setIsLoading(true);
187
+ setError(null);
188
+ const result = await getPermissionMap({ userId, scope });
189
+ setPermissions(result);
190
+ } catch (err) {
191
+ setError(err instanceof Error ? err : new Error("Failed to fetch permissions"));
192
+ } finally {
193
+ setIsLoading(false);
194
+ }
195
+ }, [userId, scope.organisationId, scope.eventId, scope.appId]);
196
+ useEffect(() => {
197
+ fetchPermissions();
198
+ }, [fetchPermissions]);
199
+ return {
200
+ permissions,
201
+ isLoading,
202
+ error,
203
+ refetch: fetchPermissions
204
+ };
205
+ }
206
+ function useCan(userId, scope, permission, pageId, useCache = true) {
207
+ const [can, setCan] = useState(false);
208
+ const [isLoading, setIsLoading] = useState(true);
209
+ const [error, setError] = useState(null);
210
+ const check = useCallback(async () => {
211
+ console.log("[useCan] check() called with:", { userId, scope, permission, pageId });
212
+ console.log("[useCan] Hook parameters:", { userId, scope, permission, pageId, useCache });
213
+ if (!userId) {
214
+ console.log("[useCan] No userId, denying access");
215
+ setCan(false);
216
+ setIsLoading(false);
217
+ return;
218
+ }
219
+ if (!scope || !scope.organisationId || !scope.appId) {
220
+ console.log("[useCan] Incomplete scope, waiting for resolution:", scope);
221
+ setCan(false);
222
+ setIsLoading(true);
223
+ return;
224
+ }
225
+ console.log("[useCan] Scope is complete, checking permission...");
226
+ console.log("[useCan] Detailed scope info:", {
227
+ organisationId: scope.organisationId,
228
+ eventId: scope.eventId,
229
+ appId: scope.appId,
230
+ permission,
231
+ pageId
232
+ });
233
+ try {
234
+ setIsLoading(true);
235
+ setError(null);
236
+ console.log("[useCan] About to call isPermitted/isPermittedCached...");
237
+ const result = useCache ? await isPermittedCached({ userId, scope, permission, pageId }) : await isPermitted({ userId, scope, permission, pageId });
238
+ console.log("[useCan] Permission check result:", result);
239
+ console.log("[useCan] Permission check details:", {
240
+ userId,
241
+ scope,
242
+ permission,
243
+ pageId,
244
+ result,
245
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
246
+ });
247
+ setCan(result);
248
+ } catch (err) {
249
+ console.error("[useCan] Permission check error:", err);
250
+ console.error("[useCan] Error details:", {
251
+ userId,
252
+ scope,
253
+ permission,
254
+ pageId,
255
+ error: err instanceof Error ? err.message : "Unknown error",
256
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
257
+ });
258
+ setError(err instanceof Error ? err : new Error("Failed to check permission"));
259
+ setCan(false);
260
+ } finally {
261
+ setIsLoading(false);
262
+ }
263
+ }, [userId, scope.organisationId, scope.eventId, scope.appId, permission, pageId, useCache]);
264
+ useEffect(() => {
265
+ check();
266
+ }, [check]);
267
+ return {
268
+ can,
269
+ isLoading,
270
+ error,
271
+ check
272
+ };
273
+ }
274
+ function useAccessLevel(userId, scope) {
275
+ const [accessLevel, setAccessLevel] = useState(null);
276
+ const [isLoading, setIsLoading] = useState(true);
277
+ const [error, setError] = useState(null);
278
+ const fetchAccessLevel = useCallback(async () => {
279
+ if (!userId) {
280
+ setAccessLevel(null);
281
+ setIsLoading(false);
282
+ return;
283
+ }
284
+ try {
285
+ setIsLoading(true);
286
+ setError(null);
287
+ const result = await getAccessLevel({ userId, scope });
288
+ setAccessLevel(result);
289
+ } catch (err) {
290
+ setError(err instanceof Error ? err : new Error("Failed to fetch access level"));
291
+ setAccessLevel(null);
292
+ } finally {
293
+ setIsLoading(false);
294
+ }
295
+ }, [userId, scope.organisationId, scope.eventId, scope.appId]);
296
+ useEffect(() => {
297
+ fetchAccessLevel();
298
+ }, [fetchAccessLevel]);
299
+ return {
300
+ accessLevel,
301
+ isLoading,
302
+ error,
303
+ refetch: fetchAccessLevel
304
+ };
305
+ }
306
+ function useMultiplePermissions(userId, scope, permissions, pageId, useCache = true) {
307
+ const [permissionResults, setPermissionResults] = useState({});
308
+ const [isLoading, setIsLoading] = useState(true);
309
+ const [error, setError] = useState(null);
310
+ const fetchPermissions = useCallback(async () => {
311
+ if (!userId || permissions.length === 0) {
312
+ setPermissionResults({});
313
+ setIsLoading(false);
314
+ return;
315
+ }
316
+ try {
317
+ setIsLoading(true);
318
+ setError(null);
319
+ const results = {};
320
+ const promises = permissions.map(async (permission) => {
321
+ const result = useCache ? await isPermittedCached({ userId, scope, permission, pageId }) : await isPermitted({ userId, scope, permission, pageId });
322
+ return { permission, result };
323
+ });
324
+ const resolved = await Promise.all(promises);
325
+ resolved.forEach(({ permission, result }) => {
326
+ results[permission] = result;
327
+ });
328
+ setPermissionResults(results);
329
+ } catch (err) {
330
+ setError(err instanceof Error ? err : new Error("Failed to check permissions"));
331
+ setPermissionResults({});
332
+ } finally {
333
+ setIsLoading(false);
334
+ }
335
+ }, [userId, scope.organisationId, scope.eventId, scope.appId, permissions, pageId, useCache]);
336
+ useEffect(() => {
337
+ fetchPermissions();
338
+ }, [fetchPermissions]);
339
+ return {
340
+ permissions: permissionResults,
341
+ isLoading,
342
+ error,
343
+ refetch: fetchPermissions
344
+ };
345
+ }
346
+ function useHasAnyPermission(userId, scope, permissions, pageId) {
347
+ const { permissions: permissionResults, isLoading, error, refetch } = useMultiplePermissions(
348
+ userId,
349
+ scope,
350
+ permissions,
351
+ pageId
352
+ );
353
+ const hasAny = useMemo(() => {
354
+ return Object.values(permissionResults).some(Boolean);
355
+ }, [permissionResults]);
356
+ return {
357
+ hasAny,
358
+ isLoading,
359
+ error,
360
+ refetch
361
+ };
362
+ }
363
+ function useHasAllPermissions(userId, scope, permissions, pageId) {
364
+ const { permissions: permissionResults, isLoading, error, refetch } = useMultiplePermissions(
365
+ userId,
366
+ scope,
367
+ permissions,
368
+ pageId
369
+ );
370
+ const hasAll = useMemo(() => {
371
+ return Object.values(permissionResults).every(Boolean);
372
+ }, [permissionResults]);
373
+ return {
374
+ hasAll,
375
+ isLoading,
376
+ error,
377
+ refetch
378
+ };
379
+ }
380
+ function useCachedPermissions(userId, scope) {
381
+ const [permissions, setPermissions] = useState({});
382
+ const [isLoading, setIsLoading] = useState(true);
383
+ const [error, setError] = useState(null);
384
+ const fetchCachedPermissions = useCallback(async () => {
385
+ if (!userId) {
386
+ setPermissions({});
387
+ setIsLoading(false);
388
+ return;
389
+ }
390
+ try {
391
+ setIsLoading(true);
392
+ setError(null);
393
+ const result = await getPermissionMap({ userId, scope });
394
+ setPermissions(result);
395
+ } catch (err) {
396
+ setError(err instanceof Error ? err : new Error("Failed to fetch cached permissions"));
397
+ } finally {
398
+ setIsLoading(false);
399
+ }
400
+ }, [userId, scope.organisationId, scope.eventId, scope.appId]);
401
+ useEffect(() => {
402
+ fetchCachedPermissions();
403
+ }, [fetchCachedPermissions]);
404
+ return {
405
+ permissions,
406
+ isLoading,
407
+ error,
408
+ refetch: fetchCachedPermissions
409
+ };
410
+ }
411
+
412
+ // src/rbac/adapters.tsx
413
+ import React, { useContext } from "react";
414
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
415
+ function PermissionGuard({
416
+ userId,
417
+ scope,
418
+ permission,
419
+ pageId,
420
+ children,
421
+ fallback = null,
422
+ onDenied,
423
+ loading = null,
424
+ // NEW: Phase 1 - Enhanced Security Features
425
+ strictMode = true,
426
+ auditLog = true,
427
+ enforceAudit = true
428
+ }) {
429
+ const logger = getRBACLogger();
430
+ const authContext = useContext(React.createContext(null));
431
+ let effectiveUserId = userId;
432
+ if (!effectiveUserId) {
433
+ try {
434
+ if (authContext?.user?.id) {
435
+ effectiveUserId = authContext.user.id;
436
+ } else {
437
+ const globalUser = window.__PACE_USER__;
438
+ if (globalUser?.id) {
439
+ effectiveUserId = globalUser.id;
440
+ }
441
+ }
442
+ } catch (error2) {
443
+ logger.debug("Could not infer userId from context:", error2);
444
+ }
445
+ }
446
+ const { can, isLoading, error } = useCan(effectiveUserId || "", scope, permission, pageId);
447
+ if (!effectiveUserId) {
448
+ logger.error("PermissionGuard: No userId provided and could not infer from context");
449
+ return /* @__PURE__ */ jsxs("div", { className: "rbac-error", role: "alert", children: [
450
+ /* @__PURE__ */ jsx("p", { children: "Permission check failed: User context not available" }),
451
+ /* @__PURE__ */ jsxs("details", { children: [
452
+ /* @__PURE__ */ jsx("summary", { children: "Debug info" }),
453
+ /* @__PURE__ */ jsx("p", { children: "Make sure to either:" }),
454
+ /* @__PURE__ */ jsxs("ul", { children: [
455
+ /* @__PURE__ */ jsx("li", { children: "Pass userId prop explicitly" }),
456
+ /* @__PURE__ */ jsx("li", { children: "Wrap your app with an auth provider" }),
457
+ /* @__PURE__ */ jsx("li", { children: "Set window.__PACE_USER__ with user data" })
458
+ ] })
459
+ ] })
460
+ ] });
461
+ }
462
+ if (isLoading) {
463
+ return loading || /* @__PURE__ */ jsx("div", { className: "rbac-loading", role: "status", "aria-live": "polite", children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Checking permissions..." }) });
464
+ }
465
+ if (error) {
466
+ logger.error("Permission check failed:", error);
467
+ if (auditLog) {
468
+ logger.info(`[PermissionGuard] Permission check failed:`, {
469
+ userId: effectiveUserId,
470
+ scope,
471
+ permission,
472
+ pageId,
473
+ error: error.message,
474
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
475
+ });
476
+ }
477
+ return fallback;
478
+ }
479
+ if (!can) {
480
+ if (auditLog) {
481
+ logger.info(`[PermissionGuard] Permission denied:`, {
482
+ userId: effectiveUserId,
483
+ scope,
484
+ permission,
485
+ pageId,
486
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
487
+ });
488
+ }
489
+ if (strictMode) {
490
+ logger.error(`[PermissionGuard] STRICT MODE VIOLATION: User attempted to access protected resource without permission`, {
491
+ userId: effectiveUserId,
492
+ scope,
493
+ permission,
494
+ pageId,
495
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
496
+ });
497
+ }
498
+ if (onDenied) {
499
+ onDenied();
500
+ }
501
+ return /* @__PURE__ */ jsx(Fragment, { children: fallback });
502
+ }
503
+ if (auditLog) {
504
+ logger.info(`[PermissionGuard] Permission granted:`, {
505
+ userId: effectiveUserId,
506
+ scope,
507
+ permission,
508
+ pageId,
509
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
510
+ });
511
+ }
512
+ return /* @__PURE__ */ jsx(Fragment, { children });
513
+ }
514
+ function AccessLevelGuard({
515
+ userId,
516
+ scope,
517
+ minLevel,
518
+ children,
519
+ fallback = null,
520
+ loading = null
521
+ }) {
522
+ const logger = getRBACLogger();
523
+ const authContext = useContext(React.createContext(null));
524
+ let effectiveUserId = userId;
525
+ if (!effectiveUserId) {
526
+ try {
527
+ if (authContext?.user?.id) {
528
+ effectiveUserId = authContext.user.id;
529
+ } else {
530
+ const globalUser = window.__PACE_USER__;
531
+ if (globalUser?.id) {
532
+ effectiveUserId = globalUser.id;
533
+ }
534
+ }
535
+ } catch (error2) {
536
+ logger.debug("Could not infer userId from context:", error2);
537
+ }
538
+ }
539
+ const { accessLevel, isLoading, error } = useAccessLevel(effectiveUserId || "", scope);
540
+ if (!effectiveUserId) {
541
+ logger.error("AccessLevelGuard: No userId provided and could not infer from context");
542
+ return /* @__PURE__ */ jsxs("div", { className: "rbac-error", role: "alert", children: [
543
+ /* @__PURE__ */ jsx("p", { children: "Access level check failed: User context not available" }),
544
+ /* @__PURE__ */ jsxs("details", { children: [
545
+ /* @__PURE__ */ jsx("summary", { children: "Debug info" }),
546
+ /* @__PURE__ */ jsx("p", { children: "Make sure to either:" }),
547
+ /* @__PURE__ */ jsxs("ul", { children: [
548
+ /* @__PURE__ */ jsx("li", { children: "Pass userId prop explicitly" }),
549
+ /* @__PURE__ */ jsx("li", { children: "Wrap your app with an auth provider" }),
550
+ /* @__PURE__ */ jsx("li", { children: "Set window.__PACE_USER__ with user data" })
551
+ ] })
552
+ ] })
553
+ ] });
554
+ }
555
+ if (isLoading) {
556
+ return loading || /* @__PURE__ */ jsx("div", { className: "rbac-loading", role: "status", "aria-live": "polite", children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Checking access level..." }) });
557
+ }
558
+ if (error) {
559
+ logger.error("Access level check failed:", error);
560
+ return fallback;
561
+ }
562
+ const levelHierarchy = ["viewer", "participant", "planner", "admin", "super"];
563
+ const userLevelIndex = accessLevel ? levelHierarchy.indexOf(accessLevel) : -1;
564
+ const requiredLevelIndex = levelHierarchy.indexOf(minLevel);
565
+ if (userLevelIndex < requiredLevelIndex) {
566
+ return /* @__PURE__ */ jsx(Fragment, { children: fallback });
567
+ }
568
+ return /* @__PURE__ */ jsx(Fragment, { children });
569
+ }
570
+ function withPermissionGuard(config, handler) {
571
+ return async (...args) => {
572
+ const [req] = args;
573
+ const userId = req.user?.id;
574
+ const organisationId = req.organisationId;
575
+ const eventId = req.eventId;
576
+ const appId = req.appId;
577
+ if (!userId || !organisationId) {
578
+ throw new Error("User context required for permission check");
579
+ }
580
+ const { isPermitted: isPermitted2 } = await import("../api-GZHIDA4X.js");
581
+ const hasPermission2 = await isPermitted2({
582
+ userId,
583
+ scope: { organisationId, eventId, appId },
584
+ permission: config.permission,
585
+ pageId: config.pageId
586
+ });
587
+ if (!hasPermission2) {
588
+ throw new Error(`Permission denied: ${config.permission}`);
589
+ }
590
+ return handler(...args);
591
+ };
592
+ }
593
+ function withAccessLevelGuard(minLevel, handler) {
594
+ return async (...args) => {
595
+ const [req] = args;
596
+ const userId = req.user?.id;
597
+ const organisationId = req.organisationId;
598
+ const eventId = req.eventId;
599
+ const appId = req.appId;
600
+ if (!userId || !organisationId) {
601
+ throw new Error("User context required for access level check");
602
+ }
603
+ const { getAccessLevel: getAccessLevel2 } = await import("../api-GZHIDA4X.js");
604
+ const accessLevel = await getAccessLevel2({
605
+ userId,
606
+ scope: { organisationId, eventId, appId }
607
+ });
608
+ const levelHierarchy = ["viewer", "participant", "planner", "admin", "super"];
609
+ const userLevelIndex = levelHierarchy.indexOf(accessLevel);
610
+ const requiredLevelIndex = levelHierarchy.indexOf(minLevel);
611
+ if (userLevelIndex < requiredLevelIndex) {
612
+ throw new Error(`Access level required: ${minLevel}, got: ${accessLevel}`);
613
+ }
614
+ return handler(...args);
615
+ };
616
+ }
617
+ function withRoleGuard(config, handler) {
618
+ return async (...args) => {
619
+ const [req] = args;
620
+ const userId = req.user?.id;
621
+ const organisationId = req.organisationId;
622
+ const eventId = req.eventId;
623
+ const appId = req.appId;
624
+ if (!userId || !organisationId) {
625
+ throw new Error("User context required for role check");
626
+ }
627
+ if (config.globalRoles && config.globalRoles.length > 0) {
628
+ const { isSuperAdmin } = await import("../api-GZHIDA4X.js");
629
+ const isSuper = await isSuperAdmin(userId);
630
+ if (isSuper) {
631
+ if (organisationId) {
632
+ const { emitAuditEvent: emitAuditEvent2 } = await import("../audit-BUW3LMJB.js");
633
+ await emitAuditEvent2({
634
+ type: "permission_check",
635
+ userId,
636
+ organisationId,
637
+ eventId,
638
+ appId,
639
+ permission: "bypass:all",
640
+ decision: true,
641
+ source: "api",
642
+ bypass: true,
643
+ duration_ms: 0,
644
+ metadata: {
645
+ operation: "role_guard",
646
+ reason: "super_admin_bypass"
647
+ }
648
+ });
649
+ }
650
+ return handler(...args);
651
+ }
652
+ }
653
+ if (config.organisationRoles && config.organisationRoles.length > 0) {
654
+ const { isOrganisationAdmin } = await import("../api-GZHIDA4X.js");
655
+ const isOrgAdmin = await isOrganisationAdmin(userId, organisationId);
656
+ if (!isOrgAdmin && config.requireAll !== false) {
657
+ throw new Error(`Organisation admin role required`);
658
+ }
659
+ }
660
+ if (config.eventAppRoles && config.eventAppRoles.length > 0 && eventId && appId) {
661
+ const { isEventAdmin } = await import("../api-GZHIDA4X.js");
662
+ const isEventAdminUser = await isEventAdmin(userId, { organisationId, eventId, appId });
663
+ if (!isEventAdminUser && config.requireAll !== false) {
664
+ throw new Error(`Event admin role required`);
665
+ }
666
+ }
667
+ if (organisationId) {
668
+ const { emitAuditEvent: emitAuditEvent2 } = await import("../audit-BUW3LMJB.js");
669
+ await emitAuditEvent2({
670
+ type: "permission_check",
671
+ userId,
672
+ organisationId,
673
+ eventId,
674
+ appId,
675
+ permission: "role:check",
676
+ decision: true,
677
+ source: "api",
678
+ bypass: false,
679
+ duration_ms: 0,
680
+ metadata: {
681
+ operation: "role_guard"
682
+ }
683
+ });
684
+ }
685
+ return handler(...args);
686
+ };
687
+ }
688
+ function createRBACMiddleware(config) {
689
+ return async (req, res, next) => {
690
+ const { pathname } = req.nextUrl;
691
+ const userId = req.user?.id;
692
+ const organisationId = req.organisationId;
693
+ if (!userId || !organisationId) {
694
+ return res.redirect(config.fallbackUrl || "/login");
695
+ }
696
+ const protectedRoute = config.protectedRoutes.find(
697
+ (route) => pathname.startsWith(route.path)
698
+ );
699
+ if (protectedRoute) {
700
+ try {
701
+ const { isPermitted: isPermitted2 } = await import("../api-GZHIDA4X.js");
702
+ const hasPermission2 = await isPermitted2({
703
+ userId,
704
+ scope: { organisationId },
705
+ permission: protectedRoute.permission,
706
+ pageId: protectedRoute.pageId
707
+ });
708
+ if (!hasPermission2) {
709
+ return res.redirect(config.fallbackUrl || "/access-denied");
710
+ }
711
+ } catch (_error) {
712
+ return res.redirect(config.fallbackUrl || "/access-denied");
713
+ }
714
+ }
715
+ next();
716
+ };
717
+ }
718
+ function createRBACExpressMiddleware(config) {
719
+ return async (req, res, next) => {
720
+ const userId = req.user?.id;
721
+ const organisationId = req.organisationId;
722
+ const eventId = req.eventId;
723
+ const appId = req.appId;
724
+ if (!userId || !organisationId) {
725
+ return res.status(401).json({ error: "User context required" });
726
+ }
727
+ try {
728
+ const { isPermitted: isPermitted2 } = await import("../api-GZHIDA4X.js");
729
+ const hasPermission2 = await isPermitted2({
730
+ userId,
731
+ scope: { organisationId, eventId, appId },
732
+ permission: config.permission,
733
+ pageId: config.pageId
734
+ });
735
+ if (!hasPermission2) {
736
+ return res.status(403).json({ error: "Permission denied" });
737
+ }
738
+ next();
739
+ } catch (_error) {
740
+ return res.status(500).json({ error: "Permission check failed" });
741
+ }
742
+ };
743
+ }
744
+ function hasPermissionCached(userId, scope, _permission, _pageId) {
745
+ const cacheKey = RBACCache.generatePermissionKey({
746
+ userId,
747
+ organisationId: scope.organisationId,
748
+ eventId: scope.eventId,
749
+ appId: scope.appId
750
+ });
751
+ return rbacCache.get(cacheKey) || false;
752
+ }
753
+ function hasAnyPermissionCached(userId, scope, permissions, pageId) {
754
+ return permissions.some(
755
+ (permission) => hasPermissionCached(userId, scope, permission, pageId)
756
+ );
757
+ }
758
+
759
+ // src/rbac/components/PagePermissionProvider.tsx
760
+ init_UnifiedAuthProvider();
761
+ import { createContext, useContext as useContext2, useState as useState2, useCallback as useCallback2, useMemo as useMemo2, useEffect as useEffect2 } from "react";
762
+ import { jsx as jsx2 } from "react/jsx-runtime";
763
+ var PagePermissionContext = createContext(null);
764
+ function PagePermissionProvider({
765
+ children,
766
+ strictMode = true,
767
+ auditLog = true,
768
+ onPageAccess,
769
+ onStrictModeViolation,
770
+ maxHistorySize = 1e3
771
+ }) {
772
+ const { user, selectedOrganisationId, selectedEventId } = useUnifiedAuth();
773
+ const [pageAccessHistory, setPageAccessHistory] = useState2([]);
774
+ const [isEnabled, setIsEnabled] = useState2(true);
775
+ const currentScope = useMemo2(() => {
776
+ if (!selectedOrganisationId) return null;
777
+ return {
778
+ organisationId: selectedOrganisationId,
779
+ eventId: selectedEventId || void 0,
780
+ appId: void 0
781
+ };
782
+ }, [selectedOrganisationId, selectedEventId]);
783
+ const hasPagePermission = useCallback2((pageName, operation, pageId, scope) => {
784
+ if (!isEnabled) return true;
785
+ if (!user?.id) return false;
786
+ const effectiveScope = scope || currentScope;
787
+ if (!effectiveScope) return false;
788
+ const permission = `${operation}:page.${pageName}`;
789
+ return false;
790
+ }, [isEnabled, user?.id, currentScope]);
791
+ const getPagePermissions = useCallback2(() => {
792
+ if (!isEnabled || !user?.id) return {};
793
+ return {};
794
+ }, [isEnabled, user?.id]);
795
+ const getPageAccessHistory = useCallback2(() => {
796
+ return [...pageAccessHistory];
797
+ }, [pageAccessHistory]);
798
+ const clearPageAccessHistory = useCallback2(() => {
799
+ setPageAccessHistory([]);
800
+ }, []);
801
+ const recordPageAccess = useCallback2((pageName, operation, allowed, pageId, scope) => {
802
+ if (!auditLog || !user?.id) return;
803
+ const record = {
804
+ pageName,
805
+ operation,
806
+ userId: user.id,
807
+ scope: scope || currentScope || { organisationId: "" },
808
+ allowed,
809
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
810
+ pageId
811
+ };
812
+ setPageAccessHistory((prev) => {
813
+ const newHistory = [record, ...prev];
814
+ return newHistory.slice(0, maxHistorySize);
815
+ });
816
+ if (onPageAccess) {
817
+ onPageAccess(pageName, operation, allowed, record);
818
+ }
819
+ if (strictMode && !allowed && onStrictModeViolation) {
820
+ onStrictModeViolation(pageName, operation, record);
821
+ }
822
+ }, [auditLog, user?.id, currentScope, maxHistorySize, onPageAccess, onStrictModeViolation, strictMode]);
823
+ const contextValue = useMemo2(() => ({
824
+ hasPagePermission,
825
+ getPagePermissions,
826
+ isEnabled,
827
+ isStrictMode: strictMode,
828
+ isAuditLogEnabled: auditLog,
829
+ getPageAccessHistory,
830
+ clearPageAccessHistory
831
+ }), [
832
+ hasPagePermission,
833
+ getPagePermissions,
834
+ isEnabled,
835
+ strictMode,
836
+ auditLog,
837
+ getPageAccessHistory,
838
+ clearPageAccessHistory
839
+ ]);
840
+ useEffect2(() => {
841
+ if (strictMode && auditLog) {
842
+ console.log(`[PagePermissionProvider] Strict mode enabled - all page access attempts will be logged and enforced`);
843
+ }
844
+ }, [strictMode, auditLog]);
845
+ return /* @__PURE__ */ jsx2(PagePermissionContext.Provider, { value: contextValue, children });
846
+ }
847
+ function usePagePermissions() {
848
+ const context = useContext2(PagePermissionContext);
849
+ if (!context) {
850
+ throw new Error("usePagePermissions must be used within a PagePermissionProvider");
851
+ }
852
+ return context;
853
+ }
854
+
855
+ // src/rbac/components/PagePermissionGuard.tsx
856
+ import { useMemo as useMemo3, useEffect as useEffect3, useState as useState3 } from "react";
857
+ init_UnifiedAuthProvider();
858
+
859
+ // src/rbac/utils/eventContext.ts
860
+ async function getOrganisationFromEvent(supabase, eventId) {
861
+ const { data, error } = await supabase.from("event").select("organisation_id").eq("event_id", eventId).single();
862
+ if (error || !data) {
863
+ return null;
864
+ }
865
+ return data.organisation_id;
866
+ }
867
+ async function createScopeFromEvent(supabase, eventId, appId) {
868
+ const organisationId = await getOrganisationFromEvent(supabase, eventId);
869
+ if (!organisationId) {
870
+ return null;
871
+ }
872
+ return {
873
+ organisationId,
874
+ eventId,
875
+ appId
876
+ };
877
+ }
878
+
879
+ // src/rbac/components/PagePermissionGuard.tsx
880
+ init_appNameResolver();
881
+ import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
882
+ function PagePermissionGuard({
883
+ pageName,
884
+ operation,
885
+ children,
886
+ fallback = /* @__PURE__ */ jsx3(DefaultAccessDenied, {}),
887
+ strictMode = true,
888
+ auditLog = true,
889
+ pageId,
890
+ scope,
891
+ onDenied,
892
+ loading = /* @__PURE__ */ jsx3(DefaultLoading, {})
893
+ }) {
894
+ const { user, selectedOrganisationId, selectedEventId, supabase } = useUnifiedAuth();
895
+ const [hasChecked, setHasChecked] = useState3(false);
896
+ const [checkError, setCheckError] = useState3(null);
897
+ const [resolvedScope, setResolvedScope] = useState3(null);
898
+ useEffect3(() => {
899
+ const resolveScope = async () => {
900
+ if (scope) {
901
+ setResolvedScope(scope);
902
+ return;
903
+ }
904
+ let appId = void 0;
905
+ if (supabase) {
906
+ const appName = getCurrentAppName();
907
+ if (appName) {
908
+ try {
909
+ console.log("[PagePermissionGuard] Resolving app name to ID:", appName);
910
+ const { data: app, error: error2 } = await supabase.from("rbac_apps").select("id, name, is_active").eq("name", appName).eq("is_active", true).single();
911
+ if (error2) {
912
+ console.error("[PagePermissionGuard] Database error resolving app ID:", error2);
913
+ const { data: inactiveApp } = await supabase.from("rbac_apps").select("id, name, is_active").eq("name", appName).single();
914
+ if (inactiveApp) {
915
+ console.error(`[PagePermissionGuard] App "${appName}" exists but is inactive (is_active: ${inactiveApp.is_active})`);
916
+ } else {
917
+ console.error(`[PagePermissionGuard] App "${appName}" not found in rbac_apps table`);
918
+ }
919
+ } else if (app) {
920
+ appId = app.id;
921
+ console.log("[PagePermissionGuard] Successfully resolved app ID:", app.id);
922
+ } else {
923
+ console.error("[PagePermissionGuard] No app data returned for:", appName);
924
+ }
925
+ } catch (error2) {
926
+ console.error("[PagePermissionGuard] Unexpected error resolving app ID:", error2);
927
+ }
928
+ } else {
929
+ console.error("[PagePermissionGuard] No app name found. Make sure to call setRBACAppName() in your app setup.");
930
+ }
931
+ }
932
+ if (selectedOrganisationId && selectedEventId) {
933
+ if (!appId) {
934
+ if (false) {
935
+ console.warn("[PagePermissionGuard] App ID not resolved in test environment, proceeding without it");
936
+ } else {
937
+ console.error("[PagePermissionGuard] CRITICAL: App ID not resolved. Check console for details.");
938
+ setCheckError(new Error("App ID not resolved. Check console for database errors."));
939
+ setResolvedScope(null);
940
+ return;
941
+ }
942
+ }
943
+ if (appId) {
944
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
945
+ if (!uuidRegex.test(appId)) {
946
+ console.error("[PagePermissionGuard] CRITICAL: App ID is not a valid UUID:", appId);
947
+ setCheckError(new Error(`Invalid app ID format: ${appId}. Expected UUID.`));
948
+ setResolvedScope(null);
949
+ return;
950
+ }
951
+ }
952
+ const resolvedScope2 = {
953
+ organisationId: selectedOrganisationId,
954
+ eventId: selectedEventId,
955
+ appId
956
+ };
957
+ console.log("[PagePermissionGuard] Setting resolved scope:", resolvedScope2);
958
+ setResolvedScope(resolvedScope2);
959
+ return;
960
+ }
961
+ if (selectedOrganisationId) {
962
+ if (!appId) {
963
+ if (false) {
964
+ console.warn("[PagePermissionGuard] App ID not resolved in test environment, proceeding without it");
965
+ } else {
966
+ console.error("[PagePermissionGuard] CRITICAL: App ID not resolved. Check console for details.");
967
+ setCheckError(new Error("App ID not resolved. Check console for database errors."));
968
+ setResolvedScope(null);
969
+ return;
970
+ }
971
+ }
972
+ if (appId) {
973
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
974
+ if (!uuidRegex.test(appId)) {
975
+ console.error("[PagePermissionGuard] CRITICAL: App ID is not a valid UUID:", appId);
976
+ setCheckError(new Error(`Invalid app ID format: ${appId}. Expected UUID.`));
977
+ setResolvedScope(null);
978
+ return;
979
+ }
980
+ }
981
+ const resolvedScope2 = {
982
+ organisationId: selectedOrganisationId,
983
+ eventId: selectedEventId || void 0,
984
+ appId
985
+ };
986
+ console.log("[PagePermissionGuard] Setting resolved scope (org only):", resolvedScope2);
987
+ setResolvedScope(resolvedScope2);
988
+ return;
989
+ }
990
+ if (selectedEventId && supabase) {
991
+ try {
992
+ const eventScope = await createScopeFromEvent(supabase, selectedEventId);
993
+ if (!eventScope) {
994
+ setCheckError(new Error("Could not resolve organization from event context"));
995
+ setResolvedScope(null);
996
+ return;
997
+ }
998
+ setResolvedScope({
999
+ ...eventScope,
1000
+ appId: appId || eventScope.appId
1001
+ });
1002
+ } catch (error2) {
1003
+ setCheckError(error2);
1004
+ setResolvedScope(null);
1005
+ }
1006
+ return;
1007
+ }
1008
+ setCheckError(new Error("Either organisation context or event context is required for page permission checking"));
1009
+ setResolvedScope(null);
1010
+ };
1011
+ resolveScope();
1012
+ }, [scope, selectedOrganisationId, selectedEventId, supabase]);
1013
+ const effectivePageId = useMemo3(() => {
1014
+ return pageId || pageName;
1015
+ }, [pageId, pageName]);
1016
+ const permission = useMemo3(() => {
1017
+ return `${operation}:page.${pageName}`;
1018
+ }, [operation, pageName]);
1019
+ console.log("[PagePermissionGuard] Calling useCan with scope:", resolvedScope);
1020
+ console.log("[PagePermissionGuard] resolvedScope:", resolvedScope);
1021
+ console.log("[PagePermissionGuard] selectedEventId:", selectedEventId);
1022
+ console.log("[PagePermissionGuard] About to call useCan with:", {
1023
+ userId: user?.id || "",
1024
+ scope: resolvedScope || { organisationId: "", appId: "", eventId: selectedEventId || void 0 },
1025
+ permission,
1026
+ pageId: effectivePageId,
1027
+ useCache: true
1028
+ });
1029
+ const { can, isLoading: canIsLoading, error: canError } = useCan(
1030
+ user?.id || "",
1031
+ resolvedScope || { organisationId: "", appId: "", eventId: selectedEventId || void 0 },
1032
+ permission,
1033
+ effectivePageId,
1034
+ true
1035
+ // Use cache
1036
+ );
1037
+ console.log("[PagePermissionGuard] useCan returned:", { can, canIsLoading, canError });
1038
+ const isLoading = !resolvedScope || canIsLoading;
1039
+ const error = checkError || canError;
1040
+ console.log("[PagePermissionGuard] Combined state:", {
1041
+ can,
1042
+ isLoading,
1043
+ canIsLoading,
1044
+ resolvedScopeExists: !!resolvedScope,
1045
+ error: error?.message
1046
+ });
1047
+ useEffect3(() => {
1048
+ if (!isLoading && !error) {
1049
+ setHasChecked(true);
1050
+ setCheckError(null);
1051
+ if (!can && onDenied) {
1052
+ onDenied(pageName, operation);
1053
+ }
1054
+ } else if (error) {
1055
+ setCheckError(error);
1056
+ setHasChecked(true);
1057
+ }
1058
+ }, [can, isLoading, error, pageName, operation, onDenied]);
1059
+ useEffect3(() => {
1060
+ if (auditLog && hasChecked && !isLoading) {
1061
+ console.log(`[PagePermissionGuard] Page access attempt:`, {
1062
+ pageName,
1063
+ operation,
1064
+ userId: user?.id,
1065
+ scope: resolvedScope,
1066
+ allowed: can,
1067
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1068
+ });
1069
+ }
1070
+ }, [auditLog, hasChecked, isLoading, pageName, operation, user?.id, resolvedScope, can]);
1071
+ useEffect3(() => {
1072
+ if (strictMode && hasChecked && !isLoading && !can) {
1073
+ console.error(`[PagePermissionGuard] STRICT MODE VIOLATION: User attempted to access protected page without permission`, {
1074
+ pageName,
1075
+ operation,
1076
+ userId: user?.id,
1077
+ scope: resolvedScope,
1078
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1079
+ });
1080
+ }
1081
+ }, [strictMode, hasChecked, isLoading, can, pageName, operation, user?.id, resolvedScope]);
1082
+ if (isLoading || !resolvedScope || !hasChecked) {
1083
+ return /* @__PURE__ */ jsx3(Fragment2, { children: loading });
1084
+ }
1085
+ if (checkError) {
1086
+ console.error(`[PagePermissionGuard] Permission check failed for page ${pageName}:`, checkError);
1087
+ return /* @__PURE__ */ jsx3(Fragment2, { children: fallback });
1088
+ }
1089
+ if (!can) {
1090
+ return /* @__PURE__ */ jsx3(Fragment2, { children: fallback });
1091
+ }
1092
+ return /* @__PURE__ */ jsx3(Fragment2, { children });
1093
+ }
1094
+ function DefaultAccessDenied() {
1095
+ return /* @__PURE__ */ jsxs2("div", { className: "flex flex-col items-center justify-center min-h-[200px] p-8 text-center", children: [
1096
+ /* @__PURE__ */ jsx3("div", { className: "mb-4", children: /* @__PURE__ */ jsx3("svg", { className: "w-16 h-16 text-acc-500 mx-auto", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z" }) }) }),
1097
+ /* @__PURE__ */ jsx3("h2", { className: "text-xl font-semibold text-sec-900 mb-2", children: "Access Denied" }),
1098
+ /* @__PURE__ */ jsx3("p", { className: "text-sec-600 mb-4", children: "You don't have permission to access this page." }),
1099
+ /* @__PURE__ */ jsx3(
1100
+ "button",
1101
+ {
1102
+ onClick: () => window.history.back(),
1103
+ className: "px-4 py-2 bg-main-600 text-main-50 rounded-md hover:bg-main-700 transition-colors",
1104
+ children: "Go Back"
1105
+ }
1106
+ )
1107
+ ] });
1108
+ }
1109
+ function DefaultLoading() {
1110
+ return /* @__PURE__ */ jsx3("div", { className: "flex items-center justify-center min-h-[200px] p-8", children: /* @__PURE__ */ jsxs2("div", { className: "flex items-center space-x-2", children: [
1111
+ /* @__PURE__ */ jsx3("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-main-600" }),
1112
+ /* @__PURE__ */ jsx3("span", { className: "text-sec-600", children: "Checking permissions..." })
1113
+ ] }) });
1114
+ }
1115
+
1116
+ // src/rbac/components/SecureDataProvider.tsx
1117
+ init_UnifiedAuthProvider();
1118
+ import { createContext as createContext2, useContext as useContext3, useState as useState4, useCallback as useCallback4, useMemo as useMemo4, useEffect as useEffect4 } from "react";
1119
+ import { jsx as jsx4 } from "react/jsx-runtime";
1120
+ var SecureDataContext = createContext2(null);
1121
+ function SecureDataProvider({
1122
+ children,
1123
+ strictMode = true,
1124
+ auditLog = true,
1125
+ onDataAccess,
1126
+ onStrictModeViolation,
1127
+ maxHistorySize = 1e3,
1128
+ enforceRLS = true
1129
+ }) {
1130
+ const { user, selectedOrganisationId, selectedEventId } = useUnifiedAuth();
1131
+ const { validateContext } = useSecureDataAccess();
1132
+ const [dataAccessHistory, setDataAccessHistory] = useState4([]);
1133
+ const [isEnabled, setIsEnabled] = useState4(true);
1134
+ const currentScope = useMemo4(() => {
1135
+ if (!selectedOrganisationId) return null;
1136
+ return {
1137
+ organisationId: selectedOrganisationId,
1138
+ eventId: selectedEventId || void 0,
1139
+ appId: void 0
1140
+ };
1141
+ }, [selectedOrganisationId, selectedEventId]);
1142
+ const isDataAccessAllowed = useCallback4((table, operation, scope) => {
1143
+ if (!isEnabled) return true;
1144
+ if (!user?.id) return false;
1145
+ const effectiveScope = scope || currentScope;
1146
+ if (!effectiveScope) return false;
1147
+ const permission = `${operation}:data.${table}`;
1148
+ return true;
1149
+ }, [isEnabled, user?.id, currentScope]);
1150
+ const getDataAccessPermissions = useCallback4(() => {
1151
+ if (!isEnabled || !user?.id) return {};
1152
+ return {};
1153
+ }, [isEnabled, user?.id]);
1154
+ const getDataAccessHistory = useCallback4(() => {
1155
+ return [...dataAccessHistory];
1156
+ }, [dataAccessHistory]);
1157
+ const clearDataAccessHistory = useCallback4(() => {
1158
+ setDataAccessHistory([]);
1159
+ }, []);
1160
+ const validateDataAccess = useCallback4((table, operation, scope) => {
1161
+ if (!isEnabled) return true;
1162
+ if (!user?.id) return false;
1163
+ const effectiveScope = scope || currentScope;
1164
+ if (!effectiveScope) return false;
1165
+ try {
1166
+ validateContext();
1167
+ } catch (error) {
1168
+ console.error(`[SecureDataProvider] Organisation context validation failed:`, error);
1169
+ return false;
1170
+ }
1171
+ return isDataAccessAllowed(table, operation, effectiveScope);
1172
+ }, [isEnabled, user?.id, currentScope, validateContext, isDataAccessAllowed]);
1173
+ const recordDataAccess = useCallback4((table, operation, allowed, query, filters, scope) => {
1174
+ if (!auditLog || !user?.id) return;
1175
+ const record = {
1176
+ table,
1177
+ operation,
1178
+ userId: user.id,
1179
+ scope: scope || currentScope || { organisationId: "" },
1180
+ allowed,
1181
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1182
+ query,
1183
+ filters
1184
+ };
1185
+ setDataAccessHistory((prev) => {
1186
+ const newHistory = [record, ...prev];
1187
+ return newHistory.slice(0, maxHistorySize);
1188
+ });
1189
+ if (onDataAccess) {
1190
+ onDataAccess(table, operation, allowed, record);
1191
+ }
1192
+ if (strictMode && !allowed && onStrictModeViolation) {
1193
+ onStrictModeViolation(table, operation, record);
1194
+ }
1195
+ }, [auditLog, user?.id, currentScope, maxHistorySize, onDataAccess, onStrictModeViolation, strictMode]);
1196
+ const contextValue = useMemo4(() => ({
1197
+ isDataAccessAllowed,
1198
+ getDataAccessPermissions,
1199
+ isEnabled,
1200
+ isStrictMode: strictMode,
1201
+ isAuditLogEnabled: auditLog,
1202
+ getDataAccessHistory,
1203
+ clearDataAccessHistory,
1204
+ validateDataAccess
1205
+ }), [
1206
+ isDataAccessAllowed,
1207
+ getDataAccessPermissions,
1208
+ isEnabled,
1209
+ strictMode,
1210
+ auditLog,
1211
+ getDataAccessHistory,
1212
+ clearDataAccessHistory,
1213
+ validateDataAccess
1214
+ ]);
1215
+ useEffect4(() => {
1216
+ if (strictMode && auditLog) {
1217
+ console.log(`[SecureDataProvider] Strict mode enabled - all data access attempts will be logged and enforced`);
1218
+ }
1219
+ }, [strictMode, auditLog]);
1220
+ useEffect4(() => {
1221
+ if (enforceRLS && auditLog) {
1222
+ console.log(`[SecureDataProvider] RLS enforcement enabled - all queries will include organisation context`);
1223
+ }
1224
+ }, [enforceRLS, auditLog]);
1225
+ return /* @__PURE__ */ jsx4(SecureDataContext.Provider, { value: contextValue, children });
1226
+ }
1227
+ function useSecureData() {
1228
+ const context = useContext3(SecureDataContext);
1229
+ if (!context) {
1230
+ throw new Error("useSecureData must be used within a SecureDataProvider");
1231
+ }
1232
+ return context;
1233
+ }
1234
+
1235
+ // src/rbac/components/PermissionEnforcer.tsx
1236
+ import { useMemo as useMemo5, useEffect as useEffect5, useState as useState5 } from "react";
1237
+ init_UnifiedAuthProvider();
1238
+ import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
1239
+ function PermissionEnforcer({
1240
+ permissions,
1241
+ operation,
1242
+ children,
1243
+ fallback = /* @__PURE__ */ jsx5(DefaultAccessDenied2, {}),
1244
+ strictMode = true,
1245
+ auditLog = true,
1246
+ scope,
1247
+ onDenied,
1248
+ loading = /* @__PURE__ */ jsx5(DefaultLoading2, {}),
1249
+ requireAll = true
1250
+ }) {
1251
+ const { user, selectedOrganisationId, selectedEventId, supabase } = useUnifiedAuth();
1252
+ const [hasChecked, setHasChecked] = useState5(false);
1253
+ const [checkError, setCheckError] = useState5(null);
1254
+ const [permissionResults, setPermissionResults] = useState5({});
1255
+ const [resolvedScope, setResolvedScope] = useState5(null);
1256
+ useEffect5(() => {
1257
+ const resolveScope = async () => {
1258
+ if (scope) {
1259
+ setResolvedScope(scope);
1260
+ return;
1261
+ }
1262
+ if (selectedOrganisationId && selectedEventId) {
1263
+ setResolvedScope({
1264
+ organisationId: selectedOrganisationId,
1265
+ eventId: selectedEventId,
1266
+ appId: void 0
1267
+ });
1268
+ return;
1269
+ }
1270
+ if (selectedOrganisationId) {
1271
+ setResolvedScope({
1272
+ organisationId: selectedOrganisationId,
1273
+ eventId: selectedEventId || void 0,
1274
+ appId: void 0
1275
+ });
1276
+ return;
1277
+ }
1278
+ if (selectedEventId && supabase) {
1279
+ try {
1280
+ const eventScope = await createScopeFromEvent(supabase, selectedEventId);
1281
+ if (!eventScope) {
1282
+ setCheckError(new Error("Could not resolve organization from event context"));
1283
+ return;
1284
+ }
1285
+ setResolvedScope(eventScope);
1286
+ } catch (error2) {
1287
+ setCheckError(error2);
1288
+ }
1289
+ return;
1290
+ }
1291
+ setCheckError(new Error("Either organisation context or event context is required for permission checking"));
1292
+ };
1293
+ resolveScope();
1294
+ }, [scope, selectedOrganisationId, selectedEventId, supabase]);
1295
+ const representativePermission = permissions[0];
1296
+ const { can, isLoading, error } = useCan(
1297
+ user?.id || "",
1298
+ resolvedScope || { eventId: selectedEventId || void 0 },
1299
+ representativePermission,
1300
+ void 0,
1301
+ true
1302
+ // Use cache
1303
+ );
1304
+ const hasRequiredPermissions = useMemo5(() => {
1305
+ if (permissions.length === 0) return true;
1306
+ return can;
1307
+ }, [permissions, can]);
1308
+ useEffect5(() => {
1309
+ if (!isLoading && !error) {
1310
+ setHasChecked(true);
1311
+ setCheckError(null);
1312
+ if (!hasRequiredPermissions && onDenied) {
1313
+ onDenied(permissions, operation);
1314
+ }
1315
+ } else if (error) {
1316
+ setCheckError(error);
1317
+ setHasChecked(true);
1318
+ }
1319
+ }, [hasRequiredPermissions, isLoading, error, permissions, operation, onDenied]);
1320
+ useEffect5(() => {
1321
+ if (auditLog && hasChecked && !isLoading) {
1322
+ console.log(`[PermissionEnforcer] Permission check attempt:`, {
1323
+ permissions,
1324
+ operation,
1325
+ userId: user?.id,
1326
+ scope: resolvedScope,
1327
+ allowed: hasRequiredPermissions,
1328
+ requireAll,
1329
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1330
+ });
1331
+ }
1332
+ }, [auditLog, hasChecked, isLoading, permissions, operation, user?.id, resolvedScope, hasRequiredPermissions, requireAll]);
1333
+ useEffect5(() => {
1334
+ if (strictMode && hasChecked && !isLoading && !hasRequiredPermissions) {
1335
+ console.error(`[PermissionEnforcer] STRICT MODE VIOLATION: User attempted to perform operation without permission`, {
1336
+ permissions,
1337
+ operation,
1338
+ userId: user?.id,
1339
+ scope: resolvedScope,
1340
+ requireAll,
1341
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1342
+ });
1343
+ }
1344
+ }, [strictMode, hasChecked, isLoading, hasRequiredPermissions, permissions, operation, user?.id, resolvedScope, requireAll]);
1345
+ if (isLoading || !hasChecked) {
1346
+ return /* @__PURE__ */ jsx5(Fragment3, { children: loading });
1347
+ }
1348
+ if (checkError) {
1349
+ console.error(`[PermissionEnforcer] Permission check failed for operation ${operation}:`, checkError);
1350
+ return /* @__PURE__ */ jsx5(Fragment3, { children: fallback });
1351
+ }
1352
+ if (!hasRequiredPermissions) {
1353
+ return /* @__PURE__ */ jsx5(Fragment3, { children: fallback });
1354
+ }
1355
+ return /* @__PURE__ */ jsx5(Fragment3, { children });
1356
+ }
1357
+ function DefaultAccessDenied2() {
1358
+ return /* @__PURE__ */ jsxs3("div", { className: "flex flex-col items-center justify-center min-h-[200px] p-8 text-center", children: [
1359
+ /* @__PURE__ */ jsx5("div", { className: "mb-4", children: /* @__PURE__ */ jsx5("svg", { className: "w-16 h-16 text-acc-500 mx-auto", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z" }) }) }),
1360
+ /* @__PURE__ */ jsx5("h2", { className: "text-xl font-semibold text-sec-900 mb-2", children: "Access Denied" }),
1361
+ /* @__PURE__ */ jsx5("p", { className: "text-sec-600 mb-4", children: "You don't have permission to perform this operation." }),
1362
+ /* @__PURE__ */ jsx5(
1363
+ "button",
1364
+ {
1365
+ onClick: () => window.history.back(),
1366
+ className: "px-4 py-2 bg-main-600 text-main-50 rounded-md hover:bg-main-700 transition-colors",
1367
+ children: "Go Back"
1368
+ }
1369
+ )
1370
+ ] });
1371
+ }
1372
+ function DefaultLoading2() {
1373
+ return /* @__PURE__ */ jsx5("div", { className: "flex items-center justify-center min-h-[200px] p-8", children: /* @__PURE__ */ jsxs3("div", { className: "flex items-center space-x-2", children: [
1374
+ /* @__PURE__ */ jsx5("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-main-600" }),
1375
+ /* @__PURE__ */ jsx5("span", { className: "text-sec-600", children: "Checking permissions..." })
1376
+ ] }) });
1377
+ }
1378
+
1379
+ // src/rbac/components/RoleBasedRouter.tsx
1380
+ import { useMemo as useMemo6, useCallback as useCallback6, useEffect as useEffect6, useState as useState6, createContext as createContext3, useContext as useContext4 } from "react";
1381
+ import { useLocation, useNavigate, Outlet } from "react-router-dom";
1382
+ init_UnifiedAuthProvider();
1383
+ import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
1384
+ var RoleBasedRouterContext = createContext3(null);
1385
+ function RoleBasedRouter({
1386
+ routes,
1387
+ fallbackRoute = "/unauthorized",
1388
+ children,
1389
+ strictMode = true,
1390
+ auditLog = true,
1391
+ onRouteAccess,
1392
+ onStrictModeViolation,
1393
+ maxHistorySize = 1e3,
1394
+ unauthorizedComponent: UnauthorizedComponent = DefaultUnauthorizedComponent
1395
+ }) {
1396
+ const { user, selectedOrganisationId, selectedEventId } = useUnifiedAuth();
1397
+ const location = useLocation();
1398
+ const navigate = useNavigate();
1399
+ const [routeAccessHistory, setRouteAccessHistory] = useState6([]);
1400
+ const [currentRoute, setCurrentRoute] = useState6("");
1401
+ const currentScope = useMemo6(() => {
1402
+ if (!selectedOrganisationId) return null;
1403
+ return {
1404
+ organisationId: selectedOrganisationId,
1405
+ eventId: selectedEventId || void 0,
1406
+ appId: void 0
1407
+ };
1408
+ }, [selectedOrganisationId, selectedEventId]);
1409
+ const currentRouteConfig = useMemo6(() => {
1410
+ const currentPath = location.pathname;
1411
+ return routes.find((route) => route.path === currentPath) || null;
1412
+ }, [routes, location.pathname]);
1413
+ const canAccessRoute = useCallback6((path) => {
1414
+ if (!user?.id || !currentScope) return false;
1415
+ const routeConfig = routes.find((route) => route.path === path);
1416
+ if (!routeConfig) return false;
1417
+ return true;
1418
+ }, [user?.id, currentScope, routes]);
1419
+ const { can: canAccessCurrentRoute, isLoading: permissionLoading } = useCan(
1420
+ user?.id || "",
1421
+ currentScope || { organisationId: "", eventId: void 0, appId: void 0 },
1422
+ currentRouteConfig?.permissions?.[0] || "read:page",
1423
+ currentRouteConfig?.pageId
1424
+ );
1425
+ const hasPermissions = currentRouteConfig?.permissions && currentRouteConfig.permissions.length > 0;
1426
+ const finalCanAccess = hasPermissions ? canAccessCurrentRoute : false;
1427
+ const finalLoading = hasPermissions ? permissionLoading : false;
1428
+ const getAccessibleRoutes = useCallback6(() => {
1429
+ if (!user?.id || !currentScope) return [];
1430
+ return routes.filter((route) => canAccessRoute(route.path));
1431
+ }, [user?.id, currentScope, routes, canAccessRoute]);
1432
+ const getRouteConfig = useCallback6((path) => {
1433
+ return routes.find((route) => route.path === path) || null;
1434
+ }, [routes]);
1435
+ const getRouteAccessHistory = useCallback6(() => {
1436
+ return [...routeAccessHistory];
1437
+ }, [routeAccessHistory]);
1438
+ const clearRouteAccessHistory = useCallback6(() => {
1439
+ setRouteAccessHistory([]);
1440
+ }, []);
1441
+ const recordRouteAccess = useCallback6((route, allowed, routeConfig) => {
1442
+ if (!auditLog || !user?.id || !currentScope) return;
1443
+ const record = {
1444
+ route,
1445
+ permissions: routeConfig.permissions,
1446
+ userId: user.id,
1447
+ scope: currentScope,
1448
+ allowed,
1449
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1450
+ pageId: routeConfig.pageId,
1451
+ roles: routeConfig.roles,
1452
+ accessLevel: routeConfig.accessLevel
1453
+ };
1454
+ setRouteAccessHistory((prev) => {
1455
+ const newHistory = [record, ...prev];
1456
+ return newHistory.slice(0, maxHistorySize);
1457
+ });
1458
+ if (onRouteAccess) {
1459
+ onRouteAccess(route, allowed, record);
1460
+ }
1461
+ if (strictMode && !allowed && onStrictModeViolation) {
1462
+ onStrictModeViolation(route, record);
1463
+ }
1464
+ }, [auditLog, user?.id, currentScope, maxHistorySize, onRouteAccess, onStrictModeViolation, strictMode]);
1465
+ useEffect6(() => {
1466
+ const currentPath = location.pathname;
1467
+ setCurrentRoute(currentPath);
1468
+ if (!currentRouteConfig) {
1469
+ if (strictMode) {
1470
+ console.error(`[RoleBasedRouter] STRICT MODE VIOLATION: Route not found in configuration`, {
1471
+ route: currentPath,
1472
+ userId: user?.id,
1473
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1474
+ });
1475
+ if (onStrictModeViolation) {
1476
+ onStrictModeViolation(currentPath, {
1477
+ route: currentPath,
1478
+ permissions: [],
1479
+ userId: user?.id || "",
1480
+ scope: currentScope || { organisationId: "" },
1481
+ allowed: false,
1482
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1483
+ });
1484
+ }
1485
+ }
1486
+ return;
1487
+ }
1488
+ const allowed = finalCanAccess;
1489
+ recordRouteAccess(currentPath, allowed, currentRouteConfig);
1490
+ if (!allowed) {
1491
+ navigate(fallbackRoute, { replace: true });
1492
+ }
1493
+ }, [location.pathname, currentRouteConfig, canAccessCurrentRoute, recordRouteAccess, strictMode, user?.id, currentScope, onStrictModeViolation, navigate, fallbackRoute]);
1494
+ const contextValue = useMemo6(() => ({
1495
+ getAccessibleRoutes,
1496
+ canAccessRoute,
1497
+ getRouteConfig,
1498
+ getRouteAccessHistory,
1499
+ clearRouteAccessHistory,
1500
+ isStrictMode: strictMode,
1501
+ isAuditLogEnabled: auditLog
1502
+ }), [
1503
+ getAccessibleRoutes,
1504
+ canAccessRoute,
1505
+ getRouteConfig,
1506
+ getRouteAccessHistory,
1507
+ clearRouteAccessHistory,
1508
+ strictMode,
1509
+ auditLog
1510
+ ]);
1511
+ if (finalLoading) {
1512
+ return /* @__PURE__ */ jsx6("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs4("div", { className: "text-center", children: [
1513
+ /* @__PURE__ */ jsx6("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-main-600 mx-auto mb-4" }),
1514
+ /* @__PURE__ */ jsx6("p", { className: "text-sec-600", children: "Checking permissions..." })
1515
+ ] }) });
1516
+ }
1517
+ if (currentRouteConfig && !finalCanAccess) {
1518
+ return /* @__PURE__ */ jsx6(
1519
+ UnauthorizedComponent,
1520
+ {
1521
+ route: currentRoute,
1522
+ reason: "Insufficient permissions"
1523
+ }
1524
+ );
1525
+ }
1526
+ return /* @__PURE__ */ jsxs4(RoleBasedRouterContext.Provider, { value: contextValue, children: [
1527
+ children,
1528
+ /* @__PURE__ */ jsx6(Outlet, {})
1529
+ ] });
1530
+ }
1531
+ function useRoleBasedRouter() {
1532
+ const context = useContext4(RoleBasedRouterContext);
1533
+ if (!context) {
1534
+ throw new Error("useRoleBasedRouter must be used within a RoleBasedRouter");
1535
+ }
1536
+ return context;
1537
+ }
1538
+ function DefaultUnauthorizedComponent({ route, reason }) {
1539
+ return /* @__PURE__ */ jsxs4("div", { className: "flex flex-col items-center justify-center min-h-screen p-8 text-center", children: [
1540
+ /* @__PURE__ */ jsx6("div", { className: "mb-4", children: /* @__PURE__ */ jsx6("svg", { className: "w-16 h-16 text-acc-500 mx-auto", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z" }) }) }),
1541
+ /* @__PURE__ */ jsx6("h2", { className: "text-xl font-semibold text-sec-900 mb-2", children: "Access Denied" }),
1542
+ /* @__PURE__ */ jsxs4("p", { className: "text-sec-600 mb-4", children: [
1543
+ "You don't have permission to access ",
1544
+ /* @__PURE__ */ jsx6("code", { className: "bg-sec-100 px-2 py-1 rounded", children: route })
1545
+ ] }),
1546
+ /* @__PURE__ */ jsxs4("p", { className: "text-sm text-sec-500 mb-4", children: [
1547
+ "Reason: ",
1548
+ reason
1549
+ ] }),
1550
+ /* @__PURE__ */ jsx6(
1551
+ "button",
1552
+ {
1553
+ onClick: () => window.history.back(),
1554
+ className: "px-4 py-2 bg-main-600 text-main-50 rounded-md hover:bg-main-700 transition-colors",
1555
+ children: "Go Back"
1556
+ }
1557
+ )
1558
+ ] });
1559
+ }
1560
+
1561
+ // src/rbac/components/NavigationProvider.tsx
1562
+ init_UnifiedAuthProvider();
1563
+ import { createContext as createContext4, useContext as useContext5, useState as useState7, useCallback as useCallback7, useMemo as useMemo7, useEffect as useEffect7 } from "react";
1564
+ import { jsx as jsx7 } from "react/jsx-runtime";
1565
+ var NavigationContext = createContext4(null);
1566
+ function NavigationProvider({
1567
+ children,
1568
+ strictMode = true,
1569
+ auditLog = true,
1570
+ onNavigationAccess,
1571
+ onStrictModeViolation,
1572
+ maxHistorySize = 1e3
1573
+ }) {
1574
+ const { user, selectedOrganisationId, selectedEventId } = useUnifiedAuth();
1575
+ const [navigationAccessHistory, setNavigationAccessHistory] = useState7([]);
1576
+ const [isEnabled, setIsEnabled] = useState7(true);
1577
+ const currentScope = useMemo7(() => {
1578
+ if (!selectedOrganisationId) return null;
1579
+ return {
1580
+ organisationId: selectedOrganisationId,
1581
+ eventId: selectedEventId || void 0,
1582
+ appId: void 0
1583
+ };
1584
+ }, [selectedOrganisationId, selectedEventId]);
1585
+ const hasNavigationPermission = useCallback7((item) => {
1586
+ if (!isEnabled) return true;
1587
+ if (!user?.id) return false;
1588
+ if (!currentScope) return false;
1589
+ return true;
1590
+ }, [isEnabled, user?.id, currentScope]);
1591
+ const getNavigationPermissions = useCallback7(() => {
1592
+ if (!isEnabled || !user?.id) return {};
1593
+ return {};
1594
+ }, [isEnabled, user?.id]);
1595
+ const getFilteredNavigationItems = useCallback7((items) => {
1596
+ if (!isEnabled) return items;
1597
+ return items.filter((item) => hasNavigationPermission(item));
1598
+ }, [isEnabled, hasNavigationPermission]);
1599
+ const getNavigationAccessHistory = useCallback7(() => {
1600
+ return [...navigationAccessHistory];
1601
+ }, [navigationAccessHistory]);
1602
+ const clearNavigationAccessHistory = useCallback7(() => {
1603
+ setNavigationAccessHistory([]);
1604
+ }, []);
1605
+ const recordNavigationAccess = useCallback7((item, allowed) => {
1606
+ if (!auditLog || !user?.id || !currentScope) return;
1607
+ const record = {
1608
+ navigationItem: item.id,
1609
+ permissions: item.permissions,
1610
+ userId: user.id,
1611
+ scope: currentScope,
1612
+ allowed,
1613
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1614
+ pageId: item.pageId,
1615
+ roles: item.roles,
1616
+ accessLevel: item.accessLevel
1617
+ };
1618
+ setNavigationAccessHistory((prev) => {
1619
+ const newHistory = [record, ...prev];
1620
+ return newHistory.slice(0, maxHistorySize);
1621
+ });
1622
+ if (onNavigationAccess) {
1623
+ onNavigationAccess(item, allowed, record);
1624
+ }
1625
+ if (strictMode && !allowed && onStrictModeViolation) {
1626
+ onStrictModeViolation(item, record);
1627
+ }
1628
+ }, [auditLog, user?.id, currentScope, maxHistorySize, onNavigationAccess, onStrictModeViolation, strictMode]);
1629
+ const contextValue = useMemo7(() => ({
1630
+ hasNavigationPermission,
1631
+ getNavigationPermissions,
1632
+ getFilteredNavigationItems,
1633
+ isEnabled,
1634
+ isStrictMode: strictMode,
1635
+ isAuditLogEnabled: auditLog,
1636
+ getNavigationAccessHistory,
1637
+ clearNavigationAccessHistory
1638
+ }), [
1639
+ hasNavigationPermission,
1640
+ getNavigationPermissions,
1641
+ getFilteredNavigationItems,
1642
+ isEnabled,
1643
+ strictMode,
1644
+ auditLog,
1645
+ getNavigationAccessHistory,
1646
+ clearNavigationAccessHistory
1647
+ ]);
1648
+ useEffect7(() => {
1649
+ if (strictMode && auditLog) {
1650
+ console.log(`[NavigationProvider] Strict mode enabled - all navigation access attempts will be logged and enforced`);
1651
+ }
1652
+ }, [strictMode, auditLog]);
1653
+ return /* @__PURE__ */ jsx7(NavigationContext.Provider, { value: contextValue, children });
1654
+ }
1655
+ function useNavigationPermissions() {
1656
+ const context = useContext5(NavigationContext);
1657
+ if (!context) {
1658
+ throw new Error("useNavigationPermissions must be used within a NavigationProvider");
1659
+ }
1660
+ return context;
1661
+ }
1662
+
1663
+ // src/rbac/components/NavigationGuard.tsx
1664
+ import { useMemo as useMemo8, useEffect as useEffect8, useState as useState8 } from "react";
1665
+ init_UnifiedAuthProvider();
1666
+ import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
1667
+ function NavigationGuard({
1668
+ navigationItem,
1669
+ children,
1670
+ fallback = /* @__PURE__ */ jsx8(DefaultAccessDenied3, {}),
1671
+ strictMode = true,
1672
+ auditLog = true,
1673
+ scope,
1674
+ onDenied,
1675
+ loading = /* @__PURE__ */ jsx8(DefaultLoading3, {}),
1676
+ requireAll = true
1677
+ }) {
1678
+ const { user, selectedOrganisationId, selectedEventId, supabase } = useUnifiedAuth();
1679
+ const [hasChecked, setHasChecked] = useState8(false);
1680
+ const [checkError, setCheckError] = useState8(null);
1681
+ const [resolvedScope, setResolvedScope] = useState8(null);
1682
+ useEffect8(() => {
1683
+ const resolveScope = async () => {
1684
+ if (scope) {
1685
+ setResolvedScope(scope);
1686
+ return;
1687
+ }
1688
+ if (selectedOrganisationId && selectedEventId) {
1689
+ setResolvedScope({
1690
+ organisationId: selectedOrganisationId,
1691
+ eventId: selectedEventId,
1692
+ appId: void 0
1693
+ });
1694
+ return;
1695
+ }
1696
+ if (selectedOrganisationId) {
1697
+ setResolvedScope({
1698
+ organisationId: selectedOrganisationId,
1699
+ eventId: selectedEventId || void 0,
1700
+ appId: void 0
1701
+ });
1702
+ return;
1703
+ }
1704
+ if (selectedEventId && supabase) {
1705
+ try {
1706
+ const eventScope = await createScopeFromEvent(supabase, selectedEventId);
1707
+ if (!eventScope) {
1708
+ setCheckError(new Error("Could not resolve organization from event context"));
1709
+ return;
1710
+ }
1711
+ setResolvedScope(eventScope);
1712
+ } catch (error2) {
1713
+ setCheckError(error2);
1714
+ }
1715
+ return;
1716
+ }
1717
+ setCheckError(new Error("Either organisation context or event context is required for navigation permission checking"));
1718
+ };
1719
+ resolveScope();
1720
+ }, [scope, selectedOrganisationId, selectedEventId, supabase]);
1721
+ const representativePermission = navigationItem.permissions[0];
1722
+ const { can, isLoading, error } = useCan(
1723
+ user?.id || "",
1724
+ resolvedScope || { eventId: selectedEventId || void 0 },
1725
+ representativePermission,
1726
+ navigationItem.pageId,
1727
+ true
1728
+ // Use cache
1729
+ );
1730
+ const hasRequiredPermissions = useMemo8(() => {
1731
+ if (navigationItem.permissions.length === 0) return true;
1732
+ return can;
1733
+ }, [navigationItem.permissions, can]);
1734
+ useEffect8(() => {
1735
+ if (!isLoading && !error) {
1736
+ setHasChecked(true);
1737
+ setCheckError(null);
1738
+ if (!hasRequiredPermissions && onDenied) {
1739
+ onDenied(navigationItem);
1740
+ }
1741
+ } else if (error) {
1742
+ setCheckError(error);
1743
+ setHasChecked(true);
1744
+ }
1745
+ }, [hasRequiredPermissions, isLoading, error, navigationItem, onDenied]);
1746
+ useEffect8(() => {
1747
+ if (auditLog && hasChecked && !isLoading) {
1748
+ console.log(`[NavigationGuard] Navigation access attempt:`, {
1749
+ navigationItem: navigationItem.id,
1750
+ permissions: navigationItem.permissions,
1751
+ userId: user?.id,
1752
+ scope: resolvedScope,
1753
+ allowed: hasRequiredPermissions,
1754
+ requireAll,
1755
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1756
+ });
1757
+ }
1758
+ }, [auditLog, hasChecked, isLoading, navigationItem, user?.id, resolvedScope, hasRequiredPermissions, requireAll]);
1759
+ useEffect8(() => {
1760
+ if (strictMode && hasChecked && !isLoading && !hasRequiredPermissions) {
1761
+ console.error(`[NavigationGuard] STRICT MODE VIOLATION: User attempted to access protected navigation item without permission`, {
1762
+ navigationItem: navigationItem.id,
1763
+ permissions: navigationItem.permissions,
1764
+ userId: user?.id,
1765
+ scope: resolvedScope,
1766
+ requireAll,
1767
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1768
+ });
1769
+ }
1770
+ }, [strictMode, hasChecked, isLoading, hasRequiredPermissions, navigationItem, user?.id, resolvedScope, requireAll]);
1771
+ if (isLoading || !resolvedScope || !hasChecked) {
1772
+ return /* @__PURE__ */ jsx8(Fragment4, { children: loading });
1773
+ }
1774
+ if (checkError) {
1775
+ console.error(`[NavigationGuard] Permission check failed for navigation item ${navigationItem.id}:`, checkError);
1776
+ return /* @__PURE__ */ jsx8(Fragment4, { children: fallback });
1777
+ }
1778
+ if (!hasRequiredPermissions) {
1779
+ return /* @__PURE__ */ jsx8(Fragment4, { children: fallback });
1780
+ }
1781
+ return /* @__PURE__ */ jsx8(Fragment4, { children });
1782
+ }
1783
+ function DefaultAccessDenied3() {
1784
+ return /* @__PURE__ */ jsx8("div", { className: "flex items-center justify-center p-2 text-center", children: /* @__PURE__ */ jsxs5("div", { className: "flex items-center space-x-2", children: [
1785
+ /* @__PURE__ */ jsx8("svg", { className: "w-4 h-4 text-acc-500", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z" }) }),
1786
+ /* @__PURE__ */ jsx8("span", { className: "text-sm text-sec-600", children: "Access Denied" })
1787
+ ] }) });
1788
+ }
1789
+ function DefaultLoading3() {
1790
+ return /* @__PURE__ */ jsx8("div", { className: "flex items-center justify-center p-2", children: /* @__PURE__ */ jsxs5("div", { className: "flex items-center space-x-2", children: [
1791
+ /* @__PURE__ */ jsx8("div", { className: "animate-spin rounded-full h-4 w-4 border-b-2 border-main-600" }),
1792
+ /* @__PURE__ */ jsx8("span", { className: "text-sm text-sec-600", children: "Checking..." })
1793
+ ] }) });
1794
+ }
1795
+ var NavigationGuard_default = NavigationGuard;
1796
+
1797
+ // src/rbac/components/EnhancedNavigationMenu.tsx
1798
+ import { useMemo as useMemo9, useCallback as useCallback9, useEffect as useEffect9, useState as useState9 } from "react";
1799
+ import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
1800
+ function EnhancedNavigationMenu({
1801
+ items,
1802
+ strictMode = true,
1803
+ auditLog = true,
1804
+ onNavigationAccess,
1805
+ onStrictModeViolation,
1806
+ className = "flex flex-col space-y-1",
1807
+ itemClassName = "px-3 py-2 rounded-md text-sm font-medium transition-colors",
1808
+ activeItemClassName = "bg-main-100 text-main-700",
1809
+ disabledItemClassName = "text-sec-400 cursor-not-allowed",
1810
+ hideUnauthorizedItems = false,
1811
+ renderItem,
1812
+ activePath,
1813
+ onItemClick
1814
+ }) {
1815
+ const {
1816
+ hasNavigationPermission,
1817
+ getFilteredNavigationItems,
1818
+ isEnabled,
1819
+ isStrictMode,
1820
+ isAuditLogEnabled
1821
+ } = useNavigationPermissions();
1822
+ const [navigationHistory, setNavigationHistory] = useState9([]);
1823
+ const filteredItems = useMemo9(() => {
1824
+ if (!isEnabled) return items;
1825
+ return getFilteredNavigationItems(items);
1826
+ }, [isEnabled, items, getFilteredNavigationItems]);
1827
+ const handleItemClick = useCallback9((item) => {
1828
+ if (onItemClick) {
1829
+ onItemClick(item);
1830
+ }
1831
+ if (auditLog) {
1832
+ console.log(`[EnhancedNavigationMenu] Navigation item clicked:`, {
1833
+ item: item.id,
1834
+ path: item.path,
1835
+ permissions: item.permissions,
1836
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1837
+ });
1838
+ }
1839
+ setNavigationHistory((prev) => {
1840
+ const newHistory = [item, ...prev.filter((i) => i.id !== item.id)];
1841
+ return newHistory.slice(0, 10);
1842
+ });
1843
+ }, [onItemClick, auditLog]);
1844
+ const handleNavigationAccess = useCallback9((item, allowed) => {
1845
+ if (onNavigationAccess) {
1846
+ onNavigationAccess(item, allowed);
1847
+ }
1848
+ if (auditLog) {
1849
+ console.log(`[EnhancedNavigationMenu] Navigation access attempt:`, {
1850
+ item: item.id,
1851
+ allowed,
1852
+ strictMode,
1853
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1854
+ });
1855
+ }
1856
+ }, [onNavigationAccess, auditLog, strictMode]);
1857
+ const handleStrictModeViolation = useCallback9((item) => {
1858
+ if (onStrictModeViolation) {
1859
+ onStrictModeViolation(item);
1860
+ }
1861
+ if (strictMode) {
1862
+ console.error(`[EnhancedNavigationMenu] STRICT MODE VIOLATION: User attempted to access protected navigation item without permission`, {
1863
+ item: item.id,
1864
+ path: item.path,
1865
+ permissions: item.permissions,
1866
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1867
+ });
1868
+ }
1869
+ }, [onStrictModeViolation, strictMode]);
1870
+ const defaultRenderItem = useCallback9((item, isAuthorized) => {
1871
+ const isActive = activePath === item.path;
1872
+ const isDisabled = !isAuthorized;
1873
+ return /* @__PURE__ */ jsx9(
1874
+ NavigationGuard_default,
1875
+ {
1876
+ navigationItem: item,
1877
+ strictMode,
1878
+ auditLog,
1879
+ onDenied: handleStrictModeViolation,
1880
+ fallback: hideUnauthorizedItems ? null : /* @__PURE__ */ jsx9("div", { className: `${itemClassName} ${disabledItemClassName}`, children: /* @__PURE__ */ jsxs6("div", { className: "flex items-center space-x-2", children: [
1881
+ item.meta?.icon && /* @__PURE__ */ jsx9("span", { className: "text-sm", children: item.meta.icon }),
1882
+ /* @__PURE__ */ jsx9("span", { children: item.label }),
1883
+ /* @__PURE__ */ jsx9("span", { className: "text-xs text-sec-400", children: "(Access Denied)" })
1884
+ ] }) }),
1885
+ children: /* @__PURE__ */ jsx9(
1886
+ "button",
1887
+ {
1888
+ onClick: () => handleItemClick(item),
1889
+ className: `${itemClassName} ${isActive ? activeItemClassName : ""} ${isDisabled ? disabledItemClassName : "hover:bg-sec-100"}`,
1890
+ disabled: isDisabled,
1891
+ children: /* @__PURE__ */ jsxs6("div", { className: "flex items-center space-x-2", children: [
1892
+ item.meta?.icon && /* @__PURE__ */ jsx9("span", { className: "text-sm", children: item.meta.icon }),
1893
+ /* @__PURE__ */ jsx9("span", { children: item.label }),
1894
+ item.meta?.description && /* @__PURE__ */ jsx9("span", { className: "text-xs text-sec-500 ml-auto", children: item.meta.description })
1895
+ ] })
1896
+ }
1897
+ )
1898
+ },
1899
+ item.id
1900
+ );
1901
+ }, [
1902
+ activePath,
1903
+ itemClassName,
1904
+ activeItemClassName,
1905
+ disabledItemClassName,
1906
+ hideUnauthorizedItems,
1907
+ strictMode,
1908
+ auditLog,
1909
+ handleStrictModeViolation,
1910
+ handleItemClick
1911
+ ]);
1912
+ useEffect9(() => {
1913
+ if (strictMode && auditLog) {
1914
+ console.log(`[EnhancedNavigationMenu] Strict mode enabled - all navigation access attempts will be logged and enforced`);
1915
+ }
1916
+ }, [strictMode, auditLog]);
1917
+ useEffect9(() => {
1918
+ if (auditLog) {
1919
+ console.log(`[EnhancedNavigationMenu] Navigation menu initialized:`, {
1920
+ totalItems: items.length,
1921
+ filteredItems: filteredItems.length,
1922
+ strictMode,
1923
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1924
+ });
1925
+ }
1926
+ }, [items.length, filteredItems.length, strictMode, auditLog]);
1927
+ return /* @__PURE__ */ jsx9("nav", { className, children: filteredItems.map((item) => {
1928
+ const isAuthorized = hasNavigationPermission(item);
1929
+ if (renderItem) {
1930
+ return renderItem(item, isAuthorized);
1931
+ }
1932
+ return defaultRenderItem(item, isAuthorized);
1933
+ }) });
1934
+ }
1935
+
1936
+ // src/rbac/permissions.ts
1937
+ var GLOBAL_PERMISSIONS = {
1938
+ MANAGE_ALL: "manage:*",
1939
+ READ_ALL: "read:*",
1940
+ CREATE_ALL: "create:*",
1941
+ UPDATE_ALL: "update:*",
1942
+ DELETE_ALL: "delete:*"
1943
+ };
1944
+ var ORGANISATION_PERMISSIONS = {
1945
+ // Organisation management
1946
+ MANAGE_ORGANISATION: "manage:organisation",
1947
+ READ_ORGANISATION: "read:organisation",
1948
+ UPDATE_ORGANISATION: "update:organisation",
1949
+ // User management
1950
+ MANAGE_USERS: "manage:users",
1951
+ READ_USERS: "read:users",
1952
+ CREATE_USERS: "create:users",
1953
+ UPDATE_USERS: "update:users",
1954
+ DELETE_USERS: "delete:users",
1955
+ // Role management
1956
+ MANAGE_ROLES: "manage:roles",
1957
+ READ_ROLES: "read:roles",
1958
+ CREATE_ROLES: "create:roles",
1959
+ UPDATE_ROLES: "update:roles",
1960
+ DELETE_ROLES: "delete:roles",
1961
+ // Event management
1962
+ MANAGE_EVENTS: "manage:events",
1963
+ READ_EVENTS: "read:events",
1964
+ CREATE_EVENTS: "create:events",
1965
+ UPDATE_EVENTS: "update:events",
1966
+ DELETE_EVENTS: "delete:events",
1967
+ // App management
1968
+ MANAGE_APPS: "manage:apps",
1969
+ READ_APPS: "read:apps",
1970
+ CREATE_APPS: "create:apps",
1971
+ UPDATE_APPS: "update:apps",
1972
+ DELETE_APPS: "delete:apps"
1973
+ };
1974
+ var EVENT_APP_PERMISSIONS = {
1975
+ // Event management
1976
+ MANAGE_EVENT: "manage:event",
1977
+ READ_EVENT: "read:event",
1978
+ UPDATE_EVENT: "update:event",
1979
+ // App management
1980
+ MANAGE_APP: "manage:app",
1981
+ READ_APP: "read:app",
1982
+ UPDATE_APP: "update:app",
1983
+ // Team management
1984
+ MANAGE_TEAM: "manage:team",
1985
+ READ_TEAM: "read:team",
1986
+ CREATE_TEAM: "create:team",
1987
+ UPDATE_TEAM: "update:team",
1988
+ DELETE_TEAM: "delete:team",
1989
+ // Team members
1990
+ MANAGE_TEAM_MEMBERS: "manage:team.members",
1991
+ READ_TEAM_MEMBERS: "read:team.members",
1992
+ CREATE_TEAM_MEMBERS: "create:team.members",
1993
+ UPDATE_TEAM_MEMBERS: "update:team.members",
1994
+ DELETE_TEAM_MEMBERS: "delete:team.members",
1995
+ // Event content
1996
+ MANAGE_EVENT_CONTENT: "manage:event.content",
1997
+ READ_EVENT_CONTENT: "read:event.content",
1998
+ CREATE_EVENT_CONTENT: "create:event.content",
1999
+ UPDATE_EVENT_CONTENT: "update:event.content",
2000
+ DELETE_EVENT_CONTENT: "delete:event.content",
2001
+ // Event settings
2002
+ MANAGE_EVENT_SETTINGS: "manage:event.settings",
2003
+ READ_EVENT_SETTINGS: "read:event.settings",
2004
+ UPDATE_EVENT_SETTINGS: "update:event.settings"
2005
+ };
2006
+ var PAGE_PERMISSIONS = {
2007
+ // General page access
2008
+ READ_PAGE: "read:page",
2009
+ MANAGE_PAGE: "manage:page",
2010
+ // Admin pages
2011
+ READ_ADMIN: "read:admin",
2012
+ MANAGE_ADMIN: "manage:admin",
2013
+ // Dashboard pages
2014
+ READ_DASHBOARD: "read:dashboard",
2015
+ MANAGE_DASHBOARD: "manage:dashboard",
2016
+ // Settings pages
2017
+ READ_SETTINGS: "read:settings",
2018
+ MANAGE_SETTINGS: "manage:settings",
2019
+ // Reports pages
2020
+ READ_REPORTS: "read:reports",
2021
+ MANAGE_REPORTS: "manage:reports"
2022
+ };
2023
+ var PERMISSION_GROUPS = {
2024
+ // Global admin permissions
2025
+ GLOBAL_ADMIN: [
2026
+ GLOBAL_PERMISSIONS.MANAGE_ALL,
2027
+ GLOBAL_PERMISSIONS.READ_ALL,
2028
+ GLOBAL_PERMISSIONS.CREATE_ALL,
2029
+ GLOBAL_PERMISSIONS.UPDATE_ALL,
2030
+ GLOBAL_PERMISSIONS.DELETE_ALL
2031
+ ],
2032
+ // Organisation admin permissions
2033
+ ORG_ADMIN: [
2034
+ ORGANISATION_PERMISSIONS.MANAGE_ORGANISATION,
2035
+ ORGANISATION_PERMISSIONS.READ_ORGANISATION,
2036
+ ORGANISATION_PERMISSIONS.UPDATE_ORGANISATION,
2037
+ ORGANISATION_PERMISSIONS.MANAGE_USERS,
2038
+ ORGANISATION_PERMISSIONS.READ_USERS,
2039
+ ORGANISATION_PERMISSIONS.CREATE_USERS,
2040
+ ORGANISATION_PERMISSIONS.UPDATE_USERS,
2041
+ ORGANISATION_PERMISSIONS.DELETE_USERS,
2042
+ ORGANISATION_PERMISSIONS.MANAGE_ROLES,
2043
+ ORGANISATION_PERMISSIONS.READ_ROLES,
2044
+ ORGANISATION_PERMISSIONS.CREATE_ROLES,
2045
+ ORGANISATION_PERMISSIONS.UPDATE_ROLES,
2046
+ ORGANISATION_PERMISSIONS.DELETE_ROLES,
2047
+ ORGANISATION_PERMISSIONS.MANAGE_EVENTS,
2048
+ ORGANISATION_PERMISSIONS.READ_EVENTS,
2049
+ ORGANISATION_PERMISSIONS.CREATE_EVENTS,
2050
+ ORGANISATION_PERMISSIONS.UPDATE_EVENTS,
2051
+ ORGANISATION_PERMISSIONS.DELETE_EVENTS,
2052
+ ORGANISATION_PERMISSIONS.MANAGE_APPS,
2053
+ ORGANISATION_PERMISSIONS.READ_APPS,
2054
+ ORGANISATION_PERMISSIONS.CREATE_APPS,
2055
+ ORGANISATION_PERMISSIONS.UPDATE_APPS,
2056
+ ORGANISATION_PERMISSIONS.DELETE_APPS
2057
+ ],
2058
+ // Event admin permissions
2059
+ EVENT_ADMIN: [
2060
+ EVENT_APP_PERMISSIONS.MANAGE_EVENT,
2061
+ EVENT_APP_PERMISSIONS.READ_EVENT,
2062
+ EVENT_APP_PERMISSIONS.UPDATE_EVENT,
2063
+ EVENT_APP_PERMISSIONS.MANAGE_APP,
2064
+ EVENT_APP_PERMISSIONS.READ_APP,
2065
+ EVENT_APP_PERMISSIONS.UPDATE_APP,
2066
+ EVENT_APP_PERMISSIONS.MANAGE_TEAM,
2067
+ EVENT_APP_PERMISSIONS.READ_TEAM,
2068
+ EVENT_APP_PERMISSIONS.CREATE_TEAM,
2069
+ EVENT_APP_PERMISSIONS.UPDATE_TEAM,
2070
+ EVENT_APP_PERMISSIONS.DELETE_TEAM,
2071
+ EVENT_APP_PERMISSIONS.MANAGE_TEAM_MEMBERS,
2072
+ EVENT_APP_PERMISSIONS.READ_TEAM_MEMBERS,
2073
+ EVENT_APP_PERMISSIONS.CREATE_TEAM_MEMBERS,
2074
+ EVENT_APP_PERMISSIONS.UPDATE_TEAM_MEMBERS,
2075
+ EVENT_APP_PERMISSIONS.DELETE_TEAM_MEMBERS,
2076
+ EVENT_APP_PERMISSIONS.MANAGE_EVENT_CONTENT,
2077
+ EVENT_APP_PERMISSIONS.READ_EVENT_CONTENT,
2078
+ EVENT_APP_PERMISSIONS.CREATE_EVENT_CONTENT,
2079
+ EVENT_APP_PERMISSIONS.UPDATE_EVENT_CONTENT,
2080
+ EVENT_APP_PERMISSIONS.DELETE_EVENT_CONTENT,
2081
+ EVENT_APP_PERMISSIONS.MANAGE_EVENT_SETTINGS,
2082
+ EVENT_APP_PERMISSIONS.READ_EVENT_SETTINGS,
2083
+ EVENT_APP_PERMISSIONS.UPDATE_EVENT_SETTINGS
2084
+ ],
2085
+ // Planner permissions
2086
+ PLANNER: [
2087
+ EVENT_APP_PERMISSIONS.READ_EVENT,
2088
+ EVENT_APP_PERMISSIONS.UPDATE_EVENT,
2089
+ EVENT_APP_PERMISSIONS.READ_APP,
2090
+ EVENT_APP_PERMISSIONS.UPDATE_APP,
2091
+ EVENT_APP_PERMISSIONS.READ_TEAM,
2092
+ EVENT_APP_PERMISSIONS.CREATE_TEAM,
2093
+ EVENT_APP_PERMISSIONS.UPDATE_TEAM,
2094
+ EVENT_APP_PERMISSIONS.READ_TEAM_MEMBERS,
2095
+ EVENT_APP_PERMISSIONS.CREATE_TEAM_MEMBERS,
2096
+ EVENT_APP_PERMISSIONS.UPDATE_TEAM_MEMBERS,
2097
+ EVENT_APP_PERMISSIONS.READ_EVENT_CONTENT,
2098
+ EVENT_APP_PERMISSIONS.CREATE_EVENT_CONTENT,
2099
+ EVENT_APP_PERMISSIONS.UPDATE_EVENT_CONTENT,
2100
+ EVENT_APP_PERMISSIONS.READ_EVENT_SETTINGS,
2101
+ EVENT_APP_PERMISSIONS.UPDATE_EVENT_SETTINGS
2102
+ ],
2103
+ // Participant permissions
2104
+ PARTICIPANT: [
2105
+ EVENT_APP_PERMISSIONS.READ_EVENT,
2106
+ EVENT_APP_PERMISSIONS.READ_APP,
2107
+ EVENT_APP_PERMISSIONS.READ_TEAM,
2108
+ EVENT_APP_PERMISSIONS.READ_TEAM_MEMBERS,
2109
+ EVENT_APP_PERMISSIONS.READ_EVENT_CONTENT,
2110
+ EVENT_APP_PERMISSIONS.READ_EVENT_SETTINGS
2111
+ ],
2112
+ // Viewer permissions
2113
+ VIEWER: [
2114
+ EVENT_APP_PERMISSIONS.READ_EVENT,
2115
+ EVENT_APP_PERMISSIONS.READ_APP,
2116
+ EVENT_APP_PERMISSIONS.READ_TEAM,
2117
+ EVENT_APP_PERMISSIONS.READ_EVENT_CONTENT
2118
+ ]
2119
+ };
2120
+ function isValidPermission(permission) {
2121
+ const pattern = /^(read|create|update|delete|manage):[a-z0-9._-]+$|^(read|create|update|delete|manage):\*$/;
2122
+ return pattern.test(permission);
2123
+ }
2124
+ function getPermissionsForRole(role) {
2125
+ switch (role) {
2126
+ case "super_admin":
2127
+ return [...PERMISSION_GROUPS.GLOBAL_ADMIN];
2128
+ case "org_admin":
2129
+ return [...PERMISSION_GROUPS.ORG_ADMIN];
2130
+ case "event_admin":
2131
+ return [...PERMISSION_GROUPS.EVENT_ADMIN];
2132
+ case "planner":
2133
+ return [...PERMISSION_GROUPS.PLANNER];
2134
+ case "participant":
2135
+ return [...PERMISSION_GROUPS.PARTICIPANT];
2136
+ case "viewer":
2137
+ return [...PERMISSION_GROUPS.VIEWER];
2138
+ default:
2139
+ return [];
2140
+ }
2141
+ }
2142
+ var ALL_PERMISSIONS = {
2143
+ ...GLOBAL_PERMISSIONS,
2144
+ ...ORGANISATION_PERMISSIONS,
2145
+ ...EVENT_APP_PERMISSIONS,
2146
+ ...PAGE_PERMISSIONS
2147
+ };
2148
+ export {
2149
+ ALL_PERMISSIONS,
2150
+ AccessLevelGuard,
2151
+ CACHE_PATTERNS,
2152
+ EVENT_APP_PERMISSIONS,
2153
+ EnhancedNavigationMenu,
2154
+ GLOBAL_PERMISSIONS,
2155
+ NavigationGuard,
2156
+ NavigationProvider,
2157
+ ORGANISATION_PERMISSIONS,
2158
+ PAGE_PERMISSIONS,
2159
+ PERMISSION_GROUPS,
2160
+ PagePermissionGuard,
2161
+ PagePermissionProvider,
2162
+ PermissionEnforcer,
2163
+ PermissionGuard,
2164
+ RBACAuditManager,
2165
+ RBACCache,
2166
+ RBACEngine,
2167
+ RoleBasedRouter,
2168
+ SecureDataProvider,
2169
+ SecureSupabaseClient,
2170
+ createAuditManager,
2171
+ createRBACConfig,
2172
+ createRBACEngine,
2173
+ createRBACExpressMiddleware,
2174
+ createRBACMiddleware,
2175
+ createSecureClient,
2176
+ emitAuditEvent,
2177
+ fromSupabaseClient,
2178
+ getAccessLevel,
2179
+ getGlobalAuditManager,
2180
+ getPermissionMap,
2181
+ getPermissionsForRole,
2182
+ getRBACConfig,
2183
+ getRBACLogger,
2184
+ hasAllPermissions,
2185
+ hasAnyPermission,
2186
+ hasAnyPermissionCached,
2187
+ hasPermission,
2188
+ hasPermissionCached,
2189
+ isDebugMode,
2190
+ isDevelopmentMode,
2191
+ isPermitted,
2192
+ isPermittedCached,
2193
+ isValidPermission,
2194
+ rbacCache,
2195
+ setGlobalAuditManager,
2196
+ setupRBAC,
2197
+ useAccessLevel,
2198
+ useCachedPermissions,
2199
+ useCan,
2200
+ useHasAllPermissions,
2201
+ useHasAnyPermission,
2202
+ useMultiplePermissions,
2203
+ useNavigationPermissions,
2204
+ usePagePermissions,
2205
+ usePermissions,
2206
+ useRoleBasedRouter,
2207
+ useSecureData,
2208
+ withAccessLevelGuard,
2209
+ withPermissionGuard,
2210
+ withRoleGuard
2211
+ };
2212
+ //# sourceMappingURL=index.js.map