60 lines
1.5 KiB
JavaScript
60 lines
1.5 KiB
JavaScript
import { API_URL } from "@/config";
|
|
|
|
|
|
// Auth fetch wrapper
|
|
export const authFetch = async (url, options = {}, retry = true) => {
|
|
const res = await fetch(url, {
|
|
...options,
|
|
credentials: "include", // cookie goes automatically
|
|
});
|
|
|
|
if (res.status === 401 && retry) {
|
|
// attempt refresh
|
|
try {
|
|
const refreshRes = await fetch(`${API_URL}/auth/refresh`, {
|
|
method: "POST",
|
|
credentials: "include",
|
|
});
|
|
|
|
if (!refreshRes.ok) throw new Error("Refresh failed");
|
|
|
|
// Retry original request once after refresh
|
|
return authFetch(url, options, false);
|
|
} catch (err) {
|
|
console.error("Refresh token failed:", err);
|
|
return res;
|
|
}
|
|
}
|
|
|
|
return res;
|
|
};
|
|
|
|
// Refresh token function (HttpOnly cookie flow)
|
|
export async function refreshAccessToken(cookieHeader) {
|
|
try {
|
|
const res = await fetch(`${API_URL}/auth/refresh`, {
|
|
method: "POST",
|
|
headers: {
|
|
cookie: cookieHeader || "", // forward cookies from the request
|
|
},
|
|
});
|
|
|
|
if (!res.ok) {
|
|
throw new Error("Failed to refresh token");
|
|
}
|
|
|
|
// assume backend responds with new tokens in JSON
|
|
return await res.json();
|
|
} catch (err) {
|
|
console.error("Refresh token failed:", err);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export function handleLogout() {
|
|
document.cookie.split(";").forEach((cookie) => {
|
|
const name = cookie.split("=")[0].trim();
|
|
document.cookie = `${name}=; Max-Age=0; path=/;`;
|
|
});
|
|
window.location.href = "/";
|
|
} |