102 lines
3.7 KiB
TypeScript
102 lines
3.7 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect } from "react";
|
|
import { useSession, signOut } from "next-auth/react";
|
|
import { clearAuthCookies } from "@/lib/session";
|
|
|
|
export function SignOutHandler() {
|
|
const { data: session } = useSession();
|
|
|
|
useEffect(() => {
|
|
const handleSignOut = async () => {
|
|
try {
|
|
// Store the user ID before signout clears the session
|
|
const userId = session?.user?.id;
|
|
console.log('Starting optimized logout process (preserving SSO)');
|
|
|
|
// First trigger server-side Redis cleanup only
|
|
if (userId) {
|
|
console.log('Triggering server-side Redis cleanup');
|
|
try {
|
|
const cleanupResponse = await fetch('/api/auth/session-cleanup', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
userId,
|
|
preserveSso: true
|
|
}),
|
|
credentials: 'include'
|
|
});
|
|
|
|
const cleanupResult = await cleanupResponse.json();
|
|
console.log('Server cleanup result:', cleanupResult);
|
|
} catch (cleanupError) {
|
|
console.error('Error during server-side cleanup:', cleanupError);
|
|
}
|
|
}
|
|
|
|
// Use NextAuth signOut but ONLY for our application cookies
|
|
// This preserves the Keycloak SSO session for other services
|
|
await signOut({ redirect: false });
|
|
|
|
// Clear ONLY application-specific cookies (not Keycloak SSO cookies)
|
|
const appCookies = [
|
|
'next-auth.session-token',
|
|
'next-auth.csrf-token',
|
|
'next-auth.callback-url',
|
|
'__Secure-next-auth.session-token',
|
|
'__Host-next-auth.csrf-token',
|
|
];
|
|
|
|
// Only clear chunked cookies for our app
|
|
const cookies = document.cookie.split(';');
|
|
const chunkedCookies = cookies
|
|
.map(cookie => cookie.split('=')[0].trim())
|
|
.filter(name => /next-auth.*\.\d+$/.test(name));
|
|
|
|
[...appCookies, ...chunkedCookies].forEach(cookieName => {
|
|
document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${window.location.hostname}; SameSite=None; Secure`;
|
|
});
|
|
|
|
// Clear Rocket Chat authentication tokens
|
|
try {
|
|
console.log('Clearing Rocket Chat tokens');
|
|
// Remove cookies
|
|
document.cookie = `rc_token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${window.location.hostname}; SameSite=None; Secure`;
|
|
document.cookie = `rc_uid=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${window.location.hostname}; SameSite=None; Secure`;
|
|
|
|
// Remove localStorage items
|
|
localStorage.removeItem('Meteor.loginToken');
|
|
localStorage.removeItem('Meteor.userId');
|
|
} catch (e) {
|
|
console.error('Error clearing Rocket Chat tokens:', e);
|
|
}
|
|
|
|
// Redirect to loggedout page
|
|
window.location.href = '/loggedout?preserveSso=true';
|
|
|
|
} catch (error) {
|
|
console.error('Error during logout:', error);
|
|
window.location.href = '/loggedout?preserveSso=true';
|
|
}
|
|
};
|
|
|
|
// Add a slight delay to ensure useSession has loaded
|
|
const timer = setTimeout(() => {
|
|
handleSignOut();
|
|
}, 100);
|
|
|
|
return () => clearTimeout(timer);
|
|
}, [session]);
|
|
|
|
return (
|
|
<div className="w-full h-full flex items-center justify-center">
|
|
<div className="text-center">
|
|
<h2 className="text-2xl font-bold">Logging out...</h2>
|
|
<p className="text-gray-500 mt-2">Please wait while we sign you out of this application.</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|