@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
@@ -35,6 +35,15 @@ var OrganisationContextRequiredError = class extends RBACError {
35
35
  this.name = "OrganisationContextRequiredError";
36
36
  }
37
37
  };
38
+ var EventContextRequiredError = class extends RBACError {
39
+ constructor() {
40
+ super(
41
+ "Event context is required for this operation",
42
+ "EVENT_CONTEXT_REQUIRED"
43
+ );
44
+ this.name = "EventContextRequiredError";
45
+ }
46
+ };
38
47
  var RBACNotInitializedError = class extends RBACError {
39
48
  constructor() {
40
49
  super(
@@ -428,19 +437,32 @@ var RBACCacheInvalidationManager = class {
428
437
  log.warn("Failed to log cache invalidation audit event:", error);
429
438
  });
430
439
  }
440
+ /**
441
+ * Cleanup subscriptions only (not all callbacks)
442
+ * Used internally to cleanup before setting up new subscriptions
443
+ */
444
+ cleanupSubscriptions() {
445
+ this.channels.forEach((channel) => {
446
+ try {
447
+ if (channel && typeof channel.unsubscribe === "function") {
448
+ channel.unsubscribe();
449
+ }
450
+ } catch (error) {
451
+ log.warn("Failed to unsubscribe from channel:", error);
452
+ }
453
+ });
454
+ this.channels = [];
455
+ }
431
456
  /**
432
457
  * Setup realtime subscriptions for automatic cache invalidation
433
- * Prevents duplicate subscriptions by checking if already set up
458
+ * Always cleans up existing subscriptions before setting up new ones to prevent duplicates
434
459
  */
435
460
  setupRealtimeSubscriptions() {
461
+ this.cleanupSubscriptions();
436
462
  if (!this.supabase.channel || typeof this.supabase.channel !== "function") {
437
463
  log.debug("Realtime not available, skipping subscriptions");
438
464
  return;
439
465
  }
440
- if (this.channels.length > 0) {
441
- log.debug("Realtime subscriptions already set up, skipping duplicate setup");
442
- return;
443
- }
444
466
  const orgRolesChannel = this.supabase.channel("rbac_organisation_roles_changes").on("postgres_changes", {
445
467
  event: "*",
446
468
  schema: "public",
@@ -672,8 +694,226 @@ function mapErrorCategoryToSecurityEventType(category) {
672
694
  }
673
695
  }
674
696
 
697
+ // src/rbac/utils/eventContext.ts
698
+ var orgDerivationCache = /* @__PURE__ */ new Map();
699
+ var MAX_CACHE_SIZE = 100;
700
+ async function getOrganisationFromEvent(supabase, eventId) {
701
+ if (orgDerivationCache.has(eventId)) {
702
+ return orgDerivationCache.get(eventId) ?? null;
703
+ }
704
+ const { data, error } = await supabase.from("event").select("organisation_id").eq("event_id", eventId).single();
705
+ let organisationId = null;
706
+ if (error || !data) {
707
+ organisationId = null;
708
+ } else {
709
+ organisationId = data.organisation_id;
710
+ }
711
+ if (orgDerivationCache.size >= MAX_CACHE_SIZE) {
712
+ const firstKey = orgDerivationCache.keys().next().value;
713
+ if (firstKey) {
714
+ orgDerivationCache.delete(firstKey);
715
+ }
716
+ }
717
+ orgDerivationCache.set(eventId, organisationId);
718
+ return organisationId;
719
+ }
720
+
721
+ // src/rbac/utils/contextValidator.ts
722
+ var log2 = createLogger("ContextValidator");
723
+ function allowsOptionalContexts(appName) {
724
+ return appName === "PORTAL" || appName === "ADMIN";
725
+ }
726
+ var ContextValidator = class {
727
+ /**
728
+ * Validate scope against app requirements
729
+ *
730
+ * @param scope - Current scope
731
+ * @param appConfig - App configuration (requires_event flag)
732
+ * @param appName - App name (for PORTAL/ADMIN special case)
733
+ * @returns Validation result with resolved scope
734
+ */
735
+ static async validateScope(scope, appConfig, appName) {
736
+ if (allowsOptionalContexts(appName)) {
737
+ return {
738
+ isValid: true,
739
+ resolvedScope: {
740
+ organisationId: scope.organisationId,
741
+ eventId: scope.eventId,
742
+ appId: scope.appId
743
+ },
744
+ error: null
745
+ };
746
+ }
747
+ if (!appConfig) {
748
+ if (!scope.organisationId) {
749
+ return {
750
+ isValid: false,
751
+ resolvedScope: null,
752
+ error: new OrganisationContextRequiredError()
753
+ };
754
+ }
755
+ return {
756
+ isValid: true,
757
+ resolvedScope: scope,
758
+ error: null
759
+ };
760
+ }
761
+ if (appConfig.requires_event) {
762
+ if (!scope.eventId) {
763
+ return {
764
+ isValid: false,
765
+ resolvedScope: null,
766
+ error: new EventContextRequiredError()
767
+ };
768
+ }
769
+ return {
770
+ isValid: true,
771
+ resolvedScope: scope,
772
+ error: null
773
+ };
774
+ }
775
+ if (!scope.organisationId) {
776
+ return {
777
+ isValid: false,
778
+ resolvedScope: null,
779
+ error: new OrganisationContextRequiredError()
780
+ };
781
+ }
782
+ return {
783
+ isValid: true,
784
+ resolvedScope: scope,
785
+ error: null
786
+ };
787
+ }
788
+ /**
789
+ * Resolve required context and derive missing values
790
+ *
791
+ * @param scope - Current scope
792
+ * @param appConfig - App configuration
793
+ * @param appName - App name (for PORTAL/ADMIN special case)
794
+ * @param supabase - Supabase client (for deriving org from event)
795
+ * @returns Resolved scope with all required context
796
+ */
797
+ static async resolveRequiredContext(scope, appConfig, appName, supabase) {
798
+ if (allowsOptionalContexts(appName)) {
799
+ return {
800
+ isValid: true,
801
+ resolvedScope: {
802
+ organisationId: scope.organisationId,
803
+ eventId: scope.eventId,
804
+ appId: scope.appId
805
+ },
806
+ error: null
807
+ };
808
+ }
809
+ if (!appConfig) {
810
+ if (!scope.organisationId) {
811
+ return {
812
+ isValid: false,
813
+ resolvedScope: null,
814
+ error: new OrganisationContextRequiredError()
815
+ };
816
+ }
817
+ return {
818
+ isValid: true,
819
+ resolvedScope: scope,
820
+ error: null
821
+ };
822
+ }
823
+ if (appConfig.requires_event) {
824
+ if (!scope.eventId) {
825
+ return {
826
+ isValid: false,
827
+ resolvedScope: null,
828
+ error: new EventContextRequiredError()
829
+ };
830
+ }
831
+ let organisationId = scope.organisationId;
832
+ if (!organisationId && supabase && scope.eventId) {
833
+ try {
834
+ const derivedOrgId = await this.deriveOrgFromEvent(supabase, scope.eventId);
835
+ organisationId = derivedOrgId || void 0;
836
+ if (!organisationId) {
837
+ return {
838
+ isValid: false,
839
+ resolvedScope: null,
840
+ error: new Error("Could not resolve organisation from event context")
841
+ };
842
+ }
843
+ } catch (error) {
844
+ log2.error("Failed to derive org from event:", error);
845
+ return {
846
+ isValid: false,
847
+ resolvedScope: null,
848
+ error: error instanceof Error ? error : new Error("Failed to derive organisation from event")
849
+ };
850
+ }
851
+ } else if (!organisationId) {
852
+ return {
853
+ isValid: false,
854
+ resolvedScope: null,
855
+ error: new Error("Event context requires organisationId but it could not be derived (supabase client not available)")
856
+ };
857
+ }
858
+ return {
859
+ isValid: true,
860
+ resolvedScope: {
861
+ organisationId,
862
+ eventId: scope.eventId,
863
+ appId: scope.appId
864
+ },
865
+ error: null
866
+ };
867
+ }
868
+ if (!scope.organisationId) {
869
+ return {
870
+ isValid: false,
871
+ resolvedScope: null,
872
+ error: new OrganisationContextRequiredError()
873
+ };
874
+ }
875
+ return {
876
+ isValid: true,
877
+ resolvedScope: scope,
878
+ error: null
879
+ };
880
+ }
881
+ /**
882
+ * Derive organisation ID from event ID
883
+ *
884
+ * @param supabase - Supabase client
885
+ * @param eventId - Event ID
886
+ * @returns Organisation ID or null
887
+ */
888
+ static async deriveOrgFromEvent(supabase, eventId) {
889
+ return getOrganisationFromEvent(supabase, eventId);
890
+ }
891
+ /**
892
+ * Check if context is ready for permission checks
893
+ *
894
+ * @param scope - Current scope
895
+ * @param appConfig - App configuration
896
+ * @param appName - App name
897
+ * @param hasSelectedEvent - Whether event is selected
898
+ * @param hasSelectedOrganisation - Whether organisation is selected
899
+ * @returns True if context is ready
900
+ */
901
+ static isContextReady(scope, appConfig, appName, hasSelectedEvent, hasSelectedOrganisation) {
902
+ if (allowsOptionalContexts(appName)) {
903
+ return true;
904
+ }
905
+ if (!appConfig) {
906
+ return !!hasSelectedOrganisation || !!scope.organisationId;
907
+ }
908
+ if (appConfig.requires_event) {
909
+ return !!hasSelectedEvent || !!scope.eventId;
910
+ }
911
+ return !!hasSelectedOrganisation || !!scope.organisationId;
912
+ }
913
+ };
914
+
675
915
  // src/rbac/security.ts
676
- var log2 = createLogger("RBACSecurity");
916
+ var log3 = createLogger("RBACSecurity");
677
917
  var RBACSecurityValidator = class {
678
918
  /**
679
919
  * Validate permission string format
@@ -782,19 +1022,13 @@ var RBACSecurityValidator = class {
782
1022
  /**
783
1023
  * Validate context requirements for security
784
1024
  * @param scope - Scope object
785
- * @param appId - Application ID
1025
+ * @param appConfig - App configuration
1026
+ * @param appName - App name (for PORTAL special case)
786
1027
  * @returns True if context is valid, false otherwise
787
1028
  */
788
- static validateContextRequirements(scope, appId) {
789
- if (!scope.organisationId) {
790
- return false;
791
- }
792
- if (appId && scope.appId === appId) {
793
- if (!scope.eventId) {
794
- return false;
795
- }
796
- }
797
- return true;
1029
+ static async validateContextRequirements(scope, appConfig, appName) {
1030
+ const validation = await ContextValidator.validateScope(scope, appConfig || null, appName);
1031
+ return validation.isValid;
798
1032
  }
799
1033
  // Only warn once per 5 seconds per user
800
1034
  static logSecurityEvent(event) {
@@ -813,7 +1047,7 @@ var RBACSecurityValidator = class {
813
1047
  this.rateLimitWarningCount.set(event.userId, userWarning);
814
1048
  return;
815
1049
  } else {
816
- log2.warn("Security event (throttled):", {
1050
+ log3.warn("Security event (throttled):", {
817
1051
  ...securityEvent,
818
1052
  details: {
819
1053
  ...securityEvent.details,
@@ -826,11 +1060,11 @@ var RBACSecurityValidator = class {
826
1060
  }
827
1061
  } else {
828
1062
  this.rateLimitWarningCount.set(event.userId, { count: 0, lastWarning: now });
829
- log2.warn("Security event:", securityEvent);
1063
+ log3.warn("Security event:", securityEvent);
830
1064
  return;
831
1065
  }
832
1066
  }
833
- log2.warn("Security event:", securityEvent);
1067
+ log3.warn("Security event:", securityEvent);
834
1068
  }
835
1069
  /**
836
1070
  * Get severity level for security event
@@ -902,10 +1136,18 @@ var RBACSecurityMiddleware = class {
902
1136
  if (!RBACSecurityValidator.validateUserId(context.userId)) {
903
1137
  errors.push("Invalid user ID format");
904
1138
  }
905
- if (!context.organisationId) {
906
- errors.push("Organisation ID is required");
907
- } else if (!RBACSecurityValidator.validateUUID(context.organisationId)) {
908
- errors.push("Invalid organisation ID format");
1139
+ const isPagePermission = input.permission?.includes(":page.") || !!input.pageId;
1140
+ const requiresOrgId = !isPagePermission;
1141
+ if (requiresOrgId) {
1142
+ if (!context.organisationId) {
1143
+ errors.push("Organisation ID is required for resource-level permissions");
1144
+ } else if (!RBACSecurityValidator.validateUUID(context.organisationId)) {
1145
+ errors.push("Invalid organisation ID format");
1146
+ }
1147
+ } else {
1148
+ if (context.organisationId && !RBACSecurityValidator.validateUUID(context.organisationId)) {
1149
+ errors.push("Invalid organisation ID format");
1150
+ }
909
1151
  }
910
1152
  if (input.permission && !RBACSecurityValidator.validatePermission(input.permission)) {
911
1153
  errors.push("Invalid permission format");
@@ -1252,7 +1494,8 @@ var RBACEngine = class {
1252
1494
  return "super";
1253
1495
  }
1254
1496
  if (scope.organisationId) {
1255
- const { data: orgRole } = await this.supabase.from("rbac_organisation_roles").select("role").eq("user_id", userId).eq("organisation_id", scope.organisationId).eq("status", "active").is("revoked_at", null).lte("valid_from", now).or(`valid_to.is.null,valid_to.gte.${now}`).single();
1497
+ const { data: orgRoles } = await this.supabase.from("rbac_organisation_roles").select("role").eq("user_id", userId).eq("organisation_id", scope.organisationId).eq("status", "active").is("revoked_at", null).lte("valid_from", now).or(`valid_to.is.null,valid_to.gte.${now}`).limit(1);
1498
+ const orgRole = orgRoles?.[0];
1256
1499
  if (orgRole?.role === "org_admin") {
1257
1500
  rbacCache.set(cacheKey, "admin", 6e4);
1258
1501
  return "admin";
@@ -1598,6 +1841,7 @@ function generateDeduplicationKey(input) {
1598
1841
  return RBACCache.generatePermissionKey({
1599
1842
  userId: input.userId,
1600
1843
  organisationId: input.scope.organisationId,
1844
+ // Can be undefined for page-level permissions
1601
1845
  eventId: input.scope.eventId,
1602
1846
  appId: input.scope.appId,
1603
1847
  permission: input.permission,
@@ -1624,7 +1868,7 @@ function getInFlightRequestCount() {
1624
1868
  }
1625
1869
 
1626
1870
  // src/rbac/api.ts
1627
- var log3 = createLogger("RBACAPI");
1871
+ var log4 = createLogger("RBACAPI");
1628
1872
  var globalEngine = null;
1629
1873
  function setupRBAC(supabase, config) {
1630
1874
  const logger = getRBACLogger();
@@ -1662,37 +1906,116 @@ function getEngine() {
1662
1906
  }
1663
1907
  return globalEngine;
1664
1908
  }
1665
- async function getAccessLevel(input) {
1909
+ async function getAccessLevel(input, appConfig, appName) {
1666
1910
  const engine = getEngine();
1667
- return engine.getAccessLevel(input);
1911
+ const isSuperAdminUser = await engine["checkSuperAdmin"](input.userId);
1912
+ if (isSuperAdminUser) {
1913
+ return "super";
1914
+ }
1915
+ let resolvedAppConfig = appConfig ?? null;
1916
+ let resolvedAppName = appName;
1917
+ if (!resolvedAppConfig && input.scope.appId) {
1918
+ resolvedAppConfig = await getAppConfig(input.scope.appId);
1919
+ }
1920
+ const validation = await ContextValidator.resolveRequiredContext(
1921
+ input.scope,
1922
+ resolvedAppConfig,
1923
+ resolvedAppName,
1924
+ engine["supabase"]
1925
+ );
1926
+ if (!validation.isValid || !validation.resolvedScope) {
1927
+ throw validation.error || new OrganisationContextRequiredError();
1928
+ }
1929
+ return engine.getAccessLevel({
1930
+ ...input,
1931
+ scope: validation.resolvedScope
1932
+ });
1668
1933
  }
1669
- async function getPermissionMap(input) {
1934
+ async function getPermissionMap(input, appConfig, appName) {
1670
1935
  const engine = getEngine();
1671
- return engine.getPermissionMap(input);
1936
+ let resolvedAppConfig = appConfig ?? null;
1937
+ let resolvedAppName = appName;
1938
+ if (!resolvedAppConfig && input.scope.appId) {
1939
+ resolvedAppConfig = await getAppConfig(input.scope.appId);
1940
+ }
1941
+ const validation = await ContextValidator.resolveRequiredContext(
1942
+ input.scope,
1943
+ resolvedAppConfig,
1944
+ resolvedAppName,
1945
+ engine["supabase"]
1946
+ );
1947
+ if (!validation.isValid || !validation.resolvedScope) {
1948
+ throw validation.error || new OrganisationContextRequiredError();
1949
+ }
1950
+ return engine.getPermissionMap({
1951
+ ...input,
1952
+ scope: validation.resolvedScope
1953
+ });
1672
1954
  }
1673
1955
  async function resolveAppContext(input) {
1674
1956
  const engine = getEngine();
1675
1957
  return engine.resolveAppContext(input);
1676
1958
  }
1677
- async function getRoleContext(input) {
1959
+ async function getRoleContext(input, appConfig, appName) {
1678
1960
  const engine = getEngine();
1679
- return engine.getRoleContext(input);
1961
+ let resolvedAppConfig = appConfig ?? null;
1962
+ let resolvedAppName = appName;
1963
+ if (!resolvedAppConfig && input.scope.appId) {
1964
+ resolvedAppConfig = await getAppConfig(input.scope.appId);
1965
+ }
1966
+ const validation = await ContextValidator.resolveRequiredContext(
1967
+ input.scope,
1968
+ resolvedAppConfig,
1969
+ resolvedAppName,
1970
+ engine["supabase"]
1971
+ );
1972
+ if (!validation.isValid || !validation.resolvedScope) {
1973
+ throw validation.error || new OrganisationContextRequiredError();
1974
+ }
1975
+ return engine.getRoleContext({
1976
+ ...input,
1977
+ scope: validation.resolvedScope
1978
+ });
1680
1979
  }
1681
- async function isPermitted(input) {
1980
+ async function isPermitted(input, appConfig, appName) {
1682
1981
  const engine = getEngine();
1683
- if (!input.scope.organisationId) {
1684
- throw new OrganisationContextRequiredError();
1982
+ let resolvedAppConfig = appConfig ?? null;
1983
+ let resolvedAppName = appName;
1984
+ if (!resolvedAppConfig && input.scope.appId) {
1985
+ resolvedAppConfig = await getAppConfig(input.scope.appId);
1685
1986
  }
1987
+ if (!resolvedAppName && input.scope.appId) {
1988
+ try {
1989
+ const { data } = await engine["supabase"].from("rbac_apps").select("name").eq("id", input.scope.appId).eq("is_active", true).single();
1990
+ if (data) {
1991
+ resolvedAppName = data.name;
1992
+ }
1993
+ } catch (err) {
1994
+ }
1995
+ }
1996
+ const validation = await ContextValidator.resolveRequiredContext(
1997
+ input.scope,
1998
+ resolvedAppConfig,
1999
+ resolvedAppName,
2000
+ engine["supabase"]
2001
+ );
2002
+ if (!validation.isValid || !validation.resolvedScope) {
2003
+ throw validation.error || new OrganisationContextRequiredError();
2004
+ }
2005
+ const validatedScope = validation.resolvedScope;
1686
2006
  const securityContext = {
1687
2007
  userId: input.userId,
1688
- organisationId: input.scope.organisationId,
1689
- // Required - no fallback
2008
+ organisationId: validatedScope.organisationId || null,
1690
2009
  timestamp: /* @__PURE__ */ new Date()
1691
2010
  // Optional fields can be omitted
1692
2011
  };
1693
- return engine.isPermitted(input, securityContext);
2012
+ const validatedInput = {
2013
+ ...input,
2014
+ scope: validatedScope
2015
+ };
2016
+ return engine.isPermitted(validatedInput, securityContext);
1694
2017
  }
1695
- async function isPermittedCached(input) {
2018
+ async function isPermittedCached(input, appConfig, appName) {
1696
2019
  const { userId, scope, permission, pageId } = input;
1697
2020
  const cacheKey = RBACCache.generatePermissionKey({
1698
2021
  userId,
@@ -1707,7 +2030,7 @@ async function isPermittedCached(input) {
1707
2030
  return cached;
1708
2031
  }
1709
2032
  return getOrCreateRequest(input, async (checkInput) => {
1710
- const result = await isPermitted(checkInput);
2033
+ const result = await isPermitted(checkInput, appConfig, appName);
1711
2034
  const isPageLevelCheck = !!pageId || permission.includes("page.");
1712
2035
  rbacCache.set(cacheKey, result, void 0, isPageLevelCheck);
1713
2036
  return result;
@@ -1747,18 +2070,48 @@ async function isSuperAdmin(userId) {
1747
2070
  return engine["checkSuperAdmin"](userId);
1748
2071
  }
1749
2072
  async function getAppConfig(appId) {
1750
- log3.warn("getAppConfig called without Supabase client - returning null");
1751
- return null;
2073
+ try {
2074
+ const engine = getEngine();
2075
+ return getAppConfigWithClient(engine["supabase"], appId);
2076
+ } catch (err) {
2077
+ if (err instanceof RBACNotInitializedError) {
2078
+ return null;
2079
+ }
2080
+ throw err;
2081
+ }
1752
2082
  }
1753
2083
  async function getAppConfigWithClient(client, appId) {
2084
+ if (!client) {
2085
+ return null;
2086
+ }
2087
+ const cacheKey = `app_config:${appId}`;
2088
+ const cached = rbacCache.get(cacheKey, true);
2089
+ if (cached !== null) {
2090
+ return cached;
2091
+ }
2092
+ try {
2093
+ const { data, error } = await client.from("rbac_apps").select("requires_event, name").eq("id", appId).eq("is_active", true).single();
2094
+ if (error || !data) {
2095
+ return null;
2096
+ }
2097
+ const appConfig = { requires_event: data.requires_event ?? false };
2098
+ rbacCache.set(cacheKey, appConfig, 5 * 60 * 1e3, true);
2099
+ return appConfig;
2100
+ } catch (err) {
2101
+ log4.error("Error fetching app config:", err);
2102
+ return null;
2103
+ }
2104
+ }
2105
+ async function getAppConfigByName(appName) {
2106
+ const engine = getEngine();
1754
2107
  try {
1755
- const { data, error } = await client.from("rbac_apps").select("requires_event").eq("id", appId).eq("is_active", true).single();
2108
+ const { data, error } = await engine["supabase"].from("rbac_apps").select("requires_event, name").eq("name", appName).eq("is_active", true).single();
1756
2109
  if (error || !data) {
1757
2110
  return null;
1758
2111
  }
1759
- return { requires_event: data.requires_event };
2112
+ return { requires_event: data.requires_event ?? false };
1760
2113
  } catch (err) {
1761
- log3.error("Error fetching app config:", err);
2114
+ log4.error("Error fetching app config by name:", err);
1762
2115
  return null;
1763
2116
  }
1764
2117
  }
@@ -1807,6 +2160,7 @@ export {
1807
2160
  RBACCache,
1808
2161
  rbacCache,
1809
2162
  CACHE_PATTERNS,
2163
+ ContextValidator,
1810
2164
  createRBACConfig,
1811
2165
  getRBACConfig,
1812
2166
  getRBACLogger,
@@ -1837,6 +2191,7 @@ export {
1837
2191
  isSuperAdmin,
1838
2192
  getAppConfig,
1839
2193
  getAppConfigWithClient,
2194
+ getAppConfigByName,
1840
2195
  isOrganisationAdmin,
1841
2196
  isEventAdmin,
1842
2197
  invalidateUserCache,
@@ -1845,4 +2200,4 @@ export {
1845
2200
  invalidateAppCache,
1846
2201
  clearCache
1847
2202
  };
1848
- //# sourceMappingURL=chunk-HEHYGYOX.js.map
2203
+ //# sourceMappingURL=chunk-RUYZKXOD.js.map