@jmruthers/pace-core 0.5.191 → 0.6.1
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.
- package/CHANGELOG.md +29 -0
- package/README.md +7 -1
- package/cursor-rules/00-pace-core-compliance.mdc +372 -0
- package/cursor-rules/01-standards-compliance.mdc +275 -0
- package/cursor-rules/02-project-structure.mdc +200 -0
- package/cursor-rules/03-solid-principles.mdc +341 -0
- package/cursor-rules/04-testing-standards.mdc +315 -0
- package/cursor-rules/05-bug-reports-and-features.mdc +246 -0
- package/cursor-rules/06-code-quality.mdc +392 -0
- package/cursor-rules/07-tech-stack-compliance.mdc +309 -0
- package/cursor-rules/CHANGELOG.md +101 -0
- package/cursor-rules/README.md +191 -0
- package/dist/{AuthService-CbP_utw2.d.ts → AuthService-DjnJHDtC.d.ts} +1 -0
- package/dist/{DataTable-Be6dH_dR.d.ts → DataTable-CH1U5Tpy.d.ts} +1 -1
- package/dist/{DataTable-WKRZD47S.js → DataTable-DQ7RSOHE.js} +8 -7
- package/dist/{PublicPageProvider-ULXC_u6U.d.ts → PublicPageProvider-ce4xlHYA.d.ts} +37 -156
- package/dist/{UnifiedAuthProvider-BYA9qB-o.d.ts → UnifiedAuthProvider-185Ih4dj.d.ts} +2 -0
- package/dist/{UnifiedAuthProvider-FTSG5XH7.js → UnifiedAuthProvider-ATAP5UTR.js} +3 -3
- package/dist/{api-IHKALJZD.js → api-N774RPUA.js} +2 -2
- package/dist/{chunk-6C4YBBJM.js → chunk-3QRJFVBR.js} +1 -1
- package/dist/chunk-3QRJFVBR.js.map +1 -0
- package/dist/{chunk-OETXORNB.js → chunk-3XTALGJF.js} +211 -136
- package/dist/chunk-3XTALGJF.js.map +1 -0
- package/dist/{chunk-6TQDD426.js → chunk-4N5C5XZU.js} +47 -228
- package/dist/chunk-4N5C5XZU.js.map +1 -0
- package/dist/{chunk-LOMZXPSN.js → chunk-4ZC4GX36.js} +47 -74
- package/dist/chunk-4ZC4GX36.js.map +1 -0
- package/dist/{chunk-6LTQQAT6.js → chunk-BYFSK72L.js} +357 -158
- package/dist/chunk-BYFSK72L.js.map +1 -0
- package/dist/{chunk-XYXSXPUK.js → chunk-EXUD6RNJ.js} +50 -10
- package/dist/chunk-EXUD6RNJ.js.map +1 -0
- package/dist/{chunk-VKB2CO4Z.js → chunk-GLK6VM3F.js} +244 -249
- package/dist/chunk-GLK6VM3F.js.map +1 -0
- package/dist/{chunk-HW3OVDUF.js → chunk-J36DSWQK.js} +1 -1
- package/dist/{chunk-HW3OVDUF.js.map → chunk-J36DSWQK.js.map} +1 -1
- package/dist/{chunk-XNYQOL3Z.js → chunk-JBKQ3SAO.js} +9 -18
- package/dist/chunk-JBKQ3SAO.js.map +1 -0
- package/dist/{chunk-ROXMHMY2.js → chunk-KNC55RTG.js} +13 -3
- package/dist/{chunk-ROXMHMY2.js.map → chunk-KNC55RTG.js.map} +1 -1
- package/dist/{chunk-QWWZ5CAQ.js → chunk-LXQLPRQ2.js} +2 -2
- package/dist/{chunk-ULHIJK66.js → chunk-T33XF5ZC.js} +255 -140
- package/dist/chunk-T33XF5ZC.js.map +1 -0
- package/dist/{chunk-VRGWKHDB.js → chunk-XM25TVIE.js} +100 -33
- package/dist/chunk-XM25TVIE.js.map +1 -0
- package/dist/components.d.ts +4 -4
- package/dist/components.js +9 -9
- package/dist/hooks.d.ts +6 -6
- package/dist/hooks.js +20 -25
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +11 -11
- package/dist/index.js +18 -21
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +3 -3
- package/dist/providers.js +2 -2
- package/dist/rbac/index.d.ts +2 -20
- package/dist/rbac/index.js +7 -9
- package/dist/{usePublicRouteParams-TZe0gy-4.d.ts → usePublicRouteParams-BJAlWfuJ.d.ts} +3 -3
- package/dist/{useToast-C8gR5ir4.d.ts → useToast-AyaT-x7p.d.ts} +2 -2
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +3 -3
- package/docs/api/classes/ColumnFactory.md +1 -1
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.md +1 -1
- package/docs/api/classes/Logger.md +1 -1
- package/docs/api/classes/MissingUserContextError.md +1 -1
- package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
- package/docs/api/classes/PermissionDeniedError.md +2 -2
- package/docs/api/classes/RBACAuditManager.md +2 -2
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +2 -2
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +1 -1
- package/docs/api/classes/SecureSupabaseClient.md +10 -10
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/enums/FileCategory.md +1 -1
- package/docs/api/enums/LogLevel.md +1 -1
- package/docs/api/enums/RBACErrorCode.md +1 -1
- package/docs/api/enums/RPCFunction.md +1 -1
- package/docs/api/interfaces/AddressFieldProps.md +1 -1
- package/docs/api/interfaces/AddressFieldRef.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +1 -1
- package/docs/api/interfaces/AutocompleteOptions.md +1 -1
- package/docs/api/interfaces/AvatarProps.md +1 -1
- package/docs/api/interfaces/BadgeProps.md +1 -1
- package/docs/api/interfaces/ButtonProps.md +1 -1
- package/docs/api/interfaces/CalendarProps.md +1 -1
- package/docs/api/interfaces/CardProps.md +1 -1
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/ComplianceResult.md +1 -1
- package/docs/api/interfaces/DataAccessRecord.md +1 -1
- package/docs/api/interfaces/DataRecord.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +1 -1
- package/docs/api/interfaces/DataTableColumn.md +1 -1
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
- package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
- package/docs/api/interfaces/DatabaseIssue.md +1 -1
- package/docs/api/interfaces/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventAppRoleData.md +1 -1
- package/docs/api/interfaces/ExportColumn.md +1 -1
- package/docs/api/interfaces/ExportOptions.md +1 -1
- package/docs/api/interfaces/FileDisplayProps.md +24 -11
- package/docs/api/interfaces/FileMetadata.md +1 -1
- package/docs/api/interfaces/FileReference.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadOptions.md +1 -1
- package/docs/api/interfaces/FileUploadProps.md +1 -1
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/FormFieldProps.md +1 -1
- package/docs/api/interfaces/FormProps.md +1 -1
- package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
- package/docs/api/interfaces/InputProps.md +1 -1
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoggerConfig.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +2 -2
- package/docs/api/interfaces/NavigationContextType.md +1 -1
- package/docs/api/interfaces/NavigationGuardProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +1 -1
- package/docs/api/interfaces/NavigationMenuProps.md +1 -1
- package/docs/api/interfaces/NavigationProviderProps.md +1 -1
- package/docs/api/interfaces/Organisation.md +1 -1
- package/docs/api/interfaces/OrganisationContextType.md +1 -1
- package/docs/api/interfaces/OrganisationMembership.md +1 -1
- package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
- package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
- package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
- package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
- package/docs/api/interfaces/PageAccessRecord.md +1 -1
- package/docs/api/interfaces/PagePermissionContextType.md +1 -1
- package/docs/api/interfaces/PagePermissionGuardProps.md +2 -2
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/ParsedAddress.md +1 -1
- package/docs/api/interfaces/PermissionEnforcerProps.md +4 -4
- package/docs/api/interfaces/ProgressProps.md +1 -1
- package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
- package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
- package/docs/api/interfaces/QuickFix.md +1 -1
- package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
- package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
- package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
- package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
- package/docs/api/interfaces/RBACConfig.md +2 -2
- package/docs/api/interfaces/RBACContext.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckResult.md +2 -2
- package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
- package/docs/api/interfaces/RBACResult.md +1 -1
- package/docs/api/interfaces/RBACRoleGrantParams.md +2 -2
- package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeParams.md +2 -2
- package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateParams.md +2 -2
- package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
- package/docs/api/interfaces/RBACRolesListParams.md +1 -1
- package/docs/api/interfaces/RBACRolesListResult.md +2 -2
- package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
- package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
- package/docs/api/interfaces/ResourcePermissions.md +1 -1
- package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RoleManagementResult.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +2 -2
- package/docs/api/interfaces/RouteConfig.md +2 -2
- package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
- package/docs/api/interfaces/SecureDataContextType.md +1 -1
- package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
- package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
- package/docs/api/interfaces/SetupIssue.md +1 -1
- package/docs/api/interfaces/StorageConfig.md +1 -1
- package/docs/api/interfaces/StorageFileInfo.md +1 -1
- package/docs/api/interfaces/StorageFileMetadata.md +1 -1
- package/docs/api/interfaces/StorageListOptions.md +1 -1
- package/docs/api/interfaces/StorageListResult.md +1 -1
- package/docs/api/interfaces/StorageUploadOptions.md +1 -1
- package/docs/api/interfaces/StorageUploadResult.md +1 -1
- package/docs/api/interfaces/StorageUrlOptions.md +1 -1
- package/docs/api/interfaces/StyleImport.md +1 -1
- package/docs/api/interfaces/SwitchProps.md +1 -1
- package/docs/api/interfaces/TabsContentProps.md +1 -1
- package/docs/api/interfaces/TabsListProps.md +1 -1
- package/docs/api/interfaces/TabsProps.md +1 -1
- package/docs/api/interfaces/TabsTriggerProps.md +1 -1
- package/docs/api/interfaces/TextareaProps.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +60 -38
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
- package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
- package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +2 -2
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +2 -2
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeOptions.md +2 -2
- package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
- package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +1 -1
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +194 -209
- package/docs/getting-started/cursor-rules.md +262 -0
- package/docs/getting-started/installation-guide.md +6 -1
- package/docs/getting-started/quick-start.md +6 -1
- package/docs/migration/MIGRATION_GUIDE.md +4 -4
- package/docs/migration/REACT_19_MIGRATION.md +227 -0
- package/docs/migration/database-changes-december-2025.md +2 -1
- package/docs/rbac/event-based-apps.md +124 -6
- package/docs/standards/README.md +39 -0
- package/docs/troubleshooting/migration.md +4 -4
- package/examples/PublicPages/PublicEventPage.tsx +1 -1
- package/package.json +11 -6
- package/scripts/audit-consuming-app.cjs +961 -0
- package/scripts/check-pace-core-compliance.cjs +315 -61
- package/scripts/install-cursor-rules.cjs +236 -0
- package/src/__tests__/helpers/test-providers.tsx +1 -1
- package/src/__tests__/helpers/test-utils.tsx +1 -1
- package/src/__tests__/rls-policies.test.ts +3 -1
- package/src/components/Badge/Badge.tsx +2 -4
- package/src/components/Button/Button.tsx +5 -4
- package/src/components/Calendar/Calendar.tsx +1 -1
- package/src/components/DataTable/DataTable.test.tsx +57 -93
- package/src/components/DataTable/DataTable.tsx +2 -2
- package/src/components/DataTable/__tests__/DataTable.default-state.test.tsx +172 -45
- package/src/components/DataTable/__tests__/DataTable.grouping-aggregation.test.tsx +121 -28
- package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +9 -8
- package/src/components/DataTable/__tests__/DataTableCore.test.tsx +20 -52
- package/src/components/DataTable/__tests__/a11y.basic.test.tsx +170 -34
- package/src/components/DataTable/__tests__/keyboard.test.tsx +75 -12
- package/src/components/DataTable/__tests__/pagination.modes.test.tsx +88 -16
- package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx +12 -12
- package/src/components/DataTable/components/AccessDeniedPage.tsx +1 -1
- package/src/components/DataTable/components/BulkOperationsDropdown.tsx +1 -1
- package/src/components/DataTable/components/DataTableCore.tsx +4 -7
- package/src/components/DataTable/components/DataTableModals.tsx +1 -1
- package/src/components/DataTable/components/EditableRow.tsx +1 -1
- package/src/components/DataTable/components/UnifiedTableBody.tsx +86 -17
- package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +23 -23
- package/src/components/DataTable/components/__tests__/EditableRow.test.tsx +11 -11
- package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +36 -36
- package/src/components/DataTable/components/__tests__/GroupHeader.test.tsx +27 -27
- package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +39 -39
- package/src/components/DataTable/components/__tests__/UnifiedTableBody.test.tsx +33 -33
- package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +29 -29
- package/src/components/DataTable/hooks/useColumnReordering.ts +2 -2
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +75 -10
- package/src/components/DataTable/hooks/useKeyboardNavigation.ts +2 -2
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +8 -14
- package/src/components/Dialog/Dialog.tsx +6 -5
- package/src/components/ErrorBoundary/ErrorBoundary.tsx +1 -1
- package/src/components/EventSelector/EventSelector.tsx +1 -1
- package/src/components/FileDisplay/FileDisplay.test.tsx +4 -3
- package/src/components/FileDisplay/FileDisplay.tsx +16 -4
- package/src/components/Footer/Footer.tsx +1 -1
- package/src/components/Form/Form.test.tsx +36 -15
- package/src/components/Form/Form.tsx +30 -26
- package/src/components/Header/Header.tsx +1 -1
- package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +40 -40
- package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +1 -1
- package/src/components/Input/Input.tsx +28 -30
- package/src/components/Label/Label.tsx +1 -1
- package/src/components/LoadingSpinner/LoadingSpinner.tsx +1 -1
- package/src/components/LoginForm/LoginForm.test.tsx +42 -42
- package/src/components/LoginForm/LoginForm.tsx +8 -8
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +6 -4
- package/src/components/NavigationMenu/NavigationMenu.tsx +2 -11
- package/src/components/OrganisationSelector/OrganisationSelector.tsx +0 -1
- package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +1 -1
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +75 -52
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +98 -69
- package/src/components/PaceAppLayout/README.md +1 -1
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +1 -8
- package/src/components/PasswordChange/PasswordChangeForm.test.tsx +33 -33
- package/src/components/PasswordChange/PasswordChangeForm.tsx +1 -1
- package/src/components/Progress/Progress.tsx +1 -1
- package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +5 -9
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +0 -1
- package/src/components/PublicLayout/PublicPageLayout.tsx +1 -1
- package/src/components/PublicLayout/PublicPageProvider.tsx +0 -1
- package/src/components/Select/Select.tsx +33 -22
- package/src/components/SessionRestorationLoader/SessionRestorationLoader.tsx +1 -1
- package/src/components/Table/Table.tsx +1 -1
- package/src/components/Textarea/Textarea.tsx +27 -29
- package/src/components/Toast/Toast.tsx +1 -1
- package/src/components/Tooltip/Tooltip.tsx +1 -1
- package/src/components/UserMenu/UserMenu.tsx +1 -1
- package/src/hooks/__tests__/hooks.integration.test.tsx +80 -55
- package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +14 -7
- package/src/hooks/__tests__/useStorage.unit.test.ts +36 -36
- package/src/hooks/public/usePublicEvent.ts +1 -1
- package/src/hooks/public/usePublicEventLogo.ts +1 -1
- package/src/hooks/public/usePublicRouteParams.ts +1 -1
- package/src/hooks/services/useAuthService.ts +21 -3
- package/src/hooks/services/useEventService.ts +21 -3
- package/src/hooks/services/useInactivityService.ts +21 -3
- package/src/hooks/services/useOrganisationService.ts +21 -3
- package/src/hooks/useDataTableState.ts +8 -18
- package/src/hooks/useFileDisplay.ts +10 -17
- package/src/hooks/useFocusManagement.ts +2 -2
- package/src/hooks/useFocusTrap.ts +4 -4
- package/src/hooks/useFormDialog.ts +8 -7
- package/src/hooks/useInactivityTracker.ts +1 -1
- package/src/hooks/usePermissionCache.ts +1 -1
- package/src/hooks/useSecureDataAccess.test.ts +16 -9
- package/src/hooks/useSecureDataAccess.ts +22 -6
- package/src/hooks/useToast.ts +2 -2
- package/src/providers/__tests__/OrganisationProvider.test.tsx +57 -13
- package/src/providers/__tests__/ProviderLifecycle.test.tsx +21 -6
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +10 -10
- package/src/providers/services/EventServiceProvider.tsx +0 -8
- package/src/providers/services/UnifiedAuthProvider.tsx +196 -46
- package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +13 -3
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +34 -40
- package/src/rbac/__tests__/isSuperAdmin.real.test.ts +82 -0
- package/src/rbac/adapters.tsx +3 -22
- package/src/rbac/api.test.ts +2 -2
- package/src/rbac/api.ts +7 -1
- package/src/rbac/components/EnhancedNavigationMenu.tsx +3 -16
- package/src/rbac/components/NavigationGuard.tsx +2 -11
- package/src/rbac/components/NavigationProvider.tsx +1 -2
- package/src/rbac/components/PagePermissionGuard.tsx +1 -1
- package/src/rbac/components/PagePermissionProvider.tsx +1 -1
- package/src/rbac/components/PermissionEnforcer.tsx +46 -13
- package/src/rbac/components/RoleBasedRouter.tsx +1 -1
- package/src/rbac/components/SecureDataProvider.tsx +1 -2
- package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +7 -43
- package/src/rbac/components/__tests__/NavigationGuard.test.tsx +4 -11
- package/src/rbac/components/__tests__/NavigationProvider.test.tsx +3 -3
- package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +1 -1
- package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +1 -1
- package/src/rbac/engine.ts +14 -2
- package/src/rbac/hooks/index.ts +0 -3
- package/src/rbac/hooks/usePermissions.ts +51 -11
- package/src/rbac/hooks/useRBAC.ts +3 -13
- package/src/rbac/hooks/useResolvedScope.test.ts +75 -54
- package/src/rbac/hooks/useResolvedScope.ts +58 -33
- package/src/rbac/hooks/useSecureSupabase.ts +4 -9
- package/src/rbac/secureClient.ts +43 -0
- package/src/services/EventService.ts +4 -57
- package/src/services/InactivityService.ts +127 -34
- package/src/services/OrganisationService.ts +68 -10
- package/src/utils/security/secureDataAccess.test.ts +31 -20
- package/src/utils/security/secureDataAccess.ts +4 -3
- package/dist/chunk-6C4YBBJM.js.map +0 -1
- package/dist/chunk-6LTQQAT6.js.map +0 -1
- package/dist/chunk-6TQDD426.js.map +0 -1
- package/dist/chunk-LOMZXPSN.js.map +0 -1
- package/dist/chunk-OETXORNB.js.map +0 -1
- package/dist/chunk-ULHIJK66.js.map +0 -1
- package/dist/chunk-VKB2CO4Z.js.map +0 -1
- package/dist/chunk-VRGWKHDB.js.map +0 -1
- package/dist/chunk-XNYQOL3Z.js.map +0 -1
- package/dist/chunk-XYXSXPUK.js.map +0 -1
- package/scripts/check-pace-core-compliance.js +0 -512
- package/src/rbac/hooks/useSuperAdminBypass.ts +0 -126
- package/src/utils/context/superAdminOverride.ts +0 -58
- /package/dist/{DataTable-WKRZD47S.js.map → DataTable-DQ7RSOHE.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-FTSG5XH7.js.map → UnifiedAuthProvider-ATAP5UTR.js.map} +0 -0
- /package/dist/{api-IHKALJZD.js.map → api-N774RPUA.js.map} +0 -0
- /package/dist/{chunk-QWWZ5CAQ.js.map → chunk-LXQLPRQ2.js.map} +0 -0
- /package/examples/{rbac → RBAC}/CompleteRBACExample.tsx +0 -0
- /package/examples/{rbac → RBAC}/EventBasedApp.tsx +0 -0
- /package/examples/{rbac → RBAC}/PermissionExample.tsx +0 -0
- /package/examples/{rbac → RBAC}/index.ts +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getAppConfigByName,
|
|
3
3
|
isSuperAdmin
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-KNC55RTG.js";
|
|
5
5
|
import {
|
|
6
6
|
assertOrganisationId,
|
|
7
7
|
assertUserId
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
} from "./chunk-PWLANIRT.js";
|
|
17
17
|
|
|
18
18
|
// src/providers/services/UnifiedAuthProvider.tsx
|
|
19
|
-
import { createContext as createContext5, useContext as useContext6, useMemo as useMemo6, useCallback, useRef as
|
|
19
|
+
import { createContext as createContext5, useContext as useContext6, useMemo as useMemo6, useCallback, useRef as useRef8, useEffect as useEffect10, useState as useState3, useReducer as useReducer5 } from "react";
|
|
20
20
|
|
|
21
21
|
// src/providers/services/AuthServiceProvider.tsx
|
|
22
22
|
import { createContext, useMemo, useEffect, useState } from "react";
|
|
@@ -627,6 +627,8 @@ var OrganisationService = class extends BaseService {
|
|
|
627
627
|
this._roleMapState = /* @__PURE__ */ new Map();
|
|
628
628
|
this._isLoading = false;
|
|
629
629
|
this._error = null;
|
|
630
|
+
this._isSuperAdmin = false;
|
|
631
|
+
// Cache super admin status
|
|
630
632
|
this._isContextReady = false;
|
|
631
633
|
this.retryCount = 0;
|
|
632
634
|
// Dependencies
|
|
@@ -667,14 +669,16 @@ var OrganisationService = class extends BaseService {
|
|
|
667
669
|
// Additional methods for testing
|
|
668
670
|
setSelectedOrganisation(organisation) {
|
|
669
671
|
if (organisation && this._organisations.length > 0) {
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
672
|
+
if (!this._isSuperAdmin) {
|
|
673
|
+
const isValidOrg = this._organisations.some((org) => org.id === organisation.id);
|
|
674
|
+
if (!isValidOrg) {
|
|
675
|
+
logger.warn("OrganisationService", "Attempted to set invalid organisation - not in user's accessible organisations", {
|
|
676
|
+
organisationId: organisation.id,
|
|
677
|
+
organisationName: organisation.name,
|
|
678
|
+
accessibleOrgIds: this._organisations.map((o) => o.id)
|
|
679
|
+
});
|
|
680
|
+
return;
|
|
681
|
+
}
|
|
678
682
|
}
|
|
679
683
|
}
|
|
680
684
|
this._selectedOrganisation = organisation;
|
|
@@ -713,6 +717,9 @@ var OrganisationService = class extends BaseService {
|
|
|
713
717
|
updateDependencies(user, session) {
|
|
714
718
|
const wasAuthenticated = !!(this.user && this.session);
|
|
715
719
|
const isAuthenticated = !!(user && session);
|
|
720
|
+
if (this.user?.id !== user?.id) {
|
|
721
|
+
this._isSuperAdmin = false;
|
|
722
|
+
}
|
|
716
723
|
this.user = user;
|
|
717
724
|
this.session = session;
|
|
718
725
|
if (wasAuthenticated && !isAuthenticated) {
|
|
@@ -936,10 +943,40 @@ var OrganisationService = class extends BaseService {
|
|
|
936
943
|
logger.error("OrganisationService", "Error loading organisation roles:", membershipError);
|
|
937
944
|
throw membershipError;
|
|
938
945
|
}
|
|
946
|
+
let userIsSuperAdmin = false;
|
|
947
|
+
if (this.user?.id) {
|
|
948
|
+
try {
|
|
949
|
+
userIsSuperAdmin = await isSuperAdmin(this.user.id);
|
|
950
|
+
this._isSuperAdmin = userIsSuperAdmin;
|
|
951
|
+
} catch (error) {
|
|
952
|
+
logger.warn("OrganisationService", "Failed to check super admin status", { error });
|
|
953
|
+
this._isSuperAdmin = false;
|
|
954
|
+
}
|
|
955
|
+
} else {
|
|
956
|
+
this._isSuperAdmin = false;
|
|
957
|
+
}
|
|
939
958
|
if (!memberships || memberships.length === 0) {
|
|
959
|
+
if (userIsSuperAdmin) {
|
|
960
|
+
this._organisations = [];
|
|
961
|
+
this._userMemberships = [];
|
|
962
|
+
this._isLoading = false;
|
|
963
|
+
this._error = null;
|
|
964
|
+
this._isContextReady = true;
|
|
965
|
+
this.notify();
|
|
966
|
+
return;
|
|
967
|
+
}
|
|
940
968
|
throw new Error("User has no active organisation memberships");
|
|
941
969
|
}
|
|
942
970
|
if (!organisations || organisations.length === 0) {
|
|
971
|
+
if (userIsSuperAdmin) {
|
|
972
|
+
this._organisations = [];
|
|
973
|
+
this._userMemberships = [];
|
|
974
|
+
this._isLoading = false;
|
|
975
|
+
this._error = null;
|
|
976
|
+
this._isContextReady = true;
|
|
977
|
+
this.notify();
|
|
978
|
+
return;
|
|
979
|
+
}
|
|
943
980
|
throw new Error("No organisations found in role data");
|
|
944
981
|
}
|
|
945
982
|
const roleMap = /* @__PURE__ */ new Map();
|
|
@@ -949,6 +986,15 @@ var OrganisationService = class extends BaseService {
|
|
|
949
986
|
const orgs = organisations;
|
|
950
987
|
const activeOrgs = orgs.filter((org) => org.is_active);
|
|
951
988
|
if (activeOrgs.length === 0) {
|
|
989
|
+
if (userIsSuperAdmin) {
|
|
990
|
+
this._organisations = [];
|
|
991
|
+
this._userMemberships = [];
|
|
992
|
+
this._isLoading = false;
|
|
993
|
+
this._error = null;
|
|
994
|
+
this._isContextReady = true;
|
|
995
|
+
this.notify();
|
|
996
|
+
return;
|
|
997
|
+
}
|
|
952
998
|
throw new Error("User has no access to active organisations");
|
|
953
999
|
}
|
|
954
1000
|
this._organisations = activeOrgs;
|
|
@@ -1149,10 +1195,6 @@ var EventService = class extends BaseService {
|
|
|
1149
1195
|
if (user?.id) {
|
|
1150
1196
|
try {
|
|
1151
1197
|
this.isSuperAdmin = await isSuperAdmin(user.id);
|
|
1152
|
-
logger.debug("EventService", "Updated super admin status", {
|
|
1153
|
-
userId: user.id,
|
|
1154
|
-
isSuperAdmin: this.isSuperAdmin
|
|
1155
|
-
});
|
|
1156
1198
|
} catch (error) {
|
|
1157
1199
|
logger.warn("EventService", "Failed to check super admin status", { error });
|
|
1158
1200
|
this.isSuperAdmin = false;
|
|
@@ -1176,7 +1218,7 @@ var EventService = class extends BaseService {
|
|
|
1176
1218
|
}
|
|
1177
1219
|
// Event state getters
|
|
1178
1220
|
getEvents() {
|
|
1179
|
-
return
|
|
1221
|
+
return this.events;
|
|
1180
1222
|
}
|
|
1181
1223
|
getSelectedEvent() {
|
|
1182
1224
|
return this.selectedEvent;
|
|
@@ -1286,31 +1328,16 @@ var EventService = class extends BaseService {
|
|
|
1286
1328
|
}
|
|
1287
1329
|
// Lifecycle methods
|
|
1288
1330
|
async initialize() {
|
|
1289
|
-
logger.debug("EventService", "initialize() called", {
|
|
1290
|
-
isInitializedRef: this.isInitializedRef,
|
|
1291
|
-
hasUser: !!this.user,
|
|
1292
|
-
hasSession: !!this.session,
|
|
1293
|
-
appName: this.appName
|
|
1294
|
-
});
|
|
1295
1331
|
await super.initialize();
|
|
1296
1332
|
}
|
|
1297
1333
|
cleanup() {
|
|
1298
1334
|
super.cleanup();
|
|
1299
1335
|
}
|
|
1300
1336
|
async doInitialize() {
|
|
1301
|
-
logger.debug("EventService", "doInitialize() called", {
|
|
1302
|
-
isInitializedRef: this.isInitializedRef,
|
|
1303
|
-
isFetchingRef: this.isFetchingRef,
|
|
1304
|
-
hasUser: !!this.user,
|
|
1305
|
-
hasSession: !!this.session,
|
|
1306
|
-
appName: this.appName
|
|
1307
|
-
});
|
|
1308
1337
|
if (this.isInitializedRef) {
|
|
1309
|
-
logger.debug("EventService", "Skipping initialization - already initialized");
|
|
1310
1338
|
return;
|
|
1311
1339
|
}
|
|
1312
1340
|
if (this.isFetchingRef) {
|
|
1313
|
-
logger.debug("EventService", "Skipping initialization - already fetching");
|
|
1314
1341
|
return;
|
|
1315
1342
|
}
|
|
1316
1343
|
try {
|
|
@@ -1321,14 +1348,8 @@ var EventService = class extends BaseService {
|
|
|
1321
1348
|
logger.warn("EventService", "Failed to clean up old storage keys:", error);
|
|
1322
1349
|
}
|
|
1323
1350
|
if (!this.user) {
|
|
1324
|
-
logger.debug("EventService", "Skipping initialization - missing user");
|
|
1325
1351
|
return;
|
|
1326
1352
|
}
|
|
1327
|
-
logger.debug("EventService", "Initializing - fetching events", {
|
|
1328
|
-
userId: this.user.id,
|
|
1329
|
-
organisationId: this.selectedOrganisation?.id || "derived-from-event",
|
|
1330
|
-
appName: this.appName
|
|
1331
|
-
});
|
|
1332
1353
|
await this.fetchEvents(false);
|
|
1333
1354
|
this.isInitializedRef = true;
|
|
1334
1355
|
}
|
|
@@ -1336,19 +1357,12 @@ var EventService = class extends BaseService {
|
|
|
1336
1357
|
}
|
|
1337
1358
|
async fetchEvents(skipLoadPersisted = false) {
|
|
1338
1359
|
if (!this.user || !this.session || !this.supabaseClient || !this.appName) {
|
|
1339
|
-
logger.debug("EventService", "Skipping fetchEvents - missing dependencies", {
|
|
1340
|
-
hasUser: !!this.user,
|
|
1341
|
-
hasSession: !!this.session,
|
|
1342
|
-
hasSupabaseClient: !!this.supabaseClient,
|
|
1343
|
-
appName: this.appName
|
|
1344
|
-
});
|
|
1345
1360
|
this.notify();
|
|
1346
1361
|
return;
|
|
1347
1362
|
}
|
|
1348
1363
|
this._isLoading = true;
|
|
1349
1364
|
this.notify();
|
|
1350
1365
|
if (this.isFetchingRef) {
|
|
1351
|
-
logger.debug("EventService", "Skipping fetchEvents - already fetching");
|
|
1352
1366
|
return;
|
|
1353
1367
|
}
|
|
1354
1368
|
this.isFetchingRef = true;
|
|
@@ -1370,18 +1384,11 @@ var EventService = class extends BaseService {
|
|
|
1370
1384
|
userIsSuperAdmin = await isSuperAdmin(this.user.id);
|
|
1371
1385
|
if (userIsSuperAdmin) {
|
|
1372
1386
|
organisationIdForRpc = null;
|
|
1373
|
-
logger.debug("EventService", "Super admin detected - fetching all events", {
|
|
1374
|
-
userId: this.user.id
|
|
1375
|
-
});
|
|
1376
1387
|
} else {
|
|
1377
1388
|
if (this.selectedEvent) {
|
|
1378
1389
|
organisationIdForRpc = this.selectedEvent.organisation_id;
|
|
1379
1390
|
} else if (this.appConfig?.requires_event === true) {
|
|
1380
1391
|
organisationIdForRpc = null;
|
|
1381
|
-
logger.debug("EventService", "Event-required app: fetching all accessible events (no event selected yet)", {
|
|
1382
|
-
userId: this.user.id,
|
|
1383
|
-
appName: this.appName
|
|
1384
|
-
});
|
|
1385
1392
|
} else if (this.selectedOrganisation) {
|
|
1386
1393
|
organisationIdForRpc = this.selectedOrganisation.id;
|
|
1387
1394
|
} else {
|
|
@@ -1405,22 +1412,11 @@ var EventService = class extends BaseService {
|
|
|
1405
1412
|
organisationIdForRpc = this.selectedOrganisation.id;
|
|
1406
1413
|
}
|
|
1407
1414
|
}
|
|
1408
|
-
logger.debug("EventService", "Fetching events via RPC", {
|
|
1409
|
-
userId: this.user.id,
|
|
1410
|
-
organisationId: organisationIdForRpc,
|
|
1411
|
-
appName: this.appName
|
|
1412
|
-
});
|
|
1413
1415
|
let { data, error: rpcError } = await this.supabaseClient.rpc("data_user_events_get", {
|
|
1414
1416
|
p_user_id: this.user.id,
|
|
1415
1417
|
p_organisation_id: organisationIdForRpc,
|
|
1416
1418
|
p_app_name: this.appName
|
|
1417
1419
|
});
|
|
1418
|
-
logger.debug("EventService", "RPC response received", {
|
|
1419
|
-
hasData: !!data,
|
|
1420
|
-
dataLength: Array.isArray(data) ? data.length : "not array",
|
|
1421
|
-
hasError: !!rpcError,
|
|
1422
|
-
error: rpcError
|
|
1423
|
-
});
|
|
1424
1420
|
if (rpcError) {
|
|
1425
1421
|
logger.error("EventService", "RPC error fetching events:", rpcError);
|
|
1426
1422
|
throw new Error(rpcError.message || "Failed to fetch events");
|
|
@@ -1545,13 +1541,6 @@ function EventServiceProvider({
|
|
|
1545
1541
|
const updateAndInitialize = async () => {
|
|
1546
1542
|
initializingRef.current = true;
|
|
1547
1543
|
try {
|
|
1548
|
-
logger.debug("EventServiceProvider", "Updating dependencies and initializing", {
|
|
1549
|
-
hasUser: !!user,
|
|
1550
|
-
hasSession: !!session,
|
|
1551
|
-
appName,
|
|
1552
|
-
hasSelectedOrganisation: !!selectedOrganisation,
|
|
1553
|
-
organisationId: selectedOrganisation?.id
|
|
1554
|
-
});
|
|
1555
1544
|
await eventService.updateDependencies(supabaseClient, user, session, appName, selectedOrganisation, setSelectedEventId);
|
|
1556
1545
|
if (!isMounted) return;
|
|
1557
1546
|
await eventService.initialize().catch((error) => {
|
|
@@ -1694,12 +1683,19 @@ var InactivityService = class extends BaseService {
|
|
|
1694
1683
|
if (this.inactivityTracker) {
|
|
1695
1684
|
this.inactivityTracker.resetActivity();
|
|
1696
1685
|
}
|
|
1686
|
+
const prevIsIdle = this._isIdle;
|
|
1687
|
+
const prevShowWarning = this._showWarning;
|
|
1688
|
+
const prevShowInactivityWarning = this._showInactivityWarning;
|
|
1689
|
+
const prevInactivityTimeRemaining = this._inactivityTimeRemaining;
|
|
1690
|
+
const prevTimeRemaining = this._timeRemaining;
|
|
1697
1691
|
this._isIdle = false;
|
|
1698
1692
|
this._showWarning = false;
|
|
1699
1693
|
this._showInactivityWarning = false;
|
|
1700
1694
|
this._inactivityTimeRemaining = 0;
|
|
1701
1695
|
this._timeRemaining = this.idleTimeoutMs;
|
|
1702
|
-
this.
|
|
1696
|
+
if (prevIsIdle !== this._isIdle || prevShowWarning !== this._showWarning || prevShowInactivityWarning !== this._showInactivityWarning || prevInactivityTimeRemaining !== this._inactivityTimeRemaining || prevTimeRemaining !== this._timeRemaining) {
|
|
1697
|
+
this.notify();
|
|
1698
|
+
}
|
|
1703
1699
|
}
|
|
1704
1700
|
startTracking() {
|
|
1705
1701
|
if (this.inactivityTracker) {
|
|
@@ -1793,8 +1789,39 @@ var InactivityService = class extends BaseService {
|
|
|
1793
1789
|
let idleTimer = null;
|
|
1794
1790
|
let warningTimer = null;
|
|
1795
1791
|
let lastActivity = Date.now();
|
|
1796
|
-
|
|
1797
|
-
|
|
1792
|
+
let pollInterval = null;
|
|
1793
|
+
let prevIsIdle = false;
|
|
1794
|
+
let prevShowWarning = false;
|
|
1795
|
+
let prevShowInactivityWarning = false;
|
|
1796
|
+
let prevInactivityTimeRemaining = 0;
|
|
1797
|
+
let prevTimeRemaining = this.idleTimeoutMs;
|
|
1798
|
+
const pollInactivityState = () => {
|
|
1799
|
+
const now = Date.now();
|
|
1800
|
+
const timeSinceActivity = now - lastActivity;
|
|
1801
|
+
const timeUntilIdle = this.idleTimeoutMs - timeSinceActivity;
|
|
1802
|
+
const timeUntilWarning = this.idleTimeoutMs - this.warnBeforeMs - timeSinceActivity;
|
|
1803
|
+
const newIsIdle = timeSinceActivity >= this.idleTimeoutMs - this.warnBeforeMs;
|
|
1804
|
+
const newShowWarning = newIsIdle && timeSinceActivity < this.idleTimeoutMs;
|
|
1805
|
+
const newShowInactivityWarning = newShowWarning;
|
|
1806
|
+
const newInactivityTimeRemaining = newShowWarning ? Math.ceil((this.idleTimeoutMs - timeSinceActivity) / 1e3) : 0;
|
|
1807
|
+
const newTimeRemaining = Math.max(0, timeUntilIdle);
|
|
1808
|
+
const stateChanged = prevIsIdle !== newIsIdle || prevShowWarning !== newShowWarning || prevShowInactivityWarning !== newShowInactivityWarning || prevInactivityTimeRemaining !== newInactivityTimeRemaining || prevTimeRemaining !== newTimeRemaining;
|
|
1809
|
+
if (stateChanged) {
|
|
1810
|
+
this._isIdle = newIsIdle;
|
|
1811
|
+
this._showWarning = newShowWarning;
|
|
1812
|
+
this._showInactivityWarning = newShowInactivityWarning;
|
|
1813
|
+
this._inactivityTimeRemaining = newInactivityTimeRemaining;
|
|
1814
|
+
this._timeRemaining = newTimeRemaining;
|
|
1815
|
+
prevIsIdle = newIsIdle;
|
|
1816
|
+
prevShowWarning = newShowWarning;
|
|
1817
|
+
prevShowInactivityWarning = newShowInactivityWarning;
|
|
1818
|
+
prevInactivityTimeRemaining = newInactivityTimeRemaining;
|
|
1819
|
+
prevTimeRemaining = newTimeRemaining;
|
|
1820
|
+
this.notify();
|
|
1821
|
+
if (newIsIdle && timeSinceActivity >= this.idleTimeoutMs) {
|
|
1822
|
+
this.handleIdleLogout();
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1798
1825
|
if (idleTimer) {
|
|
1799
1826
|
clearTimeout(idleTimer);
|
|
1800
1827
|
idleTimer = null;
|
|
@@ -1803,42 +1830,48 @@ var InactivityService = class extends BaseService {
|
|
|
1803
1830
|
clearTimeout(warningTimer);
|
|
1804
1831
|
warningTimer = null;
|
|
1805
1832
|
}
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
this.notify();
|
|
1811
|
-
};
|
|
1812
|
-
const startIdleTimer = () => {
|
|
1813
|
-
if (idleTimer) {
|
|
1814
|
-
clearTimeout(idleTimer);
|
|
1833
|
+
if (!newIsIdle && timeUntilIdle > 0) {
|
|
1834
|
+
idleTimer = setTimeout(() => {
|
|
1835
|
+
pollInactivityState();
|
|
1836
|
+
}, Math.min(1e4, timeUntilIdle));
|
|
1815
1837
|
}
|
|
1816
|
-
|
|
1817
|
-
this._isIdle = true;
|
|
1818
|
-
this._showWarning = true;
|
|
1819
|
-
this.notify();
|
|
1838
|
+
if (newShowWarning && timeUntilIdle > 0) {
|
|
1820
1839
|
warningTimer = setTimeout(() => {
|
|
1821
1840
|
this.handleIdleLogout();
|
|
1822
|
-
},
|
|
1823
|
-
}
|
|
1841
|
+
}, timeUntilIdle);
|
|
1842
|
+
}
|
|
1824
1843
|
};
|
|
1825
|
-
const
|
|
1844
|
+
const resetTimers = () => {
|
|
1845
|
+
lastActivity = Date.now();
|
|
1846
|
+
if (idleTimer) {
|
|
1847
|
+
clearTimeout(idleTimer);
|
|
1848
|
+
idleTimer = null;
|
|
1849
|
+
}
|
|
1826
1850
|
if (warningTimer) {
|
|
1827
1851
|
clearTimeout(warningTimer);
|
|
1852
|
+
warningTimer = null;
|
|
1828
1853
|
}
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1854
|
+
this._showInactivityWarning = false;
|
|
1855
|
+
this._inactivityTimeRemaining = 0;
|
|
1856
|
+
this._isIdle = false;
|
|
1857
|
+
this._showWarning = false;
|
|
1858
|
+
prevIsIdle = false;
|
|
1859
|
+
prevShowWarning = false;
|
|
1860
|
+
prevShowInactivityWarning = false;
|
|
1861
|
+
prevInactivityTimeRemaining = 0;
|
|
1862
|
+
prevTimeRemaining = this.idleTimeoutMs;
|
|
1832
1863
|
};
|
|
1833
1864
|
const activityEvents = ["mousedown", "mousemove", "keypress", "scroll", "touchstart", "click"];
|
|
1834
1865
|
const handleActivity = () => {
|
|
1835
1866
|
resetTimers();
|
|
1836
|
-
startIdleTimer();
|
|
1837
1867
|
};
|
|
1838
1868
|
activityEvents.forEach((event) => {
|
|
1839
1869
|
document.addEventListener(event, handleActivity, true);
|
|
1840
1870
|
});
|
|
1841
|
-
|
|
1871
|
+
pollInterval = setInterval(() => {
|
|
1872
|
+
pollInactivityState();
|
|
1873
|
+
}, 1e4);
|
|
1874
|
+
pollInactivityState();
|
|
1842
1875
|
this.cleanupHandlers = () => {
|
|
1843
1876
|
if (idleTimer) {
|
|
1844
1877
|
clearTimeout(idleTimer);
|
|
@@ -1848,6 +1881,10 @@ var InactivityService = class extends BaseService {
|
|
|
1848
1881
|
clearTimeout(warningTimer);
|
|
1849
1882
|
warningTimer = null;
|
|
1850
1883
|
}
|
|
1884
|
+
if (pollInterval) {
|
|
1885
|
+
clearInterval(pollInterval);
|
|
1886
|
+
pollInterval = null;
|
|
1887
|
+
}
|
|
1851
1888
|
activityEvents.forEach((event) => {
|
|
1852
1889
|
document.removeEventListener(event, handleActivity, true);
|
|
1853
1890
|
});
|
|
@@ -1906,29 +1943,61 @@ function InactivityServiceProvider({
|
|
|
1906
1943
|
}
|
|
1907
1944
|
|
|
1908
1945
|
// src/hooks/services/useAuthService.ts
|
|
1909
|
-
import { useContext, useReducer, useEffect as useEffect5 } from "react";
|
|
1946
|
+
import { useContext, useReducer, useEffect as useEffect5, useRef as useRef4 } from "react";
|
|
1910
1947
|
function useAuthService() {
|
|
1911
1948
|
const context = useContext(AuthServiceContext);
|
|
1912
1949
|
if (!context) {
|
|
1913
1950
|
throw new Error("useAuthService must be used within AuthServiceProvider");
|
|
1914
1951
|
}
|
|
1915
1952
|
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
|
1953
|
+
const timeoutRef = useRef4(null);
|
|
1916
1954
|
useEffect5(() => {
|
|
1917
|
-
|
|
1955
|
+
const debouncedUpdate = () => {
|
|
1956
|
+
if (timeoutRef.current) {
|
|
1957
|
+
clearTimeout(timeoutRef.current);
|
|
1958
|
+
}
|
|
1959
|
+
timeoutRef.current = setTimeout(() => {
|
|
1960
|
+
forceUpdate();
|
|
1961
|
+
timeoutRef.current = null;
|
|
1962
|
+
}, 50);
|
|
1963
|
+
};
|
|
1964
|
+
const unsubscribe = context.authService.subscribe(debouncedUpdate);
|
|
1965
|
+
return () => {
|
|
1966
|
+
unsubscribe();
|
|
1967
|
+
if (timeoutRef.current) {
|
|
1968
|
+
clearTimeout(timeoutRef.current);
|
|
1969
|
+
}
|
|
1970
|
+
};
|
|
1918
1971
|
}, [context.authService]);
|
|
1919
1972
|
return context.authService;
|
|
1920
1973
|
}
|
|
1921
1974
|
|
|
1922
1975
|
// src/hooks/services/useOrganisationService.ts
|
|
1923
|
-
import { useContext as useContext2, useReducer as useReducer2, useEffect as useEffect6 } from "react";
|
|
1976
|
+
import { useContext as useContext2, useReducer as useReducer2, useEffect as useEffect6, useRef as useRef5 } from "react";
|
|
1924
1977
|
function useOrganisationService() {
|
|
1925
1978
|
const context = useContext2(OrganisationServiceContext);
|
|
1926
1979
|
if (!context) {
|
|
1927
1980
|
throw new Error("useOrganisationService must be used within OrganisationServiceProvider");
|
|
1928
1981
|
}
|
|
1929
1982
|
const [, forceUpdate] = useReducer2((x) => x + 1, 0);
|
|
1983
|
+
const timeoutRef = useRef5(null);
|
|
1930
1984
|
useEffect6(() => {
|
|
1931
|
-
|
|
1985
|
+
const debouncedUpdate = () => {
|
|
1986
|
+
if (timeoutRef.current) {
|
|
1987
|
+
clearTimeout(timeoutRef.current);
|
|
1988
|
+
}
|
|
1989
|
+
timeoutRef.current = setTimeout(() => {
|
|
1990
|
+
forceUpdate();
|
|
1991
|
+
timeoutRef.current = null;
|
|
1992
|
+
}, 50);
|
|
1993
|
+
};
|
|
1994
|
+
const unsubscribe = context.organisationService.subscribe(debouncedUpdate);
|
|
1995
|
+
return () => {
|
|
1996
|
+
unsubscribe();
|
|
1997
|
+
if (timeoutRef.current) {
|
|
1998
|
+
clearTimeout(timeoutRef.current);
|
|
1999
|
+
}
|
|
2000
|
+
};
|
|
1932
2001
|
}, [context.organisationService]);
|
|
1933
2002
|
return context.organisationService;
|
|
1934
2003
|
}
|
|
@@ -1957,29 +2026,61 @@ function useOrganisations() {
|
|
|
1957
2026
|
}
|
|
1958
2027
|
|
|
1959
2028
|
// src/hooks/services/useEventService.ts
|
|
1960
|
-
import { useContext as useContext3, useReducer as useReducer3, useEffect as useEffect7 } from "react";
|
|
2029
|
+
import { useContext as useContext3, useReducer as useReducer3, useEffect as useEffect7, useRef as useRef6 } from "react";
|
|
1961
2030
|
function useEventService() {
|
|
1962
2031
|
const context = useContext3(EventServiceContext);
|
|
1963
2032
|
if (!context) {
|
|
1964
2033
|
throw new Error("useEventService must be used within EventServiceProvider");
|
|
1965
2034
|
}
|
|
1966
2035
|
const [, forceUpdate] = useReducer3((x) => x + 1, 0);
|
|
2036
|
+
const timeoutRef = useRef6(null);
|
|
1967
2037
|
useEffect7(() => {
|
|
1968
|
-
|
|
2038
|
+
const debouncedUpdate = () => {
|
|
2039
|
+
if (timeoutRef.current) {
|
|
2040
|
+
clearTimeout(timeoutRef.current);
|
|
2041
|
+
}
|
|
2042
|
+
timeoutRef.current = setTimeout(() => {
|
|
2043
|
+
forceUpdate();
|
|
2044
|
+
timeoutRef.current = null;
|
|
2045
|
+
}, 50);
|
|
2046
|
+
};
|
|
2047
|
+
const unsubscribe = context.eventService.subscribe(debouncedUpdate);
|
|
2048
|
+
return () => {
|
|
2049
|
+
unsubscribe();
|
|
2050
|
+
if (timeoutRef.current) {
|
|
2051
|
+
clearTimeout(timeoutRef.current);
|
|
2052
|
+
}
|
|
2053
|
+
};
|
|
1969
2054
|
}, [context.eventService]);
|
|
1970
2055
|
return context.eventService;
|
|
1971
2056
|
}
|
|
1972
2057
|
|
|
1973
2058
|
// src/hooks/services/useInactivityService.ts
|
|
1974
|
-
import { useContext as useContext4, useReducer as useReducer4, useEffect as useEffect8 } from "react";
|
|
2059
|
+
import { useContext as useContext4, useReducer as useReducer4, useEffect as useEffect8, useRef as useRef7 } from "react";
|
|
1975
2060
|
function useInactivityService() {
|
|
1976
2061
|
const context = useContext4(InactivityServiceContext);
|
|
1977
2062
|
if (!context) {
|
|
1978
2063
|
throw new Error("useInactivityService must be used within InactivityServiceProvider");
|
|
1979
2064
|
}
|
|
1980
2065
|
const [, forceUpdate] = useReducer4((x) => x + 1, 0);
|
|
2066
|
+
const timeoutRef = useRef7(null);
|
|
1981
2067
|
useEffect8(() => {
|
|
1982
|
-
|
|
2068
|
+
const debouncedUpdate = () => {
|
|
2069
|
+
if (timeoutRef.current) {
|
|
2070
|
+
clearTimeout(timeoutRef.current);
|
|
2071
|
+
}
|
|
2072
|
+
timeoutRef.current = setTimeout(() => {
|
|
2073
|
+
forceUpdate();
|
|
2074
|
+
timeoutRef.current = null;
|
|
2075
|
+
}, 50);
|
|
2076
|
+
};
|
|
2077
|
+
const unsubscribe = context.inactivityService.subscribe(debouncedUpdate);
|
|
2078
|
+
return () => {
|
|
2079
|
+
unsubscribe();
|
|
2080
|
+
if (timeoutRef.current) {
|
|
2081
|
+
clearTimeout(timeoutRef.current);
|
|
2082
|
+
}
|
|
2083
|
+
};
|
|
1983
2084
|
}, [context.inactivityService]);
|
|
1984
2085
|
return context.inactivityService;
|
|
1985
2086
|
}
|
|
@@ -2037,8 +2138,7 @@ var useUnifiedAuth = () => {
|
|
|
2037
2138
|
function UnifiedAuthContextProvider({
|
|
2038
2139
|
children,
|
|
2039
2140
|
appName,
|
|
2040
|
-
appConfig
|
|
2041
|
-
// Default to requiring events
|
|
2141
|
+
appConfig: appConfigProp,
|
|
2042
2142
|
supabaseClient: supabaseClientProp,
|
|
2043
2143
|
...props
|
|
2044
2144
|
}) {
|
|
@@ -2058,6 +2158,13 @@ function UnifiedAuthContextProvider({
|
|
|
2058
2158
|
restorationComplete,
|
|
2059
2159
|
restorationError
|
|
2060
2160
|
}), [isRestoring, restorationComplete, restorationError]);
|
|
2161
|
+
const [appConfigState, setAppConfigState] = useState3(appConfigProp || null);
|
|
2162
|
+
const isResolvingAppConfigRef = useRef8(false);
|
|
2163
|
+
const resolvedAppConfigRef = useRef8(null);
|
|
2164
|
+
const appConfig = useMemo6(() => {
|
|
2165
|
+
if (!appConfigState) return null;
|
|
2166
|
+
return { requires_event: appConfigState.requires_event };
|
|
2167
|
+
}, [appConfigState?.requires_event]);
|
|
2061
2168
|
let eventService;
|
|
2062
2169
|
try {
|
|
2063
2170
|
eventService = useEventService();
|
|
@@ -2081,9 +2188,9 @@ function UnifiedAuthContextProvider({
|
|
|
2081
2188
|
const isAuth = !!(currentUser && currentSession);
|
|
2082
2189
|
const supabase = useMemo6(() => supabaseClientProp, [supabaseClientProp]);
|
|
2083
2190
|
const [appId, setAppId] = useState3(void 0);
|
|
2084
|
-
const isResolvingAppIdRef =
|
|
2085
|
-
const resolvedAppIdRef =
|
|
2086
|
-
const resolvedUserIdRef =
|
|
2191
|
+
const isResolvingAppIdRef = useRef8(false);
|
|
2192
|
+
const resolvedAppIdRef = useRef8(void 0);
|
|
2193
|
+
const resolvedUserIdRef = useRef8(void 0);
|
|
2087
2194
|
useEffect10(() => {
|
|
2088
2195
|
if (!isAuth) {
|
|
2089
2196
|
resolvedAppIdRef.current = void 0;
|
|
@@ -2103,7 +2210,7 @@ function UnifiedAuthContextProvider({
|
|
|
2103
2210
|
resolvedUserIdRef.current = currentUserId;
|
|
2104
2211
|
const userId = currentUserId;
|
|
2105
2212
|
const appNameValue = appName;
|
|
2106
|
-
import("./api-
|
|
2213
|
+
import("./api-N774RPUA.js").then(async ({ resolveAppContext, setupRBAC }) => {
|
|
2107
2214
|
try {
|
|
2108
2215
|
setupRBAC(supabase);
|
|
2109
2216
|
const result = await resolveAppContext({
|
|
@@ -2113,10 +2220,6 @@ function UnifiedAuthContextProvider({
|
|
|
2113
2220
|
if (result?.appId) {
|
|
2114
2221
|
resolvedAppIdRef.current = result.appId;
|
|
2115
2222
|
setAppId(result.appId);
|
|
2116
|
-
logger.debug("UnifiedAuthProvider", "appId resolved on login", {
|
|
2117
|
-
appId: result.appId,
|
|
2118
|
-
appName: appNameValue
|
|
2119
|
-
});
|
|
2120
2223
|
} else {
|
|
2121
2224
|
resolvedUserIdRef.current = void 0;
|
|
2122
2225
|
}
|
|
@@ -2137,8 +2240,59 @@ function UnifiedAuthContextProvider({
|
|
|
2137
2240
|
});
|
|
2138
2241
|
}
|
|
2139
2242
|
}, [isAuth, currentUser?.id, supabase, appName]);
|
|
2243
|
+
useEffect10(() => {
|
|
2244
|
+
if (appConfigProp !== void 0) {
|
|
2245
|
+
setAppConfigState(appConfigProp);
|
|
2246
|
+
resolvedAppConfigRef.current = appConfigProp;
|
|
2247
|
+
return;
|
|
2248
|
+
}
|
|
2249
|
+
if (resolvedAppConfigRef.current !== null || isResolvingAppConfigRef.current) {
|
|
2250
|
+
return;
|
|
2251
|
+
}
|
|
2252
|
+
if (!supabase || !appName) {
|
|
2253
|
+
return;
|
|
2254
|
+
}
|
|
2255
|
+
isResolvingAppConfigRef.current = true;
|
|
2256
|
+
import("./api-N774RPUA.js").then(async ({ getAppConfigByName: getAppConfigByName2 }) => {
|
|
2257
|
+
try {
|
|
2258
|
+
const config = await getAppConfigByName2(appName);
|
|
2259
|
+
const resolvedConfig = config || { requires_event: false };
|
|
2260
|
+
if (resolvedAppConfigRef.current?.requires_event !== resolvedConfig.requires_event) {
|
|
2261
|
+
resolvedAppConfigRef.current = resolvedConfig;
|
|
2262
|
+
setAppConfigState(resolvedConfig);
|
|
2263
|
+
}
|
|
2264
|
+
if (import.meta.env.DEV && appName === "MINT") {
|
|
2265
|
+
logger.debug("UnifiedAuthProvider", "App config loaded", {
|
|
2266
|
+
appName,
|
|
2267
|
+
config: resolvedConfig,
|
|
2268
|
+
requiresEvent: resolvedConfig.requires_event
|
|
2269
|
+
});
|
|
2270
|
+
}
|
|
2271
|
+
} catch (error) {
|
|
2272
|
+
logger.warn("UnifiedAuthProvider", "Failed to load app config, defaulting to organisation-based", {
|
|
2273
|
+
error: error instanceof Error ? error.message : String(error),
|
|
2274
|
+
appName
|
|
2275
|
+
});
|
|
2276
|
+
if (resolvedAppConfigRef.current?.requires_event !== false) {
|
|
2277
|
+
const defaultConfig = { requires_event: false };
|
|
2278
|
+
resolvedAppConfigRef.current = defaultConfig;
|
|
2279
|
+
setAppConfigState(defaultConfig);
|
|
2280
|
+
}
|
|
2281
|
+
} finally {
|
|
2282
|
+
isResolvingAppConfigRef.current = false;
|
|
2283
|
+
}
|
|
2284
|
+
}).catch((importError) => {
|
|
2285
|
+
logger.error("UnifiedAuthProvider", "Failed to import RBAC API for app config", importError);
|
|
2286
|
+
isResolvingAppConfigRef.current = false;
|
|
2287
|
+
if (resolvedAppConfigRef.current?.requires_event !== false) {
|
|
2288
|
+
const defaultConfig = { requires_event: false };
|
|
2289
|
+
resolvedAppConfigRef.current = defaultConfig;
|
|
2290
|
+
setAppConfigState(defaultConfig);
|
|
2291
|
+
}
|
|
2292
|
+
});
|
|
2293
|
+
}, [supabase, appName, appConfigProp]);
|
|
2140
2294
|
const [, forceUpdate] = useReducer5((x) => x + 1, 0);
|
|
2141
|
-
const forceUpdateTimeoutRef =
|
|
2295
|
+
const forceUpdateTimeoutRef = useRef8(null);
|
|
2142
2296
|
const debouncedForceUpdate = useCallback(() => {
|
|
2143
2297
|
if (forceUpdateTimeoutRef.current) {
|
|
2144
2298
|
clearTimeout(forceUpdateTimeoutRef.current);
|
|
@@ -2146,12 +2300,12 @@ function UnifiedAuthContextProvider({
|
|
|
2146
2300
|
forceUpdateTimeoutRef.current = setTimeout(() => {
|
|
2147
2301
|
forceUpdate();
|
|
2148
2302
|
forceUpdateTimeoutRef.current = null;
|
|
2149
|
-
},
|
|
2303
|
+
}, 100);
|
|
2150
2304
|
}, [forceUpdate]);
|
|
2151
|
-
const authServiceRef =
|
|
2152
|
-
const organisationServiceRef =
|
|
2153
|
-
const eventServiceRef =
|
|
2154
|
-
const inactivityServiceRef =
|
|
2305
|
+
const authServiceRef = useRef8(authService);
|
|
2306
|
+
const organisationServiceRef = useRef8(organisationService);
|
|
2307
|
+
const eventServiceRef = useRef8(eventService);
|
|
2308
|
+
const inactivityServiceRef = useRef8(inactivityService);
|
|
2155
2309
|
useEffect10(() => {
|
|
2156
2310
|
authServiceRef.current = authService;
|
|
2157
2311
|
organisationServiceRef.current = organisationService;
|
|
@@ -2177,16 +2331,48 @@ function UnifiedAuthContextProvider({
|
|
|
2177
2331
|
const orgLoading = organisationService.isLoading();
|
|
2178
2332
|
const eventLoading = eventService.isLoading();
|
|
2179
2333
|
const restorationLoading = sessionRestoration.isRestoring && !sessionRestorationTimedOut && !sessionRestoration.restorationError;
|
|
2180
|
-
const
|
|
2334
|
+
const shouldIncludeOrgLoading = appName !== "ADMIN" && appName !== "PORTAL";
|
|
2335
|
+
const totalLoading = restorationLoading || authLoading || (shouldIncludeOrgLoading ? orgLoading : false) || eventLoading;
|
|
2181
2336
|
const authError = authService.getError();
|
|
2182
2337
|
const rawSelectedOrganisation = organisationService.getSelectedOrganisation();
|
|
2183
|
-
const organisations = organisationService.getOrganisations();
|
|
2184
|
-
const userMemberships = organisationService.getUserMemberships();
|
|
2185
2338
|
const organisationError = organisationService.getError();
|
|
2186
|
-
const selectedOrganisation = appConfig?.requires_event ? null : rawSelectedOrganisation;
|
|
2339
|
+
const selectedOrganisation = appConfig !== null && appConfig?.requires_event === true && !rawSelectedOrganisation ? null : rawSelectedOrganisation;
|
|
2340
|
+
useEffect10(() => {
|
|
2341
|
+
if (import.meta.env.DEV && appName === "MINT") {
|
|
2342
|
+
logger.debug("UnifiedAuthProvider", "Organisation state check", {
|
|
2343
|
+
rawSelectedOrganisation: rawSelectedOrganisation?.id || null,
|
|
2344
|
+
rawSelectedOrganisationType: typeof rawSelectedOrganisation,
|
|
2345
|
+
appConfig,
|
|
2346
|
+
appConfigRequiresEvent: appConfig?.requires_event,
|
|
2347
|
+
selectedOrganisation: selectedOrganisation?.id || null,
|
|
2348
|
+
selectedOrganisationId: selectedOrganisation?.id || null,
|
|
2349
|
+
checkResult: appConfig?.requires_event === true
|
|
2350
|
+
});
|
|
2351
|
+
}
|
|
2352
|
+
}, [appName, rawSelectedOrganisation?.id, appConfig?.requires_event, selectedOrganisation?.id]);
|
|
2187
2353
|
const hasValidOrganisationContext = organisationService.hasValidOrganisationContext();
|
|
2188
2354
|
const isContextReady = organisationService.isContextReady();
|
|
2189
|
-
const
|
|
2355
|
+
const rawEvents = eventService.getEvents();
|
|
2356
|
+
const rawOrganisations = organisationService.getOrganisations();
|
|
2357
|
+
const rawUserMemberships = organisationService.getUserMemberships();
|
|
2358
|
+
const events = useMemo6(() => {
|
|
2359
|
+
return rawEvents;
|
|
2360
|
+
}, [
|
|
2361
|
+
// Create dependency string from event IDs - only changes when events actually change
|
|
2362
|
+
rawEvents.map((e) => e.event_id || e.id).join(",")
|
|
2363
|
+
]);
|
|
2364
|
+
const organisations = useMemo6(() => {
|
|
2365
|
+
return rawOrganisations;
|
|
2366
|
+
}, [
|
|
2367
|
+
// Create dependency string from organisation IDs - only changes when orgs actually change
|
|
2368
|
+
rawOrganisations.map((o) => o.id).join(",")
|
|
2369
|
+
]);
|
|
2370
|
+
const userMemberships = useMemo6(() => {
|
|
2371
|
+
return rawUserMemberships;
|
|
2372
|
+
}, [
|
|
2373
|
+
// Create dependency string from membership IDs - only changes when memberships actually change
|
|
2374
|
+
rawUserMemberships.map((m) => `${m.organisation_id}-${m.user_id}`).join(",")
|
|
2375
|
+
]);
|
|
2190
2376
|
const selectedEvent = eventService.getSelectedEvent();
|
|
2191
2377
|
const eventError = eventService.getError();
|
|
2192
2378
|
const showInactivityWarning = inactivityService.getShowInactivityWarning();
|
|
@@ -2195,29 +2381,44 @@ function UnifiedAuthContextProvider({
|
|
|
2195
2381
|
const timeRemaining = inactivityService.getTimeRemaining();
|
|
2196
2382
|
const showWarning = inactivityService.isWarningShown();
|
|
2197
2383
|
const isTracking = inactivityService.isTracking();
|
|
2384
|
+
const inactivityState = useMemo6(() => ({
|
|
2385
|
+
showInactivityWarning,
|
|
2386
|
+
inactivityTimeRemaining,
|
|
2387
|
+
isIdle,
|
|
2388
|
+
timeRemaining,
|
|
2389
|
+
showWarning,
|
|
2390
|
+
isTracking
|
|
2391
|
+
}), [
|
|
2392
|
+
showInactivityWarning,
|
|
2393
|
+
inactivityTimeRemaining,
|
|
2394
|
+
isIdle,
|
|
2395
|
+
timeRemaining,
|
|
2396
|
+
showWarning,
|
|
2397
|
+
isTracking
|
|
2398
|
+
]);
|
|
2198
2399
|
const hasErrors = !!(authError || organisationError || eventError || sessionRestoration.restorationError);
|
|
2199
|
-
const signIn =
|
|
2200
|
-
const signUp =
|
|
2201
|
-
const signOut =
|
|
2202
|
-
const resetPassword =
|
|
2203
|
-
const updatePassword =
|
|
2204
|
-
const refreshSession =
|
|
2205
|
-
const switchOrganisation =
|
|
2206
|
-
const getUserRole =
|
|
2207
|
-
const validateOrganisationAccess =
|
|
2208
|
-
const refreshOrganisations =
|
|
2209
|
-
const ensureOrganisationContext =
|
|
2210
|
-
const isOrganisationSecure =
|
|
2211
|
-
const getPrimaryOrganisation =
|
|
2212
|
-
const setSelectedEvent =
|
|
2213
|
-
const refreshEvents =
|
|
2214
|
-
const resetActivity =
|
|
2215
|
-
const startTracking =
|
|
2216
|
-
const stopTracking =
|
|
2217
|
-
const handleIdleLogout =
|
|
2218
|
-
const handleStaySignedIn =
|
|
2219
|
-
const handleSignOutNow =
|
|
2220
|
-
const prevStateRef =
|
|
2400
|
+
const signIn = (email, password) => authService.signIn(email, password);
|
|
2401
|
+
const signUp = (email, password) => authService.signUp(email, password);
|
|
2402
|
+
const signOut = () => authService.signOut();
|
|
2403
|
+
const resetPassword = (email) => authService.resetPassword(email);
|
|
2404
|
+
const updatePassword = (password) => authService.updatePassword(password);
|
|
2405
|
+
const refreshSession = () => authService.refreshSession();
|
|
2406
|
+
const switchOrganisation = (orgId) => organisationService.switchOrganisation(orgId);
|
|
2407
|
+
const getUserRole = (orgId) => organisationService.getUserRole(orgId);
|
|
2408
|
+
const validateOrganisationAccess = (orgId) => organisationService.validateOrganisationAccess(orgId);
|
|
2409
|
+
const refreshOrganisations = () => organisationService.refreshOrganisations();
|
|
2410
|
+
const ensureOrganisationContext = () => organisationService.ensureOrganisationContext();
|
|
2411
|
+
const isOrganisationSecure = () => organisationService.isOrganisationSecure();
|
|
2412
|
+
const getPrimaryOrganisation = () => organisationService.getPrimaryOrganisation();
|
|
2413
|
+
const setSelectedEvent = (event) => eventService.setSelectedEvent(event);
|
|
2414
|
+
const refreshEvents = () => eventService.refreshEvents();
|
|
2415
|
+
const resetActivity = () => inactivityService.resetActivity();
|
|
2416
|
+
const startTracking = () => inactivityService.startTracking();
|
|
2417
|
+
const stopTracking = () => inactivityService.stopTracking();
|
|
2418
|
+
const handleIdleLogout = () => inactivityService.handleIdleLogout();
|
|
2419
|
+
const handleStaySignedIn = () => inactivityService.handleStaySignedIn();
|
|
2420
|
+
const handleSignOutNow = () => inactivityService.handleSignOutNow();
|
|
2421
|
+
const prevStateRef = useRef8(null);
|
|
2221
2422
|
const isDev = import.meta.env.DEV || import.meta.env.MODE === "development";
|
|
2222
2423
|
if (isDev) {
|
|
2223
2424
|
const currentState = {
|
|
@@ -2248,6 +2449,7 @@ function UnifiedAuthContextProvider({
|
|
|
2248
2449
|
refreshSession,
|
|
2249
2450
|
// Organisation state
|
|
2250
2451
|
selectedOrganisation,
|
|
2452
|
+
selectedOrganisationId: selectedOrganisation?.id || null,
|
|
2251
2453
|
organisations,
|
|
2252
2454
|
userMemberships,
|
|
2253
2455
|
organisationLoading: orgLoading,
|
|
@@ -2265,18 +2467,19 @@ function UnifiedAuthContextProvider({
|
|
|
2265
2467
|
// Event state
|
|
2266
2468
|
events,
|
|
2267
2469
|
selectedEvent,
|
|
2470
|
+
selectedEventId: selectedEvent?.event_id || null,
|
|
2268
2471
|
eventLoading,
|
|
2269
2472
|
eventError,
|
|
2270
2473
|
// Event methods
|
|
2271
2474
|
setSelectedEvent,
|
|
2272
2475
|
refreshEvents,
|
|
2273
2476
|
// Inactivity state
|
|
2274
|
-
showInactivityWarning,
|
|
2275
|
-
inactivityTimeRemaining,
|
|
2276
|
-
isIdle,
|
|
2277
|
-
timeRemaining,
|
|
2278
|
-
showWarning,
|
|
2279
|
-
isTracking,
|
|
2477
|
+
showInactivityWarning: inactivityState.showInactivityWarning,
|
|
2478
|
+
inactivityTimeRemaining: inactivityState.inactivityTimeRemaining,
|
|
2479
|
+
isIdle: inactivityState.isIdle,
|
|
2480
|
+
timeRemaining: inactivityState.timeRemaining,
|
|
2481
|
+
showWarning: inactivityState.showWarning,
|
|
2482
|
+
isTracking: inactivityState.isTracking,
|
|
2280
2483
|
// Inactivity methods
|
|
2281
2484
|
resetActivity,
|
|
2282
2485
|
startTracking,
|
|
@@ -2315,12 +2518,8 @@ function UnifiedAuthContextProvider({
|
|
|
2315
2518
|
selectedEvent,
|
|
2316
2519
|
eventLoading,
|
|
2317
2520
|
eventError,
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
isIdle,
|
|
2321
|
-
timeRemaining,
|
|
2322
|
-
showWarning,
|
|
2323
|
-
isTracking,
|
|
2521
|
+
inactivityState,
|
|
2522
|
+
// Use memoized object instead of individual values
|
|
2324
2523
|
totalLoading,
|
|
2325
2524
|
hasErrors,
|
|
2326
2525
|
appName,
|
|
@@ -2363,7 +2562,7 @@ function EventServiceProviderWrapper({
|
|
|
2363
2562
|
appConfig
|
|
2364
2563
|
}) {
|
|
2365
2564
|
const { selectedOrganisation: rawSelectedOrganisation } = useOrganisations();
|
|
2366
|
-
const selectedOrganisation = appConfig?.requires_event ? null : rawSelectedOrganisation;
|
|
2565
|
+
const selectedOrganisation = appConfig !== null && appConfig?.requires_event === true && !rawSelectedOrganisation ? null : rawSelectedOrganisation;
|
|
2367
2566
|
const setSelectedEventId = useCallback(() => {
|
|
2368
2567
|
}, []);
|
|
2369
2568
|
return /* @__PURE__ */ jsx5(
|
|
@@ -2459,7 +2658,7 @@ function UnifiedAuthProvider({
|
|
|
2459
2658
|
renderInactivityWarning,
|
|
2460
2659
|
dangerouslyDisableInactivity = false
|
|
2461
2660
|
}) {
|
|
2462
|
-
const clientRef =
|
|
2661
|
+
const clientRef = useRef8(supabaseClient);
|
|
2463
2662
|
useEffect10(() => {
|
|
2464
2663
|
if (clientRef.current !== supabaseClient) {
|
|
2465
2664
|
logger.warn("UnifiedAuthProvider", "Supabase client reference changed - this may indicate multiple client instances are being created", {
|
|
@@ -2508,4 +2707,4 @@ export {
|
|
|
2508
2707
|
useUnifiedAuth,
|
|
2509
2708
|
UnifiedAuthProvider
|
|
2510
2709
|
};
|
|
2511
|
-
//# sourceMappingURL=chunk-
|
|
2710
|
+
//# sourceMappingURL=chunk-BYFSK72L.js.map
|