mirror of
https://github.com/elyby/accounts-frontend.git
synced 2024-11-27 01:02:14 +05:30
#246: remove logout from user/actions. Use logoutAll from account/actions everywhere
This commit is contained in:
parent
8e06adbf21
commit
274c28a923
@ -1,6 +1,8 @@
|
||||
import { routeActions } from 'react-router-redux';
|
||||
|
||||
import authentication from 'services/api/authentication';
|
||||
import accounts from 'services/api/accounts';
|
||||
import { updateUser, logout } from 'components/user/actions';
|
||||
import { updateUser, setGuest } from 'components/user/actions';
|
||||
import { setLocale } from 'components/i18n/actions';
|
||||
import logger from 'services/logger';
|
||||
|
||||
@ -25,7 +27,7 @@ export function authenticate({token, refreshToken}) {
|
||||
authentication.validateToken({token, refreshToken})
|
||||
.catch(() => {
|
||||
// TODO: log this case
|
||||
dispatch(logout());
|
||||
dispatch(logoutAll());
|
||||
|
||||
return Promise.reject();
|
||||
})
|
||||
@ -80,17 +82,23 @@ export function revoke(account) {
|
||||
});
|
||||
}
|
||||
|
||||
return dispatch(logout());
|
||||
return dispatch(logoutAll());
|
||||
};
|
||||
}
|
||||
|
||||
export function logoutAll() {
|
||||
return (dispatch, getState) => {
|
||||
dispatch(setGuest());
|
||||
|
||||
const {accounts: {available}} = getState();
|
||||
|
||||
available.forEach((account) => authentication.logout(account));
|
||||
|
||||
dispatch(reset());
|
||||
|
||||
dispatch(routeActions.push('/login'));
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
}
|
||||
|
||||
@ -120,7 +128,7 @@ export function logoutStrangers() {
|
||||
return dispatch(authenticate(accountToReplace));
|
||||
}
|
||||
|
||||
dispatch(logout());
|
||||
dispatch(logoutAll());
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
@ -1,12 +1,16 @@
|
||||
import { routeActions } from 'react-router-redux';
|
||||
|
||||
import { updateUser, logout, acceptRules as userAcceptRules } from 'components/user/actions';
|
||||
import { authenticate } from 'components/accounts/actions';
|
||||
import logger from 'services/logger';
|
||||
import { updateUser, acceptRules as userAcceptRules } from 'components/user/actions';
|
||||
import { authenticate, logoutAll } from 'components/accounts/actions';
|
||||
import authentication from 'services/api/authentication';
|
||||
import oauth from 'services/api/oauth';
|
||||
import signup from 'services/api/signup';
|
||||
import dispatchBsod from 'components/ui/bsod/dispatchBsod';
|
||||
|
||||
export { updateUser } from 'components/user/actions';
|
||||
export { authenticate, logoutAll as logout } from 'components/accounts/actions';
|
||||
|
||||
export function login({login = '', password = '', rememberMe = false}) {
|
||||
const PASSWORD_REQUIRED = 'error.password_required';
|
||||
const LOGIN_REQUIRED = 'error.login_required';
|
||||
@ -24,9 +28,9 @@ export function login({login = '', password = '', rememberMe = false}) {
|
||||
} else if (resp.errors.login === ACTIVATION_REQUIRED) {
|
||||
return dispatch(needActivation());
|
||||
} else if (resp.errors.login === LOGIN_REQUIRED && password) {
|
||||
// TODO: log this case to backend
|
||||
// return to the first step
|
||||
return dispatch(logout());
|
||||
logger.warn('No login on password panel');
|
||||
|
||||
return dispatch(logoutAll());
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,9 +148,6 @@ export function clearErrors() {
|
||||
return setErrors(null);
|
||||
}
|
||||
|
||||
export { logout, updateUser } from 'components/user/actions';
|
||||
export { authenticate } from 'components/accounts/actions';
|
||||
|
||||
/**
|
||||
* @param {object} oauthData
|
||||
* @param {string} oauthData.clientId
|
||||
|
@ -1,7 +1,4 @@
|
||||
import { routeActions } from 'react-router-redux';
|
||||
|
||||
import accounts from 'services/api/accounts';
|
||||
import { logoutAll } from 'components/accounts/actions';
|
||||
import { setLocale } from 'components/i18n/actions';
|
||||
|
||||
export const UPDATE = 'USER_UPDATE';
|
||||
@ -18,6 +15,20 @@ export function updateUser(payload) {
|
||||
};
|
||||
}
|
||||
|
||||
export const SET = 'USER_SET';
|
||||
/**
|
||||
* Replace current user's state with a new one
|
||||
*
|
||||
* @param {User} payload
|
||||
* @return {object} - action definition
|
||||
*/
|
||||
export function setUser(payload) {
|
||||
return {
|
||||
type: SET,
|
||||
payload
|
||||
};
|
||||
}
|
||||
|
||||
export const CHANGE_LANG = 'USER_CHANGE_LANG';
|
||||
export function changeLang(lang) {
|
||||
return (dispatch, getState) => dispatch(setLocale(lang))
|
||||
@ -37,32 +48,12 @@ export function changeLang(lang) {
|
||||
});
|
||||
}
|
||||
|
||||
export const SET = 'USER_SET';
|
||||
/**
|
||||
* Replace current user's state with a new one
|
||||
*
|
||||
* @param {User} payload
|
||||
* @return {object} - action definition
|
||||
*/
|
||||
export function setUser(payload) {
|
||||
return {
|
||||
type: SET,
|
||||
payload
|
||||
};
|
||||
}
|
||||
|
||||
export function logout() {
|
||||
export function setGuest() {
|
||||
return (dispatch, getState) => {
|
||||
dispatch(setUser({
|
||||
lang: getState().user.lang,
|
||||
isGuest: true
|
||||
}));
|
||||
|
||||
dispatch(logoutAll());
|
||||
|
||||
dispatch(routeActions.push('/login'));
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import authentication from 'services/api/authentication';
|
||||
import { updateToken } from 'components/accounts/actions';
|
||||
import { logout } from '../actions';
|
||||
import logger from 'services/logger';
|
||||
import { updateToken, logoutAll } from 'components/accounts/actions';
|
||||
|
||||
/**
|
||||
* Ensures, that all user's requests have fresh access token
|
||||
@ -41,8 +41,11 @@ export default function refreshTokenMiddleware({dispatch, getState}) {
|
||||
return requestAccessToken(refreshToken, dispatch).then(() => req);
|
||||
}
|
||||
} catch (err) {
|
||||
// console.error('Bad token', err); // TODO: it would be cool to log such things to backend
|
||||
return dispatch(logout()).then(() => req);
|
||||
logger.warn('Refresh token error: bad token', {
|
||||
token
|
||||
});
|
||||
|
||||
return dispatch(logoutAll()).then(() => req);
|
||||
}
|
||||
|
||||
return Promise.resolve(req);
|
||||
@ -58,7 +61,7 @@ export default function refreshTokenMiddleware({dispatch, getState}) {
|
||||
return requestAccessToken(refreshToken, dispatch).then(restart);
|
||||
}
|
||||
|
||||
return dispatch(logout()).then(() => Promise.reject(resp));
|
||||
return dispatch(logoutAll()).then(() => Promise.reject(resp));
|
||||
}
|
||||
|
||||
return Promise.reject(resp);
|
||||
@ -76,7 +79,7 @@ function requestAccessToken(refreshToken, dispatch) {
|
||||
|
||||
return promise
|
||||
.then(({token}) => dispatch(updateToken(token)))
|
||||
.catch(() => dispatch(logout()));
|
||||
.catch(() => dispatch(logoutAll()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
import expect from 'unexpected';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import { routeActions } from 'react-router-redux';
|
||||
|
||||
import accounts from 'services/api/accounts';
|
||||
import authentication from 'services/api/authentication';
|
||||
import {
|
||||
@ -15,7 +17,7 @@ import {
|
||||
} from 'components/accounts/actions';
|
||||
import { SET_LOCALE } from 'components/i18n/actions';
|
||||
|
||||
import { updateUser } from 'components/user/actions';
|
||||
import { updateUser, setUser } from 'components/user/actions';
|
||||
|
||||
const account = {
|
||||
id: 1,
|
||||
@ -257,6 +259,25 @@ describe('components/accounts/actions', () => {
|
||||
reset()
|
||||
]);
|
||||
});
|
||||
|
||||
it('should redirect to /login', () =>
|
||||
logoutAll()(dispatch, getState).then(() => {
|
||||
expect(dispatch, 'to have a call satisfying', [
|
||||
routeActions.push('/login')
|
||||
]);
|
||||
})
|
||||
);
|
||||
|
||||
it('should change user to guest', () =>
|
||||
logoutAll()(dispatch, getState).then(() => {
|
||||
expect(dispatch, 'to have a call satisfying', [
|
||||
setUser({
|
||||
lang: user.lang,
|
||||
isGuest: true
|
||||
})
|
||||
]);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
describe('#logoutStrangers', () => {
|
||||
|
@ -1,134 +1,2 @@
|
||||
import expect from 'unexpected';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import { routeActions } from 'react-router-redux';
|
||||
|
||||
import request from 'services/request';
|
||||
import { reset, RESET } from 'components/accounts/actions';
|
||||
|
||||
import {
|
||||
logout,
|
||||
setUser
|
||||
} from 'components/user/actions';
|
||||
|
||||
|
||||
describe('components/user/actions', () => {
|
||||
const getState = sinon.stub().named('store.getState');
|
||||
const dispatch = sinon.spy((arg) =>
|
||||
typeof arg === 'function' ? arg(dispatch, getState) : arg
|
||||
).named('store.dispatch');
|
||||
|
||||
const callThunk = function(fn, ...args) {
|
||||
const thunk = fn(...args);
|
||||
|
||||
return thunk(dispatch, getState);
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
dispatch.reset();
|
||||
getState.reset();
|
||||
getState.returns({});
|
||||
sinon.stub(request, 'get').named('request.get');
|
||||
sinon.stub(request, 'post').named('request.post');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
request.get.restore();
|
||||
request.post.restore();
|
||||
});
|
||||
|
||||
describe('#logout()', () => {
|
||||
beforeEach(() => {
|
||||
request.post.returns(Promise.resolve());
|
||||
});
|
||||
|
||||
describe('user with jwt', () => {
|
||||
const token = 'iLoveRockNRoll';
|
||||
|
||||
beforeEach(() => {
|
||||
getState.returns({
|
||||
user: {
|
||||
lang: 'foo'
|
||||
},
|
||||
accounts: {
|
||||
active: {token},
|
||||
available: [{token}]
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should post to /api/authentication/logout with user jwt', () =>
|
||||
callThunk(logout).then(() => {
|
||||
expect(request.post, 'to have a call satisfying', [
|
||||
'/api/authentication/logout', {}, {
|
||||
token: expect.it('not to be empty')
|
||||
}
|
||||
]);
|
||||
})
|
||||
);
|
||||
|
||||
testChangedToGuest();
|
||||
testAccountsReset();
|
||||
testRedirectedToLogin();
|
||||
});
|
||||
|
||||
describe('user without jwt', () => {
|
||||
// (a guest with partially filled user's state)
|
||||
// DEPRECATED
|
||||
beforeEach(() => {
|
||||
getState.returns({
|
||||
user: {
|
||||
lang: 'foo'
|
||||
},
|
||||
accounts: {
|
||||
active: null,
|
||||
available: []
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should not post to /api/authentication/logout', () =>
|
||||
callThunk(logout).then(() => {
|
||||
expect(request.post, 'was not called');
|
||||
})
|
||||
);
|
||||
|
||||
testChangedToGuest();
|
||||
testAccountsReset();
|
||||
testRedirectedToLogin();
|
||||
});
|
||||
|
||||
function testChangedToGuest() {
|
||||
it('should change user to guest', () =>
|
||||
callThunk(logout).then(() => {
|
||||
expect(dispatch, 'to have a call satisfying', [
|
||||
setUser({
|
||||
lang: 'foo',
|
||||
isGuest: true
|
||||
})
|
||||
]);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function testRedirectedToLogin() {
|
||||
it('should redirect to /login', () =>
|
||||
callThunk(logout).then(() => {
|
||||
expect(dispatch, 'to have a call satisfying', [
|
||||
routeActions.push('/login')
|
||||
]);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function testAccountsReset() {
|
||||
it(`should dispatch ${RESET}`, () =>
|
||||
callThunk(logout).then(() => {
|
||||
expect(dispatch, 'to have a call satisfying', [
|
||||
reset()
|
||||
]);
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user