This commit is contained in:
alma 2026-01-18 14:31:10 +01:00
parent 6414e85a78
commit ba59d266e3
8 changed files with 81 additions and 59 deletions

BIN
.DS_Store vendored

Binary file not shown.

BIN
app/.DS_Store vendored

Binary file not shown.

View File

@ -84,7 +84,7 @@ export default function SignIn() {
return ( return (
<div <div
className="min-h-screen flex items-center justify-center" className="min-h-screen flex flex-col"
style={{ style={{
backgroundImage: "url('/SignIn.jpg')", backgroundImage: "url('/SignIn.jpg')",
backgroundSize: 'cover', backgroundSize: 'cover',
@ -92,6 +92,24 @@ export default function SignIn() {
backgroundRepeat: 'no-repeat' backgroundRepeat: 'no-repeat'
}} }}
> >
{/* Header with login button in top right */}
<header className="w-full flex justify-end p-6">
{status === "unauthenticated" && !isLoggingIn && (
<button
onClick={() => {
console.log('[SignIn] Login button clicked');
setIsLoggingIn(true);
signIn("keycloak", { callbackUrl: "/" });
}}
className="px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-semibold shadow-lg hover:shadow-xl"
>
Se connecter
</button>
)}
</header>
{/* Main content centered */}
<div className="flex-1 flex items-center justify-center">
<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">
@ -107,25 +125,9 @@ export default function SignIn() {
? "Connexion en cours..." ? "Connexion en cours..."
: status === "loading" : status === "loading"
? "Chargement..." ? "Chargement..."
: "Bienvenue"} : ""}
</h2> </h2>
{/* Show login button when user is not authenticated and not currently logging in */}
{status === "unauthenticated" && !isLoggingIn && (
<div className="mt-8 text-center">
<button
onClick={() => {
console.log('[SignIn] Login button clicked');
setIsLoggingIn(true);
signIn("keycloak", { callbackUrl: "/" });
}}
className="px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-semibold text-lg shadow-lg hover:shadow-xl"
>
Se connecter
</button>
</div>
)}
{(initializationStatus === "initializing" || isLoggingIn || status === "loading") && ( {(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>
@ -134,5 +136,6 @@ export default function SignIn() {
</div> </div>
</div> </div>
</div> </div>
</div>
); );
} }

BIN
components/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -66,16 +66,14 @@ export function SignOutHandler() {
}); });
// If we have Keycloak ID token and issuer, call Keycloak logout // If we have Keycloak ID token and issuer, call Keycloak logout
// Note: We don't use post_logout_redirect_uri to avoid "Invalid redirect uri" error
// Instead, we'll redirect manually after logout
if (keycloakIssuer && idToken) { if (keycloakIssuer && idToken) {
const keycloakLogoutUrl = new URL( const keycloakLogoutUrl = new URL(
`${keycloakIssuer}/protocol/openid-connect/logout` `${keycloakIssuer}/protocol/openid-connect/logout`
); );
// Add required parameters - include logout=true in redirect URI // Add id_token_hint to identify the session
keycloakLogoutUrl.searchParams.append(
'post_logout_redirect_uri',
window.location.origin + '/signin?logout=true'
);
keycloakLogoutUrl.searchParams.append( keycloakLogoutUrl.searchParams.append(
'id_token_hint', 'id_token_hint',
idToken idToken
@ -86,8 +84,17 @@ export function SignOutHandler() {
'LOGOUT' 'LOGOUT'
); );
// Immediate redirect to Keycloak logout (prevents widget rendering) // Use a hidden iframe to logout from Keycloak without redirect
window.location.replace(keycloakLogoutUrl.toString()); // This avoids the "Invalid redirect uri" error
const logoutIframe = document.createElement('iframe');
logoutIframe.style.display = 'none';
logoutIframe.src = keycloakLogoutUrl.toString();
document.body.appendChild(logoutIframe);
// Wait a bit for logout to process, then redirect
setTimeout(() => {
window.location.replace('/signin?logout=true');
}, 500);
} else { } else {
// Fallback: just redirect to signin if we don't have Keycloak info // Fallback: just redirect to signin if we don't have Keycloak info
window.location.replace('/signin?logout=true'); window.location.replace('/signin?logout=true');

View File

@ -169,10 +169,6 @@ export function LayoutWrapper({ children, isSignInPage, isAuthenticated }: Layou
const keycloakLogoutUrl = new URL( const keycloakLogoutUrl = new URL(
`${keycloakIssuer}/protocol/openid-connect/logout` `${keycloakIssuer}/protocol/openid-connect/logout`
); );
keycloakLogoutUrl.searchParams.append(
'post_logout_redirect_uri',
window.location.origin + '/signin?logout=true'
);
keycloakLogoutUrl.searchParams.append( keycloakLogoutUrl.searchParams.append(
'id_token_hint', 'id_token_hint',
idToken idToken
@ -182,7 +178,18 @@ export function LayoutWrapper({ children, isSignInPage, isAuthenticated }: Layou
'kc_action', 'kc_action',
'LOGOUT' 'LOGOUT'
); );
window.location.replace(keycloakLogoutUrl.toString());
// Use a hidden iframe to logout from Keycloak without redirect
// This avoids the "Invalid redirect uri" error
const logoutIframe = document.createElement('iframe');
logoutIframe.style.display = 'none';
logoutIframe.src = keycloakLogoutUrl.toString();
document.body.appendChild(logoutIframe);
// Wait a bit for logout to process, then redirect
setTimeout(() => {
window.location.replace('/signin?logout=true');
}, 500);
} else { } else {
// Fallback: redirect to signin // Fallback: redirect to signin
window.location.replace('/signin?logout=true'); window.location.replace('/signin?logout=true');

View File

@ -406,11 +406,7 @@ export function MainNav() {
`${keycloakIssuer}/protocol/openid-connect/logout` `${keycloakIssuer}/protocol/openid-connect/logout`
); );
// Add required parameters - include logout=true in redirect URI // Add id_token_hint to identify the session
keycloakLogoutUrl.searchParams.append(
'post_logout_redirect_uri',
window.location.origin + '/signin?logout=true'
);
keycloakLogoutUrl.searchParams.append( keycloakLogoutUrl.searchParams.append(
'id_token_hint', 'id_token_hint',
idToken idToken
@ -421,8 +417,17 @@ export function MainNav() {
'LOGOUT' 'LOGOUT'
); );
// Immediate redirect to Keycloak logout (prevents widget rendering) // Use a hidden iframe to logout from Keycloak without redirect
window.location.replace(keycloakLogoutUrl.toString()); // This avoids the "Invalid redirect uri" error
const logoutIframe = document.createElement('iframe');
logoutIframe.style.display = 'none';
logoutIframe.src = keycloakLogoutUrl.toString();
document.body.appendChild(logoutIframe);
// Wait a bit for logout to process, then redirect
setTimeout(() => {
window.location.replace('/signin?logout=true');
}, 500);
} else { } else {
// Fallback: just redirect to signin if we don't have Keycloak info // Fallback: just redirect to signin if we don't have Keycloak info
window.location.replace('/signin?logout=true'); window.location.replace('/signin?logout=true');

Binary file not shown.

Before

Width:  |  Height:  |  Size: 338 KiB

After

Width:  |  Height:  |  Size: 493 KiB