@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
@@ -1,492 +0,0 @@
1
- /**
2
- * @file RBACService Unit Tests
3
- * @package @jmruthers/pace-core
4
- * @module Services/__tests__
5
- * @since 0.1.0
6
- *
7
- * Unit tests for RBACService class.
8
- * Tests role-based access control operations, permission checking, and state management.
9
- */
10
-
11
- import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
12
- import { RBACService } from '../RBACService';
13
- import { AccessLevel } from '../../types/unified';
14
-
15
- // Mock Supabase client
16
- const createMockSupabaseClient = () => ({
17
- rpc: vi.fn(),
18
- from: vi.fn(() => ({
19
- select: vi.fn(() => ({
20
- eq: vi.fn(() => ({
21
- eq: vi.fn(() => ({
22
- single: vi.fn()
23
- }))
24
- }))
25
- }))
26
- })),
27
- });
28
-
29
- // Mock user and session
30
- const mockUser = {
31
- id: 'user-1',
32
- email: 'test@example.com',
33
- user_metadata: { globalRole: 'user' }
34
- };
35
-
36
- const mockSession = {
37
- access_token: 'token',
38
- user: mockUser
39
- };
40
-
41
- describe('RBACService', () => {
42
- let mockSupabase: ReturnType<typeof createMockSupabaseClient>;
43
- let rbacService: RBACService;
44
-
45
- beforeEach(() => {
46
- mockSupabase = createMockSupabaseClient();
47
- rbacService = new RBACService(mockSupabase as any, mockUser, mockSession, 'test-app');
48
- });
49
-
50
- afterEach(() => {
51
- rbacService.cleanup();
52
- vi.clearAllMocks();
53
- });
54
-
55
- describe('Initialization', () => {
56
- it('should initialize with default state', () => {
57
- expect(rbacService.getPermissions()).toEqual({});
58
- expect(rbacService.getRoles()).toEqual([]);
59
- expect(rbacService.getAccessLevel()).toBe(AccessLevel.VIEWER);
60
- expect(rbacService.isLoading()).toBe(false);
61
- expect(rbacService.getError()).toBeNull();
62
- expect(rbacService.getSelectedEventId()).toBeNull();
63
- expect(rbacService.getAppConfig()).toBeNull();
64
- expect(rbacService.getUserEventAccess()).toEqual([]);
65
- expect(rbacService.isEventAccessLoading()).toBe(false);
66
- expect(rbacService.getSelectedOrganisationId()).toBeNull();
67
- });
68
-
69
- it('should set super admin role from user metadata', async () => {
70
- const superAdminUser = {
71
- ...mockUser,
72
- user_metadata: { globalRole: 'super_admin' }
73
- };
74
-
75
- const service = new RBACService(mockSupabase as any, superAdminUser, mockSession, 'test-app');
76
- await service.initialize();
77
-
78
- expect(service.getRoles()).toContain('super_admin');
79
- expect(service.getAccessLevel()).toBe(AccessLevel.ADMIN);
80
- expect(service.getPermissions()).toHaveProperty('admin:create', true);
81
- });
82
- });
83
-
84
- describe('Permission Checking', () => {
85
- beforeEach(async () => {
86
- // Mock app config loading
87
- mockSupabase.from.mockReturnValue({
88
- select: vi.fn().mockReturnValue({
89
- eq: vi.fn().mockReturnValue({
90
- eq: vi.fn().mockReturnValue({
91
- single: vi.fn().mockResolvedValue({
92
- data: { id: 'app-1' },
93
- error: null
94
- })
95
- })
96
- })
97
- })
98
- });
99
-
100
- // Mock get_app_config RPC
101
- mockSupabase.rpc.mockImplementation((rpcName, params) => {
102
- if (rpcName === 'get_app_config') {
103
- return Promise.resolve({
104
- data: [{
105
- supports_direct_access: false,
106
- requires_event: true
107
- }],
108
- error: null
109
- });
110
- }
111
- // Mock rbac_permissions_get for permission checking
112
- return Promise.resolve({
113
- data: [
114
- {
115
- permission_type: 'event_app_access',
116
- role_name: 'planner',
117
- permission: 'events:read'
118
- }
119
- ],
120
- error: null
121
- });
122
- });
123
-
124
- // Set event ID before initialization so permissions are loaded
125
- rbacService.setSelectedEventId('event-1');
126
- await rbacService.initialize();
127
- });
128
-
129
- it('should check permissions correctly', async () => {
130
- expect(rbacService.hasPermission('events:read')).toBe(true);
131
- expect(rbacService.hasPermission('events:write')).toBe(false);
132
- });
133
-
134
- it('should check roles correctly', async () => {
135
- expect(rbacService.hasRole('planner')).toBe(true);
136
- expect(rbacService.hasRole('admin')).toBe(false);
137
- });
138
-
139
- it('should check access levels correctly', async () => {
140
- expect(rbacService.hasAccessLevel(AccessLevel.VIEWER)).toBe(true);
141
- expect(rbacService.hasAccessLevel(AccessLevel.PLANNER)).toBe(true);
142
- expect(rbacService.hasAccessLevel(AccessLevel.ADMIN)).toBe(false);
143
- });
144
-
145
- it('should check resource access correctly', async () => {
146
- expect(rbacService.canAccess('events', 'read')).toBe(true);
147
- expect(rbacService.canAccess('events', 'write')).toBe(false);
148
- });
149
-
150
- it('should validate permissions asynchronously', async () => {
151
- const result = await rbacService.validatePermission('events:read');
152
- expect(result).toBe(true);
153
- });
154
-
155
- it('should validate access asynchronously', async () => {
156
- const result = await rbacService.validateAccess('events', 'read');
157
- expect(result).toBe(true);
158
- });
159
- });
160
-
161
- describe('Event Management', () => {
162
- it('should set selected event ID', () => {
163
- rbacService.setSelectedEventId('event-123');
164
-
165
- expect(rbacService.getSelectedEventId()).toBe('event-123');
166
- });
167
-
168
- it('should get user event access for specific event', async () => {
169
- const mockEventAccess = [
170
- {
171
- event_id: 'event-1',
172
- event_name: 'Test Event',
173
- event_description: 'Test Description',
174
- start_date: '2024-01-01',
175
- end_date: '2024-01-02',
176
- event_status: 'active',
177
- app_id: 'app-1',
178
- access_level: 'planner',
179
- granted_at: '2024-01-01T00:00:00Z',
180
- organisation_id: 'org-1'
181
- }
182
- ];
183
-
184
- // Mock the rbac_apps and rbac_event_app_roles queries
185
- mockSupabase.from.mockImplementation((table: string) => {
186
- if (table === 'rbac_apps') {
187
- return {
188
- select: vi.fn().mockReturnValue({
189
- eq: vi.fn().mockReturnValue({
190
- eq: vi.fn().mockReturnValue({
191
- single: vi.fn().mockResolvedValue({
192
- data: { id: 'app-1' },
193
- error: null
194
- })
195
- })
196
- })
197
- })
198
- };
199
- }
200
- if (table === 'rbac_event_app_roles') {
201
- return {
202
- select: vi.fn().mockReturnValue({
203
- eq: vi.fn().mockReturnValue({
204
- eq: vi.fn().mockResolvedValue({
205
- data: mockEventAccess,
206
- error: null
207
- })
208
- })
209
- })
210
- };
211
- }
212
- return mockSupabase.from();
213
- });
214
-
215
- await rbacService.loadUserEventAccess();
216
-
217
- const eventAccess = rbacService.getUserEventAccessById('event-1');
218
- expect(eventAccess).toEqual(mockEventAccess[0]);
219
- });
220
- });
221
-
222
- describe('Organisation Context', () => {
223
- it('should require organisation context', () => {
224
- expect(() => rbacService.requireOrganisationContext()).toThrow('Organisation context is required but not available');
225
- });
226
-
227
- it('should return organisation context when set', () => {
228
- rbacService.setSelectedEventId('event-1'); // This sets the organisation context internally
229
-
230
- // Mock the organisation context
231
- const orgId = 'org-1';
232
- // Note: In a real implementation, this would be set by the OrganisationService
233
- // For testing, we'll simulate it
234
- (rbacService as any).selectedOrganisationId = orgId;
235
-
236
- expect(rbacService.requireOrganisationContext()).toBe(orgId);
237
- });
238
- });
239
-
240
- describe('Data Operations', () => {
241
- it('should refresh permissions for event', async () => {
242
- // Mock the rbac_apps query
243
- mockSupabase.from.mockReturnValue({
244
- select: vi.fn().mockReturnValue({
245
- eq: vi.fn().mockReturnValue({
246
- eq: vi.fn().mockReturnValue({
247
- single: vi.fn().mockResolvedValue({
248
- data: { id: 'app-1' },
249
- error: null
250
- })
251
- })
252
- })
253
- })
254
- });
255
-
256
- mockSupabase.rpc.mockImplementation((rpcName, params) => {
257
- if (rpcName === 'get_app_config') {
258
- return Promise.resolve({
259
- data: [{
260
- supports_direct_access: false,
261
- requires_event: true
262
- }],
263
- error: null
264
- });
265
- }
266
- return Promise.resolve({
267
- data: [
268
- {
269
- permission_type: 'event_app_access',
270
- role_name: 'planner',
271
- permission: 'events:read'
272
- }
273
- ],
274
- error: null
275
- });
276
- });
277
-
278
- // Ensure app config is loaded
279
- await rbacService.initialize();
280
-
281
- // Clear the RPC mock call count from initialization
282
- vi.clearAllMocks();
283
-
284
- // Re-setup mocks for the refresh call
285
- mockSupabase.from.mockReturnValue({
286
- select: vi.fn().mockReturnValue({
287
- eq: vi.fn().mockReturnValue({
288
- eq: vi.fn().mockReturnValue({
289
- single: vi.fn().mockResolvedValue({
290
- data: { id: 'app-1' },
291
- error: null
292
- })
293
- })
294
- })
295
- })
296
- });
297
-
298
- mockSupabase.rpc.mockResolvedValue({
299
- data: [
300
- {
301
- permission_type: 'event_app_access',
302
- role_name: 'planner',
303
- permission: 'events:read'
304
- }
305
- ],
306
- error: null
307
- });
308
-
309
- await rbacService.refreshPermissions('event-1');
310
-
311
- expect(mockSupabase.rpc).toHaveBeenCalledWith('rbac_permissions_get', {
312
- p_user_id: mockUser.id,
313
- p_app_id: 'app-1',
314
- p_event_id: 'event-1',
315
- p_organisation_id: null
316
- });
317
- });
318
-
319
- it('should load user event access', async () => {
320
- const mockEventAccess = [
321
- {
322
- event_id: 'event-1',
323
- role: 'planner',
324
- granted_at: '2024-01-01T00:00:00Z'
325
- }
326
- ];
327
-
328
- // Mock the rbac_apps and rbac_event_app_roles queries
329
- mockSupabase.from.mockImplementation((table: string) => {
330
- if (table === 'rbac_apps') {
331
- return {
332
- select: vi.fn().mockReturnValue({
333
- eq: vi.fn().mockReturnValue({
334
- eq: vi.fn().mockReturnValue({
335
- single: vi.fn().mockResolvedValue({
336
- data: { id: 'app-1' },
337
- error: null
338
- })
339
- })
340
- })
341
- })
342
- };
343
- }
344
- if (table === 'rbac_event_app_roles') {
345
- return {
346
- select: vi.fn().mockReturnValue({
347
- eq: vi.fn().mockReturnValue({
348
- eq: vi.fn().mockResolvedValue({
349
- data: mockEventAccess,
350
- error: null
351
- })
352
- })
353
- })
354
- };
355
- }
356
- return mockSupabase.from();
357
- });
358
-
359
- await rbacService.loadUserEventAccess();
360
-
361
- expect(rbacService.getUserEventAccess()).toHaveLength(1);
362
- expect(rbacService.getUserEventAccess()[0].event_id).toBe('event-1');
363
- });
364
-
365
- it('should handle RPC errors gracefully', async () => {
366
- // Mock the rbac_apps query
367
- mockSupabase.from.mockReturnValue({
368
- select: vi.fn().mockReturnValue({
369
- eq: vi.fn().mockReturnValue({
370
- eq: vi.fn().mockReturnValue({
371
- single: vi.fn().mockResolvedValue({
372
- data: { id: 'app-1' },
373
- error: null
374
- })
375
- })
376
- })
377
- })
378
- });
379
-
380
- // Mock the RPC call to return app config first, then error
381
- mockSupabase.rpc.mockImplementation((rpcName, params) => {
382
- if (rpcName === 'get_app_config') {
383
- return Promise.resolve({
384
- data: [{
385
- supports_direct_access: false,
386
- requires_event: true
387
- }],
388
- error: null
389
- });
390
- }
391
- if (rpcName === 'rbac_permissions_get') {
392
- return Promise.resolve({
393
- data: null,
394
- error: { message: 'RPC error' }
395
- });
396
- }
397
- return Promise.resolve({ data: null, error: null });
398
- });
399
-
400
- // Ensure app config is loaded
401
- await rbacService.initialize();
402
-
403
- await rbacService.refreshPermissions('event-1');
404
-
405
- expect(rbacService.getError()).toBeDefined();
406
- expect(rbacService.getError()?.message).toBe('RPC error');
407
- });
408
- });
409
-
410
- describe('State Management', () => {
411
- it('should notify subscribers when state changes', () => {
412
- const subscriber = vi.fn();
413
- const unsubscribe = rbacService.subscribe(subscriber);
414
-
415
- rbacService.setSelectedEventId('event-1');
416
-
417
- expect(subscriber).toHaveBeenCalled();
418
-
419
- unsubscribe();
420
- });
421
-
422
- it('should cleanup subscriptions on cleanup', () => {
423
- const subscriber = vi.fn();
424
- rbacService.subscribe(subscriber);
425
-
426
- rbacService.cleanup();
427
-
428
- // After cleanup, new state changes shouldn't notify subscribers
429
- rbacService.setSelectedEventId('event-1');
430
-
431
- expect(subscriber).not.toHaveBeenCalled();
432
- });
433
- });
434
-
435
- describe('Super Admin Override', () => {
436
- it('should grant all permissions to super admin', async () => {
437
- const superAdminUser = {
438
- ...mockUser,
439
- user_metadata: { globalRole: 'super_admin' }
440
- };
441
-
442
- const service = new RBACService(mockSupabase as any, superAdminUser, mockSession, 'test-app');
443
- await service.initialize();
444
-
445
- expect(service.hasPermission('admin:create')).toBe(true);
446
- expect(service.hasPermission('admin:read')).toBe(true);
447
- expect(service.hasPermission('admin:update')).toBe(true);
448
- expect(service.hasPermission('admin:delete')).toBe(true);
449
- expect(service.hasPermission('users:create')).toBe(true);
450
- expect(service.hasPermission('users:read')).toBe(true);
451
- expect(service.hasPermission('users:update')).toBe(true);
452
- expect(service.hasPermission('users:delete')).toBe(true);
453
- expect(service.hasPermission('events:create')).toBe(true);
454
- expect(service.hasPermission('events:read')).toBe(true);
455
- expect(service.hasPermission('events:update')).toBe(true);
456
- expect(service.hasPermission('events:delete')).toBe(true);
457
- });
458
-
459
- it('should recognize super admin role', async () => {
460
- const superAdminUser = {
461
- ...mockUser,
462
- user_metadata: { globalRole: 'super_admin' }
463
- };
464
-
465
- const service = new RBACService(mockSupabase as any, superAdminUser, mockSession, 'test-app');
466
- await service.initialize();
467
-
468
- expect(service.hasRole('super_admin')).toBe(true);
469
- expect(service.hasRole('super')).toBe(true);
470
- });
471
- });
472
-
473
- describe('Error Handling', () => {
474
- it('should handle missing dependencies gracefully', async () => {
475
- const serviceWithoutUser = new RBACService(mockSupabase as any, null, null, 'test-app', true);
476
-
477
- await serviceWithoutUser.refreshPermissions();
478
-
479
- expect(serviceWithoutUser.getPermissions()).toEqual({});
480
- expect(serviceWithoutUser.getRoles()).toEqual([]);
481
- expect(serviceWithoutUser.getAccessLevel()).toBe(AccessLevel.VIEWER);
482
- });
483
-
484
- it('should handle network errors', async () => {
485
- mockSupabase.from().select().eq().eq().single.mockRejectedValue(new Error('Network error'));
486
-
487
- await rbacService.initialize();
488
-
489
- expect(rbacService.getError()).toBeDefined();
490
- });
491
- });
492
- });
@@ -1,62 +0,0 @@
1
- /**
2
- * @file RBAC Service Interface
3
- * @package @jmruthers/pace-core
4
- * @module Services/Interfaces
5
- * @since 0.1.0
6
- *
7
- * Interface for RBAC service operations.
8
- * Defines the contract for role-based access control functionality.
9
- */
10
-
11
- import { AccessLevel } from '../../types/unified';
12
-
13
- export interface UserEventAccess {
14
- event_id: string;
15
- event_name: string;
16
- event_description?: string | null;
17
- start_date: string;
18
- end_date: string;
19
- event_status: string;
20
- app_id: string;
21
- access_level: string;
22
- granted_at: string;
23
- organisation_id: string;
24
- }
25
-
26
- export interface AppConfig {
27
- supports_direct_access: boolean;
28
- requires_event: boolean;
29
- }
30
-
31
- export interface IRBACService {
32
- // RBAC state
33
- getPermissions(): Record<string, boolean>;
34
- getRoles(): string[];
35
- getAccessLevel(): AccessLevel;
36
- isLoading(): boolean;
37
- getError(): Error | null;
38
- getSelectedEventId(): string | null;
39
- getAppConfig(): AppConfig | null;
40
- getUserEventAccess(): UserEventAccess[];
41
- isEventAccessLoading(): boolean;
42
- getSelectedOrganisationId(): string | null;
43
-
44
- // RBAC methods
45
- hasPermission(permission: string, orgId?: string): boolean;
46
- hasAnyPermission(permissions: string[], orgId?: string): boolean;
47
- hasAllPermissions(permissions: string[], orgId?: string): boolean;
48
- hasRole(role: string): boolean;
49
- hasAccessLevel(level: AccessLevel): boolean;
50
- canAccess(resource: string, action: string, orgId?: string): boolean;
51
- validatePermission(permission: string, orgId?: string): Promise<boolean>;
52
- validateAccess(resource: string, action: string, orgId?: string): Promise<boolean>;
53
- refreshPermissions(eventId?: string, orgId?: string): Promise<void>;
54
- setSelectedEventId(eventId: string | null): void;
55
- loadUserEventAccess(orgId?: string): Promise<void>;
56
- getUserEventAccessById(eventId: string): UserEventAccess | undefined;
57
- requireOrganisationContext(): string;
58
-
59
- // Lifecycle
60
- initialize(): Promise<void>;
61
- cleanup(): void;
62
- }