@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.
- package/core-usage-manifest.json +0 -4
- package/dist/{AuthService-B-cd2MA4.d.ts → AuthService-CbP_utw2.d.ts} +7 -3
- package/dist/{DataTable-IVYljGJ6.d.ts → DataTable-Be6dH_dR.d.ts} +1 -1
- package/dist/{DataTable-GUFUNZ3N.js → DataTable-WKRZD47S.js} +8 -8
- package/dist/{PublicPageProvider-B8HaLe69.d.ts → PublicPageProvider-ULXC_u6U.d.ts} +84 -25
- package/dist/{UnifiedAuthProvider-BG0AL5eE.d.ts → UnifiedAuthProvider-BYA9qB-o.d.ts} +4 -3
- package/dist/{UnifiedAuthProvider-643PUAIM.js → UnifiedAuthProvider-FTSG5XH7.js} +4 -2
- package/dist/{api-YP7XD5L6.js → api-IHKALJZD.js} +4 -2
- package/dist/{chunk-VGZZXKBR.js → chunk-6LTQQAT6.js} +351 -157
- package/dist/chunk-6LTQQAT6.js.map +1 -0
- package/dist/{chunk-MX64ZF6I.js → chunk-6TQDD426.js} +15 -15
- package/dist/chunk-6TQDD426.js.map +1 -0
- package/dist/{chunk-YHCN776L.js → chunk-G37KK66H.js} +2 -75
- package/dist/chunk-G37KK66H.js.map +1 -0
- package/dist/{chunk-THRPYOFK.js → chunk-HW3OVDUF.js} +5 -5
- package/dist/chunk-HW3OVDUF.js.map +1 -0
- package/dist/{chunk-F2IMUDXZ.js → chunk-I7PSE6JW.js} +75 -2
- package/dist/chunk-I7PSE6JW.js.map +1 -0
- package/dist/{chunk-IM4QE42D.js → chunk-LOMZXPSN.js} +141 -326
- package/dist/chunk-LOMZXPSN.js.map +1 -0
- package/dist/chunk-OETXORNB.js +614 -0
- package/dist/chunk-OETXORNB.js.map +1 -0
- package/dist/{chunk-HESYZWZW.js → chunk-QWWZ5CAQ.js} +2 -2
- package/dist/{chunk-HEHYGYOX.js → chunk-ROXMHMY2.js} +403 -46
- package/dist/chunk-ROXMHMY2.js.map +1 -0
- package/dist/{chunk-2UUZZJFT.js → chunk-ULHIJK66.js} +228 -177
- package/dist/{chunk-2UUZZJFT.js.map → chunk-ULHIJK66.js.map} +1 -1
- package/dist/{chunk-YGPFYGA6.js → chunk-VKB2CO4Z.js} +838 -503
- package/dist/chunk-VKB2CO4Z.js.map +1 -0
- package/dist/{chunk-3GOZZZYH.js → chunk-VRGWKHDB.js} +238 -301
- package/dist/chunk-VRGWKHDB.js.map +1 -0
- package/dist/{chunk-UCQSRW7Z.js → chunk-XNYQOL3Z.js} +431 -384
- package/dist/chunk-XNYQOL3Z.js.map +1 -0
- package/dist/{chunk-DDM4CCYT.js → chunk-XYXSXPUK.js} +79 -59
- package/dist/chunk-XYXSXPUK.js.map +1 -0
- package/dist/{chunk-SAUPYVLF.js → chunk-ZSAAAMVR.js} +1 -1
- package/dist/chunk-ZSAAAMVR.js.map +1 -0
- package/dist/components.d.ts +5 -6
- package/dist/components.js +19 -19
- package/dist/components.js.map +1 -1
- package/dist/{database.generated-DI89OQeI.d.ts → database.generated-CzIvgcPu.d.ts} +165 -201
- package/dist/eslint-rules/pace-core-compliance.cjs +0 -2
- package/dist/{file-reference-D037xOFK.d.ts → file-reference-BavO2eQj.d.ts} +13 -10
- package/dist/hooks.d.ts +20 -15
- package/dist/hooks.js +14 -8
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +17 -15
- package/dist/index.js +86 -81
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +3 -3
- package/dist/providers.js +3 -1
- package/dist/rbac/index.d.ts +77 -13
- package/dist/rbac/index.js +12 -9
- package/dist/{types-Bwgl--Xo.d.ts → types-CEpcvwwF.d.ts} +1 -1
- package/dist/types.d.ts +3 -3
- package/dist/types.js +1 -1
- package/dist/{usePublicRouteParams-CTDELQ7H.d.ts → usePublicRouteParams-TZe0gy-4.d.ts} +17 -10
- package/dist/utils.d.ts +8 -8
- package/dist/utils.js +16 -16
- package/docs/README.md +2 -2
- package/docs/api/classes/ColumnFactory.md +1 -1
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.md +2 -2
- package/docs/api/classes/Logger.md +1 -1
- package/docs/api/classes/MissingUserContextError.md +2 -2
- package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
- package/docs/api/classes/PermissionDeniedError.md +1 -1
- package/docs/api/classes/RBACAuditManager.md +2 -2
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +5 -5
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +2 -2
- package/docs/api/classes/SecureSupabaseClient.md +25 -20
- package/docs/api/classes/StorageUtils.md +7 -4
- 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 +20 -6
- 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 +9 -9
- 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 +62 -16
- package/docs/api/interfaces/FileMetadata.md +1 -1
- package/docs/api/interfaces/FileReference.md +2 -2
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadOptions.md +26 -12
- package/docs/api/interfaces/FileUploadProps.md +30 -19
- 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 +10 -10
- package/docs/api/interfaces/NavigationContextType.md +9 -9
- 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 +7 -7
- 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 +8 -8
- package/docs/api/interfaces/PagePermissionContextType.md +8 -8
- package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
- package/docs/api/interfaces/PagePermissionProviderProps.md +7 -7
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/ParsedAddress.md +2 -2
- package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
- package/docs/api/interfaces/ProgressProps.md +3 -11
- 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 +1 -1
- 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 +1 -1
- package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
- package/docs/api/interfaces/RBACRolesListParams.md +1 -1
- package/docs/api/interfaces/RBACRolesListResult.md +1 -1
- 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 +8 -8
- package/docs/api/interfaces/RoleBasedRouterProps.md +10 -10
- package/docs/api/interfaces/RoleManagementResult.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +10 -10
- package/docs/api/interfaces/RouteConfig.md +10 -10
- package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
- package/docs/api/interfaces/SecureDataContextType.md +9 -9
- package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
- package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
- package/docs/api/interfaces/SetupIssue.md +1 -1
- package/docs/api/interfaces/StorageConfig.md +4 -4
- package/docs/api/interfaces/StorageFileInfo.md +7 -7
- package/docs/api/interfaces/StorageFileMetadata.md +25 -14
- package/docs/api/interfaces/StorageListOptions.md +22 -9
- package/docs/api/interfaces/StorageListResult.md +4 -4
- package/docs/api/interfaces/StorageUploadOptions.md +21 -8
- package/docs/api/interfaces/StorageUploadResult.md +6 -6
- package/docs/api/interfaces/StorageUrlOptions.md +19 -6
- 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 +53 -53
- 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 +5 -5
- package/docs/api/interfaces/UseResolvedScopeReturn.md +4 -4
- package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +11 -11
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +165 -106
- package/docs/api-reference/components.md +15 -7
- package/docs/api-reference/providers.md +2 -2
- package/docs/api-reference/rpc-functions.md +1 -0
- package/docs/best-practices/README.md +1 -1
- package/docs/best-practices/deployment.md +8 -8
- package/docs/getting-started/examples/README.md +2 -2
- package/docs/getting-started/installation-guide.md +4 -4
- package/docs/getting-started/quick-start.md +3 -3
- package/docs/migration/MIGRATION_GUIDE.md +3 -3
- package/docs/migration/README.md +18 -0
- package/docs/migration/database-changes-december-2025.md +767 -0
- package/docs/migration/person-scoped-profiles-migration-guide.md +472 -0
- package/docs/rbac/compliance/compliance-guide.md +2 -2
- package/docs/rbac/event-based-apps.md +2 -2
- package/docs/rbac/getting-started.md +2 -2
- package/docs/rbac/quick-start.md +2 -2
- package/docs/security/README.md +4 -4
- package/docs/standards/07-rbac-and-rls-standard.md +430 -7
- package/docs/troubleshooting/README.md +2 -2
- package/docs/troubleshooting/migration.md +3 -3
- package/package.json +1 -3
- package/scripts/check-pace-core-compliance.cjs +1 -1
- package/scripts/check-pace-core-compliance.js +1 -1
- package/src/__tests__/fixtures/supabase.ts +301 -0
- package/src/__tests__/public-recipe-view.test.ts +19 -19
- package/src/__tests__/rls-policies.test.ts +210 -74
- package/src/components/AddressField/AddressField.test.tsx +42 -0
- package/src/components/AddressField/AddressField.tsx +71 -60
- package/src/components/AddressField/README.md +7 -6
- package/src/components/Alert/Alert.test.tsx +50 -10
- package/src/components/Alert/Alert.tsx +5 -3
- package/src/components/Avatar/Avatar.test.tsx +95 -43
- package/src/components/Avatar/Avatar.tsx +16 -16
- package/src/components/Button/Button.test.tsx +2 -1
- package/src/components/Button/Button.tsx +3 -3
- package/src/components/Calendar/Calendar.test.tsx +53 -37
- package/src/components/Calendar/Calendar.tsx +409 -82
- package/src/components/Card/Card.test.tsx +7 -4
- package/src/components/Card/Card.tsx +3 -6
- package/src/components/Checkbox/Checkbox.tsx +2 -2
- package/src/components/DataTable/components/ActionButtons.tsx +5 -5
- package/src/components/DataTable/components/BulkOperationsDropdown.tsx +2 -2
- package/src/components/DataTable/components/ColumnFilter.tsx +1 -1
- package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +3 -3
- package/src/components/DataTable/components/DataTableBody.tsx +12 -12
- package/src/components/DataTable/components/DataTableCore.tsx +3 -3
- package/src/components/DataTable/components/DataTableToolbar.tsx +5 -5
- package/src/components/DataTable/components/DraggableColumnHeader.tsx +3 -3
- package/src/components/DataTable/components/EditableRow.tsx +2 -2
- package/src/components/DataTable/components/EmptyState.tsx +3 -3
- package/src/components/DataTable/components/GroupHeader.tsx +2 -2
- package/src/components/DataTable/components/GroupingDropdown.tsx +1 -1
- package/src/components/DataTable/components/ImportModal.tsx +4 -4
- package/src/components/DataTable/components/LoadingState.tsx +1 -1
- package/src/components/DataTable/components/PaginationControls.tsx +11 -11
- package/src/components/DataTable/components/UnifiedTableBody.tsx +9 -9
- package/src/components/DataTable/components/ViewRowModal.tsx +2 -2
- package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +11 -37
- package/src/components/DataTable/components/__tests__/DataTableToolbar.test.tsx +157 -0
- package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +2 -1
- package/src/components/DataTable/components/__tests__/VirtualizedDataTable.test.tsx +128 -0
- package/src/components/DataTable/core/__tests__/ActionManager.test.ts +19 -0
- package/src/components/DataTable/core/__tests__/ColumnFactory.test.ts +51 -0
- package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +84 -0
- package/src/components/DataTable/core/__tests__/DataManager.test.ts +14 -0
- package/src/components/DataTable/core/__tests__/DataTableContext.test.tsx +136 -0
- package/src/components/DataTable/core/__tests__/LocalDataAdapter.test.ts +16 -0
- package/src/components/DataTable/core/__tests__/PluginRegistry.test.ts +18 -0
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +28 -7
- package/src/components/DataTable/utils/__tests__/hierarchicalUtils.test.ts +30 -1
- package/src/components/DataTable/utils/hierarchicalUtils.ts +38 -10
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +8 -3
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +4 -4
- package/src/components/Dialog/Dialog.tsx +2 -2
- package/src/components/EventSelector/EventSelector.tsx +7 -7
- package/src/components/FileDisplay/FileDisplay.tsx +291 -179
- package/src/components/FileUpload/FileUpload.tsx +7 -4
- package/src/components/Header/Header.test.tsx +28 -0
- package/src/components/Header/Header.tsx +22 -9
- package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +2 -2
- package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +19 -14
- package/src/components/LoadingSpinner/LoadingSpinner.tsx +5 -5
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +127 -1
- package/src/components/OrganisationSelector/OrganisationSelector.tsx +42 -22
- package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +4 -0
- package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +3 -0
- package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +3 -0
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +16 -6
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +37 -3
- package/src/components/PaceAppLayout/test-setup.tsx +1 -0
- package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +66 -45
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +6 -4
- package/src/components/Progress/Progress.test.tsx +18 -19
- package/src/components/Progress/Progress.tsx +31 -32
- package/src/components/PublicLayout/PublicLayout.test.tsx +6 -6
- package/src/components/PublicLayout/PublicPageProvider.tsx +5 -3
- package/src/components/Select/Select.test.tsx +4 -1
- package/src/components/Select/Select.tsx +65 -20
- package/src/components/Switch/Switch.test.tsx +2 -1
- package/src/components/Switch/Switch.tsx +1 -1
- package/src/components/Toast/Toast.tsx +1 -1
- package/src/components/Tooltip/Tooltip.test.tsx +8 -2
- package/src/components/UserMenu/UserMenu.tsx +3 -3
- package/src/eslint-rules/pace-core-compliance.cjs +0 -2
- package/src/eslint-rules/pace-core-compliance.js +0 -2
- package/src/hooks/__tests__/hooks.integration.test.tsx +4 -1
- package/src/hooks/__tests__/useAppConfig.unit.test.ts +76 -5
- package/src/hooks/__tests__/useDataTableState.test.ts +76 -0
- package/src/hooks/__tests__/useFileUrl.unit.test.ts +25 -69
- package/src/hooks/__tests__/useFileUrlCache.test.ts +129 -0
- package/src/hooks/__tests__/usePreventTabReload.test.ts +88 -0
- package/src/hooks/__tests__/usePublicEvent.simple.test.ts +1 -1
- package/src/hooks/__tests__/usePublicEvent.test.ts +608 -0
- package/src/hooks/__tests__/useQueryCache.test.ts +144 -0
- package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +67 -24
- package/src/hooks/index.ts +1 -1
- package/src/hooks/public/usePublicEvent.ts +10 -10
- package/src/hooks/public/usePublicFileDisplay.ts +173 -87
- package/src/hooks/useAppConfig.ts +24 -5
- package/src/hooks/useFileDisplay.ts +298 -36
- package/src/hooks/useFileReference.ts +56 -11
- package/src/hooks/useFileUrl.ts +1 -1
- package/src/hooks/useInactivityTracker.ts +16 -7
- package/src/hooks/usePermissionCache.test.ts +85 -8
- package/src/hooks/useQueryCache.ts +27 -6
- package/src/hooks/useSecureDataAccess.test.ts +87 -42
- package/src/hooks/useSecureDataAccess.ts +95 -48
- package/src/providers/__tests__/OrganisationProvider.test.tsx +27 -21
- package/src/providers/services/EventServiceProvider.tsx +37 -17
- package/src/providers/services/InactivityServiceProvider.tsx +4 -4
- package/src/providers/services/OrganisationServiceProvider.tsx +8 -1
- package/src/providers/services/UnifiedAuthProvider.tsx +115 -29
- package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +451 -0
- package/src/rbac/__tests__/engine.comprehensive.test.ts +12 -0
- package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +8 -0
- package/src/rbac/__tests__/rbac-engine-simplified.test.ts +4 -0
- package/src/rbac/api.ts +240 -36
- package/src/rbac/cache-invalidation.ts +21 -7
- package/src/rbac/compliance/quick-fix-suggestions.ts +1 -1
- package/src/rbac/components/NavigationGuard.tsx +23 -63
- package/src/rbac/components/NavigationProvider.test.tsx +52 -23
- package/src/rbac/components/NavigationProvider.tsx +13 -11
- package/src/rbac/components/PagePermissionGuard.tsx +77 -203
- package/src/rbac/components/PagePermissionProvider.tsx +13 -11
- package/src/rbac/components/PermissionEnforcer.tsx +24 -62
- package/src/rbac/components/RoleBasedRouter.tsx +14 -12
- package/src/rbac/components/SecureDataProvider.tsx +13 -11
- package/src/rbac/components/__tests__/NavigationGuard.test.tsx +104 -41
- package/src/rbac/components/__tests__/NavigationProvider.test.tsx +49 -12
- package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +22 -1
- package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +161 -82
- package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +22 -1
- package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +77 -30
- package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +39 -5
- package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +47 -4
- package/src/rbac/engine.ts +4 -2
- package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +144 -52
- package/src/rbac/hooks/index.ts +3 -0
- package/src/rbac/hooks/useCan.test.ts +101 -53
- package/src/rbac/hooks/usePermissions.ts +108 -41
- package/src/rbac/hooks/useRBAC.test.ts +11 -3
- package/src/rbac/hooks/useRBAC.ts +83 -40
- package/src/rbac/hooks/useResolvedScope.test.ts +189 -63
- package/src/rbac/hooks/useResolvedScope.ts +128 -70
- package/src/rbac/hooks/useSecureSupabase.ts +36 -19
- package/src/rbac/hooks/useSuperAdminBypass.ts +126 -0
- package/src/rbac/request-deduplication.ts +1 -1
- package/src/rbac/secureClient.ts +72 -12
- package/src/rbac/security.ts +29 -23
- package/src/rbac/types.ts +10 -0
- package/src/rbac/utils/__tests__/contextValidator.test.ts +150 -0
- package/src/rbac/utils/__tests__/deep-equal.test.ts +53 -0
- package/src/rbac/utils/__tests__/eventContext.test.ts +8 -3
- package/src/rbac/utils/__tests__/eventContext.unit.test.ts +74 -12
- package/src/rbac/utils/contextValidator.ts +288 -0
- package/src/rbac/utils/eventContext.ts +52 -3
- package/src/services/AuthService.ts +37 -8
- package/src/services/EventService.ts +165 -21
- package/src/services/OrganisationService.ts +125 -137
- package/src/services/__tests__/EventService.test.ts +26 -21
- package/src/services/__tests__/OrganisationService.pagination.test.ts +34 -8
- package/src/services/__tests__/OrganisationService.test.ts +218 -86
- package/src/types/database.generated.ts +166 -201
- package/src/types/file-reference.ts +13 -10
- package/src/types/supabase.ts +2 -2
- package/src/utils/__tests__/secureDataAccess.unit.test.ts +3 -2
- package/src/utils/app/appNameResolver.test.ts +346 -73
- package/src/utils/context/superAdminOverride.ts +58 -0
- package/src/utils/file-reference/index.ts +65 -37
- package/src/utils/google-places/googlePlacesUtils.test.ts +98 -0
- package/src/utils/google-places/googlePlacesUtils.ts +1 -1
- package/src/utils/google-places/loadGoogleMapsScript.test.ts +83 -0
- package/src/utils/google-places/types.ts +1 -1
- package/src/utils/request-deduplication.ts +4 -4
- package/src/utils/security/secureDataAccess.test.ts +1 -1
- package/src/utils/security/secureDataAccess.ts +7 -4
- package/src/utils/storage/README.md +1 -1
- package/src/utils/storage/helpers.test.ts +1 -1
- package/src/utils/storage/helpers.ts +38 -19
- package/src/utils/storage/types.ts +15 -8
- package/src/utils/validation/__tests__/csrf.test.ts +105 -0
- package/src/utils/validation/__tests__/sqlInjectionProtection.test.ts +92 -0
- package/src/vite-env.d.ts +2 -2
- package/dist/chunk-3GOZZZYH.js.map +0 -1
- package/dist/chunk-DDM4CCYT.js.map +0 -1
- package/dist/chunk-E7UAOUMY.js +0 -75
- package/dist/chunk-E7UAOUMY.js.map +0 -1
- package/dist/chunk-F2IMUDXZ.js.map +0 -1
- package/dist/chunk-HEHYGYOX.js.map +0 -1
- package/dist/chunk-IM4QE42D.js.map +0 -1
- package/dist/chunk-MX64ZF6I.js.map +0 -1
- package/dist/chunk-SAUPYVLF.js.map +0 -1
- package/dist/chunk-THRPYOFK.js.map +0 -1
- package/dist/chunk-UCQSRW7Z.js.map +0 -1
- package/dist/chunk-VGZZXKBR.js.map +0 -1
- package/dist/chunk-YGPFYGA6.js.map +0 -1
- package/dist/chunk-YHCN776L.js.map +0 -1
- /package/dist/{DataTable-GUFUNZ3N.js.map → DataTable-WKRZD47S.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-643PUAIM.js.map → UnifiedAuthProvider-FTSG5XH7.js.map} +0 -0
- /package/dist/{api-YP7XD5L6.js.map → api-IHKALJZD.js.map} +0 -0
- /package/dist/{chunk-HESYZWZW.js.map → chunk-QWWZ5CAQ.js.map} +0 -0
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getAppConfigByName,
|
|
3
|
+
isSuperAdmin
|
|
4
|
+
} from "./chunk-ROXMHMY2.js";
|
|
1
5
|
import {
|
|
2
6
|
assertOrganisationId,
|
|
3
7
|
assertUserId
|
|
@@ -315,6 +319,8 @@ var AuthService = class extends BaseService {
|
|
|
315
319
|
// Lifecycle methods
|
|
316
320
|
async initialize() {
|
|
317
321
|
await super.initialize();
|
|
322
|
+
this.authLoading = true;
|
|
323
|
+
this.notify();
|
|
318
324
|
await this.setupAuthStateListener();
|
|
319
325
|
await this.restoreSession();
|
|
320
326
|
}
|
|
@@ -420,13 +426,15 @@ var AuthService = class extends BaseService {
|
|
|
420
426
|
const hasTimeoutError = this.sessionRestorationState.restorationError?.name === "SessionRestorationTimeoutError";
|
|
421
427
|
if (this.sessionRestorationState.isRestoring || this.sessionRestorationState.restorationError || hasTimeoutError && session) {
|
|
422
428
|
this.finishSessionRestoration();
|
|
423
|
-
|
|
429
|
+
}
|
|
430
|
+
} else {
|
|
431
|
+
if (this.sessionRestorationState.isRestoring) {
|
|
432
|
+
this.finishSessionRestoration();
|
|
424
433
|
}
|
|
425
434
|
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
}
|
|
435
|
+
this.authLoading = false;
|
|
436
|
+
this.notify();
|
|
437
|
+
return;
|
|
430
438
|
}
|
|
431
439
|
this.authLoading = false;
|
|
432
440
|
this.notify();
|
|
@@ -487,7 +495,12 @@ var AuthService = class extends BaseService {
|
|
|
487
495
|
this.user = null;
|
|
488
496
|
this.authError = null;
|
|
489
497
|
}
|
|
490
|
-
|
|
498
|
+
setTimeout(() => {
|
|
499
|
+
if (this.sessionRestorationState.isRestoring && !this.sessionRestorationState.restorationComplete) {
|
|
500
|
+
logger.debug("AuthService", "INITIAL_SESSION event did not fire, finishing restoration");
|
|
501
|
+
this.finishSessionRestoration();
|
|
502
|
+
}
|
|
503
|
+
}, 100);
|
|
491
504
|
} catch (error) {
|
|
492
505
|
const restorationError = error instanceof Error ? error : new Error("Unknown error during auth initialization");
|
|
493
506
|
logger.error("AuthService", "Error during auth initialization:", restorationError);
|
|
@@ -653,6 +666,17 @@ var OrganisationService = class extends BaseService {
|
|
|
653
666
|
}
|
|
654
667
|
// Additional methods for testing
|
|
655
668
|
setSelectedOrganisation(organisation) {
|
|
669
|
+
if (organisation && this._organisations.length > 0) {
|
|
670
|
+
const isValidOrg = this._organisations.some((org) => org.id === organisation.id);
|
|
671
|
+
if (!isValidOrg) {
|
|
672
|
+
logger.warn("OrganisationService", "Attempted to set invalid organisation - not in user's accessible organisations", {
|
|
673
|
+
organisationId: organisation.id,
|
|
674
|
+
organisationName: organisation.name,
|
|
675
|
+
accessibleOrgIds: this._organisations.map((o) => o.id)
|
|
676
|
+
});
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
656
680
|
this._selectedOrganisation = organisation;
|
|
657
681
|
if (organisation) {
|
|
658
682
|
localStorage.setItem("pace-core-selected-organisation", JSON.stringify(organisation));
|
|
@@ -844,118 +868,80 @@ var OrganisationService = class extends BaseService {
|
|
|
844
868
|
this._error = null;
|
|
845
869
|
this.notify();
|
|
846
870
|
try {
|
|
847
|
-
let memberships, membershipError;
|
|
871
|
+
let memberships, membershipError, organisations = [];
|
|
848
872
|
try {
|
|
849
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
850
|
-
const timeoutId = setTimeout(() => reject(new Error("RPC call timeout after 10 seconds")), 1e4);
|
|
851
|
-
abortSignal.addEventListener("abort", () => {
|
|
852
|
-
clearTimeout(timeoutId);
|
|
853
|
-
reject(new Error("Request aborted"));
|
|
854
|
-
});
|
|
855
|
-
});
|
|
856
|
-
const rpcPromise = this.supabaseClient.rpc("data_user_organisation_roles_get", {
|
|
857
|
-
p_user_id: this.user.id,
|
|
858
|
-
p_organisation_id: null
|
|
859
|
-
});
|
|
860
873
|
if (abortSignal.aborted) {
|
|
861
874
|
throw new Error("Request aborted");
|
|
862
875
|
}
|
|
863
|
-
const
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
876
|
+
const { data: rolesData, error: rolesError } = await this.supabaseClient.from("rbac_organisation_roles").select(`
|
|
877
|
+
id,
|
|
878
|
+
user_id,
|
|
879
|
+
organisation_id,
|
|
880
|
+
role,
|
|
881
|
+
status,
|
|
882
|
+
granted_at,
|
|
883
|
+
granted_by,
|
|
884
|
+
revoked_at,
|
|
885
|
+
revoked_by,
|
|
886
|
+
notes,
|
|
887
|
+
created_at,
|
|
888
|
+
updated_at,
|
|
889
|
+
core_organisations!inner(
|
|
890
|
+
id,
|
|
891
|
+
name,
|
|
892
|
+
display_name,
|
|
893
|
+
subscription_tier,
|
|
894
|
+
settings,
|
|
895
|
+
is_active,
|
|
896
|
+
parent_id,
|
|
897
|
+
created_at,
|
|
898
|
+
updated_at
|
|
899
|
+
)
|
|
900
|
+
`).eq("user_id", this.user.id).eq("status", "active").is("revoked_at", null);
|
|
901
|
+
if (rolesError) {
|
|
902
|
+
logger.error("OrganisationService", "Error loading organisation roles:", rolesError);
|
|
903
|
+
throw rolesError;
|
|
904
|
+
}
|
|
905
|
+
memberships = rolesData?.map((m) => ({
|
|
867
906
|
...m,
|
|
868
907
|
user_id: assertUserId(m.user_id),
|
|
869
908
|
organisation_id: assertOrganisationId(m.organisation_id)
|
|
870
909
|
})) || [];
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
role,
|
|
887
|
-
status,
|
|
888
|
-
granted_at,
|
|
889
|
-
granted_by,
|
|
890
|
-
revoked_at,
|
|
891
|
-
revoked_by,
|
|
892
|
-
notes,
|
|
893
|
-
created_at,
|
|
894
|
-
updated_at,
|
|
895
|
-
organisations!inner(
|
|
896
|
-
id,
|
|
897
|
-
name,
|
|
898
|
-
display_name,
|
|
899
|
-
subscription_tier,
|
|
900
|
-
settings,
|
|
901
|
-
is_active,
|
|
902
|
-
parent_id,
|
|
903
|
-
created_at,
|
|
904
|
-
updated_at
|
|
905
|
-
)
|
|
906
|
-
`).eq("user_id", this.user.id).eq("status", "active").is("revoked_at", null).in("role", ["org_admin", "leader", "member", "supporter"]);
|
|
907
|
-
if (fallbackError) {
|
|
908
|
-
logger.error("OrganisationService", "Fallback query also failed:", fallbackError);
|
|
909
|
-
throw membershipError;
|
|
910
|
-
}
|
|
911
|
-
memberships = fallbackData?.map((m) => ({
|
|
912
|
-
...m,
|
|
913
|
-
user_id: assertUserId(m.user_id),
|
|
914
|
-
organisation_id: assertOrganisationId(m.organisation_id)
|
|
915
|
-
})) || [];
|
|
916
|
-
membershipError = null;
|
|
917
|
-
} catch (fallbackErr) {
|
|
918
|
-
logger.error("OrganisationService", "Fallback query failed:", fallbackErr);
|
|
919
|
-
throw membershipError;
|
|
910
|
+
const organisationsMap = /* @__PURE__ */ new Map();
|
|
911
|
+
rolesData?.forEach((role) => {
|
|
912
|
+
const orgData = role.core_organisations;
|
|
913
|
+
if (orgData && role.organisation_id && !organisationsMap.has(role.organisation_id)) {
|
|
914
|
+
organisationsMap.set(role.organisation_id, {
|
|
915
|
+
id: orgData.id,
|
|
916
|
+
name: orgData.name,
|
|
917
|
+
display_name: orgData.display_name,
|
|
918
|
+
subscription_tier: orgData.subscription_tier,
|
|
919
|
+
settings: orgData.settings,
|
|
920
|
+
is_active: orgData.is_active,
|
|
921
|
+
parent_id: orgData.parent_id,
|
|
922
|
+
created_at: orgData.created_at,
|
|
923
|
+
updated_at: orgData.updated_at
|
|
924
|
+
});
|
|
920
925
|
}
|
|
926
|
+
});
|
|
927
|
+
organisations = Array.from(organisationsMap.values());
|
|
928
|
+
} catch (queryError) {
|
|
929
|
+
if (queryError instanceof Error) {
|
|
930
|
+
membershipError = queryError;
|
|
931
|
+
} else if (queryError && typeof queryError === "object" && "message" in queryError) {
|
|
932
|
+
membershipError = new Error(String(queryError.message));
|
|
921
933
|
} else {
|
|
922
|
-
|
|
934
|
+
membershipError = new Error(String(queryError));
|
|
923
935
|
}
|
|
936
|
+
logger.error("OrganisationService", "Error loading organisation roles:", membershipError);
|
|
937
|
+
throw membershipError;
|
|
924
938
|
}
|
|
925
939
|
if (!memberships || memberships.length === 0) {
|
|
926
940
|
throw new Error("User has no active organisation memberships");
|
|
927
941
|
}
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
logger.warn("OrganisationService", "Invalid organisation ID (not string):", id);
|
|
931
|
-
return false;
|
|
932
|
-
}
|
|
933
|
-
const trimmedId = id.trim();
|
|
934
|
-
if (trimmedId === "") {
|
|
935
|
-
logger.warn("OrganisationService", "Empty organisation ID found");
|
|
936
|
-
return false;
|
|
937
|
-
}
|
|
938
|
-
const isValidUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(trimmedId);
|
|
939
|
-
if (!isValidUuid) {
|
|
940
|
-
logger.warn("OrganisationService", "Invalid UUID format:", trimmedId);
|
|
941
|
-
}
|
|
942
|
-
return isValidUuid;
|
|
943
|
-
});
|
|
944
|
-
if (organisationIds.length === 0) {
|
|
945
|
-
logger.warn("OrganisationService", "No valid organisation IDs found in memberships:", memberships);
|
|
946
|
-
throw new Error("No valid organisation IDs found in memberships");
|
|
947
|
-
}
|
|
948
|
-
if (abortSignal.aborted) {
|
|
949
|
-
throw new Error("Request aborted");
|
|
950
|
-
}
|
|
951
|
-
const { data: allOrganisations, error: orgError } = await this.supabaseClient.from("organisations").select("id, name, display_name, subscription_tier, settings, is_active, parent_id, created_at, updated_at");
|
|
952
|
-
if (orgError) {
|
|
953
|
-
logger.error("OrganisationService", "Error loading organisations:", orgError);
|
|
954
|
-
throw orgError;
|
|
942
|
+
if (!organisations || organisations.length === 0) {
|
|
943
|
+
throw new Error("No organisations found in role data");
|
|
955
944
|
}
|
|
956
|
-
const organisations = allOrganisations?.filter(
|
|
957
|
-
(org) => organisationIds.includes(org.id)
|
|
958
|
-
) || [];
|
|
959
945
|
const roleMap = /* @__PURE__ */ new Map();
|
|
960
946
|
memberships?.forEach((membership) => {
|
|
961
947
|
roleMap.set(membership.organisation_id, membership.role);
|
|
@@ -980,16 +966,13 @@ var OrganisationService = class extends BaseService {
|
|
|
980
966
|
initialOrg = validPersistedOrg;
|
|
981
967
|
selectionMethod = "persisted";
|
|
982
968
|
} else {
|
|
983
|
-
logger.warn("OrganisationService", "Persisted organisation not found in active orgs, clearing cache");
|
|
984
969
|
localStorage.removeItem("pace-core-selected-organisation");
|
|
985
970
|
}
|
|
986
971
|
} else {
|
|
987
|
-
logger.warn("OrganisationService", "Invalid persisted organisation ID, clearing cache");
|
|
988
972
|
localStorage.removeItem("pace-core-selected-organisation");
|
|
989
973
|
}
|
|
990
974
|
}
|
|
991
975
|
} catch (storageError) {
|
|
992
|
-
logger.warn("OrganisationService", "Failed to restore persisted organisation:", storageError);
|
|
993
976
|
localStorage.removeItem("pace-core-selected-organisation");
|
|
994
977
|
}
|
|
995
978
|
if (!initialOrg) {
|
|
@@ -1009,17 +992,29 @@ var OrganisationService = class extends BaseService {
|
|
|
1009
992
|
if (!initialOrg) {
|
|
1010
993
|
throw new Error("No valid organisation found for user");
|
|
1011
994
|
}
|
|
995
|
+
const currentSelectedOrg = this._selectedOrganisation;
|
|
996
|
+
if (currentSelectedOrg && !activeOrgs.some((org) => org.id === currentSelectedOrg.id)) {
|
|
997
|
+
logger.warn("OrganisationService", "Current selected organisation is no longer valid, resetting", {
|
|
998
|
+
invalidOrgId: currentSelectedOrg.id,
|
|
999
|
+
validOrgIds: activeOrgs.map((o) => o.id)
|
|
1000
|
+
});
|
|
1001
|
+
this._selectedOrganisation = null;
|
|
1002
|
+
}
|
|
1012
1003
|
this._selectedOrganisation = initialOrg;
|
|
1013
1004
|
localStorage.setItem("pace-core-selected-organisation", JSON.stringify(initialOrg));
|
|
1014
1005
|
await this.setDatabaseOrganisationContext(initialOrg);
|
|
1015
1006
|
this.retryCount = 0;
|
|
1016
1007
|
this.hasFailedRef = false;
|
|
1017
1008
|
} catch (err) {
|
|
1018
|
-
|
|
1019
|
-
|
|
1009
|
+
const error = err;
|
|
1010
|
+
if (error.message !== "User has no access to active organisations") {
|
|
1011
|
+
logger.error("OrganisationService", "Failed to load organisations:", err);
|
|
1012
|
+
}
|
|
1013
|
+
this._error = error;
|
|
1020
1014
|
this.retryCount = this.retryCount + 1;
|
|
1021
1015
|
this.hasFailedRef = true;
|
|
1022
1016
|
this.clearAllCachedData();
|
|
1017
|
+
this._isContextReady = true;
|
|
1023
1018
|
} finally {
|
|
1024
1019
|
this.isLoadingRef = false;
|
|
1025
1020
|
this._isLoading = false;
|
|
@@ -1058,7 +1053,12 @@ function OrganisationServiceProvider({
|
|
|
1058
1053
|
let isMounted = true;
|
|
1059
1054
|
organisationService.initialize().catch((error) => {
|
|
1060
1055
|
if (isMounted) {
|
|
1061
|
-
|
|
1056
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1057
|
+
if (errorMessage === "User has no access to active organisations") {
|
|
1058
|
+
logger.warn("OrganisationServiceProvider", "User has no active organisations (this is expected for users without organisation access):", error);
|
|
1059
|
+
} else {
|
|
1060
|
+
logger.error("OrganisationServiceProvider", "Failed to initialize organisation service:", error);
|
|
1061
|
+
}
|
|
1062
1062
|
}
|
|
1063
1063
|
});
|
|
1064
1064
|
return () => {
|
|
@@ -1095,6 +1095,10 @@ var EventService = class extends BaseService {
|
|
|
1095
1095
|
this.appName = "";
|
|
1096
1096
|
this.selectedOrganisation = null;
|
|
1097
1097
|
this.setSelectedEventId = null;
|
|
1098
|
+
this.isSuperAdmin = false;
|
|
1099
|
+
// Track super admin status for conditional validation
|
|
1100
|
+
this.appConfig = null;
|
|
1101
|
+
// Cache app config to avoid repeated lookups
|
|
1098
1102
|
// Internal state management
|
|
1099
1103
|
this.isInitializedRef = false;
|
|
1100
1104
|
this.isFetchingRef = false;
|
|
@@ -1120,6 +1124,7 @@ var EventService = class extends BaseService {
|
|
|
1120
1124
|
const newOrgId = selectedOrganisation?.id;
|
|
1121
1125
|
const previousUserId = this.user?.id || null;
|
|
1122
1126
|
const newUserId = user?.id || null;
|
|
1127
|
+
const previousAppName = this.appName;
|
|
1123
1128
|
if (previousUserId !== newUserId) {
|
|
1124
1129
|
if (previousUserId !== null) {
|
|
1125
1130
|
await this.clearEventSelectionForUser(previousUserId);
|
|
@@ -1128,6 +1133,9 @@ var EventService = class extends BaseService {
|
|
|
1128
1133
|
this.selectedEvent = null;
|
|
1129
1134
|
this.setSelectedEventId?.(null);
|
|
1130
1135
|
}
|
|
1136
|
+
this.resetInitialization();
|
|
1137
|
+
this.isInitializedRef = false;
|
|
1138
|
+
this.isFetchingRef = false;
|
|
1131
1139
|
}
|
|
1132
1140
|
this.supabaseClient = supabaseClient;
|
|
1133
1141
|
this.user = user;
|
|
@@ -1135,6 +1143,23 @@ var EventService = class extends BaseService {
|
|
|
1135
1143
|
this.appName = appName;
|
|
1136
1144
|
this.selectedOrganisation = selectedOrganisation;
|
|
1137
1145
|
this.setSelectedEventId = setSelectedEventId;
|
|
1146
|
+
if (previousAppName !== appName) {
|
|
1147
|
+
this.appConfig = null;
|
|
1148
|
+
}
|
|
1149
|
+
if (user?.id) {
|
|
1150
|
+
try {
|
|
1151
|
+
this.isSuperAdmin = await isSuperAdmin(user.id);
|
|
1152
|
+
logger.debug("EventService", "Updated super admin status", {
|
|
1153
|
+
userId: user.id,
|
|
1154
|
+
isSuperAdmin: this.isSuperAdmin
|
|
1155
|
+
});
|
|
1156
|
+
} catch (error) {
|
|
1157
|
+
logger.warn("EventService", "Failed to check super admin status", { error });
|
|
1158
|
+
this.isSuperAdmin = false;
|
|
1159
|
+
}
|
|
1160
|
+
} else {
|
|
1161
|
+
this.isSuperAdmin = false;
|
|
1162
|
+
}
|
|
1138
1163
|
if (previousOrgId !== newOrgId) {
|
|
1139
1164
|
this.resetInitialization();
|
|
1140
1165
|
this.isInitializedRef = false;
|
|
@@ -1165,18 +1190,6 @@ var EventService = class extends BaseService {
|
|
|
1165
1190
|
// Event methods
|
|
1166
1191
|
setSelectedEvent(event) {
|
|
1167
1192
|
if (event) {
|
|
1168
|
-
try {
|
|
1169
|
-
if (this.selectedOrganisation && event.organisation_id !== this.selectedOrganisation.id) {
|
|
1170
|
-
logger.error("EventService", "Event organisation_id does not match selected organisation", {
|
|
1171
|
-
eventOrganisationId: event.organisation_id,
|
|
1172
|
-
selectedOrganisationId: this.selectedOrganisation.id,
|
|
1173
|
-
eventName: event.event_name
|
|
1174
|
-
});
|
|
1175
|
-
return;
|
|
1176
|
-
}
|
|
1177
|
-
} catch (error) {
|
|
1178
|
-
logger.error("EventService", "Error during event validation:", error);
|
|
1179
|
-
}
|
|
1180
1193
|
this.selectedEvent = event;
|
|
1181
1194
|
this.setSelectedEventId?.(event.event_id);
|
|
1182
1195
|
this.persistEventSelection(event.event_id).catch((error) => {
|
|
@@ -1273,16 +1286,31 @@ var EventService = class extends BaseService {
|
|
|
1273
1286
|
}
|
|
1274
1287
|
// Lifecycle methods
|
|
1275
1288
|
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
|
+
});
|
|
1276
1295
|
await super.initialize();
|
|
1277
1296
|
}
|
|
1278
1297
|
cleanup() {
|
|
1279
1298
|
super.cleanup();
|
|
1280
1299
|
}
|
|
1281
1300
|
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
|
+
});
|
|
1282
1308
|
if (this.isInitializedRef) {
|
|
1309
|
+
logger.debug("EventService", "Skipping initialization - already initialized");
|
|
1283
1310
|
return;
|
|
1284
1311
|
}
|
|
1285
1312
|
if (this.isFetchingRef) {
|
|
1313
|
+
logger.debug("EventService", "Skipping initialization - already fetching");
|
|
1286
1314
|
return;
|
|
1287
1315
|
}
|
|
1288
1316
|
try {
|
|
@@ -1292,31 +1320,107 @@ var EventService = class extends BaseService {
|
|
|
1292
1320
|
} catch (error) {
|
|
1293
1321
|
logger.warn("EventService", "Failed to clean up old storage keys:", error);
|
|
1294
1322
|
}
|
|
1295
|
-
if (!this.user
|
|
1323
|
+
if (!this.user) {
|
|
1324
|
+
logger.debug("EventService", "Skipping initialization - missing user");
|
|
1296
1325
|
return;
|
|
1297
1326
|
}
|
|
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
|
+
});
|
|
1298
1332
|
await this.fetchEvents(false);
|
|
1333
|
+
this.isInitializedRef = true;
|
|
1299
1334
|
}
|
|
1300
1335
|
doCleanup() {
|
|
1301
1336
|
}
|
|
1302
1337
|
async fetchEvents(skipLoadPersisted = false) {
|
|
1303
|
-
if (!this.user || !this.session || !this.supabaseClient || !this.appName
|
|
1338
|
+
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
|
+
});
|
|
1304
1345
|
this.notify();
|
|
1305
1346
|
return;
|
|
1306
1347
|
}
|
|
1307
1348
|
this._isLoading = true;
|
|
1308
1349
|
this.notify();
|
|
1309
1350
|
if (this.isFetchingRef) {
|
|
1351
|
+
logger.debug("EventService", "Skipping fetchEvents - already fetching");
|
|
1310
1352
|
return;
|
|
1311
1353
|
}
|
|
1312
1354
|
this.isFetchingRef = true;
|
|
1313
1355
|
let isMounted = true;
|
|
1314
1356
|
try {
|
|
1315
|
-
|
|
1357
|
+
if (!this.appConfig && this.appName) {
|
|
1358
|
+
try {
|
|
1359
|
+
this.appConfig = await getAppConfigByName(this.appName);
|
|
1360
|
+
} catch (configError) {
|
|
1361
|
+
logger.warn("EventService", "Failed to load app config, defaulting to event-required", {
|
|
1362
|
+
error: configError
|
|
1363
|
+
});
|
|
1364
|
+
this.appConfig = { requires_event: true };
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
let organisationIdForRpc = null;
|
|
1368
|
+
let userIsSuperAdmin = false;
|
|
1369
|
+
try {
|
|
1370
|
+
userIsSuperAdmin = await isSuperAdmin(this.user.id);
|
|
1371
|
+
if (userIsSuperAdmin) {
|
|
1372
|
+
organisationIdForRpc = null;
|
|
1373
|
+
logger.debug("EventService", "Super admin detected - fetching all events", {
|
|
1374
|
+
userId: this.user.id
|
|
1375
|
+
});
|
|
1376
|
+
} else {
|
|
1377
|
+
if (this.selectedEvent) {
|
|
1378
|
+
organisationIdForRpc = this.selectedEvent.organisation_id;
|
|
1379
|
+
} else if (this.appConfig?.requires_event === true) {
|
|
1380
|
+
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
|
+
} else if (this.selectedOrganisation) {
|
|
1386
|
+
organisationIdForRpc = this.selectedOrganisation.id;
|
|
1387
|
+
} else {
|
|
1388
|
+
logger.warn("EventService", "No organisation context available for event fetch", {
|
|
1389
|
+
hasSelectedEvent: !!this.selectedEvent,
|
|
1390
|
+
hasSelectedOrganisation: !!this.selectedOrganisation,
|
|
1391
|
+
appRequiresEvent: this.appConfig?.requires_event
|
|
1392
|
+
});
|
|
1393
|
+
organisationIdForRpc = null;
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
} catch (superAdminCheckError) {
|
|
1397
|
+
logger.warn("EventService", "Failed to check super admin status, using organisation-scoped query", {
|
|
1398
|
+
error: superAdminCheckError
|
|
1399
|
+
});
|
|
1400
|
+
if (this.selectedEvent) {
|
|
1401
|
+
organisationIdForRpc = this.selectedEvent.organisation_id;
|
|
1402
|
+
} else if (this.appConfig?.requires_event === true) {
|
|
1403
|
+
organisationIdForRpc = null;
|
|
1404
|
+
} else if (this.selectedOrganisation) {
|
|
1405
|
+
organisationIdForRpc = this.selectedOrganisation.id;
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
logger.debug("EventService", "Fetching events via RPC", {
|
|
1409
|
+
userId: this.user.id,
|
|
1410
|
+
organisationId: organisationIdForRpc,
|
|
1411
|
+
appName: this.appName
|
|
1412
|
+
});
|
|
1413
|
+
let { data, error: rpcError } = await this.supabaseClient.rpc("data_user_events_get", {
|
|
1316
1414
|
p_user_id: this.user.id,
|
|
1317
|
-
p_organisation_id:
|
|
1415
|
+
p_organisation_id: organisationIdForRpc,
|
|
1318
1416
|
p_app_name: this.appName
|
|
1319
1417
|
});
|
|
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
|
+
});
|
|
1320
1424
|
if (rpcError) {
|
|
1321
1425
|
logger.error("EventService", "RPC error fetching events:", rpcError);
|
|
1322
1426
|
throw new Error(rpcError.message || "Failed to fetch events");
|
|
@@ -1428,24 +1532,41 @@ function EventServiceProvider({
|
|
|
1428
1532
|
setSelectedEventId
|
|
1429
1533
|
}) {
|
|
1430
1534
|
const eventServiceRef = useRef2(null);
|
|
1535
|
+
const initializingRef = useRef2(false);
|
|
1431
1536
|
if (!eventServiceRef.current) {
|
|
1432
1537
|
eventServiceRef.current = new EventService(supabaseClient, user, session, appName, selectedOrganisation, setSelectedEventId);
|
|
1433
1538
|
}
|
|
1434
1539
|
const eventService = eventServiceRef.current;
|
|
1435
1540
|
useEffect3(() => {
|
|
1436
1541
|
let isMounted = true;
|
|
1542
|
+
if (initializingRef.current) {
|
|
1543
|
+
return;
|
|
1544
|
+
}
|
|
1437
1545
|
const updateAndInitialize = async () => {
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1546
|
+
initializingRef.current = true;
|
|
1547
|
+
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
|
+
await eventService.updateDependencies(supabaseClient, user, session, appName, selectedOrganisation, setSelectedEventId);
|
|
1556
|
+
if (!isMounted) return;
|
|
1557
|
+
await eventService.initialize().catch((error) => {
|
|
1558
|
+
if (isMounted) {
|
|
1559
|
+
logger.error("EventServiceProvider", "Failed to initialize event service:", error);
|
|
1560
|
+
}
|
|
1561
|
+
});
|
|
1562
|
+
} finally {
|
|
1563
|
+
initializingRef.current = false;
|
|
1564
|
+
}
|
|
1445
1565
|
};
|
|
1446
1566
|
updateAndInitialize();
|
|
1447
1567
|
return () => {
|
|
1448
1568
|
isMounted = false;
|
|
1569
|
+
initializingRef.current = false;
|
|
1449
1570
|
};
|
|
1450
1571
|
}, [supabaseClient, user, session, appName, selectedOrganisation, setSelectedEventId]);
|
|
1451
1572
|
useEffect3(() => {
|
|
@@ -1750,8 +1871,10 @@ function InactivityServiceProvider({
|
|
|
1750
1871
|
supabaseClient,
|
|
1751
1872
|
user,
|
|
1752
1873
|
session,
|
|
1753
|
-
idleTimeoutMs
|
|
1754
|
-
|
|
1874
|
+
idleTimeoutMs,
|
|
1875
|
+
// REQUIRED: No default - must be explicitly provided
|
|
1876
|
+
warnBeforeMs,
|
|
1877
|
+
// REQUIRED: No default - must be explicitly provided
|
|
1755
1878
|
onIdleLogout
|
|
1756
1879
|
}) {
|
|
1757
1880
|
const inactivityServiceRef = useRef3(null);
|
|
@@ -1810,6 +1933,29 @@ function useOrganisationService() {
|
|
|
1810
1933
|
return context.organisationService;
|
|
1811
1934
|
}
|
|
1812
1935
|
|
|
1936
|
+
// src/hooks/useOrganisations.ts
|
|
1937
|
+
function useOrganisations() {
|
|
1938
|
+
const organisationService = useOrganisationService();
|
|
1939
|
+
const selectedOrg = organisationService.getSelectedOrganisation();
|
|
1940
|
+
return {
|
|
1941
|
+
selectedOrganisation: selectedOrg,
|
|
1942
|
+
organisations: organisationService.getOrganisations(),
|
|
1943
|
+
userMemberships: organisationService.getUserMemberships(),
|
|
1944
|
+
isLoading: organisationService.isLoading(),
|
|
1945
|
+
error: organisationService.getError(),
|
|
1946
|
+
hasValidOrganisationContext: organisationService.hasValidOrganisationContext(),
|
|
1947
|
+
isContextReady: organisationService.isContextReady(),
|
|
1948
|
+
setSelectedOrganisation: (org) => organisationService.setSelectedOrganisation(org),
|
|
1949
|
+
switchOrganisation: (orgId) => organisationService.switchOrganisation(orgId),
|
|
1950
|
+
getUserRole: (orgId) => organisationService.getUserRole(orgId),
|
|
1951
|
+
validateOrganisationAccess: (orgId) => organisationService.validateOrganisationAccess(orgId),
|
|
1952
|
+
refreshOrganisations: () => organisationService.refreshOrganisations(),
|
|
1953
|
+
ensureOrganisationContext: () => organisationService.ensureOrganisationContext(),
|
|
1954
|
+
isOrganisationSecure: () => organisationService.isOrganisationSecure(),
|
|
1955
|
+
getPrimaryOrganisation: () => organisationService.getPrimaryOrganisation()
|
|
1956
|
+
};
|
|
1957
|
+
}
|
|
1958
|
+
|
|
1813
1959
|
// src/hooks/services/useEventService.ts
|
|
1814
1960
|
import { useContext as useContext3, useReducer as useReducer3, useEffect as useEffect7 } from "react";
|
|
1815
1961
|
function useEventService() {
|
|
@@ -1893,6 +2039,7 @@ function UnifiedAuthContextProvider({
|
|
|
1893
2039
|
appName,
|
|
1894
2040
|
appConfig = { requires_event: true },
|
|
1895
2041
|
// Default to requiring events
|
|
2042
|
+
supabaseClient: supabaseClientProp,
|
|
1896
2043
|
...props
|
|
1897
2044
|
}) {
|
|
1898
2045
|
const authService = useAuthService();
|
|
@@ -1932,15 +2079,31 @@ function UnifiedAuthContextProvider({
|
|
|
1932
2079
|
const currentUser = authService.getUser();
|
|
1933
2080
|
const currentSession = authService.getSession();
|
|
1934
2081
|
const isAuth = !!(currentUser && currentSession);
|
|
1935
|
-
const supabase =
|
|
2082
|
+
const supabase = useMemo6(() => supabaseClientProp, [supabaseClientProp]);
|
|
1936
2083
|
const [appId, setAppId] = useState3(void 0);
|
|
1937
2084
|
const isResolvingAppIdRef = useRef4(false);
|
|
2085
|
+
const resolvedAppIdRef = useRef4(void 0);
|
|
2086
|
+
const resolvedUserIdRef = useRef4(void 0);
|
|
1938
2087
|
useEffect10(() => {
|
|
1939
|
-
if (isAuth
|
|
2088
|
+
if (!isAuth) {
|
|
2089
|
+
resolvedAppIdRef.current = void 0;
|
|
2090
|
+
resolvedUserIdRef.current = void 0;
|
|
2091
|
+
setAppId(void 0);
|
|
2092
|
+
return;
|
|
2093
|
+
}
|
|
2094
|
+
if (currentUser?.id && resolvedUserIdRef.current && resolvedUserIdRef.current !== currentUser.id) {
|
|
2095
|
+
resolvedAppIdRef.current = void 0;
|
|
2096
|
+
resolvedUserIdRef.current = void 0;
|
|
2097
|
+
setAppId(void 0);
|
|
2098
|
+
}
|
|
2099
|
+
const currentUserId = currentUser?.id;
|
|
2100
|
+
if (isAuth && currentUserId && supabase && appName && resolvedUserIdRef.current !== currentUserId && // Haven't resolved for this user yet
|
|
2101
|
+
!isResolvingAppIdRef.current) {
|
|
1940
2102
|
isResolvingAppIdRef.current = true;
|
|
1941
|
-
|
|
2103
|
+
resolvedUserIdRef.current = currentUserId;
|
|
2104
|
+
const userId = currentUserId;
|
|
1942
2105
|
const appNameValue = appName;
|
|
1943
|
-
import("./api-
|
|
2106
|
+
import("./api-IHKALJZD.js").then(async ({ resolveAppContext, setupRBAC }) => {
|
|
1944
2107
|
try {
|
|
1945
2108
|
setupRBAC(supabase);
|
|
1946
2109
|
const result = await resolveAppContext({
|
|
@@ -1948,11 +2111,14 @@ function UnifiedAuthContextProvider({
|
|
|
1948
2111
|
appName: appNameValue
|
|
1949
2112
|
});
|
|
1950
2113
|
if (result?.appId) {
|
|
2114
|
+
resolvedAppIdRef.current = result.appId;
|
|
1951
2115
|
setAppId(result.appId);
|
|
1952
2116
|
logger.debug("UnifiedAuthProvider", "appId resolved on login", {
|
|
1953
2117
|
appId: result.appId,
|
|
1954
2118
|
appName: appNameValue
|
|
1955
2119
|
});
|
|
2120
|
+
} else {
|
|
2121
|
+
resolvedUserIdRef.current = void 0;
|
|
1956
2122
|
}
|
|
1957
2123
|
} catch (error) {
|
|
1958
2124
|
logger.error("UnifiedAuthProvider", "Failed to resolve appId on login", {
|
|
@@ -1960,41 +2126,64 @@ function UnifiedAuthContextProvider({
|
|
|
1960
2126
|
appName: appNameValue,
|
|
1961
2127
|
userId
|
|
1962
2128
|
});
|
|
2129
|
+
resolvedUserIdRef.current = void 0;
|
|
1963
2130
|
} finally {
|
|
1964
2131
|
isResolvingAppIdRef.current = false;
|
|
1965
2132
|
}
|
|
1966
2133
|
}).catch((importError) => {
|
|
1967
2134
|
logger.error("UnifiedAuthProvider", "Failed to import RBAC API", importError);
|
|
1968
2135
|
isResolvingAppIdRef.current = false;
|
|
2136
|
+
resolvedUserIdRef.current = void 0;
|
|
1969
2137
|
});
|
|
1970
2138
|
}
|
|
1971
|
-
|
|
1972
|
-
setAppId(void 0);
|
|
1973
|
-
}
|
|
1974
|
-
}, [isAuth, currentUser?.id, supabase, appName, appId]);
|
|
2139
|
+
}, [isAuth, currentUser?.id, supabase, appName]);
|
|
1975
2140
|
const [, forceUpdate] = useReducer5((x) => x + 1, 0);
|
|
2141
|
+
const forceUpdateTimeoutRef = useRef4(null);
|
|
2142
|
+
const debouncedForceUpdate = useCallback(() => {
|
|
2143
|
+
if (forceUpdateTimeoutRef.current) {
|
|
2144
|
+
clearTimeout(forceUpdateTimeoutRef.current);
|
|
2145
|
+
}
|
|
2146
|
+
forceUpdateTimeoutRef.current = setTimeout(() => {
|
|
2147
|
+
forceUpdate();
|
|
2148
|
+
forceUpdateTimeoutRef.current = null;
|
|
2149
|
+
}, 0);
|
|
2150
|
+
}, [forceUpdate]);
|
|
2151
|
+
const authServiceRef = useRef4(authService);
|
|
2152
|
+
const organisationServiceRef = useRef4(organisationService);
|
|
2153
|
+
const eventServiceRef = useRef4(eventService);
|
|
2154
|
+
const inactivityServiceRef = useRef4(inactivityService);
|
|
1976
2155
|
useEffect10(() => {
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
2156
|
+
authServiceRef.current = authService;
|
|
2157
|
+
organisationServiceRef.current = organisationService;
|
|
2158
|
+
eventServiceRef.current = eventService;
|
|
2159
|
+
inactivityServiceRef.current = inactivityService;
|
|
2160
|
+
}, [authService, organisationService, eventService, inactivityService]);
|
|
2161
|
+
useEffect10(() => {
|
|
2162
|
+
const unsubscribeAuth = authServiceRef.current.subscribe(debouncedForceUpdate);
|
|
2163
|
+
const unsubscribeOrg = organisationServiceRef.current.subscribe(debouncedForceUpdate);
|
|
2164
|
+
const unsubscribeEvent = eventServiceRef.current.subscribe(debouncedForceUpdate);
|
|
2165
|
+
const unsubscribeInactivity = inactivityServiceRef.current.subscribe(debouncedForceUpdate);
|
|
1981
2166
|
return () => {
|
|
1982
2167
|
unsubscribeAuth();
|
|
1983
2168
|
unsubscribeOrg();
|
|
1984
2169
|
unsubscribeEvent();
|
|
1985
2170
|
unsubscribeInactivity();
|
|
2171
|
+
if (forceUpdateTimeoutRef.current) {
|
|
2172
|
+
clearTimeout(forceUpdateTimeoutRef.current);
|
|
2173
|
+
}
|
|
1986
2174
|
};
|
|
1987
|
-
}, [
|
|
2175
|
+
}, [debouncedForceUpdate]);
|
|
1988
2176
|
const authLoading = authService.isLoading();
|
|
1989
2177
|
const orgLoading = organisationService.isLoading();
|
|
1990
2178
|
const eventLoading = eventService.isLoading();
|
|
1991
2179
|
const restorationLoading = sessionRestoration.isRestoring && !sessionRestorationTimedOut && !sessionRestoration.restorationError;
|
|
1992
2180
|
const totalLoading = restorationLoading || authLoading || orgLoading || eventLoading;
|
|
1993
2181
|
const authError = authService.getError();
|
|
1994
|
-
const
|
|
2182
|
+
const rawSelectedOrganisation = organisationService.getSelectedOrganisation();
|
|
1995
2183
|
const organisations = organisationService.getOrganisations();
|
|
1996
2184
|
const userMemberships = organisationService.getUserMemberships();
|
|
1997
2185
|
const organisationError = organisationService.getError();
|
|
2186
|
+
const selectedOrganisation = appConfig?.requires_event ? null : rawSelectedOrganisation;
|
|
1998
2187
|
const hasValidOrganisationContext = organisationService.hasValidOrganisationContext();
|
|
1999
2188
|
const isContextReady = organisationService.isContextReady();
|
|
2000
2189
|
const events = eventService.getEvents();
|
|
@@ -2170,10 +2359,13 @@ function EventServiceProviderWrapper({
|
|
|
2170
2359
|
supabaseClient,
|
|
2171
2360
|
user,
|
|
2172
2361
|
session,
|
|
2173
|
-
appName
|
|
2362
|
+
appName,
|
|
2363
|
+
appConfig
|
|
2174
2364
|
}) {
|
|
2175
|
-
const
|
|
2176
|
-
const selectedOrganisation =
|
|
2365
|
+
const { selectedOrganisation: rawSelectedOrganisation } = useOrganisations();
|
|
2366
|
+
const selectedOrganisation = appConfig?.requires_event ? null : rawSelectedOrganisation;
|
|
2367
|
+
const setSelectedEventId = useCallback(() => {
|
|
2368
|
+
}, []);
|
|
2177
2369
|
return /* @__PURE__ */ jsx5(
|
|
2178
2370
|
EventServiceProvider,
|
|
2179
2371
|
{
|
|
@@ -2182,8 +2374,7 @@ function EventServiceProviderWrapper({
|
|
|
2182
2374
|
session,
|
|
2183
2375
|
appName,
|
|
2184
2376
|
selectedOrganisation,
|
|
2185
|
-
setSelectedEventId
|
|
2186
|
-
},
|
|
2377
|
+
setSelectedEventId,
|
|
2187
2378
|
children
|
|
2188
2379
|
}
|
|
2189
2380
|
);
|
|
@@ -2216,6 +2407,7 @@ function ServiceAwareProviders({
|
|
|
2216
2407
|
user: authService.getUser(),
|
|
2217
2408
|
session: authService.getSession(),
|
|
2218
2409
|
appName,
|
|
2410
|
+
appConfig,
|
|
2219
2411
|
children: /* @__PURE__ */ jsx5(
|
|
2220
2412
|
InactivityServiceProvider,
|
|
2221
2413
|
{
|
|
@@ -2258,11 +2450,12 @@ function UnifiedAuthProvider({
|
|
|
2258
2450
|
persistState = true,
|
|
2259
2451
|
enablePersistence,
|
|
2260
2452
|
requireOrganisationContext = true,
|
|
2261
|
-
idleTimeoutMs
|
|
2262
|
-
//
|
|
2263
|
-
warnBeforeMs
|
|
2264
|
-
//
|
|
2453
|
+
idleTimeoutMs,
|
|
2454
|
+
// REQUIRED: No default - must be explicitly provided
|
|
2455
|
+
warnBeforeMs,
|
|
2456
|
+
// REQUIRED: No default - must be explicitly provided
|
|
2265
2457
|
onIdleLogout,
|
|
2458
|
+
// REQUIRED: No default - must be explicitly provided
|
|
2266
2459
|
renderInactivityWarning,
|
|
2267
2460
|
dangerouslyDisableInactivity = false
|
|
2268
2461
|
}) {
|
|
@@ -2307,6 +2500,7 @@ export {
|
|
|
2307
2500
|
InactivityServiceProvider,
|
|
2308
2501
|
useAuthService,
|
|
2309
2502
|
useOrganisationService,
|
|
2503
|
+
useOrganisations,
|
|
2310
2504
|
useEventService,
|
|
2311
2505
|
useInactivityService,
|
|
2312
2506
|
useSessionRestoration,
|
|
@@ -2314,4 +2508,4 @@ export {
|
|
|
2314
2508
|
useUnifiedAuth,
|
|
2315
2509
|
UnifiedAuthProvider
|
|
2316
2510
|
};
|
|
2317
|
-
//# sourceMappingURL=chunk-
|
|
2511
|
+
//# sourceMappingURL=chunk-6LTQQAT6.js.map
|