diff --git a/src/models/channel.ts b/src/models/channel.ts index 7fa8561caa61144531e55a8f9c55f081090c7eb3..cee299ecfee3fc6c3e8695f115b754e7d3b3919c 100644 --- a/src/models/channel.ts +++ b/src/models/channel.ts @@ -316,7 +316,7 @@ export class Channel extends ApiKeyObject { // Checks if user has authorization to send Notification to the channel // via Form/API - async canSendByForm(authorizationBag: AuthorizationBag) { + async canSendByForm(authorizationBag: AuthorizationBag, targetedNotification: boolean = false) { // No permission to send by Form set if (!this.submissionByForm) return false; @@ -336,6 +336,12 @@ export class Channel extends ApiKeyObject { if (this.submissionByForm.includes(SubmissionByForm.administrators) && (await this.isAdmin(authorizationBag))) { return true; } + + // Targeted notifications are not allowed for members + if (targetedNotification) { + return false; + } + // If user is channel member if (this.submissionByForm.includes(SubmissionByForm.members) && (await this.isMember(authorizationBag.user))) { return true; diff --git a/src/services/impl/notifications/send-notification.ts b/src/services/impl/notifications/send-notification.ts index be7565762a9a4a9c84bd80d7f77503290b94241e..d119254586b09b3339b5d16815275eac01a6fb33 100644 --- a/src/services/impl/notifications/send-notification.ts +++ b/src/services/impl/notifications/send-notification.ts @@ -31,7 +31,12 @@ export class SendNotification implements Command { if (!targetChannel) throw new NotFoundError('Channel does not exist'); if (this.authorizationBag) { - if (!(await targetChannel.canSendByForm(this.authorizationBag))) + if ( + !(await targetChannel.canSendByForm( + this.authorizationBag, + this.notification.targetUsers || this.notification.targetGroups || this.notification.targetData, + )) + ) throw new ForbiddenError('Sending to Channel not Authorized !'); } else { // Call from the /unauthenticated @@ -41,13 +46,38 @@ export class SendNotification implements Command { this.validateFields(); let targetUsers = []; + let targetGroups = []; + + // Extract targetData values (strings comma separated) + // and fill extracted values in targetUsers and targetGroups + if (this.notification.targetData) { + console.debug('Processing targetData', this.notification.targetData); + if (!this.notification.targetUsers) this.notification.targetUsers = []; + if (!this.notification.targetGroups) this.notification.targetGroups = []; + + this.notification.targetData.forEach(id => { + if (!id) return; + const identifier = id.toLowerCase(); + // no @ mean it's a group name (or a mistake that we'll ignore) + if (!identifier.includes('@')) this.notification.targetGroups.push({ groupIdentifier: identifier }); + // @domain is not @cern.ch then it's an external user + else if (!identifier.includes('@cern.ch')) this.notification.targetUsers.push({ email: identifier }); + // email@cern.ch contains a - so it's a group + else if (identifier.includes('-')) + this.notification.targetGroups.push({ groupIdentifier: identifier.replace('@cern.ch', '') }); + // And the rest is handled as user email + else this.notification.targetUsers.push({ email: identifier }); + }); + } + if (this.notification.targetUsers) { + console.debug('Processing targetUsers', this.notification.targetUsers); this.notification.private = true; targetUsers = await this.getOrCreateTargetUsers(transactionManager, targetChannel); } - let targetGroups = []; if (this.notification.targetGroups) { + console.debug('Processing targetGroups', this.notification.targetGroups); this.notification.private = true; targetGroups = await this.getOrCreateTargetGroups(transactionManager, targetChannel); } @@ -146,9 +176,6 @@ export class SendNotification implements Command { async getOrCreateTargetUsers(transactionManager: EntityManager, targetChannel: Channel): Promise<User[]> { if (!targetChannel.sendPrivate) throw new ForbiddenError('This Channel does not allow direct notifications'); - if (!(await targetChannel.isAdmin(this.authorizationBag))) - throw new ForbiddenError('Sending direct notifications to Channel not Authorized'); - const usersToSubscribe = []; const targetUsers = []; await Promise.all( @@ -186,9 +213,6 @@ export class SendNotification implements Command { async getOrCreateTargetGroups(transactionManager: EntityManager, channel: Channel): Promise<Group[]> { if (!channel.sendPrivate) throw new ForbiddenError('This Channel does not allow direct notifications'); - if (!(await channel.isAdmin(this.authorizationBag))) - throw new ForbiddenError('Sending direct notifications to Channel not Authorized'); - const groupsToSubscribe = []; const targetGroups = []; await Promise.all(