diff --git a/src/bot.ts b/src/bot.ts index 30a0455e35a17b7c80ae3c021365b1b60fbe00e2..563cc31b98defdb2741267c453bcf800ad5c2c79 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -687,31 +687,6 @@ export class DiscordBot { } } - // Check if there's an ongoing bridge request - if ((msg.content === "!approve" || msg.content === "!deny") && this.provisioner.HasPendingRequest(chan)) { - try { - const isApproved = msg.content === "!approve"; - const successfullyBridged = await this.provisioner.MarkApproved(chan, msg.member, isApproved); - if (successfullyBridged && isApproved) { - await msg.channel.sendMessage("Thanks for your response! The matrix bridge has been approved"); - } else if (successfullyBridged && !isApproved) { - await msg.channel.sendMessage("Thanks for your response! The matrix bridge has been declined"); - } else { - await msg.channel.sendMessage("Thanks for your response, however" + - "the time for responses has expired - sorry!"); - } - } catch (err) { - if (err.message === "You do not have permission to manage webhooks in this channel") { - await msg.channel.sendMessage(err.message); - } else { - log.error("Error processing room approval"); - log.error(err); - } - } - - return; // stop processing - we're approving/declining the bridge request - } - // check if it is a command to process by the bot itself if (msg.content.startsWith("!matrix")) { await this.discordCommandHandler.Process(msg); diff --git a/src/discordcommandhandler.ts b/src/discordcommandhandler.ts index 042ec66ca8a5d4604c8add86cc13fbd02c96b4c6..29d8e92f3193506acf7bec2ad2e1727b830c8a21 100644 --- a/src/discordcommandhandler.ts +++ b/src/discordcommandhandler.ts @@ -25,7 +25,8 @@ export class DiscordCommandHandler { ) { } public async Process(msg: Discord.Message) { - if (!(msg.channel as Discord.TextChannel).guild) { + const chan = msg.channel as Discord.TextChannel; + if (!chan.guild) { await msg.channel.send("**ERROR:** only available for guild channels"); return; } @@ -33,23 +34,49 @@ export class DiscordCommandHandler { const intent = this.bridge.getIntent(); const actions: ICommandActions = { + approve: { + description: "Approve a pending bridge request", + params: [], + permission: "MANAGE_WEBHOOKS", + run: async () => { + if (await this.discord.Provisioner.MarkApproved(chan, msg.member, true)) { + return "Thanks for your response! The matrix bridge has been approved"; + } else { + return "Thanks for your response, however" + + "the time for responses has expired - sorry!"; + } + }, + }, ban: { description: "Bans a user on the matrix side", params: ["name"], permission: "BAN_MEMBERS", - run: this.ModerationActionGenerator(msg.channel as Discord.TextChannel, "ban", "Banned"), + run: this.ModerationActionGenerator(chan, "ban", "Banned"), + }, + deny: { + description: "Deny a pending bridge request", + params: [], + permission: "MANAGE_WEBHOOKS", + run: async () => { + if (await this.discord.Provisioner.MarkApproved(chan, msg.member, false)) { + return "Thanks for your response! The matrix bridge has been declined"; + } else { + return "Thanks for your response, however" + + "the time for responses has expired - sorry!"; + } + }, }, kick: { description: "Kicks a user on the matrix side", params: ["name"], permission: "KICK_MEMBERS", - run: this.ModerationActionGenerator(msg.channel as Discord.TextChannel, "kick", "Kicked"), + run: this.ModerationActionGenerator(chan, "kick", "Kicked"), }, unban: { description: "Unbans a user on the matrix side", params: ["name"], permission: "BAN_MEMBERS", - run: this.ModerationActionGenerator(msg.channel as Discord.TextChannel, "unban", "Unbanned"), + run: this.ModerationActionGenerator(chan, "unban", "Unbanned"), }, }; diff --git a/src/provisioner.ts b/src/provisioner.ts index 9a871a1750fae09eb2f3592b24d1ba1488ccc55d..c5b53068274d89b3e6644dce70104cfb4bd4e98b 100644 --- a/src/provisioner.ts +++ b/src/provisioner.ts @@ -78,7 +78,7 @@ export class Provisioner { setTimeout(() => approveFn(false, true), timeout); await channel.send(`${requestor} on matrix would like to bridge this channel. Someone with permission` + - " to manage webhooks please reply with !approve or !deny in the next 5 minutes"); + " to manage webhooks please reply with `!matrix approve` or `!matrix deny` in the next 5 minutes"); return await deferP; } diff --git a/src/util.ts b/src/util.ts index 80dc32ca65eeae9bd19dd62ae667e1e511c2f815..ff0fe9e7ac4e6edb0cbb45c9f64111cef31c8f68 100644 --- a/src/util.ts +++ b/src/util.ts @@ -337,6 +337,8 @@ export class Util { return retStr; } catch (e) { return `**ERROR:** ${e.message}`; + log.error("Error processing command"); + log.error(e); } } diff --git a/test/test_discordbot.ts b/test/test_discordbot.ts index 09088f4ceaa59f9ba5af3472b0aa73dfff3efe6e..2eeccfc065c3506ed596029794b071f94654f6af 100644 --- a/test/test_discordbot.ts +++ b/test/test_discordbot.ts @@ -133,13 +133,11 @@ describe("DiscordBot", () => { }); describe("OnMessage()", () => { let SENT_MESSAGE = false; - let MARKED = -1; let HANDLE_COMMAND = false; let ATTACHMENT = {} as any; let MSGTYPE = ""; function getDiscordBot() { SENT_MESSAGE = false; - MARKED = -1; HANDLE_COMMAND = false; ATTACHMENT = {}; MSGTYPE = ""; @@ -150,13 +148,6 @@ describe("DiscordBot", () => { {}, ); discord.bot = { user: { id: "654" } }; - discord.provisioner = { - HasPendingRequest: (chan) => true, - MarkApproved: async (chan, member, approved) => { - MARKED = approved ? 1 : 0; - return approved; - }, - }; discord.GetIntentFromDiscordMember = (_) => {return { sendMessage: async (room, msg) => { SENT_MESSAGE = true; @@ -195,22 +186,6 @@ describe("DiscordBot", () => { await discordBot.OnMessage(msg); Chai.assert.equal(SENT_MESSAGE, false); }); - it("accepts !approve", async () => { - discordBot = getDiscordBot(); - const channel = new Discord.TextChannel({} as any, {} as any); - const msg = new MockMessage(channel) as any; - msg.content = "!approve"; - await discordBot.OnMessage(msg); - Chai.assert.equal(MARKED, 1); - }); - it("denies !deny", async () => { - discordBot = getDiscordBot(); - const channel = new Discord.TextChannel({} as any, {} as any); - const msg = new MockMessage(channel) as any; - msg.content = "!deny"; - await discordBot.OnMessage(msg); - Chai.assert.equal(MARKED, 0); - }); it("Passes on !matrix commands", async () => { discordBot = getDiscordBot(); const channel = new Discord.TextChannel({} as any, {} as any); diff --git a/test/test_discordcommandhandler.ts b/test/test_discordcommandhandler.ts index eb4b725130353a170934152abd2a0a60eca986f6..f5851f4f4e1a5fb5bbdaa1f2632f61475ee3c89f 100644 --- a/test/test_discordcommandhandler.ts +++ b/test/test_discordcommandhandler.ts @@ -32,12 +32,14 @@ let USERSKICKED = 0; let USERSBANNED = 0; let USERSUNBANNED = 0; let MESSAGESENT: any = {}; +let MARKED = -1; function createCH(opts: any = {}) { USERSJOINED = 0; USERSKICKED = 0; USERSBANNED = 0; USERSUNBANNED = 0; MESSAGESENT = {}; + MARKED = -1; const bridge = { getIntent: () => { return { @@ -58,6 +60,13 @@ function createCH(opts: any = {}) { }; const discord = { ChannelSyncroniser: cs, + Provisioner: { + HasPendingRequest: (chan) => true, + MarkApproved: async (chan, member, approved) => { + MARKED = approved ? 1 : 0; + return approved; + }, + }, }; const discordCommandHndlr = (Proxyquire("../src/discordcommandhandler", { "./util": { @@ -159,4 +168,38 @@ describe("DiscordCommandHandler", () => { await handler.Process(message); expect(USERSUNBANNED).equals(1); }); + it("handles !matrix approve", async () => { + const handler: any = createCH(); + const channel = new MockChannel("123"); + const guild = new MockGuild("456", [channel]); + channel.guild = guild; + const member: any = new MockMember("123456", "blah"); + member.hasPermission = () => { + return true; + }; + const message = { + channel, + content: "!matrix approve", + member, + }; + await handler.Process(message); + expect(MARKED).equals(1); + }); + it("handles !matrix deny", async () => { + const handler: any = createCH(); + const channel = new MockChannel("123"); + const guild = new MockGuild("456", [channel]); + channel.guild = guild; + const member: any = new MockMember("123456", "blah"); + member.hasPermission = () => { + return true; + }; + const message = { + channel, + content: "!matrix deny", + member, + }; + await handler.Process(message); + expect(MARKED).equals(0); + }); });