diff --git a/CHANGELOG.md b/CHANGELOG.md index bf8cfd17cc..91ce818a83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2306.01] - 2023-02-23 + +### Added +- + +### Changed +- + +### Fixed +- + ## [2304.01] - 2023-02-09 ### Added diff --git a/back/models/notificationAcl.json b/back/models/notificationAcl.json index e3e97f52de..a201879610 100644 --- a/back/models/notificationAcl.json +++ b/back/models/notificationAcl.json @@ -6,6 +6,16 @@ "table": "util.notificationAcl" } }, + "properties":{ + "notificationFk": { + "id": true, + "type": "number" + }, + "roleFk":{ + "id": true, + "type": "number" + } + }, "relations": { "notification": { "type": "belongsTo", diff --git a/back/models/notificationSubscription.js b/back/models/notificationSubscription.js new file mode 100644 index 0000000000..f1b2811fa7 --- /dev/null +++ b/back/models/notificationSubscription.js @@ -0,0 +1,62 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.observe('before save', async function(ctx) { + const models = Self.app.models; + const userId = ctx.options.accessToken.userId; + const user = await ctx.instance.userFk; + const modifiedUser = await getUserToModify(null, user, models); + + if (userId != modifiedUser.id && userId != modifiedUser.bossFk) + throw new UserError('You dont have permission to modify this user'); + }); + + Self.remoteMethod('deleteNotification', { + description: 'Deletes a notification subscription', + accepts: [ + { + arg: 'ctx', + type: 'object', + http: {source: 'context'} + }, + { + arg: 'notificationId', + type: 'number', + required: true + }, + ], + returns: { + type: 'object', + root: true + }, + http: { + verb: 'POST', + path: '/deleteNotification' + } + }); + + Self.deleteNotification = async function(ctx, notificationId) { + const models = Self.app.models; + const user = ctx.req.accessToken.userId; + const modifiedUser = await getUserToModify(notificationId, null, models); + + if (user != modifiedUser.id && user != modifiedUser.bossFk) + throw new UserError('You dont have permission to modify this user'); + + await models.NotificationSubscription.destroyById(notificationId); + }; + + async function getUserToModify(notificationId, userFk, models) { + let userToModify = userFk; + if (notificationId) { + const subscription = await models.NotificationSubscription.findById(notificationId); + userToModify = subscription.userFk; + } + return await models.Worker.findOne({ + fields: ['id', 'bossFk'], + where: { + id: userToModify + } + }); + } +}; diff --git a/back/models/notificationSubscription.json b/back/models/notificationSubscription.json index 43fa6db274..a640e09171 100644 --- a/back/models/notificationSubscription.json +++ b/back/models/notificationSubscription.json @@ -7,15 +7,18 @@ } }, "properties": { - "notificationFk": { + "id": { "type": "number", "id": true, - "description": "Identifier" + "description": "Primary key" + }, + "notificationFk": { + "type": "number", + "description": "Foreign key to Notification" }, "userFk": { "type": "number", - "id": true, - "description": "Identifier" + "description": "Foreign key to Account" } }, "relations": { diff --git a/back/models/specs/notificationSubscription.spec.js b/back/models/specs/notificationSubscription.spec.js new file mode 100644 index 0000000000..c7f37abedd --- /dev/null +++ b/back/models/specs/notificationSubscription.spec.js @@ -0,0 +1,74 @@ +const models = require('vn-loopback/server/server').models; + +describe('loopback model NotificationSubscription', () => { + it('Should fail to delete a notification if the user is not editing itself or a subordinate', async() => { + const tx = await models.NotificationSubscription.beginTransaction({}); + + try { + const options = {transaction: tx}; + const user = 9; + const notificationSubscriptionId = 2; + const ctx = {req: {accessToken: {userId: user}}}; + const notification = await models.NotificationSubscription.findById(notificationSubscriptionId); + + let error; + + try { + await models.NotificationSubscription.deleteNotification(ctx, notification.id, options); + } catch (e) { + error = e; + } + + expect(error.message).toContain('You dont have permission to modify this user'); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('Should delete a notification if the user is editing itself', async() => { + const tx = await models.NotificationSubscription.beginTransaction({}); + + try { + const options = {transaction: tx}; + const user = 9; + const notificationSubscriptionId = 4; + const ctx = {req: {accessToken: {userId: user}}}; + const notification = await models.NotificationSubscription.findById(notificationSubscriptionId); + + await models.NotificationSubscription.deleteNotification(ctx, notification.id, options); + + const deletedNotification = await models.NotificationSubscription.findById(notificationSubscriptionId); + + expect(deletedNotification).toBeNull(); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('Should delete a notification if the user is editing a subordinate', async() => { + const tx = await models.NotificationSubscription.beginTransaction({}); + + try { + const options = {transaction: tx}; + const user = 9; + const notificationSubscriptionId = 5; + const ctx = {req: {accessToken: {userId: user}}}; + const notification = await models.NotificationSubscription.findById(notificationSubscriptionId); + + await models.NotificationSubscription.deleteNotification(ctx, notification.id, options); + + const deletedNotification = await models.NotificationSubscription.findById(notificationSubscriptionId); + + expect(deletedNotification).toBeNull(); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); + diff --git a/db/changes/230401/00-acl_notifications.sql b/db/changes/230401/00-acl_notifications.sql new file mode 100644 index 0000000000..ab40b16a58 --- /dev/null +++ b/db/changes/230401/00-acl_notifications.sql @@ -0,0 +1,4 @@ +INSERT INTO `salix`.`ACL` (model,property,accessType,principalId) + VALUES + ('NotificationSubscription','*','*','employee'), + ('NotificationAcl','*','READ','employee'); diff --git a/db/changes/230401/00-uniqueKeyNotificationSubscription.sql b/db/changes/230401/00-uniqueKeyNotificationSubscription.sql new file mode 100644 index 0000000000..623ecf7707 --- /dev/null +++ b/db/changes/230401/00-uniqueKeyNotificationSubscription.sql @@ -0,0 +1,4 @@ +ALTER TABLE + `util`.`notificationSubscription` +ADD + CONSTRAINT `notificationSubscription_UN` UNIQUE KEY (`notificationFk`, `userFk`); \ No newline at end of file diff --git a/db/changes/230401/01-alter_notSubs.sql b/db/changes/230401/01-alter_notSubs.sql new file mode 100644 index 0000000000..07ea7c2bf5 --- /dev/null +++ b/db/changes/230401/01-alter_notSubs.sql @@ -0,0 +1,7 @@ +ALTER TABLE `util`.`notificationSubscription` +ADD `id` int(11) auto_increment NULL, +DROP PRIMARY KEY, +ADD CONSTRAINT PRIMARY KEY (`id`); + +ALTER TABLE `util`.`notificationSubscription` +ADD KEY `notificationSubscription_ibfk_1` (`notificationFk`); diff --git a/db/changes/230601/.gitkeep b/db/changes/230601/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 218fcb9ca4..bb4f00ff57 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -1954,10 +1954,6 @@ INSERT INTO `vn`.`workerBusinessType` (`id`, `name`, `isFullTime`, `isPermanent` (100, 'INDEFINIDO A TIEMPO COMPLETO', 1, 1, 1), (109, 'CONVERSION DE TEMPORAL EN INDEFINIDO T.COMPLETO', 1, 1, 1); -INSERT INTO `vn`.`businessCategory` (`id`, `description`, `rate`) - VALUES - (1, 'basic employee', 1); - UPDATE `vn`.`business` b SET `rate` = 7, `workerBusinessCategoryFk` = 1, @@ -2705,7 +2701,10 @@ INSERT INTO `util`.`notificationSubscription` (`notificationFk`, `userFk`) VALUES (1, 1109), (1, 1110), - (3, 1109); + (3, 1109), + (1,9), + (1,3); + INSERT INTO `vn`.`routeConfig` (`id`, `defaultWorkCenterFk`) VALUES diff --git a/package.json b/package.json index 46b7d4ffcf..f9828624db 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-back", - "version": "23.04.01", + "version": "23.06.01", "author": "Verdnatura Levante SL", "description": "Salix backend", "license": "GPL-3.0",