#7272 - BUG Redirect To Login when ACL not exists #2371

Merged
jsegarra merged 19 commits from 7272_bug_redirectToLogin into dev 2024-05-27 06:56:20 +00:00
7 changed files with 78 additions and 26 deletions

View File

@ -18,15 +18,10 @@ module.exports = Self => {
Self.renewToken = async function(ctx) { Self.renewToken = async function(ctx) {
const {accessToken: token} = ctx.req; const {accessToken: token} = ctx.req;
// Check if current token is valid const {courtesyTime} = await models.AccessTokenConfig.findOne({
fields: ['courtesyTime']
const {renewPeriod, courtesyTime} = await models.AccessTokenConfig.findOne({
fields: ['renewPeriod', 'courtesyTime']
}); });
const now = Date.now(); const isNotExceeded = await Self.validateToken(ctx);
const differenceMilliseconds = now - token.created;
const differenceSeconds = Math.floor(differenceMilliseconds / 1000);
const isNotExceeded = differenceSeconds < renewPeriod - courtesyTime;
if (isNotExceeded) if (isNotExceeded)
return token; return token;

View File

@ -0,0 +1,30 @@
const {models} = require('vn-loopback/server/server');
module.exports = Self => {
Self.remoteMethodCtx('validateToken', {
description: 'Validates the current logged user token',
accepts: [],
accessType: 'READ',
returns: {
type: 'Boolean',
root: true
},
http: {
path: `/validateToken`,
verb: 'GET'
}
});
Self.validateToken = async function(ctx) {
const {accessToken: token} = ctx.req;
// Check if current token is valid
const {renewPeriod, courtesyTime} = await models.AccessTokenConfig.findOne({
fields: ['renewPeriod', 'courtesyTime']
});
const now = Date.now();
const differenceMilliseconds = now - token.created;
const differenceSeconds = Math.floor(differenceMilliseconds / 1000);
const isNotExceeded = differenceSeconds < renewPeriod - courtesyTime;
return isNotExceeded;
};
};

View File

@ -15,6 +15,7 @@ module.exports = function(Self) {
require('../methods/vn-user/renew-token')(Self); require('../methods/vn-user/renew-token')(Self);
require('../methods/vn-user/share-token')(Self); require('../methods/vn-user/share-token')(Self);
require('../methods/vn-user/update-user')(Self); require('../methods/vn-user/update-user')(Self);
require('../methods/vn-user/validate-token')(Self);
Self.definition.settings.acls = Self.definition.settings.acls.filter(acl => acl.property !== 'create'); Self.definition.settings.acls = Self.definition.settings.acls.filter(acl => acl.property !== 'create');

View File

@ -113,6 +113,13 @@
"principalId": "$everyone", "principalId": "$everyone",
"permission": "ALLOW" "permission": "ALLOW"
}, },
{
"property": "validateToken",
"accessType": "EXECUTE",
"principalType": "ROLE",
"principalId": "$authenticated",
"permission": "ALLOW"
},
{ {
"property": "privileges", "property": "privileges",
"accessType": "*", "accessType": "*",

View File

@ -69,3 +69,4 @@ Send cau: Enviar cau
By sending this ticket, all the data related to the error, the section, the user, etc., are already sent.: Al enviar este cau ya se envían todos los datos relacionados con el error, la sección, el usuario, etc By sending this ticket, all the data related to the error, the section, the user, etc., are already sent.: Al enviar este cau ya se envían todos los datos relacionados con el error, la sección, el usuario, etc
ExplainReason: Explique el motivo por el que no deberia aparecer este fallo ExplainReason: Explique el motivo por el que no deberia aparecer este fallo
You already have the mailAlias: Ya tienes este alias de correo You already have the mailAlias: Ya tienes este alias de correo
Error loading ACLs: Error al cargar los ACLs

View File

@ -7,16 +7,17 @@ import UserError from 'core/lib/user-error';
* @property {Boolean} loggedIn Whether the user is currently logged * @property {Boolean} loggedIn Whether the user is currently logged
*/ */
export default class Auth { export default class Auth {
constructor($http, $q, $state, $transitions, $window, vnToken, vnModules, aclService) { constructor($http, $q, vnApp, $translate, $state, $transitions, $window, vnToken, vnModules) {
Object.assign(this, { Object.assign(this, {
$http, $http,
$q, $q,
vnApp,
$translate,
$state, $state,
$transitions, $transitions,
$window, $window,
vnToken, vnToken,
vnModules, vnModules,
aclService,
loggedIn: false loggedIn: false
}); });
} }
@ -39,9 +40,26 @@ export default class Auth {
}; };
if (this.vnToken.token) { if (this.vnToken.token) {
return this.loadAcls() const loadWithRetry = () => {
.then(() => true) return this.validateToken()
.catch(redirectToLogin); .then(() => true)
.catch(err => {
switch (err.status) {
case 400:
case 401:
return redirectToLogin();
default:
return new Promise(resolve => {
setTimeout(() => {
this.vnApp.showMessage(this.$translate.instant('Loading...'));
resolve(loadWithRetry());
}, 2000);
});
}
});
};
return loadWithRetry();
} else } else
return redirectToLogin(); return redirectToLogin();
}); });
@ -87,13 +105,11 @@ export default class Auth {
headers: {Authorization: json.data.token} headers: {Authorization: json.data.token}
}).then(({data}) => { }).then(({data}) => {
this.vnToken.set(json.data.token, data.multimediaToken.id, now, json.data.ttl, remember); this.vnToken.set(json.data.token, data.multimediaToken.id, now, json.data.ttl, remember);
this.loadAcls().then(() => { let continueHash = this.$state.params.continue;
let continueHash = this.$state.params.continue; if (continueHash)
if (continueHash) this.$window.location = continueHash;
this.$window.location = continueHash; else
else this.$state.go('home');
this.$state.go('home');
});
}).catch(() => {}); }).catch(() => {});
} }
@ -107,24 +123,25 @@ export default class Auth {
this.vnToken.unset(); this.vnToken.unset();
this.loggedIn = false; this.loggedIn = false;
this.vnModules.reset(); this.vnModules.reset();
this.aclService.reset(); this.vnModules.aclService.reset();
this.$state.go('login'); this.$state.go('login');
return promise; return promise;
} }
loadAcls() { validateToken() {
return this.aclService.load() return this.$http.get('VnUsers/validateToken')
.then(() => { .then(() => {
this.loggedIn = true; this.loggedIn = true;
this.vnModules.reset(); this.vnModules.reset();
}) })
.catch(err => { .catch(err => {
this.vnToken.unset();
throw err; throw err;
}); });
} }
} }
Auth.$inject = ['$http', '$q', '$state', '$transitions', '$window', 'vnToken', 'vnModules', 'aclService']; Auth.$inject = [
'$http', '$q', 'vnApp', '$translate', '$state',
'$transitions', '$window', 'vnToken', 'vnModules'];
ngModule.service('vnAuth', Auth); ngModule.service('vnAuth', Auth);

View File

@ -12,7 +12,8 @@ function config($stateProvider, $urlRouterProvider) {
template: '<vn-layout></vn-layout>', template: '<vn-layout></vn-layout>',
resolve: { resolve: {
config: ['vnConfig', vnConfig => vnConfig.initialize()], config: ['vnConfig', vnConfig => vnConfig.initialize()],
token: ['vnToken', vnToken => vnToken.fetchConfig()] token: ['vnToken', vnToken => vnToken.fetchConfig()],
acl: ['aclService', aclService => aclService.load()]
} }
}) })
.state('outLayout', { .state('outLayout', {