Projekt

Obecné

Profil

Stáhnout (2.72 KB) Statistiky
| Větev: | Tag: | Revize:
1
import axios from 'axios'
2
import { Store } from 'redux'
3
import config from '../config/conf'
4
import { AppStore } from '../features/redux/store'
5

    
6
let store: AppStore // this will get injected in index.tsx
7

    
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
            // @ts-ignore (axios typescript types are a crime and this will always be defined)
27
            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

    
43
        // 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
        // If the error is not a 401 reject this
50
        if (err.response.status !== 401) {
51
            return Promise.reject(err)
52
        }
53

    
54
        // 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
            const refreshInstance = createBaseInstance()
65
            // @ts-ignore
66
            refreshInstance.headers['Authorization'] = oldRefreshToken as string
67

    
68
            // Set this to retry the request that failed
69
            originalConfig.retry = true
70

    
71
            // Send the request
72
            const { data } = await axiosInstance.get('/users/refreshToken')
73
            const { accessToken, refreshToken } = data
74

    
75
            // Set the new tokens
76
            store.dispatch({
77
                type: 'user/refreshTokens',
78
                payload: { accessToken, refreshToken },
79
            })
80

    
81
            // Return the failed instance so it can retry
82
            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
            originalConfig.retry = false // do not retry we are logged out
87
            return originalConfig
88
        }
89
    }
90
)
91

    
92
export default axiosInstance
    (1-1/1)