· 5 years ago · Dec 22, 2020, 12:42 PM
1export function setupAxios(axios, store) {
2 axios.interceptors.request.use(
3 config => {
4 const {
5 auth: {access}
6 } = store.getState();
7
8 if (access) {
9 config.headers.Authorization = `Bearer ${access}`;
10 }
11
12 return config;
13 },
14 err => Promise.reject(err)
15 );
16
17 axios.interceptors.response.use((response) => {
18 return response
19 },
20 (err) => {
21 const originalRequest = err.config;
22
23 const {
24 auth: {refresh}
25 } = store.getState();
26
27 if (err.response.status === 401 && originalRequest.url === REFRESH_TOKEN_URL) {
28 // redirect to login page
29 store.dispatch({
30 type: auth.actionTypes.Logout
31 });
32 history.push('/login');
33 return Promise.reject(err);
34 }
35
36 if (err.response.status === 401 && !originalRequest._retry) {
37 originalRequest._retry = true;
38 return axios.post(REFRESH_TOKEN_URL, {refresh: refresh})
39 .then(res => {
40 if (res.status === 200) {
41 store.dispatch({
42 type: auth.actionTypes.RefreshToken,
43 payload: res.data
44 });
45 axios.defaults.headers.common['Authorization'] = 'Bearer' + res.data
46 return axios(originalRequest);
47 }
48 })
49 }
50 return Promise.reject(err);
51 })
52}
53
54
55
56import {persistReducer} from "redux-persist";
57import storage from "redux-persist/lib/storage";
58import {takeLatest} from "redux-saga/effects";
59import * as routerHelpers from "../../router/RouterHelpers";
60import {toAbsoluteUrl} from "../../../_metronic/utils/utils";
61import {put} from "@redux-saga/core/effects";
62
63export const actionTypes = {
64 Login: "[Login] Action",
65 Logout: "[Logout] Action",
66 UserLoaded: "[Load User] Auth API",
67 RefreshToken: "[JWT] Refresh Token"
68};
69
70const initialAuthState = {
71 user: undefined,
72 refresh: undefined,
73 access: undefined,
74 appBuildVersion: ''
75};
76
77export const reducer = persistReducer(
78 { storage, key: "sap-auth" },
79 (state = initialAuthState, action) => {
80 switch (action.type) {
81 case actionTypes.Login: {
82 return action.payload.user
83 }
84
85 case actionTypes.Logout: {
86 routerHelpers.forgotLastLocation();
87 return initialAuthState;
88 }
89
90 case actionTypes.UserLoaded: {
91 const { user, access, refresh, appBuildVersion } = action.payload;
92 if (typeof user.pic === 'undefined')
93 user.pic = toAbsoluteUrl("/media/users/default.jpg")
94 return { ...state, user, access, refresh, appBuildVersion };
95 }
96
97 case actionTypes.RefreshToken: {
98 const {access} = action.payload;
99 return {...state, access: access};
100 }
101
102
103 default:
104 return state;
105 }
106 }
107);
108
109export const actions = {
110 login: user => ({ type: actionTypes.Login, payload: { user } }),
111 logout: () => ({ type: actionTypes.Logout }),
112 fulfillUser: (user, access, refresh, appBuildVersion) => ({ type: actionTypes.UserLoaded, payload: { user, access, refresh, appBuildVersion } }),
113};
114
115export function* saga() {
116 yield takeLatest(actionTypes.Login, function* loginSaga(data) {
117 const { user } = data.payload;
118
119 const version = `${process.env.REACT_APP_RELEASE_VERSION}`
120 yield put(actions.fulfillUser(user.user, user.access, user.refresh, version));
121 });
122}
123