fix(ui): use full-page navigation for auth-guard login redirect

This commit is contained in:
Devin AI 2026-07-15 22:08:50 +00:00
parent 9121ae3024
commit 2433efe246
2 changed files with 14 additions and 18 deletions

View file

@ -9,7 +9,6 @@ import useAuthorized from "./useAuthorized";
vi.unmock("@/app/(dashboard)/hooks/useAuthorized");
const {
replaceMock,
clearTokenCookiesMock,
getProxyBaseUrlMock,
getUiConfigMock,
@ -17,20 +16,19 @@ const {
checkTokenValidityMock,
buildLoginUrlWithReturnMock,
} = vi.hoisted(() => ({
replaceMock: vi.fn(),
clearTokenCookiesMock: vi.fn(),
getProxyBaseUrlMock: vi.fn(() => "http://proxy.example"),
getProxyBaseUrlMock: vi.fn(() => "https://proxy.example"),
getUiConfigMock: vi.fn(),
decodeTokenMock: vi.fn(),
checkTokenValidityMock: vi.fn(),
buildLoginUrlWithReturnMock: vi.fn((baseUrl: string) => baseUrl),
}));
vi.mock("next/navigation", () => ({
useRouter: () => ({
replace: replaceMock,
}),
}));
const locationReplaceMock = vi.fn();
Object.defineProperty(window, "location", {
configurable: true,
value: { ...window.location, replace: locationReplaceMock },
});
vi.mock("@/components/networking", async (importOriginal) => {
const actual = await importOriginal<typeof import("@/components/networking")>();
@ -92,7 +90,7 @@ const clearCookie = () => {
describe("useAuthorized", () => {
afterEach(() => {
replaceMock.mockReset();
locationReplaceMock.mockReset();
clearTokenCookiesMock.mockReset();
getProxyBaseUrlMock.mockClear();
getUiConfigMock.mockReset();
@ -140,7 +138,7 @@ describe("useAuthorized", () => {
expect(result.current.premiumUser).toBe(true);
expect(result.current.disabledPersonalKeyCreation).toBe(false);
expect(result.current.showSSOBanner).toBe(true);
expect(replaceMock).not.toHaveBeenCalled();
expect(locationReplaceMock).not.toHaveBeenCalled();
expect(clearTokenCookiesMock).not.toHaveBeenCalled();
});
@ -164,7 +162,7 @@ describe("useAuthorized", () => {
expect(clearTokenCookiesMock).toHaveBeenCalled();
});
expect(replaceMock).toHaveBeenCalledWith("http://proxy.example/ui/login");
expect(locationReplaceMock).toHaveBeenCalledWith("https://proxy.example/ui/login");
expect(result.current.accessToken).toBeNull();
expect(result.current.userRole).toBe("Undefined Role");
});
@ -197,7 +195,7 @@ describe("useAuthorized", () => {
const { result } = renderHook(() => useAuthorized(), { wrapper });
await waitFor(() => {
expect(replaceMock).toHaveBeenCalledWith("http://proxy.example/ui/login");
expect(locationReplaceMock).toHaveBeenCalledWith("https://proxy.example/ui/login");
});
expect(result.current.accessToken).toBe("api-key-123");
@ -221,7 +219,7 @@ describe("useAuthorized", () => {
const { result } = renderHook(() => useAuthorized(), { wrapper });
await waitFor(() => {
expect(replaceMock).toHaveBeenCalledWith("http://proxy.example/ui/login");
expect(locationReplaceMock).toHaveBeenCalledWith("https://proxy.example/ui/login");
});
expect(clearTokenCookiesMock).not.toHaveBeenCalled();
@ -256,7 +254,7 @@ describe("useAuthorized", () => {
expect(clearTokenCookiesMock).toHaveBeenCalled();
});
expect(replaceMock).toHaveBeenCalledWith("http://proxy.example/ui/login");
expect(locationReplaceMock).toHaveBeenCalledWith("https://proxy.example/ui/login");
expect(checkTokenValidityMock).toHaveBeenCalledWith(token);
});
});

View file

@ -4,13 +4,11 @@ import { getProxyBaseUrl } from "@/components/networking";
import { clearTokenCookies, getCookie } from "@/utils/cookieUtils";
import { checkTokenValidity, decodeToken } from "@/utils/jwtUtils";
import { buildLoginUrlWithReturn, storeReturnUrl } from "@/utils/returnUrlUtils";
import { useRouter } from "next/navigation";
import { useCallback, useEffect, useMemo } from "react";
import { formatUserRole } from "@/utils/roles";
import { useUIConfig } from "./uiConfig/useUIConfig";
const useAuthorized = () => {
const router = useRouter();
const { data: uiConfig, isLoading: isUIConfigLoading } = useUIConfig();
const token = typeof document !== "undefined" ? getCookie("token") : null;
@ -25,8 +23,8 @@ const useAuthorized = () => {
storeReturnUrl();
const baseLoginUrl = `${getProxyBaseUrl()}/ui/login`;
const loginUrlWithReturn = buildLoginUrlWithReturn(baseLoginUrl);
router.replace(loginUrlWithReturn);
}, [router]);
window.location.replace(loginUrlWithReturn);
}, []);
// Single useEffect for all redirect logic
useEffect(() => {