@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
@@ -44,6 +44,8 @@ describe('RBACEngine - Comprehensive Tests', () => {
44
44
 
45
45
  beforeEach(() => {
46
46
  mockSupabase = createMockSupabaseClient();
47
+ // Set default RPC mock to return true (can be overridden per test)
48
+ mockSupabase.rpc = vi.fn().mockResolvedValue({ data: true, error: null });
47
49
  engine = new RBACEngine(mockSupabase as any);
48
50
  // Clear cache before each test
49
51
  rbacCache.clear();
@@ -55,6 +57,13 @@ describe('RBACEngine - Comprehensive Tests', () => {
55
57
  rbacCache.clear();
56
58
  });
57
59
 
60
+ // Helper function to create security context
61
+ const createSecurityContext = (userId: string, organisationId?: string) => ({
62
+ userId: userId as UUID,
63
+ organisationId: organisationId as UUID | undefined,
64
+ timestamp: new Date()
65
+ });
66
+
58
67
  describe('Constructor and Factory', () => {
59
68
  it('creates engine instance with Supabase client', () => {
60
69
  expect(engine).toBeInstanceOf(RBACEngine);
@@ -69,62 +78,41 @@ describe('RBACEngine - Comprehensive Tests', () => {
69
78
 
70
79
  describe('Permission Checking - Super Admin Bypass', () => {
71
80
  it('allows super admin to bypass all permissions', async () => {
72
- // Mock the global roles query to return super_admin role
73
- mockSupabase.from.mockReturnValueOnce({
74
- select: vi.fn().mockReturnThis(),
75
- eq: vi.fn().mockReturnThis(),
76
- lte: vi.fn().mockReturnThis(),
77
- or: vi.fn().mockReturnThis(),
78
- limit: vi.fn().mockResolvedValue({
79
- data: [{ role: 'super_admin' }],
80
- error: null
81
- })
82
- });
81
+ // Override default mock - engine may call RPC multiple times
82
+ mockSupabase.rpc = vi.fn().mockResolvedValue({ data: true, error: null });
83
83
 
84
84
  const permissionCheck: PermissionCheck = {
85
- userId: 'super-admin-123' as UUID,
86
- scope: { organisationId: 'org-123' as UUID },
85
+ userId: '00000000-0000-0000-0000-000000000001' as UUID,
86
+ scope: { organisationId: '00000000-0000-0000-0000-000000000002' as UUID },
87
87
  permission: 'manage:everything' as Permission
88
88
  };
89
89
 
90
- const result = await engine.isPermitted(permissionCheck);
90
+ const securityContext = createSecurityContext('00000000-0000-0000-0000-000000000001', '00000000-0000-0000-0000-000000000002');
91
+
92
+ const result = await engine.isPermitted(permissionCheck, securityContext);
91
93
  expect(result).toBe(true);
92
94
  });
93
95
 
94
96
  it('denies non-super admin users', async () => {
95
- // Mock super admin check to return false
96
- mockSupabase.rpc.mockResolvedValue({
97
- data: [{ has_permission: false, role_name: null }],
97
+ // Mock the RPC call to return false for non-super admin
98
+ mockSupabase.rpc.mockResolvedValueOnce({
99
+ data: false,
98
100
  error: null
99
101
  });
100
102
 
101
- // Mock app config
102
- mockSupabase.from.mockReturnValue({
103
- select: vi.fn().mockReturnThis(),
104
- eq: vi.fn().mockReturnThis(),
105
- single: vi.fn().mockResolvedValue({
106
- data: { requires_event: false },
107
- error: null
108
- })
109
- });
110
-
111
- // Mock empty roles and permissions
112
- mockSupabase.from.mockImplementation(() => ({
113
- select: vi.fn().mockReturnThis(),
114
- eq: vi.fn().mockReturnThis(),
115
- lte: vi.fn().mockReturnThis(),
116
- or: vi.fn().mockReturnThis(),
117
- data: [],
118
- error: null
119
- }));
120
-
121
103
  const permissionCheck: PermissionCheck = {
122
104
  userId: 'regular-user-123' as UUID,
123
- scope: { organisationId: 'org-123' as UUID },
105
+ scope: { organisationId: '00000000-0000-0000-0000-000000000002' as UUID },
124
106
  permission: 'manage:everything' as Permission
125
107
  };
126
108
 
127
- const result = await engine.isPermitted(permissionCheck);
109
+ const securityContext = {
110
+ userId: 'regular-user-123' as UUID,
111
+ organisationId: '00000000-0000-0000-0000-000000000002' as UUID,
112
+ timestamp: new Date()
113
+ };
114
+
115
+ const result = await engine.isPermitted(permissionCheck, securityContext);
128
116
  expect(result).toBe(false);
129
117
  });
130
118
  });
@@ -158,8 +146,8 @@ describe('RBACEngine - Comprehensive Tests', () => {
158
146
  });
159
147
 
160
148
  const permissionCheck: PermissionCheck = {
161
- userId: 'user-123' as UUID,
162
- scope: { organisationId: 'org-123' as UUID, appId: 'app-123' as UUID },
149
+ userId: '00000000-0000-0000-0000-000000000001' as UUID,
150
+ scope: { organisationId: '00000000-0000-0000-0000-000000000002' as UUID, appId: '00000000-0000-0000-0000-000000000003' as UUID },
163
151
  permission: 'read:users' as Permission
164
152
  };
165
153
 
@@ -205,11 +193,11 @@ describe('RBACEngine - Comprehensive Tests', () => {
205
193
  });
206
194
 
207
195
  const permissionCheck: PermissionCheck = {
208
- userId: 'user-123' as UUID,
196
+ userId: '00000000-0000-0000-0000-000000000001' as UUID,
209
197
  scope: {
210
- organisationId: 'org-123' as UUID,
198
+ organisationId: '00000000-0000-0000-0000-000000000002' as UUID,
211
199
  eventId: 'event-123',
212
- appId: 'app-123' as UUID
200
+ appId: '00000000-0000-0000-0000-000000000003' as UUID
213
201
  },
214
202
  permission: 'read:users' as Permission
215
203
  };
@@ -246,8 +234,8 @@ describe('RBACEngine - Comprehensive Tests', () => {
246
234
  });
247
235
 
248
236
  const permissionCheck: PermissionCheck = {
249
- userId: 'user-123' as UUID,
250
- scope: { appId: 'app-123' as UUID }, // Missing organisationId
237
+ userId: '00000000-0000-0000-0000-000000000001' as UUID,
238
+ scope: { appId: '00000000-0000-0000-0000-000000000003' as UUID }, // Missing organisationId
251
239
  permission: 'read:users' as Permission
252
240
  };
253
241
 
@@ -258,276 +246,73 @@ describe('RBACEngine - Comprehensive Tests', () => {
258
246
 
259
247
  describe('Permission Checking - Grant Collection', () => {
260
248
  it('collects and processes page-level grants', async () => {
261
- // Mock super admin check to return false
262
- mockSupabase.rpc.mockResolvedValue({
263
- data: [{ has_permission: false, role_name: null }],
264
- error: null
265
- });
266
-
267
- // Mock app config
268
- mockSupabase.from.mockImplementation((table: string) => {
269
- if (table === 'rbac_apps') {
270
- return {
271
- select: vi.fn().mockReturnThis(),
272
- eq: vi.fn().mockReturnThis(),
273
- single: vi.fn().mockResolvedValue({
274
- data: { requires_event: false },
275
- error: null
276
- })
277
- };
278
- }
279
- if (table === 'rbac_app_pages') {
280
- return {
281
- select: vi.fn().mockReturnThis(),
282
- eq: vi.fn().mockReturnThis(),
283
- single: vi.fn().mockResolvedValue({
284
- data: { id: 'page-123', page_name: 'users' },
285
- error: null
286
- })
287
- };
288
- }
289
- return {
290
- select: vi.fn().mockReturnThis(),
291
- eq: vi.fn().mockReturnThis(),
292
- lte: vi.fn().mockReturnThis(),
293
- or: vi.fn().mockReturnThis(),
294
- data: [],
295
- error: null
296
- };
297
- });
298
-
299
- // Mock RPC call for page permissions
300
- mockSupabase.rpc.mockImplementation((functionName: string) => {
301
- if (functionName === 'rbac_permissions_get') {
302
- return Promise.resolve({
303
- data: [
304
- {
305
- permission_type: 'read:page.users',
306
- role_name: 'org_admin',
307
- has_permission: true,
308
- granted_at: '2023-01-01T00:00:00Z'
309
- }
310
- ],
311
- error: null
312
- });
313
- }
314
- return Promise.resolve({ data: null, error: null });
315
- });
316
-
317
- // Mock organisation roles to include org_admin
318
- mockSupabase.from.mockImplementation((table: string) => {
319
- if (table === 'rbac_apps') {
320
- return {
321
- select: vi.fn().mockReturnThis(),
322
- eq: vi.fn().mockReturnThis(),
323
- single: vi.fn().mockResolvedValue({
324
- data: { requires_event: false },
325
- error: null
326
- })
327
- };
328
- }
329
- if (table === 'rbac_app_pages') {
330
- return {
331
- select: vi.fn().mockReturnThis(),
332
- eq: vi.fn().mockReturnThis(),
333
- single: vi.fn().mockResolvedValue({
334
- data: { id: 'page-123', page_name: 'users' },
335
- error: null
336
- })
337
- };
338
- }
339
- if (table === 'rbac_organisation_roles') {
340
- return {
341
- select: vi.fn().mockReturnThis(),
342
- eq: vi.fn().mockReturnThis(),
343
- lte: vi.fn().mockReturnThis(),
344
- or: vi.fn().mockReturnThis(),
345
- limit: vi.fn().mockResolvedValue({
346
- data: [{ role: 'org_admin', status: 'active', valid_from: '2023-01-01', valid_to: null }],
347
- error: null
348
- }),
349
- data: [{ role: 'org_admin', status: 'active', valid_from: '2023-01-01', valid_to: null }],
350
- error: null
351
- };
352
- }
353
- if (table === 'rbac_global_roles') {
354
- return {
355
- select: vi.fn().mockReturnThis(),
356
- eq: vi.fn().mockReturnThis(),
357
- lte: vi.fn().mockReturnThis(),
358
- or: vi.fn().mockReturnThis(),
359
- limit: vi.fn().mockResolvedValue({ data: [], error: null }),
360
- data: [],
361
- error: null
362
- };
363
- }
364
- return {
365
- select: vi.fn().mockReturnThis(),
366
- eq: vi.fn().mockReturnThis(),
367
- lte: vi.fn().mockReturnThis(),
368
- or: vi.fn().mockReturnThis(),
369
- limit: vi.fn().mockResolvedValue({ data: [], error: null }),
370
- data: [],
371
- error: null
372
- };
373
- });
249
+ // Mock the simplified RPC to return true
250
+ mockSupabase.rpc = vi.fn().mockResolvedValue({ data: true, error: null });
374
251
 
375
252
  const permissionCheck: PermissionCheck = {
376
- userId: 'user-123' as UUID,
253
+ userId: '00000000-0000-0000-0000-000000000001' as UUID,
377
254
  scope: {
378
- organisationId: 'org-123' as UUID,
379
- appId: 'app-123' as UUID
255
+ organisationId: '00000000-0000-0000-0000-000000000002' as UUID,
256
+ appId: '00000000-0000-0000-0000-000000000003' as UUID
380
257
  },
381
- permission: 'read:page.users' as Permission,
382
- pageId: 'users'
258
+ permission: 'read:users' as Permission,
259
+ pageId: '00000000-0000-0000-0000-000000000004' as UUID
383
260
  };
384
261
 
385
- const result = await engine.isPermitted(permissionCheck);
262
+ const securityContext = createSecurityContext('00000000-0000-0000-0000-000000000001', '00000000-0000-0000-0000-000000000002');
263
+
264
+ const result = await engine.isPermitted(permissionCheck, securityContext);
386
265
  expect(result).toBe(true);
387
266
  });
388
267
 
389
268
  it('collects and processes global grants', async () => {
390
- // Mock app config
391
- mockSupabase.from.mockImplementation((table: string) => {
392
- if (table === 'rbac_apps') {
393
- return {
394
- select: vi.fn().mockReturnThis(),
395
- eq: vi.fn().mockReturnThis(),
396
- single: vi.fn().mockResolvedValue({
397
- data: { requires_event: false },
398
- error: null
399
- })
400
- };
401
- }
402
- if (table === 'rbac_global_roles') {
403
- return {
404
- select: vi.fn().mockReturnThis(),
405
- eq: vi.fn().mockReturnThis(),
406
- lte: vi.fn().mockReturnThis(),
407
- or: vi.fn().mockReturnThis(),
408
- limit: vi.fn().mockResolvedValue({
409
- data: [{ role: 'super_admin', valid_from: '2023-01-01', valid_to: null }],
410
- error: null
411
- }),
412
- data: [{ role: 'super_admin', valid_from: '2023-01-01', valid_to: null }],
413
- error: null
414
- };
415
- }
416
- return {
417
- select: vi.fn().mockReturnThis(),
418
- eq: vi.fn().mockReturnThis(),
419
- lte: vi.fn().mockReturnThis(),
420
- or: vi.fn().mockReturnThis(),
421
- limit: vi.fn().mockResolvedValue({ data: [], error: null }),
422
- data: [],
423
- error: null
424
- };
425
- });
269
+ // Mock the simplified RPC to return true
270
+ mockSupabase.rpc = vi.fn().mockResolvedValue({ data: true, error: null });
426
271
 
427
272
  const permissionCheck: PermissionCheck = {
428
- userId: 'user-123' as UUID,
429
- scope: { organisationId: 'org-123' as UUID },
430
- permission: 'read:*' as Permission
273
+ userId: '00000000-0000-0000-0000-000000000001' as UUID,
274
+ scope: { organisationId: '00000000-0000-0000-0000-000000000002' as UUID },
275
+ permission: 'read:users' as Permission
431
276
  };
432
277
 
433
- const result = await engine.isPermitted(permissionCheck);
278
+ const securityContext = createSecurityContext('00000000-0000-0000-0000-000000000001', '00000000-0000-0000-0000-000000000002');
279
+
280
+ const result = await engine.isPermitted(permissionCheck, securityContext);
434
281
  expect(result).toBe(true);
435
282
  });
436
283
  });
437
284
 
438
285
  describe('Permission Matching Logic', () => {
439
286
  it('matches exact permissions', async () => {
440
- // Mock super admin check to return false
441
- mockSupabase.rpc.mockResolvedValue({
442
- data: [{ has_permission: false, role_name: null }],
443
- error: null
444
- });
445
-
446
- // Mock app config
447
- mockSupabase.from.mockImplementation((table: string) => {
448
- if (table === 'rbac_apps') {
449
- return {
450
- select: vi.fn().mockReturnThis(),
451
- eq: vi.fn().mockReturnThis(),
452
- single: vi.fn().mockResolvedValue({
453
- data: { requires_event: false },
454
- error: null
455
- })
456
- };
457
- }
458
- if (table === 'rbac_global_roles') {
459
- return {
460
- select: vi.fn().mockReturnThis(),
461
- eq: vi.fn().mockReturnThis(),
462
- lte: vi.fn().mockReturnThis(),
463
- or: vi.fn().mockReturnThis(),
464
- limit: vi.fn().mockResolvedValue({
465
- data: [{ role: 'super_admin', valid_from: '2023-01-01', valid_to: null }],
466
- error: null
467
- })
468
- };
469
- }
470
- return {
471
- select: vi.fn().mockReturnThis(),
472
- eq: vi.fn().mockReturnThis(),
473
- lte: vi.fn().mockReturnThis(),
474
- or: vi.fn().mockReturnThis(),
475
- limit: vi.fn().mockResolvedValue({ data: [], error: null })
476
- };
477
- });
287
+ // Mock the simplified RPC to return true
288
+ mockSupabase.rpc = vi.fn().mockResolvedValue({ data: true, error: null });
478
289
 
479
290
  const permissionCheck: PermissionCheck = {
480
- userId: 'user-123' as UUID,
481
- scope: { organisationId: 'org-123' as UUID },
291
+ userId: '00000000-0000-0000-0000-000000000001' as UUID,
292
+ scope: { organisationId: '00000000-0000-0000-0000-000000000002' as UUID },
482
293
  permission: 'read:users' as Permission
483
294
  };
484
295
 
485
- const result = await engine.isPermitted(permissionCheck);
486
- expect(result).toBe(true); // Should match read:* wildcard
296
+ const securityContext = createSecurityContext('00000000-0000-0000-0000-000000000001', '00000000-0000-0000-0000-000000000002');
297
+
298
+ const result = await engine.isPermitted(permissionCheck, securityContext);
299
+ expect(result).toBe(true);
487
300
  });
488
301
 
489
302
  it('matches wildcard permissions', async () => {
490
- // Mock app config
491
- mockSupabase.from.mockImplementation((table: string) => {
492
- if (table === 'rbac_apps') {
493
- return {
494
- select: vi.fn().mockReturnThis(),
495
- eq: vi.fn().mockReturnThis(),
496
- single: vi.fn().mockResolvedValue({
497
- data: { requires_event: false },
498
- error: null
499
- })
500
- };
501
- }
502
- if (table === 'rbac_global_roles') {
503
- return {
504
- select: vi.fn().mockReturnThis(),
505
- eq: vi.fn().mockReturnThis(),
506
- lte: vi.fn().mockReturnThis(),
507
- or: vi.fn().mockReturnThis(),
508
- limit: vi.fn().mockResolvedValue({
509
- data: [{ role: 'super_admin', valid_from: '2023-01-01', valid_to: null }],
510
- error: null
511
- })
512
- };
513
- }
514
- return {
515
- select: vi.fn().mockReturnThis(),
516
- eq: vi.fn().mockReturnThis(),
517
- lte: vi.fn().mockReturnThis(),
518
- or: vi.fn().mockReturnThis(),
519
- limit: vi.fn().mockResolvedValue({ data: [], error: null })
520
- };
521
- });
303
+ // Mock the simplified RPC to return true
304
+ mockSupabase.rpc = vi.fn().mockResolvedValue({ data: true, error: null });
522
305
 
523
306
  const permissionCheck: PermissionCheck = {
524
- userId: 'user-123' as UUID,
525
- scope: { organisationId: 'org-123' as UUID },
526
- permission: 'read:organisation.users' as Permission
307
+ userId: '00000000-0000-0000-0000-000000000001' as UUID,
308
+ scope: { organisationId: '00000000-0000-0000-0000-000000000002' as UUID },
309
+ permission: 'read:organisation' as Permission
527
310
  };
528
311
 
529
- const result = await engine.isPermitted(permissionCheck);
530
- expect(result).toBe(true); // Should match read:* wildcard
312
+ const securityContext = createSecurityContext('00000000-0000-0000-0000-000000000001', '00000000-0000-0000-0000-000000000002');
313
+
314
+ const result = await engine.isPermitted(permissionCheck, securityContext);
315
+ expect(result).toBe(true);
531
316
  });
532
317
  });
533
318
 
@@ -545,7 +330,7 @@ describe('RBACEngine - Comprehensive Tests', () => {
545
330
  })
546
331
  });
547
332
 
548
- const scope: Scope = { organisationId: 'org-123' as UUID };
333
+ const scope: Scope = { organisationId: '00000000-0000-0000-0000-000000000002' as UUID };
549
334
  const accessLevel = await engine.getAccessLevel({
550
335
  userId: 'super-admin-123' as UUID,
551
336
  scope
@@ -580,6 +365,7 @@ describe('RBACEngine - Comprehensive Tests', () => {
580
365
  return {
581
366
  select: vi.fn().mockReturnThis(),
582
367
  eq: vi.fn().mockReturnThis(),
368
+ is: vi.fn().mockReturnThis(),
583
369
  single: vi.fn().mockResolvedValue({
584
370
  data: { role: 'org_admin' },
585
371
  error: null
@@ -595,9 +381,9 @@ describe('RBACEngine - Comprehensive Tests', () => {
595
381
  };
596
382
  });
597
383
 
598
- const scope: Scope = { organisationId: 'org-123' as UUID };
384
+ const scope: Scope = { organisationId: '00000000-0000-0000-0000-000000000002' as UUID };
599
385
  const accessLevel = await engine.getAccessLevel({
600
- userId: 'user-123' as UUID,
386
+ userId: '00000000-0000-0000-0000-000000000001' as UUID,
601
387
  scope
602
388
  });
603
389
 
@@ -640,6 +426,7 @@ describe('RBACEngine - Comprehensive Tests', () => {
640
426
  return {
641
427
  select: vi.fn().mockReturnThis(),
642
428
  eq: vi.fn().mockReturnThis(),
429
+ is: vi.fn().mockReturnThis(),
643
430
  single: vi.fn().mockResolvedValue({
644
431
  data: null,
645
432
  error: { code: 'PGRST116' }
@@ -650,6 +437,7 @@ describe('RBACEngine - Comprehensive Tests', () => {
650
437
  return {
651
438
  select: vi.fn().mockReturnThis(),
652
439
  eq: vi.fn().mockReturnThis(),
440
+ is: vi.fn().mockReturnThis(),
653
441
  lte: vi.fn().mockReturnThis(),
654
442
  or: vi.fn().mockReturnThis(),
655
443
  single: vi.fn().mockResolvedValue({
@@ -668,12 +456,12 @@ describe('RBACEngine - Comprehensive Tests', () => {
668
456
  });
669
457
 
670
458
  const scope: Scope = {
671
- organisationId: 'org-123' as UUID,
459
+ organisationId: '00000000-0000-0000-0000-000000000002' as UUID,
672
460
  eventId: 'event-123',
673
- appId: 'app-123' as UUID
461
+ appId: '00000000-0000-0000-0000-000000000003' as UUID
674
462
  };
675
463
  const accessLevel = await engine.getAccessLevel({
676
- userId: 'user-123' as UUID,
464
+ userId: '00000000-0000-0000-0000-000000000001' as UUID,
677
465
  scope
678
466
  });
679
467
 
@@ -706,6 +494,7 @@ describe('RBACEngine - Comprehensive Tests', () => {
706
494
  return {
707
495
  select: vi.fn().mockReturnThis(),
708
496
  eq: vi.fn().mockReturnThis(),
497
+ is: vi.fn().mockReturnThis(),
709
498
  single: vi.fn().mockResolvedValue({
710
499
  data: null,
711
500
  error: { code: 'PGRST116' }
@@ -721,9 +510,9 @@ describe('RBACEngine - Comprehensive Tests', () => {
721
510
  };
722
511
  });
723
512
 
724
- const scope: Scope = { organisationId: 'org-123' as UUID };
513
+ const scope: Scope = { organisationId: '00000000-0000-0000-0000-000000000002' as UUID };
725
514
  const accessLevel = await engine.getAccessLevel({
726
- userId: 'user-123' as UUID,
515
+ userId: '00000000-0000-0000-0000-000000000001' as UUID,
727
516
  scope
728
517
  });
729
518
 
@@ -732,7 +521,7 @@ describe('RBACEngine - Comprehensive Tests', () => {
732
521
  });
733
522
 
734
523
  describe('Permission Map Generation', () => {
735
- it('returns empty map for super admin', async () => {
524
+ it('returns wildcard permission map for super admin', async () => {
736
525
  // Mock global roles query to return super admin
737
526
  mockSupabase.from.mockReturnValue({
738
527
  select: vi.fn().mockReturnThis(),
@@ -745,13 +534,13 @@ describe('RBACEngine - Comprehensive Tests', () => {
745
534
  })
746
535
  });
747
536
 
748
- const scope: Scope = { organisationId: 'org-123' as UUID };
537
+ const scope: Scope = { organisationId: '00000000-0000-0000-0000-000000000002' as UUID };
749
538
  const permissionMap = await engine.getPermissionMap({
750
539
  userId: 'super-admin-123' as UUID,
751
540
  scope
752
541
  });
753
542
 
754
- expect(permissionMap).toEqual({});
543
+ expect(permissionMap).toEqual({ '*': true });
755
544
  });
756
545
 
757
546
  it('generates permission map for regular user', async () => {
@@ -806,11 +595,11 @@ describe('RBACEngine - Comprehensive Tests', () => {
806
595
  });
807
596
 
808
597
  const scope: Scope = {
809
- organisationId: 'org-123' as UUID,
810
- appId: 'app-123' as UUID
598
+ organisationId: '00000000-0000-0000-0000-000000000002' as UUID,
599
+ appId: '00000000-0000-0000-0000-000000000003' as UUID
811
600
  };
812
601
  const permissionMap = await engine.getPermissionMap({
813
- userId: 'user-123' as UUID,
602
+ userId: '00000000-0000-0000-0000-000000000001' as UUID,
814
603
  scope
815
604
  });
816
605
 
@@ -833,8 +622,8 @@ describe('RBACEngine - Comprehensive Tests', () => {
833
622
  });
834
623
 
835
624
  const permissionCheck: PermissionCheck = {
836
- userId: 'user-123' as UUID,
837
- scope: { organisationId: 'org-123' as UUID },
625
+ userId: '00000000-0000-0000-0000-000000000001' as UUID,
626
+ scope: { organisationId: '00000000-0000-0000-0000-000000000002' as UUID },
838
627
  permission: 'read:users' as Permission
839
628
  };
840
629
 
@@ -844,9 +633,9 @@ describe('RBACEngine - Comprehensive Tests', () => {
844
633
 
845
634
  it('handles invalid inputs gracefully', async () => {
846
635
  const invalidInputs = [
847
- { userId: '' as UUID, scope: { organisationId: 'org-123' as UUID }, permission: 'read:users' as Permission },
848
- { userId: 'user-123' as UUID, scope: {} as any, permission: 'read:users' as Permission },
849
- { userId: 'user-123' as UUID, scope: { organisationId: 'org-123' as UUID }, permission: '' as Permission },
636
+ { userId: '' as UUID, scope: { organisationId: '00000000-0000-0000-0000-000000000002' as UUID }, permission: 'read:users' as Permission },
637
+ { userId: '00000000-0000-0000-0000-000000000001' as UUID, scope: {} as any, permission: 'read:users' as Permission },
638
+ { userId: '00000000-0000-0000-0000-000000000001' as UUID, scope: { organisationId: '00000000-0000-0000-0000-000000000002' as UUID }, permission: '' as Permission },
850
639
  ];
851
640
 
852
641
  for (const input of invalidInputs) {
@@ -860,8 +649,8 @@ describe('RBACEngine - Comprehensive Tests', () => {
860
649
  mockSupabase.rpc.mockRejectedValue(new Error('RPC call failed'));
861
650
 
862
651
  const permissionCheck: PermissionCheck = {
863
- userId: 'user-123' as UUID,
864
- scope: { organisationId: 'org-123' as UUID },
652
+ userId: '00000000-0000-0000-0000-000000000001' as UUID,
653
+ scope: { organisationId: '00000000-0000-0000-0000-000000000002' as UUID },
865
654
  permission: 'read:users' as Permission
866
655
  };
867
656
 
@@ -872,54 +661,31 @@ describe('RBACEngine - Comprehensive Tests', () => {
872
661
 
873
662
  describe('Cache Integration', () => {
874
663
  it('uses cache for repeated permission checks', async () => {
875
- // Mock app config
876
- let callCount = 0;
877
- mockSupabase.from.mockImplementation((table: string) => {
878
- if (table === 'rbac_apps') {
879
- return {
880
- select: vi.fn().mockReturnThis(),
881
- eq: vi.fn().mockReturnThis(),
882
- single: vi.fn().mockResolvedValue({
883
- data: { requires_event: false },
884
- error: null
885
- })
886
- };
887
- }
888
- if (table === 'rbac_global_roles') {
889
- callCount++;
890
- return {
891
- select: vi.fn().mockReturnThis(),
892
- eq: vi.fn().mockReturnThis(),
893
- lte: vi.fn().mockReturnThis(),
894
- or: vi.fn().mockReturnThis(),
895
- limit: vi.fn().mockResolvedValue({ data: [], error: null })
896
- };
897
- }
898
- return {
899
- select: vi.fn().mockReturnThis(),
900
- eq: vi.fn().mockReturnThis(),
901
- lte: vi.fn().mockReturnThis(),
902
- or: vi.fn().mockReturnThis(),
903
- limit: vi.fn().mockResolvedValue({ data: [], error: null })
904
- };
664
+ // Mock RPC to return true
665
+ let rpcCallCount = 0;
666
+ mockSupabase.rpc.mockImplementation(() => {
667
+ rpcCallCount++;
668
+ return Promise.resolve({ data: true, error: null });
905
669
  });
906
670
 
907
671
  const permissionCheck: PermissionCheck = {
908
- userId: 'user-123' as UUID,
909
- scope: { organisationId: 'org-123' as UUID },
672
+ userId: '00000000-0000-0000-0000-000000000001' as UUID,
673
+ scope: { organisationId: '00000000-0000-0000-0000-000000000002' as UUID },
910
674
  permission: 'read:users' as Permission
911
675
  };
912
676
 
677
+ const securityContext = createSecurityContext('00000000-0000-0000-0000-000000000001', '00000000-0000-0000-0000-000000000002');
678
+
913
679
  // First call
914
- const result1 = await engine.isPermitted(permissionCheck);
915
- expect(result1).toBe(false);
680
+ const result1 = await engine.isPermitted(permissionCheck, securityContext);
681
+ expect(result1).toBe(true);
916
682
 
917
683
  // Second call should use cache
918
- const result2 = await engine.isPermitted(permissionCheck);
919
- expect(result2).toBe(false);
684
+ const result2 = await engine.isPermitted(permissionCheck, securityContext);
685
+ expect(result2).toBe(true);
920
686
 
921
- // Verify global roles query was called at least once
922
- expect(callCount).toBeGreaterThanOrEqual(1);
687
+ // Verify RPC was called exactly once (second call should hit cache)
688
+ expect(rpcCallCount).toBe(1);
923
689
 
924
690
  // Verify results are the same (caching is working)
925
691
  expect(result1).toBe(result2);
@@ -965,10 +731,10 @@ describe('RBACEngine - Comprehensive Tests', () => {
965
731
  });
966
732
 
967
733
  const permissionCheck: PermissionCheck = {
968
- userId: 'user-123' as UUID,
734
+ userId: '00000000-0000-0000-0000-000000000001' as UUID,
969
735
  scope: {
970
- organisationId: 'org-123' as UUID,
971
- appId: 'app-123' as UUID
736
+ organisationId: '00000000-0000-0000-0000-000000000002' as UUID,
737
+ appId: '00000000-0000-0000-0000-000000000003' as UUID
972
738
  },
973
739
  permission: 'read:page.users' as Permission,
974
740
  pageId: 'users' // Page name, not UUID
@@ -1008,8 +774,8 @@ describe('RBACEngine - Comprehensive Tests', () => {
1008
774
  });
1009
775
 
1010
776
  const permissionCheck: PermissionCheck = {
1011
- userId: 'user-123' as UUID,
1012
- scope: { organisationId: 'org-123' as UUID },
777
+ userId: '00000000-0000-0000-0000-000000000001' as UUID,
778
+ scope: { organisationId: '00000000-0000-0000-0000-000000000002' as UUID },
1013
779
  permission: 'read:users' as Permission
1014
780
  };
1015
781