@jmruthers/pace-core 0.5.189 → 0.5.191

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 (438) 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-IVYljGJ6.d.ts → DataTable-Be6dH_dR.d.ts} +1 -1
  4. package/dist/{DataTable-GUFUNZ3N.js → DataTable-WKRZD47S.js} +8 -8
  5. package/dist/{PublicPageProvider-B8HaLe69.d.ts → PublicPageProvider-ULXC_u6U.d.ts} +84 -25
  6. package/dist/{UnifiedAuthProvider-BG0AL5eE.d.ts → UnifiedAuthProvider-BYA9qB-o.d.ts} +4 -3
  7. package/dist/{UnifiedAuthProvider-643PUAIM.js → UnifiedAuthProvider-FTSG5XH7.js} +4 -2
  8. package/dist/{api-YP7XD5L6.js → api-IHKALJZD.js} +4 -2
  9. package/dist/{chunk-VGZZXKBR.js → chunk-6LTQQAT6.js} +351 -157
  10. package/dist/chunk-6LTQQAT6.js.map +1 -0
  11. package/dist/{chunk-MX64ZF6I.js → chunk-6TQDD426.js} +15 -15
  12. package/dist/chunk-6TQDD426.js.map +1 -0
  13. package/dist/{chunk-YHCN776L.js → chunk-G37KK66H.js} +2 -75
  14. package/dist/chunk-G37KK66H.js.map +1 -0
  15. package/dist/{chunk-THRPYOFK.js → chunk-HW3OVDUF.js} +5 -5
  16. package/dist/chunk-HW3OVDUF.js.map +1 -0
  17. package/dist/{chunk-F2IMUDXZ.js → chunk-I7PSE6JW.js} +75 -2
  18. package/dist/chunk-I7PSE6JW.js.map +1 -0
  19. package/dist/{chunk-IM4QE42D.js → chunk-LOMZXPSN.js} +141 -326
  20. package/dist/chunk-LOMZXPSN.js.map +1 -0
  21. package/dist/chunk-OETXORNB.js +614 -0
  22. package/dist/chunk-OETXORNB.js.map +1 -0
  23. package/dist/{chunk-HESYZWZW.js → chunk-QWWZ5CAQ.js} +2 -2
  24. package/dist/{chunk-HEHYGYOX.js → chunk-ROXMHMY2.js} +403 -46
  25. package/dist/chunk-ROXMHMY2.js.map +1 -0
  26. package/dist/{chunk-2UUZZJFT.js → chunk-ULHIJK66.js} +228 -177
  27. package/dist/{chunk-2UUZZJFT.js.map → chunk-ULHIJK66.js.map} +1 -1
  28. package/dist/{chunk-YGPFYGA6.js → chunk-VKB2CO4Z.js} +838 -503
  29. package/dist/chunk-VKB2CO4Z.js.map +1 -0
  30. package/dist/{chunk-3GOZZZYH.js → chunk-VRGWKHDB.js} +238 -301
  31. package/dist/chunk-VRGWKHDB.js.map +1 -0
  32. package/dist/{chunk-UCQSRW7Z.js → chunk-XNYQOL3Z.js} +431 -384
  33. package/dist/chunk-XNYQOL3Z.js.map +1 -0
  34. package/dist/{chunk-DDM4CCYT.js → chunk-XYXSXPUK.js} +79 -59
  35. package/dist/chunk-XYXSXPUK.js.map +1 -0
  36. package/dist/{chunk-SAUPYVLF.js → chunk-ZSAAAMVR.js} +1 -1
  37. package/dist/chunk-ZSAAAMVR.js.map +1 -0
  38. package/dist/components.d.ts +5 -6
  39. package/dist/components.js +19 -19
  40. package/dist/components.js.map +1 -1
  41. package/dist/{database.generated-DI89OQeI.d.ts → database.generated-CzIvgcPu.d.ts} +165 -201
  42. package/dist/eslint-rules/pace-core-compliance.cjs +0 -2
  43. package/dist/{file-reference-D037xOFK.d.ts → file-reference-BavO2eQj.d.ts} +13 -10
  44. package/dist/hooks.d.ts +20 -15
  45. package/dist/hooks.js +14 -8
  46. package/dist/hooks.js.map +1 -1
  47. package/dist/index.d.ts +17 -15
  48. package/dist/index.js +86 -81
  49. package/dist/index.js.map +1 -1
  50. package/dist/providers.d.ts +3 -3
  51. package/dist/providers.js +3 -1
  52. package/dist/rbac/index.d.ts +77 -13
  53. package/dist/rbac/index.js +12 -9
  54. package/dist/{types-Bwgl--Xo.d.ts → types-CEpcvwwF.d.ts} +1 -1
  55. package/dist/types.d.ts +3 -3
  56. package/dist/types.js +1 -1
  57. package/dist/{usePublicRouteParams-CTDELQ7H.d.ts → usePublicRouteParams-TZe0gy-4.d.ts} +17 -10
  58. package/dist/utils.d.ts +8 -8
  59. package/dist/utils.js +16 -16
  60. package/docs/README.md +2 -2
  61. package/docs/api/classes/ColumnFactory.md +1 -1
  62. package/docs/api/classes/ErrorBoundary.md +1 -1
  63. package/docs/api/classes/InvalidScopeError.md +2 -2
  64. package/docs/api/classes/Logger.md +1 -1
  65. package/docs/api/classes/MissingUserContextError.md +2 -2
  66. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  67. package/docs/api/classes/PermissionDeniedError.md +1 -1
  68. package/docs/api/classes/RBACAuditManager.md +2 -2
  69. package/docs/api/classes/RBACCache.md +1 -1
  70. package/docs/api/classes/RBACEngine.md +5 -5
  71. package/docs/api/classes/RBACError.md +1 -1
  72. package/docs/api/classes/RBACNotInitializedError.md +2 -2
  73. package/docs/api/classes/SecureSupabaseClient.md +25 -20
  74. package/docs/api/classes/StorageUtils.md +7 -4
  75. package/docs/api/enums/FileCategory.md +1 -1
  76. package/docs/api/enums/LogLevel.md +1 -1
  77. package/docs/api/enums/RBACErrorCode.md +1 -1
  78. package/docs/api/enums/RPCFunction.md +1 -1
  79. package/docs/api/interfaces/AddressFieldProps.md +1 -1
  80. package/docs/api/interfaces/AddressFieldRef.md +1 -1
  81. package/docs/api/interfaces/AggregateConfig.md +1 -1
  82. package/docs/api/interfaces/AutocompleteOptions.md +1 -1
  83. package/docs/api/interfaces/AvatarProps.md +1 -1
  84. package/docs/api/interfaces/BadgeProps.md +1 -1
  85. package/docs/api/interfaces/ButtonProps.md +1 -1
  86. package/docs/api/interfaces/CalendarProps.md +20 -6
  87. package/docs/api/interfaces/CardProps.md +1 -1
  88. package/docs/api/interfaces/ColorPalette.md +1 -1
  89. package/docs/api/interfaces/ColorShade.md +1 -1
  90. package/docs/api/interfaces/ComplianceResult.md +1 -1
  91. package/docs/api/interfaces/DataAccessRecord.md +9 -9
  92. package/docs/api/interfaces/DataRecord.md +1 -1
  93. package/docs/api/interfaces/DataTableAction.md +1 -1
  94. package/docs/api/interfaces/DataTableColumn.md +1 -1
  95. package/docs/api/interfaces/DataTableProps.md +1 -1
  96. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  97. package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
  98. package/docs/api/interfaces/DatabaseIssue.md +1 -1
  99. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  100. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  101. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  102. package/docs/api/interfaces/ExportColumn.md +1 -1
  103. package/docs/api/interfaces/ExportOptions.md +1 -1
  104. package/docs/api/interfaces/FileDisplayProps.md +62 -16
  105. package/docs/api/interfaces/FileMetadata.md +1 -1
  106. package/docs/api/interfaces/FileReference.md +2 -2
  107. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  108. package/docs/api/interfaces/FileUploadOptions.md +26 -12
  109. package/docs/api/interfaces/FileUploadProps.md +30 -19
  110. package/docs/api/interfaces/FooterProps.md +1 -1
  111. package/docs/api/interfaces/FormFieldProps.md +1 -1
  112. package/docs/api/interfaces/FormProps.md +1 -1
  113. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  114. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  115. package/docs/api/interfaces/InputProps.md +1 -1
  116. package/docs/api/interfaces/LabelProps.md +1 -1
  117. package/docs/api/interfaces/LoggerConfig.md +1 -1
  118. package/docs/api/interfaces/LoginFormProps.md +1 -1
  119. package/docs/api/interfaces/NavigationAccessRecord.md +10 -10
  120. package/docs/api/interfaces/NavigationContextType.md +9 -9
  121. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  122. package/docs/api/interfaces/NavigationItem.md +1 -1
  123. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  124. package/docs/api/interfaces/NavigationProviderProps.md +7 -7
  125. package/docs/api/interfaces/Organisation.md +1 -1
  126. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  127. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  128. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  129. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  130. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  131. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  132. package/docs/api/interfaces/PageAccessRecord.md +8 -8
  133. package/docs/api/interfaces/PagePermissionContextType.md +8 -8
  134. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  135. package/docs/api/interfaces/PagePermissionProviderProps.md +7 -7
  136. package/docs/api/interfaces/PaletteData.md +1 -1
  137. package/docs/api/interfaces/ParsedAddress.md +2 -2
  138. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  139. package/docs/api/interfaces/ProgressProps.md +3 -11
  140. package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
  141. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  142. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  143. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  144. package/docs/api/interfaces/QuickFix.md +1 -1
  145. package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
  146. package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
  147. package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
  148. package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
  149. package/docs/api/interfaces/RBACConfig.md +2 -2
  150. package/docs/api/interfaces/RBACContext.md +1 -1
  151. package/docs/api/interfaces/RBACLogger.md +1 -1
  152. package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
  153. package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
  154. package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
  155. package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
  156. package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
  157. package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
  158. package/docs/api/interfaces/RBACResult.md +1 -1
  159. package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
  160. package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
  161. package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
  162. package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
  163. package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
  164. package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
  165. package/docs/api/interfaces/RBACRolesListParams.md +1 -1
  166. package/docs/api/interfaces/RBACRolesListResult.md +1 -1
  167. package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
  168. package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
  169. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  170. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  171. package/docs/api/interfaces/RoleBasedRouterContextType.md +8 -8
  172. package/docs/api/interfaces/RoleBasedRouterProps.md +10 -10
  173. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  174. package/docs/api/interfaces/RouteAccessRecord.md +10 -10
  175. package/docs/api/interfaces/RouteConfig.md +10 -10
  176. package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
  177. package/docs/api/interfaces/SecureDataContextType.md +9 -9
  178. package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
  179. package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
  180. package/docs/api/interfaces/SetupIssue.md +1 -1
  181. package/docs/api/interfaces/StorageConfig.md +4 -4
  182. package/docs/api/interfaces/StorageFileInfo.md +7 -7
  183. package/docs/api/interfaces/StorageFileMetadata.md +25 -14
  184. package/docs/api/interfaces/StorageListOptions.md +22 -9
  185. package/docs/api/interfaces/StorageListResult.md +4 -4
  186. package/docs/api/interfaces/StorageUploadOptions.md +21 -8
  187. package/docs/api/interfaces/StorageUploadResult.md +6 -6
  188. package/docs/api/interfaces/StorageUrlOptions.md +19 -6
  189. package/docs/api/interfaces/StyleImport.md +1 -1
  190. package/docs/api/interfaces/SwitchProps.md +1 -1
  191. package/docs/api/interfaces/TabsContentProps.md +1 -1
  192. package/docs/api/interfaces/TabsListProps.md +1 -1
  193. package/docs/api/interfaces/TabsProps.md +1 -1
  194. package/docs/api/interfaces/TabsTriggerProps.md +1 -1
  195. package/docs/api/interfaces/TextareaProps.md +1 -1
  196. package/docs/api/interfaces/ToastActionElement.md +1 -1
  197. package/docs/api/interfaces/ToastProps.md +1 -1
  198. package/docs/api/interfaces/UnifiedAuthContextType.md +53 -53
  199. package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
  200. package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
  201. package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
  202. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  203. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  204. package/docs/api/interfaces/UsePublicEventLogoOptions.md +2 -2
  205. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  206. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  207. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  208. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +2 -2
  209. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  210. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  211. package/docs/api/interfaces/UseResolvedScopeOptions.md +5 -5
  212. package/docs/api/interfaces/UseResolvedScopeReturn.md +4 -4
  213. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  214. package/docs/api/interfaces/UserEventAccess.md +11 -11
  215. package/docs/api/interfaces/UserMenuProps.md +1 -1
  216. package/docs/api/interfaces/UserProfile.md +1 -1
  217. package/docs/api/modules.md +165 -106
  218. package/docs/api-reference/components.md +15 -7
  219. package/docs/api-reference/providers.md +2 -2
  220. package/docs/api-reference/rpc-functions.md +1 -0
  221. package/docs/best-practices/README.md +1 -1
  222. package/docs/best-practices/deployment.md +8 -8
  223. package/docs/getting-started/examples/README.md +2 -2
  224. package/docs/getting-started/installation-guide.md +4 -4
  225. package/docs/getting-started/quick-start.md +3 -3
  226. package/docs/migration/MIGRATION_GUIDE.md +3 -3
  227. package/docs/migration/README.md +18 -0
  228. package/docs/migration/database-changes-december-2025.md +767 -0
  229. package/docs/migration/person-scoped-profiles-migration-guide.md +472 -0
  230. package/docs/rbac/compliance/compliance-guide.md +2 -2
  231. package/docs/rbac/event-based-apps.md +2 -2
  232. package/docs/rbac/getting-started.md +2 -2
  233. package/docs/rbac/quick-start.md +2 -2
  234. package/docs/security/README.md +4 -4
  235. package/docs/standards/07-rbac-and-rls-standard.md +430 -7
  236. package/docs/troubleshooting/README.md +2 -2
  237. package/docs/troubleshooting/migration.md +3 -3
  238. package/package.json +1 -3
  239. package/scripts/check-pace-core-compliance.cjs +1 -1
  240. package/scripts/check-pace-core-compliance.js +1 -1
  241. package/src/__tests__/fixtures/supabase.ts +301 -0
  242. package/src/__tests__/public-recipe-view.test.ts +19 -19
  243. package/src/__tests__/rls-policies.test.ts +210 -74
  244. package/src/components/AddressField/AddressField.test.tsx +42 -0
  245. package/src/components/AddressField/AddressField.tsx +71 -60
  246. package/src/components/AddressField/README.md +7 -6
  247. package/src/components/Alert/Alert.test.tsx +50 -10
  248. package/src/components/Alert/Alert.tsx +5 -3
  249. package/src/components/Avatar/Avatar.test.tsx +95 -43
  250. package/src/components/Avatar/Avatar.tsx +16 -16
  251. package/src/components/Button/Button.test.tsx +2 -1
  252. package/src/components/Button/Button.tsx +3 -3
  253. package/src/components/Calendar/Calendar.test.tsx +53 -37
  254. package/src/components/Calendar/Calendar.tsx +409 -82
  255. package/src/components/Card/Card.test.tsx +7 -4
  256. package/src/components/Card/Card.tsx +3 -6
  257. package/src/components/Checkbox/Checkbox.tsx +2 -2
  258. package/src/components/DataTable/components/ActionButtons.tsx +5 -5
  259. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +2 -2
  260. package/src/components/DataTable/components/ColumnFilter.tsx +1 -1
  261. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +3 -3
  262. package/src/components/DataTable/components/DataTableBody.tsx +12 -12
  263. package/src/components/DataTable/components/DataTableCore.tsx +3 -3
  264. package/src/components/DataTable/components/DataTableToolbar.tsx +5 -5
  265. package/src/components/DataTable/components/DraggableColumnHeader.tsx +3 -3
  266. package/src/components/DataTable/components/EditableRow.tsx +2 -2
  267. package/src/components/DataTable/components/EmptyState.tsx +3 -3
  268. package/src/components/DataTable/components/GroupHeader.tsx +2 -2
  269. package/src/components/DataTable/components/GroupingDropdown.tsx +1 -1
  270. package/src/components/DataTable/components/ImportModal.tsx +4 -4
  271. package/src/components/DataTable/components/LoadingState.tsx +1 -1
  272. package/src/components/DataTable/components/PaginationControls.tsx +11 -11
  273. package/src/components/DataTable/components/UnifiedTableBody.tsx +9 -9
  274. package/src/components/DataTable/components/ViewRowModal.tsx +2 -2
  275. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +11 -37
  276. package/src/components/DataTable/components/__tests__/DataTableToolbar.test.tsx +157 -0
  277. package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +2 -1
  278. package/src/components/DataTable/components/__tests__/VirtualizedDataTable.test.tsx +128 -0
  279. package/src/components/DataTable/core/__tests__/ActionManager.test.ts +19 -0
  280. package/src/components/DataTable/core/__tests__/ColumnFactory.test.ts +51 -0
  281. package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +84 -0
  282. package/src/components/DataTable/core/__tests__/DataManager.test.ts +14 -0
  283. package/src/components/DataTable/core/__tests__/DataTableContext.test.tsx +136 -0
  284. package/src/components/DataTable/core/__tests__/LocalDataAdapter.test.ts +16 -0
  285. package/src/components/DataTable/core/__tests__/PluginRegistry.test.ts +18 -0
  286. package/src/components/DataTable/hooks/useDataTablePermissions.ts +28 -7
  287. package/src/components/DataTable/utils/__tests__/hierarchicalUtils.test.ts +30 -1
  288. package/src/components/DataTable/utils/hierarchicalUtils.ts +38 -10
  289. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +8 -3
  290. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +4 -4
  291. package/src/components/Dialog/Dialog.tsx +2 -2
  292. package/src/components/EventSelector/EventSelector.tsx +7 -7
  293. package/src/components/FileDisplay/FileDisplay.tsx +291 -179
  294. package/src/components/FileUpload/FileUpload.tsx +7 -4
  295. package/src/components/Header/Header.test.tsx +28 -0
  296. package/src/components/Header/Header.tsx +22 -9
  297. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +2 -2
  298. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +19 -14
  299. package/src/components/LoadingSpinner/LoadingSpinner.tsx +5 -5
  300. package/src/components/NavigationMenu/NavigationMenu.test.tsx +127 -1
  301. package/src/components/OrganisationSelector/OrganisationSelector.tsx +42 -22
  302. package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +4 -0
  303. package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +3 -0
  304. package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +3 -0
  305. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +16 -6
  306. package/src/components/PaceAppLayout/PaceAppLayout.tsx +37 -3
  307. package/src/components/PaceAppLayout/test-setup.tsx +1 -0
  308. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +66 -45
  309. package/src/components/PaceLoginPage/PaceLoginPage.tsx +6 -4
  310. package/src/components/Progress/Progress.test.tsx +18 -19
  311. package/src/components/Progress/Progress.tsx +31 -32
  312. package/src/components/PublicLayout/PublicLayout.test.tsx +6 -6
  313. package/src/components/PublicLayout/PublicPageProvider.tsx +5 -3
  314. package/src/components/Select/Select.test.tsx +4 -1
  315. package/src/components/Select/Select.tsx +65 -20
  316. package/src/components/Switch/Switch.test.tsx +2 -1
  317. package/src/components/Switch/Switch.tsx +1 -1
  318. package/src/components/Toast/Toast.tsx +1 -1
  319. package/src/components/Tooltip/Tooltip.test.tsx +8 -2
  320. package/src/components/UserMenu/UserMenu.tsx +3 -3
  321. package/src/eslint-rules/pace-core-compliance.cjs +0 -2
  322. package/src/eslint-rules/pace-core-compliance.js +0 -2
  323. package/src/hooks/__tests__/hooks.integration.test.tsx +4 -1
  324. package/src/hooks/__tests__/useAppConfig.unit.test.ts +76 -5
  325. package/src/hooks/__tests__/useDataTableState.test.ts +76 -0
  326. package/src/hooks/__tests__/useFileUrl.unit.test.ts +25 -69
  327. package/src/hooks/__tests__/useFileUrlCache.test.ts +129 -0
  328. package/src/hooks/__tests__/usePreventTabReload.test.ts +88 -0
  329. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +1 -1
  330. package/src/hooks/__tests__/usePublicEvent.test.ts +608 -0
  331. package/src/hooks/__tests__/useQueryCache.test.ts +144 -0
  332. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +67 -24
  333. package/src/hooks/index.ts +1 -1
  334. package/src/hooks/public/usePublicEvent.ts +10 -10
  335. package/src/hooks/public/usePublicFileDisplay.ts +173 -87
  336. package/src/hooks/useAppConfig.ts +24 -5
  337. package/src/hooks/useFileDisplay.ts +298 -36
  338. package/src/hooks/useFileReference.ts +56 -11
  339. package/src/hooks/useFileUrl.ts +1 -1
  340. package/src/hooks/useInactivityTracker.ts +16 -7
  341. package/src/hooks/usePermissionCache.test.ts +85 -8
  342. package/src/hooks/useQueryCache.ts +27 -6
  343. package/src/hooks/useSecureDataAccess.test.ts +87 -42
  344. package/src/hooks/useSecureDataAccess.ts +95 -48
  345. package/src/providers/__tests__/OrganisationProvider.test.tsx +27 -21
  346. package/src/providers/services/EventServiceProvider.tsx +37 -17
  347. package/src/providers/services/InactivityServiceProvider.tsx +4 -4
  348. package/src/providers/services/OrganisationServiceProvider.tsx +8 -1
  349. package/src/providers/services/UnifiedAuthProvider.tsx +115 -29
  350. package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +451 -0
  351. package/src/rbac/__tests__/engine.comprehensive.test.ts +12 -0
  352. package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +8 -0
  353. package/src/rbac/__tests__/rbac-engine-simplified.test.ts +4 -0
  354. package/src/rbac/api.ts +240 -36
  355. package/src/rbac/cache-invalidation.ts +21 -7
  356. package/src/rbac/compliance/quick-fix-suggestions.ts +1 -1
  357. package/src/rbac/components/NavigationGuard.tsx +23 -63
  358. package/src/rbac/components/NavigationProvider.test.tsx +52 -23
  359. package/src/rbac/components/NavigationProvider.tsx +13 -11
  360. package/src/rbac/components/PagePermissionGuard.tsx +77 -203
  361. package/src/rbac/components/PagePermissionProvider.tsx +13 -11
  362. package/src/rbac/components/PermissionEnforcer.tsx +24 -62
  363. package/src/rbac/components/RoleBasedRouter.tsx +14 -12
  364. package/src/rbac/components/SecureDataProvider.tsx +13 -11
  365. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +104 -41
  366. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +49 -12
  367. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +22 -1
  368. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +161 -82
  369. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +22 -1
  370. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +77 -30
  371. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +39 -5
  372. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +47 -4
  373. package/src/rbac/engine.ts +4 -2
  374. package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +144 -52
  375. package/src/rbac/hooks/index.ts +3 -0
  376. package/src/rbac/hooks/useCan.test.ts +101 -53
  377. package/src/rbac/hooks/usePermissions.ts +108 -41
  378. package/src/rbac/hooks/useRBAC.test.ts +11 -3
  379. package/src/rbac/hooks/useRBAC.ts +83 -40
  380. package/src/rbac/hooks/useResolvedScope.test.ts +189 -63
  381. package/src/rbac/hooks/useResolvedScope.ts +128 -70
  382. package/src/rbac/hooks/useSecureSupabase.ts +36 -19
  383. package/src/rbac/hooks/useSuperAdminBypass.ts +126 -0
  384. package/src/rbac/request-deduplication.ts +1 -1
  385. package/src/rbac/secureClient.ts +72 -12
  386. package/src/rbac/security.ts +29 -23
  387. package/src/rbac/types.ts +10 -0
  388. package/src/rbac/utils/__tests__/contextValidator.test.ts +150 -0
  389. package/src/rbac/utils/__tests__/deep-equal.test.ts +53 -0
  390. package/src/rbac/utils/__tests__/eventContext.test.ts +8 -3
  391. package/src/rbac/utils/__tests__/eventContext.unit.test.ts +74 -12
  392. package/src/rbac/utils/contextValidator.ts +288 -0
  393. package/src/rbac/utils/eventContext.ts +52 -3
  394. package/src/services/AuthService.ts +37 -8
  395. package/src/services/EventService.ts +165 -21
  396. package/src/services/OrganisationService.ts +125 -137
  397. package/src/services/__tests__/EventService.test.ts +26 -21
  398. package/src/services/__tests__/OrganisationService.pagination.test.ts +34 -8
  399. package/src/services/__tests__/OrganisationService.test.ts +218 -86
  400. package/src/types/database.generated.ts +166 -201
  401. package/src/types/file-reference.ts +13 -10
  402. package/src/types/supabase.ts +2 -2
  403. package/src/utils/__tests__/secureDataAccess.unit.test.ts +3 -2
  404. package/src/utils/app/appNameResolver.test.ts +346 -73
  405. package/src/utils/context/superAdminOverride.ts +58 -0
  406. package/src/utils/file-reference/index.ts +65 -37
  407. package/src/utils/google-places/googlePlacesUtils.test.ts +98 -0
  408. package/src/utils/google-places/googlePlacesUtils.ts +1 -1
  409. package/src/utils/google-places/loadGoogleMapsScript.test.ts +83 -0
  410. package/src/utils/google-places/types.ts +1 -1
  411. package/src/utils/request-deduplication.ts +4 -4
  412. package/src/utils/security/secureDataAccess.test.ts +1 -1
  413. package/src/utils/security/secureDataAccess.ts +7 -4
  414. package/src/utils/storage/README.md +1 -1
  415. package/src/utils/storage/helpers.test.ts +1 -1
  416. package/src/utils/storage/helpers.ts +38 -19
  417. package/src/utils/storage/types.ts +15 -8
  418. package/src/utils/validation/__tests__/csrf.test.ts +105 -0
  419. package/src/utils/validation/__tests__/sqlInjectionProtection.test.ts +92 -0
  420. package/src/vite-env.d.ts +2 -2
  421. package/dist/chunk-3GOZZZYH.js.map +0 -1
  422. package/dist/chunk-DDM4CCYT.js.map +0 -1
  423. package/dist/chunk-E7UAOUMY.js +0 -75
  424. package/dist/chunk-E7UAOUMY.js.map +0 -1
  425. package/dist/chunk-F2IMUDXZ.js.map +0 -1
  426. package/dist/chunk-HEHYGYOX.js.map +0 -1
  427. package/dist/chunk-IM4QE42D.js.map +0 -1
  428. package/dist/chunk-MX64ZF6I.js.map +0 -1
  429. package/dist/chunk-SAUPYVLF.js.map +0 -1
  430. package/dist/chunk-THRPYOFK.js.map +0 -1
  431. package/dist/chunk-UCQSRW7Z.js.map +0 -1
  432. package/dist/chunk-VGZZXKBR.js.map +0 -1
  433. package/dist/chunk-YGPFYGA6.js.map +0 -1
  434. package/dist/chunk-YHCN776L.js.map +0 -1
  435. /package/dist/{DataTable-GUFUNZ3N.js.map → DataTable-WKRZD47S.js.map} +0 -0
  436. /package/dist/{UnifiedAuthProvider-643PUAIM.js.map → UnifiedAuthProvider-FTSG5XH7.js.map} +0 -0
  437. /package/dist/{api-YP7XD5L6.js.map → api-IHKALJZD.js.map} +0 -0
  438. /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,228 @@ 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("core_events").select("organisation_id").eq("event_id", eventId).single();
705
+ let organisationId = null;
706
+ if (error || !data) {
707
+ organisationId = null;
708
+ } else if (data.organisation_id) {
709
+ organisationId = data.organisation_id;
710
+ } else {
711
+ organisationId = null;
712
+ }
713
+ if (orgDerivationCache.size >= MAX_CACHE_SIZE) {
714
+ const firstKey = orgDerivationCache.keys().next().value;
715
+ if (firstKey) {
716
+ orgDerivationCache.delete(firstKey);
717
+ }
718
+ }
719
+ orgDerivationCache.set(eventId, organisationId);
720
+ return organisationId;
721
+ }
722
+
723
+ // src/rbac/utils/contextValidator.ts
724
+ var log2 = createLogger("ContextValidator");
725
+ function allowsOptionalContexts(appName) {
726
+ return appName === "PORTAL" || appName === "ADMIN";
727
+ }
728
+ var ContextValidator = class {
729
+ /**
730
+ * Validate scope against app requirements
731
+ *
732
+ * @param scope - Current scope
733
+ * @param appConfig - App configuration (requires_event flag)
734
+ * @param appName - App name (for PORTAL/ADMIN special case)
735
+ * @returns Validation result with resolved scope
736
+ */
737
+ static async validateScope(scope, appConfig, appName) {
738
+ if (allowsOptionalContexts(appName)) {
739
+ return {
740
+ isValid: true,
741
+ resolvedScope: {
742
+ organisationId: scope.organisationId,
743
+ eventId: scope.eventId,
744
+ appId: scope.appId
745
+ },
746
+ error: null
747
+ };
748
+ }
749
+ if (!appConfig) {
750
+ if (!scope.organisationId) {
751
+ return {
752
+ isValid: false,
753
+ resolvedScope: null,
754
+ error: new OrganisationContextRequiredError()
755
+ };
756
+ }
757
+ return {
758
+ isValid: true,
759
+ resolvedScope: scope,
760
+ error: null
761
+ };
762
+ }
763
+ if (appConfig.requires_event) {
764
+ if (!scope.eventId) {
765
+ return {
766
+ isValid: false,
767
+ resolvedScope: null,
768
+ error: new EventContextRequiredError()
769
+ };
770
+ }
771
+ return {
772
+ isValid: true,
773
+ resolvedScope: scope,
774
+ error: null
775
+ };
776
+ }
777
+ if (!scope.organisationId) {
778
+ return {
779
+ isValid: false,
780
+ resolvedScope: null,
781
+ error: new OrganisationContextRequiredError()
782
+ };
783
+ }
784
+ return {
785
+ isValid: true,
786
+ resolvedScope: scope,
787
+ error: null
788
+ };
789
+ }
790
+ /**
791
+ * Resolve required context and derive missing values
792
+ *
793
+ * @param scope - Current scope
794
+ * @param appConfig - App configuration
795
+ * @param appName - App name (for PORTAL/ADMIN special case)
796
+ * @param supabase - Supabase client (for deriving org from event)
797
+ * @returns Resolved scope with all required context
798
+ */
799
+ static async resolveRequiredContext(scope, appConfig, appName, supabase) {
800
+ if (allowsOptionalContexts(appName)) {
801
+ return {
802
+ isValid: true,
803
+ resolvedScope: {
804
+ organisationId: scope.organisationId,
805
+ eventId: scope.eventId,
806
+ appId: scope.appId
807
+ },
808
+ error: null
809
+ };
810
+ }
811
+ if (!appConfig) {
812
+ if (!scope.organisationId) {
813
+ return {
814
+ isValid: false,
815
+ resolvedScope: null,
816
+ error: new OrganisationContextRequiredError()
817
+ };
818
+ }
819
+ return {
820
+ isValid: true,
821
+ resolvedScope: scope,
822
+ error: null
823
+ };
824
+ }
825
+ if (appConfig.requires_event) {
826
+ if (!scope.eventId) {
827
+ return {
828
+ isValid: false,
829
+ resolvedScope: null,
830
+ error: new EventContextRequiredError()
831
+ };
832
+ }
833
+ let organisationId = scope.organisationId;
834
+ if (!organisationId && supabase && scope.eventId) {
835
+ try {
836
+ const derivedOrgId = await this.deriveOrgFromEvent(supabase, scope.eventId);
837
+ organisationId = derivedOrgId || void 0;
838
+ if (!organisationId) {
839
+ return {
840
+ isValid: false,
841
+ resolvedScope: null,
842
+ error: new Error("Could not resolve organisation from event context")
843
+ };
844
+ }
845
+ } catch (error) {
846
+ log2.error("Failed to derive org from event:", error);
847
+ return {
848
+ isValid: false,
849
+ resolvedScope: null,
850
+ error: error instanceof Error ? error : new Error("Failed to derive organisation from event")
851
+ };
852
+ }
853
+ } else if (!organisationId) {
854
+ return {
855
+ isValid: false,
856
+ resolvedScope: null,
857
+ error: new Error("Event context requires organisationId but it could not be derived (supabase client not available)")
858
+ };
859
+ }
860
+ return {
861
+ isValid: true,
862
+ resolvedScope: {
863
+ organisationId,
864
+ eventId: scope.eventId,
865
+ appId: scope.appId
866
+ },
867
+ error: null
868
+ };
869
+ }
870
+ if (!scope.organisationId) {
871
+ return {
872
+ isValid: false,
873
+ resolvedScope: null,
874
+ error: new OrganisationContextRequiredError()
875
+ };
876
+ }
877
+ return {
878
+ isValid: true,
879
+ resolvedScope: scope,
880
+ error: null
881
+ };
882
+ }
883
+ /**
884
+ * Derive organisation ID from event ID
885
+ *
886
+ * @param supabase - Supabase client
887
+ * @param eventId - Event ID
888
+ * @returns Organisation ID or null
889
+ */
890
+ static async deriveOrgFromEvent(supabase, eventId) {
891
+ return getOrganisationFromEvent(supabase, eventId);
892
+ }
893
+ /**
894
+ * Check if context is ready for permission checks
895
+ *
896
+ * @param scope - Current scope
897
+ * @param appConfig - App configuration
898
+ * @param appName - App name
899
+ * @param hasSelectedEvent - Whether event is selected
900
+ * @param hasSelectedOrganisation - Whether organisation is selected
901
+ * @returns True if context is ready
902
+ */
903
+ static isContextReady(scope, appConfig, appName, hasSelectedEvent, hasSelectedOrganisation) {
904
+ if (allowsOptionalContexts(appName)) {
905
+ return true;
906
+ }
907
+ if (!appConfig) {
908
+ return !!hasSelectedOrganisation || !!scope.organisationId;
909
+ }
910
+ if (appConfig.requires_event) {
911
+ return !!hasSelectedEvent || !!scope.eventId;
912
+ }
913
+ return !!hasSelectedOrganisation || !!scope.organisationId;
914
+ }
915
+ };
916
+
675
917
  // src/rbac/security.ts
676
- var log2 = createLogger("RBACSecurity");
918
+ var log3 = createLogger("RBACSecurity");
677
919
  var RBACSecurityValidator = class {
678
920
  /**
679
921
  * Validate permission string format
@@ -782,19 +1024,13 @@ var RBACSecurityValidator = class {
782
1024
  /**
783
1025
  * Validate context requirements for security
784
1026
  * @param scope - Scope object
785
- * @param appId - Application ID
1027
+ * @param appConfig - App configuration
1028
+ * @param appName - App name (for PORTAL special case)
786
1029
  * @returns True if context is valid, false otherwise
787
1030
  */
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;
1031
+ static async validateContextRequirements(scope, appConfig, appName) {
1032
+ const validation = await ContextValidator.validateScope(scope, appConfig || null, appName);
1033
+ return validation.isValid;
798
1034
  }
799
1035
  // Only warn once per 5 seconds per user
800
1036
  static logSecurityEvent(event) {
@@ -813,7 +1049,7 @@ var RBACSecurityValidator = class {
813
1049
  this.rateLimitWarningCount.set(event.userId, userWarning);
814
1050
  return;
815
1051
  } else {
816
- log2.warn("Security event (throttled):", {
1052
+ log3.warn("Security event (throttled):", {
817
1053
  ...securityEvent,
818
1054
  details: {
819
1055
  ...securityEvent.details,
@@ -826,11 +1062,11 @@ var RBACSecurityValidator = class {
826
1062
  }
827
1063
  } else {
828
1064
  this.rateLimitWarningCount.set(event.userId, { count: 0, lastWarning: now });
829
- log2.warn("Security event:", securityEvent);
1065
+ log3.warn("Security event:", securityEvent);
830
1066
  return;
831
1067
  }
832
1068
  }
833
- log2.warn("Security event:", securityEvent);
1069
+ log3.warn("Security event:", securityEvent);
834
1070
  }
835
1071
  /**
836
1072
  * Get severity level for security event
@@ -902,10 +1138,18 @@ var RBACSecurityMiddleware = class {
902
1138
  if (!RBACSecurityValidator.validateUserId(context.userId)) {
903
1139
  errors.push("Invalid user ID format");
904
1140
  }
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");
1141
+ const isPagePermission = input.permission?.includes(":page.") || !!input.pageId;
1142
+ const requiresOrgId = !isPagePermission;
1143
+ if (requiresOrgId) {
1144
+ if (!context.organisationId) {
1145
+ errors.push("Organisation ID is required for resource-level permissions");
1146
+ } else if (!RBACSecurityValidator.validateUUID(context.organisationId)) {
1147
+ errors.push("Invalid organisation ID format");
1148
+ }
1149
+ } else {
1150
+ if (context.organisationId && !RBACSecurityValidator.validateUUID(context.organisationId)) {
1151
+ errors.push("Invalid organisation ID format");
1152
+ }
909
1153
  }
910
1154
  if (input.permission && !RBACSecurityValidator.validatePermission(input.permission)) {
911
1155
  errors.push("Invalid permission format");
@@ -1252,7 +1496,8 @@ var RBACEngine = class {
1252
1496
  return "super";
1253
1497
  }
1254
1498
  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();
1499
+ 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);
1500
+ const orgRole = orgRoles?.[0];
1256
1501
  if (orgRole?.role === "org_admin") {
1257
1502
  rbacCache.set(cacheKey, "admin", 6e4);
1258
1503
  return "admin";
@@ -1598,6 +1843,7 @@ function generateDeduplicationKey(input) {
1598
1843
  return RBACCache.generatePermissionKey({
1599
1844
  userId: input.userId,
1600
1845
  organisationId: input.scope.organisationId,
1846
+ // Can be undefined for page-level permissions
1601
1847
  eventId: input.scope.eventId,
1602
1848
  appId: input.scope.appId,
1603
1849
  permission: input.permission,
@@ -1624,7 +1870,7 @@ function getInFlightRequestCount() {
1624
1870
  }
1625
1871
 
1626
1872
  // src/rbac/api.ts
1627
- var log3 = createLogger("RBACAPI");
1873
+ var log4 = createLogger("RBACAPI");
1628
1874
  var globalEngine = null;
1629
1875
  function setupRBAC(supabase, config) {
1630
1876
  const logger = getRBACLogger();
@@ -1662,37 +1908,116 @@ function getEngine() {
1662
1908
  }
1663
1909
  return globalEngine;
1664
1910
  }
1665
- async function getAccessLevel(input) {
1911
+ async function getAccessLevel(input, appConfig, appName) {
1666
1912
  const engine = getEngine();
1667
- return engine.getAccessLevel(input);
1913
+ const isSuperAdminUser = await engine["checkSuperAdmin"](input.userId);
1914
+ if (isSuperAdminUser) {
1915
+ return "super";
1916
+ }
1917
+ let resolvedAppConfig = appConfig ?? null;
1918
+ let resolvedAppName = appName;
1919
+ if (!resolvedAppConfig && input.scope.appId) {
1920
+ resolvedAppConfig = await getAppConfig(input.scope.appId);
1921
+ }
1922
+ const validation = await ContextValidator.resolveRequiredContext(
1923
+ input.scope,
1924
+ resolvedAppConfig,
1925
+ resolvedAppName,
1926
+ engine["supabase"]
1927
+ );
1928
+ if (!validation.isValid || !validation.resolvedScope) {
1929
+ throw validation.error || new OrganisationContextRequiredError();
1930
+ }
1931
+ return engine.getAccessLevel({
1932
+ ...input,
1933
+ scope: validation.resolvedScope
1934
+ });
1668
1935
  }
1669
- async function getPermissionMap(input) {
1936
+ async function getPermissionMap(input, appConfig, appName) {
1670
1937
  const engine = getEngine();
1671
- return engine.getPermissionMap(input);
1938
+ let resolvedAppConfig = appConfig ?? null;
1939
+ let resolvedAppName = appName;
1940
+ if (!resolvedAppConfig && input.scope.appId) {
1941
+ resolvedAppConfig = await getAppConfig(input.scope.appId);
1942
+ }
1943
+ const validation = await ContextValidator.resolveRequiredContext(
1944
+ input.scope,
1945
+ resolvedAppConfig,
1946
+ resolvedAppName,
1947
+ engine["supabase"]
1948
+ );
1949
+ if (!validation.isValid || !validation.resolvedScope) {
1950
+ throw validation.error || new OrganisationContextRequiredError();
1951
+ }
1952
+ return engine.getPermissionMap({
1953
+ ...input,
1954
+ scope: validation.resolvedScope
1955
+ });
1672
1956
  }
1673
1957
  async function resolveAppContext(input) {
1674
1958
  const engine = getEngine();
1675
1959
  return engine.resolveAppContext(input);
1676
1960
  }
1677
- async function getRoleContext(input) {
1961
+ async function getRoleContext(input, appConfig, appName) {
1678
1962
  const engine = getEngine();
1679
- return engine.getRoleContext(input);
1963
+ let resolvedAppConfig = appConfig ?? null;
1964
+ let resolvedAppName = appName;
1965
+ if (!resolvedAppConfig && input.scope.appId) {
1966
+ resolvedAppConfig = await getAppConfig(input.scope.appId);
1967
+ }
1968
+ const validation = await ContextValidator.resolveRequiredContext(
1969
+ input.scope,
1970
+ resolvedAppConfig,
1971
+ resolvedAppName,
1972
+ engine["supabase"]
1973
+ );
1974
+ if (!validation.isValid || !validation.resolvedScope) {
1975
+ throw validation.error || new OrganisationContextRequiredError();
1976
+ }
1977
+ return engine.getRoleContext({
1978
+ ...input,
1979
+ scope: validation.resolvedScope
1980
+ });
1680
1981
  }
1681
- async function isPermitted(input) {
1982
+ async function isPermitted(input, appConfig, appName) {
1682
1983
  const engine = getEngine();
1683
- if (!input.scope.organisationId) {
1684
- throw new OrganisationContextRequiredError();
1984
+ let resolvedAppConfig = appConfig ?? null;
1985
+ let resolvedAppName = appName;
1986
+ if (!resolvedAppConfig && input.scope.appId) {
1987
+ resolvedAppConfig = await getAppConfig(input.scope.appId);
1685
1988
  }
1989
+ if (!resolvedAppName && input.scope.appId) {
1990
+ try {
1991
+ const { data } = await engine["supabase"].from("rbac_apps").select("name").eq("id", input.scope.appId).eq("is_active", true).single();
1992
+ if (data) {
1993
+ resolvedAppName = data.name;
1994
+ }
1995
+ } catch (err) {
1996
+ }
1997
+ }
1998
+ const validation = await ContextValidator.resolveRequiredContext(
1999
+ input.scope,
2000
+ resolvedAppConfig,
2001
+ resolvedAppName,
2002
+ engine["supabase"]
2003
+ );
2004
+ if (!validation.isValid || !validation.resolvedScope) {
2005
+ throw validation.error || new OrganisationContextRequiredError();
2006
+ }
2007
+ const validatedScope = validation.resolvedScope;
1686
2008
  const securityContext = {
1687
2009
  userId: input.userId,
1688
- organisationId: input.scope.organisationId,
1689
- // Required - no fallback
2010
+ organisationId: validatedScope.organisationId || null,
1690
2011
  timestamp: /* @__PURE__ */ new Date()
1691
2012
  // Optional fields can be omitted
1692
2013
  };
1693
- return engine.isPermitted(input, securityContext);
2014
+ const validatedInput = {
2015
+ ...input,
2016
+ scope: validatedScope
2017
+ };
2018
+ return engine.isPermitted(validatedInput, securityContext);
1694
2019
  }
1695
- async function isPermittedCached(input) {
2020
+ async function isPermittedCached(input, appConfig, appName) {
1696
2021
  const { userId, scope, permission, pageId } = input;
1697
2022
  const cacheKey = RBACCache.generatePermissionKey({
1698
2023
  userId,
@@ -1707,7 +2032,7 @@ async function isPermittedCached(input) {
1707
2032
  return cached;
1708
2033
  }
1709
2034
  return getOrCreateRequest(input, async (checkInput) => {
1710
- const result = await isPermitted(checkInput);
2035
+ const result = await isPermitted(checkInput, appConfig, appName);
1711
2036
  const isPageLevelCheck = !!pageId || permission.includes("page.");
1712
2037
  rbacCache.set(cacheKey, result, void 0, isPageLevelCheck);
1713
2038
  return result;
@@ -1747,18 +2072,48 @@ async function isSuperAdmin(userId) {
1747
2072
  return engine["checkSuperAdmin"](userId);
1748
2073
  }
1749
2074
  async function getAppConfig(appId) {
1750
- log3.warn("getAppConfig called without Supabase client - returning null");
1751
- return null;
2075
+ try {
2076
+ const engine = getEngine();
2077
+ return getAppConfigWithClient(engine["supabase"], appId);
2078
+ } catch (err) {
2079
+ if (err instanceof RBACNotInitializedError) {
2080
+ return null;
2081
+ }
2082
+ throw err;
2083
+ }
1752
2084
  }
1753
2085
  async function getAppConfigWithClient(client, appId) {
2086
+ if (!client) {
2087
+ return null;
2088
+ }
2089
+ const cacheKey = `app_config:${appId}`;
2090
+ const cached = rbacCache.get(cacheKey, true);
2091
+ if (cached !== null) {
2092
+ return cached;
2093
+ }
2094
+ try {
2095
+ const { data, error } = await client.from("rbac_apps").select("requires_event, name").eq("id", appId).eq("is_active", true).single();
2096
+ if (error || !data) {
2097
+ return null;
2098
+ }
2099
+ const appConfig = { requires_event: data.requires_event ?? false };
2100
+ rbacCache.set(cacheKey, appConfig, 5 * 60 * 1e3, true);
2101
+ return appConfig;
2102
+ } catch (err) {
2103
+ log4.error("Error fetching app config:", err);
2104
+ return null;
2105
+ }
2106
+ }
2107
+ async function getAppConfigByName(appName) {
2108
+ const engine = getEngine();
1754
2109
  try {
1755
- const { data, error } = await client.from("rbac_apps").select("requires_event").eq("id", appId).eq("is_active", true).single();
2110
+ const { data, error } = await engine["supabase"].from("rbac_apps").select("requires_event, name").eq("name", appName).eq("is_active", true).single();
1756
2111
  if (error || !data) {
1757
2112
  return null;
1758
2113
  }
1759
- return { requires_event: data.requires_event };
2114
+ return { requires_event: data.requires_event ?? false };
1760
2115
  } catch (err) {
1761
- log3.error("Error fetching app config:", err);
2116
+ log4.error("Error fetching app config by name:", err);
1762
2117
  return null;
1763
2118
  }
1764
2119
  }
@@ -1807,6 +2162,7 @@ export {
1807
2162
  RBACCache,
1808
2163
  rbacCache,
1809
2164
  CACHE_PATTERNS,
2165
+ ContextValidator,
1810
2166
  createRBACConfig,
1811
2167
  getRBACConfig,
1812
2168
  getRBACLogger,
@@ -1837,6 +2193,7 @@ export {
1837
2193
  isSuperAdmin,
1838
2194
  getAppConfig,
1839
2195
  getAppConfigWithClient,
2196
+ getAppConfigByName,
1840
2197
  isOrganisationAdmin,
1841
2198
  isEventAdmin,
1842
2199
  invalidateUserCache,
@@ -1845,4 +2202,4 @@ export {
1845
2202
  invalidateAppCache,
1846
2203
  clearCache
1847
2204
  };
1848
- //# sourceMappingURL=chunk-HEHYGYOX.js.map
2205
+ //# sourceMappingURL=chunk-ROXMHMY2.js.map