#188: persist oauth data if if user tries to register during oauth

This commit is contained in:
SleepWalker 2016-08-11 22:20:14 +03:00
parent a504981407
commit a20b7ec3d4
3 changed files with 74 additions and 14 deletions

View File

@ -142,12 +142,18 @@ export function oAuthValidate(oauthData) {
dispatch(setClient(resp.client)); dispatch(setClient(resp.client));
dispatch(setOAuthRequest(resp.oAuth)); dispatch(setOAuthRequest(resp.oAuth));
dispatch(setScopes(resp.session.scopes)); dispatch(setScopes(resp.session.scopes));
localStorage.setItem('oauthData', JSON.stringify({ // @see services/authFlow/AuthFlow
timestamp: Date.now(),
payload: oauthData
}));
}) })
.catch(handleOauthParamsValidation) .catch(handleOauthParamsValidation)
); );
} }
export function oAuthComplete(params = {}) { export function oAuthComplete(params = {}) {
localStorage.removeItem('oauthData');
return wrapInLoader((dispatch, getState) => return wrapInLoader((dispatch, getState) =>
oauth.complete(getState().auth.oauth, params) oauth.complete(getState().auth.oauth, params)
.then((resp) => { .then((resp) => {

View File

@ -8,8 +8,6 @@ import RecoverPasswordState from './RecoverPasswordState';
import ActivationState from './ActivationState'; import ActivationState from './ActivationState';
import ResendActivationState from './ResendActivationState'; import ResendActivationState from './ResendActivationState';
// TODO: a way to unload service (when we are on account page)
export default class AuthFlow { export default class AuthFlow {
constructor(actions) { constructor(actions) {
if (typeof actions !== 'object') { if (typeof actions !== 'object') {
@ -41,6 +39,8 @@ export default class AuthFlow {
this.getState = store.getState.bind(store); this.getState = store.getState.bind(store);
this.dispatch = store.dispatch.bind(store); this.dispatch = store.dispatch.bind(store);
this.restoreOAuthState();
} }
resolve(payload = {}) { resolve(payload = {}) {
@ -131,11 +131,6 @@ export default class AuthFlow {
this.currentRequest = request; this.currentRequest = request;
if (path === '/') {
// reset oauth data if user tried to navigate to index route
this.run('setOAuthRequest', {});
}
switch (path) { switch (path) {
case '/register': case '/register':
this.setState(new RegisterState()); this.setState(new RegisterState());
@ -179,4 +174,17 @@ export default class AuthFlow {
this.onReady(); this.onReady();
} }
/**
* @api private
*/
restoreOAuthState() {
try {
const data = JSON.parse(localStorage.getItem('oauthData'));
if (Date.now() - data.timestamp < 60 * 60 * 1000) {
this.run('oAuthValidate', data.payload);
}
} catch (err) {/* bad luck :( */}
}
} }

View File

@ -33,6 +33,59 @@ describe('AuthFlow', () => {
expect(() => flow.actions.test = 'hacked', 'to throw', /readonly/); expect(() => flow.actions.test = 'hacked', 'to throw', /readonly/);
}); });
describe('#setStore', () => {
afterEach(() => {
localStorage.removeItem('oauthData');
});
it('should create #navigate, #getState, #dispatch', () => {
flow.setStore({
getState() {},
dispatch() {}
});
expect(flow.getState, 'to be defined');
expect(flow.dispatch, 'to be defined');
expect(flow.navigate, 'to be defined');
});
it('should restore oauth state from localStorage', () => {
const oauthData = {};
localStorage.setItem('oauthData', JSON.stringify({
timestamp: Date.now() - 10,
payload: oauthData
}));
sinon.stub(flow, 'run').named('flow.run');
flow.setStore({
getState() {},
dispatch() {}
});
expect(flow.run, 'to have a call satisfying', [
'oAuthValidate', oauthData
]);
});
it('should not restore outdated (>1h) oauth state', () => {
const oauthData = {};
localStorage.setItem('oauthData', JSON.stringify({
timestamp: Date.now() - 60 * 60 * 1000,
payload: oauthData
}));
sinon.stub(flow, 'run').named('flow.run');
flow.setStore({
getState() {},
dispatch() {}
});
expect(flow.run, 'was not called');
});
});
describe('#setState', () => { describe('#setState', () => {
it('should change state', () => { it('should change state', () => {
const state = new AbstractState(); const state = new AbstractState();
@ -198,13 +251,6 @@ describe('AuthFlow', () => {
}); });
}); });
it('should run setOAuthRequest if /', () => {
flow.handleRequest({path: '/'});
expect(flow.run, 'was called once');
expect(flow.run, 'to have a call satisfying', ['setOAuthRequest', {}]);
});
it('should call callback', () => { it('should call callback', () => {
const callback = sinon.stub().named('callback'); const callback = sinon.stub().named('callback');