diff --git a/back/methods/vn-user/renew-token.js b/back/methods/vn-user/renew-token.js new file mode 100644 index 000000000..66e64e995 --- /dev/null +++ b/back/methods/vn-user/renew-token.js @@ -0,0 +1,48 @@ +module.exports = Self => { + Self.remoteMethodCtx('renewToken', { + description: 'Send email to the user', + accepts: [], + http: { + path: `/renewToken`, + verb: 'POST' + } + }); + + Self.renewToken = async function(ctx, options) { + const models = Self.app.models; + const userId = ctx.req.accessToken.userId; + const created = ctx.req.accessToken.created; + // const tokenId = ctx.req.accessToken.id; + const myOptions = {}; + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + const now = new Date(); + const differenceMilliseconds = now - created; + const differenceSeconds = Math.floor(differenceMilliseconds / 1000); // Convertir la diferencia a segundos + + const accessTokenConfig = await models.AccessTokenConfig.findOne(); + if (differenceSeconds <= accessTokenConfig.renewPeriod) { + const response = { + statusCode: 200, + data: { + message: 'Token is active', + } + }; + return response; + } + + const accessToken = await models.AccessToken.create({userId: userId}, myOptions); + await models.AccessToken.destroyAll({userId: userId}, myOptions); + // await models.AccessToken.destroyById(tokenId, myOptions); + + return {token: accessToken.id, created: accessToken.created}; + }; +}; diff --git a/back/methods/vn-user/signIn.js b/back/methods/vn-user/signIn.js index da3172ae4..bc88905cc 100644 --- a/back/methods/vn-user/signIn.js +++ b/back/methods/vn-user/signIn.js @@ -63,6 +63,6 @@ module.exports = Self => { let loginInfo = Object.assign({password}, userInfo); token = await Self.login(loginInfo, 'user'); - return {token: token.id}; + return {token: token.id, created: token.created}; }; }; diff --git a/back/model-config.json b/back/model-config.json index ff2bf5850..d945f3250 100644 --- a/back/model-config.json +++ b/back/model-config.json @@ -2,6 +2,14 @@ "AccountingType": { "dataSource": "vn" }, + "AccessTokenConfig": { + "dataSource": "vn", + "options": { + "mysql": { + "table": "salix.accessTokenConfig" + } + } + }, "Bank": { "dataSource": "vn" }, diff --git a/back/models/access-token-config.json b/back/models/access-token-config.json new file mode 100644 index 000000000..6d90a0f4d --- /dev/null +++ b/back/models/access-token-config.json @@ -0,0 +1,30 @@ +{ + "name": "AccessTokenConfig", + "base": "VnModel", + "options": { + "mysql": { + "table": "accessTokenConfig" + } + }, + "properties": { + "id": { + "type": "number", + "id": true, + "description": "Identifier" + }, + "renewPeriod": { + "type": "number", + "required": true + }, + "renewInterval": { + "type": "number", + "required": true + } + }, + "acls": [{ + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + }] +} diff --git a/back/models/vn-user.js b/back/models/vn-user.js index 84ba11794..17e6c9320 100644 --- a/back/models/vn-user.js +++ b/back/models/vn-user.js @@ -10,6 +10,7 @@ module.exports = function(Self) { require('../methods/vn-user/recover-password')(Self); require('../methods/vn-user/validate-token')(Self); require('../methods/vn-user/privileges')(Self); + require('../methods/vn-user/renew-token')(Self); // Validations diff --git a/db/changes/232201/00-salix.sql b/db/changes/232201/00-salix.sql new file mode 100644 index 000000000..75b64500a --- /dev/null +++ b/db/changes/232201/00-salix.sql @@ -0,0 +1,6 @@ +CREATE TABLE `salix`.`accessTokenConfig` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `renewPeriod` int(10) unsigned DEFAULT NULL, + `renewInterval` int(10) unsigned DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 9f06de5b0..cd4aca4bc 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -2886,6 +2886,6 @@ INSERT INTO `vn`.`wagonTypeTray` (`id`, `typeFk`, `height`, `colorFk`) (2, 1, 50, 2), (3, 1, 0, 3); - - - +INSERT INTO `salix`.`accessTokenConfig` (`id`, `renewPeriod`, `renewInterval`) + VALUES + (0, 50, 100); diff --git a/front/core/services/auth.js b/front/core/services/auth.js index 0b89a8e88..d1ac4c78d 100644 --- a/front/core/services/auth.js +++ b/front/core/services/auth.js @@ -7,7 +7,7 @@ import UserError from 'core/lib/user-error'; * @property {Boolean} loggedIn Whether the user is currently logged */ export default class Auth { - constructor($http, $q, $state, $transitions, $window, vnToken, vnModules, aclService) { + constructor($http, $q, $state, $transitions, $window, vnToken, vnTokenCreated, vnModules, aclService) { Object.assign(this, { $http, $q, @@ -15,6 +15,7 @@ export default class Auth { $transitions, $window, vnToken, + vnTokenCreated, vnModules, aclService, loggedIn: false @@ -29,8 +30,11 @@ export default class Auth { } }; this.$transitions.onStart(criteria, transition => { - if (this.loggedIn) + this.getAccessTokenConfig(); + if (this.loggedIn) { + console.log('firstIf'); return true; + } let redirectToLogin = () => { return transition.router.stateService.target('login', { @@ -39,14 +43,44 @@ export default class Auth { }; if (this.vnToken.token) { + console.log('secondIf'); + return this.loadAcls() .then(() => true) .catch(redirectToLogin); - } else + } else { + console.log('else'); + return redirectToLogin(); + } }); } + getAccessTokenConfig() { + this.$http.get('AccessTokenConfigs/findOne').then(json => { + window.localStorage.renewPeriod = json.data.renewPeriod; + window.localStorage.renewInterval = json.data.renewInterval; + + this.checkTokenValidity(); + const intervalMilliseconds = 50 * 1000; + // setInterval(this.checkTokenValidity.bind(this), intervalMilliseconds); + }); + } + + checkTokenValidity() { + const now = new Date(); + const differenceMilliseconds = now - new Date(this.vnTokenCreated.created); + const differenceSeconds = Math.floor(differenceMilliseconds / 1000); + + console.log(differenceSeconds, window.localStorage.renewPeriod); + if (differenceSeconds > window.localStorage.renewPeriod) { + this.$http.post('VnUsers/renewToken') + .then(() => { + console.log('fin'); + }); + } + } + login(user, password, remember) { if (!user) { let err = new UserError('Please enter your username'); @@ -65,6 +99,7 @@ export default class Auth { onLoginOk(json, remember) { this.vnToken.set(json.data.token, remember); + this.vnTokenCreated.set(json.data.created, remember); return this.loadAcls().then(() => { let continueHash = this.$state.params.continue; @@ -101,6 +136,6 @@ export default class Auth { }); } } -Auth.$inject = ['$http', '$q', '$state', '$transitions', '$window', 'vnToken', 'vnModules', 'aclService']; +Auth.$inject = ['$http', '$q', '$state', '$transitions', '$window', 'vnToken', 'vnTokenCreated', 'vnModules', 'aclService']; ngModule.service('vnAuth', Auth); diff --git a/front/core/services/index.js b/front/core/services/index.js index 867a13df0..6d4e34428 100644 --- a/front/core/services/index.js +++ b/front/core/services/index.js @@ -11,3 +11,5 @@ import './report'; import './email'; import './file'; import './date'; +import './token-created'; + diff --git a/front/core/services/token-created.js b/front/core/services/token-created.js new file mode 100644 index 000000000..c8e156a5d --- /dev/null +++ b/front/core/services/token-created.js @@ -0,0 +1,34 @@ +import ngModule from '../module'; + +/** + * Saves and loads the created for the current logged in user. + * + * @property {String} created The current login created or %null + */ +export default class created { + constructor() { + try { + this.created = sessionStorage.getItem('vnTokenCreated'); + if (!this.created) + this.created = localStorage.getItem('vnTokenCreated'); + } catch (e) {} + } + set(value, remember) { + this.unset(); + try { + if (remember) + localStorage.setItem('vnTokenCreated', value); + else + sessionStorage.setItem('vnTokenCreated', value); + } catch (e) {} + + this.created = value; + } + unset() { + localStorage.removeItem('vnTokenCreated'); + sessionStorage.removeItem('vnTokenCreated'); + this.created = null; + } +} + +ngModule.service('vnTokenCreated', created); diff --git a/front/salix/components/layout/index.js b/front/salix/components/layout/index.js index 48f50f404..6c4319215 100644 --- a/front/salix/components/layout/index.js +++ b/front/salix/components/layout/index.js @@ -10,6 +10,7 @@ export class Layout extends Component { $onInit() { this.getUserData(); + // this.getAccessTokenConfig(); } getUserData() { @@ -27,6 +28,25 @@ export class Layout extends Component { return `/api/Images/user/160x160/${userId}/download?access_token=${token}`; } + getAccessTokenConfig() { + this.$http.get('AccessTokenConfigs/findOne').then(json => { + window.localStorage.renewPeriod = json.data.renewPeriod; + window.localStorage.renewInterval = json.data.renewInterval; + + const intervalMilliseconds = 1 * 1000; + const intervalID = setInterval(this.checkTokenValidity, intervalMilliseconds); + }); + } + + checkTokenValidity() { + console.log('checkTokenValidity'); + + // this.$http.post('VnUsers/renewToken') + // .then(() => { + // console.log('fin'); + // }); + } + refresh() { window.location.reload(); }