From b3cd09ba003e4194745c25187d00fb6427d934a9 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 20 Jul 2016 01:31:07 -0300 Subject: [PATCH] Ivan - Update remember logic using local storage [skip ci] --- client/src/app/index.js | 8 ++- .../app/main/dashboard/dashboard-layout.js | 4 +- client/src/data/fixtures/user-fixtures.js | 14 ++++- client/src/lib-app/api-call.js | 19 +++--- client/src/lib-app/date.js | 10 +++ client/src/lib-app/local-store.js | 54 ---------------- client/src/lib-app/session-store.js | 40 ++++++++++-- client/src/stores/user-store.js | 61 +++++++++++-------- server/controllers/user/check-session.php | 20 ++++++ 9 files changed, 135 insertions(+), 95 deletions(-) create mode 100644 client/src/lib-app/date.js delete mode 100644 client/src/lib-app/local-store.js create mode 100644 server/controllers/user/check-session.php diff --git a/client/src/app/index.js b/client/src/app/index.js index 7a01f3da..e4bec24b 100644 --- a/client/src/app/index.js +++ b/client/src/app/index.js @@ -1,6 +1,7 @@ import React from 'react'; import {render} from 'react-dom' import Router from 'react-router'; +import UserStore from 'stores/user-store'; import routes from './Routes'; @@ -13,4 +14,9 @@ if (noFixtures === 'disabled') { require('lib-app/fixtures-loader'); } -render(routes, document.getElementById('app')); +let onSessionInit = function () { + render(routes, document.getElementById('app')); +}; + +UserStore.initSession().then(onSessionInit, onSessionInit); + diff --git a/client/src/app/main/dashboard/dashboard-layout.js b/client/src/app/main/dashboard/dashboard-layout.js index d8bfa4bd..f7e13d1b 100644 --- a/client/src/app/main/dashboard/dashboard-layout.js +++ b/client/src/app/main/dashboard/dashboard-layout.js @@ -14,12 +14,12 @@ const DashboardLayout = React.createClass({ }, render() { - return ( + return (UserStore.isLoggedIn()) ? (
{this.props.children}
- ); + ) : null; } }); diff --git a/client/src/data/fixtures/user-fixtures.js b/client/src/data/fixtures/user-fixtures.js index 1f63652c..fe8be0c0 100644 --- a/client/src/data/fixtures/user-fixtures.js +++ b/client/src/data/fixtures/user-fixtures.js @@ -27,12 +27,24 @@ module.exports = [ }, { path: 'user/logout', - time: 1000, + time: 100, response: function () { return { status: 'success', data: {} }; } + }, + { + path: 'user/check-session', + time: 100, + response: function () { + return { + status: 'success', + data: { + sessionActive: true + } + }; + } } ]; diff --git a/client/src/lib-app/api-call.js b/client/src/lib-app/api-call.js index 49228397..89d26ce1 100644 --- a/client/src/lib-app/api-call.js +++ b/client/src/lib-app/api-call.js @@ -9,14 +9,17 @@ function processData (data) { } module.exports = { - call: function ({path, data, onSuccess, onFail}) { - APIUtils.post(root + path, processData(data)).then(function (result) { - console.log(result); - if (result.status === 'success') { - onSuccess && onSuccess(result); - } else { - onFail && onFail(result); - } + call: function ({path, data}) { + return new Promise(function (resolve, reject) { + APIUtils.post(root + path, processData(data)).then(function (result) { + console.log(result); + + if (result.status === 'success') { + resolve(result); + } else if (reject) { + reject(result); + } + }); }); } }; \ No newline at end of file diff --git a/client/src/lib-app/date.js b/client/src/lib-app/date.js new file mode 100644 index 00000000..f14beb2b --- /dev/null +++ b/client/src/lib-app/date.js @@ -0,0 +1,10 @@ +export default { + getCurrentDate() { + let date = new Date(); + let yyyy = date.getFullYear().toString(); + let mm = (date.getMonth()+1).toString(); // getMonth() is zero-based + let dd = date.getDate().toString(); + + return (yyyy + (mm[1]?mm:"0"+mm[0]) + (dd[1]?dd:"0"+dd[0])) * 1; + } +} \ No newline at end of file diff --git a/client/src/lib-app/local-store.js b/client/src/lib-app/local-store.js deleted file mode 100644 index 21eac775..00000000 --- a/client/src/lib-app/local-store.js +++ /dev/null @@ -1,54 +0,0 @@ -import LocalStorage from 'localStorage'; - -class LocalStore { - - constructor() { - this.storage = LocalStorage; - } - - initialize() { - if (this.isRememberDataExpired()) { - this.clearRememberData(); - } - - if (!this.getItem('language')) { - this.setItem('language', 'english'); - } - } - - storeRememberData({token, userId, expiration}) { - this.setItem('rememberData-token', token); - this.setItem('rememberData-userId', userId); - this.setItem('rememberData-expiration', expiration); - } - - isRememberDataExpired() { - let rememberData = this.getRememberData(); - - return rememberData.expiration < 2016; - } - - getRememberData() { - return { - token: this.getItem('rememberData-token'), - userId: parseInt(this.getItem('rememberData-userId')), - expiration: parseInt(this.getItem('rememberData-expiration')) - }; - } - - clearRememberData() { - this.setItem('rememberData-token', null); - this.setItem('rememberData-userId', null); - this.setItem('rememberData-expiration', null); - } - - getItem(key) { - return this.storage.getItem(key); - } - - setItem(key, value) { - return this.storage.setItem(key, value); - } -} - -export default new LocalStore(); \ No newline at end of file diff --git a/client/src/lib-app/session-store.js b/client/src/lib-app/session-store.js index 90d2ca16..f6f0bb2e 100644 --- a/client/src/lib-app/session-store.js +++ b/client/src/lib-app/session-store.js @@ -1,8 +1,13 @@ -import SessionStorage from 'sessionstorage'; +import LocalStorage from 'localStorage'; +import date from 'lib-app/date'; class SessionStore { constructor() { - this.storage = SessionStorage; + this.storage = LocalStorage; + + if (!this.getItem('language')) { + this.setItem('language', 'english'); + } } createSession(userId, token) { @@ -18,7 +23,7 @@ class SessionStore { } isLoggedIn() { - return !!this.getItem('userId'); + return !!this.getItem('token'); } closeSession() { @@ -26,6 +31,33 @@ class SessionStore { this.removeItem('token'); } + storeRememberData({token, userId, expiration}) { + this.setItem('rememberData-token', token); + this.setItem('rememberData-userId', userId); + this.setItem('rememberData-expiration', expiration); + } + + isRememberDataExpired() { + let rememberData = this.getRememberData(); + + return rememberData.expiration < date.getCurrentDate(); + } + + getRememberData() { + return { + token: this.getItem('rememberData-token'), + userId: this.getItem('rememberData-userId'), + expiration: this.getItem('rememberData-expiration') + }; + } + + clearRememberData() { + this.removeItem('rememberData-token'); + this.removeItem('rememberData-userId'); + this.removeItem('rememberData-expiration'); + } + + getItem(key) { return this.storage.getItem(key); } @@ -35,7 +67,7 @@ class SessionStore { } removeItem(key) { - return this.storage.removeItem(key); + this.storage.removeItem(key); } } diff --git a/client/src/stores/user-store.js b/client/src/stores/user-store.js index d5189ef8..213123cc 100644 --- a/client/src/stores/user-store.js +++ b/client/src/stores/user-store.js @@ -1,7 +1,6 @@ const Reflux = require('reflux'); const API = require('lib-app/api-call'); const sessionStore = require('lib-app/session-store'); -const localStore = require('lib-app/local-store'); const UserActions = require('actions/user-actions'); const CommonActions = require('actions/common-actions'); @@ -14,29 +13,43 @@ const UserStore = Reflux.createStore({ this.listenTo(UserActions.checkLoginStatus, this.checkLoginStatus); this.listenTo(UserActions.login, this.loginUser); this.listenTo(UserActions.logout, this.logoutUser); + }, + + initSession() { + return API.call({ + path: 'user/check-session', + data: {} + }).then(this.tryLoginIfSessionIsInactive); + }, - if (!this.isLoggedIn()) { - this.loginIfRememberExists(); + tryLoginIfSessionIsInactive(result) { + if (!result.data.sessionActive) { + if (sessionStore.isRememberDataExpired()) { + return this.logoutUser(); + } else { + return this.loginWithRememberData(); + } } }, loginUser(loginData) { - API.call({ + let onSuccessLogin = (loginData.remember) ? this.handleLoginSuccessWithRemember : this.handleLoginSuccess; + let onFailedLogin = (loginData.isAutomatic) ? null : this.handleLoginFail; + + return API.call({ path: 'user/login', - data: loginData, - onSuccess: (loginData.remember) ? this.handleLoginSuccessWithRemember : this.handleLoginSuccess, - onFail: (loginData.isAutomatic) ? null : this.handleLoginFail - }); + data: loginData + }).then(onSuccessLogin, onFailedLogin); }, logoutUser() { - API.call({ - path: 'user/logout', - onSuccess: function () { - sessionStore.closeSession(); - CommonActions.loggedOut(); - this.trigger('LOGOUT'); - }.bind(this) + return API.call({ + path: 'user/logout' + }).then(() => { + sessionStore.closeSession(); + sessionStore.clearRememberData(); + CommonActions.loggedOut(); + this.trigger('LOGOUT'); }); }, @@ -44,20 +57,18 @@ const UserStore = Reflux.createStore({ return sessionStore.isLoggedIn(); }, - loginIfRememberExists() { - let rememberData = localStore.getRememberData(); + loginWithRememberData() { + let rememberData = sessionStore.getRememberData(); - if (!localStore.isRememberDataExpired()) { - UserActions.login({ - userId: rememberData.userId, - rememberToken: rememberData.token, - isAutomatic: true - }); - } + return this.loginUser({ + userId: rememberData.userId, + rememberToken: rememberData.token, + isAutomatic: true + }); }, handleLoginSuccessWithRemember(result) { - localStore.storeRememberData({ + sessionStore.storeRememberData({ token: result.data.rememberToken, userId: result.data.userId, expiration: result.data.rememberExpiration diff --git a/server/controllers/user/check-session.php b/server/controllers/user/check-session.php new file mode 100644 index 00000000..88cc8fd3 --- /dev/null +++ b/server/controllers/user/check-session.php @@ -0,0 +1,20 @@ + 'any', + 'requestData' => [] + ]; + } + + public function handler() { + $session = Session::getInstance(); + + Response::respondSuccess([ + 'sessionActive' => $session->sessionExists() + ]); + } +}