Files
link-free/src/services/api.ts
2021-12-18 00:50:54 -03:00

91 lines
2.3 KiB
TypeScript

import axios, { AxiosError } from 'axios'
import { GetServerSidePropsContext } from 'next'
import router from 'next/router'
import { parseCookies } from 'nookies'
import { destroyCookies } from '../utils/destroyCookies'
import { setCookies } from '../utils/setCookies'
let isRefreshing = false
let failedRequestsQueued: any[] = []
export function setupAPIClient(ctx: GetServerSidePropsContext | undefined = undefined) {
let cookies = parseCookies(ctx)
const authorization = cookies.accessToken
? { headers: { authorization: `Bearer ${cookies.accessToken}` } }
: {}
const api = axios.create({
baseURL: '/api',
...authorization
})
api.interceptors.response.use(
response => {
return response
},
(error: AxiosError) => {
if (error.response?.status === 401) {
cookies = parseCookies(ctx)
const { refreshToken } = cookies
const originalConfig = error.config
if (!isRefreshing) {
isRefreshing = true
api
.post('session/refresh-token', { refreshToken })
.then(response => {
const { accessToken, refreshToken } = response.data
setCookies({
ctx,
accessToken,
refreshToken
})
failedRequestsQueued.forEach(request => request.onSuccess(accessToken))
failedRequestsQueued = []
})
.catch(error => {
failedRequestsQueued.forEach(request => request.onFailure(error))
failedRequestsQueued = []
destroyCookies(ctx)
if (process.browser) {
router.push('/auth')
}
})
.finally(() => {
isRefreshing = false
})
return new Promise((resolve, reject) => {
failedRequestsQueued.push({
onSuccess: (token: string) => {
if (originalConfig.headers) {
originalConfig.headers['authorization'] = `Bearer ${token}`
}
resolve(api(originalConfig))
},
onFailure: (error: AxiosError) => {
reject(error)
}
})
})
}
}
return Promise.reject(error)
}
)
return api
}
export const api = setupAPIClient()