fix(ui): follow managed sign-out redirects

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip authored and GitHub committed 2026-08-03 22:34:14 -05:00
1 parent 2a90933433
commit 76f442040c
5 files changed
+92 -6

No files matched your search

+29
View File
@@ -0,0 +1,29 @@
import { afterEach, describe, expect, it, vi } from "vitest";
import { authApi } from "./auth";
describe("authApi.signOut", () => {
afterEach(() => {
vi.unstubAllGlobals();
});
it("returns the managed deployment redirect from the response", async () => {
const fetchMock = vi.fn().mockResolvedValue(
new Response(JSON.stringify({ success: true, redirectTo: "/cloud/logout" }), {
status: 200,
headers: { "Content-Type": "application/json" },
}),
);
vi.stubGlobal("fetch", fetchMock);
await expect(authApi.signOut()).resolves.toEqual({
success: true,
redirectTo: "/cloud/logout",
});
expect(fetchMock).toHaveBeenCalledWith("/api/auth/sign-out", {
method: "POST",
credentials: "include",
headers: { "Content-Type": "application/json" },
body: "{}",
});
});
});
+15 -3
View File
@@ -15,6 +15,11 @@ type AuthErrorBody =
}
| null;
export interface SignOutResult {
success?: boolean;
redirectTo?: string;
}
export class AuthApiError extends Error {
status: number;
code: string | null;
@@ -105,7 +110,7 @@ function logAuthHttpError(method: string, path: string, status: number, statusTe
});
}
async function authPost(path: string, body: Record<string, unknown>) {
async function authPost(path: string, body: Record<string, unknown>): Promise<unknown> {
let res: Response;
try {
res = await fetch(`/api/auth${path}`, {
@@ -180,7 +185,14 @@ export const authApi = {
updateProfile: async (input: UpdateCurrentUserProfile): Promise<CurrentUserProfile> =>
authPatch("/profile", input, (payload) => currentUserProfileSchema.parse(payload)),
signOut: async () => {
await authPost("/sign-out", {});
signOut: async (): Promise<SignOutResult | null> => {
const payload = await authPost("/sign-out", {});
if (!payload || typeof payload !== "object") return null;
const result = payload as Record<string, unknown>;
return {
...(typeof result.success === "boolean" ? { success: result.success } : {}),
...(typeof result.redirectTo === "string" ? { redirectTo: result.redirectTo } : {}),
};
},
};