From 7f278269a5b4e3d48910a9c71c417cc0a52c34cb Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 21 Jun 2024 14:28:55 +0200 Subject: [PATCH 1/2] feat(AccessToken&ACL): refs #7547 upgrade security --- back/methods/vn-token/killSession.js | 29 +++++++++++++++++++ back/model-config.json | 3 ++ back/models/vn-token.js | 5 ++++ back/models/vn-token.json | 22 ++++++++++++++ .../11112-blackRose/00-firstScript.sql | 13 +++++++++ modules/account/front/connections/index.html | 4 +-- modules/account/front/connections/index.js | 4 +-- 7 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 back/methods/vn-token/killSession.js create mode 100644 back/models/vn-token.js create mode 100644 back/models/vn-token.json create mode 100644 db/versions/11112-blackRose/00-firstScript.sql diff --git a/back/methods/vn-token/killSession.js b/back/methods/vn-token/killSession.js new file mode 100644 index 000000000..23d02bfc2 --- /dev/null +++ b/back/methods/vn-token/killSession.js @@ -0,0 +1,29 @@ +module.exports = Self => { + Self.remoteMethodCtx('killSession', { + description: 'Kill session', + accepts: [{ + arg: 'userId', + type: 'integer', + description: 'The user id', + required: true, + }, { + arg: 'created', + type: 'date', + description: 'The created time', + required: true, + }], + accessType: 'WRITE', + http: { + path: `/killSession`, + verb: 'POST' + } + }); + + Self.killSession = async function(ctx, userId, created) { + await Self.app.models.VnUser.userSecurity(ctx, ctx.req.accessToken.userId); + const tokens = await Self.app.models.AccessToken.find({where: {userId, created}}); + if (!tokens?.length) return; + for (const token of tokens) + await Self.app.models.AccessToken.deleteById(token.id); + }; +}; diff --git a/back/model-config.json b/back/model-config.json index b643ab54f..c956e96e5 100644 --- a/back/model-config.json +++ b/back/model-config.json @@ -166,6 +166,9 @@ "ViaexpressConfig": { "dataSource": "vn" }, + "VnToken": { + "dataSource": "vn" + }, "VnUser": { "dataSource": "vn" }, diff --git a/back/models/vn-token.js b/back/models/vn-token.js new file mode 100644 index 000000000..03d45dae2 --- /dev/null +++ b/back/models/vn-token.js @@ -0,0 +1,5 @@ +const vnModel = require('vn-loopback/common/models/vn-model'); +module.exports = function(Self) { + vnModel(Self); + require('../methods/vn-token/killSession')(Self); +}; diff --git a/back/models/vn-token.json b/back/models/vn-token.json new file mode 100644 index 000000000..fab8965d6 --- /dev/null +++ b/back/models/vn-token.json @@ -0,0 +1,22 @@ +{ + "name": "VnToken", + "base": "AccessToken", + "options": { + "mysql": { + "table": "salix.AccessToken" + } + }, + "properties": { + "created": { + "type": "date" + } + }, + "relations": { + "user": { + "type": "belongsTo", + "model": "VnUser", + "foreignKey": "userId" + } + }, + "hidden": ["id"] +} diff --git a/db/versions/11112-blackRose/00-firstScript.sql b/db/versions/11112-blackRose/00-firstScript.sql new file mode 100644 index 000000000..c26149240 --- /dev/null +++ b/db/versions/11112-blackRose/00-firstScript.sql @@ -0,0 +1,13 @@ +UPDATE `salix`.`ACL` + SET accessType='READ' + WHERE model = 'ACL'; + +UPDATE `salix`.`ACL` + SET principalId='developerBoss' + WHERE model = 'AccessToken'; + +INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) + VALUES + ('VnToken', '*', 'READ', 'ALLOW', 'ROLE', 'developer'), + ('VnToken', 'killSession', '*', 'ALLOW', 'ROLE', 'developer'), + ('ACL', '*', 'WRITE', 'ALLOW', 'ROLE', 'developerBoss'); diff --git a/modules/account/front/connections/index.html b/modules/account/front/connections/index.html index d634b7a9f..b98fbf5a8 100644 --- a/modules/account/front/connections/index.html +++ b/modules/account/front/connections/index.html @@ -1,6 +1,6 @@ @@ -42,4 +42,4 @@ ng-click="model.refresh()" vn-bind="r" fixed-bottom-right> - \ No newline at end of file + diff --git a/modules/account/front/connections/index.js b/modules/account/front/connections/index.js index c4ddd5615..236174c63 100644 --- a/modules/account/front/connections/index.js +++ b/modules/account/front/connections/index.js @@ -16,8 +16,8 @@ export default class Controller extends Section { }; } - onDisconnect(row) { - return this.$http.delete(`AccessTokens/${row.id}`) + onDisconnect({created, userId}) { + return this.$http.post(`VnTokens/killSession`, {created, userId}) .then(() => this.$.model.refresh()) .then(() => this.vnApp.showSuccess(this.$t('Session killed'))); } From 9340d474852b40355da18e0a027c52035aee8f5c Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 19 Jul 2024 09:53:41 +0200 Subject: [PATCH 2/2] test: fix connections e2e --- e2e/paths/14-account/04_acl.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/paths/14-account/04_acl.spec.js b/e2e/paths/14-account/04_acl.spec.js index ce2a63b14..180e35e68 100644 --- a/e2e/paths/14-account/04_acl.spec.js +++ b/e2e/paths/14-account/04_acl.spec.js @@ -8,7 +8,7 @@ describe('Account ACL path', () => { beforeAll(async() => { browser = await getBrowser(); page = browser.page; - await page.loginAndModule('developer', 'account'); + await page.loginAndModule('developerBoss', 'account'); await page.accessToSection('account.acl'); });