Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import axios, { AxiosRequestHeaders, AxiosResponse } from 'axios'
- import appConfig from '@/configs/app.config'
- import {
- TOKEN_TYPE,
- REQUEST_HEADER_AUTH_KEY,
- REQUEST_HEADER_ACCEPT_LANGUAGE_KEY,
- } from '@/constants/api.constant'
- import {
- PERSIST_STORE_NAME,
- REFRESH_TOKEN_PATH,
- } from '@/constants/app.constant'
- import deepParseJson from '@/utils/deepParseJson'
- import store, { refreshSuccess, signOutSuccess } from '../store'
- const unauthorizedCode = [401]
- interface RefreshTokenResponse {
- data: {
- jwt: string
- }
- }
- interface FailedRequest {
- resolve: (token: string) => void
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- reject: (reason: any) => void
- }
- let isRefreshing = false
- let failedRequestsQueue: FailedRequest[] = []
- const BaseService = axios.create({
- timeout: 60000,
- baseURL: appConfig.apiPrefix,
- })
- const BaseRefreshService = axios.create({
- timeout: 60000,
- baseURL: appConfig.apiPrefix,
- })
- BaseService.interceptors.request.use(
- (config) => {
- if (config?.headers?._retry) {
- delete config.headers._retry
- } else {
- const headers = getHeaders()
- config.headers = { ...config.headers, ...headers } as AxiosRequestHeaders
- }
- return config
- },
- (error) => {
- return Promise.reject(error)
- }
- )
- BaseService.interceptors.response.use(
- (response: AxiosResponse) => response,
- (error) => {
- const { response } = error
- if (response && unauthorizedCode.includes(response.status)) {
- if (!isRefreshing) {
- isRefreshing = true
- const headers = getHeaders()
- BaseRefreshService.post<RefreshTokenResponse>(
- REFRESH_TOKEN_PATH,
- {},
- { headers }
- )
- .then((resp) => {
- const accessToken = resp.data.data.jwt
- processQueue(null, accessToken)
- store.dispatch(refreshSuccess(accessToken))
- })
- .catch((err) => {
- processQueue(err)
- store.dispatch(signOutSuccess())
- return Promise.reject(err)
- })
- .finally(() => {
- isRefreshing = false
- })
- }
- return new Promise((resolve, reject) => {
- failedRequestsQueue.push({ resolve, reject })
- })
- .then((token) => {
- error.config.headers[
- REQUEST_HEADER_AUTH_KEY
- ] = `${TOKEN_TYPE}${token}`
- error.config.headers._retry = true
- return BaseService(error.config)
- })
- .catch((err) => {
- return Promise.reject(err)
- })
- }
- return Promise.reject(error)
- }
- )
- /**
- * Retrieves the headers for making API requests.
- * @returns The headers as AxiosRequestHeaders.
- */
- function getHeaders() {
- const headers: Record<string, string> = {}
- const rawPersistData = localStorage.getItem(PERSIST_STORE_NAME)
- const persistData = deepParseJson(rawPersistData) as {
- auth?: { session: { token: string } }
- locale?: { currentLang: string }
- }
- const accessToken =
- persistData?.auth?.session.token || store.getState().auth.session.token
- const currentLang = persistData?.locale?.currentLang || appConfig.locale
- if (accessToken) {
- headers[REQUEST_HEADER_AUTH_KEY] = `${TOKEN_TYPE}${accessToken}`
- }
- headers[REQUEST_HEADER_ACCEPT_LANGUAGE_KEY] = currentLang
- return headers as AxiosRequestHeaders
- }
- /**
- * Processes the failed requests queue.
- *
- * @param error - The error object to reject the promises with.
- * @param token - The token to resolve the promises with. Defaults to null.
- */
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- function processQueue(error: any, token: string | null = null): void {
- failedRequestsQueue.forEach((prom) => {
- if (error) {
- prom.reject(error)
- } else {
- prom.resolve(token as string)
- }
- })
- failedRequestsQueue = []
- }
- export default BaseService
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement