Projekt

Obecné

Profil

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