@jmruthers/pace-core 0.5.43 → 0.5.45
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/{DataTable-BGK2YF7A.js → DataTable-PWLLTSP7.js} +5 -5
- package/dist/{UnifiedAuthProvider-DGQsy-vY.d.ts → UnifiedAuthProvider-CQNiemcB.d.ts} +2 -2
- package/dist/{chunk-BLZBTCBT.js → chunk-2T6QEWMI.js} +2 -2
- package/dist/{chunk-DNAASEYY.js → chunk-3FAB54BI.js} +4 -4
- package/dist/{chunk-37LRETMD.js → chunk-3PNBACK3.js} +2 -2
- package/dist/{chunk-ZSLTSF55.js → chunk-6AQ7X3EE.js} +5 -5
- package/dist/{chunk-X4Y4KT5T.js → chunk-D4X7PPGX.js} +3 -3
- package/dist/{chunk-SAB5UT2E.js → chunk-FZ7EBWOT.js} +3 -3
- package/dist/{chunk-B3MGS7VR.js → chunk-GIISFLMP.js} +3 -3
- package/dist/{chunk-RL267HOF.js → chunk-NYF3CUNC.js} +2 -2
- package/dist/{chunk-P27KH7XF.js → chunk-OQ6DTLZ6.js} +156 -196
- package/dist/chunk-OQ6DTLZ6.js.map +1 -0
- package/dist/{chunk-APHGXR2D.js → chunk-VCHXOYD5.js} +3 -3
- package/dist/components.d.ts +1 -1
- package/dist/components.js +7 -7
- package/dist/hooks.js +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +10 -10
- package/dist/providers.d.ts +1 -1
- package/dist/providers.js +3 -3
- package/dist/rbac/index.js +5 -5
- package/dist/utils.js +1 -1
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.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 +1 -1
- package/docs/api/classes/PublicErrorBoundary.md +1 -1
- package/docs/api/classes/RBACAuditManager.md +1 -1
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +1 -1
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +1 -1
- package/docs/api/classes/SecureSupabaseClient.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +1 -1
- package/docs/api/interfaces/ButtonProps.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/DataAccessRecord.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/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventContextType.md +1 -1
- package/docs/api/interfaces/EventLogoProps.md +1 -1
- package/docs/api/interfaces/EventProviderProps.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadProps.md +1 -1
- package/docs/api/interfaces/FooterProps.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/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
- 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 +1 -1
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
- package/docs/api/interfaces/PublicLoadingSpinnerProps.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/RBACConfig.md +1 -1
- package/docs/api/interfaces/RBACContextType.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RBACProviderProps.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +1 -1
- package/docs/api/interfaces/RouteConfig.md +1 -1
- package/docs/api/interfaces/SecureDataContextType.md +1 -1
- package/docs/api/interfaces/SecureDataProviderProps.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/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.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 +3 -3
- package/package.json +1 -1
- package/src/components/DataTable/__tests__/DataTable.comprehensive.test.tsx +756 -0
- package/src/components/DataTable/__tests__/DataTable.test.tsx +880 -0
- package/src/components/DataTable/__tests__/DataTableCore.test.tsx +702 -0
- package/src/components/PrintButton/__tests__/PrintButton.test.tsx +271 -0
- package/src/providers/AuthProvider.tsx +131 -230
- package/src/providers/OrganisationProvider.tsx +72 -10
- package/src/providers/__tests__/AuthProvider.test.tsx +619 -0
- package/src/providers/__tests__/EventProvider.test.tsx +190 -0
- package/src/providers/__tests__/InactivityProvider.test.tsx +645 -0
- package/src/providers/__tests__/OrganisationProvider.test.tsx +343 -0
- package/src/providers/__tests__/README.md +167 -0
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +581 -0
- package/src/rbac/__tests__/rbac-core.test.tsx +277 -0
- package/dist/chunk-P27KH7XF.js.map +0 -1
- /package/dist/{DataTable-BGK2YF7A.js.map → DataTable-PWLLTSP7.js.map} +0 -0
- /package/dist/{chunk-BLZBTCBT.js.map → chunk-2T6QEWMI.js.map} +0 -0
- /package/dist/{chunk-DNAASEYY.js.map → chunk-3FAB54BI.js.map} +0 -0
- /package/dist/{chunk-37LRETMD.js.map → chunk-3PNBACK3.js.map} +0 -0
- /package/dist/{chunk-ZSLTSF55.js.map → chunk-6AQ7X3EE.js.map} +0 -0
- /package/dist/{chunk-X4Y4KT5T.js.map → chunk-D4X7PPGX.js.map} +0 -0
- /package/dist/{chunk-SAB5UT2E.js.map → chunk-FZ7EBWOT.js.map} +0 -0
- /package/dist/{chunk-B3MGS7VR.js.map → chunk-GIISFLMP.js.map} +0 -0
- /package/dist/{chunk-RL267HOF.js.map → chunk-NYF3CUNC.js.map} +0 -0
- /package/dist/{chunk-APHGXR2D.js.map → chunk-VCHXOYD5.js.map} +0 -0
|
@@ -49,262 +49,174 @@ function AuthProvider({ children, supabaseClient }) {
|
|
|
49
49
|
};
|
|
50
50
|
}, []);
|
|
51
51
|
useEffect(() => {
|
|
52
|
-
if (!supabaseClient)
|
|
53
|
-
|
|
52
|
+
if (!supabaseClient) {
|
|
53
|
+
setAuthLoading(false);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
let isMounted = true;
|
|
57
|
+
const initializeAuth = async () => {
|
|
54
58
|
try {
|
|
55
|
-
DebugLogger.log("AuthProvider",
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
DebugLogger.log("AuthProvider", "Initializing authentication...");
|
|
60
|
+
const { data: { session: currentSession }, error: sessionError } = await supabaseClient.auth.getSession();
|
|
61
|
+
if (sessionError) {
|
|
62
|
+
console.warn("[AuthProvider] Error getting current session:", sessionError);
|
|
63
|
+
}
|
|
64
|
+
if (currentSession && isMounted) {
|
|
65
|
+
DebugLogger.log("AuthProvider", "Session restored from storage:", currentSession.user?.email);
|
|
66
|
+
setSession(currentSession);
|
|
67
|
+
setUser(currentSession.user);
|
|
68
|
+
setAuthError(null);
|
|
69
|
+
} else if (isMounted) {
|
|
70
|
+
DebugLogger.log("AuthProvider", "No session found in storage");
|
|
71
|
+
const { data: { user: currentUser }, error: userError } = await supabaseClient.auth.getUser();
|
|
72
|
+
if (userError) {
|
|
73
|
+
DebugLogger.log("AuthProvider", "No user found:", userError.message);
|
|
74
|
+
} else if (currentUser && isMounted) {
|
|
75
|
+
DebugLogger.log("AuthProvider", "User found without session:", currentUser.email);
|
|
76
|
+
setUser(currentUser);
|
|
64
77
|
}
|
|
65
|
-
setAuthLoading(false);
|
|
66
|
-
return;
|
|
67
78
|
}
|
|
68
|
-
if (
|
|
69
|
-
|
|
70
|
-
setUser(initialUser);
|
|
71
|
-
} else {
|
|
72
|
-
DebugLogger.log("AuthProvider", "No initial user found");
|
|
79
|
+
if (isMounted) {
|
|
80
|
+
setAuthLoading(false);
|
|
73
81
|
}
|
|
74
|
-
setAuthLoading(false);
|
|
75
82
|
} catch (error) {
|
|
76
|
-
console.error("Error
|
|
77
|
-
if (
|
|
78
|
-
|
|
79
|
-
setTimeout(() => loadInitialUser(1), 1e3);
|
|
80
|
-
return;
|
|
83
|
+
console.error("[AuthProvider] Error during auth initialization:", error);
|
|
84
|
+
if (isMounted) {
|
|
85
|
+
setAuthLoading(false);
|
|
81
86
|
}
|
|
82
|
-
setAuthLoading(false);
|
|
83
87
|
}
|
|
84
88
|
};
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
setAuthLoading(false);
|
|
101
|
-
setAuthError(new AuthError("Authentication timeout - please try refreshing the page"));
|
|
102
|
-
}
|
|
103
|
-
}, 1e4);
|
|
104
|
-
try {
|
|
105
|
-
DebugLogger.log("AuthProvider", "Setting up auth state change listener...");
|
|
106
|
-
const authStateChange = supabaseClient.auth.onAuthStateChange(
|
|
107
|
-
(event, session2) => {
|
|
108
|
-
try {
|
|
109
|
-
DebugLogger.log("AuthProvider", "Auth state changed:", event, session2?.user?.email);
|
|
110
|
-
clearTimeout(timeoutId);
|
|
111
|
-
if (event === "SIGNED_OUT") {
|
|
112
|
-
DebugLogger.log("AuthProvider", "User signed out, clearing all state");
|
|
113
|
-
setSession(null);
|
|
114
|
-
setUser(null);
|
|
115
|
-
setAuthLoading(false);
|
|
89
|
+
const { data: { subscription } } = supabaseClient.auth.onAuthStateChange(
|
|
90
|
+
(event, session2) => {
|
|
91
|
+
if (!isMounted) return;
|
|
92
|
+
try {
|
|
93
|
+
DebugLogger.log("AuthProvider", "Auth state changed:", event, session2?.user?.email);
|
|
94
|
+
if (event === "SIGNED_OUT") {
|
|
95
|
+
DebugLogger.log("AuthProvider", "User signed out, clearing all state");
|
|
96
|
+
setSession(null);
|
|
97
|
+
setUser(null);
|
|
98
|
+
setAuthError(null);
|
|
99
|
+
} else if (event === "SIGNED_IN" || event === "TOKEN_REFRESHED") {
|
|
100
|
+
DebugLogger.log("AuthProvider", "User signed in or token refreshed");
|
|
101
|
+
setSession(session2);
|
|
102
|
+
setUser(session2?.user ?? null);
|
|
103
|
+
if (session2) {
|
|
116
104
|
setAuthError(null);
|
|
117
|
-
}
|
|
118
|
-
|
|
105
|
+
}
|
|
106
|
+
} else if (event === "INITIAL_SESSION") {
|
|
107
|
+
DebugLogger.log("AuthProvider", "Initial session event");
|
|
108
|
+
if (session2) {
|
|
119
109
|
setSession(session2);
|
|
120
|
-
setUser(session2
|
|
121
|
-
|
|
122
|
-
if (session2) {
|
|
123
|
-
setAuthError(null);
|
|
124
|
-
}
|
|
125
|
-
} else {
|
|
126
|
-
if (session2) {
|
|
127
|
-
setSession(session2);
|
|
128
|
-
setUser(session2.user ?? null);
|
|
129
|
-
setAuthLoading(false);
|
|
130
|
-
if (session2) {
|
|
131
|
-
setAuthError(null);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
110
|
+
setUser(session2.user ?? null);
|
|
111
|
+
setAuthError(null);
|
|
134
112
|
}
|
|
135
|
-
}
|
|
136
|
-
|
|
113
|
+
}
|
|
114
|
+
setAuthLoading(false);
|
|
115
|
+
} catch (error) {
|
|
116
|
+
console.warn("[AuthProvider] Error in auth state change handler:", error);
|
|
117
|
+
if (isMounted) {
|
|
137
118
|
setAuthLoading(false);
|
|
138
119
|
}
|
|
139
120
|
}
|
|
140
|
-
);
|
|
141
|
-
const subscription = authStateChange?.data?.subscription || authStateChange;
|
|
142
|
-
return () => {
|
|
143
|
-
clearTimeout(timeoutId);
|
|
144
|
-
if (subscription && typeof subscription.unsubscribe === "function") {
|
|
145
|
-
DebugLogger.log("AuthProvider", "Cleaning up auth state listener");
|
|
146
|
-
subscription.unsubscribe();
|
|
147
|
-
}
|
|
148
|
-
};
|
|
149
|
-
} catch (error) {
|
|
150
|
-
console.error("AuthProvider: Error setting up auth state change listener:", error);
|
|
151
|
-
if (error instanceof Error && !error.message.includes("No API key found") && !error.message.includes("AuthSessionMissingError") && !error.message.includes("Auth session missing")) {
|
|
152
|
-
setAuthError(error);
|
|
153
121
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
122
|
+
);
|
|
123
|
+
initializeAuth();
|
|
124
|
+
return () => {
|
|
125
|
+
isMounted = false;
|
|
126
|
+
subscription?.unsubscribe();
|
|
127
|
+
};
|
|
159
128
|
}, [supabaseClient]);
|
|
160
129
|
const signIn = useCallback(async (email, password) => {
|
|
161
130
|
if (!supabaseClient) {
|
|
162
|
-
|
|
163
|
-
setAuthError(error);
|
|
164
|
-
return { error };
|
|
131
|
+
return { error: new AuthError("Supabase client not available") };
|
|
165
132
|
}
|
|
166
|
-
setAuthLoading(true);
|
|
167
|
-
setAuthError(null);
|
|
168
133
|
try {
|
|
169
|
-
const { error } = await supabaseClient.auth.signInWithPassword({
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
134
|
+
const { error } = await supabaseClient.auth.signInWithPassword({
|
|
135
|
+
email,
|
|
136
|
+
password: password || ""
|
|
137
|
+
});
|
|
138
|
+
return { error };
|
|
139
|
+
} catch (error) {
|
|
173
140
|
return { error };
|
|
174
|
-
} catch (err) {
|
|
175
|
-
const authError2 = err;
|
|
176
|
-
setAuthError(authError2);
|
|
177
|
-
return { error: authError2 };
|
|
178
|
-
} finally {
|
|
179
|
-
setAuthLoading(false);
|
|
180
141
|
}
|
|
181
142
|
}, [supabaseClient]);
|
|
182
143
|
const signUp = useCallback(async (email, password) => {
|
|
183
144
|
if (!supabaseClient) {
|
|
184
|
-
|
|
185
|
-
setAuthError(error);
|
|
186
|
-
return { error };
|
|
145
|
+
return { error: new AuthError("Supabase client not available") };
|
|
187
146
|
}
|
|
188
|
-
setAuthError(null);
|
|
189
147
|
try {
|
|
190
|
-
const { error } = await supabaseClient.auth.signUp({
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
148
|
+
const { error } = await supabaseClient.auth.signUp({
|
|
149
|
+
email,
|
|
150
|
+
password
|
|
151
|
+
});
|
|
152
|
+
return { error };
|
|
153
|
+
} catch (error) {
|
|
194
154
|
return { error };
|
|
195
|
-
} catch (err) {
|
|
196
|
-
const authError2 = err;
|
|
197
|
-
setAuthError(authError2);
|
|
198
|
-
return { error: authError2 };
|
|
199
155
|
}
|
|
200
156
|
}, [supabaseClient]);
|
|
201
157
|
const signOut = useCallback(async () => {
|
|
202
|
-
DebugLogger.log("AuthProvider", "signOut called");
|
|
203
|
-
setAuthLoading(false);
|
|
204
158
|
if (!supabaseClient) {
|
|
205
|
-
|
|
206
|
-
setUser(null);
|
|
207
|
-
setSession(null);
|
|
208
|
-
setAuthError(null);
|
|
209
|
-
return { error: null };
|
|
159
|
+
return { error: new AuthError("Supabase client not available") };
|
|
210
160
|
}
|
|
211
|
-
DebugLogger.log("AuthProvider", "Pre-clearing state before signOut call");
|
|
212
|
-
setUser(null);
|
|
213
|
-
setSession(null);
|
|
214
|
-
setAuthError(null);
|
|
215
161
|
try {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
);
|
|
221
|
-
const { error } = await Promise.race([signOutPromise, timeoutPromise]);
|
|
222
|
-
if (error && !error.message?.includes("SignOut timeout")) {
|
|
223
|
-
console.error("[AuthProvider] signOut error:", error);
|
|
224
|
-
}
|
|
225
|
-
DebugLogger.log("AuthProvider", "signOut process completed");
|
|
226
|
-
return { error: null };
|
|
227
|
-
} catch (err) {
|
|
228
|
-
console.warn("[AuthProvider] signOut exception (ignored):", err);
|
|
229
|
-
return { error: null };
|
|
162
|
+
const { error } = await supabaseClient.auth.signOut();
|
|
163
|
+
return { error };
|
|
164
|
+
} catch (error) {
|
|
165
|
+
return { error };
|
|
230
166
|
}
|
|
231
167
|
}, [supabaseClient]);
|
|
232
168
|
const resetPassword = useCallback(async (email) => {
|
|
233
169
|
if (!supabaseClient) {
|
|
234
|
-
|
|
235
|
-
setAuthError(error);
|
|
236
|
-
return { error };
|
|
170
|
+
return { error: new AuthError("Supabase client not available") };
|
|
237
171
|
}
|
|
238
|
-
setAuthError(null);
|
|
239
172
|
try {
|
|
240
173
|
const { error } = await supabaseClient.auth.resetPasswordForEmail(email);
|
|
241
|
-
if (error) {
|
|
242
|
-
setAuthError(error);
|
|
243
|
-
}
|
|
244
174
|
return { error };
|
|
245
|
-
} catch (
|
|
246
|
-
|
|
247
|
-
setAuthError(authError2);
|
|
248
|
-
return { error: authError2 };
|
|
175
|
+
} catch (error) {
|
|
176
|
+
return { error };
|
|
249
177
|
}
|
|
250
178
|
}, [supabaseClient]);
|
|
251
179
|
const updatePassword = useCallback(async (password) => {
|
|
252
|
-
if (!supabaseClient)
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
180
|
+
if (!supabaseClient) {
|
|
181
|
+
return { error: new AuthError("Supabase client not available") };
|
|
182
|
+
}
|
|
183
|
+
try {
|
|
184
|
+
const { error } = await supabaseClient.auth.updateUser({
|
|
185
|
+
password
|
|
186
|
+
});
|
|
187
|
+
return { error };
|
|
188
|
+
} catch (error) {
|
|
189
|
+
return { error };
|
|
256
190
|
}
|
|
257
|
-
return { error };
|
|
258
191
|
}, [supabaseClient]);
|
|
259
192
|
const refreshSession = useCallback(async () => {
|
|
260
193
|
if (!supabaseClient) {
|
|
261
|
-
|
|
262
|
-
setAuthError(error);
|
|
263
|
-
return { error };
|
|
194
|
+
return { error: new AuthError("Supabase client not available") };
|
|
264
195
|
}
|
|
265
|
-
setAuthError(null);
|
|
266
196
|
try {
|
|
267
197
|
const { error } = await supabaseClient.auth.refreshSession();
|
|
268
|
-
if (error) {
|
|
269
|
-
setAuthError(error);
|
|
270
|
-
}
|
|
271
198
|
return { error };
|
|
272
|
-
} catch (
|
|
273
|
-
|
|
274
|
-
setAuthError(authError2);
|
|
275
|
-
return { error: authError2 };
|
|
199
|
+
} catch (error) {
|
|
200
|
+
return { error };
|
|
276
201
|
}
|
|
277
202
|
}, [supabaseClient]);
|
|
278
|
-
const isAuthenticated = !!user;
|
|
279
203
|
const contextValue = useMemo(() => ({
|
|
280
204
|
user,
|
|
281
205
|
session,
|
|
282
|
-
isAuthenticated,
|
|
206
|
+
isAuthenticated: !!user && !!session,
|
|
283
207
|
authLoading,
|
|
284
208
|
authError,
|
|
285
209
|
error: authError,
|
|
286
210
|
// Alias for backward compatibility
|
|
287
211
|
supabase: supabaseClient || null,
|
|
212
|
+
// Ensure null instead of undefined
|
|
288
213
|
signIn,
|
|
289
214
|
signUp,
|
|
290
215
|
signOut,
|
|
291
216
|
resetPassword,
|
|
292
217
|
updatePassword,
|
|
293
218
|
refreshSession
|
|
294
|
-
}), [
|
|
295
|
-
user,
|
|
296
|
-
session,
|
|
297
|
-
isAuthenticated,
|
|
298
|
-
authLoading,
|
|
299
|
-
authError,
|
|
300
|
-
supabaseClient,
|
|
301
|
-
signIn,
|
|
302
|
-
signUp,
|
|
303
|
-
signOut,
|
|
304
|
-
resetPassword,
|
|
305
|
-
updatePassword,
|
|
306
|
-
refreshSession
|
|
307
|
-
]);
|
|
219
|
+
}), [user, session, authLoading, authError, supabaseClient, signIn, signUp, signOut, resetPassword, updatePassword, refreshSession]);
|
|
308
220
|
return /* @__PURE__ */ jsx(AuthContext.Provider, { value: contextValue, children });
|
|
309
221
|
}
|
|
310
222
|
var AuthContext, useAuth;
|
|
@@ -7430,6 +7342,10 @@ function OrganisationProvider({ children }) {
|
|
|
7430
7342
|
setError(null);
|
|
7431
7343
|
return;
|
|
7432
7344
|
}
|
|
7345
|
+
if (isLoading) {
|
|
7346
|
+
DebugLogger.log("OrganisationProvider", "Already loading, skipping duplicate load");
|
|
7347
|
+
return;
|
|
7348
|
+
}
|
|
7433
7349
|
setIsLoading(true);
|
|
7434
7350
|
setError(null);
|
|
7435
7351
|
try {
|
|
@@ -7463,10 +7379,32 @@ function OrganisationProvider({ children }) {
|
|
|
7463
7379
|
if (!memberships || memberships.length === 0) {
|
|
7464
7380
|
throw new Error("User has no active organisation memberships");
|
|
7465
7381
|
}
|
|
7466
|
-
|
|
7382
|
+
memberships.forEach((membership, index) => {
|
|
7383
|
+
if (!membership.organisation_id || membership.organisation_id.trim() === "") {
|
|
7384
|
+
console.warn(`[OrganisationProvider] Membership ${index} has invalid organisation_id:`, membership);
|
|
7385
|
+
}
|
|
7386
|
+
});
|
|
7387
|
+
const organisationIds = memberships.map((m) => m.organisation_id).filter((id) => {
|
|
7388
|
+
if (!id || typeof id !== "string") {
|
|
7389
|
+
console.warn("[OrganisationProvider] Invalid organisation ID (not string):", id);
|
|
7390
|
+
return false;
|
|
7391
|
+
}
|
|
7392
|
+
const trimmedId = id.trim();
|
|
7393
|
+
if (trimmedId === "") {
|
|
7394
|
+
console.warn("[OrganisationProvider] Empty organisation ID found");
|
|
7395
|
+
return false;
|
|
7396
|
+
}
|
|
7397
|
+
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);
|
|
7398
|
+
if (!isValidUuid) {
|
|
7399
|
+
console.warn("[OrganisationProvider] Invalid UUID format:", trimmedId);
|
|
7400
|
+
}
|
|
7401
|
+
return isValidUuid;
|
|
7402
|
+
});
|
|
7467
7403
|
if (organisationIds.length === 0) {
|
|
7404
|
+
console.warn("[OrganisationProvider] No valid organisation IDs found in memberships:", memberships);
|
|
7468
7405
|
throw new Error("No valid organisation IDs found in memberships");
|
|
7469
7406
|
}
|
|
7407
|
+
DebugLogger.log("OrganisationProvider", "Valid organisation IDs:", organisationIds);
|
|
7470
7408
|
const { data: organisations2, error: orgError } = await supabase.from("organisations").select("id, name, display_name, subscription_tier, settings, is_active, parent_id, created_at, updated_at").in("id", organisationIds);
|
|
7471
7409
|
if (orgError) {
|
|
7472
7410
|
console.error("[OrganisationProvider] Error loading organisations:", orgError);
|
|
@@ -7490,14 +7428,23 @@ function OrganisationProvider({ children }) {
|
|
|
7490
7428
|
const persistedOrgString = localStorage.getItem(STORAGE_KEYS2.SELECTED_ORGANISATION);
|
|
7491
7429
|
if (persistedOrgString) {
|
|
7492
7430
|
const persistedOrg = JSON.parse(persistedOrgString);
|
|
7493
|
-
|
|
7494
|
-
|
|
7495
|
-
|
|
7496
|
-
|
|
7431
|
+
if (persistedOrg.id && typeof persistedOrg.id === "string" && persistedOrg.id.trim() !== "") {
|
|
7432
|
+
const validPersistedOrg = activeOrgs.find((org) => org.id === persistedOrg.id);
|
|
7433
|
+
if (validPersistedOrg) {
|
|
7434
|
+
initialOrg = validPersistedOrg;
|
|
7435
|
+
DebugLogger.log("OrganisationProvider", "Restored persisted organisation:", initialOrg.display_name);
|
|
7436
|
+
} else {
|
|
7437
|
+
console.warn("[OrganisationProvider] Persisted organisation not found in active orgs, clearing cache");
|
|
7438
|
+
localStorage.removeItem(STORAGE_KEYS2.SELECTED_ORGANISATION);
|
|
7439
|
+
}
|
|
7440
|
+
} else {
|
|
7441
|
+
console.warn("[OrganisationProvider] Invalid persisted organisation ID, clearing cache");
|
|
7442
|
+
localStorage.removeItem(STORAGE_KEYS2.SELECTED_ORGANISATION);
|
|
7497
7443
|
}
|
|
7498
7444
|
}
|
|
7499
7445
|
} catch (storageError) {
|
|
7500
7446
|
console.warn("[OrganisationProvider] Failed to restore persisted organisation:", storageError);
|
|
7447
|
+
localStorage.removeItem(STORAGE_KEYS2.SELECTED_ORGANISATION);
|
|
7501
7448
|
}
|
|
7502
7449
|
if (!initialOrg) {
|
|
7503
7450
|
const adminMembership = memberships.find((m) => m.role === "org_admin");
|
|
@@ -7535,8 +7482,21 @@ function OrganisationProvider({ children }) {
|
|
|
7535
7482
|
}
|
|
7536
7483
|
}, [user, session, supabase]);
|
|
7537
7484
|
useEffect7(() => {
|
|
7538
|
-
|
|
7539
|
-
|
|
7485
|
+
if (user && session && supabase && !isLoading) {
|
|
7486
|
+
DebugLogger.log("OrganisationProvider", "Authentication stable, loading organizations...");
|
|
7487
|
+
loadUserOrganisations();
|
|
7488
|
+
} else if (!user && !session) {
|
|
7489
|
+
DebugLogger.log("OrganisationProvider", "No authentication, clearing organization state");
|
|
7490
|
+
setSelectedOrganisation(null);
|
|
7491
|
+
setOrganisations([]);
|
|
7492
|
+
setUserMemberships([]);
|
|
7493
|
+
setRoleMapState(/* @__PURE__ */ new Map());
|
|
7494
|
+
setIsLoading(false);
|
|
7495
|
+
setError(null);
|
|
7496
|
+
localStorage.removeItem(STORAGE_KEYS2.SELECTED_ORGANISATION);
|
|
7497
|
+
localStorage.removeItem(STORAGE_KEYS2.ORGANISATION_CONTEXT);
|
|
7498
|
+
}
|
|
7499
|
+
}, [user, session, supabase, isLoading, loadUserOrganisations]);
|
|
7540
7500
|
const handleLogoutAndRedirect = useCallback7(async () => {
|
|
7541
7501
|
try {
|
|
7542
7502
|
await signOut();
|
|
@@ -7730,8 +7690,8 @@ var init_OrganisationProvider = __esm({
|
|
|
7730
7690
|
});
|
|
7731
7691
|
|
|
7732
7692
|
export {
|
|
7733
|
-
useAuth,
|
|
7734
7693
|
AuthProvider,
|
|
7694
|
+
useAuth,
|
|
7735
7695
|
init_AuthProvider,
|
|
7736
7696
|
useRBAC,
|
|
7737
7697
|
RBACProvider,
|
|
@@ -7785,4 +7745,4 @@ lodash/lodash.js:
|
|
|
7785
7745
|
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
|
7786
7746
|
*)
|
|
7787
7747
|
*/
|
|
7788
|
-
//# sourceMappingURL=chunk-
|
|
7748
|
+
//# sourceMappingURL=chunk-OQ6DTLZ6.js.map
|