Projekt

Obecné

Profil

Stáhnout (2.58 KB) Statistiky
| Větev: | Tag: | Revize:
1 37f6ff02 Vaclav Honzik
import axios from 'axios'
2
import { Store } from 'redux'
3
import config from '../config/conf'
4
import { AppStore } from '../features/redux/store'
5
6 8370b6c1 Vaclav Honzik
let store: AppStore // this will get injected in index.tsx
7 37f6ff02 Vaclav Honzik
8
export const injectStore = (_store: Store) => {
9
    store = _store
10
}
11
12
// Error
13
export interface ApiError {}
14
15
const createBaseInstance = () =>
16
    axios.create({
17
        baseURL: config.baseUrl,
18
    })
19
20
const axiosInstance = createBaseInstance()
21
22
axiosInstance.interceptors.request.use(
23
    (config) => {
24
        const accessToken = store.getState().user.accessToken // get the access token from the store
25
        if (accessToken) {
26 8370b6c1 Vaclav Honzik
            // @ts-ignore (axios typescript types are a crime and this will always be defined)
27 37f6ff02 Vaclav Honzik
            config.headers['Authorization'] = accessToken as string
28
        }
29
30
        return config
31
    },
32
    (err) => {
33
        Promise.reject(err)
34
    }
35
)
36
37
axiosInstance.interceptors.response.use(
38
    (res) => res,
39
    async (err) => {
40
        const originalConfig = err.config
41
42
        // Original URL might be login in which case we don't want to refresh the access token
43
        // Since the user just failed to log in and no token expired
44
        if (originalConfig.url === '/login' || !err.response) {
45
            return Promise.reject(err)
46
        }
47
48
        // We need to set the refresh token in the auth header
49
        const oldRefreshToken = store.getState().user.refreshToken
50
51
        // If there is no refresh token we simply log the user out
52
        if (!oldRefreshToken) {
53
            store.dispatch({ type: 'user/logout' })
54
        }
55
56
        // Try refreshing the JWT
57
        try {
58 8370b6c1 Vaclav Honzik
            const refreshInstance = createBaseInstance()
59 37f6ff02 Vaclav Honzik
            // @ts-ignore
60 8370b6c1 Vaclav Honzik
            refreshInstance.headers['Authorization'] = oldRefreshToken as string
61 37f6ff02 Vaclav Honzik
62 8370b6c1 Vaclav Honzik
            // Set this to retry the request that failed
63
            originalConfig.retry = true
64 37f6ff02 Vaclav Honzik
65 8370b6c1 Vaclav Honzik
            // Send the request
66
            const { data } = await axiosInstance.get('/users/refreshToken')
67 37f6ff02 Vaclav Honzik
            const { accessToken, refreshToken } = data
68
69
            // Set the new tokens
70
            store.dispatch({
71
                type: 'user/refreshTokens',
72
                payload: { accessToken, refreshToken },
73
            })
74
75 8370b6c1 Vaclav Honzik
            // Return the failed instance so it can retry
76 37f6ff02 Vaclav Honzik
            return axiosInstance(originalConfig)
77
        } catch (err: any) {
78
            // If the refresh token fails we log the user out
79
            store.dispatch({ type: 'user/logout' })
80 8370b6c1 Vaclav Honzik
            originalConfig.retry = false // do not retry we are logged out
81
            return originalConfig
82 37f6ff02 Vaclav Honzik
        }
83
    }
84
)
85
86
export default axiosInstance