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
This commit is contained in:
pradeepkumar
2026-03-08 12:06:07 +05:30
parent 8c499ecc6a
commit b49b07fdd6
10 changed files with 64 additions and 17 deletions

View File

@@ -280,6 +280,9 @@ export function CommonHeader() {
<button
onClick={() => {
setShowProfileMenu(false);
// Set logout flag FIRST so TokenSync and PresenceProvider
// don't restore tokens during the logout navigation
localStorage.setItem('isLoggingOut', 'true');
localStorage.removeItem('accessToken');
localStorage.removeItem('refreshToken');
localStorage.removeItem('user');

View File

@@ -29,15 +29,15 @@ export function ChatHeader({
<div className="border-b border-[#00293d]/10 pb-4">
{/* Top row - Name, status, actions */}
<div className="flex items-center justify-between mb-3">
<div className="flex items-center gap-2">
<h2 className="font-fractul font-bold text-[14px] leading-[17px] text-[#00293D]">
<div className="flex items-center gap-2 min-w-0 flex-1">
<h2 className="font-fractul font-bold text-[14px] leading-[17px] text-[#00293D] truncate">
{name}
</h2>
<span className={`w-2.5 h-2.5 rounded-full ${isOnline ? 'bg-green-500' : 'bg-gray-400'}`} />
<span className="font-serif font-normal text-[14px] leading-[19px] text-[#00293D]">
<span className={`w-2.5 h-2.5 rounded-full flex-shrink-0 ${isOnline ? 'bg-green-500' : 'bg-gray-400'}`} />
<span className="font-serif font-normal text-[14px] leading-[19px] text-[#00293D] hidden sm:inline">
{role}
</span>
<span className="font-serif font-normal text-[14px] leading-[19px] text-[#00293D]">
<span className="font-serif font-normal text-[14px] leading-[19px] text-[#00293D] hidden sm:inline">
{isTyping ? (
<span className="text-[#e58625] italic">{typingText}</span>
) : (
@@ -45,7 +45,7 @@ export function ChatHeader({
)}
</span>
</div>
<div className="flex items-center gap-2">
<div className="flex items-center gap-2 flex-shrink-0">
<button className="p-2 hover:bg-gray-100 rounded-lg transition-colors cursor-pointer">
<Image
src="/assets/icons/three-dots-horizontal-icon.svg"

View File

@@ -9,6 +9,7 @@ import { Grid } from '@giphy/react-components';
const gf = new GiphyFetch(process.env.NEXT_PUBLIC_GIPHY_API_KEY || '');
interface AttachedFile {
file: File;
preview?: string; // Object URL for image preview

View File

@@ -75,6 +75,12 @@ export function PresenceProvider({ children }: { children: React.ReactNode }) {
// Handle auth errors (token expiry) — single global handler
useEffect(() => {
const unsubscribe = socketService.onAuthError(async () => {
// Skip token refresh if logout is in progress
if (typeof window !== 'undefined' && localStorage.getItem('isLoggingOut') === 'true') {
console.log('[Presence] Auth error during logout, skipping refresh');
return;
}
console.log('[Presence] Auth error, refreshing token...');
try {
const refreshToken = localStorage.getItem('refreshToken');

View File

@@ -9,7 +9,10 @@ function TokenSync() {
const hasInitialized = useRef(false);
useEffect(() => {
if (status === "authenticated" && session?.user) {
// Never restore tokens if a logout is in progress
const loggingOut = localStorage.getItem("isLoggingOut") === "true";
if (status === "authenticated" && session?.user && !loggingOut) {
const user = session.user as { accessToken?: string; refreshToken?: string };
// Only sync tokens from NextAuth to localStorage if: