diff --git a/.DS_Store b/.DS_Store index fd078c3..d94a6ab 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/app/.DS_Store b/app/.DS_Store index 6305bed..b9dcd5f 100644 Binary files a/app/.DS_Store and b/app/.DS_Store differ diff --git a/app/signin/page.tsx b/app/signin/page.tsx index 3c0d88f..6a535fd 100644 --- a/app/signin/page.tsx +++ b/app/signin/page.tsx @@ -84,7 +84,7 @@ export default function SignIn() { return (
-
-
-

- {isLogoutRedirect - ? "Vous avez été déconnecté avec succès. Veuillez vous reconnecter." - : initializationStatus === "initializing" - ? "Initialisation de votre espace..." - : initializationStatus === "success" - ? "Initialisation réussie, redirection..." - : initializationStatus === "failed" - ? "Échec de l'initialisation. Veuillez réessayer." - : isLoggingIn - ? "Connexion en cours..." - : status === "loading" - ? "Chargement..." - : "Bienvenue"} -

- - {/* Show login button when user is not authenticated and not currently logging in */} - {status === "unauthenticated" && !isLoggingIn && ( -
- -
- )} - - {(initializationStatus === "initializing" || isLoggingIn || status === "loading") && ( -
-
-
- )} + {/* Header with login button in top right */} +
+ {status === "unauthenticated" && !isLoggingIn && ( + + )} +
+ + {/* Main content centered */} +
+
+
+

+ {isLogoutRedirect + ? "Vous avez été déconnecté avec succès. Veuillez vous reconnecter." + : initializationStatus === "initializing" + ? "Initialisation de votre espace..." + : initializationStatus === "success" + ? "Initialisation réussie, redirection..." + : initializationStatus === "failed" + ? "Échec de l'initialisation. Veuillez réessayer." + : isLoggingIn + ? "Connexion en cours..." + : status === "loading" + ? "Chargement..." + : ""} +

+ + {(initializationStatus === "initializing" || isLoggingIn || status === "loading") && ( +
+
+
+ )} +
diff --git a/components/.DS_Store b/components/.DS_Store new file mode 100644 index 0000000..dbe7151 Binary files /dev/null and b/components/.DS_Store differ diff --git a/components/auth/signout-handler.tsx b/components/auth/signout-handler.tsx index 46f991b..38fb0b7 100644 --- a/components/auth/signout-handler.tsx +++ b/components/auth/signout-handler.tsx @@ -66,16 +66,14 @@ export function SignOutHandler() { }); // 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) { 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' - ); + // Add id_token_hint to identify the session keycloakLogoutUrl.searchParams.append( 'id_token_hint', idToken @@ -86,8 +84,17 @@ export function SignOutHandler() { 'LOGOUT' ); - // Immediate redirect to Keycloak logout (prevents widget rendering) - 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 { // Fallback: just redirect to signin if we don't have Keycloak info window.location.replace('/signin?logout=true'); diff --git a/components/layout/layout-wrapper.tsx b/components/layout/layout-wrapper.tsx index aee2760..beffe26 100644 --- a/components/layout/layout-wrapper.tsx +++ b/components/layout/layout-wrapper.tsx @@ -169,10 +169,6 @@ export function LayoutWrapper({ children, isSignInPage, isAuthenticated }: Layou const keycloakLogoutUrl = new URL( `${keycloakIssuer}/protocol/openid-connect/logout` ); - keycloakLogoutUrl.searchParams.append( - 'post_logout_redirect_uri', - window.location.origin + '/signin?logout=true' - ); keycloakLogoutUrl.searchParams.append( 'id_token_hint', idToken @@ -182,7 +178,18 @@ export function LayoutWrapper({ children, isSignInPage, isAuthenticated }: Layou 'kc_action', '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 { // Fallback: redirect to signin window.location.replace('/signin?logout=true'); diff --git a/components/main-nav.tsx b/components/main-nav.tsx index 460daf1..21f14e3 100644 --- a/components/main-nav.tsx +++ b/components/main-nav.tsx @@ -406,11 +406,7 @@ export function MainNav() { `${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' - ); + // Add id_token_hint to identify the session keycloakLogoutUrl.searchParams.append( 'id_token_hint', idToken @@ -421,8 +417,17 @@ export function MainNav() { 'LOGOUT' ); - // Immediate redirect to Keycloak logout (prevents widget rendering) - 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 { // Fallback: just redirect to signin if we don't have Keycloak info window.location.replace('/signin?logout=true'); diff --git a/public/SignIn.jpg b/public/SignIn.jpg index 63e5da1..f4d7489 100644 Binary files a/public/SignIn.jpg and b/public/SignIn.jpg differ