UIKit/lib/api/makeRequest.ts

77 lines
2.2 KiB
TypeScript
Raw Normal View History

2024-04-15 20:14:39 +00:00
import axios, { AxiosResponse, Method, ResponseType } from "axios";
2023-08-14 12:03:23 +00:00
import { getAuthToken, setAuthToken } from "../stores/auth";
2023-06-06 10:02:17 +00:00
2023-06-11 09:55:06 +00:00
export async function makeRequest<TRequest = unknown, TResponse = unknown>({
2023-06-06 10:02:17 +00:00
method = "post",
url,
body,
useToken = true,
contentType = false,
responseType = "json",
2023-06-06 10:02:17 +00:00
signal,
withCredentials,
2023-06-11 09:55:06 +00:00
}: {
method?: Method;
url: string;
body?: TRequest;
/** Send access token */
useToken?: boolean;
contentType?: boolean;
2024-04-15 20:14:39 +00:00
responseType?: ResponseType;
2023-06-11 09:55:06 +00:00
signal?: AbortSignal;
/** Send refresh token */
withCredentials?: boolean;
}): Promise<TResponse> {
2023-06-06 10:02:17 +00:00
const headers: Record<string, string> = {};
2025-05-11 17:28:17 +00:00
if (useToken) headers["Authorization"] = getAuthToken() ? `Bearer ${getAuthToken()}` : "";
2023-06-06 10:02:17 +00:00
if (contentType) headers["Content-Type"] = "application/json";
try {
const response = await axios<TRequest, AxiosResponse<TResponse & { accessToken?: string; }>>({
url,
method,
headers,
data: body,
signal,
2024-04-15 20:14:39 +00:00
responseType,
2023-06-06 10:02:17 +00:00
withCredentials,
});
if (response.data?.accessToken) {
2023-06-11 09:55:06 +00:00
setAuthToken(response.data.accessToken);
2023-06-06 10:02:17 +00:00
}
return response.data;
} catch (error) {
if (axios.isAxiosError(error) && error.response?.status === 401 && !withCredentials) {
2023-06-11 09:55:06 +00:00
const refreshResponse = await refresh(getAuthToken());
if (refreshResponse.data?.accessToken) setAuthToken(refreshResponse.data.accessToken);
2023-06-06 10:02:17 +00:00
headers["Authorization"] = refreshResponse.data.accessToken;
const response = await axios.request<TRequest, AxiosResponse<TResponse>>({
url,
method,
headers,
data: body,
signal,
});
return response.data;
}
throw error;
}
2023-08-14 12:03:23 +00:00
}
2023-06-06 10:02:17 +00:00
function refresh(token: string) {
2024-04-16 10:09:45 +00:00
return axios<never, AxiosResponse<{ accessToken: string; }>>(process.env.REACT_APP_DOMAIN + "/auth/refresh", {
2023-06-06 10:02:17 +00:00
headers: {
"Authorization": `Bearer ${token}`,
2023-06-06 10:02:17 +00:00
"Content-Type": "application/json",
},
2024-04-16 10:09:45 +00:00
method: "post"
2023-06-06 10:02:17 +00:00
});
2023-07-10 16:17:54 +00:00
}