@jmruthers/pace-core 0.5.188 → 0.5.190
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core-usage-manifest.json +0 -4
- package/dist/{AuthService-B-cd2MA4.d.ts → AuthService-CbP_utw2.d.ts} +7 -3
- package/dist/{DataTable-GUFUNZ3N.js → DataTable-ON3IXISJ.js} +8 -8
- package/dist/{PublicPageProvider-DrLDztHt.d.ts → PublicPageProvider-C4uxosp6.d.ts} +129 -40
- package/dist/{UnifiedAuthProvider-BG0AL5eE.d.ts → UnifiedAuthProvider-BYA9qB-o.d.ts} +4 -3
- package/dist/{UnifiedAuthProvider-643PUAIM.js → UnifiedAuthProvider-X5NXANVI.js} +4 -2
- package/dist/{api-YP7XD5L6.js → api-I6UCQ5S6.js} +4 -2
- package/dist/{chunk-DDM4CCYT.js → chunk-4QYC5L4K.js} +60 -35
- package/dist/chunk-4QYC5L4K.js.map +1 -0
- package/dist/{chunk-IM4QE42D.js → chunk-73HSNNOQ.js} +141 -326
- package/dist/chunk-73HSNNOQ.js.map +1 -0
- package/dist/{chunk-YHCN776L.js → chunk-DZWK57KZ.js} +2 -75
- package/dist/chunk-DZWK57KZ.js.map +1 -0
- package/dist/{chunk-3GOZZZYH.js → chunk-HQVPB5MZ.js} +238 -301
- package/dist/chunk-HQVPB5MZ.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-VGZZXKBR.js → chunk-J2XXC7R5.js} +280 -52
- package/dist/chunk-J2XXC7R5.js.map +1 -0
- package/dist/{chunk-UNOTYLQF.js → chunk-NIU6J6OX.js} +772 -725
- package/dist/chunk-NIU6J6OX.js.map +1 -0
- package/dist/{chunk-HESYZWZW.js → chunk-QWWZ5CAQ.js} +2 -2
- package/dist/{chunk-HEHYGYOX.js → chunk-RUYZKXOD.js} +401 -46
- package/dist/chunk-RUYZKXOD.js.map +1 -0
- package/dist/{chunk-2UUZZJFT.js → chunk-SDMHPX3X.js} +176 -160
- package/dist/{chunk-2UUZZJFT.js.map → chunk-SDMHPX3X.js.map} +1 -1
- package/dist/{chunk-IPCH26AG.js → chunk-STYK4OH2.js} +11 -11
- package/dist/chunk-STYK4OH2.js.map +1 -0
- package/dist/{chunk-EFCLXK7F.js → chunk-VVBAW5A5.js} +4201 -3809
- package/dist/chunk-VVBAW5A5.js.map +1 -0
- package/dist/chunk-Y4BUBBHD.js +614 -0
- package/dist/chunk-Y4BUBBHD.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 +3 -5
- package/dist/components.js +19 -23
- package/dist/components.js.map +1 -1
- 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 +10 -5
- package/dist/hooks.js +14 -8
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +13 -12
- package/dist/index.js +79 -73
- 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 +76 -12
- package/dist/rbac/index.js +12 -9
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/{usePublicRouteParams-CTDELQ7H.d.ts → usePublicRouteParams-DxIDS4bC.d.ts} +16 -9
- 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 +1 -1
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +4 -4
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +2 -2
- package/docs/api/classes/SecureSupabaseClient.md +21 -16
- 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 +128 -0
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeOptions.md +4 -4
- 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 +155 -135
- package/docs/api-reference/components.md +72 -29
- 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/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 -4
- 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 +9 -9
- package/src/__tests__/rls-policies.test.ts +197 -61
- package/src/components/AddressField/AddressField.test.tsx +42 -0
- package/src/components/AddressField/AddressField.tsx +71 -60
- package/src/components/AddressField/README.md +1 -0
- package/src/components/Alert/Alert.test.tsx +50 -10
- package/src/components/Alert/Alert.tsx +5 -3
- package/src/components/Avatar/Avatar.test.tsx +252 -226
- package/src/components/Avatar/Avatar.tsx +179 -53
- package/src/components/Avatar/index.ts +1 -1
- 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 +8 -8
- 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.tsx +5 -5
- 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.test.tsx +7 -9
- package/src/components/UserMenu/UserMenu.tsx +10 -8
- package/src/components/index.ts +2 -1
- 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.unit.test.ts → usePublicEvent.test.ts} +28 -1
- package/src/hooks/__tests__/useQueryCache.test.ts +144 -0
- package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +58 -16
- package/src/hooks/index.ts +1 -1
- package/src/hooks/public/usePublicEvent.ts +2 -2
- package/src/hooks/public/usePublicFileDisplay.ts +173 -87
- package/src/hooks/useAppConfig.ts +24 -5
- package/src/hooks/useFileDisplay.ts +297 -34
- 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 +21 -0
- package/src/hooks/useSecureDataAccess.test.ts +80 -35
- package/src/hooks/useSecureDataAccess.ts +80 -37
- package/src/index.ts +2 -1
- 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 +6 -1
- package/src/rbac/utils/contextValidator.ts +288 -0
- package/src/rbac/utils/eventContext.ts +48 -2
- package/src/services/EventService.ts +165 -21
- package/src/services/OrganisationService.ts +37 -2
- package/src/services/__tests__/EventService.test.ts +26 -21
- package/src/types/file-reference.ts +13 -10
- package/src/utils/app/appNameResolver.test.ts +346 -73
- package/src/utils/context/superAdminOverride.ts +58 -0
- package/src/utils/file-reference/index.ts +61 -33
- package/src/utils/google-places/googlePlacesUtils.test.ts +98 -0
- package/src/utils/google-places/loadGoogleMapsScript.test.ts +83 -0
- 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-EFCLXK7F.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-IPCH26AG.js.map +0 -1
- package/dist/chunk-SAUPYVLF.js.map +0 -1
- package/dist/chunk-THRPYOFK.js.map +0 -1
- package/dist/chunk-UNOTYLQF.js.map +0 -1
- package/dist/chunk-VGZZXKBR.js.map +0 -1
- package/dist/chunk-YHCN776L.js.map +0 -1
- package/src/hooks/__tests__/usePermissionCache.simple.test.ts +0 -192
- package/src/hooks/__tests__/usePermissionCache.unit.test.ts +0 -741
- package/src/hooks/__tests__/usePublicEvent.simple.test.ts +0 -703
- package/src/rbac/hooks/useRBAC.simple.test.ts +0 -95
- package/src/rbac/utils/__tests__/eventContext.unit.test.ts +0 -428
- /package/dist/{DataTable-GUFUNZ3N.js.map → DataTable-ON3IXISJ.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-643PUAIM.js.map → UnifiedAuthProvider-X5NXANVI.js.map} +0 -0
- /package/dist/{api-YP7XD5L6.js.map → api-I6UCQ5S6.js.map} +0 -0
- /package/dist/{chunk-HESYZWZW.js.map → chunk-QWWZ5CAQ.js.map} +0 -0
|
@@ -31,17 +31,18 @@ export interface EventServiceProviderProps {
|
|
|
31
31
|
setSelectedEventId: (eventId: string | null) => void;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
export function EventServiceProvider({
|
|
35
|
-
children,
|
|
36
|
-
supabaseClient,
|
|
37
|
-
user,
|
|
38
|
-
session,
|
|
34
|
+
export function EventServiceProvider({
|
|
35
|
+
children,
|
|
36
|
+
supabaseClient,
|
|
37
|
+
user,
|
|
38
|
+
session,
|
|
39
39
|
appName,
|
|
40
40
|
selectedOrganisation,
|
|
41
41
|
setSelectedEventId
|
|
42
42
|
}: EventServiceProviderProps) {
|
|
43
43
|
// Create service instance once with useRef to avoid recreation on dependency changes
|
|
44
44
|
const eventServiceRef = useRef<EventService | null>(null);
|
|
45
|
+
const initializingRef = useRef(false);
|
|
45
46
|
|
|
46
47
|
if (!eventServiceRef.current) {
|
|
47
48
|
eventServiceRef.current = new EventService(supabaseClient, user, session, appName, selectedOrganisation, setSelectedEventId);
|
|
@@ -53,25 +54,44 @@ export function EventServiceProvider({
|
|
|
53
54
|
// Note: eventService is a ref and never changes, so we don't include it in dependencies
|
|
54
55
|
useEffect(() => {
|
|
55
56
|
let isMounted = true;
|
|
56
|
-
|
|
57
|
+
|
|
58
|
+
if (initializingRef.current) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
57
62
|
const updateAndInitialize = async () => {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
|
|
63
|
+
initializingRef.current = true;
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
logger.debug('EventServiceProvider', 'Updating dependencies and initializing', {
|
|
67
|
+
hasUser: !!user,
|
|
68
|
+
hasSession: !!session,
|
|
69
|
+
appName,
|
|
70
|
+
hasSelectedOrganisation: !!selectedOrganisation,
|
|
71
|
+
organisationId: selectedOrganisation?.id
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Update dependencies (now async to handle user change cleanup)
|
|
75
|
+
await eventService.updateDependencies(supabaseClient, user, session, appName, selectedOrganisation, setSelectedEventId);
|
|
76
|
+
|
|
77
|
+
if (!isMounted) return;
|
|
78
|
+
|
|
79
|
+
// Re-initialize service when dependencies change
|
|
80
|
+
await eventService.initialize().catch(error => {
|
|
81
|
+
if (isMounted) {
|
|
82
|
+
logger.error('EventServiceProvider', 'Failed to initialize event service:', error);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
} finally {
|
|
86
|
+
initializingRef.current = false;
|
|
87
|
+
}
|
|
69
88
|
};
|
|
70
89
|
|
|
71
90
|
updateAndInitialize();
|
|
72
91
|
|
|
73
92
|
return () => {
|
|
74
93
|
isMounted = false;
|
|
94
|
+
initializingRef.current = false;
|
|
75
95
|
};
|
|
76
96
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
77
97
|
// eventService is a ref and never changes, so we exclude it from dependencies
|
|
@@ -25,8 +25,8 @@ export interface InactivityServiceProviderProps {
|
|
|
25
25
|
supabaseClient: SupabaseClient;
|
|
26
26
|
user: User | null;
|
|
27
27
|
session: Session | null;
|
|
28
|
-
idleTimeoutMs
|
|
29
|
-
warnBeforeMs
|
|
28
|
+
idleTimeoutMs: number; // REQUIRED: No default - must be explicitly provided
|
|
29
|
+
warnBeforeMs: number; // REQUIRED: No default - must be explicitly provided
|
|
30
30
|
onIdleLogout: (reason: 'inactivity') => void;
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -35,8 +35,8 @@ export function InactivityServiceProvider({
|
|
|
35
35
|
supabaseClient,
|
|
36
36
|
user,
|
|
37
37
|
session,
|
|
38
|
-
idleTimeoutMs
|
|
39
|
-
warnBeforeMs
|
|
38
|
+
idleTimeoutMs, // REQUIRED: No default - must be explicitly provided
|
|
39
|
+
warnBeforeMs, // REQUIRED: No default - must be explicitly provided
|
|
40
40
|
onIdleLogout
|
|
41
41
|
}: InactivityServiceProviderProps) {
|
|
42
42
|
// Create service instance once with useRef to avoid recreation on dependency changes
|
|
@@ -52,7 +52,14 @@ export function OrganisationServiceProvider({
|
|
|
52
52
|
organisationService.initialize()
|
|
53
53
|
.catch(error => {
|
|
54
54
|
if (isMounted) {
|
|
55
|
-
|
|
55
|
+
// "User has no access to active organisations" is a valid state for users without orgs (e.g., profile pages)
|
|
56
|
+
// Log it as a warning instead of an error to reduce noise
|
|
57
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
58
|
+
if (errorMessage === 'User has no access to active organisations') {
|
|
59
|
+
logger.warn('OrganisationServiceProvider', 'User has no active organisations (this is expected for users without organisation access):', error);
|
|
60
|
+
} else {
|
|
61
|
+
logger.error('OrganisationServiceProvider', 'Failed to initialize organisation service:', error);
|
|
62
|
+
}
|
|
56
63
|
}
|
|
57
64
|
});
|
|
58
65
|
|
|
@@ -16,6 +16,7 @@ import { EventServiceProvider } from './EventServiceProvider';
|
|
|
16
16
|
import { InactivityServiceProvider } from './InactivityServiceProvider';
|
|
17
17
|
import { useAuthService } from '../../hooks/services/useAuthService';
|
|
18
18
|
import { useOrganisationService } from '../../hooks/services/useOrganisationService';
|
|
19
|
+
import { useOrganisations } from '../../hooks/useOrganisations';
|
|
19
20
|
import { useEventService } from '../../hooks/services/useEventService';
|
|
20
21
|
import { useInactivityService } from '../../hooks/services/useInactivityService';
|
|
21
22
|
import { useSessionRestoration } from '../../hooks/useSessionRestoration';
|
|
@@ -154,6 +155,7 @@ function UnifiedAuthContextProvider({
|
|
|
154
155
|
children,
|
|
155
156
|
appName,
|
|
156
157
|
appConfig = { requires_event: true }, // Default to requiring events
|
|
158
|
+
supabaseClient: supabaseClientProp,
|
|
157
159
|
...props
|
|
158
160
|
}: UnifiedAuthProviderProps) {
|
|
159
161
|
const authService = useAuthService();
|
|
@@ -196,27 +198,57 @@ function UnifiedAuthContextProvider({
|
|
|
196
198
|
const currentSession = authService.getSession();
|
|
197
199
|
const isAuth = !!(currentUser && currentSession);
|
|
198
200
|
|
|
199
|
-
//
|
|
200
|
-
|
|
201
|
+
// Stabilize supabase client reference to prevent infinite re-renders
|
|
202
|
+
// Memoize the supabaseClient prop to ensure a stable reference across renders
|
|
203
|
+
// This is critical for preventing infinite loops when supabase is used in useEffect dependency arrays
|
|
204
|
+
// The reference will only change when supabaseClientProp actually changes (different instance)
|
|
205
|
+
// If the consuming app creates the client once and reuses it, this will be stable
|
|
206
|
+
const supabase = useMemo(() => supabaseClientProp, [supabaseClientProp]);
|
|
201
207
|
|
|
202
208
|
// Resolve appId immediately when user logs in (don't wait for organisation/event)
|
|
203
209
|
// This makes appId available early for navigation menu filtering
|
|
204
210
|
const [appId, setAppId] = useState<string | undefined>(undefined);
|
|
205
211
|
const isResolvingAppIdRef = useRef(false);
|
|
212
|
+
const resolvedAppIdRef = useRef<string | undefined>(undefined);
|
|
213
|
+
const resolvedUserIdRef = useRef<string | undefined>(undefined);
|
|
206
214
|
|
|
207
215
|
useEffect(() => {
|
|
216
|
+
// Clear appId when user logs out or changes
|
|
217
|
+
if (!isAuth) {
|
|
218
|
+
// User logged out - clear all refs and state
|
|
219
|
+
resolvedAppIdRef.current = undefined;
|
|
220
|
+
resolvedUserIdRef.current = undefined;
|
|
221
|
+
setAppId(undefined);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// User changed - clear previous resolution to allow re-resolution for new user
|
|
226
|
+
if (currentUser?.id && resolvedUserIdRef.current && resolvedUserIdRef.current !== currentUser.id) {
|
|
227
|
+
resolvedAppIdRef.current = undefined;
|
|
228
|
+
resolvedUserIdRef.current = undefined;
|
|
229
|
+
setAppId(undefined);
|
|
230
|
+
}
|
|
231
|
+
|
|
208
232
|
// Resolve appId as soon as we have user + supabase + appName
|
|
209
233
|
// Don't wait for organisation or event - appId resolution only needs user + appName
|
|
234
|
+
// Extract userId to stable const to prevent reference issues
|
|
235
|
+
const currentUserId = currentUser?.id;
|
|
236
|
+
|
|
237
|
+
// Only resolve if we haven't already resolved for this user
|
|
210
238
|
if (
|
|
211
239
|
isAuth &&
|
|
212
|
-
|
|
240
|
+
currentUserId &&
|
|
213
241
|
supabase &&
|
|
214
242
|
appName &&
|
|
215
|
-
|
|
243
|
+
resolvedUserIdRef.current !== currentUserId && // Haven't resolved for this user yet
|
|
216
244
|
!isResolvingAppIdRef.current
|
|
217
245
|
) {
|
|
246
|
+
// CRITICAL FIX: Set refs IMMEDIATELY (synchronously) before async operation
|
|
247
|
+
// This prevents race conditions where effect re-runs before async completes
|
|
218
248
|
isResolvingAppIdRef.current = true;
|
|
219
|
-
|
|
249
|
+
resolvedUserIdRef.current = currentUserId; // Set BEFORE async, not after
|
|
250
|
+
|
|
251
|
+
const userId = currentUserId;
|
|
220
252
|
const appNameValue = appName;
|
|
221
253
|
|
|
222
254
|
// Resolve appId immediately
|
|
@@ -231,11 +263,16 @@ function UnifiedAuthContextProvider({
|
|
|
231
263
|
});
|
|
232
264
|
|
|
233
265
|
if (result?.appId) {
|
|
266
|
+
resolvedAppIdRef.current = result.appId;
|
|
267
|
+
// resolvedUserIdRef already set above to prevent race conditions
|
|
234
268
|
setAppId(result.appId);
|
|
235
269
|
logger.debug('UnifiedAuthProvider', 'appId resolved on login', {
|
|
236
270
|
appId: result.appId,
|
|
237
271
|
appName: appNameValue
|
|
238
272
|
});
|
|
273
|
+
} else {
|
|
274
|
+
// No appId returned - reset ref to allow retry
|
|
275
|
+
resolvedUserIdRef.current = undefined;
|
|
239
276
|
}
|
|
240
277
|
} catch (error) {
|
|
241
278
|
logger.error('UnifiedAuthProvider', 'Failed to resolve appId on login', {
|
|
@@ -243,39 +280,71 @@ function UnifiedAuthContextProvider({
|
|
|
243
280
|
appName: appNameValue,
|
|
244
281
|
userId
|
|
245
282
|
});
|
|
283
|
+
// Reset ref on error to allow retry
|
|
284
|
+
resolvedUserIdRef.current = undefined;
|
|
246
285
|
} finally {
|
|
247
286
|
isResolvingAppIdRef.current = false;
|
|
248
287
|
}
|
|
249
288
|
}).catch((importError) => {
|
|
250
289
|
logger.error('UnifiedAuthProvider', 'Failed to import RBAC API', importError);
|
|
251
290
|
isResolvingAppIdRef.current = false;
|
|
291
|
+
// Reset ref on import error to allow retry
|
|
292
|
+
resolvedUserIdRef.current = undefined;
|
|
252
293
|
});
|
|
253
294
|
}
|
|
254
|
-
|
|
255
|
-
// Clear appId when user logs out
|
|
256
|
-
if (!isAuth) {
|
|
257
|
-
setAppId(undefined);
|
|
258
|
-
}
|
|
259
|
-
}, [isAuth, currentUser?.id, supabase, appName, appId]);
|
|
295
|
+
}, [isAuth, currentUser?.id, supabase, appName]); // Removed appId from deps - it's the output, not an input. currentUser?.id is stable primitive.
|
|
260
296
|
|
|
261
297
|
// Subscribe to service state changes to trigger re-renders
|
|
262
298
|
// Use useReducer to force updates when services notify
|
|
263
299
|
const [, forceUpdate] = useReducer(x => x + 1, 0);
|
|
264
|
-
|
|
300
|
+
const forceUpdateTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
301
|
+
|
|
302
|
+
const debouncedForceUpdate = useCallback(() => {
|
|
303
|
+
if (forceUpdateTimeoutRef.current) {
|
|
304
|
+
clearTimeout(forceUpdateTimeoutRef.current);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
forceUpdateTimeoutRef.current = setTimeout(() => {
|
|
308
|
+
forceUpdate();
|
|
309
|
+
forceUpdateTimeoutRef.current = null;
|
|
310
|
+
}, 0);
|
|
311
|
+
}, [forceUpdate]);
|
|
312
|
+
|
|
313
|
+
// Use refs for services to avoid dependency on service instances
|
|
314
|
+
// This prevents re-subscriptions when service instances change reference
|
|
315
|
+
const authServiceRef = useRef(authService);
|
|
316
|
+
const organisationServiceRef = useRef(organisationService);
|
|
317
|
+
const eventServiceRef = useRef(eventService);
|
|
318
|
+
const inactivityServiceRef = useRef(inactivityService);
|
|
319
|
+
|
|
320
|
+
// Update refs when services change
|
|
265
321
|
useEffect(() => {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
322
|
+
authServiceRef.current = authService;
|
|
323
|
+
organisationServiceRef.current = organisationService;
|
|
324
|
+
eventServiceRef.current = eventService;
|
|
325
|
+
inactivityServiceRef.current = inactivityService;
|
|
326
|
+
}, [authService, organisationService, eventService, inactivityService]);
|
|
327
|
+
|
|
328
|
+
// Subscribe using refs - only depends on debouncedForceUpdate
|
|
329
|
+
// This prevents re-subscriptions when service instances change
|
|
330
|
+
useEffect(() => {
|
|
331
|
+
// Subscribe to all service changes using current refs
|
|
332
|
+
const unsubscribeAuth = authServiceRef.current.subscribe(debouncedForceUpdate);
|
|
333
|
+
const unsubscribeOrg = organisationServiceRef.current.subscribe(debouncedForceUpdate);
|
|
334
|
+
const unsubscribeEvent = eventServiceRef.current.subscribe(debouncedForceUpdate);
|
|
335
|
+
const unsubscribeInactivity = inactivityServiceRef.current.subscribe(debouncedForceUpdate);
|
|
336
|
+
|
|
272
337
|
return () => {
|
|
273
338
|
unsubscribeAuth();
|
|
274
339
|
unsubscribeOrg();
|
|
275
340
|
unsubscribeEvent();
|
|
276
341
|
unsubscribeInactivity();
|
|
342
|
+
|
|
343
|
+
if (forceUpdateTimeoutRef.current) {
|
|
344
|
+
clearTimeout(forceUpdateTimeoutRef.current);
|
|
345
|
+
}
|
|
277
346
|
};
|
|
278
|
-
}, [
|
|
347
|
+
}, [debouncedForceUpdate]);
|
|
279
348
|
|
|
280
349
|
// Get loading states - these will trigger re-renders when services change
|
|
281
350
|
const authLoading = authService.isLoading();
|
|
@@ -287,10 +356,14 @@ function UnifiedAuthContextProvider({
|
|
|
287
356
|
// Extract all primitive values from services to use in dependencies
|
|
288
357
|
const authError = authService.getError();
|
|
289
358
|
// supabase is already declared above (line 198)
|
|
290
|
-
const
|
|
359
|
+
const rawSelectedOrganisation = organisationService.getSelectedOrganisation();
|
|
291
360
|
const organisations = organisationService.getOrganisations();
|
|
292
361
|
const userMemberships = organisationService.getUserMemberships();
|
|
293
362
|
const organisationError = organisationService.getError();
|
|
363
|
+
|
|
364
|
+
// For event-required apps, selectedOrganisation is not in context (org derived from event)
|
|
365
|
+
// For org-required apps, selectedOrganisation is available
|
|
366
|
+
const selectedOrganisation = appConfig?.requires_event ? null : rawSelectedOrganisation;
|
|
294
367
|
const hasValidOrganisationContext = organisationService.hasValidOrganisationContext();
|
|
295
368
|
const isContextReady = organisationService.isContextReady();
|
|
296
369
|
const events = eventService.getEvents();
|
|
@@ -500,19 +573,32 @@ function EventServiceProviderWrapper({
|
|
|
500
573
|
supabaseClient,
|
|
501
574
|
user,
|
|
502
575
|
session,
|
|
503
|
-
appName
|
|
576
|
+
appName,
|
|
577
|
+
appConfig
|
|
504
578
|
}: {
|
|
505
579
|
children: React.ReactNode;
|
|
506
580
|
supabaseClient: SupabaseClient;
|
|
507
581
|
user: User | null;
|
|
508
582
|
session: Session | null;
|
|
509
583
|
appName: string;
|
|
584
|
+
appConfig?: { requires_event: boolean } | null;
|
|
510
585
|
}) {
|
|
511
|
-
|
|
512
|
-
|
|
586
|
+
// Use useOrganisations() hook for better reactivity - it subscribes to service changes
|
|
587
|
+
// This ensures EventServiceProvider re-renders when selectedOrganisation changes
|
|
588
|
+
const { selectedOrganisation: rawSelectedOrganisation } = useOrganisations();
|
|
589
|
+
|
|
590
|
+
// FIX: For event-required apps, don't pass selectedOrganisation to EventService
|
|
591
|
+
// Organisation will be derived from the selected event instead
|
|
592
|
+
// This prevents EventService from filtering events by the wrong organisation
|
|
593
|
+
const selectedOrganisation = appConfig?.requires_event ? null : rawSelectedOrganisation;
|
|
513
594
|
|
|
514
595
|
// Always render EventServiceProvider - it handles null user/session gracefully
|
|
515
596
|
// This ensures EventServiceContext is always available for components calling useEvents()
|
|
597
|
+
// Memoize setSelectedEventId to prevent unnecessary re-initializations
|
|
598
|
+
const setSelectedEventId = useCallback(() => {
|
|
599
|
+
// Event selection is now handled at the application level
|
|
600
|
+
}, []);
|
|
601
|
+
|
|
516
602
|
return (
|
|
517
603
|
<EventServiceProvider
|
|
518
604
|
supabaseClient={supabaseClient}
|
|
@@ -520,9 +606,7 @@ function EventServiceProviderWrapper({
|
|
|
520
606
|
session={session}
|
|
521
607
|
appName={appName}
|
|
522
608
|
selectedOrganisation={selectedOrganisation}
|
|
523
|
-
setSelectedEventId={
|
|
524
|
-
// Event selection is now handled at the application level
|
|
525
|
-
}}
|
|
609
|
+
setSelectedEventId={setSelectedEventId}
|
|
526
610
|
>
|
|
527
611
|
{children}
|
|
528
612
|
</EventServiceProvider>
|
|
@@ -557,6 +641,7 @@ function ServiceAwareProviders({
|
|
|
557
641
|
user={authService.getUser()}
|
|
558
642
|
session={authService.getSession()}
|
|
559
643
|
appName={appName}
|
|
644
|
+
appConfig={appConfig}
|
|
560
645
|
>
|
|
561
646
|
<InactivityServiceProvider
|
|
562
647
|
supabaseClient={supabaseClient}
|
|
@@ -595,9 +680,9 @@ export function UnifiedAuthProvider({
|
|
|
595
680
|
persistState = true,
|
|
596
681
|
enablePersistence,
|
|
597
682
|
requireOrganisationContext = true,
|
|
598
|
-
idleTimeoutMs
|
|
599
|
-
warnBeforeMs
|
|
600
|
-
onIdleLogout,
|
|
683
|
+
idleTimeoutMs, // REQUIRED: No default - must be explicitly provided
|
|
684
|
+
warnBeforeMs, // REQUIRED: No default - must be explicitly provided
|
|
685
|
+
onIdleLogout, // REQUIRED: No default - must be explicitly provided
|
|
601
686
|
renderInactivityWarning,
|
|
602
687
|
dangerouslyDisableInactivity = false
|
|
603
688
|
}: UnifiedAuthProviderProps) {
|
|
@@ -634,3 +719,4 @@ export function UnifiedAuthProvider({
|
|
|
634
719
|
</AuthServiceProvider>
|
|
635
720
|
);
|
|
636
721
|
}
|
|
722
|
+
|