From b49b07fdd6aa2e5b87b8b2a63879dcc7a67dd116 Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Sun, 8 Mar 2026 12:06:07 +0530 Subject: [PATCH] fix: robust logout session clearing with cookie cleanup and isLoggingOut guard - Clear next-auth session cookies directly as backup in logout page - Add isLoggingOut localStorage flag to prevent TokenSync/PresenceProvider from restoring tokens - Clear isLoggingOut flag on login page load as safety net - Add createdAt to AgentSubscription interface (fixes build error) - Add /education to public routes in middleware --- src/app/(auth)/login/page.tsx | 5 +++ src/app/logout/page.tsx | 44 +++++++++++++++---- src/components/layout/CommonHeader.tsx | 3 ++ src/components/message/ChatHeader.tsx | 12 ++--- src/components/message/MessageInput.tsx | 1 + .../providers/presence-provider.tsx | 6 +++ src/components/providers/session-provider.tsx | 5 ++- src/middleware.ts | 2 +- src/services/api.ts | 2 + src/services/stripe.service.ts | 1 + 10 files changed, 64 insertions(+), 17 deletions(-) diff --git a/src/app/(auth)/login/page.tsx b/src/app/(auth)/login/page.tsx index 8654103..5d953b3 100644 --- a/src/app/(auth)/login/page.tsx +++ b/src/app/(auth)/login/page.tsx @@ -13,6 +13,11 @@ export default function LoginPage() { const [error, setError] = useState(''); const [loading, setLoading] = useState(false); + // Safety net: clear logout flag when login page loads + if (typeof window !== 'undefined') { + localStorage.removeItem('isLoggingOut'); + } + const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setLoading(true); diff --git a/src/app/logout/page.tsx b/src/app/logout/page.tsx index 5b39e3f..942efa6 100644 --- a/src/app/logout/page.tsx +++ b/src/app/logout/page.tsx @@ -3,6 +3,25 @@ import { useEffect, useRef } from 'react'; import { signOut } from 'next-auth/react'; +function clearAuthCookies() { + // Clear next-auth v5 (Auth.js) and v4 session cookies directly + const cookieNames = [ + 'authjs.session-token', + '__Secure-authjs.session-token', + 'authjs.callback-url', + 'authjs.csrf-token', + 'next-auth.session-token', + '__Secure-next-auth.session-token', + 'next-auth.callback-url', + 'next-auth.csrf-token', + ]; + + cookieNames.forEach((name) => { + document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`; + document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=${window.location.hostname}`; + }); +} + export default function LogoutPage() { const hasStarted = useRef(false); @@ -10,24 +29,31 @@ export default function LogoutPage() { if (hasStarted.current) return; hasStarted.current = true; + // Ensure logout flag is set (prevents TokenSync and PresenceProvider from restoring tokens) + localStorage.setItem('isLoggingOut', 'true'); + // Clear localStorage tokens localStorage.removeItem('accessToken'); localStorage.removeItem('refreshToken'); localStorage.removeItem('user'); + // Clear auth cookies directly as a robust backup + clearAuthCookies(); + + const redirectToLogin = () => { + clearAuthCookies(); + // Clear the logout flag right before redirecting + localStorage.removeItem('isLoggingOut'); + window.location.href = '/login'; + }; + // Sign out via NextAuth (clears session cookie), then manually redirect signOut({ redirect: false }) - .then(() => { - window.location.href = '/login'; - }) - .catch(() => { - window.location.href = '/login'; - }); + .then(redirectToLogin) + .catch(redirectToLogin); // Safety fallback - if signOut hangs, redirect after 3 seconds - setTimeout(() => { - window.location.href = '/login'; - }, 3000); + setTimeout(redirectToLogin, 3000); }, []); return ( diff --git a/src/components/layout/CommonHeader.tsx b/src/components/layout/CommonHeader.tsx index 81830ec..20aae1b 100644 --- a/src/components/layout/CommonHeader.tsx +++ b/src/components/layout/CommonHeader.tsx @@ -280,6 +280,9 @@ export function CommonHeader() {