@jmruthers/pace-core 0.5.189 → 0.5.190

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 (420) hide show
  1. package/core-usage-manifest.json +0 -4
  2. package/dist/{AuthService-B-cd2MA4.d.ts → AuthService-CbP_utw2.d.ts} +7 -3
  3. package/dist/{DataTable-GUFUNZ3N.js → DataTable-ON3IXISJ.js} +8 -8
  4. package/dist/{PublicPageProvider-B8HaLe69.d.ts → PublicPageProvider-C4uxosp6.d.ts} +83 -24
  5. package/dist/{UnifiedAuthProvider-BG0AL5eE.d.ts → UnifiedAuthProvider-BYA9qB-o.d.ts} +4 -3
  6. package/dist/{UnifiedAuthProvider-643PUAIM.js → UnifiedAuthProvider-X5NXANVI.js} +4 -2
  7. package/dist/{api-YP7XD5L6.js → api-I6UCQ5S6.js} +4 -2
  8. package/dist/{chunk-DDM4CCYT.js → chunk-4QYC5L4K.js} +60 -35
  9. package/dist/chunk-4QYC5L4K.js.map +1 -0
  10. package/dist/{chunk-IM4QE42D.js → chunk-73HSNNOQ.js} +141 -326
  11. package/dist/chunk-73HSNNOQ.js.map +1 -0
  12. package/dist/{chunk-YHCN776L.js → chunk-DZWK57KZ.js} +2 -75
  13. package/dist/chunk-DZWK57KZ.js.map +1 -0
  14. package/dist/{chunk-3GOZZZYH.js → chunk-HQVPB5MZ.js} +238 -301
  15. package/dist/chunk-HQVPB5MZ.js.map +1 -0
  16. package/dist/{chunk-THRPYOFK.js → chunk-HW3OVDUF.js} +5 -5
  17. package/dist/chunk-HW3OVDUF.js.map +1 -0
  18. package/dist/{chunk-F2IMUDXZ.js → chunk-I7PSE6JW.js} +75 -2
  19. package/dist/chunk-I7PSE6JW.js.map +1 -0
  20. package/dist/{chunk-VGZZXKBR.js → chunk-J2XXC7R5.js} +280 -52
  21. package/dist/chunk-J2XXC7R5.js.map +1 -0
  22. package/dist/{chunk-UCQSRW7Z.js → chunk-NIU6J6OX.js} +425 -378
  23. package/dist/chunk-NIU6J6OX.js.map +1 -0
  24. package/dist/{chunk-HESYZWZW.js → chunk-QWWZ5CAQ.js} +2 -2
  25. package/dist/{chunk-HEHYGYOX.js → chunk-RUYZKXOD.js} +401 -46
  26. package/dist/chunk-RUYZKXOD.js.map +1 -0
  27. package/dist/{chunk-2UUZZJFT.js → chunk-SDMHPX3X.js} +176 -160
  28. package/dist/{chunk-2UUZZJFT.js.map → chunk-SDMHPX3X.js.map} +1 -1
  29. package/dist/{chunk-MX64ZF6I.js → chunk-STYK4OH2.js} +11 -11
  30. package/dist/chunk-STYK4OH2.js.map +1 -0
  31. package/dist/{chunk-YGPFYGA6.js → chunk-VVBAW5A5.js} +822 -498
  32. package/dist/chunk-VVBAW5A5.js.map +1 -0
  33. package/dist/chunk-Y4BUBBHD.js +614 -0
  34. package/dist/chunk-Y4BUBBHD.js.map +1 -0
  35. package/dist/{chunk-SAUPYVLF.js → chunk-ZSAAAMVR.js} +1 -1
  36. package/dist/chunk-ZSAAAMVR.js.map +1 -0
  37. package/dist/components.d.ts +3 -4
  38. package/dist/components.js +19 -19
  39. package/dist/components.js.map +1 -1
  40. package/dist/eslint-rules/pace-core-compliance.cjs +0 -2
  41. package/dist/{file-reference-D037xOFK.d.ts → file-reference-BavO2eQj.d.ts} +13 -10
  42. package/dist/hooks.d.ts +10 -5
  43. package/dist/hooks.js +14 -8
  44. package/dist/hooks.js.map +1 -1
  45. package/dist/index.d.ts +13 -11
  46. package/dist/index.js +79 -69
  47. package/dist/index.js.map +1 -1
  48. package/dist/providers.d.ts +3 -3
  49. package/dist/providers.js +3 -1
  50. package/dist/rbac/index.d.ts +76 -12
  51. package/dist/rbac/index.js +12 -9
  52. package/dist/types.d.ts +1 -1
  53. package/dist/types.js +1 -1
  54. package/dist/{usePublicRouteParams-CTDELQ7H.d.ts → usePublicRouteParams-DxIDS4bC.d.ts} +16 -9
  55. package/dist/utils.js +16 -16
  56. package/docs/README.md +2 -2
  57. package/docs/api/classes/ColumnFactory.md +1 -1
  58. package/docs/api/classes/ErrorBoundary.md +1 -1
  59. package/docs/api/classes/InvalidScopeError.md +2 -2
  60. package/docs/api/classes/Logger.md +1 -1
  61. package/docs/api/classes/MissingUserContextError.md +2 -2
  62. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  63. package/docs/api/classes/PermissionDeniedError.md +1 -1
  64. package/docs/api/classes/RBACAuditManager.md +1 -1
  65. package/docs/api/classes/RBACCache.md +1 -1
  66. package/docs/api/classes/RBACEngine.md +4 -4
  67. package/docs/api/classes/RBACError.md +1 -1
  68. package/docs/api/classes/RBACNotInitializedError.md +2 -2
  69. package/docs/api/classes/SecureSupabaseClient.md +21 -16
  70. package/docs/api/classes/StorageUtils.md +7 -4
  71. package/docs/api/enums/FileCategory.md +1 -1
  72. package/docs/api/enums/LogLevel.md +1 -1
  73. package/docs/api/enums/RBACErrorCode.md +1 -1
  74. package/docs/api/enums/RPCFunction.md +1 -1
  75. package/docs/api/interfaces/AddressFieldProps.md +1 -1
  76. package/docs/api/interfaces/AddressFieldRef.md +1 -1
  77. package/docs/api/interfaces/AggregateConfig.md +1 -1
  78. package/docs/api/interfaces/AutocompleteOptions.md +1 -1
  79. package/docs/api/interfaces/AvatarProps.md +1 -1
  80. package/docs/api/interfaces/BadgeProps.md +1 -1
  81. package/docs/api/interfaces/ButtonProps.md +1 -1
  82. package/docs/api/interfaces/CalendarProps.md +20 -6
  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/ComplianceResult.md +1 -1
  87. package/docs/api/interfaces/DataAccessRecord.md +9 -9
  88. package/docs/api/interfaces/DataRecord.md +1 -1
  89. package/docs/api/interfaces/DataTableAction.md +1 -1
  90. package/docs/api/interfaces/DataTableColumn.md +1 -1
  91. package/docs/api/interfaces/DataTableProps.md +1 -1
  92. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  93. package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
  94. package/docs/api/interfaces/DatabaseIssue.md +1 -1
  95. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  96. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  97. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  98. package/docs/api/interfaces/ExportColumn.md +1 -1
  99. package/docs/api/interfaces/ExportOptions.md +1 -1
  100. package/docs/api/interfaces/FileDisplayProps.md +62 -16
  101. package/docs/api/interfaces/FileMetadata.md +1 -1
  102. package/docs/api/interfaces/FileReference.md +2 -2
  103. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  104. package/docs/api/interfaces/FileUploadOptions.md +26 -12
  105. package/docs/api/interfaces/FileUploadProps.md +30 -19
  106. package/docs/api/interfaces/FooterProps.md +1 -1
  107. package/docs/api/interfaces/FormFieldProps.md +1 -1
  108. package/docs/api/interfaces/FormProps.md +1 -1
  109. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  110. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  111. package/docs/api/interfaces/InputProps.md +1 -1
  112. package/docs/api/interfaces/LabelProps.md +1 -1
  113. package/docs/api/interfaces/LoggerConfig.md +1 -1
  114. package/docs/api/interfaces/LoginFormProps.md +1 -1
  115. package/docs/api/interfaces/NavigationAccessRecord.md +10 -10
  116. package/docs/api/interfaces/NavigationContextType.md +9 -9
  117. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  118. package/docs/api/interfaces/NavigationItem.md +1 -1
  119. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  120. package/docs/api/interfaces/NavigationProviderProps.md +7 -7
  121. package/docs/api/interfaces/Organisation.md +1 -1
  122. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  123. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  124. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  125. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  126. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  127. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  128. package/docs/api/interfaces/PageAccessRecord.md +8 -8
  129. package/docs/api/interfaces/PagePermissionContextType.md +8 -8
  130. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  131. package/docs/api/interfaces/PagePermissionProviderProps.md +7 -7
  132. package/docs/api/interfaces/PaletteData.md +1 -1
  133. package/docs/api/interfaces/ParsedAddress.md +1 -1
  134. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  135. package/docs/api/interfaces/ProgressProps.md +3 -11
  136. package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
  137. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  138. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  139. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  140. package/docs/api/interfaces/QuickFix.md +1 -1
  141. package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
  142. package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
  143. package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
  144. package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
  145. package/docs/api/interfaces/RBACConfig.md +1 -1
  146. package/docs/api/interfaces/RBACContext.md +1 -1
  147. package/docs/api/interfaces/RBACLogger.md +1 -1
  148. package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
  149. package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
  150. package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
  151. package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
  152. package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
  153. package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
  154. package/docs/api/interfaces/RBACResult.md +1 -1
  155. package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
  156. package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
  157. package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
  158. package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
  159. package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
  160. package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
  161. package/docs/api/interfaces/RBACRolesListParams.md +1 -1
  162. package/docs/api/interfaces/RBACRolesListResult.md +1 -1
  163. package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
  164. package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
  165. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  166. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  167. package/docs/api/interfaces/RoleBasedRouterContextType.md +8 -8
  168. package/docs/api/interfaces/RoleBasedRouterProps.md +10 -10
  169. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  170. package/docs/api/interfaces/RouteAccessRecord.md +10 -10
  171. package/docs/api/interfaces/RouteConfig.md +10 -10
  172. package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
  173. package/docs/api/interfaces/SecureDataContextType.md +9 -9
  174. package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
  175. package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
  176. package/docs/api/interfaces/SetupIssue.md +1 -1
  177. package/docs/api/interfaces/StorageConfig.md +4 -4
  178. package/docs/api/interfaces/StorageFileInfo.md +7 -7
  179. package/docs/api/interfaces/StorageFileMetadata.md +25 -14
  180. package/docs/api/interfaces/StorageListOptions.md +22 -9
  181. package/docs/api/interfaces/StorageListResult.md +4 -4
  182. package/docs/api/interfaces/StorageUploadOptions.md +21 -8
  183. package/docs/api/interfaces/StorageUploadResult.md +6 -6
  184. package/docs/api/interfaces/StorageUrlOptions.md +19 -6
  185. package/docs/api/interfaces/StyleImport.md +1 -1
  186. package/docs/api/interfaces/SwitchProps.md +1 -1
  187. package/docs/api/interfaces/TabsContentProps.md +1 -1
  188. package/docs/api/interfaces/TabsListProps.md +1 -1
  189. package/docs/api/interfaces/TabsProps.md +1 -1
  190. package/docs/api/interfaces/TabsTriggerProps.md +1 -1
  191. package/docs/api/interfaces/TextareaProps.md +1 -1
  192. package/docs/api/interfaces/ToastActionElement.md +1 -1
  193. package/docs/api/interfaces/ToastProps.md +1 -1
  194. package/docs/api/interfaces/UnifiedAuthContextType.md +53 -53
  195. package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
  196. package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
  197. package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
  198. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  199. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  200. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  201. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  202. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  203. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  204. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +1 -1
  205. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  206. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  207. package/docs/api/interfaces/UseResolvedScopeOptions.md +4 -4
  208. package/docs/api/interfaces/UseResolvedScopeReturn.md +4 -4
  209. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  210. package/docs/api/interfaces/UserEventAccess.md +11 -11
  211. package/docs/api/interfaces/UserMenuProps.md +1 -1
  212. package/docs/api/interfaces/UserProfile.md +1 -1
  213. package/docs/api/modules.md +151 -92
  214. package/docs/api-reference/components.md +15 -7
  215. package/docs/api-reference/providers.md +2 -2
  216. package/docs/api-reference/rpc-functions.md +1 -0
  217. package/docs/best-practices/README.md +1 -1
  218. package/docs/best-practices/deployment.md +8 -8
  219. package/docs/getting-started/examples/README.md +2 -2
  220. package/docs/getting-started/installation-guide.md +4 -4
  221. package/docs/getting-started/quick-start.md +3 -3
  222. package/docs/migration/MIGRATION_GUIDE.md +3 -3
  223. package/docs/rbac/compliance/compliance-guide.md +2 -2
  224. package/docs/rbac/event-based-apps.md +2 -2
  225. package/docs/rbac/getting-started.md +2 -2
  226. package/docs/rbac/quick-start.md +2 -2
  227. package/docs/security/README.md +4 -4
  228. package/docs/standards/07-rbac-and-rls-standard.md +430 -7
  229. package/docs/troubleshooting/README.md +2 -2
  230. package/docs/troubleshooting/migration.md +3 -3
  231. package/package.json +1 -3
  232. package/scripts/check-pace-core-compliance.cjs +1 -1
  233. package/scripts/check-pace-core-compliance.js +1 -1
  234. package/src/__tests__/fixtures/supabase.ts +301 -0
  235. package/src/__tests__/public-recipe-view.test.ts +9 -9
  236. package/src/__tests__/rls-policies.test.ts +197 -61
  237. package/src/components/AddressField/AddressField.test.tsx +42 -0
  238. package/src/components/AddressField/AddressField.tsx +71 -60
  239. package/src/components/AddressField/README.md +1 -0
  240. package/src/components/Alert/Alert.test.tsx +50 -10
  241. package/src/components/Alert/Alert.tsx +5 -3
  242. package/src/components/Avatar/Avatar.test.tsx +95 -43
  243. package/src/components/Avatar/Avatar.tsx +16 -16
  244. package/src/components/Button/Button.test.tsx +2 -1
  245. package/src/components/Button/Button.tsx +3 -3
  246. package/src/components/Calendar/Calendar.test.tsx +53 -37
  247. package/src/components/Calendar/Calendar.tsx +409 -82
  248. package/src/components/Card/Card.test.tsx +7 -4
  249. package/src/components/Card/Card.tsx +3 -6
  250. package/src/components/Checkbox/Checkbox.tsx +2 -2
  251. package/src/components/DataTable/components/ActionButtons.tsx +5 -5
  252. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +2 -2
  253. package/src/components/DataTable/components/ColumnFilter.tsx +1 -1
  254. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +3 -3
  255. package/src/components/DataTable/components/DataTableBody.tsx +12 -12
  256. package/src/components/DataTable/components/DataTableCore.tsx +3 -3
  257. package/src/components/DataTable/components/DataTableToolbar.tsx +5 -5
  258. package/src/components/DataTable/components/DraggableColumnHeader.tsx +3 -3
  259. package/src/components/DataTable/components/EditableRow.tsx +2 -2
  260. package/src/components/DataTable/components/EmptyState.tsx +3 -3
  261. package/src/components/DataTable/components/GroupHeader.tsx +2 -2
  262. package/src/components/DataTable/components/GroupingDropdown.tsx +1 -1
  263. package/src/components/DataTable/components/ImportModal.tsx +4 -4
  264. package/src/components/DataTable/components/LoadingState.tsx +1 -1
  265. package/src/components/DataTable/components/PaginationControls.tsx +11 -11
  266. package/src/components/DataTable/components/UnifiedTableBody.tsx +9 -9
  267. package/src/components/DataTable/components/ViewRowModal.tsx +2 -2
  268. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +11 -37
  269. package/src/components/DataTable/components/__tests__/DataTableToolbar.test.tsx +157 -0
  270. package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +2 -1
  271. package/src/components/DataTable/components/__tests__/VirtualizedDataTable.test.tsx +128 -0
  272. package/src/components/DataTable/core/__tests__/ActionManager.test.ts +19 -0
  273. package/src/components/DataTable/core/__tests__/ColumnFactory.test.ts +51 -0
  274. package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +84 -0
  275. package/src/components/DataTable/core/__tests__/DataManager.test.ts +14 -0
  276. package/src/components/DataTable/core/__tests__/DataTableContext.test.tsx +136 -0
  277. package/src/components/DataTable/core/__tests__/LocalDataAdapter.test.ts +16 -0
  278. package/src/components/DataTable/core/__tests__/PluginRegistry.test.ts +18 -0
  279. package/src/components/DataTable/hooks/useDataTablePermissions.ts +28 -7
  280. package/src/components/DataTable/utils/__tests__/hierarchicalUtils.test.ts +30 -1
  281. package/src/components/DataTable/utils/hierarchicalUtils.ts +38 -10
  282. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +8 -3
  283. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +4 -4
  284. package/src/components/Dialog/Dialog.tsx +2 -2
  285. package/src/components/EventSelector/EventSelector.tsx +7 -7
  286. package/src/components/FileDisplay/FileDisplay.tsx +291 -179
  287. package/src/components/FileUpload/FileUpload.tsx +7 -4
  288. package/src/components/Header/Header.test.tsx +28 -0
  289. package/src/components/Header/Header.tsx +22 -9
  290. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +2 -2
  291. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +19 -14
  292. package/src/components/LoadingSpinner/LoadingSpinner.tsx +5 -5
  293. package/src/components/NavigationMenu/NavigationMenu.test.tsx +127 -1
  294. package/src/components/OrganisationSelector/OrganisationSelector.tsx +8 -8
  295. package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +4 -0
  296. package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +3 -0
  297. package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +3 -0
  298. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +16 -6
  299. package/src/components/PaceAppLayout/PaceAppLayout.tsx +37 -3
  300. package/src/components/PaceAppLayout/test-setup.tsx +1 -0
  301. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +66 -45
  302. package/src/components/PaceLoginPage/PaceLoginPage.tsx +6 -4
  303. package/src/components/Progress/Progress.test.tsx +18 -19
  304. package/src/components/Progress/Progress.tsx +31 -32
  305. package/src/components/PublicLayout/PublicLayout.test.tsx +6 -6
  306. package/src/components/PublicLayout/PublicPageProvider.tsx +5 -3
  307. package/src/components/Select/Select.tsx +5 -5
  308. package/src/components/Switch/Switch.test.tsx +2 -1
  309. package/src/components/Switch/Switch.tsx +1 -1
  310. package/src/components/Toast/Toast.tsx +1 -1
  311. package/src/components/Tooltip/Tooltip.test.tsx +8 -2
  312. package/src/components/UserMenu/UserMenu.tsx +3 -3
  313. package/src/eslint-rules/pace-core-compliance.cjs +0 -2
  314. package/src/eslint-rules/pace-core-compliance.js +0 -2
  315. package/src/hooks/__tests__/hooks.integration.test.tsx +4 -1
  316. package/src/hooks/__tests__/useAppConfig.unit.test.ts +76 -5
  317. package/src/hooks/__tests__/useDataTableState.test.ts +76 -0
  318. package/src/hooks/__tests__/useFileUrl.unit.test.ts +25 -69
  319. package/src/hooks/__tests__/useFileUrlCache.test.ts +129 -0
  320. package/src/hooks/__tests__/usePreventTabReload.test.ts +88 -0
  321. package/src/hooks/__tests__/{usePublicEvent.unit.test.ts → usePublicEvent.test.ts} +28 -1
  322. package/src/hooks/__tests__/useQueryCache.test.ts +144 -0
  323. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +58 -16
  324. package/src/hooks/index.ts +1 -1
  325. package/src/hooks/public/usePublicEvent.ts +2 -2
  326. package/src/hooks/public/usePublicFileDisplay.ts +173 -87
  327. package/src/hooks/useAppConfig.ts +24 -5
  328. package/src/hooks/useFileDisplay.ts +297 -34
  329. package/src/hooks/useFileReference.ts +56 -11
  330. package/src/hooks/useFileUrl.ts +1 -1
  331. package/src/hooks/useInactivityTracker.ts +16 -7
  332. package/src/hooks/usePermissionCache.test.ts +85 -8
  333. package/src/hooks/useQueryCache.ts +21 -0
  334. package/src/hooks/useSecureDataAccess.test.ts +80 -35
  335. package/src/hooks/useSecureDataAccess.ts +80 -37
  336. package/src/providers/services/EventServiceProvider.tsx +37 -17
  337. package/src/providers/services/InactivityServiceProvider.tsx +4 -4
  338. package/src/providers/services/OrganisationServiceProvider.tsx +8 -1
  339. package/src/providers/services/UnifiedAuthProvider.tsx +115 -29
  340. package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +451 -0
  341. package/src/rbac/__tests__/engine.comprehensive.test.ts +12 -0
  342. package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +8 -0
  343. package/src/rbac/__tests__/rbac-engine-simplified.test.ts +4 -0
  344. package/src/rbac/api.ts +240 -36
  345. package/src/rbac/cache-invalidation.ts +21 -7
  346. package/src/rbac/compliance/quick-fix-suggestions.ts +1 -1
  347. package/src/rbac/components/NavigationGuard.tsx +23 -63
  348. package/src/rbac/components/NavigationProvider.test.tsx +52 -23
  349. package/src/rbac/components/NavigationProvider.tsx +13 -11
  350. package/src/rbac/components/PagePermissionGuard.tsx +77 -203
  351. package/src/rbac/components/PagePermissionProvider.tsx +13 -11
  352. package/src/rbac/components/PermissionEnforcer.tsx +24 -62
  353. package/src/rbac/components/RoleBasedRouter.tsx +14 -12
  354. package/src/rbac/components/SecureDataProvider.tsx +13 -11
  355. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +104 -41
  356. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +49 -12
  357. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +22 -1
  358. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +161 -82
  359. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +22 -1
  360. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +77 -30
  361. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +39 -5
  362. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +47 -4
  363. package/src/rbac/engine.ts +4 -2
  364. package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +144 -52
  365. package/src/rbac/hooks/index.ts +3 -0
  366. package/src/rbac/hooks/useCan.test.ts +101 -53
  367. package/src/rbac/hooks/usePermissions.ts +108 -41
  368. package/src/rbac/hooks/useRBAC.test.ts +11 -3
  369. package/src/rbac/hooks/useRBAC.ts +83 -40
  370. package/src/rbac/hooks/useResolvedScope.test.ts +189 -63
  371. package/src/rbac/hooks/useResolvedScope.ts +128 -70
  372. package/src/rbac/hooks/useSecureSupabase.ts +36 -19
  373. package/src/rbac/hooks/useSuperAdminBypass.ts +126 -0
  374. package/src/rbac/request-deduplication.ts +1 -1
  375. package/src/rbac/secureClient.ts +72 -12
  376. package/src/rbac/security.ts +29 -23
  377. package/src/rbac/types.ts +10 -0
  378. package/src/rbac/utils/__tests__/contextValidator.test.ts +150 -0
  379. package/src/rbac/utils/__tests__/deep-equal.test.ts +53 -0
  380. package/src/rbac/utils/__tests__/eventContext.test.ts +6 -1
  381. package/src/rbac/utils/contextValidator.ts +288 -0
  382. package/src/rbac/utils/eventContext.ts +48 -2
  383. package/src/services/EventService.ts +165 -21
  384. package/src/services/OrganisationService.ts +37 -2
  385. package/src/services/__tests__/EventService.test.ts +26 -21
  386. package/src/types/file-reference.ts +13 -10
  387. package/src/utils/app/appNameResolver.test.ts +346 -73
  388. package/src/utils/context/superAdminOverride.ts +58 -0
  389. package/src/utils/file-reference/index.ts +61 -33
  390. package/src/utils/google-places/googlePlacesUtils.test.ts +98 -0
  391. package/src/utils/google-places/loadGoogleMapsScript.test.ts +83 -0
  392. package/src/utils/storage/helpers.test.ts +1 -1
  393. package/src/utils/storage/helpers.ts +38 -19
  394. package/src/utils/storage/types.ts +15 -8
  395. package/src/utils/validation/__tests__/csrf.test.ts +105 -0
  396. package/src/utils/validation/__tests__/sqlInjectionProtection.test.ts +92 -0
  397. package/src/vite-env.d.ts +2 -2
  398. package/dist/chunk-3GOZZZYH.js.map +0 -1
  399. package/dist/chunk-DDM4CCYT.js.map +0 -1
  400. package/dist/chunk-E7UAOUMY.js +0 -75
  401. package/dist/chunk-E7UAOUMY.js.map +0 -1
  402. package/dist/chunk-F2IMUDXZ.js.map +0 -1
  403. package/dist/chunk-HEHYGYOX.js.map +0 -1
  404. package/dist/chunk-IM4QE42D.js.map +0 -1
  405. package/dist/chunk-MX64ZF6I.js.map +0 -1
  406. package/dist/chunk-SAUPYVLF.js.map +0 -1
  407. package/dist/chunk-THRPYOFK.js.map +0 -1
  408. package/dist/chunk-UCQSRW7Z.js.map +0 -1
  409. package/dist/chunk-VGZZXKBR.js.map +0 -1
  410. package/dist/chunk-YGPFYGA6.js.map +0 -1
  411. package/dist/chunk-YHCN776L.js.map +0 -1
  412. package/src/hooks/__tests__/usePermissionCache.simple.test.ts +0 -192
  413. package/src/hooks/__tests__/usePermissionCache.unit.test.ts +0 -741
  414. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +0 -703
  415. package/src/rbac/hooks/useRBAC.simple.test.ts +0 -95
  416. package/src/rbac/utils/__tests__/eventContext.unit.test.ts +0 -428
  417. /package/dist/{DataTable-GUFUNZ3N.js.map → DataTable-ON3IXISJ.js.map} +0 -0
  418. /package/dist/{UnifiedAuthProvider-643PUAIM.js.map → UnifiedAuthProvider-X5NXANVI.js.map} +0 -0
  419. /package/dist/{api-YP7XD5L6.js.map → api-I6UCQ5S6.js.map} +0 -0
  420. /package/dist/{chunk-HESYZWZW.js.map → chunk-QWWZ5CAQ.js.map} +0 -0
@@ -1,3 +1,7 @@
1
+ import {
2
+ getAppConfigByName,
3
+ isSuperAdmin
4
+ } from "./chunk-RUYZKXOD.js";
1
5
  import {
2
6
  assertOrganisationId,
3
7
  assertUserId
@@ -653,6 +657,17 @@ var OrganisationService = class extends BaseService {
653
657
  }
654
658
  // Additional methods for testing
655
659
  setSelectedOrganisation(organisation) {
660
+ if (organisation && this._organisations.length > 0) {
661
+ const isValidOrg = this._organisations.some((org) => org.id === organisation.id);
662
+ if (!isValidOrg) {
663
+ logger.warn("OrganisationService", "Attempted to set invalid organisation - not in user's accessible organisations", {
664
+ organisationId: organisation.id,
665
+ organisationName: organisation.name,
666
+ accessibleOrgIds: this._organisations.map((o) => o.id)
667
+ });
668
+ return;
669
+ }
670
+ }
656
671
  this._selectedOrganisation = organisation;
657
672
  if (organisation) {
658
673
  localStorage.setItem("pace-core-selected-organisation", JSON.stringify(organisation));
@@ -1009,17 +1024,31 @@ var OrganisationService = class extends BaseService {
1009
1024
  if (!initialOrg) {
1010
1025
  throw new Error("No valid organisation found for user");
1011
1026
  }
1027
+ const currentSelectedOrg = this._selectedOrganisation;
1028
+ if (currentSelectedOrg && !activeOrgs.some((org) => org.id === currentSelectedOrg.id)) {
1029
+ logger.warn("OrganisationService", "Current selected organisation is no longer valid, resetting", {
1030
+ invalidOrgId: currentSelectedOrg.id,
1031
+ validOrgIds: activeOrgs.map((o) => o.id)
1032
+ });
1033
+ this._selectedOrganisation = null;
1034
+ }
1012
1035
  this._selectedOrganisation = initialOrg;
1013
1036
  localStorage.setItem("pace-core-selected-organisation", JSON.stringify(initialOrg));
1014
1037
  await this.setDatabaseOrganisationContext(initialOrg);
1015
1038
  this.retryCount = 0;
1016
1039
  this.hasFailedRef = false;
1017
1040
  } catch (err) {
1018
- logger.error("OrganisationService", "Failed to load organisations:", err);
1019
- this._error = err;
1041
+ const error = err;
1042
+ if (error.message === "User has no access to active organisations") {
1043
+ logger.warn("OrganisationService", "User has no active organisations (this is expected for users without organisation access):", error);
1044
+ } else {
1045
+ logger.error("OrganisationService", "Failed to load organisations:", err);
1046
+ }
1047
+ this._error = error;
1020
1048
  this.retryCount = this.retryCount + 1;
1021
1049
  this.hasFailedRef = true;
1022
1050
  this.clearAllCachedData();
1051
+ this._isContextReady = true;
1023
1052
  } finally {
1024
1053
  this.isLoadingRef = false;
1025
1054
  this._isLoading = false;
@@ -1058,7 +1087,12 @@ function OrganisationServiceProvider({
1058
1087
  let isMounted = true;
1059
1088
  organisationService.initialize().catch((error) => {
1060
1089
  if (isMounted) {
1061
- logger.error("OrganisationServiceProvider", "Failed to initialize organisation service:", error);
1090
+ const errorMessage = error instanceof Error ? error.message : String(error);
1091
+ if (errorMessage === "User has no access to active organisations") {
1092
+ logger.warn("OrganisationServiceProvider", "User has no active organisations (this is expected for users without organisation access):", error);
1093
+ } else {
1094
+ logger.error("OrganisationServiceProvider", "Failed to initialize organisation service:", error);
1095
+ }
1062
1096
  }
1063
1097
  });
1064
1098
  return () => {
@@ -1095,6 +1129,10 @@ var EventService = class extends BaseService {
1095
1129
  this.appName = "";
1096
1130
  this.selectedOrganisation = null;
1097
1131
  this.setSelectedEventId = null;
1132
+ this.isSuperAdmin = false;
1133
+ // Track super admin status for conditional validation
1134
+ this.appConfig = null;
1135
+ // Cache app config to avoid repeated lookups
1098
1136
  // Internal state management
1099
1137
  this.isInitializedRef = false;
1100
1138
  this.isFetchingRef = false;
@@ -1120,6 +1158,7 @@ var EventService = class extends BaseService {
1120
1158
  const newOrgId = selectedOrganisation?.id;
1121
1159
  const previousUserId = this.user?.id || null;
1122
1160
  const newUserId = user?.id || null;
1161
+ const previousAppName = this.appName;
1123
1162
  if (previousUserId !== newUserId) {
1124
1163
  if (previousUserId !== null) {
1125
1164
  await this.clearEventSelectionForUser(previousUserId);
@@ -1128,6 +1167,9 @@ var EventService = class extends BaseService {
1128
1167
  this.selectedEvent = null;
1129
1168
  this.setSelectedEventId?.(null);
1130
1169
  }
1170
+ this.resetInitialization();
1171
+ this.isInitializedRef = false;
1172
+ this.isFetchingRef = false;
1131
1173
  }
1132
1174
  this.supabaseClient = supabaseClient;
1133
1175
  this.user = user;
@@ -1135,6 +1177,23 @@ var EventService = class extends BaseService {
1135
1177
  this.appName = appName;
1136
1178
  this.selectedOrganisation = selectedOrganisation;
1137
1179
  this.setSelectedEventId = setSelectedEventId;
1180
+ if (previousAppName !== appName) {
1181
+ this.appConfig = null;
1182
+ }
1183
+ if (user?.id) {
1184
+ try {
1185
+ this.isSuperAdmin = await isSuperAdmin(user.id);
1186
+ logger.debug("EventService", "Updated super admin status", {
1187
+ userId: user.id,
1188
+ isSuperAdmin: this.isSuperAdmin
1189
+ });
1190
+ } catch (error) {
1191
+ logger.warn("EventService", "Failed to check super admin status", { error });
1192
+ this.isSuperAdmin = false;
1193
+ }
1194
+ } else {
1195
+ this.isSuperAdmin = false;
1196
+ }
1138
1197
  if (previousOrgId !== newOrgId) {
1139
1198
  this.resetInitialization();
1140
1199
  this.isInitializedRef = false;
@@ -1165,18 +1224,6 @@ var EventService = class extends BaseService {
1165
1224
  // Event methods
1166
1225
  setSelectedEvent(event) {
1167
1226
  if (event) {
1168
- try {
1169
- if (this.selectedOrganisation && event.organisation_id !== this.selectedOrganisation.id) {
1170
- logger.error("EventService", "Event organisation_id does not match selected organisation", {
1171
- eventOrganisationId: event.organisation_id,
1172
- selectedOrganisationId: this.selectedOrganisation.id,
1173
- eventName: event.event_name
1174
- });
1175
- return;
1176
- }
1177
- } catch (error) {
1178
- logger.error("EventService", "Error during event validation:", error);
1179
- }
1180
1227
  this.selectedEvent = event;
1181
1228
  this.setSelectedEventId?.(event.event_id);
1182
1229
  this.persistEventSelection(event.event_id).catch((error) => {
@@ -1273,16 +1320,31 @@ var EventService = class extends BaseService {
1273
1320
  }
1274
1321
  // Lifecycle methods
1275
1322
  async initialize() {
1323
+ logger.debug("EventService", "initialize() called", {
1324
+ isInitializedRef: this.isInitializedRef,
1325
+ hasUser: !!this.user,
1326
+ hasSession: !!this.session,
1327
+ appName: this.appName
1328
+ });
1276
1329
  await super.initialize();
1277
1330
  }
1278
1331
  cleanup() {
1279
1332
  super.cleanup();
1280
1333
  }
1281
1334
  async doInitialize() {
1335
+ logger.debug("EventService", "doInitialize() called", {
1336
+ isInitializedRef: this.isInitializedRef,
1337
+ isFetchingRef: this.isFetchingRef,
1338
+ hasUser: !!this.user,
1339
+ hasSession: !!this.session,
1340
+ appName: this.appName
1341
+ });
1282
1342
  if (this.isInitializedRef) {
1343
+ logger.debug("EventService", "Skipping initialization - already initialized");
1283
1344
  return;
1284
1345
  }
1285
1346
  if (this.isFetchingRef) {
1347
+ logger.debug("EventService", "Skipping initialization - already fetching");
1286
1348
  return;
1287
1349
  }
1288
1350
  try {
@@ -1292,31 +1354,107 @@ var EventService = class extends BaseService {
1292
1354
  } catch (error) {
1293
1355
  logger.warn("EventService", "Failed to clean up old storage keys:", error);
1294
1356
  }
1295
- if (!this.user || !this.selectedOrganisation) {
1357
+ if (!this.user) {
1358
+ logger.debug("EventService", "Skipping initialization - missing user");
1296
1359
  return;
1297
1360
  }
1361
+ logger.debug("EventService", "Initializing - fetching events", {
1362
+ userId: this.user.id,
1363
+ organisationId: this.selectedOrganisation?.id || "derived-from-event",
1364
+ appName: this.appName
1365
+ });
1298
1366
  await this.fetchEvents(false);
1367
+ this.isInitializedRef = true;
1299
1368
  }
1300
1369
  doCleanup() {
1301
1370
  }
1302
1371
  async fetchEvents(skipLoadPersisted = false) {
1303
- if (!this.user || !this.session || !this.supabaseClient || !this.appName || !this.selectedOrganisation) {
1372
+ if (!this.user || !this.session || !this.supabaseClient || !this.appName) {
1373
+ logger.debug("EventService", "Skipping fetchEvents - missing dependencies", {
1374
+ hasUser: !!this.user,
1375
+ hasSession: !!this.session,
1376
+ hasSupabaseClient: !!this.supabaseClient,
1377
+ appName: this.appName
1378
+ });
1304
1379
  this.notify();
1305
1380
  return;
1306
1381
  }
1307
1382
  this._isLoading = true;
1308
1383
  this.notify();
1309
1384
  if (this.isFetchingRef) {
1385
+ logger.debug("EventService", "Skipping fetchEvents - already fetching");
1310
1386
  return;
1311
1387
  }
1312
1388
  this.isFetchingRef = true;
1313
1389
  let isMounted = true;
1314
1390
  try {
1315
- const { data, error: rpcError } = await this.supabaseClient.rpc("data_user_events_get", {
1391
+ if (!this.appConfig && this.appName) {
1392
+ try {
1393
+ this.appConfig = await getAppConfigByName(this.appName);
1394
+ } catch (configError) {
1395
+ logger.warn("EventService", "Failed to load app config, defaulting to event-required", {
1396
+ error: configError
1397
+ });
1398
+ this.appConfig = { requires_event: true };
1399
+ }
1400
+ }
1401
+ let organisationIdForRpc = null;
1402
+ let userIsSuperAdmin = false;
1403
+ try {
1404
+ userIsSuperAdmin = await isSuperAdmin(this.user.id);
1405
+ if (userIsSuperAdmin) {
1406
+ organisationIdForRpc = null;
1407
+ logger.debug("EventService", "Super admin detected - fetching all events", {
1408
+ userId: this.user.id
1409
+ });
1410
+ } else {
1411
+ if (this.selectedEvent) {
1412
+ organisationIdForRpc = this.selectedEvent.organisation_id;
1413
+ } else if (this.appConfig?.requires_event === true) {
1414
+ organisationIdForRpc = null;
1415
+ logger.debug("EventService", "Event-required app: fetching all accessible events (no event selected yet)", {
1416
+ userId: this.user.id,
1417
+ appName: this.appName
1418
+ });
1419
+ } else if (this.selectedOrganisation) {
1420
+ organisationIdForRpc = this.selectedOrganisation.id;
1421
+ } else {
1422
+ logger.warn("EventService", "No organisation context available for event fetch", {
1423
+ hasSelectedEvent: !!this.selectedEvent,
1424
+ hasSelectedOrganisation: !!this.selectedOrganisation,
1425
+ appRequiresEvent: this.appConfig?.requires_event
1426
+ });
1427
+ organisationIdForRpc = null;
1428
+ }
1429
+ }
1430
+ } catch (superAdminCheckError) {
1431
+ logger.warn("EventService", "Failed to check super admin status, using organisation-scoped query", {
1432
+ error: superAdminCheckError
1433
+ });
1434
+ if (this.selectedEvent) {
1435
+ organisationIdForRpc = this.selectedEvent.organisation_id;
1436
+ } else if (this.appConfig?.requires_event === true) {
1437
+ organisationIdForRpc = null;
1438
+ } else if (this.selectedOrganisation) {
1439
+ organisationIdForRpc = this.selectedOrganisation.id;
1440
+ }
1441
+ }
1442
+ logger.debug("EventService", "Fetching events via RPC", {
1443
+ userId: this.user.id,
1444
+ organisationId: organisationIdForRpc,
1445
+ appName: this.appName
1446
+ });
1447
+ let { data, error: rpcError } = await this.supabaseClient.rpc("data_user_events_get", {
1316
1448
  p_user_id: this.user.id,
1317
- p_organisation_id: this.selectedOrganisation.id,
1449
+ p_organisation_id: organisationIdForRpc,
1318
1450
  p_app_name: this.appName
1319
1451
  });
1452
+ logger.debug("EventService", "RPC response received", {
1453
+ hasData: !!data,
1454
+ dataLength: Array.isArray(data) ? data.length : "not array",
1455
+ hasError: !!rpcError,
1456
+ error: rpcError
1457
+ });
1320
1458
  if (rpcError) {
1321
1459
  logger.error("EventService", "RPC error fetching events:", rpcError);
1322
1460
  throw new Error(rpcError.message || "Failed to fetch events");
@@ -1428,24 +1566,41 @@ function EventServiceProvider({
1428
1566
  setSelectedEventId
1429
1567
  }) {
1430
1568
  const eventServiceRef = useRef2(null);
1569
+ const initializingRef = useRef2(false);
1431
1570
  if (!eventServiceRef.current) {
1432
1571
  eventServiceRef.current = new EventService(supabaseClient, user, session, appName, selectedOrganisation, setSelectedEventId);
1433
1572
  }
1434
1573
  const eventService = eventServiceRef.current;
1435
1574
  useEffect3(() => {
1436
1575
  let isMounted = true;
1576
+ if (initializingRef.current) {
1577
+ return;
1578
+ }
1437
1579
  const updateAndInitialize = async () => {
1438
- await eventService.updateDependencies(supabaseClient, user, session, appName, selectedOrganisation, setSelectedEventId);
1439
- if (!isMounted) return;
1440
- await eventService.initialize().catch((error) => {
1441
- if (isMounted) {
1442
- logger.error("EventServiceProvider", "Failed to initialize event service:", error);
1443
- }
1444
- });
1580
+ initializingRef.current = true;
1581
+ try {
1582
+ logger.debug("EventServiceProvider", "Updating dependencies and initializing", {
1583
+ hasUser: !!user,
1584
+ hasSession: !!session,
1585
+ appName,
1586
+ hasSelectedOrganisation: !!selectedOrganisation,
1587
+ organisationId: selectedOrganisation?.id
1588
+ });
1589
+ await eventService.updateDependencies(supabaseClient, user, session, appName, selectedOrganisation, setSelectedEventId);
1590
+ if (!isMounted) return;
1591
+ await eventService.initialize().catch((error) => {
1592
+ if (isMounted) {
1593
+ logger.error("EventServiceProvider", "Failed to initialize event service:", error);
1594
+ }
1595
+ });
1596
+ } finally {
1597
+ initializingRef.current = false;
1598
+ }
1445
1599
  };
1446
1600
  updateAndInitialize();
1447
1601
  return () => {
1448
1602
  isMounted = false;
1603
+ initializingRef.current = false;
1449
1604
  };
1450
1605
  }, [supabaseClient, user, session, appName, selectedOrganisation, setSelectedEventId]);
1451
1606
  useEffect3(() => {
@@ -1750,8 +1905,10 @@ function InactivityServiceProvider({
1750
1905
  supabaseClient,
1751
1906
  user,
1752
1907
  session,
1753
- idleTimeoutMs = 30 * 60 * 1e3,
1754
- warnBeforeMs = 60 * 1e3,
1908
+ idleTimeoutMs,
1909
+ // REQUIRED: No default - must be explicitly provided
1910
+ warnBeforeMs,
1911
+ // REQUIRED: No default - must be explicitly provided
1755
1912
  onIdleLogout
1756
1913
  }) {
1757
1914
  const inactivityServiceRef = useRef3(null);
@@ -1810,6 +1967,29 @@ function useOrganisationService() {
1810
1967
  return context.organisationService;
1811
1968
  }
1812
1969
 
1970
+ // src/hooks/useOrganisations.ts
1971
+ function useOrganisations() {
1972
+ const organisationService = useOrganisationService();
1973
+ const selectedOrg = organisationService.getSelectedOrganisation();
1974
+ return {
1975
+ selectedOrganisation: selectedOrg,
1976
+ organisations: organisationService.getOrganisations(),
1977
+ userMemberships: organisationService.getUserMemberships(),
1978
+ isLoading: organisationService.isLoading(),
1979
+ error: organisationService.getError(),
1980
+ hasValidOrganisationContext: organisationService.hasValidOrganisationContext(),
1981
+ isContextReady: organisationService.isContextReady(),
1982
+ setSelectedOrganisation: (org) => organisationService.setSelectedOrganisation(org),
1983
+ switchOrganisation: (orgId) => organisationService.switchOrganisation(orgId),
1984
+ getUserRole: (orgId) => organisationService.getUserRole(orgId),
1985
+ validateOrganisationAccess: (orgId) => organisationService.validateOrganisationAccess(orgId),
1986
+ refreshOrganisations: () => organisationService.refreshOrganisations(),
1987
+ ensureOrganisationContext: () => organisationService.ensureOrganisationContext(),
1988
+ isOrganisationSecure: () => organisationService.isOrganisationSecure(),
1989
+ getPrimaryOrganisation: () => organisationService.getPrimaryOrganisation()
1990
+ };
1991
+ }
1992
+
1813
1993
  // src/hooks/services/useEventService.ts
1814
1994
  import { useContext as useContext3, useReducer as useReducer3, useEffect as useEffect7 } from "react";
1815
1995
  function useEventService() {
@@ -1893,6 +2073,7 @@ function UnifiedAuthContextProvider({
1893
2073
  appName,
1894
2074
  appConfig = { requires_event: true },
1895
2075
  // Default to requiring events
2076
+ supabaseClient: supabaseClientProp,
1896
2077
  ...props
1897
2078
  }) {
1898
2079
  const authService = useAuthService();
@@ -1932,15 +2113,31 @@ function UnifiedAuthContextProvider({
1932
2113
  const currentUser = authService.getUser();
1933
2114
  const currentSession = authService.getSession();
1934
2115
  const isAuth = !!(currentUser && currentSession);
1935
- const supabase = authService.getSupabaseClient();
2116
+ const supabase = useMemo6(() => supabaseClientProp, [supabaseClientProp]);
1936
2117
  const [appId, setAppId] = useState3(void 0);
1937
2118
  const isResolvingAppIdRef = useRef4(false);
2119
+ const resolvedAppIdRef = useRef4(void 0);
2120
+ const resolvedUserIdRef = useRef4(void 0);
1938
2121
  useEffect10(() => {
1939
- if (isAuth && currentUser?.id && supabase && appName && !appId && !isResolvingAppIdRef.current) {
2122
+ if (!isAuth) {
2123
+ resolvedAppIdRef.current = void 0;
2124
+ resolvedUserIdRef.current = void 0;
2125
+ setAppId(void 0);
2126
+ return;
2127
+ }
2128
+ if (currentUser?.id && resolvedUserIdRef.current && resolvedUserIdRef.current !== currentUser.id) {
2129
+ resolvedAppIdRef.current = void 0;
2130
+ resolvedUserIdRef.current = void 0;
2131
+ setAppId(void 0);
2132
+ }
2133
+ const currentUserId = currentUser?.id;
2134
+ if (isAuth && currentUserId && supabase && appName && resolvedUserIdRef.current !== currentUserId && // Haven't resolved for this user yet
2135
+ !isResolvingAppIdRef.current) {
1940
2136
  isResolvingAppIdRef.current = true;
1941
- const userId = currentUser.id;
2137
+ resolvedUserIdRef.current = currentUserId;
2138
+ const userId = currentUserId;
1942
2139
  const appNameValue = appName;
1943
- import("./api-YP7XD5L6.js").then(async ({ resolveAppContext, setupRBAC }) => {
2140
+ import("./api-I6UCQ5S6.js").then(async ({ resolveAppContext, setupRBAC }) => {
1944
2141
  try {
1945
2142
  setupRBAC(supabase);
1946
2143
  const result = await resolveAppContext({
@@ -1948,11 +2145,14 @@ function UnifiedAuthContextProvider({
1948
2145
  appName: appNameValue
1949
2146
  });
1950
2147
  if (result?.appId) {
2148
+ resolvedAppIdRef.current = result.appId;
1951
2149
  setAppId(result.appId);
1952
2150
  logger.debug("UnifiedAuthProvider", "appId resolved on login", {
1953
2151
  appId: result.appId,
1954
2152
  appName: appNameValue
1955
2153
  });
2154
+ } else {
2155
+ resolvedUserIdRef.current = void 0;
1956
2156
  }
1957
2157
  } catch (error) {
1958
2158
  logger.error("UnifiedAuthProvider", "Failed to resolve appId on login", {
@@ -1960,41 +2160,64 @@ function UnifiedAuthContextProvider({
1960
2160
  appName: appNameValue,
1961
2161
  userId
1962
2162
  });
2163
+ resolvedUserIdRef.current = void 0;
1963
2164
  } finally {
1964
2165
  isResolvingAppIdRef.current = false;
1965
2166
  }
1966
2167
  }).catch((importError) => {
1967
2168
  logger.error("UnifiedAuthProvider", "Failed to import RBAC API", importError);
1968
2169
  isResolvingAppIdRef.current = false;
2170
+ resolvedUserIdRef.current = void 0;
1969
2171
  });
1970
2172
  }
1971
- if (!isAuth) {
1972
- setAppId(void 0);
1973
- }
1974
- }, [isAuth, currentUser?.id, supabase, appName, appId]);
2173
+ }, [isAuth, currentUser?.id, supabase, appName]);
1975
2174
  const [, forceUpdate] = useReducer5((x) => x + 1, 0);
2175
+ const forceUpdateTimeoutRef = useRef4(null);
2176
+ const debouncedForceUpdate = useCallback(() => {
2177
+ if (forceUpdateTimeoutRef.current) {
2178
+ clearTimeout(forceUpdateTimeoutRef.current);
2179
+ }
2180
+ forceUpdateTimeoutRef.current = setTimeout(() => {
2181
+ forceUpdate();
2182
+ forceUpdateTimeoutRef.current = null;
2183
+ }, 0);
2184
+ }, [forceUpdate]);
2185
+ const authServiceRef = useRef4(authService);
2186
+ const organisationServiceRef = useRef4(organisationService);
2187
+ const eventServiceRef = useRef4(eventService);
2188
+ const inactivityServiceRef = useRef4(inactivityService);
2189
+ useEffect10(() => {
2190
+ authServiceRef.current = authService;
2191
+ organisationServiceRef.current = organisationService;
2192
+ eventServiceRef.current = eventService;
2193
+ inactivityServiceRef.current = inactivityService;
2194
+ }, [authService, organisationService, eventService, inactivityService]);
1976
2195
  useEffect10(() => {
1977
- const unsubscribeAuth = authService.subscribe(() => forceUpdate());
1978
- const unsubscribeOrg = organisationService.subscribe(() => forceUpdate());
1979
- const unsubscribeEvent = eventService.subscribe(() => forceUpdate());
1980
- const unsubscribeInactivity = inactivityService.subscribe(() => forceUpdate());
2196
+ const unsubscribeAuth = authServiceRef.current.subscribe(debouncedForceUpdate);
2197
+ const unsubscribeOrg = organisationServiceRef.current.subscribe(debouncedForceUpdate);
2198
+ const unsubscribeEvent = eventServiceRef.current.subscribe(debouncedForceUpdate);
2199
+ const unsubscribeInactivity = inactivityServiceRef.current.subscribe(debouncedForceUpdate);
1981
2200
  return () => {
1982
2201
  unsubscribeAuth();
1983
2202
  unsubscribeOrg();
1984
2203
  unsubscribeEvent();
1985
2204
  unsubscribeInactivity();
2205
+ if (forceUpdateTimeoutRef.current) {
2206
+ clearTimeout(forceUpdateTimeoutRef.current);
2207
+ }
1986
2208
  };
1987
- }, [authService, organisationService, eventService, inactivityService]);
2209
+ }, [debouncedForceUpdate]);
1988
2210
  const authLoading = authService.isLoading();
1989
2211
  const orgLoading = organisationService.isLoading();
1990
2212
  const eventLoading = eventService.isLoading();
1991
2213
  const restorationLoading = sessionRestoration.isRestoring && !sessionRestorationTimedOut && !sessionRestoration.restorationError;
1992
2214
  const totalLoading = restorationLoading || authLoading || orgLoading || eventLoading;
1993
2215
  const authError = authService.getError();
1994
- const selectedOrganisation = organisationService.getSelectedOrganisation();
2216
+ const rawSelectedOrganisation = organisationService.getSelectedOrganisation();
1995
2217
  const organisations = organisationService.getOrganisations();
1996
2218
  const userMemberships = organisationService.getUserMemberships();
1997
2219
  const organisationError = organisationService.getError();
2220
+ const selectedOrganisation = appConfig?.requires_event ? null : rawSelectedOrganisation;
1998
2221
  const hasValidOrganisationContext = organisationService.hasValidOrganisationContext();
1999
2222
  const isContextReady = organisationService.isContextReady();
2000
2223
  const events = eventService.getEvents();
@@ -2170,10 +2393,13 @@ function EventServiceProviderWrapper({
2170
2393
  supabaseClient,
2171
2394
  user,
2172
2395
  session,
2173
- appName
2396
+ appName,
2397
+ appConfig
2174
2398
  }) {
2175
- const organisationService = useOrganisationService();
2176
- const selectedOrganisation = organisationService.getSelectedOrganisation();
2399
+ const { selectedOrganisation: rawSelectedOrganisation } = useOrganisations();
2400
+ const selectedOrganisation = appConfig?.requires_event ? null : rawSelectedOrganisation;
2401
+ const setSelectedEventId = useCallback(() => {
2402
+ }, []);
2177
2403
  return /* @__PURE__ */ jsx5(
2178
2404
  EventServiceProvider,
2179
2405
  {
@@ -2182,8 +2408,7 @@ function EventServiceProviderWrapper({
2182
2408
  session,
2183
2409
  appName,
2184
2410
  selectedOrganisation,
2185
- setSelectedEventId: () => {
2186
- },
2411
+ setSelectedEventId,
2187
2412
  children
2188
2413
  }
2189
2414
  );
@@ -2216,6 +2441,7 @@ function ServiceAwareProviders({
2216
2441
  user: authService.getUser(),
2217
2442
  session: authService.getSession(),
2218
2443
  appName,
2444
+ appConfig,
2219
2445
  children: /* @__PURE__ */ jsx5(
2220
2446
  InactivityServiceProvider,
2221
2447
  {
@@ -2258,11 +2484,12 @@ function UnifiedAuthProvider({
2258
2484
  persistState = true,
2259
2485
  enablePersistence,
2260
2486
  requireOrganisationContext = true,
2261
- idleTimeoutMs = 30 * 60 * 1e3,
2262
- // 30 minutes
2263
- warnBeforeMs = 60 * 1e3,
2264
- // 60 seconds
2487
+ idleTimeoutMs,
2488
+ // REQUIRED: No default - must be explicitly provided
2489
+ warnBeforeMs,
2490
+ // REQUIRED: No default - must be explicitly provided
2265
2491
  onIdleLogout,
2492
+ // REQUIRED: No default - must be explicitly provided
2266
2493
  renderInactivityWarning,
2267
2494
  dangerouslyDisableInactivity = false
2268
2495
  }) {
@@ -2307,6 +2534,7 @@ export {
2307
2534
  InactivityServiceProvider,
2308
2535
  useAuthService,
2309
2536
  useOrganisationService,
2537
+ useOrganisations,
2310
2538
  useEventService,
2311
2539
  useInactivityService,
2312
2540
  useSessionRestoration,
@@ -2314,4 +2542,4 @@ export {
2314
2542
  useUnifiedAuth,
2315
2543
  UnifiedAuthProvider
2316
2544
  };
2317
- //# sourceMappingURL=chunk-VGZZXKBR.js.map
2545
+ //# sourceMappingURL=chunk-J2XXC7R5.js.map