marco.pms.web/src/utils/axiosClient.jsx

204 lines
6.5 KiB
JavaScript

import axios from "axios";
import { useNavigate } from "react-router-dom";
import axiosRetry from "axios-retry";
import showToast from "../services/toastService";
const base_Url = process.env.VITE_BASE_URL;
// const base_Url = "https://api.marcoaiot.com";
export const axiosClient = axios.create({
baseURL: base_Url, // Your Web API URL
withCredentials: false, // Required if the API uses cookies
headers: {
"Content-Type": "application/json", // Specify the content type
},
});
axiosRetry(axiosClient, { retries: 3 });
// Request interceptor to add Bearer token
axiosClient.interceptors.request.use(
async (config) => {
if (config.authRequired) {
const token = localStorage.getItem("jwtToken");
if (token) {
config.headers["Authorization"] = `Bearer ${token}`;
config._retry = true;
}
else{
config._retry = false;
}
}
return config;
},
(error) => Promise.reject(error)
);
// // Response interceptor to handle responses globally (optional)
// Add an interceptor to handle expired tokens
axiosClient.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config;
if (!originalRequest) {
return Promise.reject(error);
}
// Prevent multiple toasts for the same request
if (!originalRequest._toastShown) {
originalRequest._toastShown = true;
if (error.code === "ERR_CONNECTION_REFUSED") {
console.error(
"Connection refused. Please ensure the server is running."
);
if (error.config.url.indexOf("refresh-token") != -1) {
//showToast("Server is unreachable. Try again later!", "error");
console.log("1 - error fetching refresh token :", error);
} else {
showToast(
"Unable to connect to the server. Please try again later.",
"error"
);
}
} else if (error.code === "ERR_NETWORK") {
console.error("Network error: Unable to reach the server.");
if (error.config.url.indexOf("refresh-token") != -1) {
//showToast("Server is unreachable. Try again later!", "error");
console.log("2 - error fetching refresh token :", error);
}
redirectToLogin();
} else if (error.code === "ECONNABORTED") {
console.error("Request timed out.");
if (error.config.url.indexOf("refresh-token") != -1) {
//showToast("Server is unreachable. Try again later!", "error");
console.log("3 - error fetching refresh token :", error);
} else {
showToast(
"The request took too long. Please try again later.",
"error"
);
}
} else if (error.response) {
if (error.config.url.indexOf("refresh-token") != -1) {
//showToast("Server is unreachable. Try again later!", "error");
console.log("4 - error fetching refresh token :", error);
}
// else {
// // showToast(error.response.data.message, "error"); // repeted toast
// }
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
try {
// Get the refresh token from secure storage
const refreshToken = localStorage.getItem("refreshToken");
if (!refreshToken) {
// Redirect to login if refresh token is not available
redirectToLogin();
return Promise.reject(error);
}
// Make a request to refresh the access token
const response = await axiosClient
.post("/api/Auth/refresh-token", {
token: localStorage.getItem("jwtToken"),
refreshToken,
})
.catch((error) => {
console.log("7 - error fetching refresh token :", error);
});
const { token, refreshToken: newRefreshToken } = response.data.data;
localStorage.setItem("jwtToken", token);
localStorage.setItem("refreshToken", newRefreshToken);
// Retry the original request with the new token
originalRequest.headers["Authorization"] = `Bearer ${token}`;
// Retry the original request
return axiosClient(originalRequest);
} catch (err) {
console.log(
"5 - error fetching refresh token during refresh call :",
error
);
// Redirect to login if token refresh fails
redirectToLogin();
return Promise.reject(err);
}
} else {
if (error.config.url.indexOf("refresh-token") != -1) {
//showToast("Server is unreachable. Try again later!", "error");
console.log("6 - error fetching refresh token :", error);
}
// showToast(
// error.response.data?.message ||
// "An error occurred. Please try again.",
// "error"
// );
}
} else {
console.error("An unknown error occurred:", error.message);
}
}
return Promise.reject(error);
}
);
// Generic API Call
const apiRequest = async (method, url, data = {}, config = {}) => {
try {
const response = await axiosClient({
method,
url,
data: method !== "get" ? data : undefined,
params: method === "get" ? data : undefined,
...config,
});
return response.data;
} catch (error) {
throw error;
}
};
export const api = {
// For public routes like login, set authRequired: false
postPublic: (url, data = {}, customHeaders = {}) =>
apiRequest("post", url, data, {
headers: { ...customHeaders },
authRequired: false,
}),
// For protected routes, authRequired defaults to true
get: (url, params = {}, customHeaders = {}) =>
apiRequest("get", url, params, {
headers: { ...customHeaders },
authRequired: true,
}),
post: (url, data = {}, customHeaders = {}) =>
apiRequest("post", url, data, {
headers: { ...customHeaders },
authRequired: true,
}),
put: (url, data = {}, customHeaders = {}) =>
apiRequest("put", url, data, {
headers: { ...customHeaders },
authRequired: true,
}),
delete: (url, data = {}, customHeaders = {}) =>
apiRequest("delete", url, data, {
headers: { ...customHeaders },
authRequired: true,
}),
};
//export default axiosClient;
function redirectToLogin() {
// window.location.href = "/auth/login";
}