import { all, call, put, takeLatest } from '@redux-saga/core/effects'; import { decodeToken } from 'react-jwt'; import history from '../utils/history'; import { AUTHENTICATE_USER, LOGIN_USER_FETCH, LOGOUT_USER, REFRESH_TOKEN, GENERATE_TOKEN, } from '../actions/login/loginActionConstants'; import { attemptLogin, logoutUserRequest, refreshTokenRequest, generateTokenRequest, } from '../../request/loginRequest'; import { fetchUserError, fetchUserSuccess, resetLoginState, updateUserToken, } from '../actions/login/loginActions'; import { LOGIN_PAGE } from '../../constants/pages'; import { setUser } from '../actions/user/userActions'; import { addHeaderToken, removeHeaderToken, } from '../../request'; import { IMPERSONATE_USER_UID, REGISTRATION_USER_UID, } from '../../constants/sessionStorage'; import { JWT_REFRESH_TOKEN, JWT_TOKEN, REFRESH_TOKEN_CONST, } from '../../constants/localStorage'; import { authScopeClearHelper, authScopeStringGetHelper, authScopeRemoveHelper, authScopeSetHelper, } from '../../util/helpers/authScopeHelpers'; import { rejectErrorCodeHelper } from '../../util/helpers/rejectErrorCodeHelper'; function* fetchUser({ payload }) { try { const { data } = yield call(attemptLogin, payload); if (data.JwtToken) { const user = decodeToken(data.JwtToken); yield call(authScopeSetHelper, JWT_TOKEN, data.JwtToken); yield call(authScopeSetHelper, JWT_REFRESH_TOKEN, data.JwtRefreshToken); yield call(authScopeSetHelper, REFRESH_TOKEN_CONST, data.RefreshToken); yield call(addHeaderToken, data.JwtToken); yield put(setUser(user)); } yield put(fetchUserSuccess(data)); if (payload.handleApiResponseSuccess) { yield call(payload.handleApiResponseSuccess); } } catch (e) { if (e.response && e.response.data) { if (payload.handleApiResponseSuccess) { yield call(payload.handleApiResponseSuccess); } const errorMessage = yield call(rejectErrorCodeHelper, e); yield put(fetchUserError(errorMessage)); } } } function* authenticateUser() { try { const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); if (!JwtToken) { yield call(history.push, LOGIN_PAGE); } return yield put( fetchUserSuccess({ JwtToken, }), ); } catch (error) { const errorMessage = yield call(rejectErrorCodeHelper, error); yield put(fetchUserError(errorMessage)); yield call(authScopeRemoveHelper, JWT_TOKEN); yield call(authScopeRemoveHelper, JWT_REFRESH_TOKEN); yield call(authScopeRemoveHelper, REFRESH_TOKEN_CONST); } } function* logoutUser() { try { const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); const user = decodeToken(JwtToken); if (user) { yield call(logoutUserRequest, user.UserUid); } } catch (error) { console.log(error); // eslint-disable-line } finally { yield call(authScopeClearHelper); yield call(removeHeaderToken); yield put(resetLoginState()); yield call(history.replace, LOGIN_PAGE); } } export function* refreshToken() { try { const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); const JwtRefreshToken = yield call( authScopeStringGetHelper, JWT_REFRESH_TOKEN, ); if (JwtToken && JwtRefreshToken) { const { data } = yield call(refreshTokenRequest, { JwtRefreshToken, JwtToken, }); yield call(authScopeSetHelper, JWT_TOKEN, data.JwtToken); yield call(authScopeSetHelper, JWT_REFRESH_TOKEN, data.JwtRefreshToken); const user = decodeToken(data.JwtToken); addHeaderToken(data.JwtToken); yield put(setUser(user)); yield put(updateUserToken(data.JwtToken)); } } catch (error) { yield call(logoutUser); console.log(error); // eslint-disable-line } } export function* generateToken({ payload }) { try { const { data } = yield call(generateTokenRequest, payload.data); const { JwtToken, JwtRefreshToken } = data; if (JwtToken && JwtRefreshToken) { yield call(authScopeSetHelper, JWT_TOKEN, data.JwtToken); yield call(authScopeSetHelper, JWT_REFRESH_TOKEN, data.JwtRefreshToken); if (payload.impersonate) { sessionStorage.setItem(IMPERSONATE_USER_UID, payload.accountUid); } if (payload.registration) { sessionStorage.setItem(REGISTRATION_USER_UID, payload.accountUid); } const user = decodeToken(data.JwtToken); addHeaderToken(data.JwtToken); if (user) { yield put(setUser(user)); } yield put(updateUserToken(data.JwtToken)); if (payload.onSuccess) { yield call(payload.onSuccess); } } } catch (error) { yield call(logoutUser); console.log(error); // eslint-disable-line } } export default function* loginSaga() { yield all([ takeLatest(LOGIN_USER_FETCH, fetchUser), takeLatest(AUTHENTICATE_USER, authenticateUser), takeLatest(LOGOUT_USER, logoutUser), takeLatest(REFRESH_TOKEN, refreshToken), takeLatest(GENERATE_TOKEN, generateToken), ]); }