61 lines
1.9 KiB
TypeScript
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);
|
|
}
|