Files
shop/frontend/shared/src/api.ts
Marek Lenczewski e3e88cc58e wahnsinn vibe
2026-04-16 19:42:06 +02:00

61 lines
1.9 KiB
TypeScript

import axios, { type AxiosInstance } from "axios";
const STORAGE_KEY_ACCESS = "shop_access_token";
const STORAGE_KEY_REFRESH = "shop_refresh_token";
export function createApi(baseURL: string): AxiosInstance {
// 10 min — LLM plan calls over many items on a local CPU can take several minutes.
const api = axios.create({ baseURL, timeout: 600000 });
api.interceptors.request.use((cfg) => {
const token = localStorage.getItem(STORAGE_KEY_ACCESS);
if (token) {
cfg.headers = cfg.headers || {};
cfg.headers["Authorization"] = `Bearer ${token}`;
}
return cfg;
});
api.interceptors.response.use(
(r) => r,
async (err) => {
const original = err.config;
if (err.response?.status === 401 && !original._retry) {
const refresh = localStorage.getItem(STORAGE_KEY_REFRESH);
if (refresh) {
original._retry = true;
try {
const resp = await axios.post(`${baseURL}/api/auth/refresh`, {
refresh_token: refresh,
});
localStorage.setItem(STORAGE_KEY_ACCESS, resp.data.access_token);
localStorage.setItem(STORAGE_KEY_REFRESH, resp.data.refresh_token);
original.headers.Authorization = `Bearer ${resp.data.access_token}`;
return api(original);
} catch {
localStorage.removeItem(STORAGE_KEY_ACCESS);
localStorage.removeItem(STORAGE_KEY_REFRESH);
}
}
}
throw err;
}
);
return api;
}
export function saveTokens(access: string, refresh: string): void {
localStorage.setItem(STORAGE_KEY_ACCESS, access);
localStorage.setItem(STORAGE_KEY_REFRESH, refresh);
}
export function clearTokens(): void {
localStorage.removeItem(STORAGE_KEY_ACCESS);
localStorage.removeItem(STORAGE_KEY_REFRESH);
}
export function hasAccess(): boolean {
return !!localStorage.getItem(STORAGE_KEY_ACCESS);
}