NeahNew/components/auth/signout-handler.tsx

71 lines
2.4 KiB
TypeScript

"use client";
import { useEffect } from "react";
import { signOut, useSession } from "next-auth/react";
import { clearAuthCookies, clearKeycloakCookies } from "@/lib/session";
export function SignOutHandler() {
const { data: session } = useSession();
useEffect(() => {
const handleSignOut = async () => {
try {
// Mark that we're logging out to prevent auto-login and refresh attempts
sessionStorage.setItem('just_logged_out', 'true');
// Also set a cookie flag that persists across redirects
document.cookie = 'logout_in_progress=true; path=/; max-age=60'; // 60 seconds
// Get Keycloak issuer from environment
const keycloakIssuer = process.env.NEXT_PUBLIC_KEYCLOAK_ISSUER;
const idToken = session?.idToken;
// Clear NextAuth cookies immediately before signOut
clearAuthCookies();
// Also attempt to clear Keycloak cookies
clearKeycloakCookies();
// Sign out from NextAuth (clears NextAuth session)
await signOut({
callbackUrl: "/signin?logout=true",
redirect: false
});
// If we have Keycloak ID token and issuer, call Keycloak logout
if (keycloakIssuer && idToken) {
const keycloakLogoutUrl = new URL(
`${keycloakIssuer}/protocol/openid-connect/logout`
);
// Add required parameters - include logout=true in redirect URI
keycloakLogoutUrl.searchParams.append(
'post_logout_redirect_uri',
window.location.origin + '/signin?logout=true'
);
keycloakLogoutUrl.searchParams.append(
'id_token_hint',
idToken
);
// Add kc_action=LOGOUT to ensure SSO session is cleared
keycloakLogoutUrl.searchParams.append(
'kc_action',
'LOGOUT'
);
// Immediate redirect to Keycloak logout (prevents widget rendering)
window.location.replace(keycloakLogoutUrl.toString());
} else {
// Fallback: just redirect to signin if we don't have Keycloak info
window.location.replace('/signin?logout=true');
}
} catch (error) {
console.error('Error during sign out:', error);
// Fallback: redirect to signin on error
window.location.replace('/signin?logout=true');
}
};
handleSignOut();
}, [session]);
return null;
}