From 35cc24c5ec89e501afe1ee1b4b3dba745511ec2a Mon Sep 17 00:00:00 2001 From: Flexomatic81 Date: Thu, 12 Feb 2026 13:02:49 +0100 Subject: [PATCH] fix: auto-redirect to Keycloak login, skip intermediate screen Since tOS uses Keycloak as sole auth provider, the intermediate login page with the manual "Mit Keycloak anmelden" button was unnecessary. Now unauthenticated users are redirected directly to Keycloak. The error UI with retry button is preserved for failed auth attempts (expired session, unauthorized). Co-Authored-By: Claude Opus 4.6 --- apps/web/src/app/[locale]/login/page.tsx | 37 ++++++++++++++---------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/apps/web/src/app/[locale]/login/page.tsx b/apps/web/src/app/[locale]/login/page.tsx index a7acd1e..f1b8d6e 100644 --- a/apps/web/src/app/[locale]/login/page.tsx +++ b/apps/web/src/app/[locale]/login/page.tsx @@ -3,7 +3,7 @@ import { signIn, useSession } from 'next-auth/react'; import { useRouter, useSearchParams } from 'next/navigation'; import { useTranslations } from 'next-intl'; -import { useEffect, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { motion } from 'framer-motion'; import { Loader2, KeyRound } from 'lucide-react'; @@ -16,7 +16,7 @@ interface LoginPageProps { /** * Login page component - * Handles authentication via Keycloak + * Automatically redirects to Keycloak. Only shows UI on auth errors. */ export default function LoginPage({ params: { locale } }: LoginPageProps) { const { status } = useSession(); @@ -24,6 +24,7 @@ export default function LoginPage({ params: { locale } }: LoginPageProps) { const searchParams = useSearchParams(); const t = useTranslations('auth'); const [isLoading, setIsLoading] = useState(false); + const autoSignInTriggered = useRef(false); const callbackUrl = searchParams.get('callbackUrl') || `/${locale}/dashboard`; const error = searchParams.get('error'); @@ -35,6 +36,14 @@ export default function LoginPage({ params: { locale } }: LoginPageProps) { } }, [status, router, callbackUrl]); + // Auto-redirect to Keycloak if no error + useEffect(() => { + if (status === 'unauthenticated' && !error && !autoSignInTriggered.current) { + autoSignInTriggered.current = true; + signIn('keycloak', { callbackUrl }); + } + }, [status, error, callbackUrl]); + const handleLogin = async () => { setIsLoading(true); try { @@ -44,8 +53,8 @@ export default function LoginPage({ params: { locale } }: LoginPageProps) { } }; - // Show loading state while checking session - if (status === 'loading') { + // Show loading spinner during auto-redirect or session check + if (!error) { return (
@@ -53,6 +62,7 @@ export default function LoginPage({ params: { locale } }: LoginPageProps) { ); } + // Only show full UI when there's an error (so user can retry) return (
- {/* Logo */}
t OS @@ -73,18 +82,14 @@ export default function LoginPage({ params: { locale } }: LoginPageProps) {
- {/* Error message */} - {error && ( - - {error === 'SessionRequired' ? t('sessionExpired') : t('unauthorized')} - - )} + + {error === 'SessionRequired' ? t('sessionExpired') : t('unauthorized')} + - {/* Login button */}