Correction signin
This commit is contained in:
parent
f682af6c10
commit
54c7990ed8
@ -9,75 +9,68 @@ export default function SignIn() {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
const [initializationStatus, setInitializationStatus] = useState<string | null>(null);
|
const [initializationStatus, setInitializationStatus] = useState<string | null>(null);
|
||||||
|
const [isLoggingIn, setIsLoggingIn] = useState(false);
|
||||||
const hasAttemptedLogin = useRef(false);
|
const hasAttemptedLogin = useRef(false);
|
||||||
const isLogoutRedirect = useRef(false);
|
|
||||||
|
|
||||||
// Check if we should force login prompt (after logout)
|
// Check URL parameters for logout flag
|
||||||
|
const logoutParam = searchParams.get('logout');
|
||||||
|
const isLogoutRedirect = logoutParam === 'true';
|
||||||
|
|
||||||
|
// Debug logging
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Check for server-side cookie that marks logout
|
console.log('[SignIn] Status:', status, 'Session:', !!session, 'Logout redirect:', isLogoutRedirect, 'Has attempted:', hasAttemptedLogin.current);
|
||||||
const forceLoginCookie = document.cookie
|
}, [status, session, isLogoutRedirect]);
|
||||||
.split(';')
|
|
||||||
.find(c => c.trim().startsWith('force_login_prompt='));
|
|
||||||
|
|
||||||
// Check URL parameters for logout flag
|
// Clear stale force_login_prompt cookie on mount (it should only last 5 minutes)
|
||||||
const logoutParam = searchParams.get('logout');
|
useEffect(() => {
|
||||||
|
// If not a logout redirect, clear any stale force_login_prompt cookie
|
||||||
|
if (!isLogoutRedirect) {
|
||||||
|
const forceLoginCookie = document.cookie
|
||||||
|
.split(';')
|
||||||
|
.find(c => c.trim().startsWith('force_login_prompt='));
|
||||||
|
|
||||||
// If logout occurred, mark it and prevent auto-login
|
if (forceLoginCookie) {
|
||||||
if (forceLoginCookie || logoutParam === 'true') {
|
console.log('[SignIn] Clearing stale force_login_prompt cookie');
|
||||||
isLogoutRedirect.current = true;
|
document.cookie = 'force_login_prompt=; path=/; expires=Thu, 01 Jan 1970 00:00:00 UTC';
|
||||||
|
|
||||||
// Clear OAuth parameters from URL if present
|
|
||||||
const url = new URL(window.location.href);
|
|
||||||
const hasOAuthParams = url.searchParams.has('code') ||
|
|
||||||
url.searchParams.has('state') ||
|
|
||||||
url.searchParams.has('error');
|
|
||||||
|
|
||||||
if (hasOAuthParams) {
|
|
||||||
url.searchParams.delete('code');
|
|
||||||
url.searchParams.delete('state');
|
|
||||||
url.searchParams.delete('error');
|
|
||||||
url.searchParams.delete('error_description');
|
|
||||||
url.searchParams.set('logout', 'true');
|
|
||||||
window.history.replaceState({}, '', url.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't auto-trigger login after logout
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}, [searchParams]);
|
}, [isLogoutRedirect]);
|
||||||
|
|
||||||
|
// Handle authentication redirect
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// If user is already authenticated, redirect to home
|
// If user is already authenticated, redirect to home
|
||||||
if (status === "authenticated" && session?.user) {
|
if (status === "authenticated" && session?.user) {
|
||||||
|
console.log('[SignIn] User authenticated, redirecting to home');
|
||||||
router.push("/");
|
router.push("/");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't auto-login if this is a logout redirect or we've already attempted login
|
// Don't auto-login if this is a logout redirect
|
||||||
if (isLogoutRedirect.current || hasAttemptedLogin.current) {
|
if (isLogoutRedirect) {
|
||||||
|
console.log('[SignIn] Logout redirect detected, showing login button');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't auto-login if status is still loading (might be processing OAuth callback)
|
// Don't auto-login if we've already attempted or are currently logging in
|
||||||
|
if (hasAttemptedLogin.current || isLoggingIn) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't auto-login if status is still loading
|
||||||
if (status === "loading") {
|
if (status === "loading") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto-login for new users (SSO natural flow)
|
// Auto-login for new users (SSO natural flow)
|
||||||
// Only if not authenticated and not from logout
|
|
||||||
if (status === "unauthenticated") {
|
if (status === "unauthenticated") {
|
||||||
|
console.log('[SignIn] Status is unauthenticated, triggering Keycloak login');
|
||||||
hasAttemptedLogin.current = true;
|
hasAttemptedLogin.current = true;
|
||||||
// Small delay to ensure we're not in a logout redirect flow
|
setIsLoggingIn(true);
|
||||||
const timer = setTimeout(() => {
|
|
||||||
if (status === "unauthenticated" && !isLogoutRedirect.current) {
|
|
||||||
// Trigger Keycloak sign-in (SSO will work naturally)
|
|
||||||
signIn("keycloak", { callbackUrl: "/" });
|
|
||||||
}
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
return () => clearTimeout(timer);
|
// Trigger Keycloak sign-in immediately
|
||||||
|
signIn("keycloak", { callbackUrl: "/" });
|
||||||
}
|
}
|
||||||
}, [status, session, router]);
|
}, [status, session, router, isLogoutRedirect, isLoggingIn]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (session?.user) {
|
if (session?.user) {
|
||||||
@ -113,10 +106,6 @@ export default function SignIn() {
|
|||||||
}
|
}
|
||||||
}, [session]);
|
}, [session]);
|
||||||
|
|
||||||
// Show logout message if coming from logout
|
|
||||||
const showLogoutMessage = isLogoutRedirect.current ||
|
|
||||||
searchParams.get('logout') === 'true';
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="min-h-screen flex items-center justify-center"
|
className="min-h-screen flex items-center justify-center"
|
||||||
@ -130,7 +119,7 @@ export default function SignIn() {
|
|||||||
<div className="w-full max-w-md space-y-8 bg-white/90 backdrop-blur-sm p-8 rounded-xl shadow-xl">
|
<div className="w-full max-w-md space-y-8 bg-white/90 backdrop-blur-sm p-8 rounded-xl shadow-xl">
|
||||||
<div>
|
<div>
|
||||||
<h2 className="mt-6 text-center text-3xl font-bold tracking-tight text-gray-900">
|
<h2 className="mt-6 text-center text-3xl font-bold tracking-tight text-gray-900">
|
||||||
{showLogoutMessage
|
{isLogoutRedirect
|
||||||
? "Vous avez été déconnecté avec succès. Veuillez vous reconnecter."
|
? "Vous avez été déconnecté avec succès. Veuillez vous reconnecter."
|
||||||
: initializationStatus === "initializing"
|
: initializationStatus === "initializing"
|
||||||
? "Initialisation de votre espace..."
|
? "Initialisation de votre espace..."
|
||||||
@ -138,28 +127,22 @@ export default function SignIn() {
|
|||||||
? "Initialisation réussie, redirection..."
|
? "Initialisation réussie, redirection..."
|
||||||
: initializationStatus === "failed"
|
: initializationStatus === "failed"
|
||||||
? "Échec de l'initialisation. Veuillez réessayer."
|
? "Échec de l'initialisation. Veuillez réessayer."
|
||||||
|
: isLoggingIn
|
||||||
|
? "Connexion à Keycloak en cours..."
|
||||||
|
: status === "loading"
|
||||||
|
? "Chargement..."
|
||||||
: "Redirection vers la page de connexion..."}
|
: "Redirection vers la page de connexion..."}
|
||||||
</h2>
|
</h2>
|
||||||
{showLogoutMessage && (
|
|
||||||
|
{/* Show login button after logout OR if auto-login failed */}
|
||||||
|
{(isLogoutRedirect || (status === "unauthenticated" && hasAttemptedLogin.current && !isLoggingIn)) && (
|
||||||
<div className="mt-4 text-center">
|
<div className="mt-4 text-center">
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
// Clear flags before logging in
|
console.log('[SignIn] Manual login button clicked');
|
||||||
hasAttemptedLogin.current = false;
|
hasAttemptedLogin.current = false;
|
||||||
isLogoutRedirect.current = false;
|
setIsLoggingIn(true);
|
||||||
|
signIn("keycloak", { callbackUrl: "/" });
|
||||||
// Use NextAuth signin normally
|
|
||||||
// The force_login_prompt cookie set by mark-logout will be used
|
|
||||||
// to determine if we should add prompt=login
|
|
||||||
// For now, we'll rely on Keycloak's behavior: if SSO session exists
|
|
||||||
// and we want to force login, we need to add prompt=login
|
|
||||||
// Since NextAuth doesn't easily support dynamic prompt, we'll
|
|
||||||
// use a workaround: modify the authorization URL after NextAuth generates it
|
|
||||||
// This is complex, so for now we'll use normal signin
|
|
||||||
// The user will be prompted if SSO session was cleared by end-sso-session
|
|
||||||
signIn("keycloak", {
|
|
||||||
callbackUrl: "/",
|
|
||||||
});
|
|
||||||
}}
|
}}
|
||||||
className="mt-4 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
|
className="mt-4 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
|
||||||
>
|
>
|
||||||
@ -167,7 +150,8 @@ export default function SignIn() {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{initializationStatus === "initializing" && (
|
|
||||||
|
{(initializationStatus === "initializing" || isLoggingIn || status === "loading") && (
|
||||||
<div className="flex justify-center mt-4">
|
<div className="flex justify-center mt-4">
|
||||||
<div className="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-blue-500"></div>
|
<div className="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-blue-500"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,10 @@
|
|||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {
|
const nextConfig = {
|
||||||
|
// Allow cross-origin requests from the reverse proxy domain
|
||||||
|
allowedDevOrigins: [
|
||||||
|
'hub.slm-lab.net',
|
||||||
|
'https://hub.slm-lab.net',
|
||||||
|
],
|
||||||
webpack: (config, { isServer }) => {
|
webpack: (config, { isServer }) => {
|
||||||
// Handle node: protocol imports
|
// Handle node: protocol imports
|
||||||
if (!isServer) {
|
if (!isServer) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user