Fix login with rememberToken

This commit is contained in:
Ivan Diaz 2018-11-16 19:34:07 -03:00
parent 048d18e3cb
commit 4251e3b5e7
9 changed files with 63 additions and 23 deletions

View File

@ -1,3 +1,5 @@
import _ from 'lodash';
import API from 'lib-app/api-call'; import API from 'lib-app/api-call';
import AdminDataActions from 'actions/admin-data-actions'; import AdminDataActions from 'actions/admin-data-actions';
import sessionStore from 'lib-app/session-store'; import sessionStore from 'lib-app/session-store';
@ -12,7 +14,7 @@ export default {
let loginCall = () => { let loginCall = () => {
API.call({ API.call({
path: '/user/login', path: '/user/login',
data: loginData data: _.extend(loginData, {remember: loginData.remember * 1})
}).then((result) => { }).then((result) => {
store.dispatch(this.getUserData(result.data.userId, result.data.token, result.data.staff)).then(() => { store.dispatch(this.getUserData(result.data.userId, result.data.token, result.data.staff)).then(() => {
if(result.data.staff) { if(result.data.staff) {
@ -48,7 +50,8 @@ export default {
data: { data: {
userId: rememberData.userId, userId: rememberData.userId,
rememberToken: rememberData.token, rememberToken: rememberData.token,
isAutomatic: true remember: 1,
isAutomatic: 1
} }
}).then((result) => { }).then((result) => {
store.dispatch(this.getUserData(result.data.userId, result.data.token)); store.dispatch(this.getUserData(result.data.userId, result.data.token));

View File

@ -12,13 +12,14 @@ import Message from 'core-components/message';
class AdminPanelNewTickets extends React.Component { class AdminPanelNewTickets extends React.Component {
static defaultProps = { static defaultProps = {
page: 1,
userId: 0, userId: 0,
departments: [], departments: [],
tickets: [] tickets: []
}; };
componentDidMount() { componentDidMount() {
this.retrieveNewTickets() this.retrieveNewTickets();
} }
render() { render() {

View File

@ -103,9 +103,9 @@ class SessionReducer extends Reducer {
onUserDataRetrieved(state, payload) { onUserDataRetrieved(state, payload) {
let userData = payload.data; let userData = payload.data;
sessionStore.storeUserData(payload.data); sessionStore.storeUserData(payload.data);
return _.extend({}, state, { return _.extend({}, state, {
staff: userData.staff, staff: userData.staff,
userName: userData.name, userName: userData.name,
@ -117,11 +117,11 @@ class SessionReducer extends Reducer {
userSendEmailOnNewTicket: userData.sendEmailOnNewTicket * 1 userSendEmailOnNewTicket: userData.sendEmailOnNewTicket * 1
}); });
} }
onSessionChecked(state) { onSessionChecked(state) {
let userData = sessionStore.getUserData(); let userData = sessionStore.getUserData();
let userId = sessionStore.getSessionData().userId; let userId = sessionStore.getSessionData().userId;
return _.extend({}, state, { return _.extend({}, state, {
initDone: true, initDone: true,
logged: true, logged: true,
@ -144,4 +144,4 @@ class SessionReducer extends Reducer {
} }
} }
export default SessionReducer.getInstance(); export default SessionReducer.getInstance();

View File

@ -50,6 +50,8 @@ class GetLogsController extends Controller {
$removeOlderThanDays = 31; $removeOlderThanDays = 31;
$oldDate = floor(Date::getPreviousDate($removeOlderThanDays) / 10000); $oldDate = floor(Date::getPreviousDate($removeOlderThanDays) / 10000);
RedBean::exec("DELETE FROM log WHERE date < $oldDate"); try {
RedBean::exec("DELETE FROM log WHERE date < $oldDate");
} catch(Exception $e) {}
} }
} }

View File

@ -1,4 +1,5 @@
<?php <?php
use RedBeanPHP\Facade as RedBean;
/** /**
* @api {post} /user/login Login * @api {post} /user/login Login
@ -39,6 +40,7 @@ class LoginController extends Controller {
private $userInstance; private $userInstance;
private $rememberToken; private $rememberToken;
private $rememberExpiration;
public function validations() { public function validations() {
return [ return [
@ -56,6 +58,8 @@ class LoginController extends Controller {
throw new Exception(ERRORS::SESSION_EXISTS); throw new Exception(ERRORS::SESSION_EXISTS);
} }
$this->clearOldRememberTokens();
if ($this->checkInputCredentials() || $this->checkRememberToken()) { if ($this->checkInputCredentials() || $this->checkRememberToken()) {
if($this->userInstance->verificationToken !== null) { if($this->userInstance->verificationToken !== null) {
throw new Exception(ERRORS::UNVERIFIED_USER); throw new Exception(ERRORS::UNVERIFIED_USER);
@ -66,7 +70,7 @@ class LoginController extends Controller {
} }
$this->createUserSession(); $this->createUserSession();
$this->createSessionCookie(); $this->createRememberToken();
if(Controller::request('staff')) { if(Controller::request('staff')) {
$this->userInstance->lastLogin = Date::getCurrentDate(); $this->userInstance->lastLogin = Date::getCurrentDate();
$this->userInstance->store(); $this->userInstance->store();
@ -106,7 +110,8 @@ class LoginController extends Controller {
'userEmail' => $userInstance->email, 'userEmail' => $userInstance->email,
'staff' => Controller::request('staff'), 'staff' => Controller::request('staff'),
'token' => Session::getInstance()->getToken(), 'token' => Session::getInstance()->getToken(),
'rememberToken' => $this->rememberToken 'rememberToken' => $this->rememberToken,
'rememberExpiration' => $this->rememberExpiration
); );
} }
@ -138,18 +143,30 @@ class LoginController extends Controller {
return $userInstance; return $userInstance;
} }
private function createSessionCookie() { private function clearOldRememberTokens() {
$remember = Controller::request('remember'); $currentDate = Date::getCurrentDate();
try {
RedBean::exec("DELETE FROM sessioncookie WHERE expiration_date < $currentDate");
} catch(Exception $e) {}
}
private function createRememberToken() {
$remember = Controller::request('remember');
if ($remember) { if ($remember) {
$this->rememberToken = Hashing::generateRandomToken(); $this->rememberToken = Hashing::generateRandomToken();
$this->rememberExpiration = Date::getNextDate(30);
$sessionCookie = new SessionCookie(); $sessionCookie = new SessionCookie();
$sessionCookie->setProperties(array( $sessionCookie->setProperties(array(
'user' => $this->userInstance, 'user' => $this->userInstance,
'token' => $this->rememberToken, 'token' => $this->rememberToken,
'ip' => $_SERVER['REMOTE_ADDR'], 'ip' => $_SERVER['REMOTE_ADDR'],
'creationDate' => date('d-m-Y (H:i:s)') 'creationDate' => Date::getCurrentDate(),
'expirationDate' => $this->rememberExpiration
)); ));
$sessionCookie->store(); $sessionCookie->store();
} }
} }

View File

@ -7,4 +7,8 @@ class Date {
public static function getPreviousDate($days = 1) { public static function getPreviousDate($days = 1) {
return date('YmdHi', strtotime(" -$days day ")); return date('YmdHi', strtotime(" -$days day "));
} }
public static function getNextDate($days = 1) {
return date('YmdHi', strtotime(" +$days day "));
}
} }

View File

@ -10,6 +10,7 @@ namespace RedBeanPHP {
self::setStatics(array( self::setStatics(array(
'trash' => parent::stub(), 'trash' => parent::stub(),
'store' => parent::stub(), 'store' => parent::stub(),
'exec' => parent::stub(),
'dispense' => parent::stub()->returns(new \BeanMock()) 'dispense' => parent::stub()->returns(new \BeanMock())
)); ));
} }

View File

@ -8,6 +8,7 @@ include_once 'tests/__mocks__/SessionMock.php';
include_once 'tests/__mocks__/UserMock.php'; include_once 'tests/__mocks__/UserMock.php';
include_once 'tests/__mocks__/HashingMock.php'; include_once 'tests/__mocks__/HashingMock.php';
include_once 'tests/__mocks__/SessionCookieMock.php'; include_once 'tests/__mocks__/SessionCookieMock.php';
include_once 'tests/__mocks__/RedBeanMock.php';
include_once 'data/ERRORS.php'; include_once 'data/ERRORS.php';
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
@ -43,7 +44,8 @@ class LoginControllerTest extends TestCase {
'userEmail' => 'MOCK_EMAIL', 'userEmail' => 'MOCK_EMAIL',
'staff' => false, 'staff' => false,
'token' => 'TEST_TOKEN', 'token' => 'TEST_TOKEN',
'rememberToken' => null 'rememberToken' => null,
'rememberExpiration' => Date::getNextDate(30)
))); )));
} }

View File

@ -44,28 +44,38 @@ describe '/user/login' do
(result['data']['staff']).should.equal('true') (result['data']['staff']).should.equal('true')
end end
it 'should return remember token' do it 'should work with remember token' do
request('/user/logout', {}) request('/user/logout', {})
result = request('/user/login', { result = request('/user/login', {
email: @loginEmail, email: @loginEmail,
password: @loginPass, password: @loginPass,
remember: true remember: 1
}) })
(result['status']).should.equal('success') (result['status']).should.equal('success')
@rememberToken = result['data']['rememberToken'] @rememberToken = result['data']['rememberToken']
@userid = result['data']['userId'] @userId = result['data']['userId']
end
it 'should login with token' do
request('/user/logout', {}) request('/user/logout', {})
result = request('/user/login', { result = request('/user/login', {
rememberToken: @rememberToken, userId: @userId,
userId: @userid rememberToken: '12abc',
remember: 1
}) })
(result['status']).should.equal('fail')
result = request('/user/login', {
userId: 1,
rememberToken: @rememberToken,
remember: 1
})
(result['status']).should.equal('fail')
result = request('/user/login', {
userId: @userId,
rememberToken: @rememberToken,
remember: 1
})
(result['status']).should.equal('success') (result['status']).should.equal('success')
(result['data']['userId']).should.equal(@userid)
end end
end end