mirror of
https://github.com/elyby/accounts-frontend.git
synced 2025-03-07 00:09:13 +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 authentication from 'services/api/authentication';
|
||||||
import accounts from 'services/api/accounts';
|
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 { setLocale } from 'components/i18n/actions';
|
||||||
import logger from 'services/logger';
|
import logger from 'services/logger';
|
||||||
|
|
||||||
@ -25,7 +27,7 @@ export function authenticate({token, refreshToken}) {
|
|||||||
authentication.validateToken({token, refreshToken})
|
authentication.validateToken({token, refreshToken})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
// TODO: log this case
|
// TODO: log this case
|
||||||
dispatch(logout());
|
dispatch(logoutAll());
|
||||||
|
|
||||||
return Promise.reject();
|
return Promise.reject();
|
||||||
})
|
})
|
||||||
@ -80,17 +82,23 @@ export function revoke(account) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return dispatch(logout());
|
return dispatch(logoutAll());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function logoutAll() {
|
export function logoutAll() {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
|
dispatch(setGuest());
|
||||||
|
|
||||||
const {accounts: {available}} = getState();
|
const {accounts: {available}} = getState();
|
||||||
|
|
||||||
available.forEach((account) => authentication.logout(account));
|
available.forEach((account) => authentication.logout(account));
|
||||||
|
|
||||||
dispatch(reset());
|
dispatch(reset());
|
||||||
|
|
||||||
|
dispatch(routeActions.push('/login'));
|
||||||
|
|
||||||
|
return Promise.resolve();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +128,7 @@ export function logoutStrangers() {
|
|||||||
return dispatch(authenticate(accountToReplace));
|
return dispatch(authenticate(accountToReplace));
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch(logout());
|
dispatch(logoutAll());
|
||||||
|
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
};
|
};
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
import { routeActions } from 'react-router-redux';
|
import { routeActions } from 'react-router-redux';
|
||||||
|
|
||||||
import { updateUser, logout, acceptRules as userAcceptRules } from 'components/user/actions';
|
import logger from 'services/logger';
|
||||||
import { authenticate } from 'components/accounts/actions';
|
import { updateUser, acceptRules as userAcceptRules } from 'components/user/actions';
|
||||||
|
import { authenticate, logoutAll } from 'components/accounts/actions';
|
||||||
import authentication from 'services/api/authentication';
|
import authentication from 'services/api/authentication';
|
||||||
import oauth from 'services/api/oauth';
|
import oauth from 'services/api/oauth';
|
||||||
import signup from 'services/api/signup';
|
import signup from 'services/api/signup';
|
||||||
import dispatchBsod from 'components/ui/bsod/dispatchBsod';
|
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}) {
|
export function login({login = '', password = '', rememberMe = false}) {
|
||||||
const PASSWORD_REQUIRED = 'error.password_required';
|
const PASSWORD_REQUIRED = 'error.password_required';
|
||||||
const LOGIN_REQUIRED = 'error.login_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) {
|
} else if (resp.errors.login === ACTIVATION_REQUIRED) {
|
||||||
return dispatch(needActivation());
|
return dispatch(needActivation());
|
||||||
} else if (resp.errors.login === LOGIN_REQUIRED && password) {
|
} else if (resp.errors.login === LOGIN_REQUIRED && password) {
|
||||||
// TODO: log this case to backend
|
logger.warn('No login on password panel');
|
||||||
// return to the first step
|
|
||||||
return dispatch(logout());
|
return dispatch(logoutAll());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,9 +148,6 @@ export function clearErrors() {
|
|||||||
return setErrors(null);
|
return setErrors(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
export { logout, updateUser } from 'components/user/actions';
|
|
||||||
export { authenticate } from 'components/accounts/actions';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {object} oauthData
|
* @param {object} oauthData
|
||||||
* @param {string} oauthData.clientId
|
* @param {string} oauthData.clientId
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
import { routeActions } from 'react-router-redux';
|
|
||||||
|
|
||||||
import accounts from 'services/api/accounts';
|
import accounts from 'services/api/accounts';
|
||||||
import { logoutAll } from 'components/accounts/actions';
|
|
||||||
import { setLocale } from 'components/i18n/actions';
|
import { setLocale } from 'components/i18n/actions';
|
||||||
|
|
||||||
export const UPDATE = 'USER_UPDATE';
|
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 const CHANGE_LANG = 'USER_CHANGE_LANG';
|
||||||
export function changeLang(lang) {
|
export function changeLang(lang) {
|
||||||
return (dispatch, getState) => dispatch(setLocale(lang))
|
return (dispatch, getState) => dispatch(setLocale(lang))
|
||||||
@ -37,32 +48,12 @@ export function changeLang(lang) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SET = 'USER_SET';
|
export function setGuest() {
|
||||||
/**
|
|
||||||
* 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() {
|
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
dispatch(setUser({
|
dispatch(setUser({
|
||||||
lang: getState().user.lang,
|
lang: getState().user.lang,
|
||||||
isGuest: true
|
isGuest: true
|
||||||
}));
|
}));
|
||||||
|
|
||||||
dispatch(logoutAll());
|
|
||||||
|
|
||||||
dispatch(routeActions.push('/login'));
|
|
||||||
|
|
||||||
return Promise.resolve();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import authentication from 'services/api/authentication';
|
import authentication from 'services/api/authentication';
|
||||||
import { updateToken } from 'components/accounts/actions';
|
import logger from 'services/logger';
|
||||||
import { logout } from '../actions';
|
import { updateToken, logoutAll } from 'components/accounts/actions';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures, that all user's requests have fresh access token
|
* 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);
|
return requestAccessToken(refreshToken, dispatch).then(() => req);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// console.error('Bad token', err); // TODO: it would be cool to log such things to backend
|
logger.warn('Refresh token error: bad token', {
|
||||||
return dispatch(logout()).then(() => req);
|
token
|
||||||
|
});
|
||||||
|
|
||||||
|
return dispatch(logoutAll()).then(() => req);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.resolve(req);
|
return Promise.resolve(req);
|
||||||
@ -58,7 +61,7 @@ export default function refreshTokenMiddleware({dispatch, getState}) {
|
|||||||
return requestAccessToken(refreshToken, dispatch).then(restart);
|
return requestAccessToken(refreshToken, dispatch).then(restart);
|
||||||
}
|
}
|
||||||
|
|
||||||
return dispatch(logout()).then(() => Promise.reject(resp));
|
return dispatch(logoutAll()).then(() => Promise.reject(resp));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.reject(resp);
|
return Promise.reject(resp);
|
||||||
@ -76,7 +79,7 @@ function requestAccessToken(refreshToken, dispatch) {
|
|||||||
|
|
||||||
return promise
|
return promise
|
||||||
.then(({token}) => dispatch(updateToken(token)))
|
.then(({token}) => dispatch(updateToken(token)))
|
||||||
.catch(() => dispatch(logout()));
|
.catch(() => dispatch(logoutAll()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import expect from 'unexpected';
|
import expect from 'unexpected';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
|
|
||||||
|
import { routeActions } from 'react-router-redux';
|
||||||
|
|
||||||
import accounts from 'services/api/accounts';
|
import accounts from 'services/api/accounts';
|
||||||
import authentication from 'services/api/authentication';
|
import authentication from 'services/api/authentication';
|
||||||
import {
|
import {
|
||||||
@ -15,7 +17,7 @@ import {
|
|||||||
} from 'components/accounts/actions';
|
} from 'components/accounts/actions';
|
||||||
import { SET_LOCALE } from 'components/i18n/actions';
|
import { SET_LOCALE } from 'components/i18n/actions';
|
||||||
|
|
||||||
import { updateUser } from 'components/user/actions';
|
import { updateUser, setUser } from 'components/user/actions';
|
||||||
|
|
||||||
const account = {
|
const account = {
|
||||||
id: 1,
|
id: 1,
|
||||||
@ -257,6 +259,25 @@ describe('components/accounts/actions', () => {
|
|||||||
reset()
|
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', () => {
|
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', () => {
|
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…
x
Reference in New Issue
Block a user