From 61bb2f14ba0fff815034dbbece8e13711771827e Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 30 Nov 2020 18:45:50 +0100 Subject: [PATCH 01/15] LDAP sync hotfix --- modules/account/back/models/ldap-config.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/modules/account/back/models/ldap-config.js b/modules/account/back/models/ldap-config.js index 9f0e84c666..6b9d9f4dc4 100644 --- a/modules/account/back/models/ldap-config.js +++ b/modules/account/back/models/ldap-config.js @@ -146,17 +146,22 @@ module.exports = Self => { if (!info.hasAccount) return; - reqs = []; for (let role of info.user.roles()) { + let roleName = role.inherits().name; + + let dn = `cn=${roleName},${this.groupDn}`; let change = new ldap.Change({ operation: 'add', modification: {memberUid: userName} }); - let roleName = role.inherits().name; - let dn = `cn=${roleName},${this.groupDn}`; - reqs.push(client.modify(dn, change)); + + try { + await client.modify(dn, change); + } catch (err) { + if (err.name !== 'NoSuchObjectError') + throw err; + } } - await Promise.all(reqs); }, async getUsers(usersToSync) { From b2a3adc96ff4eacfe85ad84b7ac1734a7300bc43 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 30 Nov 2020 18:50:04 +0100 Subject: [PATCH 02/15] LDAP sync hotfix --- modules/account/back/models/ldap-config.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/modules/account/back/models/ldap-config.js b/modules/account/back/models/ldap-config.js index 9f0e84c666..6b9d9f4dc4 100644 --- a/modules/account/back/models/ldap-config.js +++ b/modules/account/back/models/ldap-config.js @@ -146,17 +146,22 @@ module.exports = Self => { if (!info.hasAccount) return; - reqs = []; for (let role of info.user.roles()) { + let roleName = role.inherits().name; + + let dn = `cn=${roleName},${this.groupDn}`; let change = new ldap.Change({ operation: 'add', modification: {memberUid: userName} }); - let roleName = role.inherits().name; - let dn = `cn=${roleName},${this.groupDn}`; - reqs.push(client.modify(dn, change)); + + try { + await client.modify(dn, change); + } catch (err) { + if (err.name !== 'NoSuchObjectError') + throw err; + } } - await Promise.all(reqs); }, async getUsers(usersToSync) { From 954ba0c69de786c8c919ba7d604e8f70a8ec0aa5 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 30 Nov 2020 19:05:33 +0100 Subject: [PATCH 03/15] Back replicas --- Jenkinsfile | 2 ++ docker-compose.yml | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index e5f668581a..f22392528d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -25,9 +25,11 @@ pipeline { switch (env.BRANCH_NAME) { case 'master': env.NODE_ENV = 'production' + env.BACK_REPLICAS = 4 break case 'test': env.NODE_ENV = 'test' + env.BACK_REPLICAS = 2 break } } diff --git a/docker-compose.yml b/docker-compose.yml index c04f7e3887..24e1446e91 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,7 +8,7 @@ services: ports: - 80 deploy: - replicas: 3 + replicas: 2 back: image: registry.verdnatura.es/salix-back:${BRANCH_NAME:?} build: . @@ -30,7 +30,7 @@ services: - /mnt/storage/dms:/var/lib/salix/dms - /mnt/storage/image:/var/lib/salix/image deploy: - replicas: 6 + replicas: ${BACK_REPLICAS:?} configs: datasources: external: true From 49111e3d730240c77412ed0e77ad2a0836206479 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 30 Nov 2020 19:11:20 +0100 Subject: [PATCH 04/15] Replicas removed from compose --- Jenkinsfile | 2 -- docker-compose.yml | 4 ---- 2 files changed, 6 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 7cf0861c02..d87695cc42 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -25,11 +25,9 @@ pipeline { switch (env.BRANCH_NAME) { case 'master': env.NODE_ENV = 'production' - env.BACK_REPLICAS = 4 break case 'test': env.NODE_ENV = 'test' - env.BACK_REPLICAS = 2 break } } diff --git a/docker-compose.yml b/docker-compose.yml index 24e1446e91..b244166ae1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,8 +7,6 @@ services: dockerfile: front/Dockerfile ports: - 80 - deploy: - replicas: 2 back: image: registry.verdnatura.es/salix-back:${BRANCH_NAME:?} build: . @@ -29,8 +27,6 @@ services: - /mnt/storage/pdfs:/var/lib/salix/pdfs - /mnt/storage/dms:/var/lib/salix/dms - /mnt/storage/image:/var/lib/salix/image - deploy: - replicas: ${BACK_REPLICAS:?} configs: datasources: external: true From cc9f313867ab63cc23cb9ae8aafe420adcfb25fe Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 30 Nov 2020 19:20:52 +0100 Subject: [PATCH 05/15] Docker replicas restored --- Jenkinsfile | 2 ++ docker-compose.yml | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index d87695cc42..7cf0861c02 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -25,9 +25,11 @@ pipeline { switch (env.BRANCH_NAME) { case 'master': env.NODE_ENV = 'production' + env.BACK_REPLICAS = 4 break case 'test': env.NODE_ENV = 'test' + env.BACK_REPLICAS = 2 break } } diff --git a/docker-compose.yml b/docker-compose.yml index b244166ae1..24e1446e91 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,6 +7,8 @@ services: dockerfile: front/Dockerfile ports: - 80 + deploy: + replicas: 2 back: image: registry.verdnatura.es/salix-back:${BRANCH_NAME:?} build: . @@ -27,6 +29,8 @@ services: - /mnt/storage/pdfs:/var/lib/salix/pdfs - /mnt/storage/dms:/var/lib/salix/dms - /mnt/storage/image:/var/lib/salix/image + deploy: + replicas: ${BACK_REPLICAS:?} configs: datasources: external: true From 6f6f23bec46d651a555ebd31d043df440488434f Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Wed, 9 Dec 2020 12:28:18 +0100 Subject: [PATCH 06/15] LDAP user sync only syncs changed attributes --- modules/account/back/models/ldap-config.js | 143 ++++++++++++++------- 1 file changed, 95 insertions(+), 48 deletions(-) diff --git a/modules/account/back/models/ldap-config.js b/modules/account/back/models/ldap-config.js index 6b9d9f4dc4..819659066d 100644 --- a/modules/account/back/models/ldap-config.js +++ b/modules/account/back/models/ldap-config.js @@ -35,14 +35,13 @@ module.exports = Self => { accountConfig } = this; - let newEntry; + let dn = `uid=${userName},${this.userDn}`; if (info.hasAccount) { let {user} = info; let oldUser = await client.searchOne(this.userDn, { scope: 'sub', - attributes: ['userPassword', 'sambaNTPassword'], filter: `&(uid=${userName})` }); @@ -52,7 +51,7 @@ module.exports = Self => { ? nameArgs.splice(1).join(' ') : '-'; - newEntry = { + let newEntry = { uid: userName, objectClass: [ 'inetOrgPerson', @@ -101,67 +100,115 @@ module.exports = Self => { if (newEntry[prop] == null) delete newEntry[prop]; } + + if (oldUser) { + let changes = []; + let skipProps = new Set([ + 'dn', + 'controls' + ]); + + for (let prop in oldUser) { + let deleteProp = !skipProps.has(prop) + && !newEntry.hasOwnProperty(prop); + if (!deleteProp) continue; + changes.push(new ldap.Change({ + operation: 'delete', + modification: { + [prop]: oldUser[prop] + } + })); + } + for (let prop in newEntry) { + if (this.isEqual(oldUser[prop], newEntry[prop])) + continue; + changes.push(new ldap.Change({ + operation: 'replace', + modification: { + [prop]: newEntry[prop] + } + })); + } + + if (changes.length) + await client.modify(dn, changes); + } else + await client.add(dn, newEntry); + } else { + try { + await client.del(dn); + console.log(` -> User '${userName}' removed from LDAP`); + } catch (e) { + if (e.name !== 'NoSuchObjectError') throw e; + } } + }, - // Remove and recreate (if applicable) user - - let dn = `uid=${userName},${this.userDn}`; - let operation; - - try { - await client.del(dn); - operation = 'delete'; - } catch (e) { - if (e.name !== 'NoSuchObjectError') throw e; - } - - if (info.hasAccount) { - await client.add(dn, newEntry); - operation = 'add'; - } - - if (operation === 'delete') - console.log(` -> User '${userName}' removed from LDAP`); + isEqual(a, b) { + if (Array.isArray(a) && Array.isArray(b)) { + if (a.length !== b.length) + return false; + for (let element of a) { + if (b.indexOf(element) === -1) + return false; + } + return true; + } else + return a == b; }, async syncUserGroups(userName, info) { let {client} = this; + let {user} = info; + let groupDn = this.groupDn; let opts = { scope: 'sub', - attributes: ['dn'], + attributes: ['dn', 'cn'], filter: `&(memberUid=${userName})(objectClass=posixGroup)` }; - let oldGroups = await client.searchAll(this.groupDn, opts); + let oldGroups = await client.searchAll(groupDn, opts); - let reqs = []; - for (let oldGroup of oldGroups) { - let change = new ldap.Change({ - operation: 'delete', - modification: {memberUid: userName} - }); - reqs.push(client.modify(oldGroup.dn, change)); + let deleteGroups = []; + let addGroups = []; + + if (info.hasAccount) { + let oldSet = new Set(); + oldGroups.forEach(e => oldSet.add(e.cn)); + + let newSet = new Set(); + user.roles().forEach(e => newSet.add(e.inherits().name)); + + for (let group of oldGroups) { + if (!newSet.has(group.cn)) + deleteGroups.push(group.cn); + } + for (let role of user.roles()) { + if (!oldSet.has(role.inherits().name)) + addGroups.push(role.inherits().name); + } + } else { + for (let group of oldGroups) + deleteGroups.push(group.cn); } - await Promise.all(reqs); - if (!info.hasAccount) return; - - for (let role of info.user.roles()) { - let roleName = role.inherits().name; - - let dn = `cn=${roleName},${this.groupDn}`; - let change = new ldap.Change({ - operation: 'add', - modification: {memberUid: userName} - }); - - try { - await client.modify(dn, change); - } catch (err) { - if (err.name !== 'NoSuchObjectError') - throw err; + async function applyOperations(groups, operation) { + for (let group of groups) { + try { + let dn = `cn=${group},${groupDn}`; + await client.modify(dn, new ldap.Change({ + operation, + modification: {memberUid: userName} + })); + } catch (err) { + if (err.name !== 'NoSuchObjectError') + throw err; + } } } + + await applyOperations(deleteGroups, 'delete'); + await applyOperations(addGroups, 'add'); }, async getUsers(usersToSync) { From 292a46106e760772f8e98f81aa89f152e5f278fb Mon Sep 17 00:00:00 2001 From: joan Date: Mon, 4 Jan 2021 15:08:52 +0100 Subject: [PATCH 07/15] Translation fix --- back/methods/image/upload.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/methods/image/upload.js b/back/methods/image/upload.js index 649d13c680..a93ead6510 100644 --- a/back/methods/image/upload.js +++ b/back/methods/image/upload.js @@ -48,7 +48,7 @@ module.exports = Self => { throw new UserError(`You don't have enough privileges`); if (process.env.NODE_ENV == 'test') - throw new UserError(`You can't upload images on the test instance`); + throw new UserError(`You can't upload images on the test environment`); // Upload file to temporary path const tempContainer = await TempContainer.container(args.collection); From 8b3af8851ccf05f69d7be1773aaef64160e81d90 Mon Sep 17 00:00:00 2001 From: bernat Date: Mon, 11 Jan 2021 11:29:47 +0100 Subject: [PATCH 08/15] fix trigger itemTag --- db/changes/12270-wisemen/00-itemTag.sql | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 db/changes/12270-wisemen/00-itemTag.sql diff --git a/db/changes/12270-wisemen/00-itemTag.sql b/db/changes/12270-wisemen/00-itemTag.sql new file mode 100644 index 0000000000..9762314f55 --- /dev/null +++ b/db/changes/12270-wisemen/00-itemTag.sql @@ -0,0 +1,19 @@ +DROP TRIGGER IF EXISTS `vn`.`itemTag_afterUpdate`; + +DELIMITER $$ +USE `vn`$$ +CREATE DEFINER=`root`@`%` TRIGGER `vn`.`itemTag_afterUpdate` + AFTER UPDATE ON `itemTag` FOR EACH ROW +trig: BEGIN + IF @isTriggerDisabled THEN + LEAVE trig; + END IF; + + DROP TEMPORARY TABLE IF EXISTS tmp.item; + CREATE TEMPORARY TABLE tmp.item + SELECT vItem id; + + CALL item_refreshTags(); + DROP TEMPORARY TABLE tmp.item; +END$$ +DELIMITER ; \ No newline at end of file From 880093921e1a7965a6aad656706f036fece3dc98 Mon Sep 17 00:00:00 2001 From: joan Date: Tue, 12 Jan 2021 07:45:13 +0100 Subject: [PATCH 09/15] Vn-th sortable icon hotfix --- front/core/components/th/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/front/core/components/th/index.js b/front/core/components/th/index.js index f815056f6e..b9ea8fde8a 100644 --- a/front/core/components/th/index.js +++ b/front/core/components/th/index.js @@ -1,4 +1,5 @@ import ngModule from '../../module'; +import './style.scss'; export default class Th { constructor($element) { From dd29b351d28ae3ff461a283fda64572f452d5854 Mon Sep 17 00:00:00 2001 From: joan Date: Tue, 12 Jan 2021 14:25:01 +0100 Subject: [PATCH 10/15] Disabled loggable --- modules/worker/back/models/calendar.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/worker/back/models/calendar.json b/modules/worker/back/models/calendar.json index 199d81e6c7..1da7179c4e 100644 --- a/modules/worker/back/models/calendar.json +++ b/modules/worker/back/models/calendar.json @@ -1,6 +1,6 @@ { "name": "Calendar", - "base": "Loggable", + "base": "VnModel", "log": { "model": "WorkerLog", "relation": "labour" From 7bcad01bef560cfdd9b9aa4c4a29a5ab20e7bfed Mon Sep 17 00:00:00 2001 From: joan Date: Tue, 12 Jan 2021 14:25:01 +0100 Subject: [PATCH 11/15] Disabled loggable --- modules/worker/back/models/calendar.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/worker/back/models/calendar.json b/modules/worker/back/models/calendar.json index 199d81e6c7..1da7179c4e 100644 --- a/modules/worker/back/models/calendar.json +++ b/modules/worker/back/models/calendar.json @@ -1,6 +1,6 @@ { "name": "Calendar", - "base": "Loggable", + "base": "VnModel", "log": { "model": "WorkerLog", "relation": "labour" From 975e158ebbea62e7ef23935480f18a2356639403 Mon Sep 17 00:00:00 2001 From: bernat Date: Wed, 13 Jan 2021 08:17:41 +0100 Subject: [PATCH 12/15] itemTag trigger --- db/changes/12270-wisemen/00-itemTag.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/changes/12270-wisemen/00-itemTag.sql b/db/changes/12270-wisemen/00-itemTag.sql index 9762314f55..f1e9370d5f 100644 --- a/db/changes/12270-wisemen/00-itemTag.sql +++ b/db/changes/12270-wisemen/00-itemTag.sql @@ -11,7 +11,7 @@ trig: BEGIN DROP TEMPORARY TABLE IF EXISTS tmp.item; CREATE TEMPORARY TABLE tmp.item - SELECT vItem id; + SELECT NEW.itemFk id; CALL item_refreshTags(); DROP TEMPORARY TABLE tmp.item; From 5059abca809ba189f120138179910b5e7b4f521d Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 13 Jan 2021 10:40:51 +0100 Subject: [PATCH 13/15] Dms edit hotfix --- modules/worker/front/dms/index/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/worker/front/dms/index/index.html b/modules/worker/front/dms/index/index.html index d74d65bfa8..e3535f7bcb 100644 --- a/modules/worker/front/dms/index/index.html +++ b/modules/worker/front/dms/index/index.html @@ -60,7 +60,7 @@ - From 0e9160f61b2e93bd54cd5df9d89a74bf876aaba6 Mon Sep 17 00:00:00 2001 From: joan Date: Wed, 13 Jan 2021 11:05:30 +0100 Subject: [PATCH 14/15] Letter debtor hotfix --- print/templates/email/letter-debtor-nd/sql/client.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/print/templates/email/letter-debtor-nd/sql/client.sql b/print/templates/email/letter-debtor-nd/sql/client.sql index 1f672879b6..aad907a4b1 100644 --- a/print/templates/email/letter-debtor-nd/sql/client.sql +++ b/print/templates/email/letter-debtor-nd/sql/client.sql @@ -7,4 +7,4 @@ FROM client c JOIN company AS cny JOIN supplierAccount AS sa ON sa.id = cny.supplierAccountFk JOIN bankEntity be ON be.id = sa.bankEntityFk -WHERE c.id = ? AND cny.id = ?` \ No newline at end of file +WHERE c.id = ? AND cny.id = ? \ No newline at end of file From 53e80d29c87b515b0db13c4ae921f6b15a2e00aa Mon Sep 17 00:00:00 2001 From: joan Date: Thu, 14 Jan 2021 13:41:50 +0100 Subject: [PATCH 15/15] Consumption hotfix --- modules/client/front/consumption/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/client/front/consumption/index.js b/modules/client/front/consumption/index.js index e36e94682a..394220dcb6 100644 --- a/modules/client/front/consumption/index.js +++ b/modules/client/front/consumption/index.js @@ -29,7 +29,7 @@ class Controller extends Section { get reportParams() { const userParams = this.$.model.userParams; return Object.assign({ - authorization: this.vnToken.token, + recipient: this.client.email, recipientId: this.client.id }, userParams); }