diff --git a/airflow-core/src/airflow/ui/src/layouts/Nav/LogoutModal.tsx b/airflow-core/src/airflow/ui/src/layouts/Nav/LogoutModal.tsx index 97b5e67cb35ba..a4824f126d9c5 100644 --- a/airflow-core/src/airflow/ui/src/layouts/Nav/LogoutModal.tsx +++ b/airflow-core/src/airflow/ui/src/layouts/Nav/LogoutModal.tsx @@ -20,6 +20,7 @@ import { Text } from "@chakra-ui/react"; import React from "react"; import { ConfirmationModal } from "src/components/ConfirmationModal"; +import { getRedirectPath } from "src/utils/links.ts"; import { TOKEN_STORAGE_KEY } from "src/utils/tokenHandler"; type LogoutModalProps = { @@ -31,9 +32,7 @@ const LogoutModal: React.FC = ({ isOpen, onClose }) => ( { - const baseHref = document.querySelector("head>base")?.getAttribute("href") ?? ""; - const baseUrl = new URL(baseHref, globalThis.location.origin); - const logoutPath = new URL("api/v2/auth/logout", baseUrl).pathname; + const logoutPath = getRedirectPath("api/v2/auth/logout"); localStorage.removeItem(TOKEN_STORAGE_KEY); globalThis.location.replace(logoutPath); diff --git a/airflow-core/src/airflow/ui/src/main.tsx b/airflow-core/src/airflow/ui/src/main.tsx index 9d26f27d986f7..f91fdd4cf44c8 100644 --- a/airflow-core/src/airflow/ui/src/main.tsx +++ b/airflow-core/src/airflow/ui/src/main.tsx @@ -27,6 +27,7 @@ import type { HTTPExceptionResponse } from "openapi/requests/types.gen"; import { ColorModeProvider } from "src/context/colorMode"; import { TimezoneProvider } from "src/context/timezone"; import { router } from "src/router"; +import { getRedirectPath } from "src/utils/links.ts"; import { queryClient } from "./queryClient"; import { system } from "./theme"; @@ -44,13 +45,7 @@ axios.interceptors.response.use( const params = new URLSearchParams(); params.set("next", globalThis.location.href); - - const baseHref = document.querySelector("head>base")?.getAttribute("href") ?? ""; - - // Resolve the scheme-relative URL from the base relative to the current URL - const baseUrl = new URL(baseHref, globalThis.location.origin); - - const loginPath = new URL("api/v2/auth/login", baseUrl).pathname; + const loginPath = getRedirectPath("api/v2/auth/login"); globalThis.location.replace(`${loginPath}?${params.toString()}`); } diff --git a/airflow-core/src/airflow/ui/src/utils/links.ts b/airflow-core/src/airflow/ui/src/utils/links.ts index 69f634268e685..c56f19a1bcd0d 100644 --- a/airflow-core/src/airflow/ui/src/utils/links.ts +++ b/airflow-core/src/airflow/ui/src/utils/links.ts @@ -32,3 +32,10 @@ export const getTaskInstanceLinkFromObj = ({ mapIndex: number; taskId: string; }) => `/dags/${dagId}/runs/${dagRunId}/tasks/${taskId}${mapIndex >= 0 ? `/mapped/${mapIndex}` : ""}`; + +export const getRedirectPath = (targetPath: string): string => { + const baseHref = document.querySelector("head > base")?.getAttribute("href") ?? ""; + const baseUrl = new URL(baseHref, globalThis.location.origin); + + return new URL(targetPath, baseUrl).pathname; +};