@jmruthers/pace-core 0.5.76 → 0.5.78

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 (447) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/{RBACService-C4udt_Zp.d.ts → AuthService-Df3IozMG.d.ts} +10 -118
  3. package/dist/{DataTable-ntgmhO2W.d.ts → DataTable-BE0OXZKQ.d.ts} +9 -2
  4. package/dist/{DataTable-4GAVPIEG.js → DataTable-ETGVF4Y5.js} +50 -13
  5. package/dist/{PublicLoadingSpinner-BiNER8F5.d.ts → PublicLoadingSpinner-CnUaz0vG.d.ts} +5 -2
  6. package/dist/{UnifiedAuthProvider-Bj6YCf7c.d.ts → UnifiedAuthProvider-B391Aqum.d.ts} +42 -45
  7. package/dist/{UnifiedAuthProvider-3NKDOSOK.js → UnifiedAuthProvider-P5SOJAQ6.js} +4 -5
  8. package/dist/{api-DDMUKIUD.js → api-KG4A2X7P.js} +9 -3
  9. package/dist/{audit-6TOCAMKO.js → audit-65VNHEV2.js} +2 -2
  10. package/dist/{chunk-K34IM5CT.js → chunk-2OGV6IRV.js} +196 -626
  11. package/dist/chunk-2OGV6IRV.js.map +1 -0
  12. package/dist/{chunk-NTNILOBC.js → chunk-5BO3MI5Y.js} +4 -4
  13. package/dist/{chunk-XLZ7U46Z.js → chunk-CVMVPYAL.js} +9 -60
  14. package/dist/chunk-CVMVPYAL.js.map +1 -0
  15. package/dist/{chunk-URUTVZ7N.js → chunk-FL4ZCQLD.js} +2 -2
  16. package/dist/{chunk-LW7MMEAQ.js → chunk-FT2M4R4F.js} +2 -2
  17. package/dist/{chunk-5BSLGBYI.js → chunk-JCQZ6LA7.js} +2 -8
  18. package/dist/{chunk-5BSLGBYI.js.map → chunk-JCQZ6LA7.js.map} +1 -1
  19. package/dist/{chunk-KHJS6VIA.js → chunk-LRQ6RBJC.js} +157 -112
  20. package/dist/chunk-LRQ6RBJC.js.map +1 -0
  21. package/dist/{chunk-WN6XJWOS.js → chunk-MNJXXD6C.js} +274 -743
  22. package/dist/chunk-MNJXXD6C.js.map +1 -0
  23. package/dist/{chunk-KK73ZB4E.js → chunk-PTR5PMPE.js} +153 -132
  24. package/dist/chunk-PTR5PMPE.js.map +1 -0
  25. package/dist/{chunk-B2WTCLCV.js → chunk-Q7APDV6H.js} +18 -8
  26. package/dist/chunk-Q7APDV6H.js.map +1 -0
  27. package/dist/{chunk-A4FUBC7B.js → chunk-QGVSOUJ2.js} +2 -4
  28. package/dist/{chunk-A4FUBC7B.js.map → chunk-QGVSOUJ2.js.map} +1 -1
  29. package/dist/{chunk-FGMFQSHX.js → chunk-S63MFSY6.js} +500 -551
  30. package/dist/chunk-S63MFSY6.js.map +1 -0
  31. package/dist/{chunk-AFGTSUAD.js → chunk-VSOKOFRF.js} +4 -4
  32. package/dist/chunk-WUXCWRL6.js +20 -0
  33. package/dist/chunk-WUXCWRL6.js.map +1 -0
  34. package/dist/{chunk-Y6TXWPJO.js → chunk-YVVGHRGI.js} +105 -31
  35. package/dist/chunk-YVVGHRGI.js.map +1 -0
  36. package/dist/{chunk-M5IWZRBT.js → chunk-ZMNXIJP4.js} +2187 -981
  37. package/dist/chunk-ZMNXIJP4.js.map +1 -0
  38. package/dist/components.d.ts +6 -6
  39. package/dist/components.js +14 -18
  40. package/dist/components.js.map +1 -1
  41. package/dist/{database-C3Szpi5J.d.ts → database-BXAfr2Y_.d.ts} +18 -0
  42. package/dist/hooks.d.ts +5 -5
  43. package/dist/hooks.js +8 -9
  44. package/dist/hooks.js.map +1 -1
  45. package/dist/index.d.ts +19 -27
  46. package/dist/index.js +21 -29
  47. package/dist/index.js.map +1 -1
  48. package/dist/{organisation-BtshODVF.d.ts → organisation-D6qRDtbF.d.ts} +1 -1
  49. package/dist/providers.d.ts +7 -21
  50. package/dist/providers.js +3 -10
  51. package/dist/rbac/index.d.ts +71 -221
  52. package/dist/rbac/index.js +15 -16
  53. package/dist/{types-CGX9Vyf5.d.ts → types-BDg1mAGG.d.ts} +36 -6
  54. package/dist/types.d.ts +3 -3
  55. package/dist/types.js +61 -18
  56. package/dist/types.js.map +1 -1
  57. package/dist/{unified-CM7T0aTK.d.ts → unified-DQ4VcT7H.d.ts} +1 -1
  58. package/dist/{usePublicRouteParams-B-CumWRc.d.ts → usePublicRouteParams-BlgwXweB.d.ts} +3 -3
  59. package/dist/utils.d.ts +2 -2
  60. package/dist/utils.js +52 -9
  61. package/dist/utils.js.map +1 -1
  62. package/docs/CONTENT_AUDIT_REPORT.md +253 -0
  63. package/docs/DOCUMENTATION_AUDIT.md +172 -0
  64. package/docs/README.md +142 -147
  65. package/docs/STYLE_GUIDE.md +37 -0
  66. package/docs/api/classes/ColumnFactory.md +17 -17
  67. package/docs/api/classes/ErrorBoundary.md +1 -1
  68. package/docs/api/classes/InvalidScopeError.md +4 -4
  69. package/docs/api/classes/MissingUserContextError.md +4 -4
  70. package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
  71. package/docs/api/classes/PermissionDeniedError.md +5 -5
  72. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  73. package/docs/api/classes/RBACAuditManager.md +8 -8
  74. package/docs/api/classes/RBACCache.md +35 -5
  75. package/docs/api/classes/RBACEngine.md +49 -20
  76. package/docs/api/classes/RBACError.md +4 -4
  77. package/docs/api/classes/RBACNotInitializedError.md +4 -4
  78. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  79. package/docs/api/classes/StorageUtils.md +1 -1
  80. package/docs/api/enums/FileCategory.md +1 -1
  81. package/docs/api/interfaces/AggregateConfig.md +4 -4
  82. package/docs/api/interfaces/ButtonProps.md +1 -1
  83. package/docs/api/interfaces/CardProps.md +1 -1
  84. package/docs/api/interfaces/ColorPalette.md +1 -1
  85. package/docs/api/interfaces/ColorShade.md +1 -1
  86. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  87. package/docs/api/interfaces/DataRecord.md +11 -0
  88. package/docs/api/interfaces/DataTableAction.md +65 -29
  89. package/docs/api/interfaces/DataTableColumn.md +36 -23
  90. package/docs/api/interfaces/DataTableProps.md +80 -38
  91. package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
  92. package/docs/api/interfaces/EmptyStateConfig.md +5 -5
  93. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  94. package/docs/api/interfaces/EventLogoProps.md +1 -1
  95. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  96. package/docs/api/interfaces/FileMetadata.md +1 -1
  97. package/docs/api/interfaces/FileReference.md +1 -1
  98. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  99. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  100. package/docs/api/interfaces/FileUploadProps.md +1 -1
  101. package/docs/api/interfaces/FooterProps.md +1 -1
  102. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  103. package/docs/api/interfaces/InputProps.md +1 -1
  104. package/docs/api/interfaces/LabelProps.md +1 -1
  105. package/docs/api/interfaces/LoginFormProps.md +1 -1
  106. package/docs/api/interfaces/NavigationAccessRecord.md +11 -11
  107. package/docs/api/interfaces/NavigationContextType.md +9 -9
  108. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  109. package/docs/api/interfaces/NavigationItem.md +1 -1
  110. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  111. package/docs/api/interfaces/NavigationProviderProps.md +7 -7
  112. package/docs/api/interfaces/Organisation.md +1 -1
  113. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  114. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  115. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  116. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  117. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  118. package/docs/api/interfaces/PaceLoginPageProps.md +16 -3
  119. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  120. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  121. package/docs/api/interfaces/PagePermissionGuardProps.md +2 -2
  122. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  123. package/docs/api/interfaces/PaletteData.md +1 -1
  124. package/docs/api/interfaces/PermissionEnforcerProps.md +4 -4
  125. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  126. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  127. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  128. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  129. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  130. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  131. package/docs/api/interfaces/RBACConfig.md +1 -1
  132. package/docs/api/interfaces/RBACLogger.md +1 -1
  133. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  134. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  135. package/docs/api/interfaces/RouteAccessRecord.md +2 -2
  136. package/docs/api/interfaces/RouteConfig.md +2 -2
  137. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  138. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  139. package/docs/api/interfaces/StorageConfig.md +1 -1
  140. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  141. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  142. package/docs/api/interfaces/StorageListOptions.md +1 -1
  143. package/docs/api/interfaces/StorageListResult.md +1 -1
  144. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  145. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  146. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  147. package/docs/api/interfaces/StyleImport.md +1 -1
  148. package/docs/api/interfaces/SwitchProps.md +1 -1
  149. package/docs/api/interfaces/ToastActionElement.md +1 -1
  150. package/docs/api/interfaces/ToastProps.md +1 -1
  151. package/docs/api/interfaces/UnifiedAuthContextType.md +94 -521
  152. package/docs/api/interfaces/UnifiedAuthProviderProps.md +16 -16
  153. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  154. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  155. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  156. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  157. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  158. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  159. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  160. package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
  161. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  162. package/docs/api/interfaces/UserEventAccess.md +11 -11
  163. package/docs/api/interfaces/UserMenuProps.md +1 -1
  164. package/docs/api/interfaces/UserProfile.md +1 -1
  165. package/docs/api/modules.md +251 -269
  166. package/docs/api-reference/components.md +193 -0
  167. package/docs/api-reference/hooks.md +265 -0
  168. package/docs/api-reference/providers.md +6 -0
  169. package/docs/api-reference/types.md +6 -0
  170. package/docs/api-reference/utilities.md +207 -0
  171. package/docs/architecture/README.md +6 -0
  172. package/docs/{database-schema-requirements.md → architecture/database-schema-requirements.md} +6 -0
  173. package/docs/architecture/rbac-security-architecture.md +258 -0
  174. package/docs/architecture/services.md +9 -1
  175. package/docs/best-practices/README.md +6 -0
  176. package/docs/best-practices/accessibility.md +6 -0
  177. package/docs/{common-patterns.md → best-practices/common-patterns.md} +6 -0
  178. package/docs/best-practices/deployment.md +6 -0
  179. package/docs/best-practices/performance.md +475 -2
  180. package/docs/best-practices/security.md +6 -0
  181. package/docs/best-practices/testing.md +6 -0
  182. package/docs/core-concepts/authentication.md +6 -0
  183. package/docs/core-concepts/events.md +6 -0
  184. package/docs/core-concepts/organisations.md +6 -0
  185. package/docs/core-concepts/permissions.md +6 -0
  186. package/docs/core-concepts/rbac-system.md +8 -0
  187. package/docs/documentation-index.md +121 -182
  188. package/docs/{consuming-app-vite-config.md → getting-started/consuming-app-vite-config.md} +6 -0
  189. package/docs/getting-started/documentation-index.md +40 -0
  190. package/docs/getting-started/examples/README.md +878 -35
  191. package/docs/{faq.md → getting-started/faq.md} +7 -1
  192. package/docs/getting-started/installation-guide.md +6 -0
  193. package/docs/{quick-reference.md → getting-started/quick-reference.md} +6 -0
  194. package/docs/implementation-guides/app-layout.md +6 -0
  195. package/docs/implementation-guides/authentication.md +1021 -0
  196. package/docs/implementation-guides/component-styling.md +6 -0
  197. package/docs/implementation-guides/data-tables.md +1264 -2076
  198. package/docs/implementation-guides/dynamic-colors.md +6 -0
  199. package/docs/implementation-guides/event-theming-summary.md +6 -0
  200. package/docs/{file-reference-system.md → implementation-guides/file-reference-system.md} +6 -0
  201. package/docs/implementation-guides/file-upload-storage.md +6 -0
  202. package/docs/implementation-guides/forms.md +6 -0
  203. package/docs/implementation-guides/inactivity-tracking.md +6 -0
  204. package/docs/implementation-guides/navigation.md +6 -0
  205. package/docs/implementation-guides/organisation-security.md +6 -0
  206. package/docs/implementation-guides/permission-enforcement.md +6 -0
  207. package/docs/implementation-guides/public-pages-advanced.md +6 -0
  208. package/docs/implementation-guides/public-pages.md +6 -0
  209. package/docs/migration/MIGRATION_GUIDE.md +827 -351
  210. package/docs/migration/README.md +7 -1
  211. package/docs/migration/organisation-context-timing-fix.md +6 -0
  212. package/docs/migration/rbac-migration.md +44 -1
  213. package/docs/migration/service-architecture.md +6 -0
  214. package/docs/migration/v0.4.15-tailwind-scanning.md +6 -0
  215. package/docs/migration/v0.4.16-css-first-approach.md +6 -0
  216. package/docs/migration/v0.4.17-source-path-fix.md +6 -0
  217. package/docs/rbac/README-rbac-rls-integration.md +6 -0
  218. package/docs/rbac/README.md +6 -0
  219. package/docs/rbac/advanced-patterns.md +6 -0
  220. package/docs/rbac/api-reference.md +7 -1
  221. package/docs/rbac/breaking-changes-v3.md +222 -0
  222. package/docs/rbac/examples/rbac-rls-integration-example.md +6 -0
  223. package/docs/rbac/examples.md +6 -0
  224. package/docs/rbac/getting-started.md +6 -0
  225. package/docs/rbac/migration-guide.md +260 -0
  226. package/docs/rbac/quick-start.md +70 -13
  227. package/docs/rbac/rbac-rls-integration.md +6 -0
  228. package/docs/rbac/super-admin-guide.md +6 -0
  229. package/docs/rbac/troubleshooting.md +6 -0
  230. package/docs/security/README.md +6 -0
  231. package/docs/security/checklist.md +6 -0
  232. package/docs/styles/README.md +7 -1
  233. package/docs/{usage.md → styles/usage.md} +6 -0
  234. package/docs/testing/README.md +6 -0
  235. package/docs/{visual-testing.md → testing/visual-testing.md} +6 -0
  236. package/docs/troubleshooting/README.md +387 -5
  237. package/docs/troubleshooting/cake-page-permission-guard-issue-summary.md +6 -0
  238. package/docs/troubleshooting/common-issues.md +6 -0
  239. package/docs/troubleshooting/database-view-compatibility.md +6 -0
  240. package/docs/troubleshooting/organisation-context-setup.md +6 -0
  241. package/docs/troubleshooting/react-hooks-issue-analysis.md +6 -0
  242. package/docs/troubleshooting/styling-issues.md +6 -0
  243. package/docs/troubleshooting/tailwind-content-scanning.md +6 -0
  244. package/package.json +1 -1
  245. package/src/__tests__/helpers/__tests__/test-providers.test.tsx +2 -1
  246. package/src/__tests__/helpers/test-providers.tsx +3 -53
  247. package/src/components/DataTable/DataTable.test.tsx +319 -0
  248. package/src/components/DataTable/DataTable.tsx +32 -11
  249. package/src/components/DataTable/__tests__/{DataTable.comprehensive.test.tsx → DataTable.comprehensive.test.tsx.skip} +6 -4
  250. package/src/components/DataTable/__tests__/{DataTable.test.tsx → DataTable.test.tsx.skip} +6 -4
  251. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +31 -9
  252. package/src/components/DataTable/__tests__/a11y.basic.test.tsx +601 -0
  253. package/src/components/DataTable/__tests__/keyboard.test.tsx +615 -0
  254. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +639 -0
  255. package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx.skip +330 -0
  256. package/src/components/DataTable/components/AccessDeniedPage.tsx +2 -2
  257. package/src/components/DataTable/components/ActionButtons.tsx +88 -104
  258. package/src/components/DataTable/components/DataTableCore.tsx +309 -337
  259. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +4 -2
  260. package/src/components/DataTable/components/DataTableModals.tsx +22 -1
  261. package/src/components/DataTable/components/EditableRow.tsx +69 -84
  262. package/src/components/DataTable/components/EmptyState.tsx +5 -1
  263. package/src/components/DataTable/components/ImportModal.tsx +65 -36
  264. package/src/components/DataTable/components/PaginationControls.tsx +40 -100
  265. package/src/components/DataTable/components/UnifiedTableBody.tsx +125 -148
  266. package/src/components/DataTable/context/DataTableContext.tsx +1 -1
  267. package/src/components/DataTable/core/ColumnFactory.ts +5 -0
  268. package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +12 -10
  269. package/src/components/DataTable/examples/HierarchicalExample.tsx +1 -1
  270. package/src/components/DataTable/examples/InitialPageSizeExample.tsx +1 -0
  271. package/src/components/DataTable/examples/PerformanceExample.tsx +1 -0
  272. package/src/components/DataTable/hooks/__tests__/useColumnOrderPersistence.test.ts +1 -5
  273. package/src/components/DataTable/hooks/__tests__/useColumnVisibilityPersistence.test.ts +167 -0
  274. package/src/components/DataTable/hooks/index.ts +7 -0
  275. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +32 -15
  276. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +102 -0
  277. package/src/components/DataTable/hooks/useDataTableConfiguration.ts +89 -0
  278. package/src/components/DataTable/hooks/useDataTableDataPipeline.ts +117 -0
  279. package/src/components/DataTable/hooks/useDataTablePermissions.ts +71 -27
  280. package/src/components/DataTable/hooks/useDataTableState.ts +39 -11
  281. package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +33 -0
  282. package/src/components/DataTable/hooks/useHierarchicalState.ts +15 -1
  283. package/src/components/DataTable/hooks/useKeyboardNavigation.ts +447 -0
  284. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +94 -0
  285. package/src/components/DataTable/hooks/useTableColumns.ts +10 -7
  286. package/src/components/DataTable/hooks/useTableHandlers.ts +174 -0
  287. package/src/components/DataTable/index.ts +12 -3
  288. package/src/components/DataTable/types.ts +129 -9
  289. package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +159 -22
  290. package/src/components/DataTable/utils/__tests__/flexibleImport.test.ts +111 -0
  291. package/src/components/DataTable/utils/__tests__/rowUtils.test.ts +15 -29
  292. package/src/components/DataTable/utils/a11yUtils.ts +244 -0
  293. package/src/components/DataTable/utils/debugTools.ts +609 -0
  294. package/src/components/DataTable/utils/exportUtils.ts +114 -16
  295. package/src/components/DataTable/utils/flexibleImport.ts +202 -32
  296. package/src/components/DataTable/utils/hierarchicalUtils.ts +1 -1
  297. package/src/components/DataTable/utils/index.ts +2 -0
  298. package/src/components/DataTable/utils/paginationUtils.ts +350 -0
  299. package/src/components/DataTable/utils/rowUtils.ts +6 -5
  300. package/src/components/NavigationMenu/NavigationMenu.test.tsx +19 -24
  301. package/src/components/NavigationMenu/NavigationMenu.tsx +19 -8
  302. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +1 -23
  303. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +56 -6
  304. package/src/components/PaceLoginPage/PaceLoginPage.tsx +137 -13
  305. package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +1 -1
  306. package/src/components/Select/Select.tsx +1 -0
  307. package/src/components/examples/PermissionExample.tsx +173 -0
  308. package/src/examples/CorrectPublicPageImplementation.tsx +301 -0
  309. package/src/examples/PublicEventPage.tsx +274 -0
  310. package/src/examples/PublicPageApp.tsx +308 -0
  311. package/src/examples/PublicPageUsageExample.tsx +216 -0
  312. package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +12 -1
  313. package/src/hooks/__tests__/useOrganisationSecurity.unit.test.tsx +129 -17
  314. package/src/hooks/__tests__/useRBAC.unit.test.ts +151 -846
  315. package/src/hooks/useOrganisationPermissions.test.ts +42 -18
  316. package/src/hooks/useOrganisationPermissions.ts +12 -6
  317. package/src/hooks/useOrganisationSecurity.test.ts +138 -85
  318. package/src/hooks/useOrganisationSecurity.ts +41 -10
  319. package/src/index.ts +0 -1
  320. package/src/providers/AuthProvider.simplified.tsx +880 -0
  321. package/src/providers/UnifiedAuthProvider.test.simple.tsx +8 -8
  322. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +29 -19
  323. package/src/providers/index.ts +0 -1
  324. package/src/providers/services/EventServiceProvider.tsx +19 -15
  325. package/src/providers/services/InactivityServiceProvider.tsx +19 -15
  326. package/src/providers/services/OrganisationServiceProvider.tsx +19 -15
  327. package/src/providers/services/UnifiedAuthProvider.tsx +156 -127
  328. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +1 -1
  329. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +3 -3
  330. package/src/rbac/README.md +1 -1
  331. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +25 -27
  332. package/src/rbac/__tests__/auth-rbac-security.integration.test.tsx +313 -0
  333. package/src/rbac/__tests__/engine.comprehensive.test.ts +114 -348
  334. package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +28 -110
  335. package/src/rbac/__tests__/rbac-engine-simplified.test.ts +33 -85
  336. package/src/rbac/__tests__/scenarios.user-role.test.tsx +2 -2
  337. package/src/rbac/adapters.tsx +26 -69
  338. package/src/rbac/api.test.ts +90 -27
  339. package/src/rbac/api.ts +61 -10
  340. package/src/rbac/audit.test.ts +33 -38
  341. package/src/rbac/audit.ts +21 -6
  342. package/src/rbac/cache.ts +33 -1
  343. package/src/rbac/components/NavigationGuard.tsx +11 -11
  344. package/src/rbac/components/NavigationProvider.test.tsx +11 -5
  345. package/src/rbac/components/NavigationProvider.tsx +37 -13
  346. package/src/rbac/components/PagePermissionGuard.tsx +111 -50
  347. package/src/rbac/components/PagePermissionProvider.tsx +5 -5
  348. package/src/rbac/components/PermissionEnforcer.tsx +11 -11
  349. package/src/rbac/components/RoleBasedRouter.tsx +5 -5
  350. package/src/rbac/components/SecureDataProvider.tsx +5 -5
  351. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +8 -8
  352. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +14 -14
  353. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +12 -12
  354. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +6 -6
  355. package/src/rbac/engine.test.simple.ts +19 -13
  356. package/src/rbac/engine.test.ts +1 -0
  357. package/src/rbac/engine.ts +330 -766
  358. package/src/rbac/errors.ts +156 -0
  359. package/src/rbac/hooks/usePermissions.ts +32 -10
  360. package/src/rbac/hooks/useRBAC.test.ts +126 -512
  361. package/src/rbac/hooks/useRBAC.ts +147 -193
  362. package/src/rbac/hooks/useResolvedScope.ts +12 -0
  363. package/src/rbac/index.ts +7 -4
  364. package/src/rbac/security.ts +109 -18
  365. package/src/rbac/types.ts +12 -1
  366. package/src/services/AuthService.ts +2 -15
  367. package/src/services/EventService.ts +43 -46
  368. package/src/services/OrganisationService.ts +51 -31
  369. package/src/services/__tests__/AuthService.test.ts +1 -1
  370. package/src/services/__tests__/EventService.test.ts +1 -1
  371. package/src/services/__tests__/OrganisationService.test.ts +1 -1
  372. package/src/services/base/BaseService.ts +8 -0
  373. package/src/styles/base.css +208 -0
  374. package/src/styles/semantic.css +24 -0
  375. package/src/types/database.generated.ts +7347 -0
  376. package/src/types/database.ts +20 -0
  377. package/src/utils/logger.ts +179 -0
  378. package/src/utils/organisationContext.ts +11 -4
  379. package/src/utils/storage/__tests__/helpers.unit.test.ts +6 -2
  380. package/dist/appNameResolver-UURKN7NF.js +0 -22
  381. package/dist/audit-6TOCAMKO.js.map +0 -1
  382. package/dist/chunk-B2WTCLCV.js.map +0 -1
  383. package/dist/chunk-FGMFQSHX.js.map +0 -1
  384. package/dist/chunk-K34IM5CT.js.map +0 -1
  385. package/dist/chunk-KHJS6VIA.js.map +0 -1
  386. package/dist/chunk-KK73ZB4E.js.map +0 -1
  387. package/dist/chunk-M5IWZRBT.js.map +0 -1
  388. package/dist/chunk-ULBI5JGB.js +0 -109
  389. package/dist/chunk-ULBI5JGB.js.map +0 -1
  390. package/dist/chunk-WN6XJWOS.js.map +0 -1
  391. package/dist/chunk-XLZ7U46Z.js.map +0 -1
  392. package/dist/chunk-Y6TXWPJO.js.map +0 -1
  393. package/docs/DOCUMENTATION_CHECKLIST.md +0 -281
  394. package/docs/TERMINOLOGY.md +0 -231
  395. package/docs/api/interfaces/RBACContextType.md +0 -468
  396. package/docs/api/interfaces/RBACProviderProps.md +0 -107
  397. package/docs/best-practices/performance-expansion.md +0 -473
  398. package/docs/breaking-changes.md +0 -179
  399. package/docs/consuming-app-example.md +0 -290
  400. package/docs/documentation-templates.md +0 -539
  401. package/docs/examples/navigation-menu-auth-fix.md +0 -344
  402. package/docs/getting-started/examples/basic-auth-app.md +0 -520
  403. package/docs/getting-started/examples/full-featured-app.md +0 -616
  404. package/docs/getting-started/quick-start.md +0 -376
  405. package/docs/implementation-guides/datatable-filtering.md +0 -313
  406. package/docs/implementation-guides/datatable-rbac-usage.md +0 -317
  407. package/docs/implementation-guides/hierarchical-datatable.md +0 -850
  408. package/docs/implementation-guides/large-datasets.md +0 -281
  409. package/docs/implementation-guides/performance.md +0 -403
  410. package/docs/migration/quick-migration-guide.md +0 -320
  411. package/docs/migration-guide.md +0 -193
  412. package/docs/migration-guides/unified-auth-provider-mandatory-timeouts.md +0 -226
  413. package/docs/performance/README.md +0 -551
  414. package/docs/style-guide.md +0 -964
  415. package/docs/troubleshooting/authentication-issues.md +0 -334
  416. package/docs/troubleshooting/debugging.md +0 -1117
  417. package/docs/troubleshooting/migration.md +0 -918
  418. package/src/__tests__/hooks/usePermissions.test.ts +0 -261
  419. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.rbac.test.tsx +0 -574
  420. package/src/hooks/__tests__/ServiceHooks.test.tsx +0 -613
  421. package/src/hooks/services/__tests__/useServiceHooks.test.tsx +0 -137
  422. package/src/hooks/services/usePermissions.ts +0 -70
  423. package/src/hooks/services/useRBACService.ts +0 -30
  424. package/src/hooks/usePermissionCheck.ts +0 -150
  425. package/src/providers/__tests__/ServiceProviders.test.tsx +0 -477
  426. package/src/providers/services/RBACServiceProvider.tsx +0 -79
  427. package/src/rbac/__tests__/integration.authflow.test.tsx +0 -119
  428. package/src/rbac/__tests__/integration.navigation.test.tsx +0 -69
  429. package/src/rbac/__tests__/integration.securedata.test.tsx +0 -92
  430. package/src/rbac/__tests__/integration.smoke.test.tsx +0 -73
  431. package/src/rbac/providers/RBACProvider.tsx +0 -645
  432. package/src/rbac/providers/__tests__/RBACProvider.integration.test.tsx +0 -688
  433. package/src/rbac/providers/__tests__/RBACProvider.test.tsx +0 -1186
  434. package/src/rbac/providers/index.ts +0 -11
  435. package/src/services/RBACService.ts +0 -522
  436. package/src/services/__tests__/RBACService.test.ts +0 -492
  437. package/src/services/interfaces/IRBACService.ts +0 -62
  438. package/src/utils/appNameResolver.test 2.ts +0 -494
  439. /package/dist/{DataTable-4GAVPIEG.js.map → DataTable-ETGVF4Y5.js.map} +0 -0
  440. /package/dist/{UnifiedAuthProvider-3NKDOSOK.js.map → UnifiedAuthProvider-P5SOJAQ6.js.map} +0 -0
  441. /package/dist/{api-DDMUKIUD.js.map → api-KG4A2X7P.js.map} +0 -0
  442. /package/dist/{appNameResolver-UURKN7NF.js.map → audit-65VNHEV2.js.map} +0 -0
  443. /package/dist/{chunk-NTNILOBC.js.map → chunk-5BO3MI5Y.js.map} +0 -0
  444. /package/dist/{chunk-URUTVZ7N.js.map → chunk-FL4ZCQLD.js.map} +0 -0
  445. /package/dist/{chunk-LW7MMEAQ.js.map → chunk-FT2M4R4F.js.map} +0 -0
  446. /package/dist/{chunk-AFGTSUAD.js.map → chunk-VSOKOFRF.js.map} +0 -0
  447. /package/docs/{app.css.example → styles/app.css.example} +0 -0
@@ -2,34 +2,25 @@ import {
2
2
  createScopeFromEvent,
3
3
  useAccessLevel,
4
4
  useCan
5
- } from "./chunk-KHJS6VIA.js";
5
+ } from "./chunk-LRQ6RBJC.js";
6
6
  import {
7
7
  OrganisationContextRequiredError,
8
8
  RBACCache,
9
9
  getRBACLogger,
10
10
  rbacCache
11
- } from "./chunk-FGMFQSHX.js";
11
+ } from "./chunk-S63MFSY6.js";
12
12
  import {
13
13
  useSecureDataAccess
14
- } from "./chunk-NTNILOBC.js";
14
+ } from "./chunk-5BO3MI5Y.js";
15
15
  import {
16
16
  init_UnifiedAuthProvider
17
- } from "./chunk-URUTVZ7N.js";
17
+ } from "./chunk-FL4ZCQLD.js";
18
18
  import {
19
19
  useUnifiedAuth
20
- } from "./chunk-WN6XJWOS.js";
20
+ } from "./chunk-MNJXXD6C.js";
21
21
  import {
22
- AccessLevel,
23
- init_unified
24
- } from "./chunk-ULBI5JGB.js";
25
- import {
26
- getCurrentAppName,
27
- init_appNameResolver
28
- } from "./chunk-5BSLGBYI.js";
29
- import {
30
- DebugLogger,
31
- init_debugLogger
32
- } from "./chunk-XLZ7U46Z.js";
22
+ getCurrentAppName
23
+ } from "./chunk-JCQZ6LA7.js";
33
24
 
34
25
  // src/rbac/secureClient.ts
35
26
  import { createClient } from "@supabase/supabase-js";
@@ -171,17 +162,17 @@ function PagePermissionProvider({
171
162
  onStrictModeViolation,
172
163
  maxHistorySize = 1e3
173
164
  }) {
174
- const { user, selectedOrganisationId, selectedEventId } = useUnifiedAuth();
165
+ const { user, selectedOrganisation, selectedEvent } = useUnifiedAuth();
175
166
  const [pageAccessHistory, setPageAccessHistory] = useState([]);
176
167
  const [isEnabled, setIsEnabled] = useState(true);
177
168
  const currentScope = useMemo(() => {
178
- if (!selectedOrganisationId) return null;
169
+ if (!selectedOrganisation) return null;
179
170
  return {
180
- organisationId: selectedOrganisationId,
181
- eventId: selectedEventId || void 0,
171
+ organisationId: selectedOrganisation.id,
172
+ eventId: selectedEvent?.event_id || void 0,
182
173
  appId: void 0
183
174
  };
184
- }, [selectedOrganisationId, selectedEventId]);
175
+ }, [selectedOrganisation, selectedEvent]);
185
176
  const hasPagePermission = useCallback((pageName, operation, pageId, scope) => {
186
177
  if (!isEnabled) return true;
187
178
  if (!user?.id) return false;
@@ -257,7 +248,6 @@ function usePagePermissions() {
257
248
  // src/rbac/components/PagePermissionGuard.tsx
258
249
  import { useMemo as useMemo2, useEffect as useEffect2, useState as useState2, useRef } from "react";
259
250
  init_UnifiedAuthProvider();
260
- init_appNameResolver();
261
251
  import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
262
252
  var PagePermissionGuardComponent = ({
263
253
  pageName,
@@ -274,10 +264,11 @@ var PagePermissionGuardComponent = ({
274
264
  const instanceId = useMemo2(() => Math.random().toString(36).substr(2, 9), []);
275
265
  const renderCountRef = useRef(0);
276
266
  renderCountRef.current += 1;
277
- const { user, selectedOrganisationId, selectedEventId, supabase } = useUnifiedAuth();
267
+ const { user, selectedOrganisation, selectedEvent, supabase } = useUnifiedAuth();
278
268
  const [hasChecked, setHasChecked] = useState2(false);
279
269
  const [checkError, setCheckError] = useState2(null);
280
270
  const [resolvedScope, setResolvedScope] = useState2(null);
271
+ const scopeResolutionAbortRef = useRef(null);
281
272
  const supabaseRef = useRef(supabase);
282
273
  supabaseRef.current = supabase;
283
274
  const lastScopeRef = useRef(null);
@@ -304,9 +295,27 @@ var PagePermissionGuardComponent = ({
304
295
  }
305
296
  const stableScope = stableScopeRef.current;
306
297
  useEffect2(() => {
298
+ const abortController = new AbortController();
299
+ scopeResolutionAbortRef.current?.abort();
300
+ scopeResolutionAbortRef.current = abortController;
301
+ const { signal } = abortController;
302
+ const safeSetResolvedScope = (value) => {
303
+ if (!signal.aborted) {
304
+ setResolvedScope(value);
305
+ }
306
+ };
307
+ const safeSetCheckError = (value) => {
308
+ if (!signal.aborted) {
309
+ setCheckError(value);
310
+ }
311
+ };
307
312
  const resolveScope = async () => {
313
+ if (signal.aborted) {
314
+ return;
315
+ }
308
316
  if (scope) {
309
- setResolvedScope(scope);
317
+ safeSetResolvedScope(scope);
318
+ safeSetCheckError(null);
310
319
  return;
311
320
  }
312
321
  let appId = void 0;
@@ -315,9 +324,18 @@ var PagePermissionGuardComponent = ({
315
324
  if (appName) {
316
325
  try {
317
326
  const { data: app, error: error2 } = await supabaseRef.current.from("rbac_apps").select("id, name, is_active").eq("name", appName).eq("is_active", true).single();
327
+ if (signal.aborted) {
328
+ return;
329
+ }
318
330
  if (error2) {
319
331
  console.error("[PagePermissionGuard] Database error resolving app ID:", error2);
332
+ if (signal.aborted) {
333
+ return;
334
+ }
320
335
  const { data: inactiveApp } = await supabaseRef.current.from("rbac_apps").select("id, name, is_active").eq("name", appName).single();
336
+ if (signal.aborted) {
337
+ return;
338
+ }
321
339
  if (inactiveApp) {
322
340
  console.error(`[PagePermissionGuard] App "${appName}" exists but is inactive (is_active: ${inactiveApp.is_active})`);
323
341
  } else {
@@ -329,20 +347,26 @@ var PagePermissionGuardComponent = ({
329
347
  console.error("[PagePermissionGuard] No app data returned for:", appName);
330
348
  }
331
349
  } catch (error2) {
350
+ if (signal.aborted) {
351
+ return;
352
+ }
332
353
  console.error("[PagePermissionGuard] Unexpected error resolving app ID:", error2);
333
354
  }
334
355
  } else {
335
356
  console.error("[PagePermissionGuard] No app name found. Make sure to call setRBACAppName() in your app setup.");
336
357
  }
337
358
  }
338
- if (selectedOrganisationId && selectedEventId) {
359
+ if (signal.aborted) {
360
+ return;
361
+ }
362
+ if (selectedOrganisation && selectedEvent) {
339
363
  if (!appId) {
340
364
  if (import.meta.env.MODE === "test") {
341
365
  console.warn("[PagePermissionGuard] App ID not resolved in test environment, proceeding without it");
342
366
  } else {
343
367
  console.error("[PagePermissionGuard] CRITICAL: App ID not resolved. Check console for details.");
344
- setCheckError(new Error("App ID not resolved. Check console for database errors."));
345
- setResolvedScope(null);
368
+ safeSetCheckError(new Error("App ID not resolved. Check console for database errors."));
369
+ safeSetResolvedScope(null);
346
370
  return;
347
371
  }
348
372
  }
@@ -350,28 +374,31 @@ var PagePermissionGuardComponent = ({
350
374
  const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
351
375
  if (!uuidRegex.test(appId)) {
352
376
  console.error("[PagePermissionGuard] CRITICAL: App ID is not a valid UUID:", appId);
353
- setCheckError(new Error(`Invalid app ID format: ${appId}. Expected UUID.`));
354
- setResolvedScope(null);
377
+ safeSetCheckError(new Error(`Invalid app ID format: ${appId}. Expected UUID.`));
378
+ safeSetResolvedScope(null);
355
379
  return;
356
380
  }
357
381
  }
358
- const resolvedScope2 = {
359
- organisationId: selectedOrganisationId,
360
- eventId: selectedEventId,
382
+ const resolvedContext = {
383
+ organisationId: selectedOrganisation.id,
384
+ eventId: selectedEvent.event_id,
361
385
  appId
362
386
  };
363
- setResolvedScope(resolvedScope2);
364
- setCheckError(null);
387
+ safeSetResolvedScope(resolvedContext);
388
+ safeSetCheckError(null);
389
+ return;
390
+ }
391
+ if (signal.aborted) {
365
392
  return;
366
393
  }
367
- if (selectedOrganisationId) {
394
+ if (selectedOrganisation) {
368
395
  if (!appId) {
369
396
  if (import.meta.env.MODE === "test") {
370
397
  console.warn("[PagePermissionGuard] App ID not resolved in test environment, proceeding without it");
371
398
  } else {
372
399
  console.error("[PagePermissionGuard] CRITICAL: App ID not resolved. Check console for details.");
373
- setCheckError(new Error("App ID not resolved. Check console for database errors."));
374
- setResolvedScope(null);
400
+ safeSetCheckError(new Error("App ID not resolved. Check console for database errors."));
401
+ safeSetResolvedScope(null);
375
402
  return;
376
403
  }
377
404
  }
@@ -379,51 +406,69 @@ var PagePermissionGuardComponent = ({
379
406
  const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
380
407
  if (!uuidRegex.test(appId)) {
381
408
  console.error("[PagePermissionGuard] CRITICAL: App ID is not a valid UUID:", appId);
382
- setCheckError(new Error(`Invalid app ID format: ${appId}. Expected UUID.`));
383
- setResolvedScope(null);
409
+ safeSetCheckError(new Error(`Invalid app ID format: ${appId}. Expected UUID.`));
410
+ safeSetResolvedScope(null);
384
411
  return;
385
412
  }
386
413
  }
387
- const resolvedScope2 = {
388
- organisationId: selectedOrganisationId,
389
- eventId: selectedEventId || void 0,
414
+ const resolvedContext = {
415
+ organisationId: selectedOrganisation.id,
416
+ eventId: selectedEvent?.event_id || void 0,
390
417
  appId
391
418
  };
392
- setResolvedScope(resolvedScope2);
393
- setCheckError(null);
419
+ safeSetResolvedScope(resolvedContext);
420
+ safeSetCheckError(null);
394
421
  return;
395
422
  }
396
- if (selectedEventId && supabaseRef.current) {
423
+ if (signal.aborted) {
424
+ return;
425
+ }
426
+ if (selectedEvent && supabaseRef.current) {
397
427
  try {
398
- const eventScope = await createScopeFromEvent(supabaseRef.current, selectedEventId);
428
+ const eventScope = await createScopeFromEvent(supabaseRef.current, selectedEvent.event_id);
429
+ if (signal.aborted) {
430
+ return;
431
+ }
399
432
  if (!eventScope) {
400
- setCheckError(new Error("Could not resolve organization from event context"));
401
- setResolvedScope(null);
433
+ safeSetCheckError(new Error("Could not resolve organization from event context"));
434
+ safeSetResolvedScope(null);
402
435
  return;
403
436
  }
404
- setResolvedScope({
437
+ safeSetResolvedScope({
405
438
  ...eventScope,
406
439
  appId: appId || eventScope.appId
407
440
  });
408
- setCheckError(null);
441
+ safeSetCheckError(null);
409
442
  } catch (error2) {
410
- setCheckError(error2);
411
- setResolvedScope(null);
443
+ if (signal.aborted) {
444
+ return;
445
+ }
446
+ safeSetCheckError(error2);
447
+ safeSetResolvedScope(null);
412
448
  }
413
449
  return;
414
450
  }
415
- const errorMessage = !selectedOrganisationId && !selectedEventId ? "Either organisation context or event context is required for page permission checking" : "Insufficient context for permission checking. Please ensure you are properly authenticated and have selected an organisation or event.";
451
+ if (signal.aborted) {
452
+ return;
453
+ }
454
+ const errorMessage = !selectedOrganisation && !selectedEvent ? "Either organisation context or event context is required for page permission checking" : "Insufficient context for permission checking. Please ensure you are properly authenticated and have selected an organisation or event.";
416
455
  console.error("[PagePermissionGuard] Context resolution failed:", {
417
- selectedOrganisationId,
418
- selectedEventId,
456
+ selectedOrganisation: selectedOrganisation ? selectedOrganisation.id : null,
457
+ selectedEvent: selectedEvent ? selectedEvent.event_id : null,
419
458
  appId,
420
459
  error: errorMessage
421
460
  });
422
- setCheckError(new Error(errorMessage));
423
- setResolvedScope(null);
461
+ safeSetCheckError(new Error(errorMessage));
462
+ safeSetResolvedScope(null);
424
463
  };
425
464
  resolveScope();
426
- }, [scope, selectedOrganisationId, selectedEventId]);
465
+ return () => {
466
+ abortController.abort();
467
+ if (scopeResolutionAbortRef.current === abortController) {
468
+ scopeResolutionAbortRef.current = null;
469
+ }
470
+ };
471
+ }, [scope, selectedOrganisation, selectedEvent]);
427
472
  const effectivePageId = useMemo2(() => {
428
473
  return pageId || pageName;
429
474
  }, [pageId, pageName]);
@@ -533,18 +578,18 @@ function SecureDataProvider({
533
578
  maxHistorySize = 1e3,
534
579
  enforceRLS = true
535
580
  }) {
536
- const { user, selectedOrganisationId, selectedEventId } = useUnifiedAuth();
581
+ const { user, selectedOrganisation, selectedEvent } = useUnifiedAuth();
537
582
  const { validateContext } = useSecureDataAccess();
538
583
  const [dataAccessHistory, setDataAccessHistory] = useState3([]);
539
584
  const [isEnabled, setIsEnabled] = useState3(true);
540
585
  const currentScope = useMemo3(() => {
541
- if (!selectedOrganisationId) return null;
586
+ if (!selectedOrganisation) return null;
542
587
  return {
543
- organisationId: selectedOrganisationId,
544
- eventId: selectedEventId || void 0,
588
+ organisationId: selectedOrganisation.id,
589
+ eventId: selectedEvent?.event_id || void 0,
545
590
  appId: void 0
546
591
  };
547
- }, [selectedOrganisationId, selectedEventId]);
592
+ }, [selectedOrganisation, selectedEvent]);
548
593
  const isDataAccessAllowed = useCallback3((table, operation, scope) => {
549
594
  if (!isEnabled) return true;
550
595
  if (!user?.id) return false;
@@ -654,7 +699,7 @@ function PermissionEnforcer({
654
699
  loading = /* @__PURE__ */ jsx4(DefaultLoading2, {}),
655
700
  requireAll = true
656
701
  }) {
657
- const { user, selectedOrganisationId, selectedEventId, supabase } = useUnifiedAuth();
702
+ const { user, selectedOrganisation, selectedEvent, supabase } = useUnifiedAuth();
658
703
  const [hasChecked, setHasChecked] = useState4(false);
659
704
  const [checkError, setCheckError] = useState4(null);
660
705
  const [permissionResults, setPermissionResults] = useState4({});
@@ -665,25 +710,25 @@ function PermissionEnforcer({
665
710
  setResolvedScope(scope);
666
711
  return;
667
712
  }
668
- if (selectedOrganisationId && selectedEventId) {
713
+ if (selectedOrganisation && selectedEvent) {
669
714
  setResolvedScope({
670
- organisationId: selectedOrganisationId,
671
- eventId: selectedEventId,
715
+ organisationId: selectedOrganisation.id,
716
+ eventId: selectedEvent.event_id,
672
717
  appId: void 0
673
718
  });
674
719
  return;
675
720
  }
676
- if (selectedOrganisationId) {
721
+ if (selectedOrganisation) {
677
722
  setResolvedScope({
678
- organisationId: selectedOrganisationId,
679
- eventId: selectedEventId || void 0,
723
+ organisationId: selectedOrganisation.id,
724
+ eventId: selectedEvent?.event_id || void 0,
680
725
  appId: void 0
681
726
  });
682
727
  return;
683
728
  }
684
- if (selectedEventId && supabase) {
729
+ if (selectedEvent && supabase) {
685
730
  try {
686
- const eventScope = await createScopeFromEvent(supabase, selectedEventId);
731
+ const eventScope = await createScopeFromEvent(supabase, selectedEvent.event_id);
687
732
  if (!eventScope) {
688
733
  setCheckError(new Error("Could not resolve organization from event context"));
689
734
  return;
@@ -697,11 +742,11 @@ function PermissionEnforcer({
697
742
  setCheckError(new Error("Either organisation context or event context is required for permission checking"));
698
743
  };
699
744
  resolveScope();
700
- }, [scope, selectedOrganisationId, selectedEventId, supabase]);
745
+ }, [scope, selectedOrganisation, selectedEvent, supabase]);
701
746
  const representativePermission = permissions[0];
702
747
  const { can, isLoading, error } = useCan(
703
748
  user?.id || "",
704
- resolvedScope || { eventId: selectedEventId || void 0 },
749
+ resolvedScope || { eventId: selectedEvent?.event_id || void 0 },
705
750
  representativePermission,
706
751
  void 0,
707
752
  true
@@ -799,19 +844,19 @@ function RoleBasedRouter({
799
844
  maxHistorySize = 1e3,
800
845
  unauthorizedComponent: UnauthorizedComponent = DefaultUnauthorizedComponent
801
846
  }) {
802
- const { user, selectedOrganisationId, selectedEventId } = useUnifiedAuth();
847
+ const { user, selectedOrganisation, selectedEvent } = useUnifiedAuth();
803
848
  const location = useLocation();
804
849
  const navigate = useNavigate();
805
850
  const [routeAccessHistory, setRouteAccessHistory] = useState5([]);
806
851
  const [currentRoute, setCurrentRoute] = useState5("");
807
852
  const currentScope = useMemo5(() => {
808
- if (!selectedOrganisationId) return null;
853
+ if (!selectedOrganisation) return null;
809
854
  return {
810
- organisationId: selectedOrganisationId,
811
- eventId: selectedEventId || void 0,
855
+ organisationId: selectedOrganisation.id,
856
+ eventId: selectedEvent?.event_id || void 0,
812
857
  appId: void 0
813
858
  };
814
- }, [selectedOrganisationId, selectedEventId]);
859
+ }, [selectedOrganisation, selectedEvent]);
815
860
  const currentRouteConfig = useMemo5(() => {
816
861
  const currentPath = location.pathname;
817
862
  return routes.find((route) => route.path === currentPath) || null;
@@ -977,22 +1022,39 @@ function NavigationProvider({
977
1022
  onStrictModeViolation,
978
1023
  maxHistorySize = 1e3
979
1024
  }) {
980
- const { user, selectedOrganisationId, selectedEventId } = useUnifiedAuth();
1025
+ const { user, selectedOrganisation, selectedEvent } = useUnifiedAuth();
981
1026
  const [navigationAccessHistory, setNavigationAccessHistory] = useState6([]);
982
1027
  const [isEnabled, setIsEnabled] = useState6(true);
983
1028
  const currentScope = useMemo6(() => {
984
- if (!selectedOrganisationId) return null;
1029
+ if (!selectedOrganisation) return null;
985
1030
  return {
986
- organisationId: selectedOrganisationId,
987
- eventId: selectedEventId || void 0,
1031
+ organisationId: selectedOrganisation.id,
1032
+ eventId: selectedEvent?.event_id || void 0,
988
1033
  appId: void 0
989
1034
  };
990
- }, [selectedOrganisationId, selectedEventId]);
1035
+ }, [selectedOrganisation, selectedEvent]);
991
1036
  const hasNavigationPermission = useCallback6((item) => {
992
1037
  if (!isEnabled) return true;
993
1038
  if (!user?.id) return false;
994
1039
  if (!currentScope) return false;
995
- return true;
1040
+ if (!item.permissions || item.permissions.length === 0) {
1041
+ console.warn(`[NavigationProvider] Navigation item "${item.id}" has no permissions defined - denying access`);
1042
+ return false;
1043
+ }
1044
+ const permission = item.permissions[0];
1045
+ const { can, error } = useCan(
1046
+ user.id,
1047
+ currentScope,
1048
+ permission,
1049
+ item.pageId,
1050
+ true
1051
+ // useCache
1052
+ );
1053
+ if (error) {
1054
+ console.warn(`[NavigationProvider] Permission check error for "${item.id}": ${error.message} - allowing access for graceful degradation`);
1055
+ return true;
1056
+ }
1057
+ return can;
996
1058
  }, [isEnabled, user?.id, currentScope]);
997
1059
  const getNavigationPermissions = useCallback6(() => {
998
1060
  if (!isEnabled || !user?.id) return {};
@@ -1081,7 +1143,7 @@ function NavigationGuard({
1081
1143
  loading = /* @__PURE__ */ jsx7(DefaultLoading3, {}),
1082
1144
  requireAll = true
1083
1145
  }) {
1084
- const { user, selectedOrganisationId, selectedEventId, supabase } = useUnifiedAuth();
1146
+ const { user, selectedOrganisation, selectedEvent, supabase } = useUnifiedAuth();
1085
1147
  const [hasChecked, setHasChecked] = useState7(false);
1086
1148
  const [checkError, setCheckError] = useState7(null);
1087
1149
  const [resolvedScope, setResolvedScope] = useState7(null);
@@ -1091,25 +1153,25 @@ function NavigationGuard({
1091
1153
  setResolvedScope(scope);
1092
1154
  return;
1093
1155
  }
1094
- if (selectedOrganisationId && selectedEventId) {
1156
+ if (selectedOrganisation && selectedEvent) {
1095
1157
  setResolvedScope({
1096
- organisationId: selectedOrganisationId,
1097
- eventId: selectedEventId,
1158
+ organisationId: selectedOrganisation.id,
1159
+ eventId: selectedEvent.event_id,
1098
1160
  appId: void 0
1099
1161
  });
1100
1162
  return;
1101
1163
  }
1102
- if (selectedOrganisationId) {
1164
+ if (selectedOrganisation) {
1103
1165
  setResolvedScope({
1104
- organisationId: selectedOrganisationId,
1105
- eventId: selectedEventId || void 0,
1166
+ organisationId: selectedOrganisation.id,
1167
+ eventId: selectedEvent?.event_id || void 0,
1106
1168
  appId: void 0
1107
1169
  });
1108
1170
  return;
1109
1171
  }
1110
- if (selectedEventId && supabase) {
1172
+ if (selectedEvent && supabase) {
1111
1173
  try {
1112
- const eventScope = await createScopeFromEvent(supabase, selectedEventId);
1174
+ const eventScope = await createScopeFromEvent(supabase, selectedEvent.event_id);
1113
1175
  if (!eventScope) {
1114
1176
  setCheckError(new Error("Could not resolve organization from event context"));
1115
1177
  return;
@@ -1123,11 +1185,11 @@ function NavigationGuard({
1123
1185
  setCheckError(new Error("Either organisation context or event context is required for navigation permission checking"));
1124
1186
  };
1125
1187
  resolveScope();
1126
- }, [scope, selectedOrganisationId, selectedEventId, supabase]);
1188
+ }, [scope, selectedOrganisation, selectedEvent, supabase]);
1127
1189
  const representativePermission = navigationItem.permissions[0];
1128
1190
  const { can, isLoading, error } = useCan(
1129
1191
  user?.id || "",
1130
- resolvedScope || { eventId: selectedEventId || void 0 },
1192
+ resolvedScope || { eventId: selectedEvent?.event_id || void 0 },
1131
1193
  representativePermission,
1132
1194
  navigationItem.pageId,
1133
1195
  true
@@ -1341,467 +1403,9 @@ function EnhancedNavigationMenu({
1341
1403
  }) });
1342
1404
  }
1343
1405
 
1344
- // src/rbac/providers/RBACProvider.tsx
1345
- init_unified();
1346
- init_debugLogger();
1347
- import { createContext as createContext5, useContext as useContext5, useState as useState9, useEffect as useEffect9, useCallback as useCallback9, useMemo as useMemo9 } from "react";
1348
- import { jsx as jsx9 } from "react/jsx-runtime";
1349
- var RBACContext = createContext5(void 0);
1350
- var useRBAC = () => {
1351
- const context = useContext5(RBACContext);
1352
- if (!context) {
1353
- throw new Error("useRBAC must be used within an RBACProvider");
1354
- }
1355
- return context;
1356
- };
1357
- var STORAGE_KEYS = {
1358
- SELECTED_EVENT: "pace-core-selected-event"
1359
- };
1360
- var transformRBACPermissions = (rbacData, _appName) => {
1361
- const permissions = {};
1362
- let roles = [];
1363
- let access_level = "viewer" /* VIEWER */;
1364
- if (!rbacData || !Array.isArray(rbacData)) {
1365
- return { permissions: {}, roles: ["viewer"], access_level: "viewer" /* VIEWER */ };
1366
- }
1367
- const superAdminPerm = rbacData.find((p) => p.permission_type === "all_permissions");
1368
- if (superAdminPerm) {
1369
- return {
1370
- permissions: { "all:all": true },
1371
- roles: ["super"],
1372
- access_level: "super" /* SUPER */
1373
- };
1374
- }
1375
- const eventAppPerms = rbacData.filter((p) => p.permission_type === "event_app_access");
1376
- if (eventAppPerms.length > 0) {
1377
- const role = eventAppPerms[0].role_name;
1378
- switch (role) {
1379
- case "event_admin":
1380
- access_level = "admin" /* ADMIN */;
1381
- roles = ["admin"];
1382
- break;
1383
- case "planner":
1384
- access_level = "planner" /* PLANNER */;
1385
- roles = ["planner"];
1386
- break;
1387
- case "participant":
1388
- access_level = "participant" /* PARTICIPANT */;
1389
- roles = ["participant"];
1390
- break;
1391
- case "editor":
1392
- access_level = "editor" /* EDITOR */;
1393
- roles = ["editor"];
1394
- break;
1395
- case "viewer":
1396
- default:
1397
- access_level = "viewer" /* VIEWER */;
1398
- roles = ["viewer"];
1399
- break;
1400
- }
1401
- const basePermissions = ["read"];
1402
- if (["event_admin", "planner"].includes(role)) {
1403
- basePermissions.push("create", "update");
1404
- }
1405
- if (role === "event_admin") {
1406
- basePermissions.push("delete");
1407
- }
1408
- basePermissions.forEach((operation) => {
1409
- permissions[`default:${operation}`] = true;
1410
- });
1411
- }
1412
- const orgPerms = rbacData.filter((p) => p.permission_type === "organisation_access");
1413
- if (orgPerms.length > 0) {
1414
- const role = orgPerms[0].role_name;
1415
- if (role === "org_admin") {
1416
- access_level = "admin" /* ADMIN */;
1417
- roles = ["admin"];
1418
- ["create", "read", "update", "delete"].forEach((operation) => {
1419
- permissions[`default:${operation}`] = true;
1420
- });
1421
- }
1422
- }
1423
- return { permissions, roles, access_level };
1424
- };
1425
- function RBACProvider({
1426
- children,
1427
- supabaseClient,
1428
- user,
1429
- session,
1430
- appName,
1431
- enableRBAC = false,
1432
- persistState = true,
1433
- enablePersistence,
1434
- requireOrganisationContext: _requireOrganisationContext = true
1435
- }) {
1436
- const shouldPersist = enablePersistence !== void 0 ? enablePersistence : persistState;
1437
- const [permissions, setPermissions] = useState9({});
1438
- const [roles, setRoles] = useState9([]);
1439
- const [accessLevel, setAccessLevel] = useState9("viewer" /* VIEWER */);
1440
- const [rbacLoading, setRbacLoading] = useState9(false);
1441
- const [rbacError, setRbacError] = useState9(null);
1442
- const [selectedEventId, setSelectedEventId] = useState9(null);
1443
- const [appConfig, setAppConfig] = useState9(null);
1444
- const [userEventAccess, setUserEventAccess] = useState9([]);
1445
- const [eventAccessLoading, setEventAccessLoading] = useState9(false);
1446
- const [selectedOrganisationId, _setSelectedOrganisationId] = useState9(null);
1447
- useEffect9(() => {
1448
- if (!supabaseClient) return;
1449
- const loadAppConfig = async () => {
1450
- try {
1451
- const { getCurrentAppName: getCurrentAppName2 } = await import("./appNameResolver-UURKN7NF.js");
1452
- const resolvedAppName = getCurrentAppName2() || appName;
1453
- const { data: appData, error: appError } = await supabaseClient.from("rbac_apps").select("id").eq("name", resolvedAppName).eq("is_active", true).single();
1454
- if (appError || !appData) {
1455
- console.warn("App not found or inactive:", resolvedAppName);
1456
- setAppConfig({
1457
- supports_direct_access: false,
1458
- // Field removed from rbac_apps table
1459
- requires_event: true
1460
- });
1461
- return;
1462
- }
1463
- const response = await supabaseClient.rpc("get_app_config", {
1464
- app_id: appData.id
1465
- });
1466
- const { data } = response || {};
1467
- if (data && data.length > 0) {
1468
- setAppConfig({
1469
- supports_direct_access: false,
1470
- // Field removed from rbac_apps table
1471
- requires_event: data[0].requires_event
1472
- });
1473
- } else {
1474
- setAppConfig({
1475
- supports_direct_access: false,
1476
- requires_event: true
1477
- });
1478
- }
1479
- } catch (error) {
1480
- console.warn("Clearing corrupted localStorage data");
1481
- if (typeof localStorage !== "undefined") {
1482
- localStorage.removeItem(STORAGE_KEYS.SELECTED_EVENT);
1483
- }
1484
- console.warn("Failed to load app configuration:", error);
1485
- setAppConfig({
1486
- supports_direct_access: false,
1487
- // Field removed from rbac_apps table
1488
- requires_event: true
1489
- });
1490
- }
1491
- };
1492
- loadAppConfig();
1493
- }, [supabaseClient, appName]);
1494
- useEffect9(() => {
1495
- const isSuperAdmin = user?.user_metadata?.globalRole === "super_admin";
1496
- if (isSuperAdmin) {
1497
- setRoles(["super_admin"]);
1498
- } else {
1499
- setRoles([]);
1500
- }
1501
- }, [user]);
1502
- useEffect9(() => {
1503
- if (!shouldPersist) return;
1504
- try {
1505
- const persistedEvent = localStorage.getItem(STORAGE_KEYS.SELECTED_EVENT);
1506
- if (persistedEvent) {
1507
- setSelectedEventId(JSON.parse(persistedEvent));
1508
- }
1509
- } catch (error) {
1510
- console.warn("Clearing corrupted localStorage data");
1511
- localStorage.removeItem(STORAGE_KEYS.SELECTED_EVENT);
1512
- }
1513
- }, [shouldPersist]);
1514
- useEffect9(() => {
1515
- if (!shouldPersist) return;
1516
- try {
1517
- if (selectedEventId) {
1518
- localStorage.setItem(
1519
- STORAGE_KEYS.SELECTED_EVENT,
1520
- JSON.stringify(selectedEventId)
1521
- );
1522
- } else {
1523
- localStorage.removeItem(STORAGE_KEYS.SELECTED_EVENT);
1524
- }
1525
- } catch (error) {
1526
- console.warn("Clearing corrupted localStorage data");
1527
- localStorage.removeItem(STORAGE_KEYS.SELECTED_EVENT);
1528
- console.warn("Failed to persist auth state:", error);
1529
- }
1530
- }, [selectedEventId, shouldPersist]);
1531
- const refreshPermissions = useCallback9(async (eventId) => {
1532
- if (!supabaseClient || !user || !appConfig || !session) {
1533
- DebugLogger.log("RBACProvider", "refreshPermissions: Missing required dependencies, clearing permissions");
1534
- setPermissions({});
1535
- setRoles([]);
1536
- setAccessLevel("viewer" /* VIEWER */);
1537
- return;
1538
- }
1539
- const { data: globalRoles } = await supabaseClient.from("rbac_global_roles").select("role").eq("user_id", user.id).eq("role", "super_admin").lte("valid_from", (/* @__PURE__ */ new Date()).toISOString()).or(`valid_to.is.null,valid_to.gte.${(/* @__PURE__ */ new Date()).toISOString()}`).limit(1);
1540
- const isSuperAdmin = globalRoles && globalRoles.length > 0;
1541
- if (isSuperAdmin) {
1542
- setPermissions({
1543
- "admin:create": true,
1544
- "admin:read": true,
1545
- "admin:update": true,
1546
- "admin:delete": true,
1547
- "users:create": true,
1548
- "users:read": true,
1549
- "users:update": true,
1550
- "users:delete": true,
1551
- "events:create": true,
1552
- "events:read": true,
1553
- "events:update": true,
1554
- "events:delete": true
1555
- });
1556
- setRoles(["super_admin"]);
1557
- setAccessLevel("super" /* SUPER */);
1558
- return;
1559
- }
1560
- const shouldLoadDirectPermissions = !eventId && !appConfig.requires_event;
1561
- const shouldLoadEventPermissions = eventId;
1562
- const shouldClearPermissions = !eventId && appConfig.requires_event;
1563
- if (shouldClearPermissions) {
1564
- setPermissions({});
1565
- setRoles([]);
1566
- setAccessLevel("viewer" /* VIEWER */);
1567
- return;
1568
- }
1569
- if (!shouldLoadDirectPermissions && !shouldLoadEventPermissions) {
1570
- return;
1571
- }
1572
- setRbacLoading(true);
1573
- setRbacError(null);
1574
- try {
1575
- const { getCurrentAppName: getCurrentAppName2 } = await import("./appNameResolver-UURKN7NF.js");
1576
- const resolvedAppName = getCurrentAppName2() || appName;
1577
- const { data: appData, error: appError } = await supabaseClient.from("rbac_apps").select("id").eq("name", resolvedAppName).eq("is_active", true).single();
1578
- if (appError || !appData) {
1579
- console.warn("App not found or inactive:", resolvedAppName);
1580
- setRbacLoading(false);
1581
- return;
1582
- }
1583
- const { data, error } = await supabaseClient.rpc("rbac_permissions_get", {
1584
- p_user_id: user.id,
1585
- p_app_id: appData.id,
1586
- p_event_id: eventId || null,
1587
- p_organisation_id: selectedOrganisationId || null
1588
- });
1589
- if (error) {
1590
- throw error;
1591
- }
1592
- const { permissions: permissions2, roles: roles2, access_level } = transformRBACPermissions(data, appName);
1593
- setPermissions(permissions2);
1594
- setRoles(roles2);
1595
- setAccessLevel(access_level);
1596
- } catch (err) {
1597
- setRbacError(err);
1598
- } finally {
1599
- setRbacLoading(false);
1600
- }
1601
- }, [supabaseClient, user, session, appName, appConfig, selectedOrganisationId]);
1602
- const loadUserEventAccess = useCallback9(async () => {
1603
- if (!supabaseClient || !user || !session) {
1604
- DebugLogger.log("RBACProvider", "loadUserEventAccess: Missing required dependencies, clearing event access");
1605
- setUserEventAccess([]);
1606
- return;
1607
- }
1608
- setEventAccessLoading(true);
1609
- try {
1610
- const { getCurrentAppName: getCurrentAppName2 } = await import("./appNameResolver-UURKN7NF.js");
1611
- const resolvedAppName = getCurrentAppName2() || appName;
1612
- const { data: appData, error: appError } = await supabaseClient.from("rbac_apps").select("id").eq("name", resolvedAppName).eq("is_active", true).single();
1613
- if (appError || !appData) {
1614
- console.warn("App not found or inactive:", resolvedAppName);
1615
- setEventAccessLoading(false);
1616
- return;
1617
- }
1618
- const { data, error } = await supabaseClient.from("rbac_event_app_roles").select(`
1619
- event_id,
1620
- role,
1621
- granted_at
1622
- `).eq("user_id", user.id).eq("app_id", appData.id);
1623
- if (error) {
1624
- console.error("Failed to load user event access:", error);
1625
- setUserEventAccess([]);
1626
- return;
1627
- }
1628
- const eventAccess = data?.map((item) => ({
1629
- event_id: item.event_id,
1630
- event_name: "Unknown Event",
1631
- // Event details not available in this query
1632
- event_description: null,
1633
- // Not available in this schema
1634
- start_date: "",
1635
- // Event date not available in this query
1636
- end_date: "",
1637
- // Event date not available in this query
1638
- event_status: "unknown",
1639
- // Not available in this schema
1640
- app_id: appData.id,
1641
- access_level: item.role,
1642
- // Map role to access_level
1643
- granted_at: item.granted_at,
1644
- organisation_id: ""
1645
- // Will be populated from event's organisation_id if needed
1646
- })) || [];
1647
- setUserEventAccess(eventAccess);
1648
- } catch (error) {
1649
- console.warn("Clearing corrupted localStorage data");
1650
- localStorage.removeItem(STORAGE_KEYS.SELECTED_EVENT);
1651
- console.error("Error loading user event access:", error);
1652
- setUserEventAccess([]);
1653
- } finally {
1654
- setEventAccessLoading(false);
1655
- }
1656
- }, [supabaseClient, user, session, appName]);
1657
- const getUserEventAccess = useCallback9((eventId) => {
1658
- return userEventAccess.find((access) => access.event_id === eventId);
1659
- }, [userEventAccess]);
1660
- useEffect9(() => {
1661
- if (!user || !appConfig || !session) {
1662
- DebugLogger.log("RBACProvider", "Skipping permission refresh - no user, session, or app config");
1663
- return;
1664
- }
1665
- const isSuperAdmin = user?.user_metadata?.globalRole === "super_admin";
1666
- if (isSuperAdmin) {
1667
- setPermissions({
1668
- "admin:create": true,
1669
- "admin:read": true,
1670
- "admin:update": true,
1671
- "admin:delete": true,
1672
- "users:create": true,
1673
- "users:read": true,
1674
- "users:update": true,
1675
- "users:delete": true,
1676
- "events:create": true,
1677
- "events:read": true,
1678
- "events:update": true,
1679
- "events:delete": true
1680
- });
1681
- setRoles(["super_admin"]);
1682
- setAccessLevel("admin" /* ADMIN */);
1683
- return;
1684
- }
1685
- if (selectedEventId) {
1686
- refreshPermissions(selectedEventId);
1687
- } else if (!appConfig.requires_event) {
1688
- refreshPermissions();
1689
- } else {
1690
- setPermissions({});
1691
- setRoles([]);
1692
- setAccessLevel("viewer" /* VIEWER */);
1693
- }
1694
- }, [selectedEventId, user, session, appConfig, refreshPermissions]);
1695
- useEffect9(() => {
1696
- let isMounted = true;
1697
- if (user && session) {
1698
- DebugLogger.log("RBACProvider", "Loading user event access for authenticated user");
1699
- loadUserEventAccess().catch((error) => {
1700
- if (isMounted) {
1701
- console.error("Error loading user event access:", error);
1702
- }
1703
- });
1704
- } else {
1705
- DebugLogger.log("RBACProvider", "Clearing user event access - no user or session");
1706
- if (isMounted) {
1707
- setUserEventAccess([]);
1708
- }
1709
- }
1710
- return () => {
1711
- isMounted = false;
1712
- };
1713
- }, [user, session, loadUserEventAccess]);
1714
- const hasPermission2 = useCallback9((permission) => {
1715
- const hasPerm = !!permissions[permission];
1716
- return hasPerm;
1717
- }, [permissions]);
1718
- const hasAnyPermission2 = useCallback9((perms) => perms.some((p) => !!permissions[p]), [permissions]);
1719
- const hasAllPermissions2 = useCallback9((perms) => perms.every((p) => !!permissions[p]), [permissions]);
1720
- const hasRole = useCallback9((role) => {
1721
- const isSuperAdmin = user?.user_metadata?.globalRole === "super_admin";
1722
- if (role.toLowerCase() === "super_admin") {
1723
- return isSuperAdmin;
1724
- }
1725
- return roles.includes(role);
1726
- }, [roles, user]);
1727
- const hasAccessLevel = useCallback9((level) => {
1728
- const levels = Object.values(AccessLevel);
1729
- return levels.indexOf(accessLevel) >= levels.indexOf(level);
1730
- }, [accessLevel]);
1731
- const canAccess = useCallback9((resource, action) => {
1732
- const permission = `${resource}:${action}`;
1733
- const hasAccess = hasPermission2(permission);
1734
- return hasAccess;
1735
- }, [hasPermission2]);
1736
- const validatePermission = useCallback9(async (permission) => hasPermission2(permission), [hasPermission2]);
1737
- const validateAccess = useCallback9(async (resource, action) => {
1738
- return Promise.resolve(canAccess(resource, action));
1739
- }, [canAccess]);
1740
- const contextValue = useMemo9(() => ({
1741
- permissions,
1742
- roles,
1743
- accessLevel,
1744
- rbacLoading,
1745
- rbacError,
1746
- selectedEventId,
1747
- appConfig,
1748
- userEventAccess,
1749
- eventAccessLoading,
1750
- // Organisation context
1751
- selectedOrganisationId,
1752
- requireOrganisationContext: () => {
1753
- if (!selectedOrganisationId) {
1754
- throw new Error("Organisation context is required but not available");
1755
- }
1756
- return selectedOrganisationId;
1757
- },
1758
- hasPermission: hasPermission2,
1759
- hasAnyPermission: hasAnyPermission2,
1760
- hasAllPermissions: hasAllPermissions2,
1761
- hasRole,
1762
- hasAccessLevel,
1763
- canAccess,
1764
- validatePermission,
1765
- validateAccess,
1766
- refreshPermissions,
1767
- setSelectedEventId,
1768
- // New RBAC system support
1769
- rbacEnabled: enableRBAC,
1770
- rbacContext: void 0,
1771
- // Will be populated by useRBAC hook when enabled
1772
- loadUserEventAccess,
1773
- getUserEventAccess
1774
- }), [
1775
- permissions,
1776
- roles,
1777
- accessLevel,
1778
- rbacLoading,
1779
- rbacError,
1780
- selectedEventId,
1781
- appConfig,
1782
- userEventAccess,
1783
- eventAccessLoading,
1784
- selectedOrganisationId,
1785
- hasPermission2,
1786
- hasAnyPermission2,
1787
- hasAllPermissions2,
1788
- hasRole,
1789
- hasAccessLevel,
1790
- canAccess,
1791
- validatePermission,
1792
- validateAccess,
1793
- refreshPermissions,
1794
- setSelectedEventId,
1795
- enableRBAC,
1796
- loadUserEventAccess,
1797
- getUserEventAccess
1798
- ]);
1799
- return /* @__PURE__ */ jsx9(RBACContext.Provider, { value: contextValue, children });
1800
- }
1801
-
1802
1406
  // src/rbac/adapters.tsx
1803
- import React10, { useContext as useContext6 } from "react";
1804
- import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
1407
+ init_UnifiedAuthProvider();
1408
+ import { Fragment as Fragment4, jsx as jsx9 } from "react/jsx-runtime";
1805
1409
  function PermissionGuard({
1806
1410
  userId,
1807
1411
  scope,
@@ -1817,40 +1421,24 @@ function PermissionGuard({
1817
1421
  enforceAudit = true
1818
1422
  }) {
1819
1423
  const logger = getRBACLogger();
1820
- const authContext = useContext6(React10.createContext(null));
1821
- let effectiveUserId = userId;
1822
- if (!effectiveUserId) {
1823
- try {
1824
- if (authContext?.user?.id) {
1825
- effectiveUserId = authContext.user.id;
1826
- } else {
1827
- const globalUser = window.__PACE_USER__;
1828
- if (globalUser?.id) {
1829
- effectiveUserId = globalUser.id;
1830
- }
1831
- }
1832
- } catch (error2) {
1833
- logger.debug("Could not infer userId from context:", error2);
1424
+ let authContext = null;
1425
+ try {
1426
+ authContext = useUnifiedAuth();
1427
+ } catch (error2) {
1428
+ if (error2 instanceof Error && error2.message.includes("must be used within")) {
1429
+ authContext = null;
1430
+ } else {
1431
+ throw error2;
1834
1432
  }
1835
1433
  }
1434
+ const effectiveUserId = userId ?? authContext?.user?.id ?? null;
1836
1435
  const { can, isLoading, error } = useCan(effectiveUserId || "", scope, permission, pageId);
1837
1436
  if (!effectiveUserId) {
1838
1437
  logger.error("PermissionGuard: No userId provided and could not infer from context");
1839
- return /* @__PURE__ */ jsxs6("div", { className: "rbac-error", role: "alert", children: [
1840
- /* @__PURE__ */ jsx10("p", { children: "Permission check failed: User context not available" }),
1841
- /* @__PURE__ */ jsxs6("details", { children: [
1842
- /* @__PURE__ */ jsx10("summary", { children: "Debug info" }),
1843
- /* @__PURE__ */ jsx10("p", { children: "Make sure to either:" }),
1844
- /* @__PURE__ */ jsxs6("ul", { children: [
1845
- /* @__PURE__ */ jsx10("li", { children: "Pass userId prop explicitly" }),
1846
- /* @__PURE__ */ jsx10("li", { children: "Wrap your app with an auth provider" }),
1847
- /* @__PURE__ */ jsx10("li", { children: "Set window.__PACE_USER__ with user data" })
1848
- ] })
1849
- ] })
1850
- ] });
1438
+ return fallback ?? null;
1851
1439
  }
1852
1440
  if (isLoading) {
1853
- return loading || /* @__PURE__ */ jsx10("div", { className: "rbac-loading", role: "status", "aria-live": "polite", children: /* @__PURE__ */ jsx10("span", { className: "sr-only", children: "Checking permissions..." }) });
1441
+ return loading || /* @__PURE__ */ jsx9("div", { className: "rbac-loading", role: "status", "aria-live": "polite", children: /* @__PURE__ */ jsx9("span", { className: "sr-only", children: "Checking permissions..." }) });
1854
1442
  }
1855
1443
  if (error) {
1856
1444
  logger.error("Permission check failed:", error);
@@ -1888,7 +1476,7 @@ function PermissionGuard({
1888
1476
  if (onDenied) {
1889
1477
  onDenied();
1890
1478
  }
1891
- return /* @__PURE__ */ jsx10(Fragment4, { children: fallback });
1479
+ return /* @__PURE__ */ jsx9(Fragment4, { children: fallback });
1892
1480
  }
1893
1481
  if (auditLog) {
1894
1482
  logger.info(`[PermissionGuard] Permission granted:`, {
@@ -1899,7 +1487,7 @@ function PermissionGuard({
1899
1487
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
1900
1488
  });
1901
1489
  }
1902
- return /* @__PURE__ */ jsx10(Fragment4, { children });
1490
+ return /* @__PURE__ */ jsx9(Fragment4, { children });
1903
1491
  }
1904
1492
  function AccessLevelGuard({
1905
1493
  userId,
@@ -1910,40 +1498,24 @@ function AccessLevelGuard({
1910
1498
  loading = null
1911
1499
  }) {
1912
1500
  const logger = getRBACLogger();
1913
- const authContext = useContext6(React10.createContext(null));
1914
- let effectiveUserId = userId;
1915
- if (!effectiveUserId) {
1916
- try {
1917
- if (authContext?.user?.id) {
1918
- effectiveUserId = authContext.user.id;
1919
- } else {
1920
- const globalUser = window.__PACE_USER__;
1921
- if (globalUser?.id) {
1922
- effectiveUserId = globalUser.id;
1923
- }
1924
- }
1925
- } catch (error2) {
1926
- logger.debug("Could not infer userId from context:", error2);
1501
+ let authContext = null;
1502
+ try {
1503
+ authContext = useUnifiedAuth();
1504
+ } catch (error2) {
1505
+ if (error2 instanceof Error && error2.message.includes("must be used within")) {
1506
+ authContext = null;
1507
+ } else {
1508
+ throw error2;
1927
1509
  }
1928
1510
  }
1511
+ const effectiveUserId = userId ?? authContext?.user?.id ?? null;
1929
1512
  const { accessLevel, isLoading, error } = useAccessLevel(effectiveUserId || "", scope);
1930
1513
  if (!effectiveUserId) {
1931
1514
  logger.error("AccessLevelGuard: No userId provided and could not infer from context");
1932
- return /* @__PURE__ */ jsxs6("div", { className: "rbac-error", role: "alert", children: [
1933
- /* @__PURE__ */ jsx10("p", { children: "Access level check failed: User context not available" }),
1934
- /* @__PURE__ */ jsxs6("details", { children: [
1935
- /* @__PURE__ */ jsx10("summary", { children: "Debug info" }),
1936
- /* @__PURE__ */ jsx10("p", { children: "Make sure to either:" }),
1937
- /* @__PURE__ */ jsxs6("ul", { children: [
1938
- /* @__PURE__ */ jsx10("li", { children: "Pass userId prop explicitly" }),
1939
- /* @__PURE__ */ jsx10("li", { children: "Wrap your app with an auth provider" }),
1940
- /* @__PURE__ */ jsx10("li", { children: "Set window.__PACE_USER__ with user data" })
1941
- ] })
1942
- ] })
1943
- ] });
1515
+ return fallback ?? null;
1944
1516
  }
1945
1517
  if (isLoading) {
1946
- return loading || /* @__PURE__ */ jsx10("div", { className: "rbac-loading", role: "status", "aria-live": "polite", children: /* @__PURE__ */ jsx10("span", { className: "sr-only", children: "Checking access level..." }) });
1518
+ return loading || /* @__PURE__ */ jsx9("div", { className: "rbac-loading", role: "status", "aria-live": "polite", children: /* @__PURE__ */ jsx9("span", { className: "sr-only", children: "Checking access level..." }) });
1947
1519
  }
1948
1520
  if (error) {
1949
1521
  logger.error("Access level check failed:", error);
@@ -1953,9 +1525,9 @@ function AccessLevelGuard({
1953
1525
  const userLevelIndex = accessLevel ? levelHierarchy.indexOf(accessLevel) : -1;
1954
1526
  const requiredLevelIndex = levelHierarchy.indexOf(minLevel);
1955
1527
  if (userLevelIndex < requiredLevelIndex) {
1956
- return /* @__PURE__ */ jsx10(Fragment4, { children: fallback });
1528
+ return /* @__PURE__ */ jsx9(Fragment4, { children: fallback });
1957
1529
  }
1958
- return /* @__PURE__ */ jsx10(Fragment4, { children });
1530
+ return /* @__PURE__ */ jsx9(Fragment4, { children });
1959
1531
  }
1960
1532
  function withPermissionGuard(config, handler) {
1961
1533
  return async (...args) => {
@@ -1967,7 +1539,7 @@ function withPermissionGuard(config, handler) {
1967
1539
  if (!userId || !organisationId) {
1968
1540
  throw new Error("User context required for permission check");
1969
1541
  }
1970
- const { isPermitted: isPermitted2 } = await import("./api-DDMUKIUD.js");
1542
+ const { isPermitted: isPermitted2 } = await import("./api-KG4A2X7P.js");
1971
1543
  const hasPermission2 = await isPermitted2({
1972
1544
  userId,
1973
1545
  scope: { organisationId, eventId, appId },
@@ -1990,7 +1562,7 @@ function withAccessLevelGuard(minLevel, handler) {
1990
1562
  if (!userId || !organisationId) {
1991
1563
  throw new Error("User context required for access level check");
1992
1564
  }
1993
- const { getAccessLevel: getAccessLevel2 } = await import("./api-DDMUKIUD.js");
1565
+ const { getAccessLevel: getAccessLevel2 } = await import("./api-KG4A2X7P.js");
1994
1566
  const accessLevel = await getAccessLevel2({
1995
1567
  userId,
1996
1568
  scope: { organisationId, eventId, appId }
@@ -2015,11 +1587,11 @@ function withRoleGuard(config, handler) {
2015
1587
  throw new Error("User context required for role check");
2016
1588
  }
2017
1589
  if (config.globalRoles && config.globalRoles.length > 0) {
2018
- const { isSuperAdmin } = await import("./api-DDMUKIUD.js");
1590
+ const { isSuperAdmin } = await import("./api-KG4A2X7P.js");
2019
1591
  const isSuper = await isSuperAdmin(userId);
2020
1592
  if (isSuper) {
2021
1593
  if (organisationId) {
2022
- const { emitAuditEvent: emitAuditEvent2 } = await import("./audit-6TOCAMKO.js");
1594
+ const { emitAuditEvent: emitAuditEvent2 } = await import("./audit-65VNHEV2.js");
2023
1595
  await emitAuditEvent2({
2024
1596
  type: "permission_check",
2025
1597
  userId,
@@ -2041,21 +1613,21 @@ function withRoleGuard(config, handler) {
2041
1613
  }
2042
1614
  }
2043
1615
  if (config.organisationRoles && config.organisationRoles.length > 0) {
2044
- const { isOrganisationAdmin } = await import("./api-DDMUKIUD.js");
1616
+ const { isOrganisationAdmin } = await import("./api-KG4A2X7P.js");
2045
1617
  const isOrgAdmin = await isOrganisationAdmin(userId, organisationId);
2046
1618
  if (!isOrgAdmin && config.requireAll !== false) {
2047
1619
  throw new Error(`Organisation admin role required`);
2048
1620
  }
2049
1621
  }
2050
1622
  if (config.eventAppRoles && config.eventAppRoles.length > 0 && eventId && appId) {
2051
- const { isEventAdmin } = await import("./api-DDMUKIUD.js");
1623
+ const { isEventAdmin } = await import("./api-KG4A2X7P.js");
2052
1624
  const isEventAdminUser = await isEventAdmin(userId, { organisationId, eventId, appId });
2053
1625
  if (!isEventAdminUser && config.requireAll !== false) {
2054
1626
  throw new Error(`Event admin role required`);
2055
1627
  }
2056
1628
  }
2057
1629
  if (organisationId) {
2058
- const { emitAuditEvent: emitAuditEvent2 } = await import("./audit-6TOCAMKO.js");
1630
+ const { emitAuditEvent: emitAuditEvent2 } = await import("./audit-65VNHEV2.js");
2059
1631
  await emitAuditEvent2({
2060
1632
  type: "permission_check",
2061
1633
  userId,
@@ -2088,7 +1660,7 @@ function createRBACMiddleware(config) {
2088
1660
  );
2089
1661
  if (protectedRoute) {
2090
1662
  try {
2091
- const { isPermitted: isPermitted2 } = await import("./api-DDMUKIUD.js");
1663
+ const { isPermitted: isPermitted2 } = await import("./api-KG4A2X7P.js");
2092
1664
  const hasPermission2 = await isPermitted2({
2093
1665
  userId,
2094
1666
  scope: { organisationId },
@@ -2115,7 +1687,7 @@ function createRBACExpressMiddleware(config) {
2115
1687
  return res.status(401).json({ error: "User context required" });
2116
1688
  }
2117
1689
  try {
2118
- const { isPermitted: isPermitted2 } = await import("./api-DDMUKIUD.js");
1690
+ const { isPermitted: isPermitted2 } = await import("./api-KG4A2X7P.js");
2119
1691
  const hasPermission2 = await isPermitted2({
2120
1692
  userId,
2121
1693
  scope: { organisationId, eventId, appId },
@@ -2271,8 +1843,6 @@ export {
2271
1843
  useNavigationPermissions,
2272
1844
  NavigationGuard,
2273
1845
  EnhancedNavigationMenu,
2274
- useRBAC,
2275
- RBACProvider,
2276
1846
  PermissionGuard,
2277
1847
  AccessLevelGuard,
2278
1848
  withPermissionGuard,
@@ -2290,4 +1860,4 @@ export {
2290
1860
  getPermissionsForRole,
2291
1861
  ALL_PERMISSIONS
2292
1862
  };
2293
- //# sourceMappingURL=chunk-K34IM5CT.js.map
1863
+ //# sourceMappingURL=chunk-2OGV6IRV.js.map