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:
2026-03-08 19:29:04 +08:00
parent b53f58cb0c
commit 1670054356
2 changed files with 58 additions and 0 deletions

56
tests/api/client.test.js Normal file
View 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");
});
});