@jmruthers/pace-core 0.5.190 → 0.5.193
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/dist/{AuthService-CbP_utw2.d.ts → AuthService-DjnJHDtC.d.ts} +1 -0
- package/dist/{DataTable-ON3IXISJ.js → DataTable-5FU7IESH.js} +7 -6
- package/dist/{DataTable-IVYljGJ6.d.ts → DataTable-Be6dH_dR.d.ts} +1 -1
- package/dist/{PublicPageProvider-C4uxosp6.d.ts → PublicPageProvider-C0Sm_e5k.d.ts} +4 -2
- package/dist/{UnifiedAuthProvider-BYA9qB-o.d.ts → UnifiedAuthProvider-185Ih4dj.d.ts} +2 -0
- package/dist/{UnifiedAuthProvider-X5NXANVI.js → UnifiedAuthProvider-RGJTDE2C.js} +3 -3
- package/dist/{api-I6UCQ5S6.js → api-N774RPUA.js} +2 -2
- package/dist/chunk-6C4YBBJM 5.js +628 -0
- package/dist/chunk-7D4SUZUM.js 2.map +1 -0
- package/dist/{chunk-73HSNNOQ.js → chunk-7EQTDTTJ.js} +47 -74
- package/dist/chunk-7EQTDTTJ.js 2.map +1 -0
- package/dist/chunk-7EQTDTTJ.js.map +1 -0
- package/dist/{chunk-J2XXC7R5.js → chunk-7FLMSG37.js} +409 -244
- package/dist/chunk-7FLMSG37.js 2.map +1 -0
- package/dist/chunk-7FLMSG37.js.map +1 -0
- package/dist/{chunk-NIU6J6OX.js → chunk-BC4IJKSL.js} +23 -32
- package/dist/chunk-BC4IJKSL.js.map +1 -0
- package/dist/{chunk-SDMHPX3X.js → chunk-E3SPN4VZ 5.js } +198 -53
- package/dist/chunk-E3SPN4VZ.js +12917 -0
- package/dist/{chunk-SDMHPX3X.js.map → chunk-E3SPN4VZ.js.map} +1 -1
- package/dist/chunk-E66EQZE6 5.js +37 -0
- package/dist/chunk-E66EQZE6.js 2.map +1 -0
- package/dist/{chunk-DZWK57KZ.js → chunk-G37KK66H.js} +1 -1
- package/dist/{chunk-DZWK57KZ.js.map → chunk-G37KK66H.js.map} +1 -1
- package/dist/{chunk-STYK4OH2.js → chunk-HWIIPPNI.js} +44 -225
- package/dist/chunk-HWIIPPNI.js.map +1 -0
- package/dist/chunk-I7PSE6JW 5.js +191 -0
- package/dist/chunk-I7PSE6JW.js 2.map +1 -0
- package/dist/{chunk-Y4BUBBHD.js → chunk-IIELH4DL.js} +211 -136
- package/dist/chunk-IIELH4DL.js.map +1 -0
- package/dist/{chunk-RUYZKXOD.js → chunk-KNC55RTG.js} +17 -5
- package/dist/chunk-KNC55RTG.js 5.map +1 -0
- package/dist/chunk-KNC55RTG.js.map +1 -0
- package/dist/chunk-KQCRWDSA.js 5.map +1 -0
- package/dist/{chunk-4QYC5L4K.js → chunk-LFNCN2SP.js} +26 -30
- package/dist/chunk-LFNCN2SP.js 2.map +1 -0
- package/dist/chunk-LFNCN2SP.js.map +1 -0
- package/dist/chunk-LMC26NLJ 2.js +84 -0
- package/dist/{chunk-VVBAW5A5.js → chunk-NOAYCWCX 5.js } +118 -110
- package/dist/chunk-NOAYCWCX.js +4993 -0
- package/dist/chunk-NOAYCWCX.js.map +1 -0
- package/dist/chunk-QWWZ5CAQ.js 3.map +1 -0
- package/dist/chunk-QXHPKYJV 3.js +113 -0
- package/dist/chunk-R77UEZ4E 3.js +68 -0
- package/dist/chunk-VBXEHIUJ.js 6.map +1 -0
- package/dist/{chunk-HQVPB5MZ.js → chunk-XNXXZ43G.js} +77 -33
- package/dist/chunk-XNXXZ43G.js.map +1 -0
- package/dist/chunk-ZSAAAMVR 6.js +25 -0
- package/dist/components.d.ts +4 -4
- package/dist/components.js +8 -8
- package/dist/components.js 5.map +1 -0
- package/dist/{database.generated-DI89OQeI.d.ts → database.generated-CzIvgcPu.d.ts} +165 -201
- package/dist/hooks.d.ts +12 -12
- package/dist/hooks.js +9 -9
- package/dist/index.d.ts +11 -11
- package/dist/index.js +20 -27
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +3 -3
- package/dist/providers.js +2 -2
- package/dist/rbac/index.d.ts +2 -20
- package/dist/rbac/index.js +7 -9
- package/dist/styles/index 2.js +12 -0
- package/dist/styles/index.js 5.map +1 -0
- package/dist/theming/runtime 5.js +19 -0
- package/dist/theming/runtime.js 5.map +1 -0
- package/dist/{types-Bwgl--Xo.d.ts → types-CEpcvwwF.d.ts} +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/{usePublicRouteParams-DxIDS4bC.d.ts → usePublicRouteParams-TZe0gy-4.d.ts} +1 -1
- package/dist/utils.d.ts +8 -8
- package/dist/utils.js +2 -2
- package/docs/api/classes/ColumnFactory.md +1 -1
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.md +1 -1
- package/docs/api/classes/Logger.md +1 -1
- package/docs/api/classes/MissingUserContextError.md +1 -1
- package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
- package/docs/api/classes/PermissionDeniedError.md +2 -2
- package/docs/api/classes/RBACAuditManager.md +2 -2
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +2 -2
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +1 -1
- package/docs/api/classes/SecureSupabaseClient.md +10 -10
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/enums/FileCategory.md +1 -1
- package/docs/api/enums/LogLevel.md +1 -1
- package/docs/api/enums/RBACErrorCode.md +1 -1
- package/docs/api/enums/RPCFunction.md +1 -1
- package/docs/api/interfaces/AddressFieldProps.md +1 -1
- package/docs/api/interfaces/AddressFieldRef.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +1 -1
- package/docs/api/interfaces/AutocompleteOptions.md +1 -1
- package/docs/api/interfaces/AvatarProps.md +1 -1
- package/docs/api/interfaces/BadgeProps.md +1 -1
- package/docs/api/interfaces/ButtonProps.md +1 -1
- package/docs/api/interfaces/CalendarProps.md +1 -1
- package/docs/api/interfaces/CardProps.md +1 -1
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/ComplianceResult.md +1 -1
- package/docs/api/interfaces/DataAccessRecord.md +1 -1
- package/docs/api/interfaces/DataRecord.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +1 -1
- package/docs/api/interfaces/DataTableColumn.md +1 -1
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
- package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
- package/docs/api/interfaces/DatabaseIssue.md +1 -1
- package/docs/api/interfaces/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventAppRoleData.md +1 -1
- package/docs/api/interfaces/ExportColumn.md +1 -1
- package/docs/api/interfaces/ExportOptions.md +1 -1
- package/docs/api/interfaces/FileDisplayProps.md +24 -11
- package/docs/api/interfaces/FileMetadata.md +1 -1
- package/docs/api/interfaces/FileReference.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadOptions.md +1 -1
- package/docs/api/interfaces/FileUploadProps.md +1 -1
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/FormFieldProps.md +1 -1
- package/docs/api/interfaces/FormProps.md +1 -1
- package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
- package/docs/api/interfaces/InputProps.md +1 -1
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoggerConfig.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +2 -2
- package/docs/api/interfaces/NavigationContextType.md +1 -1
- package/docs/api/interfaces/NavigationGuardProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +1 -1
- package/docs/api/interfaces/NavigationMenuProps.md +1 -1
- package/docs/api/interfaces/NavigationProviderProps.md +1 -1
- package/docs/api/interfaces/Organisation.md +1 -1
- package/docs/api/interfaces/OrganisationContextType.md +1 -1
- package/docs/api/interfaces/OrganisationMembership.md +1 -1
- package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
- package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
- package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
- package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
- package/docs/api/interfaces/PageAccessRecord.md +1 -1
- package/docs/api/interfaces/PagePermissionContextType.md +1 -1
- package/docs/api/interfaces/PagePermissionGuardProps.md +2 -2
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/ParsedAddress.md +2 -2
- package/docs/api/interfaces/PermissionEnforcerProps.md +4 -4
- package/docs/api/interfaces/ProgressProps.md +1 -1
- package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
- package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
- package/docs/api/interfaces/QuickFix.md +1 -1
- package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
- package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
- package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
- package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
- package/docs/api/interfaces/RBACConfig.md +2 -2
- package/docs/api/interfaces/RBACContext.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckResult.md +2 -2
- package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
- package/docs/api/interfaces/RBACResult.md +1 -1
- package/docs/api/interfaces/RBACRoleGrantParams.md +2 -2
- package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeParams.md +2 -2
- package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateParams.md +2 -2
- package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
- package/docs/api/interfaces/RBACRolesListParams.md +1 -1
- package/docs/api/interfaces/RBACRolesListResult.md +2 -2
- package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
- package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
- package/docs/api/interfaces/ResourcePermissions.md +1 -1
- package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RoleManagementResult.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +2 -2
- package/docs/api/interfaces/RouteConfig.md +2 -2
- package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
- package/docs/api/interfaces/SecureDataContextType.md +1 -1
- package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
- package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
- package/docs/api/interfaces/SetupIssue.md +1 -1
- package/docs/api/interfaces/StorageConfig.md +1 -1
- package/docs/api/interfaces/StorageFileInfo.md +1 -1
- package/docs/api/interfaces/StorageFileMetadata.md +1 -1
- package/docs/api/interfaces/StorageListOptions.md +1 -1
- package/docs/api/interfaces/StorageListResult.md +1 -1
- package/docs/api/interfaces/StorageUploadOptions.md +1 -1
- package/docs/api/interfaces/StorageUploadResult.md +1 -1
- package/docs/api/interfaces/StorageUrlOptions.md +1 -1
- package/docs/api/interfaces/StyleImport.md +1 -1
- package/docs/api/interfaces/SwitchProps.md +1 -1
- package/docs/api/interfaces/TabsContentProps.md +1 -1
- package/docs/api/interfaces/TabsListProps.md +1 -1
- package/docs/api/interfaces/TabsProps.md +1 -1
- package/docs/api/interfaces/TabsTriggerProps.md +1 -1
- package/docs/api/interfaces/TextareaProps.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +60 -38
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
- package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
- package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +2 -2
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +2 -2
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeOptions.md +2 -2
- package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
- package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +1 -1
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +202 -217
- package/docs/migration/README.md +18 -0
- package/docs/migration/database-changes-december-2025.md +768 -0
- package/docs/migration/person-scoped-profiles-migration-guide.md +472 -0
- package/docs/rbac/event-based-apps.md +124 -6
- package/package.json +1 -1
- package/scripts/check-pace-core-compliance.cjs +292 -57
- package/src/__tests__/public-recipe-view.test.ts +10 -10
- package/src/__tests__/rls-policies.test.ts +16 -14
- package/src/components/AddressField/README.md +6 -6
- package/src/components/DataTable/__tests__/DataTable.default-state.test.tsx +172 -45
- package/src/components/DataTable/__tests__/DataTable.grouping-aggregation.test.tsx +121 -28
- package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +9 -8
- package/src/components/DataTable/__tests__/DataTableCore.test.tsx +20 -52
- package/src/components/DataTable/__tests__/a11y.basic.test.tsx +170 -34
- package/src/components/DataTable/__tests__/keyboard.test.tsx +75 -12
- package/src/components/DataTable/__tests__/pagination.modes.test.tsx +75 -11
- package/src/components/DataTable/components/UnifiedTableBody.tsx +85 -14
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +75 -10
- package/src/components/FileDisplay/FileDisplay.test.tsx +2 -1
- package/src/components/FileDisplay/FileDisplay.tsx +16 -4
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +6 -4
- package/src/components/NavigationMenu/NavigationMenu.tsx +1 -10
- package/src/components/OrganisationSelector/OrganisationSelector.tsx +35 -16
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +25 -2
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +97 -68
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +0 -7
- package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +5 -9
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +0 -1
- package/src/components/PublicLayout/PublicPageProvider.tsx +0 -1
- package/src/components/Select/Select.test.tsx +4 -1
- package/src/components/Select/Select.tsx +60 -15
- package/src/hooks/__tests__/usePermissionCache.simple.test.ts +192 -0
- package/src/hooks/__tests__/usePermissionCache.unit.test.ts +741 -0
- package/src/hooks/__tests__/usePublicEvent.simple.test.ts +703 -0
- package/src/hooks/__tests__/usePublicEvent.unit.test.ts +581 -0
- package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +23 -15
- package/src/hooks/public/usePublicEvent.ts +8 -8
- package/src/hooks/public/usePublicFileDisplay.ts +2 -2
- package/src/hooks/services/useAuthService.ts +21 -3
- package/src/hooks/services/useEventService.ts +21 -3
- package/src/hooks/services/useInactivityService.ts +21 -3
- package/src/hooks/services/useOrganisationService.ts +21 -3
- package/src/hooks/useFileDisplay.ts +18 -26
- package/src/hooks/useQueryCache.ts +6 -6
- package/src/hooks/useSecureDataAccess.test.ts +24 -17
- package/src/hooks/useSecureDataAccess.ts +18 -13
- package/src/providers/__tests__/OrganisationProvider.test.tsx +27 -21
- package/src/providers/services/EventServiceProvider.tsx +0 -8
- package/src/providers/services/UnifiedAuthProvider.tsx +174 -24
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +10 -16
- package/src/rbac/__tests__/isSuperAdmin.real.test.ts +82 -0
- package/src/rbac/adapters.tsx +3 -22
- package/src/rbac/api.test.ts +2 -2
- package/src/rbac/api.ts +7 -1
- package/src/rbac/components/EnhancedNavigationMenu.tsx +2 -15
- package/src/rbac/components/NavigationGuard.tsx +1 -10
- package/src/rbac/components/NavigationProvider.tsx +0 -1
- package/src/rbac/components/PermissionEnforcer.tsx +45 -12
- package/src/rbac/components/SecureDataProvider.tsx +0 -1
- package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +7 -43
- package/src/rbac/components/__tests__/NavigationGuard.test.tsx +4 -11
- package/src/rbac/components/__tests__/NavigationProvider.test.tsx +3 -3
- package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +1 -1
- package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +1 -1
- package/src/rbac/engine.ts +14 -2
- package/src/rbac/hooks/index.ts +0 -3
- package/src/rbac/hooks/usePermissions.ts +51 -11
- package/src/rbac/hooks/useRBAC.simple.test.ts +95 -0
- package/src/rbac/hooks/useRBAC.ts +3 -13
- package/src/rbac/hooks/useResolvedScope.test.ts +75 -54
- package/src/rbac/hooks/useResolvedScope.ts +58 -33
- package/src/rbac/hooks/useSecureSupabase.ts +4 -9
- package/src/rbac/secureClient.ts +31 -0
- package/src/rbac/utils/__tests__/eventContext.test.ts +2 -2
- package/src/rbac/utils/__tests__/eventContext.unit.test.ts +490 -0
- package/src/rbac/utils/eventContext.ts +5 -2
- package/src/services/AuthService.ts +37 -8
- package/src/services/EventService.ts +4 -57
- package/src/services/InactivityService.ts +127 -34
- package/src/services/OrganisationService.ts +160 -149
- 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/supabase.ts +2 -2
- package/src/utils/__tests__/secureDataAccess.unit.test.ts +3 -2
- package/src/utils/file-reference/index.ts +4 -4
- package/src/utils/google-places/googlePlacesUtils.ts +1 -1
- 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/dist/chunk-4QYC5L4K.js.map +0 -1
- package/dist/chunk-73HSNNOQ.js.map +0 -1
- package/dist/chunk-HQVPB5MZ.js.map +0 -1
- package/dist/chunk-J2XXC7R5.js.map +0 -1
- package/dist/chunk-NIU6J6OX.js.map +0 -1
- package/dist/chunk-RUYZKXOD.js.map +0 -1
- package/dist/chunk-STYK4OH2.js.map +0 -1
- package/dist/chunk-VVBAW5A5.js.map +0 -1
- package/dist/chunk-Y4BUBBHD.js.map +0 -1
- package/scripts/check-pace-core-compliance.js +0 -512
- package/src/rbac/hooks/useSuperAdminBypass.ts +0 -126
- package/src/utils/context/superAdminOverride.ts +0 -58
- /package/dist/{DataTable-ON3IXISJ.js.map → DataTable-5FU7IESH.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-X5NXANVI.js.map → UnifiedAuthProvider-RGJTDE2C.js.map} +0 -0
- /package/dist/{api-I6UCQ5S6.js.map → api-N774RPUA.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getAppConfigByName,
|
|
3
3
|
isSuperAdmin
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-KNC55RTG.js";
|
|
5
5
|
import {
|
|
6
6
|
assertOrganisationId,
|
|
7
7
|
assertUserId
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
} from "./chunk-PWLANIRT.js";
|
|
17
17
|
|
|
18
18
|
// src/providers/services/UnifiedAuthProvider.tsx
|
|
19
|
-
import { createContext as createContext5, useContext as useContext6, useMemo as useMemo6, useCallback, useRef as
|
|
19
|
+
import { createContext as createContext5, useContext as useContext6, useMemo as useMemo6, useCallback, useRef as useRef8, useEffect as useEffect10, useState as useState3, useReducer as useReducer5 } from "react";
|
|
20
20
|
|
|
21
21
|
// src/providers/services/AuthServiceProvider.tsx
|
|
22
22
|
import { createContext, useMemo, useEffect, useState } from "react";
|
|
@@ -319,6 +319,8 @@ var AuthService = class extends BaseService {
|
|
|
319
319
|
// Lifecycle methods
|
|
320
320
|
async initialize() {
|
|
321
321
|
await super.initialize();
|
|
322
|
+
this.authLoading = true;
|
|
323
|
+
this.notify();
|
|
322
324
|
await this.setupAuthStateListener();
|
|
323
325
|
await this.restoreSession();
|
|
324
326
|
}
|
|
@@ -424,13 +426,15 @@ var AuthService = class extends BaseService {
|
|
|
424
426
|
const hasTimeoutError = this.sessionRestorationState.restorationError?.name === "SessionRestorationTimeoutError";
|
|
425
427
|
if (this.sessionRestorationState.isRestoring || this.sessionRestorationState.restorationError || hasTimeoutError && session) {
|
|
426
428
|
this.finishSessionRestoration();
|
|
427
|
-
|
|
429
|
+
}
|
|
430
|
+
} else {
|
|
431
|
+
if (this.sessionRestorationState.isRestoring) {
|
|
432
|
+
this.finishSessionRestoration();
|
|
428
433
|
}
|
|
429
434
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
}
|
|
435
|
+
this.authLoading = false;
|
|
436
|
+
this.notify();
|
|
437
|
+
return;
|
|
434
438
|
}
|
|
435
439
|
this.authLoading = false;
|
|
436
440
|
this.notify();
|
|
@@ -491,7 +495,12 @@ var AuthService = class extends BaseService {
|
|
|
491
495
|
this.user = null;
|
|
492
496
|
this.authError = null;
|
|
493
497
|
}
|
|
494
|
-
|
|
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);
|
|
495
504
|
} catch (error) {
|
|
496
505
|
const restorationError = error instanceof Error ? error : new Error("Unknown error during auth initialization");
|
|
497
506
|
logger.error("AuthService", "Error during auth initialization:", restorationError);
|
|
@@ -618,6 +627,8 @@ var OrganisationService = class extends BaseService {
|
|
|
618
627
|
this._roleMapState = /* @__PURE__ */ new Map();
|
|
619
628
|
this._isLoading = false;
|
|
620
629
|
this._error = null;
|
|
630
|
+
this._isSuperAdmin = false;
|
|
631
|
+
// Cache super admin status
|
|
621
632
|
this._isContextReady = false;
|
|
622
633
|
this.retryCount = 0;
|
|
623
634
|
// Dependencies
|
|
@@ -658,14 +669,16 @@ var OrganisationService = class extends BaseService {
|
|
|
658
669
|
// Additional methods for testing
|
|
659
670
|
setSelectedOrganisation(organisation) {
|
|
660
671
|
if (organisation && this._organisations.length > 0) {
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
672
|
+
if (!this._isSuperAdmin) {
|
|
673
|
+
const isValidOrg = this._organisations.some((org) => org.id === organisation.id);
|
|
674
|
+
if (!isValidOrg) {
|
|
675
|
+
logger.warn("OrganisationService", "Attempted to set invalid organisation - not in user's accessible organisations", {
|
|
676
|
+
organisationId: organisation.id,
|
|
677
|
+
organisationName: organisation.name,
|
|
678
|
+
accessibleOrgIds: this._organisations.map((o) => o.id)
|
|
679
|
+
});
|
|
680
|
+
return;
|
|
681
|
+
}
|
|
669
682
|
}
|
|
670
683
|
}
|
|
671
684
|
this._selectedOrganisation = organisation;
|
|
@@ -704,6 +717,9 @@ var OrganisationService = class extends BaseService {
|
|
|
704
717
|
updateDependencies(user, session) {
|
|
705
718
|
const wasAuthenticated = !!(this.user && this.session);
|
|
706
719
|
const isAuthenticated = !!(user && session);
|
|
720
|
+
if (this.user?.id !== user?.id) {
|
|
721
|
+
this._isSuperAdmin = false;
|
|
722
|
+
}
|
|
707
723
|
this.user = user;
|
|
708
724
|
this.session = session;
|
|
709
725
|
if (wasAuthenticated && !isAuthenticated) {
|
|
@@ -859,118 +875,110 @@ var OrganisationService = class extends BaseService {
|
|
|
859
875
|
this._error = null;
|
|
860
876
|
this.notify();
|
|
861
877
|
try {
|
|
862
|
-
let memberships, membershipError;
|
|
878
|
+
let memberships, membershipError, organisations = [];
|
|
863
879
|
try {
|
|
864
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
865
|
-
const timeoutId = setTimeout(() => reject(new Error("RPC call timeout after 10 seconds")), 1e4);
|
|
866
|
-
abortSignal.addEventListener("abort", () => {
|
|
867
|
-
clearTimeout(timeoutId);
|
|
868
|
-
reject(new Error("Request aborted"));
|
|
869
|
-
});
|
|
870
|
-
});
|
|
871
|
-
const rpcPromise = this.supabaseClient.rpc("data_user_organisation_roles_get", {
|
|
872
|
-
p_user_id: this.user.id,
|
|
873
|
-
p_organisation_id: null
|
|
874
|
-
});
|
|
875
880
|
if (abortSignal.aborted) {
|
|
876
881
|
throw new Error("Request aborted");
|
|
877
882
|
}
|
|
878
|
-
const
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
883
|
+
const { data: rolesData, error: rolesError } = await this.supabaseClient.from("rbac_organisation_roles").select(`
|
|
884
|
+
id,
|
|
885
|
+
user_id,
|
|
886
|
+
organisation_id,
|
|
887
|
+
role,
|
|
888
|
+
status,
|
|
889
|
+
granted_at,
|
|
890
|
+
granted_by,
|
|
891
|
+
revoked_at,
|
|
892
|
+
revoked_by,
|
|
893
|
+
notes,
|
|
894
|
+
created_at,
|
|
895
|
+
updated_at,
|
|
896
|
+
core_organisations!inner(
|
|
897
|
+
id,
|
|
898
|
+
name,
|
|
899
|
+
display_name,
|
|
900
|
+
subscription_tier,
|
|
901
|
+
settings,
|
|
902
|
+
is_active,
|
|
903
|
+
parent_id,
|
|
904
|
+
created_at,
|
|
905
|
+
updated_at
|
|
906
|
+
)
|
|
907
|
+
`).eq("user_id", this.user.id).eq("status", "active").is("revoked_at", null);
|
|
908
|
+
if (rolesError) {
|
|
909
|
+
logger.error("OrganisationService", "Error loading organisation roles:", rolesError);
|
|
910
|
+
throw rolesError;
|
|
911
|
+
}
|
|
912
|
+
memberships = rolesData?.map((m) => ({
|
|
882
913
|
...m,
|
|
883
914
|
user_id: assertUserId(m.user_id),
|
|
884
915
|
organisation_id: assertOrganisationId(m.organisation_id)
|
|
885
916
|
})) || [];
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
role,
|
|
902
|
-
status,
|
|
903
|
-
granted_at,
|
|
904
|
-
granted_by,
|
|
905
|
-
revoked_at,
|
|
906
|
-
revoked_by,
|
|
907
|
-
notes,
|
|
908
|
-
created_at,
|
|
909
|
-
updated_at,
|
|
910
|
-
organisations!inner(
|
|
911
|
-
id,
|
|
912
|
-
name,
|
|
913
|
-
display_name,
|
|
914
|
-
subscription_tier,
|
|
915
|
-
settings,
|
|
916
|
-
is_active,
|
|
917
|
-
parent_id,
|
|
918
|
-
created_at,
|
|
919
|
-
updated_at
|
|
920
|
-
)
|
|
921
|
-
`).eq("user_id", this.user.id).eq("status", "active").is("revoked_at", null).in("role", ["org_admin", "leader", "member", "supporter"]);
|
|
922
|
-
if (fallbackError) {
|
|
923
|
-
logger.error("OrganisationService", "Fallback query also failed:", fallbackError);
|
|
924
|
-
throw membershipError;
|
|
925
|
-
}
|
|
926
|
-
memberships = fallbackData?.map((m) => ({
|
|
927
|
-
...m,
|
|
928
|
-
user_id: assertUserId(m.user_id),
|
|
929
|
-
organisation_id: assertOrganisationId(m.organisation_id)
|
|
930
|
-
})) || [];
|
|
931
|
-
membershipError = null;
|
|
932
|
-
} catch (fallbackErr) {
|
|
933
|
-
logger.error("OrganisationService", "Fallback query failed:", fallbackErr);
|
|
934
|
-
throw membershipError;
|
|
917
|
+
const organisationsMap = /* @__PURE__ */ new Map();
|
|
918
|
+
rolesData?.forEach((role) => {
|
|
919
|
+
const orgData = role.core_organisations;
|
|
920
|
+
if (orgData && role.organisation_id && !organisationsMap.has(role.organisation_id)) {
|
|
921
|
+
organisationsMap.set(role.organisation_id, {
|
|
922
|
+
id: orgData.id,
|
|
923
|
+
name: orgData.name,
|
|
924
|
+
display_name: orgData.display_name,
|
|
925
|
+
subscription_tier: orgData.subscription_tier,
|
|
926
|
+
settings: orgData.settings,
|
|
927
|
+
is_active: orgData.is_active,
|
|
928
|
+
parent_id: orgData.parent_id,
|
|
929
|
+
created_at: orgData.created_at,
|
|
930
|
+
updated_at: orgData.updated_at
|
|
931
|
+
});
|
|
935
932
|
}
|
|
933
|
+
});
|
|
934
|
+
organisations = Array.from(organisationsMap.values());
|
|
935
|
+
} catch (queryError) {
|
|
936
|
+
if (queryError instanceof Error) {
|
|
937
|
+
membershipError = queryError;
|
|
938
|
+
} else if (queryError && typeof queryError === "object" && "message" in queryError) {
|
|
939
|
+
membershipError = new Error(String(queryError.message));
|
|
936
940
|
} else {
|
|
937
|
-
|
|
941
|
+
membershipError = new Error(String(queryError));
|
|
942
|
+
}
|
|
943
|
+
logger.error("OrganisationService", "Error loading organisation roles:", membershipError);
|
|
944
|
+
throw membershipError;
|
|
945
|
+
}
|
|
946
|
+
let userIsSuperAdmin = false;
|
|
947
|
+
if (this.user?.id) {
|
|
948
|
+
try {
|
|
949
|
+
userIsSuperAdmin = await isSuperAdmin(this.user.id);
|
|
950
|
+
this._isSuperAdmin = userIsSuperAdmin;
|
|
951
|
+
} catch (error) {
|
|
952
|
+
logger.warn("OrganisationService", "Failed to check super admin status", { error });
|
|
953
|
+
this._isSuperAdmin = false;
|
|
938
954
|
}
|
|
955
|
+
} else {
|
|
956
|
+
this._isSuperAdmin = false;
|
|
939
957
|
}
|
|
940
958
|
if (!memberships || memberships.length === 0) {
|
|
959
|
+
if (userIsSuperAdmin) {
|
|
960
|
+
this._organisations = [];
|
|
961
|
+
this._userMemberships = [];
|
|
962
|
+
this._isLoading = false;
|
|
963
|
+
this._error = null;
|
|
964
|
+
this._isContextReady = true;
|
|
965
|
+
this.notify();
|
|
966
|
+
return;
|
|
967
|
+
}
|
|
941
968
|
throw new Error("User has no active organisation memberships");
|
|
942
969
|
}
|
|
943
|
-
|
|
944
|
-
if (
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
return
|
|
952
|
-
}
|
|
953
|
-
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);
|
|
954
|
-
if (!isValidUuid) {
|
|
955
|
-
logger.warn("OrganisationService", "Invalid UUID format:", trimmedId);
|
|
970
|
+
if (!organisations || organisations.length === 0) {
|
|
971
|
+
if (userIsSuperAdmin) {
|
|
972
|
+
this._organisations = [];
|
|
973
|
+
this._userMemberships = [];
|
|
974
|
+
this._isLoading = false;
|
|
975
|
+
this._error = null;
|
|
976
|
+
this._isContextReady = true;
|
|
977
|
+
this.notify();
|
|
978
|
+
return;
|
|
956
979
|
}
|
|
957
|
-
|
|
958
|
-
});
|
|
959
|
-
if (organisationIds.length === 0) {
|
|
960
|
-
logger.warn("OrganisationService", "No valid organisation IDs found in memberships:", memberships);
|
|
961
|
-
throw new Error("No valid organisation IDs found in memberships");
|
|
980
|
+
throw new Error("No organisations found in role data");
|
|
962
981
|
}
|
|
963
|
-
if (abortSignal.aborted) {
|
|
964
|
-
throw new Error("Request aborted");
|
|
965
|
-
}
|
|
966
|
-
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");
|
|
967
|
-
if (orgError) {
|
|
968
|
-
logger.error("OrganisationService", "Error loading organisations:", orgError);
|
|
969
|
-
throw orgError;
|
|
970
|
-
}
|
|
971
|
-
const organisations = allOrganisations?.filter(
|
|
972
|
-
(org) => organisationIds.includes(org.id)
|
|
973
|
-
) || [];
|
|
974
982
|
const roleMap = /* @__PURE__ */ new Map();
|
|
975
983
|
memberships?.forEach((membership) => {
|
|
976
984
|
roleMap.set(membership.organisation_id, membership.role);
|
|
@@ -978,6 +986,15 @@ var OrganisationService = class extends BaseService {
|
|
|
978
986
|
const orgs = organisations;
|
|
979
987
|
const activeOrgs = orgs.filter((org) => org.is_active);
|
|
980
988
|
if (activeOrgs.length === 0) {
|
|
989
|
+
if (userIsSuperAdmin) {
|
|
990
|
+
this._organisations = [];
|
|
991
|
+
this._userMemberships = [];
|
|
992
|
+
this._isLoading = false;
|
|
993
|
+
this._error = null;
|
|
994
|
+
this._isContextReady = true;
|
|
995
|
+
this.notify();
|
|
996
|
+
return;
|
|
997
|
+
}
|
|
981
998
|
throw new Error("User has no access to active organisations");
|
|
982
999
|
}
|
|
983
1000
|
this._organisations = activeOrgs;
|
|
@@ -995,16 +1012,13 @@ var OrganisationService = class extends BaseService {
|
|
|
995
1012
|
initialOrg = validPersistedOrg;
|
|
996
1013
|
selectionMethod = "persisted";
|
|
997
1014
|
} else {
|
|
998
|
-
logger.warn("OrganisationService", "Persisted organisation not found in active orgs, clearing cache");
|
|
999
1015
|
localStorage.removeItem("pace-core-selected-organisation");
|
|
1000
1016
|
}
|
|
1001
1017
|
} else {
|
|
1002
|
-
logger.warn("OrganisationService", "Invalid persisted organisation ID, clearing cache");
|
|
1003
1018
|
localStorage.removeItem("pace-core-selected-organisation");
|
|
1004
1019
|
}
|
|
1005
1020
|
}
|
|
1006
1021
|
} catch (storageError) {
|
|
1007
|
-
logger.warn("OrganisationService", "Failed to restore persisted organisation:", storageError);
|
|
1008
1022
|
localStorage.removeItem("pace-core-selected-organisation");
|
|
1009
1023
|
}
|
|
1010
1024
|
if (!initialOrg) {
|
|
@@ -1039,9 +1053,7 @@ var OrganisationService = class extends BaseService {
|
|
|
1039
1053
|
this.hasFailedRef = false;
|
|
1040
1054
|
} catch (err) {
|
|
1041
1055
|
const error = err;
|
|
1042
|
-
if (error.message
|
|
1043
|
-
logger.warn("OrganisationService", "User has no active organisations (this is expected for users without organisation access):", error);
|
|
1044
|
-
} else {
|
|
1056
|
+
if (error.message !== "User has no access to active organisations") {
|
|
1045
1057
|
logger.error("OrganisationService", "Failed to load organisations:", err);
|
|
1046
1058
|
}
|
|
1047
1059
|
this._error = error;
|
|
@@ -1183,10 +1195,6 @@ var EventService = class extends BaseService {
|
|
|
1183
1195
|
if (user?.id) {
|
|
1184
1196
|
try {
|
|
1185
1197
|
this.isSuperAdmin = await isSuperAdmin(user.id);
|
|
1186
|
-
logger.debug("EventService", "Updated super admin status", {
|
|
1187
|
-
userId: user.id,
|
|
1188
|
-
isSuperAdmin: this.isSuperAdmin
|
|
1189
|
-
});
|
|
1190
1198
|
} catch (error) {
|
|
1191
1199
|
logger.warn("EventService", "Failed to check super admin status", { error });
|
|
1192
1200
|
this.isSuperAdmin = false;
|
|
@@ -1210,7 +1218,7 @@ var EventService = class extends BaseService {
|
|
|
1210
1218
|
}
|
|
1211
1219
|
// Event state getters
|
|
1212
1220
|
getEvents() {
|
|
1213
|
-
return
|
|
1221
|
+
return this.events;
|
|
1214
1222
|
}
|
|
1215
1223
|
getSelectedEvent() {
|
|
1216
1224
|
return this.selectedEvent;
|
|
@@ -1320,31 +1328,16 @@ var EventService = class extends BaseService {
|
|
|
1320
1328
|
}
|
|
1321
1329
|
// Lifecycle methods
|
|
1322
1330
|
async initialize() {
|
|
1323
|
-
logger.debug("EventService", "initialize() called", {
|
|
1324
|
-
isInitializedRef: this.isInitializedRef,
|
|
1325
|
-
hasUser: !!this.user,
|
|
1326
|
-
hasSession: !!this.session,
|
|
1327
|
-
appName: this.appName
|
|
1328
|
-
});
|
|
1329
1331
|
await super.initialize();
|
|
1330
1332
|
}
|
|
1331
1333
|
cleanup() {
|
|
1332
1334
|
super.cleanup();
|
|
1333
1335
|
}
|
|
1334
1336
|
async doInitialize() {
|
|
1335
|
-
logger.debug("EventService", "doInitialize() called", {
|
|
1336
|
-
isInitializedRef: this.isInitializedRef,
|
|
1337
|
-
isFetchingRef: this.isFetchingRef,
|
|
1338
|
-
hasUser: !!this.user,
|
|
1339
|
-
hasSession: !!this.session,
|
|
1340
|
-
appName: this.appName
|
|
1341
|
-
});
|
|
1342
1337
|
if (this.isInitializedRef) {
|
|
1343
|
-
logger.debug("EventService", "Skipping initialization - already initialized");
|
|
1344
1338
|
return;
|
|
1345
1339
|
}
|
|
1346
1340
|
if (this.isFetchingRef) {
|
|
1347
|
-
logger.debug("EventService", "Skipping initialization - already fetching");
|
|
1348
1341
|
return;
|
|
1349
1342
|
}
|
|
1350
1343
|
try {
|
|
@@ -1355,14 +1348,8 @@ var EventService = class extends BaseService {
|
|
|
1355
1348
|
logger.warn("EventService", "Failed to clean up old storage keys:", error);
|
|
1356
1349
|
}
|
|
1357
1350
|
if (!this.user) {
|
|
1358
|
-
logger.debug("EventService", "Skipping initialization - missing user");
|
|
1359
1351
|
return;
|
|
1360
1352
|
}
|
|
1361
|
-
logger.debug("EventService", "Initializing - fetching events", {
|
|
1362
|
-
userId: this.user.id,
|
|
1363
|
-
organisationId: this.selectedOrganisation?.id || "derived-from-event",
|
|
1364
|
-
appName: this.appName
|
|
1365
|
-
});
|
|
1366
1353
|
await this.fetchEvents(false);
|
|
1367
1354
|
this.isInitializedRef = true;
|
|
1368
1355
|
}
|
|
@@ -1370,19 +1357,12 @@ var EventService = class extends BaseService {
|
|
|
1370
1357
|
}
|
|
1371
1358
|
async fetchEvents(skipLoadPersisted = false) {
|
|
1372
1359
|
if (!this.user || !this.session || !this.supabaseClient || !this.appName) {
|
|
1373
|
-
logger.debug("EventService", "Skipping fetchEvents - missing dependencies", {
|
|
1374
|
-
hasUser: !!this.user,
|
|
1375
|
-
hasSession: !!this.session,
|
|
1376
|
-
hasSupabaseClient: !!this.supabaseClient,
|
|
1377
|
-
appName: this.appName
|
|
1378
|
-
});
|
|
1379
1360
|
this.notify();
|
|
1380
1361
|
return;
|
|
1381
1362
|
}
|
|
1382
1363
|
this._isLoading = true;
|
|
1383
1364
|
this.notify();
|
|
1384
1365
|
if (this.isFetchingRef) {
|
|
1385
|
-
logger.debug("EventService", "Skipping fetchEvents - already fetching");
|
|
1386
1366
|
return;
|
|
1387
1367
|
}
|
|
1388
1368
|
this.isFetchingRef = true;
|
|
@@ -1404,18 +1384,11 @@ var EventService = class extends BaseService {
|
|
|
1404
1384
|
userIsSuperAdmin = await isSuperAdmin(this.user.id);
|
|
1405
1385
|
if (userIsSuperAdmin) {
|
|
1406
1386
|
organisationIdForRpc = null;
|
|
1407
|
-
logger.debug("EventService", "Super admin detected - fetching all events", {
|
|
1408
|
-
userId: this.user.id
|
|
1409
|
-
});
|
|
1410
1387
|
} else {
|
|
1411
1388
|
if (this.selectedEvent) {
|
|
1412
1389
|
organisationIdForRpc = this.selectedEvent.organisation_id;
|
|
1413
1390
|
} else if (this.appConfig?.requires_event === true) {
|
|
1414
1391
|
organisationIdForRpc = null;
|
|
1415
|
-
logger.debug("EventService", "Event-required app: fetching all accessible events (no event selected yet)", {
|
|
1416
|
-
userId: this.user.id,
|
|
1417
|
-
appName: this.appName
|
|
1418
|
-
});
|
|
1419
1392
|
} else if (this.selectedOrganisation) {
|
|
1420
1393
|
organisationIdForRpc = this.selectedOrganisation.id;
|
|
1421
1394
|
} else {
|
|
@@ -1439,22 +1412,11 @@ var EventService = class extends BaseService {
|
|
|
1439
1412
|
organisationIdForRpc = this.selectedOrganisation.id;
|
|
1440
1413
|
}
|
|
1441
1414
|
}
|
|
1442
|
-
logger.debug("EventService", "Fetching events via RPC", {
|
|
1443
|
-
userId: this.user.id,
|
|
1444
|
-
organisationId: organisationIdForRpc,
|
|
1445
|
-
appName: this.appName
|
|
1446
|
-
});
|
|
1447
1415
|
let { data, error: rpcError } = await this.supabaseClient.rpc("data_user_events_get", {
|
|
1448
1416
|
p_user_id: this.user.id,
|
|
1449
1417
|
p_organisation_id: organisationIdForRpc,
|
|
1450
1418
|
p_app_name: this.appName
|
|
1451
1419
|
});
|
|
1452
|
-
logger.debug("EventService", "RPC response received", {
|
|
1453
|
-
hasData: !!data,
|
|
1454
|
-
dataLength: Array.isArray(data) ? data.length : "not array",
|
|
1455
|
-
hasError: !!rpcError,
|
|
1456
|
-
error: rpcError
|
|
1457
|
-
});
|
|
1458
1420
|
if (rpcError) {
|
|
1459
1421
|
logger.error("EventService", "RPC error fetching events:", rpcError);
|
|
1460
1422
|
throw new Error(rpcError.message || "Failed to fetch events");
|
|
@@ -1579,13 +1541,6 @@ function EventServiceProvider({
|
|
|
1579
1541
|
const updateAndInitialize = async () => {
|
|
1580
1542
|
initializingRef.current = true;
|
|
1581
1543
|
try {
|
|
1582
|
-
logger.debug("EventServiceProvider", "Updating dependencies and initializing", {
|
|
1583
|
-
hasUser: !!user,
|
|
1584
|
-
hasSession: !!session,
|
|
1585
|
-
appName,
|
|
1586
|
-
hasSelectedOrganisation: !!selectedOrganisation,
|
|
1587
|
-
organisationId: selectedOrganisation?.id
|
|
1588
|
-
});
|
|
1589
1544
|
await eventService.updateDependencies(supabaseClient, user, session, appName, selectedOrganisation, setSelectedEventId);
|
|
1590
1545
|
if (!isMounted) return;
|
|
1591
1546
|
await eventService.initialize().catch((error) => {
|
|
@@ -1728,12 +1683,19 @@ var InactivityService = class extends BaseService {
|
|
|
1728
1683
|
if (this.inactivityTracker) {
|
|
1729
1684
|
this.inactivityTracker.resetActivity();
|
|
1730
1685
|
}
|
|
1686
|
+
const prevIsIdle = this._isIdle;
|
|
1687
|
+
const prevShowWarning = this._showWarning;
|
|
1688
|
+
const prevShowInactivityWarning = this._showInactivityWarning;
|
|
1689
|
+
const prevInactivityTimeRemaining = this._inactivityTimeRemaining;
|
|
1690
|
+
const prevTimeRemaining = this._timeRemaining;
|
|
1731
1691
|
this._isIdle = false;
|
|
1732
1692
|
this._showWarning = false;
|
|
1733
1693
|
this._showInactivityWarning = false;
|
|
1734
1694
|
this._inactivityTimeRemaining = 0;
|
|
1735
1695
|
this._timeRemaining = this.idleTimeoutMs;
|
|
1736
|
-
this.
|
|
1696
|
+
if (prevIsIdle !== this._isIdle || prevShowWarning !== this._showWarning || prevShowInactivityWarning !== this._showInactivityWarning || prevInactivityTimeRemaining !== this._inactivityTimeRemaining || prevTimeRemaining !== this._timeRemaining) {
|
|
1697
|
+
this.notify();
|
|
1698
|
+
}
|
|
1737
1699
|
}
|
|
1738
1700
|
startTracking() {
|
|
1739
1701
|
if (this.inactivityTracker) {
|
|
@@ -1827,8 +1789,39 @@ var InactivityService = class extends BaseService {
|
|
|
1827
1789
|
let idleTimer = null;
|
|
1828
1790
|
let warningTimer = null;
|
|
1829
1791
|
let lastActivity = Date.now();
|
|
1830
|
-
|
|
1831
|
-
|
|
1792
|
+
let pollInterval = null;
|
|
1793
|
+
let prevIsIdle = false;
|
|
1794
|
+
let prevShowWarning = false;
|
|
1795
|
+
let prevShowInactivityWarning = false;
|
|
1796
|
+
let prevInactivityTimeRemaining = 0;
|
|
1797
|
+
let prevTimeRemaining = this.idleTimeoutMs;
|
|
1798
|
+
const pollInactivityState = () => {
|
|
1799
|
+
const now = Date.now();
|
|
1800
|
+
const timeSinceActivity = now - lastActivity;
|
|
1801
|
+
const timeUntilIdle = this.idleTimeoutMs - timeSinceActivity;
|
|
1802
|
+
const timeUntilWarning = this.idleTimeoutMs - this.warnBeforeMs - timeSinceActivity;
|
|
1803
|
+
const newIsIdle = timeSinceActivity >= this.idleTimeoutMs - this.warnBeforeMs;
|
|
1804
|
+
const newShowWarning = newIsIdle && timeSinceActivity < this.idleTimeoutMs;
|
|
1805
|
+
const newShowInactivityWarning = newShowWarning;
|
|
1806
|
+
const newInactivityTimeRemaining = newShowWarning ? Math.ceil((this.idleTimeoutMs - timeSinceActivity) / 1e3) : 0;
|
|
1807
|
+
const newTimeRemaining = Math.max(0, timeUntilIdle);
|
|
1808
|
+
const stateChanged = prevIsIdle !== newIsIdle || prevShowWarning !== newShowWarning || prevShowInactivityWarning !== newShowInactivityWarning || prevInactivityTimeRemaining !== newInactivityTimeRemaining || prevTimeRemaining !== newTimeRemaining;
|
|
1809
|
+
if (stateChanged) {
|
|
1810
|
+
this._isIdle = newIsIdle;
|
|
1811
|
+
this._showWarning = newShowWarning;
|
|
1812
|
+
this._showInactivityWarning = newShowInactivityWarning;
|
|
1813
|
+
this._inactivityTimeRemaining = newInactivityTimeRemaining;
|
|
1814
|
+
this._timeRemaining = newTimeRemaining;
|
|
1815
|
+
prevIsIdle = newIsIdle;
|
|
1816
|
+
prevShowWarning = newShowWarning;
|
|
1817
|
+
prevShowInactivityWarning = newShowInactivityWarning;
|
|
1818
|
+
prevInactivityTimeRemaining = newInactivityTimeRemaining;
|
|
1819
|
+
prevTimeRemaining = newTimeRemaining;
|
|
1820
|
+
this.notify();
|
|
1821
|
+
if (newIsIdle && timeSinceActivity >= this.idleTimeoutMs) {
|
|
1822
|
+
this.handleIdleLogout();
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1832
1825
|
if (idleTimer) {
|
|
1833
1826
|
clearTimeout(idleTimer);
|
|
1834
1827
|
idleTimer = null;
|
|
@@ -1837,42 +1830,48 @@ var InactivityService = class extends BaseService {
|
|
|
1837
1830
|
clearTimeout(warningTimer);
|
|
1838
1831
|
warningTimer = null;
|
|
1839
1832
|
}
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
this.notify();
|
|
1845
|
-
};
|
|
1846
|
-
const startIdleTimer = () => {
|
|
1847
|
-
if (idleTimer) {
|
|
1848
|
-
clearTimeout(idleTimer);
|
|
1833
|
+
if (!newIsIdle && timeUntilIdle > 0) {
|
|
1834
|
+
idleTimer = setTimeout(() => {
|
|
1835
|
+
pollInactivityState();
|
|
1836
|
+
}, Math.min(1e4, timeUntilIdle));
|
|
1849
1837
|
}
|
|
1850
|
-
|
|
1851
|
-
this._isIdle = true;
|
|
1852
|
-
this._showWarning = true;
|
|
1853
|
-
this.notify();
|
|
1838
|
+
if (newShowWarning && timeUntilIdle > 0) {
|
|
1854
1839
|
warningTimer = setTimeout(() => {
|
|
1855
1840
|
this.handleIdleLogout();
|
|
1856
|
-
},
|
|
1857
|
-
}
|
|
1841
|
+
}, timeUntilIdle);
|
|
1842
|
+
}
|
|
1858
1843
|
};
|
|
1859
|
-
const
|
|
1844
|
+
const resetTimers = () => {
|
|
1845
|
+
lastActivity = Date.now();
|
|
1846
|
+
if (idleTimer) {
|
|
1847
|
+
clearTimeout(idleTimer);
|
|
1848
|
+
idleTimer = null;
|
|
1849
|
+
}
|
|
1860
1850
|
if (warningTimer) {
|
|
1861
1851
|
clearTimeout(warningTimer);
|
|
1852
|
+
warningTimer = null;
|
|
1862
1853
|
}
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1854
|
+
this._showInactivityWarning = false;
|
|
1855
|
+
this._inactivityTimeRemaining = 0;
|
|
1856
|
+
this._isIdle = false;
|
|
1857
|
+
this._showWarning = false;
|
|
1858
|
+
prevIsIdle = false;
|
|
1859
|
+
prevShowWarning = false;
|
|
1860
|
+
prevShowInactivityWarning = false;
|
|
1861
|
+
prevInactivityTimeRemaining = 0;
|
|
1862
|
+
prevTimeRemaining = this.idleTimeoutMs;
|
|
1866
1863
|
};
|
|
1867
1864
|
const activityEvents = ["mousedown", "mousemove", "keypress", "scroll", "touchstart", "click"];
|
|
1868
1865
|
const handleActivity = () => {
|
|
1869
1866
|
resetTimers();
|
|
1870
|
-
startIdleTimer();
|
|
1871
1867
|
};
|
|
1872
1868
|
activityEvents.forEach((event) => {
|
|
1873
1869
|
document.addEventListener(event, handleActivity, true);
|
|
1874
1870
|
});
|
|
1875
|
-
|
|
1871
|
+
pollInterval = setInterval(() => {
|
|
1872
|
+
pollInactivityState();
|
|
1873
|
+
}, 1e4);
|
|
1874
|
+
pollInactivityState();
|
|
1876
1875
|
this.cleanupHandlers = () => {
|
|
1877
1876
|
if (idleTimer) {
|
|
1878
1877
|
clearTimeout(idleTimer);
|
|
@@ -1882,6 +1881,10 @@ var InactivityService = class extends BaseService {
|
|
|
1882
1881
|
clearTimeout(warningTimer);
|
|
1883
1882
|
warningTimer = null;
|
|
1884
1883
|
}
|
|
1884
|
+
if (pollInterval) {
|
|
1885
|
+
clearInterval(pollInterval);
|
|
1886
|
+
pollInterval = null;
|
|
1887
|
+
}
|
|
1885
1888
|
activityEvents.forEach((event) => {
|
|
1886
1889
|
document.removeEventListener(event, handleActivity, true);
|
|
1887
1890
|
});
|
|
@@ -1940,29 +1943,61 @@ function InactivityServiceProvider({
|
|
|
1940
1943
|
}
|
|
1941
1944
|
|
|
1942
1945
|
// src/hooks/services/useAuthService.ts
|
|
1943
|
-
import { useContext, useReducer, useEffect as useEffect5 } from "react";
|
|
1946
|
+
import { useContext, useReducer, useEffect as useEffect5, useRef as useRef4 } from "react";
|
|
1944
1947
|
function useAuthService() {
|
|
1945
1948
|
const context = useContext(AuthServiceContext);
|
|
1946
1949
|
if (!context) {
|
|
1947
1950
|
throw new Error("useAuthService must be used within AuthServiceProvider");
|
|
1948
1951
|
}
|
|
1949
1952
|
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
|
1953
|
+
const timeoutRef = useRef4(null);
|
|
1950
1954
|
useEffect5(() => {
|
|
1951
|
-
|
|
1955
|
+
const debouncedUpdate = () => {
|
|
1956
|
+
if (timeoutRef.current) {
|
|
1957
|
+
clearTimeout(timeoutRef.current);
|
|
1958
|
+
}
|
|
1959
|
+
timeoutRef.current = setTimeout(() => {
|
|
1960
|
+
forceUpdate();
|
|
1961
|
+
timeoutRef.current = null;
|
|
1962
|
+
}, 50);
|
|
1963
|
+
};
|
|
1964
|
+
const unsubscribe = context.authService.subscribe(debouncedUpdate);
|
|
1965
|
+
return () => {
|
|
1966
|
+
unsubscribe();
|
|
1967
|
+
if (timeoutRef.current) {
|
|
1968
|
+
clearTimeout(timeoutRef.current);
|
|
1969
|
+
}
|
|
1970
|
+
};
|
|
1952
1971
|
}, [context.authService]);
|
|
1953
1972
|
return context.authService;
|
|
1954
1973
|
}
|
|
1955
1974
|
|
|
1956
1975
|
// src/hooks/services/useOrganisationService.ts
|
|
1957
|
-
import { useContext as useContext2, useReducer as useReducer2, useEffect as useEffect6 } from "react";
|
|
1976
|
+
import { useContext as useContext2, useReducer as useReducer2, useEffect as useEffect6, useRef as useRef5 } from "react";
|
|
1958
1977
|
function useOrganisationService() {
|
|
1959
1978
|
const context = useContext2(OrganisationServiceContext);
|
|
1960
1979
|
if (!context) {
|
|
1961
1980
|
throw new Error("useOrganisationService must be used within OrganisationServiceProvider");
|
|
1962
1981
|
}
|
|
1963
1982
|
const [, forceUpdate] = useReducer2((x) => x + 1, 0);
|
|
1983
|
+
const timeoutRef = useRef5(null);
|
|
1964
1984
|
useEffect6(() => {
|
|
1965
|
-
|
|
1985
|
+
const debouncedUpdate = () => {
|
|
1986
|
+
if (timeoutRef.current) {
|
|
1987
|
+
clearTimeout(timeoutRef.current);
|
|
1988
|
+
}
|
|
1989
|
+
timeoutRef.current = setTimeout(() => {
|
|
1990
|
+
forceUpdate();
|
|
1991
|
+
timeoutRef.current = null;
|
|
1992
|
+
}, 50);
|
|
1993
|
+
};
|
|
1994
|
+
const unsubscribe = context.organisationService.subscribe(debouncedUpdate);
|
|
1995
|
+
return () => {
|
|
1996
|
+
unsubscribe();
|
|
1997
|
+
if (timeoutRef.current) {
|
|
1998
|
+
clearTimeout(timeoutRef.current);
|
|
1999
|
+
}
|
|
2000
|
+
};
|
|
1966
2001
|
}, [context.organisationService]);
|
|
1967
2002
|
return context.organisationService;
|
|
1968
2003
|
}
|
|
@@ -1991,29 +2026,61 @@ function useOrganisations() {
|
|
|
1991
2026
|
}
|
|
1992
2027
|
|
|
1993
2028
|
// src/hooks/services/useEventService.ts
|
|
1994
|
-
import { useContext as useContext3, useReducer as useReducer3, useEffect as useEffect7 } from "react";
|
|
2029
|
+
import { useContext as useContext3, useReducer as useReducer3, useEffect as useEffect7, useRef as useRef6 } from "react";
|
|
1995
2030
|
function useEventService() {
|
|
1996
2031
|
const context = useContext3(EventServiceContext);
|
|
1997
2032
|
if (!context) {
|
|
1998
2033
|
throw new Error("useEventService must be used within EventServiceProvider");
|
|
1999
2034
|
}
|
|
2000
2035
|
const [, forceUpdate] = useReducer3((x) => x + 1, 0);
|
|
2036
|
+
const timeoutRef = useRef6(null);
|
|
2001
2037
|
useEffect7(() => {
|
|
2002
|
-
|
|
2038
|
+
const debouncedUpdate = () => {
|
|
2039
|
+
if (timeoutRef.current) {
|
|
2040
|
+
clearTimeout(timeoutRef.current);
|
|
2041
|
+
}
|
|
2042
|
+
timeoutRef.current = setTimeout(() => {
|
|
2043
|
+
forceUpdate();
|
|
2044
|
+
timeoutRef.current = null;
|
|
2045
|
+
}, 50);
|
|
2046
|
+
};
|
|
2047
|
+
const unsubscribe = context.eventService.subscribe(debouncedUpdate);
|
|
2048
|
+
return () => {
|
|
2049
|
+
unsubscribe();
|
|
2050
|
+
if (timeoutRef.current) {
|
|
2051
|
+
clearTimeout(timeoutRef.current);
|
|
2052
|
+
}
|
|
2053
|
+
};
|
|
2003
2054
|
}, [context.eventService]);
|
|
2004
2055
|
return context.eventService;
|
|
2005
2056
|
}
|
|
2006
2057
|
|
|
2007
2058
|
// src/hooks/services/useInactivityService.ts
|
|
2008
|
-
import { useContext as useContext4, useReducer as useReducer4, useEffect as useEffect8 } from "react";
|
|
2059
|
+
import { useContext as useContext4, useReducer as useReducer4, useEffect as useEffect8, useRef as useRef7 } from "react";
|
|
2009
2060
|
function useInactivityService() {
|
|
2010
2061
|
const context = useContext4(InactivityServiceContext);
|
|
2011
2062
|
if (!context) {
|
|
2012
2063
|
throw new Error("useInactivityService must be used within InactivityServiceProvider");
|
|
2013
2064
|
}
|
|
2014
2065
|
const [, forceUpdate] = useReducer4((x) => x + 1, 0);
|
|
2066
|
+
const timeoutRef = useRef7(null);
|
|
2015
2067
|
useEffect8(() => {
|
|
2016
|
-
|
|
2068
|
+
const debouncedUpdate = () => {
|
|
2069
|
+
if (timeoutRef.current) {
|
|
2070
|
+
clearTimeout(timeoutRef.current);
|
|
2071
|
+
}
|
|
2072
|
+
timeoutRef.current = setTimeout(() => {
|
|
2073
|
+
forceUpdate();
|
|
2074
|
+
timeoutRef.current = null;
|
|
2075
|
+
}, 50);
|
|
2076
|
+
};
|
|
2077
|
+
const unsubscribe = context.inactivityService.subscribe(debouncedUpdate);
|
|
2078
|
+
return () => {
|
|
2079
|
+
unsubscribe();
|
|
2080
|
+
if (timeoutRef.current) {
|
|
2081
|
+
clearTimeout(timeoutRef.current);
|
|
2082
|
+
}
|
|
2083
|
+
};
|
|
2017
2084
|
}, [context.inactivityService]);
|
|
2018
2085
|
return context.inactivityService;
|
|
2019
2086
|
}
|
|
@@ -2071,8 +2138,7 @@ var useUnifiedAuth = () => {
|
|
|
2071
2138
|
function UnifiedAuthContextProvider({
|
|
2072
2139
|
children,
|
|
2073
2140
|
appName,
|
|
2074
|
-
appConfig
|
|
2075
|
-
// Default to requiring events
|
|
2141
|
+
appConfig: appConfigProp,
|
|
2076
2142
|
supabaseClient: supabaseClientProp,
|
|
2077
2143
|
...props
|
|
2078
2144
|
}) {
|
|
@@ -2092,6 +2158,13 @@ function UnifiedAuthContextProvider({
|
|
|
2092
2158
|
restorationComplete,
|
|
2093
2159
|
restorationError
|
|
2094
2160
|
}), [isRestoring, restorationComplete, restorationError]);
|
|
2161
|
+
const [appConfigState, setAppConfigState] = useState3(appConfigProp || null);
|
|
2162
|
+
const isResolvingAppConfigRef = useRef8(false);
|
|
2163
|
+
const resolvedAppConfigRef = useRef8(null);
|
|
2164
|
+
const appConfig = useMemo6(() => {
|
|
2165
|
+
if (!appConfigState) return null;
|
|
2166
|
+
return { requires_event: appConfigState.requires_event };
|
|
2167
|
+
}, [appConfigState?.requires_event]);
|
|
2095
2168
|
let eventService;
|
|
2096
2169
|
try {
|
|
2097
2170
|
eventService = useEventService();
|
|
@@ -2115,9 +2188,9 @@ function UnifiedAuthContextProvider({
|
|
|
2115
2188
|
const isAuth = !!(currentUser && currentSession);
|
|
2116
2189
|
const supabase = useMemo6(() => supabaseClientProp, [supabaseClientProp]);
|
|
2117
2190
|
const [appId, setAppId] = useState3(void 0);
|
|
2118
|
-
const isResolvingAppIdRef =
|
|
2119
|
-
const resolvedAppIdRef =
|
|
2120
|
-
const resolvedUserIdRef =
|
|
2191
|
+
const isResolvingAppIdRef = useRef8(false);
|
|
2192
|
+
const resolvedAppIdRef = useRef8(void 0);
|
|
2193
|
+
const resolvedUserIdRef = useRef8(void 0);
|
|
2121
2194
|
useEffect10(() => {
|
|
2122
2195
|
if (!isAuth) {
|
|
2123
2196
|
resolvedAppIdRef.current = void 0;
|
|
@@ -2137,7 +2210,7 @@ function UnifiedAuthContextProvider({
|
|
|
2137
2210
|
resolvedUserIdRef.current = currentUserId;
|
|
2138
2211
|
const userId = currentUserId;
|
|
2139
2212
|
const appNameValue = appName;
|
|
2140
|
-
import("./api-
|
|
2213
|
+
import("./api-N774RPUA.js").then(async ({ resolveAppContext, setupRBAC }) => {
|
|
2141
2214
|
try {
|
|
2142
2215
|
setupRBAC(supabase);
|
|
2143
2216
|
const result = await resolveAppContext({
|
|
@@ -2147,10 +2220,6 @@ function UnifiedAuthContextProvider({
|
|
|
2147
2220
|
if (result?.appId) {
|
|
2148
2221
|
resolvedAppIdRef.current = result.appId;
|
|
2149
2222
|
setAppId(result.appId);
|
|
2150
|
-
logger.debug("UnifiedAuthProvider", "appId resolved on login", {
|
|
2151
|
-
appId: result.appId,
|
|
2152
|
-
appName: appNameValue
|
|
2153
|
-
});
|
|
2154
2223
|
} else {
|
|
2155
2224
|
resolvedUserIdRef.current = void 0;
|
|
2156
2225
|
}
|
|
@@ -2171,8 +2240,59 @@ function UnifiedAuthContextProvider({
|
|
|
2171
2240
|
});
|
|
2172
2241
|
}
|
|
2173
2242
|
}, [isAuth, currentUser?.id, supabase, appName]);
|
|
2243
|
+
useEffect10(() => {
|
|
2244
|
+
if (appConfigProp !== void 0) {
|
|
2245
|
+
setAppConfigState(appConfigProp);
|
|
2246
|
+
resolvedAppConfigRef.current = appConfigProp;
|
|
2247
|
+
return;
|
|
2248
|
+
}
|
|
2249
|
+
if (resolvedAppConfigRef.current !== null || isResolvingAppConfigRef.current) {
|
|
2250
|
+
return;
|
|
2251
|
+
}
|
|
2252
|
+
if (!supabase || !appName) {
|
|
2253
|
+
return;
|
|
2254
|
+
}
|
|
2255
|
+
isResolvingAppConfigRef.current = true;
|
|
2256
|
+
import("./api-N774RPUA.js").then(async ({ getAppConfigByName: getAppConfigByName2 }) => {
|
|
2257
|
+
try {
|
|
2258
|
+
const config = await getAppConfigByName2(appName);
|
|
2259
|
+
const resolvedConfig = config || { requires_event: false };
|
|
2260
|
+
if (resolvedAppConfigRef.current?.requires_event !== resolvedConfig.requires_event) {
|
|
2261
|
+
resolvedAppConfigRef.current = resolvedConfig;
|
|
2262
|
+
setAppConfigState(resolvedConfig);
|
|
2263
|
+
}
|
|
2264
|
+
if (import.meta.env.DEV && appName === "MINT") {
|
|
2265
|
+
logger.debug("UnifiedAuthProvider", "App config loaded", {
|
|
2266
|
+
appName,
|
|
2267
|
+
config: resolvedConfig,
|
|
2268
|
+
requiresEvent: resolvedConfig.requires_event
|
|
2269
|
+
});
|
|
2270
|
+
}
|
|
2271
|
+
} catch (error) {
|
|
2272
|
+
logger.warn("UnifiedAuthProvider", "Failed to load app config, defaulting to organisation-based", {
|
|
2273
|
+
error: error instanceof Error ? error.message : String(error),
|
|
2274
|
+
appName
|
|
2275
|
+
});
|
|
2276
|
+
if (resolvedAppConfigRef.current?.requires_event !== false) {
|
|
2277
|
+
const defaultConfig = { requires_event: false };
|
|
2278
|
+
resolvedAppConfigRef.current = defaultConfig;
|
|
2279
|
+
setAppConfigState(defaultConfig);
|
|
2280
|
+
}
|
|
2281
|
+
} finally {
|
|
2282
|
+
isResolvingAppConfigRef.current = false;
|
|
2283
|
+
}
|
|
2284
|
+
}).catch((importError) => {
|
|
2285
|
+
logger.error("UnifiedAuthProvider", "Failed to import RBAC API for app config", importError);
|
|
2286
|
+
isResolvingAppConfigRef.current = false;
|
|
2287
|
+
if (resolvedAppConfigRef.current?.requires_event !== false) {
|
|
2288
|
+
const defaultConfig = { requires_event: false };
|
|
2289
|
+
resolvedAppConfigRef.current = defaultConfig;
|
|
2290
|
+
setAppConfigState(defaultConfig);
|
|
2291
|
+
}
|
|
2292
|
+
});
|
|
2293
|
+
}, [supabase, appName, appConfigProp]);
|
|
2174
2294
|
const [, forceUpdate] = useReducer5((x) => x + 1, 0);
|
|
2175
|
-
const forceUpdateTimeoutRef =
|
|
2295
|
+
const forceUpdateTimeoutRef = useRef8(null);
|
|
2176
2296
|
const debouncedForceUpdate = useCallback(() => {
|
|
2177
2297
|
if (forceUpdateTimeoutRef.current) {
|
|
2178
2298
|
clearTimeout(forceUpdateTimeoutRef.current);
|
|
@@ -2180,12 +2300,12 @@ function UnifiedAuthContextProvider({
|
|
|
2180
2300
|
forceUpdateTimeoutRef.current = setTimeout(() => {
|
|
2181
2301
|
forceUpdate();
|
|
2182
2302
|
forceUpdateTimeoutRef.current = null;
|
|
2183
|
-
},
|
|
2303
|
+
}, 100);
|
|
2184
2304
|
}, [forceUpdate]);
|
|
2185
|
-
const authServiceRef =
|
|
2186
|
-
const organisationServiceRef =
|
|
2187
|
-
const eventServiceRef =
|
|
2188
|
-
const inactivityServiceRef =
|
|
2305
|
+
const authServiceRef = useRef8(authService);
|
|
2306
|
+
const organisationServiceRef = useRef8(organisationService);
|
|
2307
|
+
const eventServiceRef = useRef8(eventService);
|
|
2308
|
+
const inactivityServiceRef = useRef8(inactivityService);
|
|
2189
2309
|
useEffect10(() => {
|
|
2190
2310
|
authServiceRef.current = authService;
|
|
2191
2311
|
organisationServiceRef.current = organisationService;
|
|
@@ -2211,16 +2331,48 @@ function UnifiedAuthContextProvider({
|
|
|
2211
2331
|
const orgLoading = organisationService.isLoading();
|
|
2212
2332
|
const eventLoading = eventService.isLoading();
|
|
2213
2333
|
const restorationLoading = sessionRestoration.isRestoring && !sessionRestorationTimedOut && !sessionRestoration.restorationError;
|
|
2214
|
-
const
|
|
2334
|
+
const shouldIncludeOrgLoading = appName !== "ADMIN" && appName !== "PORTAL";
|
|
2335
|
+
const totalLoading = restorationLoading || authLoading || (shouldIncludeOrgLoading ? orgLoading : false) || eventLoading;
|
|
2215
2336
|
const authError = authService.getError();
|
|
2216
2337
|
const rawSelectedOrganisation = organisationService.getSelectedOrganisation();
|
|
2217
|
-
const organisations = organisationService.getOrganisations();
|
|
2218
|
-
const userMemberships = organisationService.getUserMemberships();
|
|
2219
2338
|
const organisationError = organisationService.getError();
|
|
2220
|
-
const selectedOrganisation = appConfig?.requires_event ? null : rawSelectedOrganisation;
|
|
2339
|
+
const selectedOrganisation = appConfig !== null && appConfig?.requires_event === true && !rawSelectedOrganisation ? null : rawSelectedOrganisation;
|
|
2340
|
+
useEffect10(() => {
|
|
2341
|
+
if (import.meta.env.DEV && appName === "MINT") {
|
|
2342
|
+
logger.debug("UnifiedAuthProvider", "Organisation state check", {
|
|
2343
|
+
rawSelectedOrganisation: rawSelectedOrganisation?.id || null,
|
|
2344
|
+
rawSelectedOrganisationType: typeof rawSelectedOrganisation,
|
|
2345
|
+
appConfig,
|
|
2346
|
+
appConfigRequiresEvent: appConfig?.requires_event,
|
|
2347
|
+
selectedOrganisation: selectedOrganisation?.id || null,
|
|
2348
|
+
selectedOrganisationId: selectedOrganisation?.id || null,
|
|
2349
|
+
checkResult: appConfig?.requires_event === true
|
|
2350
|
+
});
|
|
2351
|
+
}
|
|
2352
|
+
}, [appName, rawSelectedOrganisation?.id, appConfig?.requires_event, selectedOrganisation?.id]);
|
|
2221
2353
|
const hasValidOrganisationContext = organisationService.hasValidOrganisationContext();
|
|
2222
2354
|
const isContextReady = organisationService.isContextReady();
|
|
2223
|
-
const
|
|
2355
|
+
const rawEvents = eventService.getEvents();
|
|
2356
|
+
const rawOrganisations = organisationService.getOrganisations();
|
|
2357
|
+
const rawUserMemberships = organisationService.getUserMemberships();
|
|
2358
|
+
const events = useMemo6(() => {
|
|
2359
|
+
return rawEvents;
|
|
2360
|
+
}, [
|
|
2361
|
+
// Create dependency string from event IDs - only changes when events actually change
|
|
2362
|
+
rawEvents.map((e) => e.event_id || e.id).join(",")
|
|
2363
|
+
]);
|
|
2364
|
+
const organisations = useMemo6(() => {
|
|
2365
|
+
return rawOrganisations;
|
|
2366
|
+
}, [
|
|
2367
|
+
// Create dependency string from organisation IDs - only changes when orgs actually change
|
|
2368
|
+
rawOrganisations.map((o) => o.id).join(",")
|
|
2369
|
+
]);
|
|
2370
|
+
const userMemberships = useMemo6(() => {
|
|
2371
|
+
return rawUserMemberships;
|
|
2372
|
+
}, [
|
|
2373
|
+
// Create dependency string from membership IDs - only changes when memberships actually change
|
|
2374
|
+
rawUserMemberships.map((m) => `${m.organisation_id}-${m.user_id}`).join(",")
|
|
2375
|
+
]);
|
|
2224
2376
|
const selectedEvent = eventService.getSelectedEvent();
|
|
2225
2377
|
const eventError = eventService.getError();
|
|
2226
2378
|
const showInactivityWarning = inactivityService.getShowInactivityWarning();
|
|
@@ -2229,6 +2381,21 @@ function UnifiedAuthContextProvider({
|
|
|
2229
2381
|
const timeRemaining = inactivityService.getTimeRemaining();
|
|
2230
2382
|
const showWarning = inactivityService.isWarningShown();
|
|
2231
2383
|
const isTracking = inactivityService.isTracking();
|
|
2384
|
+
const inactivityState = useMemo6(() => ({
|
|
2385
|
+
showInactivityWarning,
|
|
2386
|
+
inactivityTimeRemaining,
|
|
2387
|
+
isIdle,
|
|
2388
|
+
timeRemaining,
|
|
2389
|
+
showWarning,
|
|
2390
|
+
isTracking
|
|
2391
|
+
}), [
|
|
2392
|
+
showInactivityWarning,
|
|
2393
|
+
inactivityTimeRemaining,
|
|
2394
|
+
isIdle,
|
|
2395
|
+
timeRemaining,
|
|
2396
|
+
showWarning,
|
|
2397
|
+
isTracking
|
|
2398
|
+
]);
|
|
2232
2399
|
const hasErrors = !!(authError || organisationError || eventError || sessionRestoration.restorationError);
|
|
2233
2400
|
const signIn = useCallback((email, password) => authService.signIn(email, password), [authService]);
|
|
2234
2401
|
const signUp = useCallback((email, password) => authService.signUp(email, password), [authService]);
|
|
@@ -2251,7 +2418,7 @@ function UnifiedAuthContextProvider({
|
|
|
2251
2418
|
const handleIdleLogout = useCallback(() => inactivityService.handleIdleLogout(), [inactivityService]);
|
|
2252
2419
|
const handleStaySignedIn = useCallback(() => inactivityService.handleStaySignedIn(), [inactivityService]);
|
|
2253
2420
|
const handleSignOutNow = useCallback(() => inactivityService.handleSignOutNow(), [inactivityService]);
|
|
2254
|
-
const prevStateRef =
|
|
2421
|
+
const prevStateRef = useRef8(null);
|
|
2255
2422
|
const isDev = import.meta.env.DEV || import.meta.env.MODE === "development";
|
|
2256
2423
|
if (isDev) {
|
|
2257
2424
|
const currentState = {
|
|
@@ -2282,6 +2449,7 @@ function UnifiedAuthContextProvider({
|
|
|
2282
2449
|
refreshSession,
|
|
2283
2450
|
// Organisation state
|
|
2284
2451
|
selectedOrganisation,
|
|
2452
|
+
selectedOrganisationId: selectedOrganisation?.id || null,
|
|
2285
2453
|
organisations,
|
|
2286
2454
|
userMemberships,
|
|
2287
2455
|
organisationLoading: orgLoading,
|
|
@@ -2299,18 +2467,19 @@ function UnifiedAuthContextProvider({
|
|
|
2299
2467
|
// Event state
|
|
2300
2468
|
events,
|
|
2301
2469
|
selectedEvent,
|
|
2470
|
+
selectedEventId: selectedEvent?.event_id || null,
|
|
2302
2471
|
eventLoading,
|
|
2303
2472
|
eventError,
|
|
2304
2473
|
// Event methods
|
|
2305
2474
|
setSelectedEvent,
|
|
2306
2475
|
refreshEvents,
|
|
2307
2476
|
// Inactivity state
|
|
2308
|
-
showInactivityWarning,
|
|
2309
|
-
inactivityTimeRemaining,
|
|
2310
|
-
isIdle,
|
|
2311
|
-
timeRemaining,
|
|
2312
|
-
showWarning,
|
|
2313
|
-
isTracking,
|
|
2477
|
+
showInactivityWarning: inactivityState.showInactivityWarning,
|
|
2478
|
+
inactivityTimeRemaining: inactivityState.inactivityTimeRemaining,
|
|
2479
|
+
isIdle: inactivityState.isIdle,
|
|
2480
|
+
timeRemaining: inactivityState.timeRemaining,
|
|
2481
|
+
showWarning: inactivityState.showWarning,
|
|
2482
|
+
isTracking: inactivityState.isTracking,
|
|
2314
2483
|
// Inactivity methods
|
|
2315
2484
|
resetActivity,
|
|
2316
2485
|
startTracking,
|
|
@@ -2349,12 +2518,8 @@ function UnifiedAuthContextProvider({
|
|
|
2349
2518
|
selectedEvent,
|
|
2350
2519
|
eventLoading,
|
|
2351
2520
|
eventError,
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
isIdle,
|
|
2355
|
-
timeRemaining,
|
|
2356
|
-
showWarning,
|
|
2357
|
-
isTracking,
|
|
2521
|
+
inactivityState,
|
|
2522
|
+
// Use memoized object instead of individual values
|
|
2358
2523
|
totalLoading,
|
|
2359
2524
|
hasErrors,
|
|
2360
2525
|
appName,
|
|
@@ -2397,7 +2562,7 @@ function EventServiceProviderWrapper({
|
|
|
2397
2562
|
appConfig
|
|
2398
2563
|
}) {
|
|
2399
2564
|
const { selectedOrganisation: rawSelectedOrganisation } = useOrganisations();
|
|
2400
|
-
const selectedOrganisation = appConfig?.requires_event ? null : rawSelectedOrganisation;
|
|
2565
|
+
const selectedOrganisation = appConfig !== null && appConfig?.requires_event === true && !rawSelectedOrganisation ? null : rawSelectedOrganisation;
|
|
2401
2566
|
const setSelectedEventId = useCallback(() => {
|
|
2402
2567
|
}, []);
|
|
2403
2568
|
return /* @__PURE__ */ jsx5(
|
|
@@ -2493,7 +2658,7 @@ function UnifiedAuthProvider({
|
|
|
2493
2658
|
renderInactivityWarning,
|
|
2494
2659
|
dangerouslyDisableInactivity = false
|
|
2495
2660
|
}) {
|
|
2496
|
-
const clientRef =
|
|
2661
|
+
const clientRef = useRef8(supabaseClient);
|
|
2497
2662
|
useEffect10(() => {
|
|
2498
2663
|
if (clientRef.current !== supabaseClient) {
|
|
2499
2664
|
logger.warn("UnifiedAuthProvider", "Supabase client reference changed - this may indicate multiple client instances are being created", {
|
|
@@ -2542,4 +2707,4 @@ export {
|
|
|
2542
2707
|
useUnifiedAuth,
|
|
2543
2708
|
UnifiedAuthProvider
|
|
2544
2709
|
};
|
|
2545
|
-
//# sourceMappingURL=chunk-
|
|
2710
|
+
//# sourceMappingURL=chunk-7FLMSG37.js.map
|