diff --git a/src/webapp/app/api/auth/logout/route.ts b/src/webapp/app/api/auth/logout/route.ts new file mode 100644 index 00000000..7de43579 --- /dev/null +++ b/src/webapp/app/api/auth/logout/route.ts @@ -0,0 +1,21 @@ +import { NextRequest, NextResponse } from 'next/server'; + +export async function POST(request: NextRequest) { + try { + // Create response + const response = NextResponse.json({ + success: true, + message: 'Logged out successfully', + }); + + // Clear httpOnly cookies by setting them with past expiration + response.cookies.delete('accessToken'); + + response.cookies.delete('refreshToken'); + + return response; + } catch (error) { + console.error('Logout error:', error); + return NextResponse.json({ error: 'Failed to logout' }, { status: 500 }); + } +} diff --git a/src/webapp/hooks/useAuth.tsx b/src/webapp/hooks/useAuth.tsx index 8805d085..eb3e342f 100644 --- a/src/webapp/hooks/useAuth.tsx +++ b/src/webapp/hooks/useAuth.tsx @@ -27,6 +27,7 @@ interface AuthContextType { logout: () => Promise; refreshTokens: () => Promise; setTokens: (accessToken: string, refreshToken: string) => Promise; + revokeTokens: () => Promise; } const AuthContext = createContext(undefined); @@ -69,12 +70,7 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => { console.error('Logout error:', error); // Continue with logout even if API call fails } finally { - // Clear auth state - clearAuth(); - setAccessToken(null); - setRefreshToken(null); - setUser(null); - setIsAuthenticated(false); + revokeTokens(); // Redirect to login router.push('/login'); @@ -236,6 +232,26 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => { [], ); + const revokeTokens = useCallback(async () => { + // Clear auth state + clearAuth(); + setAccessToken(null); + setRefreshToken(null); + setUser(null); + setIsAuthenticated(false); + + // Clear server-side cookies + try { + await fetch('/api/auth/logout', { + method: 'POST', + credentials: 'include', // Important for cookie handling + }); + } catch (error) { + console.error('Failed to clear server-side cookies:', error); + // Don't throw error - localStorage tokens are already cleared + } + }, []); + return ( { logout: handleLogout, refreshTokens, setTokens, + revokeTokens, }} > {children}