mirror of
https://github.com/ershisan99/flashcards-example-project.git
synced 2025-12-17 05:09:29 +00:00
80 lines
2.0 KiB
TypeScript
80 lines
2.0 KiB
TypeScript
import { router } from '@/router'
|
|
import {
|
|
BaseQueryFn,
|
|
FetchArgs,
|
|
FetchBaseQueryError,
|
|
fetchBaseQuery,
|
|
} from '@reduxjs/toolkit/query/react'
|
|
import { Mutex } from 'async-mutex'
|
|
|
|
// create a new mutex
|
|
const mutex = new Mutex()
|
|
|
|
const baseQuery = fetchBaseQuery({
|
|
baseUrl: 'https://api.flashcards.andrii.es',
|
|
prepareHeaders: headers => {
|
|
const token = localStorage.getItem('accessToken')
|
|
|
|
if (headers.get('Authorization')) {
|
|
return headers
|
|
}
|
|
|
|
if (token) {
|
|
headers.set('Authorization', `Bearer ${token}`)
|
|
}
|
|
|
|
return headers
|
|
},
|
|
})
|
|
|
|
export const baseQueryWithReauth: BaseQueryFn<
|
|
FetchArgs | string,
|
|
unknown,
|
|
FetchBaseQueryError
|
|
> = async (args, api, extraOptions) => {
|
|
// wait until the mutex is available without locking it
|
|
await mutex.waitForUnlock()
|
|
let result = await baseQuery(args, api, extraOptions)
|
|
|
|
if (result.error && result.error.status === 401) {
|
|
// checking whether the mutex is locked
|
|
if (!mutex.isLocked()) {
|
|
const release = await mutex.acquire()
|
|
|
|
try {
|
|
const refreshToken = localStorage.getItem('refreshToken')
|
|
const refreshResult = (await baseQuery(
|
|
{
|
|
headers: {
|
|
Authorization: `Bearer ${refreshToken}`,
|
|
},
|
|
method: 'POST',
|
|
url: '/v2/auth/refresh-token',
|
|
},
|
|
api,
|
|
extraOptions
|
|
)) as any
|
|
|
|
if (refreshResult.data) {
|
|
localStorage.setItem('accessToken', refreshResult.data.accessToken)
|
|
localStorage.setItem('refreshToken', refreshResult.data.refreshToken)
|
|
|
|
// retry the initial query
|
|
result = await baseQuery(args, api, extraOptions)
|
|
} else {
|
|
router.navigate('/login')
|
|
}
|
|
} finally {
|
|
// release must be called once the mutex should be released again.
|
|
release()
|
|
}
|
|
} else {
|
|
// wait until the mutex is available without locking it
|
|
await mutex.waitForUnlock()
|
|
result = await baseQuery(args, api, extraOptions)
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|