Clear all auth cookies when API token refresh fails before redirecting to login
Co-Authored-By: Codex <codex@openai.com>
This commit is contained in:
@@ -88,6 +88,8 @@ apiClient.interceptors.response.use(
|
|||||||
|
|
||||||
// Refresh failed: clear auth and redirect to login
|
// Refresh failed: clear auth and redirect to login
|
||||||
deleteCookie("luciaToken");
|
deleteCookie("luciaToken");
|
||||||
|
deleteCookie("luciaRefreshToken");
|
||||||
|
deleteCookie("isLuciaLoggedIn");
|
||||||
window.location.href = "/login";
|
window.location.href = "/login";
|
||||||
return Promise.reject(refreshError);
|
return Promise.reject(refreshError);
|
||||||
}
|
}
|
||||||
|
|||||||
56
tests/api/client.test.js
Normal file
56
tests/api/client.test.js
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
// The Lucia project.
|
||||||
|
// Copyright 2026-2026 DSP, inc. All rights reserved.
|
||||||
|
// Authors:
|
||||||
|
// imacat.yang@dsp.im (imacat), 2026/03/08
|
||||||
|
|
||||||
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
|
const { mockAxiosCreate, mockRequestUse, mockResponseUse, mockDeleteCookie } =
|
||||||
|
vi.hoisted(() => ({
|
||||||
|
mockAxiosCreate: vi.fn(),
|
||||||
|
mockRequestUse: vi.fn(),
|
||||||
|
mockResponseUse: vi.fn(),
|
||||||
|
mockDeleteCookie: vi.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("axios", () => ({
|
||||||
|
default: {
|
||||||
|
create: mockAxiosCreate,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("@/utils/cookieUtil.js", () => ({
|
||||||
|
getCookie: vi.fn(() => null),
|
||||||
|
deleteCookie: mockDeleteCookie,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("@/api/auth.js", () => ({
|
||||||
|
refreshTokenAndGetNew: vi.fn().mockRejectedValue(new Error("401")),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("apiClient response interceptor", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.clearAllMocks();
|
||||||
|
mockAxiosCreate.mockReturnValue({
|
||||||
|
interceptors: {
|
||||||
|
request: { use: mockRequestUse },
|
||||||
|
response: { use: mockResponseUse },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("clears all auth cookies when token refresh fails", async () => {
|
||||||
|
await import("@/api/client.js");
|
||||||
|
const rejectedHandler = mockResponseUse.mock.calls[0][1];
|
||||||
|
await expect(
|
||||||
|
rejectedHandler({
|
||||||
|
response: { status: 401 },
|
||||||
|
config: { url: "/api/my-account", headers: {} },
|
||||||
|
}),
|
||||||
|
).rejects.toThrow("401");
|
||||||
|
|
||||||
|
expect(mockDeleteCookie).toHaveBeenCalledWith("luciaToken");
|
||||||
|
expect(mockDeleteCookie).toHaveBeenCalledWith("luciaRefreshToken");
|
||||||
|
expect(mockDeleteCookie).toHaveBeenCalledWith("isLuciaLoggedIn");
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user