Files
Messenger/web/src/api/http.ts
Codex 776a7634d2
Some checks failed
Android CI / android (push) Has started running
Android Release / release (push) Has been cancelled
CI / test (push) Has been cancelled
web: fix reset password token flow and auth interceptor
2026-03-09 21:52:24 +03:00

62 lines
1.8 KiB
TypeScript

import axios from "axios";
import type { AxiosError, InternalAxiosRequestConfig } from "axios";
import { useAuthStore } from "../store/authStore";
const apiBaseUrl = import.meta.env.VITE_API_BASE_URL ?? "/api/v1";
export const http = axios.create({
baseURL: apiBaseUrl,
timeout: 10000
});
http.interceptors.request.use((config) => {
const token = useAuthStore.getState().accessToken;
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
let refreshInFlight: Promise<void> | null = null;
function shouldSkipRefresh(config?: InternalAxiosRequestConfig): boolean {
const url = config?.url ?? "";
return (
url.includes("/auth/login") ||
url.includes("/auth/refresh") ||
url.includes("/auth/register") ||
url.includes("/auth/check-email") ||
url.includes("/auth/verify-email") ||
url.includes("/auth/resend-verification") ||
url.includes("/auth/request-password-reset") ||
url.includes("/auth/reset-password")
);
}
http.interceptors.response.use(
(response) => response,
async (error: AxiosError) => {
const status = error.response?.status;
const originalRequest = error.config as (InternalAxiosRequestConfig & { _retry?: boolean }) | undefined;
if (!originalRequest || status !== 401 || originalRequest._retry || shouldSkipRefresh(originalRequest)) {
return Promise.reject(error);
}
originalRequest._retry = true;
const authStore = useAuthStore.getState();
try {
if (!refreshInFlight) {
refreshInFlight = authStore.refresh().finally(() => {
refreshInFlight = null;
});
}
await refreshInFlight;
return http.request(originalRequest);
} catch (refreshError) {
useAuthStore.getState().logout();
return Promise.reject(refreshError);
}
}
);