Repository: reactiflux/discord-irc (js)

Issue:
IRC users can ping @everyone
Users on IRC can type `@everyone` to ping everyone, even when this is disabled in all the roles that a bot is a member of.

## User

![image](https://user-images.githubusercontent.com/2122943/60191096-ab82c300-982b-11e9-8601-989c423b4e77.png)

## Roles

* User is a member of Bot and Everyone, both have mention everyone disabled.
* The channel has mention everyone disabled on both Bot and Everyone.
* None of these roles have admin privileges set

### Bot role

![image](https://user-images.githubusercontent.com/2122943/60191058-9a39b680-982b-11e9-9ebc-2805448bd9c1.png)


Pull request description:
Defer to discord for disabling at-everyone in webhooks
Currently, webhooks permit IRC users to send `@everyone` and `@here` pings through, as they're not stripped (and webhooks always have this permission).

Discord already has permissions for whether the bot can ping everyone, and the webhook send method has a `disableEveryone` option, so let's defer to the inbuilt Discord permission for this.

When permissions can't be found (shouldn't happen), defaults to disabling the pings.

Fixes #494. Supersedes #496 and #457.

Patch:
diff --git a/lib/bot.js b/lib/bot.js
index 8bc83ac..925d516 100644
--- a/lib/bot.js
+++ b/lib/bot.js
@@ -555,12 +555,18 @@ class Bot {
     const webhook = this.findWebhook(channel);
     if (webhook) {
       logger.debug('Sending message to Discord via webhook', withMentions, channel, '->', `#${discordChannel.name}`);
+      const permissions = discordChannel.permissionsFor(this.discord.user);
+      let canPingEveryone = false;
+      if (permissions) {
+        canPingEveryone = permissions.has(discord.Permissions.FLAGS.MENTION_EVERYONE);
+      }
       const avatarURL = this.getDiscordAvatar(author, channel);
       const username = _.padEnd(author.substring(0, USERNAME_MAX_LENGTH), USERNAME_MIN_LENGTH, '_');
       webhook.client.sendMessage(withMentions, {
         username,
         text,
-        avatarURL
+        avatarURL,
+        disableEveryone: !canPingEveryone,
       }).catch(logger.error);
       return;
     }


Test patch:
diff --git a/test/bot.test.js b/test/bot.test.js
index 6f1a1a5..e6c9e7c 100644
--- a/test/bot.test.js
+++ b/test/bot.test.js
@@ -986,6 +986,7 @@ describe('Bot', function () {
       username: 'n_',
       text,
       avatarURL: null,
+      disableEveryone: true,
     });
   });
 
@@ -999,6 +1000,48 @@ describe('Bot', function () {
       username: '12345678901234567890123456789012',
       text,
       avatarURL: null,
+      disableEveryone: true,
+    });
+  });
+
+  it('does not ping everyone if user lacks permission', function () {
+    const newConfig = { ...config, webhooks: { '#discord': 'https://discordapp.com/api/webhooks/id/token' } };
+    const bot = new Bot(newConfig);
+    const text = 'message';
+    const permission = discord.Permissions.FLAGS.VIEW_CHANNEL
+      + discord.Permissions.FLAGS.SEND_MESSAGES;
+    bot.discord.channels.get('1234').setPermissionStub(
+      bot.discord.user,
+      new discord.Permissions(permission),
+    );
+    bot.connect();
+    bot.sendToDiscord('nick', '#irc', text);
+    this.sendWebhookMessageStub.should.have.been.calledWith(text, {
+      username: 'nick',
+      text,
+      avatarURL: null,
+      disableEveryone: true,
+    });
+  });
+
+  it('sends @everyone messages if the bot has permission to do so', function () {
+    const newConfig = { ...config, webhooks: { '#discord': 'https://discordapp.com/api/webhooks/id/token' } };
+    const bot = new Bot(newConfig);
+    const text = 'message';
+    const permission = discord.Permissions.FLAGS.VIEW_CHANNEL
+      + discord.Permissions.FLAGS.SEND_MESSAGES
+      + discord.Permissions.FLAGS.MENTION_EVERYONE;
+    bot.discord.channels.get('1234').setPermissionStub(
+      bot.discord.user,
+      new discord.Permissions(permission),
+    );
+    bot.connect();
+    bot.sendToDiscord('nick', '#irc', text);
+    this.sendWebhookMessageStub.should.have.been.calledWith(text, {
+      username: 'nick',
+      text,
+      avatarURL: null,
+      disableEveryone: false,
     });
   });
 
diff --git a/test/stubs/discord-stub.js b/test/stubs/discord-stub.js
index 12bd4c9..934fe9e 100644
--- a/test/stubs/discord-stub.js
+++ b/test/stubs/discord-stub.js
@@ -29,6 +29,9 @@ export default function createDiscordStub(sendStub, discordUsers) {
       }, textChannel);
       const textChannelObj = new discord.TextChannel(guild, textChannelData);
       textChannelObj.send = sendStub;
+      const permissions = new discord.Collection();
+      textChannelObj.setPermissionStub = (user, perms) => permissions.set(user, perms);
+      textChannelObj.permissionsFor = user => permissions.get(user);
       this.channels.set(textChannelObj.id, textChannelObj);
       return textChannelObj;
     }