(web) bug fix - redirect to login if not signed-in

This commit is contained in:
Alexey Kontsevoy 2017-01-12 22:54:03 -05:00
parent 36a2d488d7
commit e0e163be8b
6 changed files with 61 additions and 40 deletions

View file

@ -991,10 +991,10 @@ webpackJsonp([0],{
var cfg = __webpack_require__(217);
var $ = __webpack_require__(219);
var logger = __webpack_require__(230).create('services/auth');
__webpack_require__(231); // This puts it in window.u2f
var AUTH_IS_RENEWING = 'GRV_AUTH_IS_RENEWING';
var PROVIDER_GOOGLE = 'google';
var SECOND_FACTOR_TYPE_HOTP = 'hotp';
var SECOND_FACTOR_TYPE_OIDC = 'oidc';
@ -1030,6 +1030,7 @@ webpackJsonp([0],{
u2f_register_response: res,
invite_token: inviteToken
};
api.post(cfg.api.u2fCreateUserPath, response, false).then(function (data) {
session.setUserData(data);
auth._startTokenRefresher();
@ -1100,6 +1101,9 @@ webpackJsonp([0],{
var userData = session.getUserData();
// ping the server to check if user signed out from another tab
this._checkStatus();
if (!userData.token) {
return $.Deferred().reject();
}
@ -1134,24 +1138,24 @@ webpackJsonp([0],{
var delta = created + expires_in - new Date().getTime();
// give some extra time for slow connection */
// give some extra time for slow connection
return delta < CHECK_TOKEN_REFRESH_RATE * 3;
},
_startTokenRefresher: function _startTokenRefresher() {
refreshTokenTimerId = setInterval(auth._fetchStatus.bind(auth), CHECK_TOKEN_REFRESH_RATE);
refreshTokenTimerId = setInterval(auth.ensureUser.bind(auth), CHECK_TOKEN_REFRESH_RATE);
},
_stopTokenRefresher: function _stopTokenRefresher() {
clearInterval(refreshTokenTimerId);
refreshTokenTimerId = null;
},
_fetchStatus: function _fetchStatus() {
_checkStatus: function _checkStatus() {
// do not attemp to fetch the status with potentially invalid token
// as it will trigger logout action.
if (localStorage.getItem(AUTH_IS_RENEWING) !== null) {
return;
}
api.get(cfg.api.userStatus).done(auth.ensureUser.bind(this)).fail(function (err) {
api.get(cfg.api.userStatus).fail(function (err) {
// indicates that user session is no longer valid
if (err.status == 403) {
auth.logout();
@ -1159,11 +1163,13 @@ webpackJsonp([0],{
});
},
_refreshToken: function _refreshToken() {
localStorage.setItem(AUTH_IS_RENEWING, true);
return api.post(cfg.api.renewTokenPath).then(function (data) {
session.setUserData(data);
return data;
}).fail(function () {
auth.logout();
}).always(function () {
localStorage.removeItem(AUTH_IS_RENEWING);
});
},
_getU2fErr: function _getU2fErr(errorCode) {

File diff suppressed because one or more lines are too long

2
web/dist/index.html vendored
View file

@ -10,5 +10,5 @@
<body class="grv">
<div id="app"></div>
<div id="bearer_token" style="display: none;">{{.Session}}</div>
<script type="text/javascript" src="/web/app/vendor.413147faa79807fc46a9.js"></script><script type="text/javascript" src="/web/app/styles.413147faa79807fc46a9.js"></script><script type="text/javascript" src="/web/app/app.413147faa79807fc46a9.js"></script></body>
<script type="text/javascript" src="/web/app/vendor.f04179d72ade36111d9e.js"></script><script type="text/javascript" src="/web/app/styles.f04179d72ade36111d9e.js"></script><script type="text/javascript" src="/web/app/app.f04179d72ade36111d9e.js"></script></body>
</html>

View file

@ -20,6 +20,7 @@ var api = require('app/services/api');
var session = require('app/services/session');
var spyOn = expect.spyOn;
var auth = require('app/services/auth');
var cfg = require('app/config');
describe('auth', function () {
var sample = { token: 'token', expires_in: 599, created: new Date().getTime() };
@ -29,6 +30,7 @@ describe('auth', function () {
spyOn(session, 'getUserData');
spyOn(session, 'clear');
spyOn(api, 'post');
spyOn(api, 'get');
spyOn(api, 'delete').andReturn($.Deferred().resolve());
spyOn(auth, '_startTokenRefresher');
spyOn(auth, '_stopTokenRefresher');
@ -107,7 +109,8 @@ describe('auth', function () {
session.getUserData.andReturn(sample);
auth.ensureUser('user', 'password').done(()=> { wasCalled = true });
expect(wasCalled).toEqual(true);
expect(wasCalled).toEqual(true);
expect(api.get).toHaveBeenCalledWith(cfg.api.userStatus);
expect(auth._startTokenRefresher).toHaveBeenCalled();
expect(auth._shouldRefreshToken).toHaveBeenCalled();
});
@ -125,16 +128,18 @@ describe('auth', function () {
auth.ensureUser('user', 'password').done(()=> { wasCalled = true });
expect(wasCalled).toEqual(true);
expect(api.get).toHaveBeenCalledWith(cfg.api.userStatus);
expect(auth._startTokenRefresher).toHaveBeenCalled();
expect(auth._shouldRefreshToken).toHaveBeenCalled();
});
});
describe('when token is missing', function () {
it('should reject', function () {
var wasCalled = false;
session.getUserData.andReturn({});
auth.ensureUser('user', 'password').fail(()=> { wasCalled = true });
auth.ensureUser('user', 'password').fail(() => { wasCalled = true });
expect(api.get).toHaveBeenCalledWith(cfg.api.userStatus);
expect(wasCalled).toEqual(true);
});
});

View file

@ -19,10 +19,10 @@ var session = require('./session');
var cfg = require('app/config');
var $ = require('jQuery');
var logger = require('app/common/logger').create('services/auth');
require('u2f-api-polyfill'); // This puts it in window.u2f
const AUTH_IS_RENEWING = 'GRV_AUTH_IS_RENEWING';
const PROVIDER_GOOGLE = 'google';
const SECOND_FACTOR_TYPE_HOTP = 'hotp';
const SECOND_FACTOR_TYPE_OIDC = 'oidc';
@ -30,9 +30,9 @@ const SECOND_FACTOR_TYPE_U2F = 'u2f';
const CHECK_TOKEN_REFRESH_RATE = 10 * 1000; // 10 sec
var refreshTokenTimerId = null;
let refreshTokenTimerId = null;
var auth = {
const auth = {
signUp(name, password, token, inviteToken){
var data = {user: name, pass: password, second_factor_token: token, invite_token: inviteToken};
@ -56,18 +56,21 @@ var auth = {
}
var response = {
user: name,
pass: password,
user: name,
pass: password,
u2f_register_response: res,
invite_token: inviteToken
invite_token: inviteToken
};
api.post(cfg.api.u2fCreateUserPath, response, false).then(data=>{
session.setUserData(data);
auth._startTokenRefresher();
deferred.resolve(data);
}).fail(data=>{
deferred.reject(data);
})
api.post(cfg.api.u2fCreateUserPath, response, false)
.then(data => {
session.setUserData(data);
auth._startTokenRefresher();
deferred.resolve(data);
})
.fail(data => {
deferred.reject(data);
})
});
return deferred.promise();
@ -130,18 +133,21 @@ var auth = {
ensureUser(){
this._stopTokenRefresher();
var userData = session.getUserData();
let userData = session.getUserData();
// ping the server to check if user signed out from another tab
this._checkStatus();
if(!userData.token){
return $.Deferred().reject();
}
if(this._shouldRefreshToken(userData)){
return this._refreshToken().done(this._startTokenRefresher);
}
this._startTokenRefresher();
return $.Deferred().resolve(userData);
return $.Deferred().resolve(userData);
},
logout(){
@ -166,12 +172,12 @@ var auth = {
var delta = created + expires_in - new Date().getTime();
// give some extra time for slow connection */
// give some extra time for slow connection
return delta < CHECK_TOKEN_REFRESH_RATE * 3;
},
_startTokenRefresher(){
refreshTokenTimerId = setInterval(auth._fetchStatus.bind(auth), CHECK_TOKEN_REFRESH_RATE);
refreshTokenTimerId = setInterval(auth.ensureUser.bind(auth), CHECK_TOKEN_REFRESH_RATE);
},
_stopTokenRefresher(){
@ -179,16 +185,15 @@ var auth = {
refreshTokenTimerId = null;
},
_fetchStatus(){
_checkStatus(){
// do not attemp to fetch the status with potentially invalid token
// as it will trigger logout action.
if(localStorage.getItem(AUTH_IS_RENEWING) !== null){
return;
}
api.get(cfg.api.userStatus)
.done(auth.ensureUser.bind(this))
.fail( err => {
api.get(cfg.api.userStatus)
.fail(err => {
// indicates that user session is no longer valid
if(err.status == 403){
auth.logout();
@ -196,13 +201,18 @@ var auth = {
});
},
_refreshToken(){
return api.post(cfg.api.renewTokenPath).then(data=>{
session.setUserData(data);
return data;
}).fail(()=>{
auth.logout();
});
_refreshToken() {
localStorage.setItem(AUTH_IS_RENEWING, true);
return api.post(cfg.api.renewTokenPath)
.then(data => {
session.setUserData(data);
})
.fail(() => {
auth.logout();
})
.always(() => {
localStorage.removeItem(AUTH_IS_RENEWING);
});
},
_getU2fErr(errorCode){