diff --git a/src/models/notification.ts b/src/models/notification.ts
index 92ca8d3d6dfb17814fadb770b9d9b29b71db87f7..f77cd0261185a0bc77176bbc192bf745073205be 100644
--- a/src/models/notification.ts
+++ b/src/models/notification.ts
@@ -78,6 +78,9 @@ export class Notification {
@Column({ default: false })
private: boolean;
+ @Column({ default: false })
+ intersection: boolean;
+
@ManyToMany(type => User)
// @JoinTable()
@JoinTable({ name: 'notifications_target_users__users' })
@@ -105,6 +108,7 @@ export class Notification {
this.priority = notification.priority;
this.source = notification.source;
this.private = notification.private || false;
+ this.intersection = notification.intersection || false;
this.targetUsers = notification.targetUsers || [];
this.targetGroups = notification.targetGroups || [];
}
diff --git a/src/services/impl/notifications/send-notification.ts b/src/services/impl/notifications/send-notification.ts
index d119254586b09b3339b5d16815275eac01a6fb33..bf938441c5c60eac372ced5aa14874a97787c241 100644
--- a/src/services/impl/notifications/send-notification.ts
+++ b/src/services/impl/notifications/send-notification.ts
@@ -73,13 +73,26 @@ export class SendNotification implements Command {
if (this.notification.targetUsers) {
console.debug('Processing targetUsers', this.notification.targetUsers);
this.notification.private = true;
- targetUsers = await this.getOrCreateTargetUsers(transactionManager, targetChannel);
+ targetUsers = await this.getOrCreateTargetUsers(
+ transactionManager,
+ targetChannel,
+ this.notification.intersection,
+ );
}
if (this.notification.targetGroups) {
console.debug('Processing targetGroups', this.notification.targetGroups);
this.notification.private = true;
- targetGroups = await this.getOrCreateTargetGroups(transactionManager, targetChannel);
+ if (this.notification.intersection) {
+ // If intersection, pass the group list as is and the router
+ // will list the members intersected with the existing channel members
+ targetGroups = this.notification.targetGroups;
+ } else {
+ targetGroups = await this.getOrCreateTargetGroups(
+ transactionManager,
+ targetChannel,
+ );
+ }
}
const notificationInDB = await transactionManager.findOne(Notification, {
@@ -173,39 +186,62 @@ export class SendNotification implements Command {
}
// Get users objects, create and subscribe if needed
- async getOrCreateTargetUsers(transactionManager: EntityManager, targetChannel: Channel): Promise<User[]> {
- if (!targetChannel.sendPrivate) throw new ForbiddenError('This Channel does not allow direct notifications');
+ async getOrCreateTargetUsers(
+ transactionManager: EntityManager,
+ targetChannel: Channel,
+ intersection: boolean,
+ ): 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(
this.notification.targetUsers.map(async (_targetUser: User) => {
const userIdentifier = _targetUser.email.trim();
-
// Ignore subscribe status, it's handled later at routing time
const user = await transactionManager.findOne(User, {
where: [{ username: userIdentifier }, { email: userIdentifier }],
});
if (user && (await targetChannel.isMember(user))) {
targetUsers.push(user);
-
return;
}
- try {
- const user = await this.usersService.GetOrCreateUserFromUsernameOrEmail(userIdentifier);
- usersToSubscribe.push(user);
- targetUsers.push(user);
- } catch (ex) {
- console.warn('Direct notification to new member: ', userIdentifier, ex);
- throw new BadRequestError('Error adding target user: ' + userIdentifier);
+ if (!intersection) {
+ try {
+ const user =
+ await this.usersService.GetOrCreateUserFromUsernameOrEmail(
+ userIdentifier,
+ );
+ usersToSubscribe.push(user);
+ targetUsers.push(user);
+ } catch (ex) {
+ console.warn(
+ 'Direct notification to new member: ',
+ userIdentifier,
+ ex,
+ );
+ throw new BadRequestError(
+ 'Error adding target user: ' + userIdentifier,
+ );
+ }
}
}),
);
// subscribe users after creation to avoid inconsistent state
- usersToSubscribe.forEach(user => targetChannel.addMember(user));
- await transactionManager.save(targetChannel);
+ if (!intersection) {
+ usersToSubscribe.forEach(user => targetChannel.addMember(user));
+ await transactionManager.save(targetChannel);
+ }
return targetUsers;
}