#981 Login bugs fixed, cookies disabled, session remember by default

This commit is contained in:
Juan Ferrer 2019-01-25 12:04:35 +01:00
parent e600a4b5b7
commit 013710c6b3
12 changed files with 92 additions and 101 deletions

View File

@ -1,14 +1,6 @@
module.exports = Self => {
Self.remoteMethod('validateToken', {
description: 'Get the user information and permissions',
accepts: [
{
arg: 'token',
type: 'String',
description: 'The token to validate',
required: true
}
],
description: 'Validates the current logged user token',
returns: {
type: 'Boolean',
root: true
@ -19,13 +11,7 @@ module.exports = Self => {
}
});
Self.validateToken = function(tokenId, cb) {
Self.app.models.AccessToken.findById(tokenId, (err, token) => {
if (err) return cb(err);
if (token)
token.validate((_, isValid) => cb(null, isValid === true));
else
cb(null, false);
});
Self.validateToken = async function() {
return true;
};
};

View File

@ -52,7 +52,7 @@
"property": "validateToken",
"accessType": "EXECUTE",
"principalType": "ROLE",
"principalId": "$everyone",
"principalId": "$authenticated",
"permission": "ALLOW"
}
]

View File

@ -1,6 +1,5 @@
import './module-loader';
import './crud';
import './app';
import './acl-service';
import './storage-services';
import './template';

View File

@ -13,18 +13,18 @@ export default class App {
}
showMessage(message) {
if (this.snackbar)
this.snackbar.show({message: message});
if (this.logger)
this.logger.showMessage(message);
}
showSuccess(message) {
if (this.snackbar)
this.snackbar.showSuccess({message: message});
if (this.logger)
this.logger.showSuccess(message);
}
showError(message) {
if (this.snackbar)
this.snackbar.showError({message: message});
if (this.logger)
this.logger.showError(message);
}
pushLoader() {

View File

@ -16,29 +16,29 @@ export default class Auth {
vnToken,
vnModules,
aclService,
token: null,
loggedIn: false,
dataLoaded: false
loggedIn: false
});
}
initialize() {
this.loggedIn = this.vnToken.token != null;
let criteria = {
to: state => state.name != 'login'
};
this.$transitions.onStart(criteria, transition => {
if (!this.loggedIn) {
let params = {continue: this.$window.location.hash};
return transition.router.stateService.target('login', params);
}
if (!this.dataLoaded) {
this.resetData();
this.dataLoaded = true;
return this.aclService.load();
}
if (this.loggedIn)
return true;
return true;
let redirectToLogin = () => {
return transition.router.stateService.target('login', {
continue: this.$window.location.hash
});
};
if (this.vnToken.token) {
return this.loadAcls()
.then(() => true)
.catch(redirectToLogin);
} else
return redirectToLogin();
});
}
login(user, password, remember) {
@ -49,22 +49,21 @@ export default class Auth {
user,
password: password || undefined
};
return this.$http.post('/api/Accounts/login', params).then(
json => this.onLoginOk(json, remember),
json => this.onLoginErr(json)
);
json => this.onLoginErr(json));
}
onLoginOk(json, remember) {
this.resetData();
this.vnToken.set(json.data.token, remember);
this.loggedIn = true;
let continueHash = this.$state.params.continue;
if (continueHash)
this.$window.location = continueHash;
else
this.$state.go('home');
return this.loadAcls().then(() => {
let continueHash = this.$state.params.continue;
if (continueHash)
this.$window.location = continueHash;
else
this.$state.go('home');
});
}
onLoginErr(json) {
let message;
@ -89,15 +88,22 @@ export default class Auth {
this.vnToken.unset();
this.loggedIn = false;
this.resetData();
this.vnModules.reset();
this.aclService.reset();
this.$state.go('login');
return promise;
}
resetData() {
this.aclService.reset();
this.vnModules.reset();
this.dataLoaded = false;
loadAcls() {
return this.aclService.load()
.then(() => {
this.loggedIn = true;
this.vnModules.reset();
})
.catch(err => {
this.vnToken.unset();
throw err;
});
}
}
Auth.$inject = ['$http', '$state', '$transitions', '$window', 'vnToken', 'vnModules', 'aclService'];

View File

@ -1,3 +1,5 @@
import './app';
import './auth';
import './token';
import './modules';

View File

@ -6,17 +6,12 @@ import ngModule from '../module';
* @property {String} token The current login token or %null
*/
export default class Token {
constructor($cookies) {
this.$cookies = $cookies;
constructor() {
try {
this.token = sessionStorage.getItem('vnToken');
if (!this.token)
this.token = localStorage.getItem('vnToken');
} catch (e) {}
if (!this.token)
this.token = this.$cookies.get('vnToken');
}
set(value, remember) {
this.unset();
@ -25,27 +20,15 @@ export default class Token {
localStorage.setItem('vnToken', value);
else
sessionStorage.setItem('vnToken', value);
} catch (e) {
let options = {};
} catch (e) {}
if (location.protocol == 'https:')
options.secure = true;
if (remember) {
let now = new Date().getTime();
options.expires = new Date(now + 7 * 86400000);
}
this.$cookies.put('vnToken', value, options);
}
this.token = value;
}
unset() {
localStorage.removeItem('vnToken');
sessionStorage.removeItem('vnToken');
this.$cookies.remove('vnToken');
this.token = null;
}
}
Token.$inject = ['$cookies'];
ngModule.service('vnToken', Token);

View File

@ -1,4 +1,4 @@
<vn-topbar ng-if="$ctrl.inApp">
<vn-topbar ng-if="$ctrl.showTopbar">
<a class="logo" ui-sref="home" title="{{'Home' | translate}}">
<img src="./logo.svg" alt="Logo"></img>
</a>
@ -12,7 +12,7 @@
</vn-topbar>
<div ui-view
class="main-view"
ng-class="{'padding': $ctrl.inApp}">
ng-class="{'padding': $ctrl.showTopbar}">
<vn-home></vn-home>
</div>
<div

View File

@ -2,42 +2,63 @@ import ngModule from '../../module';
import './style.scss';
export default class App {
constructor($element, $scope, vnApp, $state, $transitions) {
this.$element = $element;
this.$ = $scope;
this.vnApp = vnApp;
this.$state = $state;
constructor($, $element, vnApp, $state, $transitions) {
Object.assign(this, {
$,
$element,
vnApp,
$state
});
$transitions.onStart({}, () => {
if (this.menuShown) this.hideMenu();
});
}
$postLink() {
this.background = this.$element[0].querySelector('.background');
this.vnApp.snackbar = this.$.snackbar;
this.vnApp.logger = this;
}
// TODO: Temporary fix to hide the topbar when login is displayed
get inApp() {
$onDestroy() {
this.vnApp.logger = null;
}
get showTopbar() {
let state = this.$state.current.name;
return state && state != 'login';
}
get leftBlock() {
return this.$element[0].querySelector('.left-block');
}
showMenu() {
let leftBlock = this.leftBlock;
if (!leftBlock) return;
leftBlock.classList.add('shown');
this.menuShown = true;
}
hideMenu() {
this.menuShown = false;
let leftBlock = this.leftBlock;
if (!leftBlock) return;
leftBlock.classList.remove('shown');
}
showMessage(message) {
this.$.snackbar.show({message: message});
}
showSuccess(message) {
this.$.snackbar.showSuccess({message: message});
}
showError(message) {
this.$.snackbar.showError({message: message});
}
}
App.$inject = ['$element', '$scope', 'vnApp', '$state', '$transitions'];
App.$inject = ['$scope', '$element', 'vnApp', '$state', '$transitions'];
ngModule.component('vnApp', {
template: require('./app.html'),

View File

@ -5,11 +5,14 @@ import './style.scss';
* A simple login form.
*/
export default class Controller {
constructor($element, $scope, vnAuth) {
this.$element = $element;
this.$ = $scope;
this.vnAuth = vnAuth;
this.user = localStorage.getItem('lastUser');
constructor($, $element, vnAuth) {
Object.assign(this, {
$,
$element,
vnAuth,
user: localStorage.getItem('lastUser'),
remember: true
});
}
submit() {
this.loading = true;
@ -30,7 +33,7 @@ export default class Controller {
this.$.userField.focus();
}
}
Controller.$inject = ['$element', '$scope', 'vnAuth'];
Controller.$inject = ['$scope', '$element', 'vnAuth'];
ngModule.component('vnLogin', {
template: require('./login.html'),

View File

@ -1,4 +0,0 @@
{
"default": "/login",
"salix": "/login"
}

View File

@ -36,11 +36,6 @@ let buildDir = `${appDir}/dist`;
let servicesDir = `${appDir}/modules`;
let modulesPath = `${appDir}/modules.yml`;
// TODO: It should be stored at some config file
app.set('api key', 'salix');
app.set('url auth', '/auth');
app.set('applications', require('./application.json'));
app.use(cookieParser());
// Internationalization