"use client"; import { signIn, useSession } from "next-auth/react"; import { useEffect, useState, useRef } from "react"; import { useRouter, useSearchParams } from "next/navigation"; export default function SignIn() { const { data: session, status } = useSession(); const router = useRouter(); const searchParams = useSearchParams(); const [initializationStatus, setInitializationStatus] = useState(null); const hasAttemptedLogin = useRef(false); const isLogoutRedirect = useRef(false); // Check if this is a logout redirect (from Keycloak post_logout_redirect_uri) // OR if session was invalidated (e.g., from iframe logout) useEffect(() => { // Check URL parameters or session storage for logout flag const logoutParam = searchParams.get('logout'); const fromLogout = sessionStorage.getItem('just_logged_out'); const sessionInvalidated = sessionStorage.getItem('session_invalidated'); // Check if there's a NextAuth session cookie that's now invalid // This indicates the session was invalidated (e.g., by iframe logout) const hasInvalidSessionCookie = document.cookie .split(';') .some(c => c.trim().startsWith('next-auth.session-token=') || c.trim().startsWith('__Secure-next-auth.session-token=') || c.trim().startsWith('__Host-next-auth.session-token=')); // If session was invalidated or this is a logout redirect, prevent auto-login if (logoutParam === 'true' || fromLogout === 'true' || sessionInvalidated === 'true') { isLogoutRedirect.current = true; sessionStorage.removeItem('just_logged_out'); sessionStorage.removeItem('session_invalidated'); // Clear any OAuth parameters from URL to prevent callback processing const url = new URL(window.location.href); const hasOAuthParams = url.searchParams.has('code') || url.searchParams.has('state') || url.searchParams.has('error'); if (hasOAuthParams) { // Remove OAuth parameters but keep logout=true url.searchParams.delete('code'); url.searchParams.delete('state'); url.searchParams.delete('error'); url.searchParams.delete('error_description'); url.searchParams.set('logout', 'true'); // Replace URL without OAuth params window.history.replaceState({}, '', url.toString()); } // Don't auto-trigger login after logout return; } // Detect session invalidation: if status becomes unauthenticated // and we had a session cookie, it means the session was invalidated if (status === 'unauthenticated' && hasInvalidSessionCookie && !hasAttemptedLogin.current) { console.log('Session invalidation detected (likely from iframe logout), preventing auto-login'); sessionStorage.setItem('session_invalidated', 'true'); isLogoutRedirect.current = true; // Don't auto-login - user must manually click "Se connecter" return; } }, [searchParams, status]); useEffect(() => { // If user is already authenticated, redirect to home if (status === "authenticated" && session?.user) { router.push("/"); return; } // Don't auto-login if this is a logout redirect, session was invalidated, or we've already attempted login const sessionInvalidated = sessionStorage.getItem('session_invalidated') === 'true'; if (isLogoutRedirect.current || sessionInvalidated || hasAttemptedLogin.current) { return; } // Don't auto-login if status is still loading (might be processing OAuth callback) if (status === "loading") { return; } // Only trigger Keycloak sign-in if not authenticated, not loading, and not from logout // AND only if this is a truly new user (never logged in), not a session invalidation if (status === "unauthenticated") { // Check if there's evidence of a previous session (session cookie exists but invalid) // This indicates session was invalidated, not a new user const hasSessionCookie = document.cookie .split(';') .some(c => { const cookie = c.trim(); return cookie.startsWith('next-auth.session-token=') || cookie.startsWith('__Secure-next-auth.session-token=') || cookie.startsWith('__Host-next-auth.session-token='); }); // If there's a session cookie but status is unauthenticated, session was invalidated // Don't auto-login in this case if (hasSessionCookie) { console.log('Session cookie detected but status is unauthenticated - session was invalidated, preventing auto-login'); sessionStorage.setItem('session_invalidated', 'true'); isLogoutRedirect.current = true; return; } // Only auto-login for truly new users (no session cookie) hasAttemptedLogin.current = true; // Longer delay to ensure we're not in a logout redirect flow or OAuth callback const timer = setTimeout(() => { // Double-check we're still unauthenticated and not in a logout flow const stillInvalidated = sessionStorage.getItem('session_invalidated') === 'true'; if (!isLogoutRedirect.current && !stillInvalidated) { // Trigger Keycloak sign-in only for new users signIn("keycloak", { callbackUrl: "/" }); } }, 1000); return () => clearTimeout(timer); } }, [status, session, router]); useEffect(() => { if (session?.user) { console.log("Session available, initializing storage"); // Initialize storage using direct API const initializeStorage = async () => { try { setInitializationStatus("initializing"); const response = await fetch('/api/storage/init', { method: 'POST' }); if (!response.ok) { console.error('Failed to initialize storage:', await response.text()); setInitializationStatus("failed"); } else { console.log('Storage initialized successfully'); setInitializationStatus("success"); // Force reload to ensure session is updated setTimeout(() => { window.location.href = "/"; }, 1000); } } catch (error) { console.error('Error initializing storage:', error); setInitializationStatus("failed"); } }; initializeStorage(); } }, [session]); // Show logout message if coming from logout or session was invalidated const sessionInvalidated = sessionStorage.getItem('session_invalidated') === 'true'; const showLogoutMessage = isLogoutRedirect.current || searchParams.get('logout') === 'true' || sessionInvalidated; return (

{showLogoutMessage ? (sessionInvalidated ? "Votre session a expiré. Veuillez vous reconnecter." : "Vous avez été déconnecté avec succès") : initializationStatus === "initializing" ? "Initialisation de votre espace..." : initializationStatus === "success" ? "Initialisation réussie, redirection..." : initializationStatus === "failed" ? "Échec de l'initialisation. Veuillez réessayer." : "Redirection vers la page de connexion..."}

{showLogoutMessage && (
)} {initializationStatus === "initializing" && (
)}
); }