Projekt

Obecné

Profil

Stáhnout (2.72 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 f2db3e05 Vaclav Honzik
43 37f6ff02 Vaclav Honzik
        // Original URL might be login in which case we don't want to refresh the access token
44
        // Since the user just failed to log in and no token expired
45
        if (originalConfig.url === '/login' || !err.response) {
46
            return Promise.reject(err)
47
        }
48
49 f2db3e05 Vaclav Honzik
        // If the error is not a 401 reject this
50
        if (err.response.status !== 401) {
51
            return Promise.reject(err)
52
        }
53
54 37f6ff02 Vaclav Honzik
        // We need to set the refresh token in the auth header
55
        const oldRefreshToken = store.getState().user.refreshToken
56
57
        // If there is no refresh token we simply log the user out
58
        if (!oldRefreshToken) {
59
            store.dispatch({ type: 'user/logout' })
60
        }
61
62
        // Try refreshing the JWT
63
        try {
64 8370b6c1 Vaclav Honzik
            const refreshInstance = createBaseInstance()
65 37f6ff02 Vaclav Honzik
            // @ts-ignore
66 8370b6c1 Vaclav Honzik
            refreshInstance.headers['Authorization'] = oldRefreshToken as string
67 37f6ff02 Vaclav Honzik
68 8370b6c1 Vaclav Honzik
            // Set this to retry the request that failed
69
            originalConfig.retry = true
70 37f6ff02 Vaclav Honzik
71 8370b6c1 Vaclav Honzik
            // Send the request
72
            const { data } = await axiosInstance.get('/users/refreshToken')
73 37f6ff02 Vaclav Honzik
            const { accessToken, refreshToken } = data
74
75
            // Set the new tokens
76
            store.dispatch({
77
                type: 'user/refreshTokens',
78
                payload: { accessToken, refreshToken },
79
            })
80
81 8370b6c1 Vaclav Honzik
            // Return the failed instance so it can retry
82 37f6ff02 Vaclav Honzik
            return axiosInstance(originalConfig)
83
        } catch (err: any) {
84
            // If the refresh token fails we log the user out
85
            store.dispatch({ type: 'user/logout' })
86 8370b6c1 Vaclav Honzik
            originalConfig.retry = false // do not retry we are logged out
87
            return originalConfig
88 37f6ff02 Vaclav Honzik
        }
89
    }
90
)
91
92
export default axiosInstance