diff --git a/web/src/components/features/auth/SignOutHandler.tsx b/web/src/components/features/auth/SignOutHandler.tsx new file mode 100644 index 000000000..ec9d93a00 --- /dev/null +++ b/web/src/components/features/auth/SignOutHandler.tsx @@ -0,0 +1,17 @@ +'use client'; + +import { useCallback } from 'react'; +import { signOut } from '@/lib/supabase/signOut'; +import { clearAllBrowserStorage } from '@/lib/browser/storage'; + +export const useSignOut = () => { + const handleSignOut = useCallback(async () => { + // First clear all client-side storage + clearAllBrowserStorage(); + + // Then perform server-side sign out + await signOut(); + }, []); + + return handleSignOut; +}; diff --git a/web/src/components/features/sidebars/SidebarUserFooter/SidebarUserFooter.tsx b/web/src/components/features/sidebars/SidebarUserFooter/SidebarUserFooter.tsx index cf72a9886..7de13ef88 100644 --- a/web/src/components/features/sidebars/SidebarUserFooter/SidebarUserFooter.tsx +++ b/web/src/components/features/sidebars/SidebarUserFooter/SidebarUserFooter.tsx @@ -15,8 +15,8 @@ import { BUSTER_DOCS_URL } from '@/routes/externalRoutes'; import { type DropdownProps, Dropdown } from '@/components/ui/dropdown/Dropdown'; import { AvatarUserButton } from '@/components/ui/avatar/AvatarUserButton'; import { useUserConfigContextSelector } from '@/context/Users'; -import { signOut as signOutServer } from '@/lib/supabase/signOut'; import { useContactSupportModalStore } from '@/context/BusterAppLayout'; +import { useSignOut } from '@/components/features/auth/SignOutHandler'; export const SidebarUserFooter: React.FC<{}> = () => { const user = useUserConfigContextSelector((x) => x.user); @@ -26,8 +26,10 @@ export const SidebarUserFooter: React.FC<{}> = () => { if (!name || !email) return null; + const handleSignOut = useSignOut(); + return ( - +
diff --git a/web/src/lib/browser/storage.ts b/web/src/lib/browser/storage.ts new file mode 100644 index 000000000..1522394e7 --- /dev/null +++ b/web/src/lib/browser/storage.ts @@ -0,0 +1,17 @@ +/** + * Clears all browser storage including localStorage, sessionStorage, and cookies + * @returns void + */ +export const clearAllBrowserStorage = (): void => { + // Clear localStorage + localStorage.clear(); + + // Clear sessionStorage + sessionStorage.clear(); + + // Clear all cookies + document.cookie.split(';').forEach((cookie) => { + const cookieName = cookie.replace(/^ +/, '').split('=')[0]; + document.cookie = `${cookieName}=;expires=${new Date().toUTCString()};path=/`; + }); +}; diff --git a/web/src/lib/supabase/signOut.tsx b/web/src/lib/supabase/signOut.tsx index adbd1bc6e..ef949517b 100644 --- a/web/src/lib/supabase/signOut.tsx +++ b/web/src/lib/supabase/signOut.tsx @@ -3,10 +3,18 @@ import { createClient } from './server'; import { redirect } from 'next/navigation'; import { BusterRoutes, createBusterRoute } from '@/routes/busterRoutes'; +import { cookies } from 'next/headers'; export const signOut = async () => { 'use server'; const supabase = await createClient(); + const cookieStore = cookies(); + + // Clear all cookies + const allCookies = cookieStore.getAll(); + allCookies.forEach((cookie) => { + cookieStore.delete(cookie.name); + }); const { error } = await supabase.auth.signOut();