accounts-frontend/src/components/user/actions.js

151 lines
4.0 KiB
JavaScript
Raw Normal View History

2016-05-01 16:01:40 +05:30
import { routeActions } from 'react-router-redux';
2016-02-26 11:55:47 +05:30
import request from 'services/request';
import accounts from 'services/api/accounts';
2016-05-20 01:11:43 +05:30
import { setLocale } from 'components/i18n/actions';
2016-02-26 11:55:47 +05:30
export const UPDATE = 'USER_UPDATE';
/**
* @param {string|Object} payload jwt token or user object
* @return {Object} action definition
*/
export function updateUser(payload) {
return {
type: UPDATE,
payload
};
}
2016-05-20 01:11:43 +05:30
export const CHANGE_LANG = 'USER_CHANGE_LANG';
export function changeLang(lang) {
return (dispatch, getState) => dispatch(setLocale(lang))
.then((lang) => {
const {user: {isGuest, lang: oldLang}} = getState();
if (!isGuest && oldLang !== lang) {
accounts.changeLang(lang);
}
dispatch({
type: CHANGE_LANG,
payload: {
lang
}
});
});
}
export const SET = 'USER_SET';
export function setUser(payload) {
return {
type: SET,
payload
};
}
export function logout() {
return (dispatch, getState) => {
dispatch(setUser({
lang: getState().user.lang,
isGuest: true
}));
2016-05-01 16:01:40 +05:30
dispatch(routeActions.push('/login'));
};
}
2016-02-26 11:55:47 +05:30
export function fetchUserData() {
return (dispatch, getState) =>
accounts.current()
.then((resp) => {
dispatch(updateUser(resp));
2016-05-20 01:11:43 +05:30
return dispatch(changeLang(resp.lang));
})
.catch((resp) => {
/*
{
"name": "Unauthorized",
"message": "You are requesting with an invalid credential.",
"code": 0,
"status": 401,
"type": "yii\\web\\UnauthorizedHttpException"
}
{
"name": "Unauthorized",
"message": "Token expired",
"code": 0,
"status": 401,
"type": "yii\\web\\UnauthorizedHttpException"
}
*/
if (resp && resp.status === 401) {
const {token} = getState().user;
if (resp.message === 'Token expired' && token) {
return dispatch(authenticate(token));
}
dispatch(logout());
}
});
2016-02-26 11:55:47 +05:30
}
export function changePassword({
password = '',
newPassword = '',
newRePassword = '',
logoutAll = true,
}) {
return (dispatch) =>
accounts.changePassword(
{password, newPassword, newRePassword, logoutAll}
)
.then((resp) => {
dispatch(updateUser({
shouldChangePassword: false
}));
return resp;
})
;
}
import authentication from 'services/api/authentication';
export function authenticate(token, refreshToken) { // TODO: this action, probably, belongs to components/auth
const jwt = getJWTPayload(token);
return (dispatch, getState) => {
refreshToken = refreshToken || getState().user.refreshToken;
if (jwt.exp < Date.now() / 1000) {
return authentication.refreshToken(refreshToken)
.then((resp) => dispatch(authenticate(resp.access_token)))
.catch(() => dispatch(logout()));
}
request.setAuthToken(token);
return dispatch(fetchUserData()).then((resp) => {
dispatch(updateUser({
isGuest: false,
token,
refreshToken
}));
return resp;
});
};
}
function getJWTPayload(jwt) {
const parts = (jwt || '').split('.');
if (parts.length !== 3) {
throw new Error('Invalid jwt token');
}
try {
return JSON.parse(atob(parts[1]));
} catch (err) {
throw new Error('Can not decode jwt token');
}
}