diff --git a/back/methods/account/set-password.js b/back/methods/account/set-password.js index fc54b5abe..b27d5c330 100644 --- a/back/methods/account/set-password.js +++ b/back/methods/account/set-password.js @@ -1,4 +1,3 @@ - module.exports = Self => { Self.remoteMethod('setPassword', { description: 'Sets the user password', diff --git a/db/changes/10460-mother/00-salix_ACL.sql b/db/changes/10460-mother/00-salix_ACL.sql new file mode 100644 index 000000000..d8200b3d2 --- /dev/null +++ b/db/changes/10460-mother/00-salix_ACL.sql @@ -0,0 +1,9 @@ +DELETE FROM `salix`.`ACL` + WHERE id=1 AND property='*' AND principalId='employee'; +INSERT INTO `salix`.`ACL` (model,property,accessType,principalId) + VALUES + -- ('Account','*','READ','marketing'), + -- ('Account','*','READ','hr'), + -- ('Account','setPassword','WRITE','hr'), + ('Client','setPassword','WRITE','salesPerson'), + ('Client','updateUser','WRITE','salesPerson'); diff --git a/e2e/paths/02-client/07_edit_web_access.spec.js b/e2e/paths/02-client/07_edit_web_access.spec.js index bcd476f6b..9836b1e70 100644 --- a/e2e/paths/02-client/07_edit_web_access.spec.js +++ b/e2e/paths/02-client/07_edit_web_access.spec.js @@ -50,7 +50,7 @@ describe('Client Edit web access path', () => { await page.accessToSection('client.card.log'); }); - it(`should confirm the last log is showing the updated client name and no modifications on the active checkbox`, async() => { + it(`should confirm the last log shows updated client name and no modifications on the active checkbox`, async() => { let lastModificationPreviousValue = await page .waitToGetProperty(selectors.clientLog.lastModificationPreviousValue, 'innerText'); let lastModificationCurrentValue = await page @@ -60,7 +60,7 @@ describe('Client Edit web access path', () => { expect(lastModificationCurrentValue).toEqual('name Hulk active false'); }); - it(`should confirm the penultimate log is showing the updated avtive field and no modifications on the client name`, async() => { + it(`should confirm the penultimate log shows updated active field and no modifications on client name`, async() => { let penultimateModificationPreviousValue = await page .waitToGetProperty(selectors.clientLog.penultimateModificationPreviousValue, 'innerText'); let penultimateModificationCurrentValue = await page diff --git a/modules/client/back/methods/client/setPassword.js b/modules/client/back/methods/client/setPassword.js new file mode 100644 index 000000000..022be5e2e --- /dev/null +++ b/modules/client/back/methods/client/setPassword.js @@ -0,0 +1,36 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.remoteMethod('setPassword', { + description: `Sets a client's account password`, + accessType: 'WRITE', + accepts: [ + { + arg: 'id', + type: 'number', + description: 'The user id', + http: {source: 'path'} + }, + { + arg: 'newPassword', + type: 'string', + description: 'The new password', + required: true + }, + ], + http: { + path: `/:id/setPassword`, + verb: 'PATCH' + } + }); + + Self.setPassword = async(id, newPassword) => { + const models = Self.app.models; + const isWorker = await models.Worker.findById(id); + + if (isWorker) + throw new UserError('Cannot set password of a worker'); + + await models.Account.setPassword(id, newPassword); + }; +}; diff --git a/modules/client/back/methods/client/specs/setPassword.spec.js b/modules/client/back/methods/client/specs/setPassword.spec.js new file mode 100644 index 000000000..42fe266eb --- /dev/null +++ b/modules/client/back/methods/client/specs/setPassword.spec.js @@ -0,0 +1,40 @@ +const {models} = require('vn-loopback/server/server'); +const UserError = require('vn-loopback/util/user-error'); +const LoopBackContext = require('loopback-context'); + +describe('client setPassword()', () => { + const salesPersonId = 18; + const employeeId = 1; + const customerId = 1101; + + const activeCtx = { + accessToken: {userId: employeeId}, + http: { + req: { + headers: {origin: 'http://localhost'} + } + } + }; + + beforeEach(() => { + spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ + active: activeCtx + }); + }); + + it('should throw an error when the target customer is also a worker', async() => { + const ctx = {req: {accessToken: {userId: salesPersonId}}}; + + const req = models.Client.setPassword(ctx, employeeId, 'Very$ecurePa22.'); + + await expectAsync(req).toBeRejectedWithError(UserError, `Cannot set password of a worker`); + }); + + it('should update password when it passes requirements', async() => { + const ctx = {req: {accessToken: {userId: salesPersonId}}}; + + const req = models.Client.setPassword(ctx, customerId, 'Very$ecurePa22.'); + + await expectAsync(req).toBeResolved(); + }); +}); diff --git a/modules/client/back/models/client.js b/modules/client/back/models/client.js index 5ccc1ec64..ab76b77f8 100644 --- a/modules/client/back/models/client.js +++ b/modules/client/back/models/client.js @@ -31,6 +31,7 @@ module.exports = Self => { require('../methods/client/createReceipt')(Self); require('../methods/client/updatePortfolio')(Self); require('../methods/client/checkDuplicated')(Self); + require('../methods/client/setPassword')(Self); // Validations diff --git a/modules/client/front/web-access/index.js b/modules/client/front/web-access/index.js index a37e72a9d..2cfff8750 100644 --- a/modules/client/front/web-access/index.js +++ b/modules/client/front/web-access/index.js @@ -44,11 +44,11 @@ export default class Controller extends Section { throw new Error(`You must enter a new password`); if (this.newPassword != this.repeatPassword) throw new Error(`Passwords don't match`); - let account = { - password: this.newPassword + const account = { + newPassword: this.newPassword }; - this.$http.patch(`Accounts/${this.client.id}`, account).then(res => { + this.$http.patch(`Clients/${this.client.id}/setPassword`, account).then(res => { this.vnApp.showSuccess(this.$t('Data saved!')); }); } catch (e) {