From 97ca48f56ae0f22c4bcb18f4ce7117c9d64be96f Mon Sep 17 00:00:00 2001 From: Oliver Kieselbach Date: Fri, 27 Feb 2026 15:40:32 +0100 Subject: [PATCH] fix: stop MSAL-triggered navigation to dashboard while on session detail page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause: MSAL fires handleRedirectPromise twice on page load, causing isAuthenticated to briefly flip false between the two settlements. This triggered ProtectedRoute to redirect to '/', which then re-authenticated and redirected to '/dashboard', causing the dashboard page to mount and unmount periodically while the user was viewing a session. Two fixes: 1. navigateToLoginRequestUrl: false — prevents MSAL from navigating to the stored login request URL after redirect settlement, eliminating the spurious navigation that caused the dashboard to mount. 2. ProtectedRoute unauthenticated redirect now waits 500ms before executing, giving MSAL time to complete its double-settlement cycle before we conclude the user is truly unauthenticated. Co-Authored-By: Claude Opus 4.6 --- .../components/ProtectedRoute.tsx | 10 ++++++++-- src/Web/autopilot-monitor-web/lib/msalConfig.ts | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Web/autopilot-monitor-web/components/ProtectedRoute.tsx b/src/Web/autopilot-monitor-web/components/ProtectedRoute.tsx index 39a6773c..05247165 100644 --- a/src/Web/autopilot-monitor-web/components/ProtectedRoute.tsx +++ b/src/Web/autopilot-monitor-web/components/ProtectedRoute.tsx @@ -26,8 +26,14 @@ export function ProtectedRoute({ children, requireGalacticAdmin = false }: Prote useEffect(() => { if (!isLoading && !isAuthenticated && !wasAuthenticated.current) { - // Never been authenticated in this session -> redirect to landing - router.push("/"); + // Delay redirect slightly to let MSAL finish its double handleRedirectPromise + // settling cycle before deciding the user is truly unauthenticated. + const t = setTimeout(() => { + if (!wasAuthenticated.current) { + router.push("/"); + } + }, 500); + return () => clearTimeout(t); } }, [isAuthenticated, isLoading, router]); diff --git a/src/Web/autopilot-monitor-web/lib/msalConfig.ts b/src/Web/autopilot-monitor-web/lib/msalConfig.ts index 59a20970..3b2f12b6 100644 --- a/src/Web/autopilot-monitor-web/lib/msalConfig.ts +++ b/src/Web/autopilot-monitor-web/lib/msalConfig.ts @@ -16,7 +16,7 @@ export const msalConfig: Configuration = { authority: "https://login.microsoftonline.com/organizations", // Multi-tenant redirectUri: process.env.NEXT_PUBLIC_ENTRA_REDIRECT_URI || "http://localhost:3000", postLogoutRedirectUri: process.env.NEXT_PUBLIC_ENTRA_POST_LOGOUT_REDIRECT_URI || "http://localhost:3000", - navigateToLoginRequestUrl: true, + navigateToLoginRequestUrl: false, }, cache: { cacheLocation: "sessionStorage", // Using sessionStorage for better XSS protection