import { boot } from "quasar/wrappers"; import { useAuth } from "src/composables/useAuth"; import { Cookies, Notify } from "quasar"; import axios from "axios"; const api = axios.create({ baseURL: process.env.API_URL + "/api", withCredentials: true, withXSRFToken: true, }); api.interceptors.request.use( async (config) => { const accessToken = Cookies.get("access_token"); const savedLanguage = Cookies.get("locale"); const language = savedLanguage || window.navigator.language; config.headers["Accept-Language"] = language; if (accessToken) { config.headers.Authorization = `Bearer ${accessToken}`; } return config; }, (error) => { return Promise.reject(error); }, ); let isRefreshing = false; let validQueue = []; const errorInterceptor = async (error) => { if (error.config?.retryCount) { error.config.retryCount = 0; } if (error.config.retryCount >= 3) { return Promise.reject(error); } error.config.retryCount++; if (!error.response) { Notify.create({ message: error.message, type: "negative", }); return Promise.reject(error); } if (error.response.status === 401) { if (error?.config?.url === "/login") { Notify.create({ message: error.response.data.message, type: "negative", }); return Promise.reject(error); } if (isRefreshing) { return new Promise((resolve, reject) => { validQueue.push({ resolve, reject, config: error.config }); }); } isRefreshing = true; try { await useAuth().refreshToken(); } catch (error) { validQueue = []; Cookies.remove("access_token"); Cookies.remove("refresh_token"); if (window.location.pathname !== "/login") { window.location.href = "/login"; } return Promise.reject(error); } try { validQueue.forEach((request) => { request.resolve(api.request(request.config)); }); validQueue = []; return await api.request(error.config); } catch (error) { Notify.create({ message: error.response.data.message, type: "negative", }); } finally { isRefreshing = false; } } Notify.create({ message: error.response.data.message, type: "negative", }); return Promise.reject(error); }; const successInterceptor = (response) => { if (response.data.message) { Notify.create({ message: response.data.message, type: "positive", }); } return response; }; export default boot(({ app }) => { api.interceptors.response.use( (response) => successInterceptor(response), (error) => errorInterceptor(error), ); // for use inside Vue files (Options API) through this.$axios and this.$api app.config.globalProperties.$axios = axios; // ^ ^ ^ this will allow you to use this.$axios (for Vue Options API form) // so you won't necessarily have to import axios in each vue file app.config.globalProperties.$api = api; // ^ ^ ^ this will allow you to use this.$api (for Vue Options API form) // so you can easily perform requests against your app's API }); export { api };