diff --git a/src/App.tsx b/src/App.tsx index 81d82b3f..f04c6f3f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -43,6 +43,7 @@ import AdminSettings from "./pages/AdminSettings"; import BlogIndex from "./pages/BlogIndex"; import BlogPost from "./pages/BlogPost"; import AdminBlog from "./pages/AdminBlog"; +import ForceLogout from "./pages/ForceLogout"; const queryClient = new QueryClient(); @@ -96,6 +97,7 @@ function AppContent() { } /> } /> } /> + } /> {/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */} } /> diff --git a/src/lib/authStorage.ts b/src/lib/authStorage.ts index cb291b27..40e5799a 100644 --- a/src/lib/authStorage.ts +++ b/src/lib/authStorage.ts @@ -156,6 +156,37 @@ class AuthStorage { : null }; } + + // Clear all auth-related storage (for force logout) + clearAll(): void { + console.log('[AuthStorage] Clearing all auth storage'); + try { + if (this.storage) { + // Get all keys from storage + const keys: string[] = []; + for (let i = 0; i < this.storage.length; i++) { + const key = this.storage.key(i); + if (key?.startsWith('sb-')) { + keys.push(key); + } + } + + // Remove all Supabase auth keys + keys.forEach(key => { + console.log('[AuthStorage] Removing key:', key); + this.storage!.removeItem(key); + }); + } + + // Clear memory storage + this.memoryStorage.clear(); + console.log('[AuthStorage] ✓ All auth storage cleared'); + } catch (error) { + console.error('[AuthStorage] Error clearing storage:', error); + // Still clear memory storage as fallback + this.memoryStorage.clear(); + } + } } export const authStorage = new AuthStorage(); diff --git a/src/pages/ForceLogout.tsx b/src/pages/ForceLogout.tsx new file mode 100644 index 00000000..1d021b09 --- /dev/null +++ b/src/pages/ForceLogout.tsx @@ -0,0 +1,55 @@ +import { useEffect } from "react"; +import { useNavigate } from "react-router-dom"; +import { supabase } from "@/integrations/supabase/client"; +import { authStorage } from "@/lib/authStorage"; + +/** + * ForceLogout - Hidden endpoint for completely clearing auth session + * Access via: /force-logout + * Not linked anywhere in the UI - for manual navigation only + */ +const ForceLogout = () => { + const navigate = useNavigate(); + + useEffect(() => { + const performFullLogout = async () => { + console.log('[ForceLogout] Starting complete auth cleanup...'); + + try { + // 1. Sign out from Supabase + console.log('[ForceLogout] Signing out from Supabase...'); + await supabase.auth.signOut(); + + // 2. Clear all auth-related storage + console.log('[ForceLogout] Clearing all auth storage...'); + authStorage.clearAll(); + + // 3. Brief delay to ensure cleanup completes + await new Promise(resolve => setTimeout(resolve, 500)); + + console.log('[ForceLogout] ✓ Auth cleanup complete, redirecting to home...'); + + // 4. Redirect to home page + navigate('/', { replace: true }); + } catch (error) { + console.error('[ForceLogout] Error during logout:', error); + // Still redirect even if there's an error + navigate('/', { replace: true }); + } + }; + + performFullLogout(); + }, [navigate]); + + return ( +
+
+
+

Clearing session...

+

You will be redirected shortly.

+
+
+ ); +}; + +export default ForceLogout;