@jmruthers/pace-core 0.6.2 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/cursor-rules/00-pace-core-compliance.mdc +34 -2
- package/dist/{AuthService-BPvc3Ka0.d.ts → AuthService-Cb34EQs3.d.ts} +9 -1
- package/dist/{DataTable-TPTKCX4D.js → DataTable-E7YQZD7D.js} +9 -8
- package/dist/{PublicPageProvider-DC6kCaqf.d.ts → PublicPageProvider-DEMpysFR.d.ts} +45 -67
- package/dist/{UnifiedAuthProvider-CVcTjx-d.d.ts → UnifiedAuthProvider-CKvHP1MK.d.ts} +1 -8
- package/dist/{UnifiedAuthProvider-CH6Z342H.js → UnifiedAuthProvider-QPXO24B4.js} +5 -4
- package/dist/{api-MVVQZLJI.js → api-6LVZTHDS.js} +10 -10
- package/dist/{audit-B5P6FFIR.js → audit-V53FV5AG.js} +2 -2
- package/dist/chunk-36LVWXB2.js +227 -0
- package/dist/chunk-36LVWXB2.js.map +1 -0
- package/dist/{chunk-24UVZUZG.js → chunk-3LPHPB62.js} +129 -387
- package/dist/chunk-3LPHPB62.js.map +1 -0
- package/dist/{chunk-2UOI2FG5.js → chunk-5EC5MEWX.js} +4 -4
- package/dist/{chunk-3XC4CPTD.js → chunk-7JPAB3T5.js} +244 -5727
- package/dist/chunk-7JPAB3T5.js.map +1 -0
- package/dist/{chunk-6J4GEEJR.js → chunk-ATKZM7RX.js} +53 -27
- package/dist/chunk-ATKZM7RX.js.map +1 -0
- package/dist/{chunk-EHMR7VYL.js → chunk-AVMLPIM7.js} +443 -189
- package/dist/chunk-AVMLPIM7.js.map +1 -0
- package/dist/chunk-DGUM43GV.js +11 -0
- package/dist/{chunk-NECFR5MM.js → chunk-I6DAQMWX.js} +575 -647
- package/dist/chunk-I6DAQMWX.js.map +1 -0
- package/dist/{chunk-F2IMUDXZ.js → chunk-M7MPQISP.js} +2 -2
- package/dist/{chunk-XWQCNGTQ.js → chunk-NN6WWZ5U.js} +173 -79
- package/dist/chunk-NN6WWZ5U.js.map +1 -0
- package/dist/{chunk-MMZ7JXPU.js → chunk-OEWDTMG7.js} +13 -21
- package/dist/{chunk-MMZ7JXPU.js.map → chunk-OEWDTMG7.js.map} +1 -1
- package/dist/{chunk-SFZUDBL5.js → chunk-YKRAFF5K.js} +70 -56
- package/dist/chunk-YKRAFF5K.js.map +1 -0
- package/dist/components.d.ts +2 -2
- package/dist/components.js +12 -13
- package/dist/contextValidator-OOPCLPZW.js +9 -0
- package/dist/contextValidator-OOPCLPZW.js.map +1 -0
- package/dist/eslint-rules/pace-core-compliance.cjs +106 -0
- package/dist/hooks.d.ts +2 -2
- package/dist/hooks.js +7 -6
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +7 -7
- package/dist/index.js +21 -16
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +3 -3
- package/dist/providers.js +4 -3
- package/dist/rbac/index.d.ts +67 -27
- package/dist/rbac/index.js +15 -8
- package/dist/styles/index.js +1 -1
- package/dist/theming/runtime.js +1 -1
- package/dist/types.js +1 -1
- package/dist/{usePublicRouteParams-1oMokgLF.d.ts → usePublicRouteParams-i3qtoBgg.d.ts} +7 -16
- package/dist/utils.js +5 -7
- package/dist/utils.js.map +1 -1
- package/docs/api/README.md +14 -16
- package/docs/api/modules.md +3796 -2513
- package/docs/components/context-selector.md +126 -0
- package/docs/migration/RBAC_SCOPE_MIGRATION.md +385 -0
- package/docs/pace-mint-fix-auto-selection.md +218 -0
- package/docs/pace-mint-rbac-setup.md +391 -0
- package/docs/rbac/secure-client-protection.md +330 -0
- package/package.json +10 -5
- package/scripts/audit/core/checks/compliance.cjs +72 -0
- package/scripts/audit/core/checks/dependencies.cjs +568 -28
- package/scripts/audit/core/checks/documentation.cjs +68 -3
- package/scripts/audit/core/checks/environment.cjs +2 -14
- package/scripts/audit/core/checks/error-handling.cjs +47 -6
- package/src/components/ContextSelector/ContextSelector.tsx +384 -0
- package/src/components/ContextSelector/index.ts +3 -0
- package/src/components/DataTable/components/RowComponent.tsx +19 -19
- package/src/components/DataTable/components/UnifiedTableBody.tsx +2 -2
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +8 -6
- package/src/components/Dialog/Dialog.tsx +29 -1
- package/src/components/FileDisplay/FileDisplay.tsx +42 -10
- package/src/components/Header/Header.test.tsx +43 -73
- package/src/components/Header/Header.tsx +44 -45
- package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +10 -19
- package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +2 -2
- package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +5 -5
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +9 -9
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +157 -36
- package/src/components/PaceAppLayout/README.md +14 -17
- package/src/components/PaceAppLayout/test-setup.tsx +2 -2
- package/src/components/index.ts +5 -5
- package/src/eslint-rules/pace-core-compliance.cjs +106 -0
- package/src/hooks/__tests__/useAppConfig.unit.test.ts +4 -98
- package/src/hooks/useAppConfig.ts +15 -30
- package/src/hooks/useFileDisplay.ts +77 -50
- package/src/index.ts +4 -5
- package/src/providers/services/AuthServiceProvider.tsx +17 -7
- package/src/providers/services/EventServiceProvider.tsx +33 -5
- package/src/providers/services/UnifiedAuthProvider.tsx +90 -134
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +1 -1
- package/src/rbac/adapters.tsx +2 -2
- package/src/rbac/api.test.ts +59 -51
- package/src/rbac/api.ts +178 -132
- package/src/rbac/components/PagePermissionGuard.tsx +38 -10
- package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +32 -21
- package/src/rbac/hooks/permissions/useAccessLevel.ts +1 -1
- package/src/rbac/hooks/permissions/useCan.ts +41 -11
- package/src/rbac/hooks/permissions/useHasAllPermissions.ts +1 -1
- package/src/rbac/hooks/permissions/useHasAnyPermission.ts +1 -1
- package/src/rbac/hooks/permissions/useMultiplePermissions.ts +1 -1
- package/src/rbac/hooks/useCan.test.ts +0 -9
- package/src/rbac/hooks/useRBAC.test.ts +1 -5
- package/src/rbac/hooks/useRBAC.ts +36 -37
- package/src/rbac/hooks/useResolvedScope.test.ts +120 -35
- package/src/rbac/hooks/useResolvedScope.ts +35 -40
- package/src/rbac/hooks/useSecureSupabase.ts +7 -7
- package/src/rbac/index.ts +7 -0
- package/src/rbac/secureClient.test.ts +22 -18
- package/src/rbac/secureClient.ts +103 -16
- package/src/rbac/security.ts +0 -17
- package/src/rbac/types.ts +1 -0
- package/src/rbac/utils/__tests__/contextValidator.test.ts +64 -86
- package/src/rbac/utils/clientSecurity.ts +93 -0
- package/src/rbac/utils/contextValidator.ts +77 -168
- package/src/services/AuthService.ts +39 -7
- package/src/services/EventService.ts +285 -56
- package/src/services/OrganisationService.ts +81 -14
- package/src/services/__tests__/EventService.test.ts +1 -2
- package/src/services/base/BaseService.ts +3 -0
- package/src/utils/dynamic/dynamicUtils.ts +7 -4
- package/dist/chunk-24UVZUZG.js.map +0 -1
- package/dist/chunk-3XC4CPTD.js.map +0 -1
- package/dist/chunk-6J4GEEJR.js.map +0 -1
- package/dist/chunk-7D4SUZUM.js +0 -38
- package/dist/chunk-EHMR7VYL.js.map +0 -1
- package/dist/chunk-NECFR5MM.js.map +0 -1
- package/dist/chunk-SFZUDBL5.js.map +0 -1
- package/dist/chunk-XWQCNGTQ.js.map +0 -1
- package/docs/api/classes/ColumnFactory.md +0 -243
- package/docs/api/classes/InvalidScopeError.md +0 -73
- package/docs/api/classes/Logger.md +0 -178
- package/docs/api/classes/MissingUserContextError.md +0 -66
- package/docs/api/classes/OrganisationContextRequiredError.md +0 -66
- package/docs/api/classes/PermissionDeniedError.md +0 -73
- package/docs/api/classes/RBACAuditManager.md +0 -297
- package/docs/api/classes/RBACCache.md +0 -322
- package/docs/api/classes/RBACEngine.md +0 -171
- package/docs/api/classes/RBACError.md +0 -76
- package/docs/api/classes/RBACNotInitializedError.md +0 -66
- package/docs/api/classes/SecureSupabaseClient.md +0 -163
- package/docs/api/classes/StorageUtils.md +0 -328
- package/docs/api/enums/FileCategory.md +0 -184
- package/docs/api/enums/LogLevel.md +0 -54
- package/docs/api/enums/RBACErrorCode.md +0 -228
- package/docs/api/enums/RPCFunction.md +0 -118
- package/docs/api/interfaces/AddressFieldProps.md +0 -241
- package/docs/api/interfaces/AddressFieldRef.md +0 -94
- package/docs/api/interfaces/AggregateConfig.md +0 -43
- package/docs/api/interfaces/AutocompleteOptions.md +0 -75
- package/docs/api/interfaces/AvatarProps.md +0 -128
- package/docs/api/interfaces/BadgeProps.md +0 -34
- package/docs/api/interfaces/ButtonProps.md +0 -56
- package/docs/api/interfaces/CalendarProps.md +0 -73
- package/docs/api/interfaces/CardProps.md +0 -69
- package/docs/api/interfaces/ColorPalette.md +0 -7
- package/docs/api/interfaces/ColorShade.md +0 -66
- package/docs/api/interfaces/ComplianceResult.md +0 -30
- package/docs/api/interfaces/DataAccessRecord.md +0 -96
- package/docs/api/interfaces/DataRecord.md +0 -11
- package/docs/api/interfaces/DataTableAction.md +0 -252
- package/docs/api/interfaces/DataTableColumn.md +0 -504
- package/docs/api/interfaces/DataTableProps.md +0 -625
- package/docs/api/interfaces/DataTableToolbarButton.md +0 -96
- package/docs/api/interfaces/DatabaseComplianceResult.md +0 -85
- package/docs/api/interfaces/DatabaseIssue.md +0 -41
- package/docs/api/interfaces/EmptyStateConfig.md +0 -61
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +0 -235
- package/docs/api/interfaces/ErrorBoundaryProps.md +0 -147
- package/docs/api/interfaces/ErrorBoundaryProviderProps.md +0 -36
- package/docs/api/interfaces/ErrorBoundaryState.md +0 -75
- package/docs/api/interfaces/EventAppRoleData.md +0 -71
- package/docs/api/interfaces/ExportColumn.md +0 -90
- package/docs/api/interfaces/ExportOptions.md +0 -126
- package/docs/api/interfaces/FileDisplayProps.md +0 -249
- package/docs/api/interfaces/FileMetadata.md +0 -129
- package/docs/api/interfaces/FileReference.md +0 -118
- package/docs/api/interfaces/FileSizeLimits.md +0 -7
- package/docs/api/interfaces/FileUploadOptions.md +0 -139
- package/docs/api/interfaces/FileUploadProps.md +0 -296
- package/docs/api/interfaces/FooterProps.md +0 -107
- package/docs/api/interfaces/FormFieldProps.md +0 -166
- package/docs/api/interfaces/FormProps.md +0 -113
- package/docs/api/interfaces/GrantEventAppRoleParams.md +0 -122
- package/docs/api/interfaces/InactivityWarningModalProps.md +0 -115
- package/docs/api/interfaces/InputProps.md +0 -56
- package/docs/api/interfaces/LabelProps.md +0 -107
- package/docs/api/interfaces/LoggerConfig.md +0 -62
- package/docs/api/interfaces/LoginFormProps.md +0 -187
- package/docs/api/interfaces/NavigationAccessRecord.md +0 -107
- package/docs/api/interfaces/NavigationContextType.md +0 -164
- package/docs/api/interfaces/NavigationGuardProps.md +0 -139
- package/docs/api/interfaces/NavigationItem.md +0 -120
- package/docs/api/interfaces/NavigationMenuProps.md +0 -221
- package/docs/api/interfaces/NavigationProviderProps.md +0 -117
- package/docs/api/interfaces/Organisation.md +0 -140
- package/docs/api/interfaces/OrganisationContextType.md +0 -388
- package/docs/api/interfaces/OrganisationMembership.md +0 -140
- package/docs/api/interfaces/OrganisationProviderProps.md +0 -76
- package/docs/api/interfaces/OrganisationSecurityError.md +0 -62
- package/docs/api/interfaces/PaceAppLayoutProps.md +0 -409
- package/docs/api/interfaces/PaceLoginPageProps.md +0 -49
- package/docs/api/interfaces/PageAccessRecord.md +0 -85
- package/docs/api/interfaces/PagePermissionContextType.md +0 -140
- package/docs/api/interfaces/PagePermissionGuardProps.md +0 -153
- package/docs/api/interfaces/PagePermissionProviderProps.md +0 -119
- package/docs/api/interfaces/PaletteData.md +0 -41
- package/docs/api/interfaces/ParsedAddress.md +0 -120
- package/docs/api/interfaces/PermissionEnforcerProps.md +0 -153
- package/docs/api/interfaces/ProgressProps.md +0 -42
- package/docs/api/interfaces/ProtectedRouteProps.md +0 -78
- package/docs/api/interfaces/PublicPageFooterProps.md +0 -112
- package/docs/api/interfaces/PublicPageHeaderProps.md +0 -125
- package/docs/api/interfaces/PublicPageLayoutProps.md +0 -185
- package/docs/api/interfaces/QuickFix.md +0 -52
- package/docs/api/interfaces/RBACAccessValidateParams.md +0 -52
- package/docs/api/interfaces/RBACAccessValidateResult.md +0 -41
- package/docs/api/interfaces/RBACAuditLogParams.md +0 -85
- package/docs/api/interfaces/RBACAuditLogResult.md +0 -52
- package/docs/api/interfaces/RBACConfig.md +0 -133
- package/docs/api/interfaces/RBACContext.md +0 -52
- package/docs/api/interfaces/RBACLogger.md +0 -112
- package/docs/api/interfaces/RBACPageAccessCheckParams.md +0 -74
- package/docs/api/interfaces/RBACPerformanceMetrics.md +0 -138
- package/docs/api/interfaces/RBACPermissionCheckParams.md +0 -74
- package/docs/api/interfaces/RBACPermissionCheckResult.md +0 -52
- package/docs/api/interfaces/RBACPermissionsGetParams.md +0 -63
- package/docs/api/interfaces/RBACPermissionsGetResult.md +0 -63
- package/docs/api/interfaces/RBACResult.md +0 -58
- package/docs/api/interfaces/RBACRoleGrantParams.md +0 -63
- package/docs/api/interfaces/RBACRoleGrantResult.md +0 -52
- package/docs/api/interfaces/RBACRoleRevokeParams.md +0 -63
- package/docs/api/interfaces/RBACRoleRevokeResult.md +0 -52
- package/docs/api/interfaces/RBACRoleValidateParams.md +0 -52
- package/docs/api/interfaces/RBACRoleValidateResult.md +0 -63
- package/docs/api/interfaces/RBACRolesListParams.md +0 -52
- package/docs/api/interfaces/RBACRolesListResult.md +0 -74
- package/docs/api/interfaces/RBACSessionTrackParams.md +0 -74
- package/docs/api/interfaces/RBACSessionTrackResult.md +0 -52
- package/docs/api/interfaces/ResourcePermissions.md +0 -155
- package/docs/api/interfaces/RevokeEventAppRoleParams.md +0 -100
- package/docs/api/interfaces/RoleBasedRouterContextType.md +0 -151
- package/docs/api/interfaces/RoleBasedRouterProps.md +0 -156
- package/docs/api/interfaces/RoleManagementResult.md +0 -52
- package/docs/api/interfaces/RouteAccessRecord.md +0 -107
- package/docs/api/interfaces/RouteConfig.md +0 -134
- package/docs/api/interfaces/RuntimeComplianceResult.md +0 -55
- package/docs/api/interfaces/SecureDataContextType.md +0 -168
- package/docs/api/interfaces/SecureDataProviderProps.md +0 -132
- package/docs/api/interfaces/SessionRestorationLoaderProps.md +0 -34
- package/docs/api/interfaces/SetupIssue.md +0 -41
- package/docs/api/interfaces/StorageConfig.md +0 -41
- package/docs/api/interfaces/StorageFileInfo.md +0 -74
- package/docs/api/interfaces/StorageFileMetadata.md +0 -151
- package/docs/api/interfaces/StorageListOptions.md +0 -99
- package/docs/api/interfaces/StorageListResult.md +0 -41
- package/docs/api/interfaces/StorageUploadOptions.md +0 -101
- package/docs/api/interfaces/StorageUploadResult.md +0 -63
- package/docs/api/interfaces/StorageUrlOptions.md +0 -60
- package/docs/api/interfaces/StyleImport.md +0 -19
- package/docs/api/interfaces/SwitchProps.md +0 -34
- package/docs/api/interfaces/TabsContentProps.md +0 -9
- package/docs/api/interfaces/TabsListProps.md +0 -9
- package/docs/api/interfaces/TabsProps.md +0 -9
- package/docs/api/interfaces/TabsTriggerProps.md +0 -50
- package/docs/api/interfaces/TextareaProps.md +0 -53
- package/docs/api/interfaces/ToastActionElement.md +0 -12
- package/docs/api/interfaces/ToastProps.md +0 -9
- package/docs/api/interfaces/UnifiedAuthContextType.md +0 -823
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +0 -173
- package/docs/api/interfaces/UseFormDialogOptions.md +0 -62
- package/docs/api/interfaces/UseFormDialogReturn.md +0 -117
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +0 -138
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +0 -123
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +0 -87
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +0 -84
- package/docs/api/interfaces/UsePublicEventOptions.md +0 -34
- package/docs/api/interfaces/UsePublicEventReturn.md +0 -71
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +0 -47
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +0 -123
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +0 -97
- package/docs/api/interfaces/UseResolvedScopeOptions.md +0 -47
- package/docs/api/interfaces/UseResolvedScopeReturn.md +0 -47
- package/docs/api/interfaces/UseResourcePermissionsOptions.md +0 -34
- package/docs/api/interfaces/UserEventAccess.md +0 -121
- package/docs/api/interfaces/UserMenuProps.md +0 -88
- package/docs/api/interfaces/UserProfile.md +0 -63
- package/src/components/EventSelector/EventSelector.test.tsx +0 -720
- package/src/components/EventSelector/EventSelector.tsx +0 -423
- package/src/components/EventSelector/index.ts +0 -3
- package/src/components/OrganisationSelector/OrganisationSelector.test.tsx +0 -784
- package/src/components/OrganisationSelector/OrganisationSelector.tsx +0 -327
- package/src/components/OrganisationSelector/index.ts +0 -9
- /package/dist/{DataTable-TPTKCX4D.js.map → DataTable-E7YQZD7D.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-CH6Z342H.js.map → UnifiedAuthProvider-QPXO24B4.js.map} +0 -0
- /package/dist/{api-MVVQZLJI.js.map → api-6LVZTHDS.js.map} +0 -0
- /package/dist/{audit-B5P6FFIR.js.map → audit-V53FV5AG.js.map} +0 -0
- /package/dist/{chunk-2UOI2FG5.js.map → chunk-5EC5MEWX.js.map} +0 -0
- /package/dist/{chunk-7D4SUZUM.js.map → chunk-DGUM43GV.js.map} +0 -0
- /package/dist/{chunk-F2IMUDXZ.js.map → chunk-M7MPQISP.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
} from "./chunk-
|
|
2
|
+
isRBACInitialized,
|
|
3
|
+
setupRBAC
|
|
4
|
+
} from "./chunk-3LPHPB62.js";
|
|
5
5
|
import {
|
|
6
6
|
assertOrganisationId,
|
|
7
7
|
assertUserId
|
|
@@ -16,10 +16,10 @@ 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 useRef9, useEffect as useEffect10, useState as useState3, useReducer as useReducer5 } from "react";
|
|
20
20
|
|
|
21
21
|
// src/providers/services/AuthServiceProvider.tsx
|
|
22
|
-
import { createContext, useMemo, useEffect, useState } from "react";
|
|
22
|
+
import { createContext, useMemo, useEffect, useState, useRef } from "react";
|
|
23
23
|
|
|
24
24
|
// src/services/AuthService.ts
|
|
25
25
|
import { AuthError } from "@supabase/supabase-js";
|
|
@@ -49,6 +49,9 @@ var BaseService = class {
|
|
|
49
49
|
* This triggers React re-renders
|
|
50
50
|
*/
|
|
51
51
|
notify() {
|
|
52
|
+
const serviceName = this.constructor.name;
|
|
53
|
+
const instanceId = this.instanceId || "unknown";
|
|
54
|
+
logger.debug("BaseService", `[${serviceName} ID:${instanceId}] Notifying ${this.subscribers.length} subscribers`);
|
|
52
55
|
this.subscribers.forEach((callback) => {
|
|
53
56
|
try {
|
|
54
57
|
callback();
|
|
@@ -93,7 +96,7 @@ var BaseService = class {
|
|
|
93
96
|
};
|
|
94
97
|
|
|
95
98
|
// src/services/AuthService.ts
|
|
96
|
-
var
|
|
99
|
+
var _AuthService = class _AuthService extends BaseService {
|
|
97
100
|
constructor(supabaseClient, appName) {
|
|
98
101
|
super();
|
|
99
102
|
this.user = null;
|
|
@@ -113,11 +116,21 @@ var AuthService = class extends BaseService {
|
|
|
113
116
|
this.appName = void 0;
|
|
114
117
|
this.errorHandler = null;
|
|
115
118
|
this.unhandledRejectionHandler = null;
|
|
119
|
+
this.instanceId = ++_AuthService.instanceCount;
|
|
116
120
|
this.supabaseClient = supabaseClient;
|
|
117
121
|
this.appName = appName;
|
|
122
|
+
logger.debug("AuthService", `Instance created [ID:${this.instanceId}]`, { appName });
|
|
123
|
+
}
|
|
124
|
+
getInstanceId() {
|
|
125
|
+
return this.instanceId;
|
|
118
126
|
}
|
|
119
127
|
// Auth state getters
|
|
120
128
|
getUser() {
|
|
129
|
+
if (this.user) {
|
|
130
|
+
logger.debug("AuthService", `getUser() [ID:${this.instanceId}] returning user: ${this.user.id}`);
|
|
131
|
+
} else {
|
|
132
|
+
logger.debug("AuthService", `getUser() [ID:${this.instanceId}] returning null`);
|
|
133
|
+
}
|
|
121
134
|
return this.user;
|
|
122
135
|
}
|
|
123
136
|
getSession() {
|
|
@@ -398,24 +411,29 @@ var AuthService = class extends BaseService {
|
|
|
398
411
|
const subscription = this.supabaseClient.auth.onAuthStateChange(
|
|
399
412
|
(event, session) => {
|
|
400
413
|
try {
|
|
414
|
+
logger.debug("AuthService", `Auth state change [ID:${this.instanceId}]`, {
|
|
415
|
+
event,
|
|
416
|
+
hasSession: !!session,
|
|
417
|
+
userId: session?.user?.id
|
|
418
|
+
});
|
|
401
419
|
if (event === "SIGNED_OUT") {
|
|
402
420
|
this.session = null;
|
|
403
421
|
this.user = null;
|
|
404
422
|
this.authError = null;
|
|
405
423
|
if (session?.user) {
|
|
406
424
|
this.trackSession("logout", session).catch((err) => {
|
|
407
|
-
logger.warn("AuthService",
|
|
425
|
+
logger.warn("AuthService", `Failed to track logout session [ID:${this.instanceId}]:`, err);
|
|
408
426
|
});
|
|
409
427
|
}
|
|
410
428
|
} else if (event === "SIGNED_IN" || event === "TOKEN_REFRESHED") {
|
|
411
429
|
this.session = session;
|
|
412
430
|
this.user = session?.user ?? null;
|
|
413
|
-
if (session) {
|
|
431
|
+
if (session?.user) {
|
|
414
432
|
this.authError = null;
|
|
415
433
|
}
|
|
416
434
|
if (event === "SIGNED_IN" && session?.user) {
|
|
417
435
|
this.trackSession("login", session).catch((err) => {
|
|
418
|
-
logger.warn("AuthService",
|
|
436
|
+
logger.warn("AuthService", `Failed to track login session [ID:${this.instanceId}]:`, err);
|
|
419
437
|
});
|
|
420
438
|
}
|
|
421
439
|
} else if (event === "INITIAL_SESSION") {
|
|
@@ -433,13 +451,22 @@ var AuthService = class extends BaseService {
|
|
|
433
451
|
}
|
|
434
452
|
}
|
|
435
453
|
this.authLoading = false;
|
|
454
|
+
logger.debug("AuthService", `State synchronized after INITIAL_SESSION [ID:${this.instanceId}]`, {
|
|
455
|
+
hasUser: !!this.user,
|
|
456
|
+
userId: this.user?.id
|
|
457
|
+
});
|
|
436
458
|
this.notify();
|
|
437
459
|
return;
|
|
438
460
|
}
|
|
439
461
|
this.authLoading = false;
|
|
462
|
+
logger.debug("AuthService", `State synchronized after event [ID:${this.instanceId}]`, {
|
|
463
|
+
event,
|
|
464
|
+
hasUser: !!this.user,
|
|
465
|
+
userId: this.user?.id
|
|
466
|
+
});
|
|
440
467
|
this.notify();
|
|
441
468
|
} catch (error) {
|
|
442
|
-
logger.warn("AuthService",
|
|
469
|
+
logger.warn("AuthService", `Error in auth state change handler [ID:${this.instanceId}]:`, error);
|
|
443
470
|
this.authLoading = false;
|
|
444
471
|
this.notify();
|
|
445
472
|
}
|
|
@@ -578,15 +605,20 @@ var AuthService = class extends BaseService {
|
|
|
578
605
|
}
|
|
579
606
|
}
|
|
580
607
|
};
|
|
608
|
+
_AuthService.instanceCount = 0;
|
|
609
|
+
var AuthService = _AuthService;
|
|
581
610
|
|
|
582
611
|
// src/providers/services/AuthServiceProvider.tsx
|
|
583
612
|
import { jsx } from "react/jsx-runtime";
|
|
584
613
|
var AuthServiceContext = createContext(null);
|
|
585
614
|
function AuthServiceProvider({ children, supabaseClient, appName }) {
|
|
586
|
-
const
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
615
|
+
const authServiceRef = useRef(null);
|
|
616
|
+
if (!authServiceRef.current) {
|
|
617
|
+
authServiceRef.current = new AuthService(supabaseClient, appName);
|
|
618
|
+
}
|
|
619
|
+
const authService = authServiceRef.current;
|
|
620
|
+
useEffect(() => {
|
|
621
|
+
}, [authService, supabaseClient, appName]);
|
|
590
622
|
const [sessionRestoration, setSessionRestoration] = useState(
|
|
591
623
|
() => authService.getSessionRestorationState()
|
|
592
624
|
);
|
|
@@ -615,10 +647,10 @@ function AuthServiceProvider({ children, supabaseClient, appName }) {
|
|
|
615
647
|
}
|
|
616
648
|
|
|
617
649
|
// src/providers/services/OrganisationServiceProvider.tsx
|
|
618
|
-
import { createContext as createContext2, useMemo as useMemo2, useEffect as useEffect2, useRef } from "react";
|
|
650
|
+
import { createContext as createContext2, useMemo as useMemo2, useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
619
651
|
|
|
620
652
|
// src/services/OrganisationService.ts
|
|
621
|
-
var
|
|
653
|
+
var _OrganisationService = class _OrganisationService extends BaseService {
|
|
622
654
|
constructor(supabaseClient, user, session) {
|
|
623
655
|
super();
|
|
624
656
|
this._selectedOrganisation = null;
|
|
@@ -640,9 +672,17 @@ var OrganisationService = class extends BaseService {
|
|
|
640
672
|
this.lastLoadTimeRef = 0;
|
|
641
673
|
this.hasFailedRef = false;
|
|
642
674
|
this.abortControllerRef = null;
|
|
675
|
+
this.instanceId = ++_OrganisationService.instanceCount;
|
|
643
676
|
this.supabaseClient = supabaseClient;
|
|
644
677
|
this.user = user;
|
|
645
678
|
this.session = session;
|
|
679
|
+
logger.debug("OrganisationService", `Instance created [ID:${this.instanceId}]`, {
|
|
680
|
+
hasUser: !!user,
|
|
681
|
+
userId: user?.id
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
getInstanceId() {
|
|
685
|
+
return this.instanceId;
|
|
646
686
|
}
|
|
647
687
|
// Interface implementation
|
|
648
688
|
getSelectedOrganisation() {
|
|
@@ -715,16 +755,35 @@ var OrganisationService = class extends BaseService {
|
|
|
715
755
|
}
|
|
716
756
|
// Update dependencies
|
|
717
757
|
updateDependencies(user, session) {
|
|
718
|
-
const
|
|
719
|
-
const
|
|
720
|
-
|
|
758
|
+
const previousUserId = this.user?.id || null;
|
|
759
|
+
const newUserId = user?.id || null;
|
|
760
|
+
const userChanged = previousUserId !== newUserId;
|
|
761
|
+
const needsRetry = this._error !== null && !this.isLoadingRef;
|
|
762
|
+
const isEmpty = newUserId !== null && this._organisations.length === 0 && !this.isLoadingRef;
|
|
763
|
+
if (userChanged || needsRetry || isEmpty) {
|
|
764
|
+
if (userChanged) {
|
|
765
|
+
logger.debug("OrganisationService", `User changed [ID:${this.instanceId}], resetting initialization`, {
|
|
766
|
+
previousUserId,
|
|
767
|
+
newUserId
|
|
768
|
+
});
|
|
769
|
+
} else if (needsRetry) {
|
|
770
|
+
logger.debug("OrganisationService", `Previous error detected [ID:${this.instanceId}], retrying initialization`);
|
|
771
|
+
} else if (isEmpty) {
|
|
772
|
+
logger.debug("OrganisationService", `No organisations found [ID:${this.instanceId}], retrying initialization`);
|
|
773
|
+
}
|
|
721
774
|
this._isSuperAdmin = false;
|
|
775
|
+
this.resetInitialization();
|
|
776
|
+
if (userChanged) {
|
|
777
|
+
this._organisations = [];
|
|
778
|
+
this._userMemberships = [];
|
|
779
|
+
this._roleMapState = /* @__PURE__ */ new Map();
|
|
780
|
+
this._selectedOrganisation = null;
|
|
781
|
+
this._isContextReady = false;
|
|
782
|
+
}
|
|
783
|
+
this.lastLoadTimeRef = 0;
|
|
722
784
|
}
|
|
723
785
|
this.user = user;
|
|
724
786
|
this.session = session;
|
|
725
|
-
if (wasAuthenticated && !isAuthenticated) {
|
|
726
|
-
this.resetInitialization();
|
|
727
|
-
}
|
|
728
787
|
this.notify();
|
|
729
788
|
}
|
|
730
789
|
// Organisation methods
|
|
@@ -793,6 +852,10 @@ var OrganisationService = class extends BaseService {
|
|
|
793
852
|
}
|
|
794
853
|
// Lifecycle methods
|
|
795
854
|
async initialize() {
|
|
855
|
+
if (!this.user) {
|
|
856
|
+
logger.debug("OrganisationService", "Skipping initialization - no user");
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
796
859
|
await super.initialize();
|
|
797
860
|
if (!this.isLoadingRef) {
|
|
798
861
|
await this.loadUserOrganisations();
|
|
@@ -855,7 +918,7 @@ var OrganisationService = class extends BaseService {
|
|
|
855
918
|
return;
|
|
856
919
|
}
|
|
857
920
|
const now = Date.now();
|
|
858
|
-
if (now - this.lastLoadTimeRef < 2e3) {
|
|
921
|
+
if (this._organisations.length > 0 && now - this.lastLoadTimeRef < 2e3) {
|
|
859
922
|
if (this._organisations.length > 0 || this._selectedOrganisation) {
|
|
860
923
|
this._isLoading = false;
|
|
861
924
|
} else {
|
|
@@ -874,6 +937,9 @@ var OrganisationService = class extends BaseService {
|
|
|
874
937
|
this._isLoading = true;
|
|
875
938
|
this._error = null;
|
|
876
939
|
this.notify();
|
|
940
|
+
logger.debug("OrganisationService", "Loading organisations for user", {
|
|
941
|
+
userId: this.user.id
|
|
942
|
+
});
|
|
877
943
|
try {
|
|
878
944
|
let memberships, membershipError, organisations = [];
|
|
879
945
|
try {
|
|
@@ -932,6 +998,10 @@ var OrganisationService = class extends BaseService {
|
|
|
932
998
|
}
|
|
933
999
|
});
|
|
934
1000
|
organisations = Array.from(organisationsMap.values());
|
|
1001
|
+
logger.debug("OrganisationService", "Query results", {
|
|
1002
|
+
membershipsCount: memberships.length,
|
|
1003
|
+
organisationsCount: organisations.length
|
|
1004
|
+
});
|
|
935
1005
|
} catch (queryError) {
|
|
936
1006
|
if (queryError instanceof Error) {
|
|
937
1007
|
membershipError = queryError;
|
|
@@ -946,7 +1016,15 @@ var OrganisationService = class extends BaseService {
|
|
|
946
1016
|
let userIsSuperAdmin = false;
|
|
947
1017
|
if (this.user?.id) {
|
|
948
1018
|
try {
|
|
949
|
-
|
|
1019
|
+
const { isSuperAdmin: checkSuperAdmin, isRBACInitialized: isRBACInitialized2, setupRBAC: setupRBAC2 } = await import("./api-6LVZTHDS.js");
|
|
1020
|
+
if (!isRBACInitialized2() && this.supabaseClient) {
|
|
1021
|
+
setupRBAC2(this.supabaseClient);
|
|
1022
|
+
}
|
|
1023
|
+
if (isRBACInitialized2()) {
|
|
1024
|
+
userIsSuperAdmin = await checkSuperAdmin(this.user.id);
|
|
1025
|
+
} else {
|
|
1026
|
+
userIsSuperAdmin = false;
|
|
1027
|
+
}
|
|
950
1028
|
this._isSuperAdmin = userIsSuperAdmin;
|
|
951
1029
|
} catch (error) {
|
|
952
1030
|
logger.warn("OrganisationService", "Failed to check super admin status", { error });
|
|
@@ -997,7 +1075,12 @@ var OrganisationService = class extends BaseService {
|
|
|
997
1075
|
}
|
|
998
1076
|
throw new Error("User has no access to active organisations");
|
|
999
1077
|
}
|
|
1000
|
-
|
|
1078
|
+
const sortedOrgs = [...activeOrgs].sort((a, b) => {
|
|
1079
|
+
const nameA = (a.display_name || a.name || "").toLowerCase();
|
|
1080
|
+
const nameB = (b.display_name || b.name || "").toLowerCase();
|
|
1081
|
+
return nameA.localeCompare(nameB);
|
|
1082
|
+
});
|
|
1083
|
+
this._organisations = sortedOrgs;
|
|
1001
1084
|
this._userMemberships = memberships;
|
|
1002
1085
|
this._roleMapState = roleMap;
|
|
1003
1086
|
let initialOrg = null;
|
|
@@ -1079,6 +1162,8 @@ var OrganisationService = class extends BaseService {
|
|
|
1079
1162
|
this._isContextReady = false;
|
|
1080
1163
|
}
|
|
1081
1164
|
};
|
|
1165
|
+
_OrganisationService.instanceCount = 0;
|
|
1166
|
+
var OrganisationService = _OrganisationService;
|
|
1082
1167
|
|
|
1083
1168
|
// src/providers/services/OrganisationServiceProvider.tsx
|
|
1084
1169
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
@@ -1089,7 +1174,7 @@ function OrganisationServiceProvider({
|
|
|
1089
1174
|
user,
|
|
1090
1175
|
session
|
|
1091
1176
|
}) {
|
|
1092
|
-
const organisationServiceRef =
|
|
1177
|
+
const organisationServiceRef = useRef2(null);
|
|
1093
1178
|
if (!organisationServiceRef.current) {
|
|
1094
1179
|
organisationServiceRef.current = new OrganisationService(supabaseClient, user, session);
|
|
1095
1180
|
}
|
|
@@ -1123,10 +1208,10 @@ function OrganisationServiceProvider({
|
|
|
1123
1208
|
}
|
|
1124
1209
|
|
|
1125
1210
|
// src/providers/services/EventServiceProvider.tsx
|
|
1126
|
-
import { createContext as createContext3, useMemo as useMemo3, useEffect as useEffect3, useRef as
|
|
1211
|
+
import { createContext as createContext3, useMemo as useMemo3, useEffect as useEffect3, useRef as useRef3 } from "react";
|
|
1127
1212
|
|
|
1128
1213
|
// src/services/EventService.ts
|
|
1129
|
-
var
|
|
1214
|
+
var _EventService = class _EventService extends BaseService {
|
|
1130
1215
|
constructor(supabaseClient, user, session, appName, selectedOrganisation, setSelectedEventId) {
|
|
1131
1216
|
super();
|
|
1132
1217
|
this.events = [];
|
|
@@ -1143,19 +1228,27 @@ var EventService = class extends BaseService {
|
|
|
1143
1228
|
this.setSelectedEventId = null;
|
|
1144
1229
|
this.isSuperAdmin = false;
|
|
1145
1230
|
// Track super admin status for conditional validation
|
|
1146
|
-
|
|
1147
|
-
// Cache app config to avoid repeated lookups
|
|
1231
|
+
// App config removed - scope is now page-level only (rbac_app_pages.scope_type)
|
|
1148
1232
|
// Internal state management
|
|
1149
1233
|
this.isInitializedRef = false;
|
|
1150
1234
|
this.isFetchingRef = false;
|
|
1151
1235
|
this.hasAutoSelectedRef = false;
|
|
1152
1236
|
this.userClearedEventRef = false;
|
|
1237
|
+
this.instanceId = ++_EventService.instanceCount;
|
|
1153
1238
|
this.supabaseClient = supabaseClient;
|
|
1154
1239
|
this.user = user;
|
|
1155
1240
|
this.session = session;
|
|
1156
1241
|
this.appName = appName;
|
|
1157
1242
|
this.selectedOrganisation = selectedOrganisation;
|
|
1158
1243
|
this.setSelectedEventId = setSelectedEventId;
|
|
1244
|
+
logger.debug("EventService", `Instance created [ID:${this.instanceId}]`, {
|
|
1245
|
+
appName,
|
|
1246
|
+
hasUser: !!user,
|
|
1247
|
+
userId: user?.id
|
|
1248
|
+
});
|
|
1249
|
+
}
|
|
1250
|
+
getInstanceId() {
|
|
1251
|
+
return this.instanceId;
|
|
1159
1252
|
}
|
|
1160
1253
|
// Helper method to get user-scoped storage key
|
|
1161
1254
|
getStorageKey(userId) {
|
|
@@ -1182,6 +1275,13 @@ var EventService = class extends BaseService {
|
|
|
1182
1275
|
this.resetInitialization();
|
|
1183
1276
|
this.isInitializedRef = false;
|
|
1184
1277
|
this.isFetchingRef = false;
|
|
1278
|
+
this.userClearedEventRef = false;
|
|
1279
|
+
this.hasAutoSelectedRef = false;
|
|
1280
|
+
logger.debug("EventService", `User changed [ID:${this.instanceId}]`, {
|
|
1281
|
+
previousUserId,
|
|
1282
|
+
newUserId,
|
|
1283
|
+
willInitialize: newUserId !== null
|
|
1284
|
+
});
|
|
1185
1285
|
}
|
|
1186
1286
|
this.supabaseClient = supabaseClient;
|
|
1187
1287
|
this.user = user;
|
|
@@ -1189,15 +1289,31 @@ var EventService = class extends BaseService {
|
|
|
1189
1289
|
this.appName = appName;
|
|
1190
1290
|
this.selectedOrganisation = selectedOrganisation;
|
|
1191
1291
|
this.setSelectedEventId = setSelectedEventId;
|
|
1192
|
-
if (previousAppName !== appName) {
|
|
1193
|
-
this.appConfig = null;
|
|
1194
|
-
}
|
|
1195
1292
|
if (user?.id) {
|
|
1196
1293
|
try {
|
|
1197
|
-
|
|
1294
|
+
const { isRBACInitialized: isRBACInitialized2, isSuperAdmin: checkSuperAdmin, setupRBAC: setupRBAC2 } = await import("./api-6LVZTHDS.js");
|
|
1295
|
+
if (!isRBACInitialized2() && this.supabaseClient) {
|
|
1296
|
+
setupRBAC2(this.supabaseClient);
|
|
1297
|
+
}
|
|
1298
|
+
if (isRBACInitialized2()) {
|
|
1299
|
+
this.isSuperAdmin = await checkSuperAdmin(user.id);
|
|
1300
|
+
logger.debug("EventService", "Super admin status updated in updateDependencies", {
|
|
1301
|
+
userId: user.id,
|
|
1302
|
+
isSuperAdmin: this.isSuperAdmin
|
|
1303
|
+
});
|
|
1304
|
+
} else {
|
|
1305
|
+
logger.warn("EventService", "RBAC not initialized in updateDependencies, keeping existing super admin status", {
|
|
1306
|
+
userId: user.id,
|
|
1307
|
+
existingIsSuperAdmin: this.isSuperAdmin,
|
|
1308
|
+
note: "RBAC should be initialized by UnifiedAuthProvider. This may indicate EventService is being used outside the provider."
|
|
1309
|
+
});
|
|
1310
|
+
}
|
|
1198
1311
|
} catch (error) {
|
|
1199
|
-
logger.warn("EventService", "Failed to check super admin status", {
|
|
1200
|
-
|
|
1312
|
+
logger.warn("EventService", "Failed to check super admin status in updateDependencies", {
|
|
1313
|
+
error,
|
|
1314
|
+
userId: user.id,
|
|
1315
|
+
existingIsSuperAdmin: this.isSuperAdmin
|
|
1316
|
+
});
|
|
1201
1317
|
}
|
|
1202
1318
|
} else {
|
|
1203
1319
|
this.isSuperAdmin = false;
|
|
@@ -1206,12 +1322,33 @@ var EventService = class extends BaseService {
|
|
|
1206
1322
|
this.resetInitialization();
|
|
1207
1323
|
this.isInitializedRef = false;
|
|
1208
1324
|
this.isFetchingRef = false;
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
this.
|
|
1214
|
-
|
|
1325
|
+
const shouldClearEvents = !this.isSuperAdmin;
|
|
1326
|
+
const isFirstOrgSet = (previousOrgId === null || previousOrgId === void 0) && newOrgId !== null && newOrgId !== void 0;
|
|
1327
|
+
if (isFirstOrgSet) {
|
|
1328
|
+
const hadAutoSelectedEvent = this.hasAutoSelectedRef && !!this.selectedEvent;
|
|
1329
|
+
this.userClearedEventRef = false;
|
|
1330
|
+
if (!hadAutoSelectedEvent) {
|
|
1331
|
+
this.hasAutoSelectedRef = false;
|
|
1332
|
+
}
|
|
1333
|
+
logger.debug("EventService", "Organisation first set - preserving event and resetting auto-selection flags", {
|
|
1334
|
+
organisationId: newOrgId,
|
|
1335
|
+
hasSelectedEvent: !!this.selectedEvent,
|
|
1336
|
+
selectedEventId: this.selectedEvent?.event_id,
|
|
1337
|
+
hadAutoSelectedEvent,
|
|
1338
|
+
preservingEvent: hadAutoSelectedEvent,
|
|
1339
|
+
previousOrgId,
|
|
1340
|
+
newOrgId
|
|
1341
|
+
});
|
|
1342
|
+
} else if (previousOrgId !== null && previousOrgId !== void 0 && newOrgId !== null && newOrgId !== void 0 && previousOrgId !== newOrgId) {
|
|
1343
|
+
if (shouldClearEvents) {
|
|
1344
|
+
this.events = [];
|
|
1345
|
+
this.setSelectedEvent(null);
|
|
1346
|
+
}
|
|
1347
|
+
} else if (previousOrgId !== null && previousOrgId !== void 0 && newOrgId === null) {
|
|
1348
|
+
if (shouldClearEvents) {
|
|
1349
|
+
this.events = [];
|
|
1350
|
+
this.setSelectedEvent(null);
|
|
1351
|
+
}
|
|
1215
1352
|
}
|
|
1216
1353
|
}
|
|
1217
1354
|
this.notify();
|
|
@@ -1238,7 +1375,13 @@ var EventService = class extends BaseService {
|
|
|
1238
1375
|
logger.warn("EventService", "Failed to persist event selection:", error);
|
|
1239
1376
|
});
|
|
1240
1377
|
this.userClearedEventRef = false;
|
|
1378
|
+
logger.debug("EventService", "Event selected", {
|
|
1379
|
+
eventId: event.event_id,
|
|
1380
|
+
eventName: event.event_name,
|
|
1381
|
+
userClearedEventRef: this.userClearedEventRef
|
|
1382
|
+
});
|
|
1241
1383
|
} else {
|
|
1384
|
+
const previousEventId = this.selectedEvent?.event_id;
|
|
1242
1385
|
this.selectedEvent = null;
|
|
1243
1386
|
this.setSelectedEventId?.(null);
|
|
1244
1387
|
this.clearEventSelection().catch((error) => {
|
|
@@ -1246,6 +1389,11 @@ var EventService = class extends BaseService {
|
|
|
1246
1389
|
});
|
|
1247
1390
|
this.hasAutoSelectedRef = false;
|
|
1248
1391
|
this.userClearedEventRef = true;
|
|
1392
|
+
logger.debug("EventService", "Event cleared via setSelectedEvent(null)", {
|
|
1393
|
+
previousEventId,
|
|
1394
|
+
userClearedEventRef: this.userClearedEventRef,
|
|
1395
|
+
stackTrace: new Error().stack
|
|
1396
|
+
});
|
|
1249
1397
|
}
|
|
1250
1398
|
this.notify();
|
|
1251
1399
|
}
|
|
@@ -1335,9 +1483,11 @@ var EventService = class extends BaseService {
|
|
|
1335
1483
|
}
|
|
1336
1484
|
async doInitialize() {
|
|
1337
1485
|
if (this.isInitializedRef) {
|
|
1486
|
+
logger.debug("EventService", "Skipping initialization - already initialized");
|
|
1338
1487
|
return;
|
|
1339
1488
|
}
|
|
1340
1489
|
if (this.isFetchingRef) {
|
|
1490
|
+
logger.debug("EventService", "Skipping initialization - already fetching");
|
|
1341
1491
|
return;
|
|
1342
1492
|
}
|
|
1343
1493
|
try {
|
|
@@ -1348,10 +1498,22 @@ var EventService = class extends BaseService {
|
|
|
1348
1498
|
logger.warn("EventService", "Failed to clean up old storage keys:", error);
|
|
1349
1499
|
}
|
|
1350
1500
|
if (!this.user) {
|
|
1501
|
+
logger.debug("EventService", "Skipping initialization - no user");
|
|
1351
1502
|
return;
|
|
1352
1503
|
}
|
|
1504
|
+
logger.debug("EventService", "Initializing", {
|
|
1505
|
+
userId: this.user.id,
|
|
1506
|
+
appName: this.appName,
|
|
1507
|
+
hasSelectedOrganisation: !!this.selectedOrganisation,
|
|
1508
|
+
hasSupabaseClient: !!this.supabaseClient,
|
|
1509
|
+
hasSession: !!this.session
|
|
1510
|
+
});
|
|
1353
1511
|
await this.fetchEvents(false);
|
|
1354
1512
|
this.isInitializedRef = true;
|
|
1513
|
+
logger.debug("EventService", "Initialization complete", {
|
|
1514
|
+
eventsCount: this.events.length,
|
|
1515
|
+
hasError: !!this.error
|
|
1516
|
+
});
|
|
1355
1517
|
}
|
|
1356
1518
|
doCleanup() {
|
|
1357
1519
|
}
|
|
@@ -1368,55 +1530,91 @@ var EventService = class extends BaseService {
|
|
|
1368
1530
|
this.isFetchingRef = true;
|
|
1369
1531
|
let isMounted = true;
|
|
1370
1532
|
try {
|
|
1371
|
-
if (!this.appConfig && this.appName) {
|
|
1372
|
-
try {
|
|
1373
|
-
this.appConfig = await getAppConfigByName(this.appName);
|
|
1374
|
-
} catch (configError) {
|
|
1375
|
-
logger.warn("EventService", "Failed to load app config, defaulting to event-required", {
|
|
1376
|
-
error: configError
|
|
1377
|
-
});
|
|
1378
|
-
this.appConfig = { requires_event: true };
|
|
1379
|
-
}
|
|
1380
|
-
}
|
|
1381
1533
|
let organisationIdForRpc = null;
|
|
1382
|
-
let userIsSuperAdmin =
|
|
1534
|
+
let userIsSuperAdmin = this.isSuperAdmin;
|
|
1383
1535
|
try {
|
|
1384
|
-
|
|
1536
|
+
const { isRBACInitialized: isRBACInitialized2, isSuperAdmin: checkSuperAdmin, setupRBAC: setupRBAC2 } = await import("./api-6LVZTHDS.js");
|
|
1537
|
+
if (!isRBACInitialized2() && this.supabaseClient) {
|
|
1538
|
+
setupRBAC2(this.supabaseClient);
|
|
1539
|
+
}
|
|
1540
|
+
if (isRBACInitialized2()) {
|
|
1541
|
+
userIsSuperAdmin = await checkSuperAdmin(this.user.id);
|
|
1542
|
+
this.isSuperAdmin = userIsSuperAdmin;
|
|
1543
|
+
logger.debug("EventService", "Super admin check completed", {
|
|
1544
|
+
userId: this.user.id,
|
|
1545
|
+
isSuperAdmin: userIsSuperAdmin
|
|
1546
|
+
});
|
|
1547
|
+
} else {
|
|
1548
|
+
if (this.isSuperAdmin) {
|
|
1549
|
+
userIsSuperAdmin = true;
|
|
1550
|
+
logger.warn("EventService", "RBAC not initialized, using cached super admin status", {
|
|
1551
|
+
userId: this.user.id,
|
|
1552
|
+
cachedIsSuperAdmin: this.isSuperAdmin,
|
|
1553
|
+
note: "RBAC should be initialized by UnifiedAuthProvider. This may indicate EventService is being used outside the provider."
|
|
1554
|
+
});
|
|
1555
|
+
} else {
|
|
1556
|
+
logger.warn("EventService", "RBAC not initialized, using cached non-super-admin status", {
|
|
1557
|
+
userId: this.user.id,
|
|
1558
|
+
cachedIsSuperAdmin: this.isSuperAdmin,
|
|
1559
|
+
note: "RBAC should be initialized by UnifiedAuthProvider. This may indicate EventService is being used outside the provider."
|
|
1560
|
+
});
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1385
1563
|
if (userIsSuperAdmin) {
|
|
1386
1564
|
organisationIdForRpc = null;
|
|
1387
1565
|
} else {
|
|
1388
1566
|
if (this.selectedEvent) {
|
|
1389
1567
|
organisationIdForRpc = this.selectedEvent.organisation_id;
|
|
1390
|
-
} else if (this.appConfig?.requires_event === true) {
|
|
1391
|
-
organisationIdForRpc = null;
|
|
1392
1568
|
} else if (this.selectedOrganisation) {
|
|
1393
1569
|
organisationIdForRpc = this.selectedOrganisation.id;
|
|
1394
1570
|
} else {
|
|
1395
|
-
logger.
|
|
1571
|
+
logger.debug("EventService", "No organisation context available, fetching all accessible events", {
|
|
1396
1572
|
hasSelectedEvent: !!this.selectedEvent,
|
|
1397
|
-
hasSelectedOrganisation: !!this.selectedOrganisation
|
|
1398
|
-
appRequiresEvent: this.appConfig?.requires_event
|
|
1573
|
+
hasSelectedOrganisation: !!this.selectedOrganisation
|
|
1399
1574
|
});
|
|
1400
1575
|
organisationIdForRpc = null;
|
|
1401
1576
|
}
|
|
1402
1577
|
}
|
|
1403
1578
|
} catch (superAdminCheckError) {
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
});
|
|
1407
|
-
if (this.selectedEvent) {
|
|
1408
|
-
organisationIdForRpc = this.selectedEvent.organisation_id;
|
|
1409
|
-
} else if (this.appConfig?.requires_event === true) {
|
|
1579
|
+
if (this.isSuperAdmin) {
|
|
1580
|
+
userIsSuperAdmin = true;
|
|
1410
1581
|
organisationIdForRpc = null;
|
|
1411
|
-
|
|
1412
|
-
|
|
1582
|
+
logger.warn("EventService", "Super admin check failed, using cached super admin status", {
|
|
1583
|
+
error: superAdminCheckError,
|
|
1584
|
+
cachedIsSuperAdmin: this.isSuperAdmin
|
|
1585
|
+
});
|
|
1586
|
+
} else {
|
|
1587
|
+
logger.warn("EventService", "Failed to check super admin status, using organisation-scoped query", {
|
|
1588
|
+
error: superAdminCheckError,
|
|
1589
|
+
cachedIsSuperAdmin: this.isSuperAdmin
|
|
1590
|
+
});
|
|
1591
|
+
if (this.selectedEvent) {
|
|
1592
|
+
organisationIdForRpc = this.selectedEvent.organisation_id;
|
|
1593
|
+
} else if (this.selectedOrganisation) {
|
|
1594
|
+
organisationIdForRpc = this.selectedOrganisation.id;
|
|
1595
|
+
} else {
|
|
1596
|
+
organisationIdForRpc = null;
|
|
1597
|
+
}
|
|
1413
1598
|
}
|
|
1414
1599
|
}
|
|
1600
|
+
logger.debug("EventService", "Fetching events", {
|
|
1601
|
+
userId: this.user.id,
|
|
1602
|
+
organisationIdForRpc,
|
|
1603
|
+
appName: this.appName,
|
|
1604
|
+
hasSelectedEvent: !!this.selectedEvent,
|
|
1605
|
+
hasSelectedOrganisation: !!this.selectedOrganisation,
|
|
1606
|
+
isSuperAdmin: userIsSuperAdmin
|
|
1607
|
+
});
|
|
1415
1608
|
let { data, error: rpcError } = await this.supabaseClient.rpc("data_user_events_get", {
|
|
1416
1609
|
p_user_id: this.user.id,
|
|
1417
1610
|
p_organisation_id: organisationIdForRpc,
|
|
1418
1611
|
p_app_name: this.appName
|
|
1419
1612
|
});
|
|
1613
|
+
logger.debug("EventService", "RPC response", {
|
|
1614
|
+
dataLength: data?.length || 0,
|
|
1615
|
+
hasError: !!rpcError,
|
|
1616
|
+
error: rpcError
|
|
1617
|
+
});
|
|
1420
1618
|
if (rpcError) {
|
|
1421
1619
|
logger.error("EventService", "RPC error fetching events:", rpcError);
|
|
1422
1620
|
throw new Error(rpcError.message || "Failed to fetch events");
|
|
@@ -1439,25 +1637,84 @@ var EventService = class extends BaseService {
|
|
|
1439
1637
|
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1440
1638
|
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1441
1639
|
}));
|
|
1442
|
-
|
|
1640
|
+
const sortedEvents = [...transformedEvents].sort((a, b) => {
|
|
1641
|
+
if (a.event_date && b.event_date) {
|
|
1642
|
+
return new Date(b.event_date).getTime() - new Date(a.event_date).getTime();
|
|
1643
|
+
}
|
|
1644
|
+
if (a.event_date && !b.event_date) return -1;
|
|
1645
|
+
if (!a.event_date && b.event_date) return 1;
|
|
1646
|
+
return 0;
|
|
1647
|
+
});
|
|
1648
|
+
this.events = sortedEvents;
|
|
1443
1649
|
this.error = null;
|
|
1650
|
+
if (this.selectedEvent) {
|
|
1651
|
+
const selectedEventId = this.selectedEvent.event_id;
|
|
1652
|
+
const eventStillExists = transformedEvents.some(
|
|
1653
|
+
(e) => e.event_id === selectedEventId
|
|
1654
|
+
);
|
|
1655
|
+
if (!eventStillExists) {
|
|
1656
|
+
const previousUserClearedRef = this.userClearedEventRef;
|
|
1657
|
+
this.selectedEvent = null;
|
|
1658
|
+
this.setSelectedEventId?.(null);
|
|
1659
|
+
this.userClearedEventRef = previousUserClearedRef;
|
|
1660
|
+
logger.debug("EventService", "Cleared selected event - no longer in events list", {
|
|
1661
|
+
previousEventId: selectedEventId,
|
|
1662
|
+
eventsCount: transformedEvents.length
|
|
1663
|
+
});
|
|
1664
|
+
}
|
|
1665
|
+
}
|
|
1444
1666
|
this.hasAutoSelectedRef = false;
|
|
1445
1667
|
if (!skipLoadPersisted) {
|
|
1446
1668
|
const persistedEventLoaded = await this.loadPersistedEvent(transformedEvents);
|
|
1669
|
+
logger.debug("EventService", "Event selection check", {
|
|
1670
|
+
persistedEventLoaded,
|
|
1671
|
+
userClearedEventRef: this.userClearedEventRef,
|
|
1672
|
+
eventsCount: transformedEvents.length,
|
|
1673
|
+
hasSelectedEvent: !!this.selectedEvent
|
|
1674
|
+
});
|
|
1447
1675
|
if (!persistedEventLoaded && !this.userClearedEventRef) {
|
|
1448
1676
|
const nextEvent = this.getNextEventByDate(transformedEvents);
|
|
1677
|
+
logger.debug("EventService", "Auto-selection attempt", {
|
|
1678
|
+
nextEventFound: !!nextEvent,
|
|
1679
|
+
nextEventId: nextEvent?.event_id,
|
|
1680
|
+
nextEventDate: nextEvent?.event_date
|
|
1681
|
+
});
|
|
1449
1682
|
if (nextEvent) {
|
|
1450
1683
|
this.hasAutoSelectedRef = true;
|
|
1451
1684
|
this.setSelectedEvent(nextEvent);
|
|
1685
|
+
logger.debug("EventService", "Auto-selected next event", {
|
|
1686
|
+
eventId: nextEvent.event_id,
|
|
1687
|
+
eventName: nextEvent.event_name,
|
|
1688
|
+
eventDate: nextEvent.event_date
|
|
1689
|
+
});
|
|
1690
|
+
} else {
|
|
1691
|
+
logger.debug("EventService", "No next event found for auto-selection", {
|
|
1692
|
+
eventsCount: transformedEvents.length,
|
|
1693
|
+
eventsWithDates: transformedEvents.filter((e) => e.event_date).length
|
|
1694
|
+
});
|
|
1452
1695
|
}
|
|
1696
|
+
} else if (persistedEventLoaded) {
|
|
1697
|
+
logger.debug("EventService", "Skipped auto-selection - persisted event loaded");
|
|
1698
|
+
} else if (this.userClearedEventRef) {
|
|
1699
|
+
logger.debug("EventService", "Skipped auto-selection - user explicitly cleared event");
|
|
1453
1700
|
}
|
|
1454
1701
|
} else {
|
|
1455
1702
|
if (!this.userClearedEventRef) {
|
|
1456
1703
|
const nextEvent = this.getNextEventByDate(transformedEvents);
|
|
1704
|
+
logger.debug("EventService", "Auto-selection attempt (skip persisted)", {
|
|
1705
|
+
nextEventFound: !!nextEvent,
|
|
1706
|
+
nextEventId: nextEvent?.event_id
|
|
1707
|
+
});
|
|
1457
1708
|
if (nextEvent) {
|
|
1458
1709
|
this.hasAutoSelectedRef = true;
|
|
1459
1710
|
this.setSelectedEvent(nextEvent);
|
|
1711
|
+
logger.debug("EventService", "Auto-selected next event (skip persisted)", {
|
|
1712
|
+
eventId: nextEvent.event_id,
|
|
1713
|
+
eventName: nextEvent.event_name
|
|
1714
|
+
});
|
|
1460
1715
|
}
|
|
1716
|
+
} else {
|
|
1717
|
+
logger.debug("EventService", "Skipped auto-selection (skip persisted) - user explicitly cleared event");
|
|
1461
1718
|
}
|
|
1462
1719
|
}
|
|
1463
1720
|
}
|
|
@@ -1514,6 +1771,8 @@ var EventService = class extends BaseService {
|
|
|
1514
1771
|
return null;
|
|
1515
1772
|
}
|
|
1516
1773
|
};
|
|
1774
|
+
_EventService.instanceCount = 0;
|
|
1775
|
+
var EventService = _EventService;
|
|
1517
1776
|
|
|
1518
1777
|
// src/providers/services/EventServiceProvider.tsx
|
|
1519
1778
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
@@ -1527,27 +1786,52 @@ function EventServiceProvider({
|
|
|
1527
1786
|
selectedOrganisation,
|
|
1528
1787
|
setSelectedEventId
|
|
1529
1788
|
}) {
|
|
1530
|
-
const eventServiceRef =
|
|
1531
|
-
const initializingRef =
|
|
1789
|
+
const eventServiceRef = useRef3(null);
|
|
1790
|
+
const initializingRef = useRef3(false);
|
|
1532
1791
|
if (!eventServiceRef.current) {
|
|
1533
1792
|
eventServiceRef.current = new EventService(supabaseClient, user, session, appName, selectedOrganisation, setSelectedEventId);
|
|
1534
1793
|
}
|
|
1535
1794
|
const eventService = eventServiceRef.current;
|
|
1536
1795
|
useEffect3(() => {
|
|
1537
1796
|
let isMounted = true;
|
|
1797
|
+
logger.debug("EventServiceProvider", "useEffect triggered", {
|
|
1798
|
+
hasUser: !!user,
|
|
1799
|
+
userId: user?.id,
|
|
1800
|
+
hasSession: !!session,
|
|
1801
|
+
appName,
|
|
1802
|
+
isInitializing: initializingRef.current
|
|
1803
|
+
});
|
|
1538
1804
|
if (initializingRef.current) {
|
|
1805
|
+
logger.debug("EventServiceProvider", "Skipping - already initializing");
|
|
1539
1806
|
return;
|
|
1540
1807
|
}
|
|
1541
1808
|
const updateAndInitialize = async () => {
|
|
1542
1809
|
initializingRef.current = true;
|
|
1543
1810
|
try {
|
|
1811
|
+
logger.debug("EventServiceProvider", "Updating dependencies and initializing", {
|
|
1812
|
+
hasUser: !!user,
|
|
1813
|
+
userId: user?.id,
|
|
1814
|
+
hasSession: !!session,
|
|
1815
|
+
appName,
|
|
1816
|
+
hasSelectedOrganisation: !!selectedOrganisation
|
|
1817
|
+
});
|
|
1544
1818
|
await eventService.updateDependencies(supabaseClient, user, session, appName, selectedOrganisation, setSelectedEventId);
|
|
1545
1819
|
if (!isMounted) return;
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1820
|
+
if (user && session && supabaseClient && appName) {
|
|
1821
|
+
logger.debug("EventServiceProvider", "Initializing event service");
|
|
1822
|
+
await eventService.initialize().catch((error) => {
|
|
1823
|
+
if (isMounted) {
|
|
1824
|
+
logger.error("EventServiceProvider", "Failed to initialize event service:", error);
|
|
1825
|
+
}
|
|
1826
|
+
});
|
|
1827
|
+
} else {
|
|
1828
|
+
logger.debug("EventServiceProvider", "Skipping initialization - missing required dependencies", {
|
|
1829
|
+
hasUser: !!user,
|
|
1830
|
+
hasSession: !!session,
|
|
1831
|
+
hasSupabaseClient: !!supabaseClient,
|
|
1832
|
+
appName
|
|
1833
|
+
});
|
|
1834
|
+
}
|
|
1551
1835
|
} finally {
|
|
1552
1836
|
initializingRef.current = false;
|
|
1553
1837
|
}
|
|
@@ -1570,7 +1854,7 @@ function EventServiceProvider({
|
|
|
1570
1854
|
}
|
|
1571
1855
|
|
|
1572
1856
|
// src/providers/services/InactivityServiceProvider.tsx
|
|
1573
|
-
import { createContext as createContext4, useMemo as useMemo4, useEffect as useEffect4, useRef as
|
|
1857
|
+
import { createContext as createContext4, useMemo as useMemo4, useEffect as useEffect4, useRef as useRef4 } from "react";
|
|
1574
1858
|
|
|
1575
1859
|
// src/services/InactivityService.ts
|
|
1576
1860
|
var InactivityService = class extends BaseService {
|
|
@@ -1914,7 +2198,7 @@ function InactivityServiceProvider({
|
|
|
1914
2198
|
// REQUIRED: No default - must be explicitly provided
|
|
1915
2199
|
onIdleLogout
|
|
1916
2200
|
}) {
|
|
1917
|
-
const inactivityServiceRef =
|
|
2201
|
+
const inactivityServiceRef = useRef4(null);
|
|
1918
2202
|
if (!inactivityServiceRef.current) {
|
|
1919
2203
|
inactivityServiceRef.current = new InactivityService(supabaseClient, user, session, idleTimeoutMs, warnBeforeMs, onIdleLogout);
|
|
1920
2204
|
}
|
|
@@ -1943,14 +2227,14 @@ function InactivityServiceProvider({
|
|
|
1943
2227
|
}
|
|
1944
2228
|
|
|
1945
2229
|
// src/hooks/services/useAuthService.ts
|
|
1946
|
-
import { useContext, useReducer, useEffect as useEffect5, useRef as
|
|
2230
|
+
import { useContext, useReducer, useEffect as useEffect5, useRef as useRef5 } from "react";
|
|
1947
2231
|
function useAuthService() {
|
|
1948
2232
|
const context = useContext(AuthServiceContext);
|
|
1949
2233
|
if (!context) {
|
|
1950
2234
|
throw new Error("useAuthService must be used within AuthServiceProvider");
|
|
1951
2235
|
}
|
|
1952
2236
|
const [, forceUpdate] = useReducer((x) => x + 1, 0);
|
|
1953
|
-
const timeoutRef =
|
|
2237
|
+
const timeoutRef = useRef5(null);
|
|
1954
2238
|
useEffect5(() => {
|
|
1955
2239
|
const debouncedUpdate = () => {
|
|
1956
2240
|
if (timeoutRef.current) {
|
|
@@ -1973,14 +2257,14 @@ function useAuthService() {
|
|
|
1973
2257
|
}
|
|
1974
2258
|
|
|
1975
2259
|
// src/hooks/services/useOrganisationService.ts
|
|
1976
|
-
import { useContext as useContext2, useReducer as useReducer2, useEffect as useEffect6, useRef as
|
|
2260
|
+
import { useContext as useContext2, useReducer as useReducer2, useEffect as useEffect6, useRef as useRef6 } from "react";
|
|
1977
2261
|
function useOrganisationService() {
|
|
1978
2262
|
const context = useContext2(OrganisationServiceContext);
|
|
1979
2263
|
if (!context) {
|
|
1980
2264
|
throw new Error("useOrganisationService must be used within OrganisationServiceProvider");
|
|
1981
2265
|
}
|
|
1982
2266
|
const [, forceUpdate] = useReducer2((x) => x + 1, 0);
|
|
1983
|
-
const timeoutRef =
|
|
2267
|
+
const timeoutRef = useRef6(null);
|
|
1984
2268
|
useEffect6(() => {
|
|
1985
2269
|
const debouncedUpdate = () => {
|
|
1986
2270
|
if (timeoutRef.current) {
|
|
@@ -2026,14 +2310,14 @@ function useOrganisations() {
|
|
|
2026
2310
|
}
|
|
2027
2311
|
|
|
2028
2312
|
// src/hooks/services/useEventService.ts
|
|
2029
|
-
import { useContext as useContext3, useReducer as useReducer3, useEffect as useEffect7, useRef as
|
|
2313
|
+
import { useContext as useContext3, useReducer as useReducer3, useEffect as useEffect7, useRef as useRef7 } from "react";
|
|
2030
2314
|
function useEventService() {
|
|
2031
2315
|
const context = useContext3(EventServiceContext);
|
|
2032
2316
|
if (!context) {
|
|
2033
2317
|
throw new Error("useEventService must be used within EventServiceProvider");
|
|
2034
2318
|
}
|
|
2035
2319
|
const [, forceUpdate] = useReducer3((x) => x + 1, 0);
|
|
2036
|
-
const timeoutRef =
|
|
2320
|
+
const timeoutRef = useRef7(null);
|
|
2037
2321
|
useEffect7(() => {
|
|
2038
2322
|
const debouncedUpdate = () => {
|
|
2039
2323
|
if (timeoutRef.current) {
|
|
@@ -2056,14 +2340,14 @@ function useEventService() {
|
|
|
2056
2340
|
}
|
|
2057
2341
|
|
|
2058
2342
|
// src/hooks/services/useInactivityService.ts
|
|
2059
|
-
import { useContext as useContext4, useReducer as useReducer4, useEffect as useEffect8, useRef as
|
|
2343
|
+
import { useContext as useContext4, useReducer as useReducer4, useEffect as useEffect8, useRef as useRef8 } from "react";
|
|
2060
2344
|
function useInactivityService() {
|
|
2061
2345
|
const context = useContext4(InactivityServiceContext);
|
|
2062
2346
|
if (!context) {
|
|
2063
2347
|
throw new Error("useInactivityService must be used within InactivityServiceProvider");
|
|
2064
2348
|
}
|
|
2065
2349
|
const [, forceUpdate] = useReducer4((x) => x + 1, 0);
|
|
2066
|
-
const timeoutRef =
|
|
2350
|
+
const timeoutRef = useRef8(null);
|
|
2067
2351
|
useEffect8(() => {
|
|
2068
2352
|
const debouncedUpdate = () => {
|
|
2069
2353
|
if (timeoutRef.current) {
|
|
@@ -2138,7 +2422,6 @@ var useUnifiedAuth = () => {
|
|
|
2138
2422
|
function UnifiedAuthContextProvider({
|
|
2139
2423
|
children,
|
|
2140
2424
|
appName,
|
|
2141
|
-
appConfig: appConfigProp,
|
|
2142
2425
|
supabaseClient: supabaseClientProp,
|
|
2143
2426
|
...props
|
|
2144
2427
|
}) {
|
|
@@ -2158,13 +2441,6 @@ function UnifiedAuthContextProvider({
|
|
|
2158
2441
|
restorationComplete,
|
|
2159
2442
|
restorationError
|
|
2160
2443
|
}), [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]);
|
|
2168
2444
|
let eventService;
|
|
2169
2445
|
try {
|
|
2170
2446
|
eventService = useEventService();
|
|
@@ -2188,9 +2464,17 @@ function UnifiedAuthContextProvider({
|
|
|
2188
2464
|
const isAuth = !!(currentUser && currentSession);
|
|
2189
2465
|
const supabase = useMemo6(() => supabaseClientProp, [supabaseClientProp]);
|
|
2190
2466
|
const [appId, setAppId] = useState3(void 0);
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2467
|
+
useEffect10(() => {
|
|
2468
|
+
logger.debug("UnifiedAuthContextProvider", `Rendering [AuthService ID:${authService.getInstanceId?.() || "unknown"}]`, {
|
|
2469
|
+
hasUser: !!currentUser,
|
|
2470
|
+
userId: currentUser?.id,
|
|
2471
|
+
hasSession: !!currentSession,
|
|
2472
|
+
isAuth
|
|
2473
|
+
});
|
|
2474
|
+
}, [currentUser?.id, currentSession?.access_token, isAuth, authService]);
|
|
2475
|
+
const isResolvingAppIdRef = useRef9(false);
|
|
2476
|
+
const resolvedAppIdRef = useRef9(void 0);
|
|
2477
|
+
const resolvedUserIdRef = useRef9(void 0);
|
|
2194
2478
|
useEffect10(() => {
|
|
2195
2479
|
if (!isAuth) {
|
|
2196
2480
|
resolvedAppIdRef.current = void 0;
|
|
@@ -2210,9 +2494,9 @@ function UnifiedAuthContextProvider({
|
|
|
2210
2494
|
resolvedUserIdRef.current = currentUserId;
|
|
2211
2495
|
const userId = currentUserId;
|
|
2212
2496
|
const appNameValue = appName;
|
|
2213
|
-
import("./api-
|
|
2497
|
+
import("./api-6LVZTHDS.js").then(async ({ resolveAppContext, setupRBAC: setupRBAC2 }) => {
|
|
2214
2498
|
try {
|
|
2215
|
-
|
|
2499
|
+
setupRBAC2(supabase);
|
|
2216
2500
|
const result = await resolveAppContext({
|
|
2217
2501
|
userId,
|
|
2218
2502
|
appName: appNameValue
|
|
@@ -2240,59 +2524,8 @@ function UnifiedAuthContextProvider({
|
|
|
2240
2524
|
});
|
|
2241
2525
|
}
|
|
2242
2526
|
}, [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-MVVQZLJI.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]);
|
|
2294
2527
|
const [, forceUpdate] = useReducer5((x) => x + 1, 0);
|
|
2295
|
-
const forceUpdateTimeoutRef =
|
|
2528
|
+
const forceUpdateTimeoutRef = useRef9(null);
|
|
2296
2529
|
const debouncedForceUpdate = useCallback(() => {
|
|
2297
2530
|
if (forceUpdateTimeoutRef.current) {
|
|
2298
2531
|
clearTimeout(forceUpdateTimeoutRef.current);
|
|
@@ -2302,10 +2535,10 @@ function UnifiedAuthContextProvider({
|
|
|
2302
2535
|
forceUpdateTimeoutRef.current = null;
|
|
2303
2536
|
}, 100);
|
|
2304
2537
|
}, [forceUpdate]);
|
|
2305
|
-
const authServiceRef =
|
|
2306
|
-
const organisationServiceRef =
|
|
2307
|
-
const eventServiceRef =
|
|
2308
|
-
const inactivityServiceRef =
|
|
2538
|
+
const authServiceRef = useRef9(authService);
|
|
2539
|
+
const organisationServiceRef = useRef9(organisationService);
|
|
2540
|
+
const eventServiceRef = useRef9(eventService);
|
|
2541
|
+
const inactivityServiceRef = useRef9(inactivityService);
|
|
2309
2542
|
useEffect10(() => {
|
|
2310
2543
|
authServiceRef.current = authService;
|
|
2311
2544
|
organisationServiceRef.current = organisationService;
|
|
@@ -2336,20 +2569,7 @@ function UnifiedAuthContextProvider({
|
|
|
2336
2569
|
const authError = authService.getError();
|
|
2337
2570
|
const rawSelectedOrganisation = organisationService.getSelectedOrganisation();
|
|
2338
2571
|
const organisationError = organisationService.getError();
|
|
2339
|
-
const selectedOrganisation =
|
|
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]);
|
|
2572
|
+
const selectedOrganisation = rawSelectedOrganisation;
|
|
2353
2573
|
const hasValidOrganisationContext = organisationService.hasValidOrganisationContext();
|
|
2354
2574
|
const isContextReady = organisationService.isContextReady();
|
|
2355
2575
|
const rawEvents = eventService.getEvents();
|
|
@@ -2418,7 +2638,7 @@ function UnifiedAuthContextProvider({
|
|
|
2418
2638
|
const handleIdleLogout = () => inactivityService.handleIdleLogout();
|
|
2419
2639
|
const handleStaySignedIn = () => inactivityService.handleStaySignedIn();
|
|
2420
2640
|
const handleSignOutNow = () => inactivityService.handleSignOutNow();
|
|
2421
|
-
const prevStateRef =
|
|
2641
|
+
const prevStateRef = useRef9(null);
|
|
2422
2642
|
const isDev = import.meta.env.DEV || import.meta.env.MODE === "development";
|
|
2423
2643
|
if (isDev) {
|
|
2424
2644
|
const currentState = {
|
|
@@ -2491,7 +2711,6 @@ function UnifiedAuthContextProvider({
|
|
|
2491
2711
|
appName,
|
|
2492
2712
|
appId,
|
|
2493
2713
|
// Resolved immediately on login
|
|
2494
|
-
appConfig,
|
|
2495
2714
|
isLoading: totalLoading,
|
|
2496
2715
|
hasErrors,
|
|
2497
2716
|
sessionRestoration,
|
|
@@ -2524,7 +2743,6 @@ function UnifiedAuthContextProvider({
|
|
|
2524
2743
|
hasErrors,
|
|
2525
2744
|
appName,
|
|
2526
2745
|
appId,
|
|
2527
|
-
appConfig,
|
|
2528
2746
|
sessionRestoration,
|
|
2529
2747
|
sessionRestorationTimedOut,
|
|
2530
2748
|
sessionRestorationTimeoutMs,
|
|
@@ -2558,13 +2776,19 @@ function EventServiceProviderWrapper({
|
|
|
2558
2776
|
supabaseClient,
|
|
2559
2777
|
user,
|
|
2560
2778
|
session,
|
|
2561
|
-
appName
|
|
2562
|
-
appConfig
|
|
2779
|
+
appName
|
|
2563
2780
|
}) {
|
|
2564
|
-
const { selectedOrganisation
|
|
2565
|
-
const selectedOrganisation = appConfig !== null && appConfig?.requires_event === true && !rawSelectedOrganisation ? null : rawSelectedOrganisation;
|
|
2781
|
+
const { selectedOrganisation } = useOrganisations();
|
|
2566
2782
|
const setSelectedEventId = useCallback(() => {
|
|
2567
2783
|
}, []);
|
|
2784
|
+
useEffect10(() => {
|
|
2785
|
+
logger.debug("EventServiceProviderWrapper", "Rendering with props", {
|
|
2786
|
+
hasUser: !!user,
|
|
2787
|
+
userId: user?.id,
|
|
2788
|
+
hasSession: !!session,
|
|
2789
|
+
selectedOrganisationId: selectedOrganisation?.id
|
|
2790
|
+
});
|
|
2791
|
+
}, [user?.id, session?.access_token, selectedOrganisation?.id]);
|
|
2568
2792
|
return /* @__PURE__ */ jsx5(
|
|
2569
2793
|
EventServiceProvider,
|
|
2570
2794
|
{
|
|
@@ -2582,7 +2806,6 @@ function ServiceAwareProviders({
|
|
|
2582
2806
|
children,
|
|
2583
2807
|
supabaseClient,
|
|
2584
2808
|
appName,
|
|
2585
|
-
appConfig,
|
|
2586
2809
|
persistState,
|
|
2587
2810
|
enablePersistence,
|
|
2588
2811
|
requireOrganisationContext,
|
|
@@ -2593,26 +2816,51 @@ function ServiceAwareProviders({
|
|
|
2593
2816
|
dangerouslyDisableInactivity
|
|
2594
2817
|
}) {
|
|
2595
2818
|
const authService = useAuthService();
|
|
2819
|
+
const [userState, setUserState] = useState3(() => authService.getUser());
|
|
2820
|
+
const [sessionState, setSessionState] = useState3(() => authService.getSession());
|
|
2821
|
+
useEffect10(() => {
|
|
2822
|
+
const unsubscribe = authService.subscribe(() => {
|
|
2823
|
+
const newUser = authService.getUser();
|
|
2824
|
+
const newSession = authService.getSession();
|
|
2825
|
+
logger.debug("ServiceAwareProviders", "Auth service notified, updating state", {
|
|
2826
|
+
hasUser: !!newUser,
|
|
2827
|
+
userId: newUser?.id,
|
|
2828
|
+
hasSession: !!newSession
|
|
2829
|
+
});
|
|
2830
|
+
setUserState(newUser);
|
|
2831
|
+
setSessionState(newSession);
|
|
2832
|
+
});
|
|
2833
|
+
return unsubscribe;
|
|
2834
|
+
}, [authService]);
|
|
2835
|
+
const user = userState;
|
|
2836
|
+
const session = sessionState;
|
|
2837
|
+
useEffect10(() => {
|
|
2838
|
+
logger.debug("ServiceAwareProviders", `User/session state [AuthService ID:${authService.getInstanceId?.() || "unknown"}]`, {
|
|
2839
|
+
hasUser: !!user,
|
|
2840
|
+
userId: user?.id,
|
|
2841
|
+
hasSession: !!session,
|
|
2842
|
+
sessionToken: session?.access_token ? "present" : "missing"
|
|
2843
|
+
});
|
|
2844
|
+
}, [user?.id, session?.access_token, authService]);
|
|
2596
2845
|
return /* @__PURE__ */ jsx5(
|
|
2597
2846
|
OrganisationServiceProvider,
|
|
2598
2847
|
{
|
|
2599
2848
|
supabaseClient,
|
|
2600
|
-
user
|
|
2601
|
-
session
|
|
2849
|
+
user,
|
|
2850
|
+
session,
|
|
2602
2851
|
children: /* @__PURE__ */ jsx5(
|
|
2603
2852
|
EventServiceProviderWrapper,
|
|
2604
2853
|
{
|
|
2605
2854
|
supabaseClient,
|
|
2606
|
-
user
|
|
2607
|
-
session
|
|
2855
|
+
user,
|
|
2856
|
+
session,
|
|
2608
2857
|
appName,
|
|
2609
|
-
appConfig,
|
|
2610
2858
|
children: /* @__PURE__ */ jsx5(
|
|
2611
2859
|
InactivityServiceProvider,
|
|
2612
2860
|
{
|
|
2613
2861
|
supabaseClient,
|
|
2614
|
-
user
|
|
2615
|
-
session
|
|
2862
|
+
user,
|
|
2863
|
+
session,
|
|
2616
2864
|
idleTimeoutMs,
|
|
2617
2865
|
warnBeforeMs,
|
|
2618
2866
|
onIdleLogout,
|
|
@@ -2620,7 +2868,6 @@ function ServiceAwareProviders({
|
|
|
2620
2868
|
UnifiedAuthContextProvider,
|
|
2621
2869
|
{
|
|
2622
2870
|
appName,
|
|
2623
|
-
appConfig,
|
|
2624
2871
|
supabaseClient,
|
|
2625
2872
|
persistState,
|
|
2626
2873
|
enablePersistence,
|
|
@@ -2644,8 +2891,6 @@ function UnifiedAuthProvider({
|
|
|
2644
2891
|
children,
|
|
2645
2892
|
supabaseClient,
|
|
2646
2893
|
appName,
|
|
2647
|
-
appConfig = { requires_event: true },
|
|
2648
|
-
// Default to requiring events
|
|
2649
2894
|
persistState = true,
|
|
2650
2895
|
enablePersistence,
|
|
2651
2896
|
requireOrganisationContext = true,
|
|
@@ -2658,7 +2903,7 @@ function UnifiedAuthProvider({
|
|
|
2658
2903
|
renderInactivityWarning,
|
|
2659
2904
|
dangerouslyDisableInactivity = false
|
|
2660
2905
|
}) {
|
|
2661
|
-
const clientRef =
|
|
2906
|
+
const clientRef = useRef9(supabaseClient);
|
|
2662
2907
|
useEffect10(() => {
|
|
2663
2908
|
if (clientRef.current !== supabaseClient) {
|
|
2664
2909
|
logger.warn("UnifiedAuthProvider", "Supabase client reference changed - this may indicate multiple client instances are being created", {
|
|
@@ -2667,14 +2912,23 @@ function UnifiedAuthProvider({
|
|
|
2667
2912
|
note: 'Ensure you create the Supabase client once and reuse it. Creating multiple clients can cause performance issues and the "Multiple GoTrueClient instances" warning.'
|
|
2668
2913
|
});
|
|
2669
2914
|
clientRef.current = supabaseClient;
|
|
2915
|
+
} else {
|
|
2916
|
+
logger.debug("UnifiedAuthProvider", "Supabase client reference is stable");
|
|
2670
2917
|
}
|
|
2671
2918
|
}, [supabaseClient]);
|
|
2919
|
+
if (supabaseClient && !isRBACInitialized()) {
|
|
2920
|
+
try {
|
|
2921
|
+
setupRBAC(supabaseClient);
|
|
2922
|
+
logger.debug("UnifiedAuthProvider", "RBAC initialized synchronously");
|
|
2923
|
+
} catch (err) {
|
|
2924
|
+
logger.error("UnifiedAuthProvider", "Failed to initialize RBAC", err);
|
|
2925
|
+
}
|
|
2926
|
+
}
|
|
2672
2927
|
return /* @__PURE__ */ jsx5(AuthServiceProvider, { supabaseClient, appName, children: /* @__PURE__ */ jsx5(
|
|
2673
2928
|
ServiceAwareProviders,
|
|
2674
2929
|
{
|
|
2675
2930
|
supabaseClient,
|
|
2676
2931
|
appName,
|
|
2677
|
-
appConfig,
|
|
2678
2932
|
persistState,
|
|
2679
2933
|
enablePersistence,
|
|
2680
2934
|
requireOrganisationContext,
|
|
@@ -2707,4 +2961,4 @@ export {
|
|
|
2707
2961
|
useUnifiedAuth,
|
|
2708
2962
|
UnifiedAuthProvider
|
|
2709
2963
|
};
|
|
2710
|
-
//# sourceMappingURL=chunk-
|
|
2964
|
+
//# sourceMappingURL=chunk-AVMLPIM7.js.map
|