From 913770c4cb670af8709be16b8640e103074245d2 Mon Sep 17 00:00:00 2001 From: Jay Colson Date: Wed, 6 Feb 2019 13:01:19 +0000 Subject: [PATCH 01/22] added LUSERS function --- lib/irslackd.js | 65 +++++++++++++++++++++++++++++++++++------------ package-lock.json | 8 +++--- package.json | 2 +- 3 files changed, 54 insertions(+), 21 deletions(-) diff --git a/lib/irslackd.js b/lib/irslackd.js index 70dab8c..63559ca 100644 --- a/lib/irslackd.js +++ b/lib/irslackd.js @@ -19,22 +19,23 @@ class Irslackd { const self = this; self.ircd = self.getNewIrcd(self.config.tlsOpts); new Map([ - [ 'AWAY', self.makeIrcHandler(self.onIrcAway) ], - [ 'JOIN', self.makeIrcHandler(self.onIrcJoin) ], - [ 'NICK', self.makeIrcHandler(self.onIrcNick) ], - [ 'PART', self.makeIrcHandler(self.onIrcPart) ], - [ 'PASS', self.makeIrcHandler(self.onIrcPass) ], - [ 'PRIVMSG', self.makeIrcHandler(self.onIrcPrivmsg) ], - [ 'QUIT', self.makeIrcHandler(self.onIrcQuit) ], - [ 'USER', self.makeIrcHandler(self.onIrcUser) ], - [ 'WHO', self.makeIrcHandler(self.onIrcWho) ], - [ 'WHOIS', self.makeIrcHandler(self.onIrcWhois) ], - [ 'PING', self.makeIrcHandler(self.onIrcPing) ], - [ 'MODE', self.makeIrcHandler(self.onIrcMode) ], - [ 'LIST', self.makeIrcHandler(self.onIrcList) ], - [ 'ircLine', self.makeIrcHandler(self.onIrcLine) ], - [ 'ircError', self.makeIrcHandler(self.onIrcError) ], - [ 'ircClose', self.makeIrcHandler(self.onIrcClose) ], + [ 'AWAY', self.makeIrcHandler(self.onIrcAway) ], + [ 'JOIN', self.makeIrcHandler(self.onIrcJoin) ], + [ 'NICK', self.makeIrcHandler(self.onIrcNick) ], + [ 'PART', self.makeIrcHandler(self.onIrcPart) ], + [ 'PASS', self.makeIrcHandler(self.onIrcPass) ], + [ 'PRIVMSG', self.makeIrcHandler(self.onIrcPrivmsg) ], + [ 'QUIT', self.makeIrcHandler(self.onIrcQuit) ], + [ 'USER', self.makeIrcHandler(self.onIrcUser) ], + [ 'WHO', self.makeIrcHandler(self.onIrcWho) ], + [ 'WHOIS', self.makeIrcHandler(self.onIrcWhois) ], + [ 'PING', self.makeIrcHandler(self.onIrcPing) ], + [ 'MODE', self.makeIrcHandler(self.onIrcMode) ], + [ 'LIST', self.makeIrcHandler(self.onIrcList) ], + [ 'LUSERS', self.makeIrcHandler(self.onIrcListUsers)], + [ 'ircLine', self.makeIrcHandler(self.onIrcLine) ], + [ 'ircError', self.makeIrcHandler(self.onIrcError) ], + [ 'ircClose', self.makeIrcHandler(self.onIrcClose) ], [ 'ircConnect', (socket) => { self.onIrcConnect(socket); } ], ]).forEach((handler, cmd, map) => { self.ircd.on(cmd, handler); @@ -307,6 +308,38 @@ class Irslackd { this.ircd.write(ircUser.socket, 'irslackd', 'MODE', [ target ]); } } + async onIrcListUsers(ircUser, msg) { + const self = this; + var userSearch; + if (msg.args.length > 1) return; // Only support `LUSERS` with one params + if (msg.args.length > 0) { + userSearch = msg.args[0]; + } + self.ircd.write(ircUser.socket, 'irslackd', '323', [ ircUser.ircNick, ':Start of LUSERS' ]); + let users = await ircUser.slackWeb.paginateCallOrThrow('users.list', 'members', { + presence: false, + limit: 1000, + }); + users.members.forEach((user) => { + var writeit = false; + if (userSearch) { + if (user.name.toLowerCase().toLowerCase().indexOf(userSearch.toLowerCase()) > 0) { + writeit = true; + } + } else { + writeit = true; + } + if (writeit) { + self.ircd.write(ircUser.socket, 'irslackd', '323', [ + ircUser.ircNick, + '@' + user.name, + user.id, + user.profile.real_name, + ]); + } + }); + self.ircd.write(ircUser.socket, 'irslackd', '323', [ ircUser.ircNick, ':End of LUSERS' ]); + } async onIrcList(ircUser, msg) { const self = this; if (msg.args.length > 0) return; // Only support `LIST` with no params diff --git a/package-lock.json b/package-lock.json index 6f5f755..8176aca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1460,9 +1460,9 @@ } }, "tape": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz", - "integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==", + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.2.tgz", + "integrity": "sha512-lPXKRKILZ1kZaUy5ynWKs8ATGSUO7HAFHCFnBam6FaGSqPdOwMWbxXHq4EXFLE8WRTleo/YOMXkaUTRmTB1Fiw==", "requires": { "deep-equal": "~1.0.1", "defined": "~1.0.0", @@ -1481,7 +1481,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" } } diff --git a/package.json b/package.json index b323a95..b366749 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "@slack/client": "^4.8.0", "await-lock": "^1.1.3", "node-getopt": "^0.3.2", - "tape": "^4.9.1" + "tape": "^4.9.2" }, "devDependencies": { "eslint": "^4.19.1", From 7889d2e2b44b4becf8f0056340cbab821b52d7f1 Mon Sep 17 00:00:00 2001 From: Jay Colson Date: Wed, 6 Feb 2019 13:20:27 +0000 Subject: [PATCH 02/22] indexOf was not tested properly ... test for > -1 --- lib/irslackd.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/irslackd.js b/lib/irslackd.js index 63559ca..1afcbe8 100644 --- a/lib/irslackd.js +++ b/lib/irslackd.js @@ -323,7 +323,7 @@ class Irslackd { users.members.forEach((user) => { var writeit = false; if (userSearch) { - if (user.name.toLowerCase().toLowerCase().indexOf(userSearch.toLowerCase()) > 0) { + if (user.name.toLowerCase().indexOf(userSearch.toLowerCase()) > -1) { writeit = true; } } else { From 48d2ac8231ea6e42144cad7e2f1bb0dacd40d148 Mon Sep 17 00:00:00 2001 From: EC2 Default User Date: Wed, 6 Feb 2019 13:26:37 +0000 Subject: [PATCH 03/22] added patch #55 --- lib/irslackd.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/irslackd.js b/lib/irslackd.js index 70dab8c..a1bb75c 100644 --- a/lib/irslackd.js +++ b/lib/irslackd.js @@ -304,7 +304,7 @@ class Irslackd { async onIrcMode(ircUser, msg) { let target = msg.args[0]; if (target.substr(0, 1) === '#') { - this.ircd.write(ircUser.socket, 'irslackd', 'MODE', [ target ]); + this.ircd.write(ircUser.socket, 'irslackd', 'MODE', msg.args); } } async onIrcList(ircUser, msg) { From a1d9186f62ec906a6ca2b4828c1150e1634ee778 Mon Sep 17 00:00:00 2001 From: Jay Colson Date: Wed, 6 Feb 2019 16:15:33 +0000 Subject: [PATCH 04/22] added functionality for /WHO --- lib/irslackd.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/irslackd.js b/lib/irslackd.js index 07a9bf5..dc737f6 100644 --- a/lib/irslackd.js +++ b/lib/irslackd.js @@ -32,7 +32,6 @@ class Irslackd { [ 'PING', self.makeIrcHandler(self.onIrcPing) ], [ 'MODE', self.makeIrcHandler(self.onIrcMode) ], [ 'LIST', self.makeIrcHandler(self.onIrcList) ], - [ 'LUSERS', self.makeIrcHandler(self.onIrcListUsers)], [ 'ircLine', self.makeIrcHandler(self.onIrcLine) ], [ 'ircError', self.makeIrcHandler(self.onIrcError) ], [ 'ircClose', self.makeIrcHandler(self.onIrcClose) ], @@ -308,14 +307,14 @@ class Irslackd { this.ircd.write(ircUser.socket, 'irslackd', 'MODE', msg.args); } } - async onIrcListUsers(ircUser, msg) { + async onIrcWho(ircUser, msg) { const self = this; var userSearch; - if (msg.args.length > 1) return; // Only support `LUSERS` with one params + if (msg.args.length > 1) return; // Only support `WHO` with one params if (msg.args.length > 0) { userSearch = msg.args[0]; } - self.ircd.write(ircUser.socket, 'irslackd', '323', [ ircUser.ircNick, ':Start of LUSERS' ]); + self.ircd.write(ircUser.socket, 'irslackd', '371', [ ircUser.ircNick, ':Start of WHO' ]); let users = await ircUser.slackWeb.paginateCallOrThrow('users.list', 'members', { presence: false, limit: 1000, @@ -330,15 +329,20 @@ class Irslackd { writeit = true; } if (writeit) { - self.ircd.write(ircUser.socket, 'irslackd', '323', [ + self.ircd.write(ircUser.socket, 'irslackd', '352', [ ircUser.ircNick, - '@' + user.name, + '#', user.id, + "slack.com", + "example.com", + user.name, + user.profile.email?user.profile.email:"nobody@example.com", + "0", user.profile.real_name, ]); } }); - self.ircd.write(ircUser.socket, 'irslackd', '323', [ ircUser.ircNick, ':End of LUSERS' ]); + self.ircd.write(ircUser.socket, 'irslackd', '315', [ ircUser.ircNick, ':End of WHO' ]); } async onIrcList(ircUser, msg) { const self = this; @@ -633,9 +637,9 @@ class Irslackd { // Update presence subscriptions this.updatePresenceSubscriptions(ircUser); } - async onIrcWho(ircUser, msg) { +/** async onIrcWho(ircUser, msg) { await this.onIrcWhois(ircUser, msg); - } + }*/ async onIrcWhois(ircUser, msg) { if (msg.args.length < 1) return; let ircNick = msg.args[0]; From 1602e02b271fe7fac87ebc1f4e918714534c6297 Mon Sep 17 00:00:00 2001 From: Jay Colson Date: Wed, 6 Feb 2019 16:23:12 +0000 Subject: [PATCH 05/22] changed quotes to doubles, changed hostname to be consistant irslackd --- lib/irslackd.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/irslackd.js b/lib/irslackd.js index dc737f6..b1992b4 100644 --- a/lib/irslackd.js +++ b/lib/irslackd.js @@ -331,9 +331,9 @@ class Irslackd { if (writeit) { self.ircd.write(ircUser.socket, 'irslackd', '352', [ ircUser.ircNick, - '#', + "#", user.id, - "slack.com", + "irslackd", "example.com", user.name, user.profile.email?user.profile.email:"nobody@example.com", From e47fb86a85c8ffce824ffc61359be133c952fff0 Mon Sep 17 00:00:00 2001 From: Jay Colson Date: Wed, 6 Feb 2019 18:37:41 +0000 Subject: [PATCH 06/22] added ability to /invite user --- lib/irslackd.js | 73 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/lib/irslackd.js b/lib/irslackd.js index b1992b4..d4c79c0 100644 --- a/lib/irslackd.js +++ b/lib/irslackd.js @@ -27,6 +27,7 @@ class Irslackd { [ 'PRIVMSG', self.makeIrcHandler(self.onIrcPrivmsg) ], [ 'QUIT', self.makeIrcHandler(self.onIrcQuit) ], [ 'USER', self.makeIrcHandler(self.onIrcUser) ], + [ 'INVITE', self.makeIrcHandler(self.onIrcInvite) ], [ 'WHO', self.makeIrcHandler(self.onIrcWho) ], [ 'WHOIS', self.makeIrcHandler(self.onIrcWhois) ], [ 'PING', self.makeIrcHandler(self.onIrcPing) ], @@ -307,10 +308,78 @@ class Irslackd { this.ircd.write(ircUser.socket, 'irslackd', 'MODE', msg.args); } } + /** + * @todo: work in progress + * @param {*} ircUser + * @param {*} msg + */ + async onIrcInvite(ircUser, msg) { + console.log("in the irc invite method"); + const self = this; + if (msg.args.length !== 2) { + self.ircd.write(ircUser.socket, 'irslackd', '371', [ ircUser.ircNick, ':Must pass two params, the user to invite and the channel' ]); + return; // must have two params (nick and channel) + } + var userId = await self.lookupUserId(ircUser, msg.args[0]); + var channelId = await self.lookupChannelId(ircUser, msg.args[1].substr(1)); // remove hash + await ircUser.slackWeb.paginateCallOrThrow('channels.invite', 'channel', { + channel: channelId, + user: userId, + }); + self.ircd.write(ircUser.socket, 'irslackd', '341', [ + ircUser.ircNick, + channelId, + userId, + ]); + } + async lookupChannelId(ircUser, channelName) { + var channelId; + let conversations = await ircUser.slackWeb.paginateCallOrThrow('conversations.list', 'channels', { + types: "public_channel, private_channel, mpim, im", + exclude_archived: true, + limit: 1000, + }); + var BreakException = {}; + try { + conversations.channels.forEach((channel) => { + if (channel.name === channelName) { + channelId = channel.id; + throw BreakException; + } + }); + } catch (e) { + if (e !== BreakException) throw e; + } + return channelId; + } + async lookupUserId(ircUser, userName) { + var userId; + let users = await ircUser.slackWeb.paginateCallOrThrow('users.list', 'members', { + presence: false, + limit: 1000, + }); + var BreakException = {}; + try { + users.members.forEach((member) => { + if (member.name === userName) { + userId = member.id; + throw BreakException; + } + }); + } catch (e) { + if (e !== BreakException) throw e; + } + return userId; + } async onIrcWho(ircUser, msg) { const self = this; - var userSearch; + var userSearch, channelSearch; if (msg.args.length > 1) return; // Only support `WHO` with one params + if (msg.args.length > 0 && msg.args[0].substr(0,1) === "#") { + channelSearch = msg.args[0].substr(1); + self.ircd.write(ircUser.socket, 'irslackd', '315', [ ircUser.ircNick, ':End of WHO - channels not implemented' ]); + return; + } if (msg.args.length > 0) { userSearch = msg.args[0]; } @@ -331,7 +400,7 @@ class Irslackd { if (writeit) { self.ircd.write(ircUser.socket, 'irslackd', '352', [ ircUser.ircNick, - "#", + "*", user.id, "irslackd", "example.com", From efd99bb866f40159ae7deb0e4f4cfd234f67e841 Mon Sep 17 00:00:00 2001 From: Jay Colson Date: Wed, 6 Feb 2019 18:41:23 +0000 Subject: [PATCH 07/22] replaced all double qutoes for singles --- lib/irslackd.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/irslackd.js b/lib/irslackd.js index d4c79c0..38da620 100644 --- a/lib/irslackd.js +++ b/lib/irslackd.js @@ -314,7 +314,6 @@ class Irslackd { * @param {*} msg */ async onIrcInvite(ircUser, msg) { - console.log("in the irc invite method"); const self = this; if (msg.args.length !== 2) { self.ircd.write(ircUser.socket, 'irslackd', '371', [ ircUser.ircNick, ':Must pass two params, the user to invite and the channel' ]); @@ -335,7 +334,7 @@ class Irslackd { async lookupChannelId(ircUser, channelName) { var channelId; let conversations = await ircUser.slackWeb.paginateCallOrThrow('conversations.list', 'channels', { - types: "public_channel, private_channel, mpim, im", + types: 'public_channel, private_channel, mpim, im', exclude_archived: true, limit: 1000, }); @@ -375,7 +374,7 @@ class Irslackd { const self = this; var userSearch, channelSearch; if (msg.args.length > 1) return; // Only support `WHO` with one params - if (msg.args.length > 0 && msg.args[0].substr(0,1) === "#") { + if (msg.args.length > 0 && msg.args[0].substr(0,1) === '#') { channelSearch = msg.args[0].substr(1); self.ircd.write(ircUser.socket, 'irslackd', '315', [ ircUser.ircNick, ':End of WHO - channels not implemented' ]); return; @@ -400,13 +399,13 @@ class Irslackd { if (writeit) { self.ircd.write(ircUser.socket, 'irslackd', '352', [ ircUser.ircNick, - "*", + '*', user.id, - "irslackd", - "example.com", + 'irslackd', + 'example.com', user.name, - user.profile.email?user.profile.email:"nobody@example.com", - "0", + user.profile.email?user.profile.email:'nobody@example.com', + '0', user.profile.real_name, ]); } From 2613ee17628d83d98de047a09cf03c6ca2dcdfa6 Mon Sep 17 00:00:00 2001 From: Jay Colson Date: Thu, 7 Feb 2019 16:28:47 +0000 Subject: [PATCH 08/22] catch exceptions on invite and give error feedback to user --- lib/irslackd.js | 272 ++++++++++++++++++++++++++++-------------------- 1 file changed, 159 insertions(+), 113 deletions(-) diff --git a/lib/irslackd.js b/lib/irslackd.js index 38da620..a43224b 100644 --- a/lib/irslackd.js +++ b/lib/irslackd.js @@ -1,10 +1,10 @@ 'use strict'; -const util = require('util'); -const slack = require('@slack/client'); +const util = require('util'); +const slack = require('@slack/client'); const AwaitLock = require('await-lock'); -const ircd = require('./ircd'); -const refresh = require('./slack-refresh'); +const ircd = require('./ircd'); +const refresh = require('./slack-refresh'); const debugChannel = '+irslackd'; class Irslackd { @@ -19,24 +19,26 @@ class Irslackd { const self = this; self.ircd = self.getNewIrcd(self.config.tlsOpts); new Map([ - [ 'AWAY', self.makeIrcHandler(self.onIrcAway) ], - [ 'JOIN', self.makeIrcHandler(self.onIrcJoin) ], - [ 'NICK', self.makeIrcHandler(self.onIrcNick) ], - [ 'PART', self.makeIrcHandler(self.onIrcPart) ], - [ 'PASS', self.makeIrcHandler(self.onIrcPass) ], - [ 'PRIVMSG', self.makeIrcHandler(self.onIrcPrivmsg) ], - [ 'QUIT', self.makeIrcHandler(self.onIrcQuit) ], - [ 'USER', self.makeIrcHandler(self.onIrcUser) ], - [ 'INVITE', self.makeIrcHandler(self.onIrcInvite) ], - [ 'WHO', self.makeIrcHandler(self.onIrcWho) ], - [ 'WHOIS', self.makeIrcHandler(self.onIrcWhois) ], - [ 'PING', self.makeIrcHandler(self.onIrcPing) ], - [ 'MODE', self.makeIrcHandler(self.onIrcMode) ], - [ 'LIST', self.makeIrcHandler(self.onIrcList) ], - [ 'ircLine', self.makeIrcHandler(self.onIrcLine) ], - [ 'ircError', self.makeIrcHandler(self.onIrcError) ], - [ 'ircClose', self.makeIrcHandler(self.onIrcClose) ], - [ 'ircConnect', (socket) => { self.onIrcConnect(socket); } ], + ['AWAY', self.makeIrcHandler(self.onIrcAway)], + ['JOIN', self.makeIrcHandler(self.onIrcJoin)], + ['NICK', self.makeIrcHandler(self.onIrcNick)], + ['PART', self.makeIrcHandler(self.onIrcPart)], + ['PASS', self.makeIrcHandler(self.onIrcPass)], + ['PRIVMSG', self.makeIrcHandler(self.onIrcPrivmsg)], + ['QUIT', self.makeIrcHandler(self.onIrcQuit)], + ['USER', self.makeIrcHandler(self.onIrcUser)], + ['INVITE', self.makeIrcHandler(self.onIrcInvite)], + ['WHO', self.makeIrcHandler(self.onIrcWho)], + ['WHOIS', self.makeIrcHandler(self.onIrcWhois)], + ['PING', self.makeIrcHandler(self.onIrcPing)], + ['MODE', self.makeIrcHandler(self.onIrcMode)], + ['LIST', self.makeIrcHandler(self.onIrcList)], + ['ircLine', self.makeIrcHandler(self.onIrcLine)], + ['ircError', self.makeIrcHandler(self.onIrcError)], + ['ircClose', self.makeIrcHandler(self.onIrcClose)], + ['ircConnect', (socket) => { + self.onIrcConnect(socket); + }], ]).forEach((handler, cmd, map) => { self.ircd.on(cmd, handler); }); @@ -86,24 +88,24 @@ class Irslackd { // Setup Slack handlers self.rtmMap.set(ircUser.slackRtm, ircUser); new Map([ - [ 'ready', self.makeSlackHandler(self.onSlackReady) ], - [ 'message', self.makeSlackHandler(self.onSlackMessage) ], - [ 'channel_joined', self.makeSlackHandler(self.onSlackChannelJoined) ], - [ 'channel_left', self.makeSlackHandler(self.onSlackChannelLeft) ], - [ 'channel_rename', self.makeSlackHandler(self.onSlackChannelRename) ], - [ 'channel_created', self.makeSlackHandler(self.onSlackChannelCreated) ], - [ 'member_joined_channel', self.makeSlackHandler(self.onSlackMemberJoinedChannel) ], - [ 'member_left_channel', self.makeSlackHandler(self.onSlackMemberLeftChannel) ], - [ 'mpim_open', self.makeSlackHandler(self.onSlackMpimOpen) ], - [ 'mpim_close', self.makeSlackHandler(self.onSlackMpimClose) ], - [ 'reaction_added', self.makeSlackHandler(self.onSlackReactionAdded) ], - [ 'reaction_removed', self.makeSlackHandler(self.onSlackReactionRemoved) ], - [ 'subteam_created', self.makeSlackHandler(self.onSlackSubteamUpdated) ], - [ 'subteam_updated', self.makeSlackHandler(self.onSlackSubteamUpdated) ], - [ 'user_typing', self.makeSlackHandler(self.onSlackUserTyping) ], - [ 'presence_change', self.makeSlackHandler(self.onSlackPresenceChange) ], - [ 'team_join', self.makeSlackHandler(self.onSlackTeamJoin) ], - [ 'slack_event', self.makeSlackHandler(self.onSlackEvent) ], + ['ready', self.makeSlackHandler(self.onSlackReady)], + ['message', self.makeSlackHandler(self.onSlackMessage)], + ['channel_joined', self.makeSlackHandler(self.onSlackChannelJoined)], + ['channel_left', self.makeSlackHandler(self.onSlackChannelLeft)], + ['channel_rename', self.makeSlackHandler(self.onSlackChannelRename)], + ['channel_created', self.makeSlackHandler(self.onSlackChannelCreated)], + ['member_joined_channel', self.makeSlackHandler(self.onSlackMemberJoinedChannel)], + ['member_left_channel', self.makeSlackHandler(self.onSlackMemberLeftChannel)], + ['mpim_open', self.makeSlackHandler(self.onSlackMpimOpen)], + ['mpim_close', self.makeSlackHandler(self.onSlackMpimClose)], + ['reaction_added', self.makeSlackHandler(self.onSlackReactionAdded)], + ['reaction_removed', self.makeSlackHandler(self.onSlackReactionRemoved)], + ['subteam_created', self.makeSlackHandler(self.onSlackSubteamUpdated)], + ['subteam_updated', self.makeSlackHandler(self.onSlackSubteamUpdated)], + ['user_typing', self.makeSlackHandler(self.onSlackUserTyping)], + ['presence_change', self.makeSlackHandler(self.onSlackPresenceChange)], + ['team_join', self.makeSlackHandler(self.onSlackTeamJoin)], + ['slack_event', self.makeSlackHandler(self.onSlackEvent)], ]).forEach((handler, event, map) => { ircUser.slackRtm.on(event, handler); }); @@ -163,7 +165,9 @@ class Irslackd { if (!alreadyInSlackChanId) { let slackChanName = ircChan; if (slackChanName.substr(0, 1) === '#') slackChanName = slackChanName.substr(1); - convo = await ircUser.slackWeb.apiCallOrThrow('channels.join', { name: slackChanName }); + convo = await ircUser.slackWeb.apiCallOrThrow('channels.join', { + name: slackChanName + }); alreadyInSlackChan = convo.already_in_channel; slackChanId = convo.channel.id; } else { @@ -179,7 +183,9 @@ class Irslackd { if (alreadyInSlackChan) { // Call conversations.info // (channels.join returns limited channel info if already in channel case) - convo = await ircUser.slackWeb.apiCallOrThrow('conversations.info', { channel: slackChanId }); + convo = await ircUser.slackWeb.apiCallOrThrow('conversations.info', { + channel: slackChanId + }); } // Update maps @@ -192,7 +198,7 @@ class Irslackd { }); // Assemble IRC nicks - let ircNicks = [ ircUser.ircNick ]; + let ircNicks = [ircUser.ircNick]; let ircNickPromises = []; members.members.forEach((userId) => { let ircNickPromise = self.resolveSlackUser(ircUser, userId); @@ -233,7 +239,9 @@ class Irslackd { // Leave Slack channel let apiMethod = slackChan.substr(0, 1) === 'G' ? 'mpim.close' : 'conversations.leave'; - await ircUser.slackWeb.apiCallOrThrow(apiMethod, { channel: slackChan }); + await ircUser.slackWeb.apiCallOrThrow(apiMethod, { + channel: slackChan + }); // Unset channel marker and leave IRC channel this.sendIrcChannelPart(ircUser, ircChan); @@ -267,7 +275,9 @@ class Irslackd { // Sending to a user, update nick-channel map slackChan = ircUser.ircNickToSlackChanId.get(target); if (!slackChan) { - let im = await ircUser.slackWeb.apiCallOrThrow('im.open', { user: slackTarget }); + let im = await ircUser.slackWeb.apiCallOrThrow('im.open', { + user: slackTarget + }); slackChan = im.channel.id; ircUser.ircNickToSlackChanId.set(target, slackChan); } @@ -289,7 +299,7 @@ class Irslackd { } // Call chat.(post|me)Message - await this.rememberSelfEcho(ircUser, message, async() => { + await this.rememberSelfEcho(ircUser, message, async () => { return await ircUser.slackWeb.apiCallOrThrow(apiMethod, { channel: slackChan, text: message, @@ -300,7 +310,7 @@ class Irslackd { } async onIrcPing(ircUser, msg) { // Send PONG - this.ircd.write(ircUser.socket, 'irslackd', 'PONG', [ 'irslackd' ]); + this.ircd.write(ircUser.socket, 'irslackd', 'PONG', ['irslackd']); } async onIrcMode(ircUser, msg) { let target = msg.args[0]; @@ -315,21 +325,29 @@ class Irslackd { */ async onIrcInvite(ircUser, msg) { const self = this; - if (msg.args.length !== 2) { - self.ircd.write(ircUser.socket, 'irslackd', '371', [ ircUser.ircNick, ':Must pass two params, the user to invite and the channel' ]); - return; // must have two params (nick and channel) - } - var userId = await self.lookupUserId(ircUser, msg.args[0]); - var channelId = await self.lookupChannelId(ircUser, msg.args[1].substr(1)); // remove hash - await ircUser.slackWeb.paginateCallOrThrow('channels.invite', 'channel', { - channel: channelId, - user: userId, - }); - self.ircd.write(ircUser.socket, 'irslackd', '341', [ - ircUser.ircNick, - channelId, - userId, - ]); + try { + if (msg.args.length !== 2) { + self.ircd.write(ircUser.socket, 'irslackd', '371', [ircUser.ircNick, ':Must pass two params, the user to invite and the channel']); + return; // must have two params (nick and channel) + } + var userId = await self.lookupUserId(ircUser, msg.args[0].substr(0, 1) === '@' ? msg.args[0].substr(1) : msg.args[0]); //remove at-sign + var channelId = await self.lookupChannelId(ircUser, msg.args[1].substr(0, 1) === '#' ? msg.args[1].substr(1) : msg.args[1]); // remove hash + await ircUser.slackWeb.paginateCallOrThrow('channels.invite', 'channel', { + channel: channelId, + user: userId, + }); + self.ircd.write(ircUser.socket, 'irslackd', '341', [ + ircUser.ircNick, + channelId, + userId, + ]); + } catch (e) { + self.ircd.write(ircUser.socket, 'irslackd', '371', [ + ircUser.ircNick, ':/INVITE failed->' + + JSON.parse(e.message).error.code + '->' + + JSON.parse(e.message).error.data.error + ]); + } } async lookupChannelId(ircUser, channelName) { var channelId; @@ -374,15 +392,15 @@ class Irslackd { const self = this; var userSearch, channelSearch; if (msg.args.length > 1) return; // Only support `WHO` with one params - if (msg.args.length > 0 && msg.args[0].substr(0,1) === '#') { + if (msg.args.length > 0 && msg.args[0].substr(0, 1) === '#') { channelSearch = msg.args[0].substr(1); - self.ircd.write(ircUser.socket, 'irslackd', '315', [ ircUser.ircNick, ':End of WHO - channels not implemented' ]); + self.ircd.write(ircUser.socket, 'irslackd', '315', [ircUser.ircNick, ':End of WHO - channels not implemented']); return; } if (msg.args.length > 0) { userSearch = msg.args[0]; } - self.ircd.write(ircUser.socket, 'irslackd', '371', [ ircUser.ircNick, ':Start of WHO' ]); + self.ircd.write(ircUser.socket, 'irslackd', '371', [ircUser.ircNick, ':Start of WHO']); let users = await ircUser.slackWeb.paginateCallOrThrow('users.list', 'members', { presence: false, limit: 1000, @@ -404,13 +422,13 @@ class Irslackd { 'irslackd', 'example.com', user.name, - user.profile.email?user.profile.email:'nobody@example.com', + user.profile.email ? user.profile.email : 'nobody@example.com', '0', user.profile.real_name, ]); } }); - self.ircd.write(ircUser.socket, 'irslackd', '315', [ ircUser.ircNick, ':End of WHO' ]); + self.ircd.write(ircUser.socket, 'irslackd', '315', [ircUser.ircNick, ':End of WHO']); } async onIrcList(ircUser, msg) { const self = this; @@ -428,17 +446,17 @@ class Irslackd { ':' + channel.topic.value, ]); }); - self.ircd.write(ircUser.socket, 'irslackd', '323', [ ircUser.ircNick, ':End of LIST' ]); + self.ircd.write(ircUser.socket, 'irslackd', '323', [ircUser.ircNick, ':End of LIST']); } async onIrcQuit(ircUser, msg) { // Close link - this.ircd.write(ircUser.socket, 'irslackd', 'ERROR', [ ':Closing Link' ]); + this.ircd.write(ircUser.socket, 'irslackd', 'ERROR', [':Closing Link']); ircUser.socket.destroy(); } async onSlackReady(ircUser, event) { // Send MOTD - this.ircd.write(ircUser.socket, 'irslackd', '001', [ ircUser.ircNick, 'irslackd' ]); - this.ircd.write(ircUser.socket, 'irslackd', '376', [ ircUser.ircNick, 'End of MOTD' ]); + this.ircd.write(ircUser.socket, 'irslackd', '001', [ircUser.ircNick, 'irslackd']); + this.ircd.write(ircUser.socket, 'irslackd', '376', [ircUser.ircNick, 'End of MOTD']); // set user presence to auto instead of away await this.setSlackPresence(ircUser, true); @@ -503,7 +521,9 @@ class Irslackd { if (typeof event.text !== 'string') { if (event.subtype !== 'message_replied') { // Not sure where this might happen - this.logError(ircUser, 'onSlackMessage with no event.text; event: ' + util.inspect(event, { depth: 4 })); + this.logError(ircUser, 'onSlackMessage with no event.text; event: ' + util.inspect(event, { + depth: 4 + })); } return; } @@ -532,7 +552,7 @@ class Irslackd { } // Also send attachments - let messages = [ event.text ]; + let messages = [event.text]; if (event.attachments) { event.attachments.forEach((attachment, idx) => { if (attachment.fallback) messages.push('> ' + self.ircizeText(ircUser, self.decodeEntities(attachment.fallback))); @@ -553,7 +573,7 @@ class Irslackd { line = line.trim(); if (line.length < 1) return; if (event.subtype === 'me_message') line = self.meText(line); - self.ircd.write(ircUser.socket, ircNick, 'PRIVMSG', [ ircTarget, ':' + line ]); + self.ircd.write(ircUser.socket, ircNick, 'PRIVMSG', [ircTarget, ':' + line]); }); }); } @@ -566,7 +586,7 @@ class Irslackd { event.topic = this.ircizeText(ircUser, this.decodeEntities(event.topic)); // Send topic message - this.ircd.write(ircUser.socket, ircNick, 'TOPIC', [ ircChan, event.topic ]); + this.ircd.write(ircUser.socket, ircNick, 'TOPIC', [ircChan, event.topic]); } async onSlackChannelJoined(ircUser, event) { let ircChan = await this.resolveSlackChannel(ircUser, event.channel); @@ -577,7 +597,9 @@ class Irslackd { async onSlackChannelLeft(ircUser, event) { let ircChan = await this.resolveSlackChannel(ircUser, event.channel); if (ircChan) { - await this.onIrcPart(ircUser, { args: [ ircChan ] }, event.channel); + await this.onIrcPart(ircUser, { + args: [ircChan] + }, event.channel); } } async onSlackChannelRename(ircUser, event) { @@ -585,7 +607,7 @@ class Irslackd { let newIrcChan = '#' + event.channel.name; let isInChan = ircUser.isInChannel(oldIrcChan); if (isInChan) { - this.ircd.write(ircUser.socket, ircUser.ircNick, 'PART', [ oldIrcChan ]); + this.ircd.write(ircUser.socket, ircUser.ircNick, 'PART', [oldIrcChan]); ircUser.partChannel(oldIrcChan); } ircUser.ircToSlack.delete(oldIrcChan); @@ -600,7 +622,7 @@ class Irslackd { let [ircNick, ircChan] = await this.resolveSlackTarget(ircUser, event); if (ircNick && ircChan && !ircUser.isNickInChannel(ircChan, ircNick)) { ircUser.addNickToChannel(ircChan, ircNick); - this.ircd.write(ircUser.socket, ircNick, 'JOIN', [ ircChan ]); + this.ircd.write(ircUser.socket, ircNick, 'JOIN', [ircChan]); } } async onSlackMemberLeftChannel(ircUser, event) { @@ -608,7 +630,7 @@ class Irslackd { let [ircNick, ircChan] = await this.resolveSlackTarget(ircUser, event); if (ircNick && ircChan && ircUser.isNickInChannel(ircChan, ircNick)) { ircUser.removeNickFromChannel(ircChan, ircNick); - this.ircd.write(ircUser.socket, ircNick, 'PART', [ ircChan ]); + this.ircd.write(ircUser.socket, ircNick, 'PART', [ircChan]); } } async onSlackMpimOpen(ircUser, event) { @@ -636,9 +658,9 @@ class Irslackd { count: 1, inclusive: 1, }); - if (history.messages.length > 0 - && history.messages[0].ts === event.item.ts - && (history.messages[0].user || history.messages[0].bot_id) + if (history.messages.length > 0 && + history.messages[0].ts === event.item.ts && + (history.messages[0].user || history.messages[0].bot_id) ) { event.item_user = history.messages[0].user || history.messages[0].bot_id; } else { @@ -648,11 +670,11 @@ class Irslackd { } let ircReacter = this.resolveSlackUser(ircUser, event.user); let ircReactee = this.resolveSlackUser(ircUser, event.item_user); - let ircChan = this.resolveSlackChannel(ircUser, event.item.channel); + let ircChan = this.resolveSlackChannel(ircUser, event.item.channel); try { ircReacter = await ircReacter; ircReactee = await ircReactee; - ircChan = await ircChan; + ircChan = await ircChan; if (!ircReacter || !ircReactee || !ircChan) { throw Error('Missing reaction info'); } @@ -661,7 +683,7 @@ class Irslackd { return; } let message = this.meText(verb + ' @ ' + ircReactee + ' :' + event.reaction + ':'); - this.ircd.write(ircUser.socket, ircReacter, 'PRIVMSG', [ ircChan, message ]); + this.ircd.write(ircUser.socket, ircReacter, 'PRIVMSG', [ircChan, message]); } async onSlackUserTyping(ircUser, event) { if (!ircUser.typingNotificationsEnabled()) { @@ -674,7 +696,7 @@ class Irslackd { } console.log('slack_typing', ircNick, ircTarget); let line = this.typingText('1'); - this.ircd.write(ircUser.socket, ircNick, 'PRIVMSG', [ ircTarget, line ]); + this.ircd.write(ircUser.socket, ircNick, 'PRIVMSG', [ircTarget, line]); } async onSlackPresenceChange(ircUser, event) { if (!ircUser.presenceEnabled()) { @@ -705,9 +727,9 @@ class Irslackd { // Update presence subscriptions this.updatePresenceSubscriptions(ircUser); } -/** async onIrcWho(ircUser, msg) { - await this.onIrcWhois(ircUser, msg); - }*/ + /** async onIrcWho(ircUser, msg) { + await this.onIrcWhois(ircUser, msg); + }*/ async onIrcWhois(ircUser, msg) { if (msg.args.length < 1) return; let ircNick = msg.args[0]; @@ -717,7 +739,9 @@ class Irslackd { let slackUser = ircUser.ircToSlack.get(ircNick); if (!slackUser) return; try { - let user = await ircUser.slackWeb.apiCallOrThrow('users.info', { user: slackUser }); + let user = await ircUser.slackWeb.apiCallOrThrow('users.info', { + user: slackUser + }); this.ircd.write(ircUser.socket, 'irslackd', '311', [ ircUser.ircNick, ircNick, @@ -737,17 +761,28 @@ class Irslackd { onIrcDebugPrivmsg(ircUser, msg) { let cmd = msg.args[0]; let out = null; - const iOpts = { depth: 3, showHidden: true }; + const iOpts = { + depth: 3, + showHidden: true + }; switch (cmd) { - case 'dump_server': out = util.inspect(this, iOpts); break; - case 'dump_user': out = util.inspect(ircUser, iOpts); break; - case 'dump_rtm': out = util.inspect(ircUser.slackRtm, iOpts); break; - case 'dump_web': out = util.inspect(ircUser.slackWeb, iOpts); break; + case 'dump_server': + out = util.inspect(this, iOpts); + break; + case 'dump_user': + out = util.inspect(ircUser, iOpts); + break; + case 'dump_rtm': + out = util.inspect(ircUser.slackRtm, iOpts); + break; + case 'dump_web': + out = util.inspect(ircUser.slackWeb, iOpts); + break; } if (out) console.log('debug', cmd, out); } onIrcDebugJoin(ircUser) { - this.sendIrcChannelJoin(ircUser, debugChannel, 'irslackd debug', [ ircUser.ircNick ]); + this.sendIrcChannelJoin(ircUser, debugChannel, 'irslackd debug', [ircUser.ircNick]); } onIrcDebugPart(ircUser) { this.sendIrcChannelPart(ircUser, debugChannel); @@ -788,7 +823,7 @@ class Irslackd { } catch (e) { this.logError(ircUser, util.inspect(e)); } - return [ ircNick, ircChan ]; + return [ircNick, ircChan]; } async resolveSlackChannel(ircUser, slackChan) { // Check cache @@ -796,7 +831,9 @@ class Irslackd { if (ircChan) return ircChan; // Try conversations.info - let convo = await ircUser.slackWeb.apiCallOrThrow('conversations.info', { channel: slackChan }); + let convo = await ircUser.slackWeb.apiCallOrThrow('conversations.info', { + channel: slackChan + }); // If it's an im, pass to resolveSlackUser if (convo.channel.is_im) { @@ -819,7 +856,9 @@ class Irslackd { } // Try users.info - let user = await ircUser.slackWeb.apiCallOrThrow('users.info', { user: slackUser }); + let user = await ircUser.slackWeb.apiCallOrThrow('users.info', { + user: slackUser + }); // Set cache; return ircNick = this.replaceIllegalIrcNickChars(user.user.name); @@ -832,7 +871,9 @@ class Irslackd { if (ircNick) return ircNick; // Try bots.info - let bot = await ircUser.slackWeb.apiCallOrThrow('bots.info', { bot: slackBotId }); + let bot = await ircUser.slackWeb.apiCallOrThrow('bots.info', { + bot: slackBotId + }); // Set cache; return ircNick = this.replaceIllegalIrcNickChars(bot.bot.name); @@ -864,10 +905,10 @@ class Irslackd { ircUser.joinChannel(ircChan, ircNicks); // Join IRC channel - this.ircd.write(ircUser.socket, ircUser.ircNick, 'JOIN', [ ircChan ]); + this.ircd.write(ircUser.socket, ircUser.ircNick, 'JOIN', [ircChan]); if (topic) { topic = this.ircizeText(ircUser, this.decodeEntities(topic)); - this.ircd.write(ircUser.socket, 'irslackd', '332', [ ircUser.ircNick, ircChan, ':' + topic ]); + this.ircd.write(ircUser.socket, 'irslackd', '332', [ircUser.ircNick, ircChan, ':' + topic]); } // Send nicks in chunks of 20 @@ -886,7 +927,7 @@ class Irslackd { sendIrcChannelPart(ircUser, ircChan) { // Unset channel marker and leave IRC channel if (ircUser.partChannel(ircChan)) { - this.ircd.write(ircUser.socket, ircUser.ircNick, 'PART', [ ircChan ]); + this.ircd.write(ircUser.socket, ircUser.ircNick, 'PART', [ircChan]); } } updatePresenceSubscriptions(ircUser) { @@ -967,9 +1008,9 @@ class Irslackd { let re = /^@thread-([^ ]+) /; let match = re.exec(text); if (match) { - return [ text.replace(re, ''), match[1] ]; + return [text.replace(re, ''), match[1]]; } - return [ text, null ]; + return [text, null]; } async rememberSelfEcho(ircUser, message, apiCb) { await ircUser.selfEchoLock.acquireAsync(); @@ -1004,7 +1045,7 @@ class Irslackd { } makeIrcHandler(method) { const self = this; - return function() { + return function () { const args = Array.from(arguments); const socket = args.shift(); const ircUser = self.socketMap.get(socket); @@ -1023,7 +1064,7 @@ class Irslackd { } makeSlackHandler(method) { const self = this; - return function() { + return function () { const args = Array.from(arguments); const rtm = this; const ircUser = self.rtmMap.get(rtm); @@ -1068,9 +1109,9 @@ class Irslackd { } else { results[aggKey] = results[aggKey].concat(result[aggKey]); } - if (!result.response_metadata - || !result.response_metadata.next_cursor - || result.response_metadata.next_cursor.length < 1 + if (!result.response_metadata || + !result.response_metadata.next_cursor || + result.response_metadata.next_cursor.length < 1 ) { break; } @@ -1080,7 +1121,9 @@ class Irslackd { } async setSlackPresence(ircUser, active) { let status = (active) ? 'auto' : 'away'; - await ircUser.slackWeb.apiCallOrThrow('users.setPresence', { presence: status }); + await ircUser.slackWeb.apiCallOrThrow('users.setPresence', { + presence: status + }); } // Dependency injectors getNewIrcd(tlsOpts) { @@ -1092,7 +1135,10 @@ class Irslackd { getNewSlackRtmClient(token) { return new slack.RTMClient(token, { logLevel: this.config.rtmClientLogLevel || 'info', - retryConfig: { forever: true, maxTimeout: 60000 }, + retryConfig: { + forever: true, + maxTimeout: 60000 + }, }); } } @@ -1183,4 +1229,4 @@ class IrcUser { } } -exports.Irslackd = Irslackd; +exports.Irslackd = Irslackd; \ No newline at end of file From 58591c33a95b6a53299dd9b250836b73e04c806a Mon Sep 17 00:00:00 2001 From: Jay Colson Date: Fri, 8 Feb 2019 11:13:23 +0000 Subject: [PATCH 09/22] formatting changes, lint made me do it --- lib/irslackd.js | 168 +++++++++++++++++++++---------------------- package.json | 2 +- tests/test_invite.js | 23 ++++++ 3 files changed, 105 insertions(+), 88 deletions(-) create mode 100644 tests/test_invite.js diff --git a/lib/irslackd.js b/lib/irslackd.js index 38da620..758bce8 100644 --- a/lib/irslackd.js +++ b/lib/irslackd.js @@ -1,10 +1,10 @@ 'use strict'; -const util = require('util'); -const slack = require('@slack/client'); +const util = require('util'); +const slack = require('@slack/client'); const AwaitLock = require('await-lock'); -const ircd = require('./ircd'); -const refresh = require('./slack-refresh'); +const ircd = require('./ircd'); +const refresh = require('./slack-refresh'); const debugChannel = '+irslackd'; class Irslackd { @@ -19,24 +19,24 @@ class Irslackd { const self = this; self.ircd = self.getNewIrcd(self.config.tlsOpts); new Map([ - [ 'AWAY', self.makeIrcHandler(self.onIrcAway) ], - [ 'JOIN', self.makeIrcHandler(self.onIrcJoin) ], - [ 'NICK', self.makeIrcHandler(self.onIrcNick) ], - [ 'PART', self.makeIrcHandler(self.onIrcPart) ], - [ 'PASS', self.makeIrcHandler(self.onIrcPass) ], - [ 'PRIVMSG', self.makeIrcHandler(self.onIrcPrivmsg) ], - [ 'QUIT', self.makeIrcHandler(self.onIrcQuit) ], - [ 'USER', self.makeIrcHandler(self.onIrcUser) ], - [ 'INVITE', self.makeIrcHandler(self.onIrcInvite) ], - [ 'WHO', self.makeIrcHandler(self.onIrcWho) ], - [ 'WHOIS', self.makeIrcHandler(self.onIrcWhois) ], - [ 'PING', self.makeIrcHandler(self.onIrcPing) ], - [ 'MODE', self.makeIrcHandler(self.onIrcMode) ], - [ 'LIST', self.makeIrcHandler(self.onIrcList) ], - [ 'ircLine', self.makeIrcHandler(self.onIrcLine) ], - [ 'ircError', self.makeIrcHandler(self.onIrcError) ], - [ 'ircClose', self.makeIrcHandler(self.onIrcClose) ], - [ 'ircConnect', (socket) => { self.onIrcConnect(socket); } ], + ['AWAY', self.makeIrcHandler(self.onIrcAway)], + ['JOIN', self.makeIrcHandler(self.onIrcJoin)], + ['NICK', self.makeIrcHandler(self.onIrcNick)], + ['PART', self.makeIrcHandler(self.onIrcPart)], + ['PASS', self.makeIrcHandler(self.onIrcPass)], + ['PRIVMSG', self.makeIrcHandler(self.onIrcPrivmsg)], + ['QUIT', self.makeIrcHandler(self.onIrcQuit)], + ['USER', self.makeIrcHandler(self.onIrcUser)], + ['INVITE', self.makeIrcHandler(self.onIrcInvite)], + ['WHO', self.makeIrcHandler(self.onIrcWho)], + ['WHOIS', self.makeIrcHandler(self.onIrcWhois)], + ['PING', self.makeIrcHandler(self.onIrcPing)], + ['MODE', self.makeIrcHandler(self.onIrcMode)], + ['LIST', self.makeIrcHandler(self.onIrcList)], + ['ircLine', self.makeIrcHandler(self.onIrcLine)], + ['ircError', self.makeIrcHandler(self.onIrcError)], + ['ircClose', self.makeIrcHandler(self.onIrcClose)], + ['ircConnect', (socket) => { self.onIrcConnect(socket); }], ]).forEach((handler, cmd, map) => { self.ircd.on(cmd, handler); }); @@ -86,24 +86,24 @@ class Irslackd { // Setup Slack handlers self.rtmMap.set(ircUser.slackRtm, ircUser); new Map([ - [ 'ready', self.makeSlackHandler(self.onSlackReady) ], - [ 'message', self.makeSlackHandler(self.onSlackMessage) ], - [ 'channel_joined', self.makeSlackHandler(self.onSlackChannelJoined) ], - [ 'channel_left', self.makeSlackHandler(self.onSlackChannelLeft) ], - [ 'channel_rename', self.makeSlackHandler(self.onSlackChannelRename) ], - [ 'channel_created', self.makeSlackHandler(self.onSlackChannelCreated) ], - [ 'member_joined_channel', self.makeSlackHandler(self.onSlackMemberJoinedChannel) ], - [ 'member_left_channel', self.makeSlackHandler(self.onSlackMemberLeftChannel) ], - [ 'mpim_open', self.makeSlackHandler(self.onSlackMpimOpen) ], - [ 'mpim_close', self.makeSlackHandler(self.onSlackMpimClose) ], - [ 'reaction_added', self.makeSlackHandler(self.onSlackReactionAdded) ], - [ 'reaction_removed', self.makeSlackHandler(self.onSlackReactionRemoved) ], - [ 'subteam_created', self.makeSlackHandler(self.onSlackSubteamUpdated) ], - [ 'subteam_updated', self.makeSlackHandler(self.onSlackSubteamUpdated) ], - [ 'user_typing', self.makeSlackHandler(self.onSlackUserTyping) ], - [ 'presence_change', self.makeSlackHandler(self.onSlackPresenceChange) ], - [ 'team_join', self.makeSlackHandler(self.onSlackTeamJoin) ], - [ 'slack_event', self.makeSlackHandler(self.onSlackEvent) ], + ['ready', self.makeSlackHandler(self.onSlackReady)], + ['message', self.makeSlackHandler(self.onSlackMessage)], + ['channel_joined', self.makeSlackHandler(self.onSlackChannelJoined)], + ['channel_left', self.makeSlackHandler(self.onSlackChannelLeft)], + ['channel_rename', self.makeSlackHandler(self.onSlackChannelRename)], + ['channel_created', self.makeSlackHandler(self.onSlackChannelCreated)], + ['member_joined_channel', self.makeSlackHandler(self.onSlackMemberJoinedChannel)], + ['member_left_channel', self.makeSlackHandler(self.onSlackMemberLeftChannel)], + ['mpim_open', self.makeSlackHandler(self.onSlackMpimOpen)], + ['mpim_close', self.makeSlackHandler(self.onSlackMpimClose)], + ['reaction_added', self.makeSlackHandler(self.onSlackReactionAdded)], + ['reaction_removed', self.makeSlackHandler(self.onSlackReactionRemoved)], + ['subteam_created', self.makeSlackHandler(self.onSlackSubteamUpdated)], + ['subteam_updated', self.makeSlackHandler(self.onSlackSubteamUpdated)], + ['user_typing', self.makeSlackHandler(self.onSlackUserTyping)], + ['presence_change', self.makeSlackHandler(self.onSlackPresenceChange)], + ['team_join', self.makeSlackHandler(self.onSlackTeamJoin)], + ['slack_event', self.makeSlackHandler(self.onSlackEvent)], ]).forEach((handler, event, map) => { ircUser.slackRtm.on(event, handler); }); @@ -192,7 +192,7 @@ class Irslackd { }); // Assemble IRC nicks - let ircNicks = [ ircUser.ircNick ]; + let ircNicks = [ircUser.ircNick]; let ircNickPromises = []; members.members.forEach((userId) => { let ircNickPromise = self.resolveSlackUser(ircUser, userId); @@ -300,7 +300,7 @@ class Irslackd { } async onIrcPing(ircUser, msg) { // Send PONG - this.ircd.write(ircUser.socket, 'irslackd', 'PONG', [ 'irslackd' ]); + this.ircd.write(ircUser.socket, 'irslackd', 'PONG', ['irslackd']); } async onIrcMode(ircUser, msg) { let target = msg.args[0]; @@ -308,15 +308,10 @@ class Irslackd { this.ircd.write(ircUser.socket, 'irslackd', 'MODE', msg.args); } } - /** - * @todo: work in progress - * @param {*} ircUser - * @param {*} msg - */ async onIrcInvite(ircUser, msg) { const self = this; if (msg.args.length !== 2) { - self.ircd.write(ircUser.socket, 'irslackd', '371', [ ircUser.ircNick, ':Must pass two params, the user to invite and the channel' ]); + self.ircd.write(ircUser.socket, 'irslackd', '371', [ircUser.ircNick, ':Must pass two params, the user to invite and the channel']); return; // must have two params (nick and channel) } var userId = await self.lookupUserId(ircUser, msg.args[0]); @@ -328,7 +323,7 @@ class Irslackd { self.ircd.write(ircUser.socket, 'irslackd', '341', [ ircUser.ircNick, channelId, - userId, + userId, ]); } async lookupChannelId(ircUser, channelName) { @@ -372,17 +367,16 @@ class Irslackd { } async onIrcWho(ircUser, msg) { const self = this; - var userSearch, channelSearch; + var userSearch; if (msg.args.length > 1) return; // Only support `WHO` with one params - if (msg.args.length > 0 && msg.args[0].substr(0,1) === '#') { - channelSearch = msg.args[0].substr(1); - self.ircd.write(ircUser.socket, 'irslackd', '315', [ ircUser.ircNick, ':End of WHO - channels not implemented' ]); + if (msg.args.length > 0 && msg.args[0].substr(0, 1) === '#') { + self.ircd.write(ircUser.socket, 'irslackd', '315', [ircUser.ircNick, ':End of WHO - channels not implemented']); return; } if (msg.args.length > 0) { userSearch = msg.args[0]; } - self.ircd.write(ircUser.socket, 'irslackd', '371', [ ircUser.ircNick, ':Start of WHO' ]); + self.ircd.write(ircUser.socket, 'irslackd', '371', [ircUser.ircNick, ':Start of WHO']); let users = await ircUser.slackWeb.paginateCallOrThrow('users.list', 'members', { presence: false, limit: 1000, @@ -404,13 +398,13 @@ class Irslackd { 'irslackd', 'example.com', user.name, - user.profile.email?user.profile.email:'nobody@example.com', + user.profile.email ? user.profile.email : 'nobody@example.com', '0', user.profile.real_name, ]); } }); - self.ircd.write(ircUser.socket, 'irslackd', '315', [ ircUser.ircNick, ':End of WHO' ]); + self.ircd.write(ircUser.socket, 'irslackd', '315', [ircUser.ircNick, ':End of WHO']); } async onIrcList(ircUser, msg) { const self = this; @@ -428,17 +422,17 @@ class Irslackd { ':' + channel.topic.value, ]); }); - self.ircd.write(ircUser.socket, 'irslackd', '323', [ ircUser.ircNick, ':End of LIST' ]); + self.ircd.write(ircUser.socket, 'irslackd', '323', [ircUser.ircNick, ':End of LIST']); } async onIrcQuit(ircUser, msg) { // Close link - this.ircd.write(ircUser.socket, 'irslackd', 'ERROR', [ ':Closing Link' ]); + this.ircd.write(ircUser.socket, 'irslackd', 'ERROR', [':Closing Link']); ircUser.socket.destroy(); } async onSlackReady(ircUser, event) { // Send MOTD - this.ircd.write(ircUser.socket, 'irslackd', '001', [ ircUser.ircNick, 'irslackd' ]); - this.ircd.write(ircUser.socket, 'irslackd', '376', [ ircUser.ircNick, 'End of MOTD' ]); + this.ircd.write(ircUser.socket, 'irslackd', '001', [ircUser.ircNick, 'irslackd']); + this.ircd.write(ircUser.socket, 'irslackd', '376', [ircUser.ircNick, 'End of MOTD']); // set user presence to auto instead of away await this.setSlackPresence(ircUser, true); @@ -532,7 +526,7 @@ class Irslackd { } // Also send attachments - let messages = [ event.text ]; + let messages = [event.text]; if (event.attachments) { event.attachments.forEach((attachment, idx) => { if (attachment.fallback) messages.push('> ' + self.ircizeText(ircUser, self.decodeEntities(attachment.fallback))); @@ -553,7 +547,7 @@ class Irslackd { line = line.trim(); if (line.length < 1) return; if (event.subtype === 'me_message') line = self.meText(line); - self.ircd.write(ircUser.socket, ircNick, 'PRIVMSG', [ ircTarget, ':' + line ]); + self.ircd.write(ircUser.socket, ircNick, 'PRIVMSG', [ircTarget, ':' + line]); }); }); } @@ -566,7 +560,7 @@ class Irslackd { event.topic = this.ircizeText(ircUser, this.decodeEntities(event.topic)); // Send topic message - this.ircd.write(ircUser.socket, ircNick, 'TOPIC', [ ircChan, event.topic ]); + this.ircd.write(ircUser.socket, ircNick, 'TOPIC', [ircChan, event.topic]); } async onSlackChannelJoined(ircUser, event) { let ircChan = await this.resolveSlackChannel(ircUser, event.channel); @@ -577,7 +571,7 @@ class Irslackd { async onSlackChannelLeft(ircUser, event) { let ircChan = await this.resolveSlackChannel(ircUser, event.channel); if (ircChan) { - await this.onIrcPart(ircUser, { args: [ ircChan ] }, event.channel); + await this.onIrcPart(ircUser, { args: [ircChan] }, event.channel); } } async onSlackChannelRename(ircUser, event) { @@ -585,7 +579,7 @@ class Irslackd { let newIrcChan = '#' + event.channel.name; let isInChan = ircUser.isInChannel(oldIrcChan); if (isInChan) { - this.ircd.write(ircUser.socket, ircUser.ircNick, 'PART', [ oldIrcChan ]); + this.ircd.write(ircUser.socket, ircUser.ircNick, 'PART', [oldIrcChan]); ircUser.partChannel(oldIrcChan); } ircUser.ircToSlack.delete(oldIrcChan); @@ -600,7 +594,7 @@ class Irslackd { let [ircNick, ircChan] = await this.resolveSlackTarget(ircUser, event); if (ircNick && ircChan && !ircUser.isNickInChannel(ircChan, ircNick)) { ircUser.addNickToChannel(ircChan, ircNick); - this.ircd.write(ircUser.socket, ircNick, 'JOIN', [ ircChan ]); + this.ircd.write(ircUser.socket, ircNick, 'JOIN', [ircChan]); } } async onSlackMemberLeftChannel(ircUser, event) { @@ -608,7 +602,7 @@ class Irslackd { let [ircNick, ircChan] = await this.resolveSlackTarget(ircUser, event); if (ircNick && ircChan && ircUser.isNickInChannel(ircChan, ircNick)) { ircUser.removeNickFromChannel(ircChan, ircNick); - this.ircd.write(ircUser.socket, ircNick, 'PART', [ ircChan ]); + this.ircd.write(ircUser.socket, ircNick, 'PART', [ircChan]); } } async onSlackMpimOpen(ircUser, event) { @@ -648,11 +642,11 @@ class Irslackd { } let ircReacter = this.resolveSlackUser(ircUser, event.user); let ircReactee = this.resolveSlackUser(ircUser, event.item_user); - let ircChan = this.resolveSlackChannel(ircUser, event.item.channel); + let ircChan = this.resolveSlackChannel(ircUser, event.item.channel); try { ircReacter = await ircReacter; ircReactee = await ircReactee; - ircChan = await ircChan; + ircChan = await ircChan; if (!ircReacter || !ircReactee || !ircChan) { throw Error('Missing reaction info'); } @@ -661,7 +655,7 @@ class Irslackd { return; } let message = this.meText(verb + ' @ ' + ircReactee + ' :' + event.reaction + ':'); - this.ircd.write(ircUser.socket, ircReacter, 'PRIVMSG', [ ircChan, message ]); + this.ircd.write(ircUser.socket, ircReacter, 'PRIVMSG', [ircChan, message]); } async onSlackUserTyping(ircUser, event) { if (!ircUser.typingNotificationsEnabled()) { @@ -674,7 +668,7 @@ class Irslackd { } console.log('slack_typing', ircNick, ircTarget); let line = this.typingText('1'); - this.ircd.write(ircUser.socket, ircNick, 'PRIVMSG', [ ircTarget, line ]); + this.ircd.write(ircUser.socket, ircNick, 'PRIVMSG', [ircTarget, line]); } async onSlackPresenceChange(ircUser, event) { if (!ircUser.presenceEnabled()) { @@ -705,9 +699,9 @@ class Irslackd { // Update presence subscriptions this.updatePresenceSubscriptions(ircUser); } -/** async onIrcWho(ircUser, msg) { - await this.onIrcWhois(ircUser, msg); - }*/ + /** async onIrcWho(ircUser, msg) { + await this.onIrcWhois(ircUser, msg); + }*/ async onIrcWhois(ircUser, msg) { if (msg.args.length < 1) return; let ircNick = msg.args[0]; @@ -739,15 +733,15 @@ class Irslackd { let out = null; const iOpts = { depth: 3, showHidden: true }; switch (cmd) { - case 'dump_server': out = util.inspect(this, iOpts); break; - case 'dump_user': out = util.inspect(ircUser, iOpts); break; - case 'dump_rtm': out = util.inspect(ircUser.slackRtm, iOpts); break; - case 'dump_web': out = util.inspect(ircUser.slackWeb, iOpts); break; + case 'dump_server': out = util.inspect(this, iOpts); break; + case 'dump_user': out = util.inspect(ircUser, iOpts); break; + case 'dump_rtm': out = util.inspect(ircUser.slackRtm, iOpts); break; + case 'dump_web': out = util.inspect(ircUser.slackWeb, iOpts); break; } if (out) console.log('debug', cmd, out); } onIrcDebugJoin(ircUser) { - this.sendIrcChannelJoin(ircUser, debugChannel, 'irslackd debug', [ ircUser.ircNick ]); + this.sendIrcChannelJoin(ircUser, debugChannel, 'irslackd debug', [ircUser.ircNick]); } onIrcDebugPart(ircUser) { this.sendIrcChannelPart(ircUser, debugChannel); @@ -788,7 +782,7 @@ class Irslackd { } catch (e) { this.logError(ircUser, util.inspect(e)); } - return [ ircNick, ircChan ]; + return [ircNick, ircChan]; } async resolveSlackChannel(ircUser, slackChan) { // Check cache @@ -864,10 +858,10 @@ class Irslackd { ircUser.joinChannel(ircChan, ircNicks); // Join IRC channel - this.ircd.write(ircUser.socket, ircUser.ircNick, 'JOIN', [ ircChan ]); + this.ircd.write(ircUser.socket, ircUser.ircNick, 'JOIN', [ircChan]); if (topic) { topic = this.ircizeText(ircUser, this.decodeEntities(topic)); - this.ircd.write(ircUser.socket, 'irslackd', '332', [ ircUser.ircNick, ircChan, ':' + topic ]); + this.ircd.write(ircUser.socket, 'irslackd', '332', [ircUser.ircNick, ircChan, ':' + topic]); } // Send nicks in chunks of 20 @@ -886,7 +880,7 @@ class Irslackd { sendIrcChannelPart(ircUser, ircChan) { // Unset channel marker and leave IRC channel if (ircUser.partChannel(ircChan)) { - this.ircd.write(ircUser.socket, ircUser.ircNick, 'PART', [ ircChan ]); + this.ircd.write(ircUser.socket, ircUser.ircNick, 'PART', [ircChan]); } } updatePresenceSubscriptions(ircUser) { @@ -967,9 +961,9 @@ class Irslackd { let re = /^@thread-([^ ]+) /; let match = re.exec(text); if (match) { - return [ text.replace(re, ''), match[1] ]; + return [text.replace(re, ''), match[1]]; } - return [ text, null ]; + return [text, null]; } async rememberSelfEcho(ircUser, message, apiCb) { await ircUser.selfEchoLock.acquireAsync(); @@ -1069,8 +1063,8 @@ class Irslackd { results[aggKey] = results[aggKey].concat(result[aggKey]); } if (!result.response_metadata - || !result.response_metadata.next_cursor - || result.response_metadata.next_cursor.length < 1 + || !result.response_metadata.next_cursor + || result.response_metadata.next_cursor.length < 1 ) { break; } diff --git a/package.json b/package.json index b366749..ea4e979 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "homepage": "https://github.com/adsr/irslackd#readme", "scripts": { "pretest": "eslint --ignore-path .gitignore .", - "test": "testfn() { patt=${@:-test_}; find tests -name \"*${patt}*\" | xargs -rn1 node | awk -f bin/filter-tape.awk; }; testfn" + "test": "testfn() { patt=${@:-test_}; find tests -name \"*${patt}*\" | xargs -n1 node | awk -f bin/filter-tape.awk; }; testfn" }, "dependencies": { "@slack/client": "^4.8.0", diff --git a/tests/test_invite.js b/tests/test_invite.js new file mode 100644 index 0000000..9b689c7 --- /dev/null +++ b/tests/test_invite.js @@ -0,0 +1,23 @@ +'use strict'; + +const test = require('tape'); +const mocks = require('./mocks'); + +test('irc_list', async(t) => { + t.plan(5 + mocks.connectOneIrcClient.planCount); + const c = await mocks.connectOneIrcClient(t); + c.slackWeb.expect('channel.invite', { exclude_archived: true, types: 'public_channel', limit: 1000 }, { + ok: true, + channels: [ + { name: 'chan1', num_members: 1, topic: { value: 'chan1 topic' } }, + { name: 'chan2', num_members: 2, topic: { value: 'chan2 topic' } }, + { name: 'chan3', num_members: 3, topic: { value: 'chan3 topic' } }, + ], + }); + c.ircSocket.expect(':irslackd 322 test_slack_user #chan1 1 :chan1 topic'); + c.ircSocket.expect(':irslackd 322 test_slack_user #chan2 2 :chan2 topic'); + c.ircSocket.expect(':irslackd 322 test_slack_user #chan3 3 :chan3 topic'); + c.ircSocket.expect(':irslackd 323 test_slack_user :End of LIST'); + await c.daemon.onIrcInvite(c.ircUser, { args: ['U1234USER', 'CFOOBAR'] }); + t.end(); +}); From 9dcc5164d234feb1bd7d251297ad4807edd69662 Mon Sep 17 00:00:00 2001 From: Jay Colson Date: Fri, 8 Feb 2019 18:30:42 +0000 Subject: [PATCH 10/22] switched from channel.invite to conversations.invite --- lib/irslackd.js | 11 +++++++---- tests/test_invite.js | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/irslackd.js b/lib/irslackd.js index 6645770..be99510 100644 --- a/lib/irslackd.js +++ b/lib/irslackd.js @@ -320,7 +320,6 @@ class Irslackd { } async onIrcInvite(ircUser, msg) { const self = this; - try { if (msg.args.length !== 2) { self.ircd.write(ircUser.socket, 'irslackd', '371', [ircUser.ircNick, ':Must pass two params, the user to invite and the channel']); @@ -328,16 +327,18 @@ class Irslackd { } var userId = await self.lookupUserId(ircUser, msg.args[0].substr(0, 1) === '@' ? msg.args[0].substr(1) : msg.args[0]); // remove at-sign var channelId = await self.lookupChannelId(ircUser, msg.args[1].substr(0, 1) === '#' ? msg.args[1].substr(1) : msg.args[1]); // remove hash - await ircUser.slackWeb.paginateCallOrThrow('channels.invite', 'channel', { + var result = await ircUser.slackWeb.paginateCallOrThrow('conversations.invite', 'channel', { + users: userId, channel: channelId, - user: userId, }); + console.debug('invite call response: ' + JSON.stringify(result)); self.ircd.write(ircUser.socket, 'irslackd', '341', [ ircUser.ircNick, channelId, userId, ]); } catch (e) { + console.debug('invite call failed response: ' + JSON.stringify(e.message)); self.ircd.write(ircUser.socket, 'irslackd', '371', [ ircUser.ircNick, ':/INVITE failed->' + JSON.parse(e.message).error.code + '->' + @@ -1125,7 +1126,9 @@ class Irslackd { return new ircd.Ircd(tlsOpts); } getNewSlackWebClient(token) { - return new slack.WebClient(token); + return new slack.WebClient(token, { + logLevel: this.config.rtmClientLogLevel || 'info', + }); } getNewSlackRtmClient(token) { return new slack.RTMClient(token, { diff --git a/tests/test_invite.js b/tests/test_invite.js index 9b689c7..d0e0931 100644 --- a/tests/test_invite.js +++ b/tests/test_invite.js @@ -3,7 +3,7 @@ const test = require('tape'); const mocks = require('./mocks'); -test('irc_list', async(t) => { +test('irc_invite', async(t) => { t.plan(5 + mocks.connectOneIrcClient.planCount); const c = await mocks.connectOneIrcClient(t); c.slackWeb.expect('channel.invite', { exclude_archived: true, types: 'public_channel', limit: 1000 }, { From 094d3021cb1465f19fa62bc0c60835f3f04e8b9e Mon Sep 17 00:00:00 2001 From: Jay Colson Date: Fri, 8 Feb 2019 21:17:24 +0000 Subject: [PATCH 11/22] updated test_invite --- lib/irslackd.js | 2 +- tests/test_connect.js | 2 +- tests/test_invite.js | 16 ++++++---------- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/lib/irslackd.js b/lib/irslackd.js index be99510..d66ed99 100644 --- a/lib/irslackd.js +++ b/lib/irslackd.js @@ -334,8 +334,8 @@ class Irslackd { console.debug('invite call response: ' + JSON.stringify(result)); self.ircd.write(ircUser.socket, 'irslackd', '341', [ ircUser.ircNick, - channelId, userId, + channelId, ]); } catch (e) { console.debug('invite call failed response: ' + JSON.stringify(e.message)); diff --git a/tests/test_connect.js b/tests/test_connect.js index 56fb33e..c6f096c 100644 --- a/tests/test_connect.js +++ b/tests/test_connect.js @@ -4,7 +4,7 @@ const test = require('tape'); const mocks = require('./mocks'); test('connect_simple', async(t) => { - t.plan(mocks.connectOneIrcClient.planCout); + t.plan(mocks.connectOneIrcClient.planCount); await mocks.connectOneIrcClient(t); t.end(); }); diff --git a/tests/test_invite.js b/tests/test_invite.js index d0e0931..5c59516 100644 --- a/tests/test_invite.js +++ b/tests/test_invite.js @@ -4,20 +4,16 @@ const test = require('tape'); const mocks = require('./mocks'); test('irc_invite', async(t) => { - t.plan(5 + mocks.connectOneIrcClient.planCount); + t.plan(mocks.connectOneIrcClient.planCount); const c = await mocks.connectOneIrcClient(t); - c.slackWeb.expect('channel.invite', { exclude_archived: true, types: 'public_channel', limit: 1000 }, { + c.slackWeb.expect('channel.invite', { users: 'U1234USER', + channel: 'CFOOBAR'}, { ok: true, - channels: [ - { name: 'chan1', num_members: 1, topic: { value: 'chan1 topic' } }, - { name: 'chan2', num_members: 2, topic: { value: 'chan2 topic' } }, - { name: 'chan3', num_members: 3, topic: { value: 'chan3 topic' } }, + channel: [ + { id: 'CFOOBAR' }, ], }); - c.ircSocket.expect(':irslackd 322 test_slack_user #chan1 1 :chan1 topic'); - c.ircSocket.expect(':irslackd 322 test_slack_user #chan2 2 :chan2 topic'); - c.ircSocket.expect(':irslackd 322 test_slack_user #chan3 3 :chan3 topic'); - c.ircSocket.expect(':irslackd 323 test_slack_user :End of LIST'); + c.ircSocket.expect('jay has invited U1234USER to CFOOBAR'); await c.daemon.onIrcInvite(c.ircUser, { args: ['U1234USER', 'CFOOBAR'] }); t.end(); }); From 664d07b33f766a235f0c8d4b83c2a62b8514f80e Mon Sep 17 00:00:00 2001 From: Jay Colson Date: Sat, 9 Feb 2019 17:52:04 +0000 Subject: [PATCH 12/22] changed plan number --- tests/test_invite.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_invite.js b/tests/test_invite.js index 5c59516..8fa9f81 100644 --- a/tests/test_invite.js +++ b/tests/test_invite.js @@ -4,16 +4,16 @@ const test = require('tape'); const mocks = require('./mocks'); test('irc_invite', async(t) => { - t.plan(mocks.connectOneIrcClient.planCount); + t.plan(1 + mocks.connectOneIrcClient.planCount); const c = await mocks.connectOneIrcClient(t); - c.slackWeb.expect('channel.invite', { users: 'U1234USER', + c.slackWeb.expect('conversations.invite', { users: 'U1235BARR', channel: 'CFOOBAR'}, { ok: true, channel: [ { id: 'CFOOBAR' }, ], }); - c.ircSocket.expect('jay has invited U1234USER to CFOOBAR'); - await c.daemon.onIrcInvite(c.ircUser, { args: ['U1234USER', 'CFOOBAR'] }); + c.ircSocket.expect('jay has invited U1235BARR to CFOOBAR'); + await c.daemon.onIrcInvite(c.ircUser, { args: ['U1235BARR', 'CFOOBAR'] }); t.end(); }); From a5d13d5e89773bf0928863c49d46892f6f2b4466 Mon Sep 17 00:00:00 2001 From: Jay Colson Date: Sat, 9 Feb 2019 18:17:54 +0000 Subject: [PATCH 13/22] data element during testing was null, causing an unexpected exception, test for undefined --- lib/irslackd.js | 4 ++-- tests/test_invite.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/irslackd.js b/lib/irslackd.js index d66ed99..599a17b 100644 --- a/lib/irslackd.js +++ b/lib/irslackd.js @@ -338,11 +338,11 @@ class Irslackd { channelId, ]); } catch (e) { - console.debug('invite call failed response: ' + JSON.stringify(e.message)); + var errorFromData = typeof JSON.parse(e.message).error.data !== 'undefined' ? JSON.parse(e.message).error.data.error : 'no data element in error response'; self.ircd.write(ircUser.socket, 'irslackd', '371', [ ircUser.ircNick, ':/INVITE failed->' + JSON.parse(e.message).error.code + '->' + - JSON.parse(e.message).error.data.error, + errorFromData, ]); } } diff --git a/tests/test_invite.js b/tests/test_invite.js index 8fa9f81..c425443 100644 --- a/tests/test_invite.js +++ b/tests/test_invite.js @@ -4,7 +4,7 @@ const test = require('tape'); const mocks = require('./mocks'); test('irc_invite', async(t) => { - t.plan(1 + mocks.connectOneIrcClient.planCount); + t.plan(2 + mocks.connectOneIrcClient.planCount); const c = await mocks.connectOneIrcClient(t); c.slackWeb.expect('conversations.invite', { users: 'U1235BARR', channel: 'CFOOBAR'}, { From 2900f15a2c6dd0c8651bf66797db5c375cc6a12e Mon Sep 17 00:00:00 2001 From: Jay Colson Date: Sat, 9 Feb 2019 18:56:50 +0000 Subject: [PATCH 14/22] used ircToSlack map instead of lookupUserId --- lib/irslackd.js | 42 ++++++++++++++++++++++-------------------- tests/test_invite.js | 2 +- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/lib/irslackd.js b/lib/irslackd.js index 599a17b..495c2c3 100644 --- a/lib/irslackd.js +++ b/lib/irslackd.js @@ -325,8 +325,10 @@ class Irslackd { self.ircd.write(ircUser.socket, 'irslackd', '371', [ircUser.ircNick, ':Must pass two params, the user to invite and the channel']); return; // must have two params (nick and channel) } - var userId = await self.lookupUserId(ircUser, msg.args[0].substr(0, 1) === '@' ? msg.args[0].substr(1) : msg.args[0]); // remove at-sign + // var userId = await self.lookupUserId(ircUser, msg.args[0].substr(0, 1) === '@' ? msg.args[0].substr(1) : msg.args[0]); // remove at-sign var channelId = await self.lookupChannelId(ircUser, msg.args[1].substr(0, 1) === '#' ? msg.args[1].substr(1) : msg.args[1]); // remove hash + var userId = ircUser.ircToSlack.get(msg.args[0].substr(0, 1) === '@' ? msg.args[0].substr(1) : msg.args[0]); + // var channelId = ircUser. var result = await ircUser.slackWeb.paginateCallOrThrow('conversations.invite', 'channel', { users: userId, channel: channelId, @@ -366,25 +368,25 @@ class Irslackd { } return channelId; } - async lookupUserId(ircUser, userName) { - var userId; - let users = await ircUser.slackWeb.paginateCallOrThrow('users.list', 'members', { - presence: false, - limit: 1000, - }); - var BreakException = {}; - try { - users.members.forEach((member) => { - if (member.name === userName) { - userId = member.id; - throw BreakException; - } - }); - } catch (e) { - if (e !== BreakException) throw e; - } - return userId; - } + // async lookupUserId(ircUser, userName) { + // var userId; + // let users = await ircUser.slackWeb.paginateCallOrThrow('users.list', 'members', { + // presence: false, + // limit: 1000, + // }); + // var BreakException = {}; + // try { + // users.members.forEach((member) => { + // if (member.name === userName) { + // userId = member.id; + // throw BreakException; + // } + // }); + // } catch (e) { + // if (e !== BreakException) throw e; + // } + // return userId; + // } async onIrcWho(ircUser, msg) { const self = this; var userSearch; diff --git a/tests/test_invite.js b/tests/test_invite.js index c425443..afda5ff 100644 --- a/tests/test_invite.js +++ b/tests/test_invite.js @@ -13,7 +13,7 @@ test('irc_invite', async(t) => { { id: 'CFOOBAR' }, ], }); - c.ircSocket.expect('jay has invited U1235BARR to CFOOBAR'); + c.ircSocket.expect(':irslackd 341 jay has invited U1235BARR to CFOOBAR'); await c.daemon.onIrcInvite(c.ircUser, { args: ['U1235BARR', 'CFOOBAR'] }); t.end(); }); From 9da1d69c541aeb9effc2c546c438b173fbe32999 Mon Sep 17 00:00:00 2001 From: Jay Colson Date: Sat, 9 Feb 2019 19:09:57 +0000 Subject: [PATCH 15/22] throw an exception instead of sending error to ircclient right away --- lib/irslackd.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/irslackd.js b/lib/irslackd.js index 495c2c3..7863469 100644 --- a/lib/irslackd.js +++ b/lib/irslackd.js @@ -322,8 +322,7 @@ class Irslackd { const self = this; try { if (msg.args.length !== 2) { - self.ircd.write(ircUser.socket, 'irslackd', '371', [ircUser.ircNick, ':Must pass two params, the user to invite and the channel']); - return; // must have two params (nick and channel) + throw Error('Must pass two params, the user to invite and the channel'); } // var userId = await self.lookupUserId(ircUser, msg.args[0].substr(0, 1) === '@' ? msg.args[0].substr(1) : msg.args[0]); // remove at-sign var channelId = await self.lookupChannelId(ircUser, msg.args[1].substr(0, 1) === '#' ? msg.args[1].substr(1) : msg.args[1]); // remove hash @@ -340,11 +339,18 @@ class Irslackd { channelId, ]); } catch (e) { - var errorFromData = typeof JSON.parse(e.message).error.data !== 'undefined' ? JSON.parse(e.message).error.data.error : 'no data element in error response'; - self.ircd.write(ircUser.socket, 'irslackd', '371', [ - ircUser.ircNick, ':/INVITE failed->' + + var message; + if (JSON.parse(e.message).error.code) { + var errorFromData = typeof JSON.parse(e.message).error.data !== 'undefined' ? JSON.parse(e.message).error.data.error : 'no data element in error response'; + message = ':/INVITE failed->' + JSON.parse(e.message).error.code + '->' + - errorFromData, + errorFromData; + } else { + message = ':/INVITE failed->' + e.message; + } + self.ircd.write(ircUser.socket, 'irslackd', '371', [ + ircUser.ircNick, + message, ]); } } From 37c76e233d8cadd10b38af264ab7ad7050847e98 Mon Sep 17 00:00:00 2001 From: Jay Colson Date: Sat, 9 Feb 2019 19:14:05 +0000 Subject: [PATCH 16/22] use ircToSlack map instead of lookupChannelId --- lib/irslackd.js | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/lib/irslackd.js b/lib/irslackd.js index 7863469..101e163 100644 --- a/lib/irslackd.js +++ b/lib/irslackd.js @@ -324,10 +324,8 @@ class Irslackd { if (msg.args.length !== 2) { throw Error('Must pass two params, the user to invite and the channel'); } - // var userId = await self.lookupUserId(ircUser, msg.args[0].substr(0, 1) === '@' ? msg.args[0].substr(1) : msg.args[0]); // remove at-sign - var channelId = await self.lookupChannelId(ircUser, msg.args[1].substr(0, 1) === '#' ? msg.args[1].substr(1) : msg.args[1]); // remove hash var userId = ircUser.ircToSlack.get(msg.args[0].substr(0, 1) === '@' ? msg.args[0].substr(1) : msg.args[0]); - // var channelId = ircUser. + var channelId = ircUser.ircToSlack.get(msg.args[1]); var result = await ircUser.slackWeb.paginateCallOrThrow('conversations.invite', 'channel', { users: userId, channel: channelId, @@ -354,26 +352,26 @@ class Irslackd { ]); } } - async lookupChannelId(ircUser, channelName) { - var channelId; - let conversations = await ircUser.slackWeb.paginateCallOrThrow('conversations.list', 'channels', { - types: 'public_channel, private_channel, mpim, im', - exclude_archived: true, - limit: 1000, - }); - var BreakException = {}; - try { - conversations.channels.forEach((channel) => { - if (channel.name === channelName) { - channelId = channel.id; - throw BreakException; - } - }); - } catch (e) { - if (e !== BreakException) throw e; - } - return channelId; - } + // async lookupChannelId(ircUser, channelName) { + // var channelId; + // let conversations = await ircUser.slackWeb.paginateCallOrThrow('conversations.list', 'channels', { + // types: 'public_channel, private_channel, mpim, im', + // exclude_archived: true, + // limit: 1000, + // }); + // var BreakException = {}; + // try { + // conversations.channels.forEach((channel) => { + // if (channel.name === channelName) { + // channelId = channel.id; + // throw BreakException; + // } + // }); + // } catch (e) { + // if (e !== BreakException) throw e; + // } + // return channelId; + // } // async lookupUserId(ircUser, userName) { // var userId; // let users = await ircUser.slackWeb.paginateCallOrThrow('users.list', 'members', { From d0e35e24ee4ba63afcf3bde8fb7f5503f882f925 Mon Sep 17 00:00:00 2001 From: Jay Colson Date: Sat, 9 Feb 2019 19:42:29 +0000 Subject: [PATCH 17/22] invite test almost working --- lib/irslackd.js | 39 --------------------------------------- tests/test_invite.js | 16 +++++++++++----- 2 files changed, 11 insertions(+), 44 deletions(-) diff --git a/lib/irslackd.js b/lib/irslackd.js index 101e163..fb14de3 100644 --- a/lib/irslackd.js +++ b/lib/irslackd.js @@ -352,45 +352,6 @@ class Irslackd { ]); } } - // async lookupChannelId(ircUser, channelName) { - // var channelId; - // let conversations = await ircUser.slackWeb.paginateCallOrThrow('conversations.list', 'channels', { - // types: 'public_channel, private_channel, mpim, im', - // exclude_archived: true, - // limit: 1000, - // }); - // var BreakException = {}; - // try { - // conversations.channels.forEach((channel) => { - // if (channel.name === channelName) { - // channelId = channel.id; - // throw BreakException; - // } - // }); - // } catch (e) { - // if (e !== BreakException) throw e; - // } - // return channelId; - // } - // async lookupUserId(ircUser, userName) { - // var userId; - // let users = await ircUser.slackWeb.paginateCallOrThrow('users.list', 'members', { - // presence: false, - // limit: 1000, - // }); - // var BreakException = {}; - // try { - // users.members.forEach((member) => { - // if (member.name === userName) { - // userId = member.id; - // throw BreakException; - // } - // }); - // } catch (e) { - // if (e !== BreakException) throw e; - // } - // return userId; - // } async onIrcWho(ircUser, msg) { const self = this; var userSearch; diff --git a/tests/test_invite.js b/tests/test_invite.js index afda5ff..9730f56 100644 --- a/tests/test_invite.js +++ b/tests/test_invite.js @@ -6,14 +6,20 @@ const mocks = require('./mocks'); test('irc_invite', async(t) => { t.plan(2 + mocks.connectOneIrcClient.planCount); const c = await mocks.connectOneIrcClient(t); - c.slackWeb.expect('conversations.invite', { users: 'U1235BARR', - channel: 'CFOOBAR'}, { + c.ircUser.mapIrcToSlack('fun_user', 'U1234USER'); + c.ircUser.mapIrcToSlack('#fun_channel', 'C1234CHAN1'); + console.log('irctoslack:'); + for (var i = 0, keys = Object.keys(c.ircUser.ircToSlack), ii = keys.length; i < ii; i++) { + console.log(keys[i] + '|' + c.ircUser.ircToSlack[keys[i]].list); + } + c.slackWeb.expect('conversations.invite', { users: 'U1234USER', + channel: 'C1234CHAN1'}, { ok: true, channel: [ - { id: 'CFOOBAR' }, + { id: 'C1234CHAN1' }, ], }); - c.ircSocket.expect(':irslackd 341 jay has invited U1235BARR to CFOOBAR'); - await c.daemon.onIrcInvite(c.ircUser, { args: ['U1235BARR', 'CFOOBAR'] }); + c.ircSocket.expect(':irslackd 341 jay has invited U1234USER to C1234CHAN1'); + await c.daemon.onIrcInvite(c.ircUser, { args: ['fun_user', '#fun_channel'] }); t.end(); }); From c8949cae06c219cbb4893052cf883c60b244e613 Mon Sep 17 00:00:00 2001 From: Jay Colson Date: Sat, 9 Feb 2019 19:44:16 +0000 Subject: [PATCH 18/22] invite_test working now --- tests/test_invite.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_invite.js b/tests/test_invite.js index 9730f56..b5c1147 100644 --- a/tests/test_invite.js +++ b/tests/test_invite.js @@ -19,7 +19,7 @@ test('irc_invite', async(t) => { { id: 'C1234CHAN1' }, ], }); - c.ircSocket.expect(':irslackd 341 jay has invited U1234USER to C1234CHAN1'); + c.ircSocket.expect(':irslackd 341 test_slack_user U1234USER C1234CHAN1'); await c.daemon.onIrcInvite(c.ircUser, { args: ['fun_user', '#fun_channel'] }); t.end(); }); From 43f4e4e0581c65de6649322e5774bed18a8dba38 Mon Sep 17 00:00:00 2001 From: Jay Colson Date: Sat, 9 Feb 2019 19:46:42 +0000 Subject: [PATCH 19/22] removed console debug for invite function --- lib/irslackd.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/irslackd.js b/lib/irslackd.js index fb14de3..9eda68d 100644 --- a/lib/irslackd.js +++ b/lib/irslackd.js @@ -326,11 +326,10 @@ class Irslackd { } var userId = ircUser.ircToSlack.get(msg.args[0].substr(0, 1) === '@' ? msg.args[0].substr(1) : msg.args[0]); var channelId = ircUser.ircToSlack.get(msg.args[1]); - var result = await ircUser.slackWeb.paginateCallOrThrow('conversations.invite', 'channel', { + await ircUser.slackWeb.paginateCallOrThrow('conversations.invite', 'channel', { users: userId, channel: channelId, }); - console.debug('invite call response: ' + JSON.stringify(result)); self.ircd.write(ircUser.socket, 'irslackd', '341', [ ircUser.ircNick, userId, From c041f2335d5fae0bbe82c610fb750ed8fc9543ba Mon Sep 17 00:00:00 2001 From: Jay Colson Date: Sat, 9 Feb 2019 19:48:47 +0000 Subject: [PATCH 20/22] throw exception if id's aren't found in map --- lib/irslackd.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/irslackd.js b/lib/irslackd.js index 9eda68d..30f276d 100644 --- a/lib/irslackd.js +++ b/lib/irslackd.js @@ -326,6 +326,8 @@ class Irslackd { } var userId = ircUser.ircToSlack.get(msg.args[0].substr(0, 1) === '@' ? msg.args[0].substr(1) : msg.args[0]); var channelId = ircUser.ircToSlack.get(msg.args[1]); + if (!userId) throw Error('IRC nick not found in irslackd cache'); + if (!channelId) throw Error('IRC channel not found in irslackd cache'); await ircUser.slackWeb.paginateCallOrThrow('conversations.invite', 'channel', { users: userId, channel: channelId, From 4ae0d808d9571abfe1a9286fe390e402f97ec306 Mon Sep 17 00:00:00 2001 From: Jay Colson Date: Sat, 9 Feb 2019 19:56:21 +0000 Subject: [PATCH 21/22] added not in cache exception test for invite --- lib/irslackd.js | 10 +++++++++- tests/test_invite.js | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/irslackd.js b/lib/irslackd.js index 30f276d..ad638be 100644 --- a/lib/irslackd.js +++ b/lib/irslackd.js @@ -339,7 +339,7 @@ class Irslackd { ]); } catch (e) { var message; - if (JSON.parse(e.message).error.code) { + if (this.isJson(e.message)) { var errorFromData = typeof JSON.parse(e.message).error.data !== 'undefined' ? JSON.parse(e.message).error.data.error : 'no data element in error response'; message = ':/INVITE failed->' + JSON.parse(e.message).error.code + '->' + @@ -353,6 +353,14 @@ class Irslackd { ]); } } + isJson(str) { + try { + JSON.parse(str); + } catch (e) { + return false; + } + return true; + } async onIrcWho(ircUser, msg) { const self = this; var userSearch; diff --git a/tests/test_invite.js b/tests/test_invite.js index b5c1147..58c906a 100644 --- a/tests/test_invite.js +++ b/tests/test_invite.js @@ -23,3 +23,17 @@ test('irc_invite', async(t) => { await c.daemon.onIrcInvite(c.ircUser, { args: ['fun_user', '#fun_channel'] }); t.end(); }); + +test('irc_invite_not_in_cache', async(t) => { + t.plan(1 + mocks.connectOneIrcClient.planCount); + const c = await mocks.connectOneIrcClient(t); + // c.ircUser.mapIrcToSlack('fun_user', 'U1234USER'); + c.ircUser.mapIrcToSlack('#fun_channel', 'C1234CHAN1'); + console.log('irctoslack:'); + for (var i = 0, keys = Object.keys(c.ircUser.ircToSlack), ii = keys.length; i < ii; i++) { + console.log(keys[i] + '|' + c.ircUser.ircToSlack[keys[i]].list); + } + c.ircSocket.expect(':irslackd 371 test_slack_user :/INVITE failed->IRC nick not found in irslackd cache'); + await c.daemon.onIrcInvite(c.ircUser, { args: ['fun_user', '#fun_channel'] }); + t.end(); +}); From cfd3b0a5be436d90941248420ef059ff9a463cfe Mon Sep 17 00:00:00 2001 From: Jay Colson Date: Sat, 9 Feb 2019 21:03:03 +0000 Subject: [PATCH 22/22] added test for /who --- lib/irslackd.js | 7 ++----- tests/test_invite.js | 10 +--------- tests/test_who.js | 27 +++++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 14 deletions(-) create mode 100644 tests/test_who.js diff --git a/lib/irslackd.js b/lib/irslackd.js index ad638be..0311847 100644 --- a/lib/irslackd.js +++ b/lib/irslackd.js @@ -372,7 +372,7 @@ class Irslackd { if (msg.args.length > 0) { userSearch = msg.args[0]; } - self.ircd.write(ircUser.socket, 'irslackd', '371', [ircUser.ircNick, ':Start of WHO']); + // self.ircd.write(ircUser.socket, 'irslackd', '371', [ircUser.ircNick, ':Start of WHO']); let users = await ircUser.slackWeb.paginateCallOrThrow('users.list', 'members', { presence: false, limit: 1000, @@ -396,7 +396,7 @@ class Irslackd { user.name, user.profile.email ? user.profile.email : 'nobody@example.com', '0', - user.profile.real_name, + user.profile.real_name ? user.profile.real_name : 'Nobody', ]); } }); @@ -699,9 +699,6 @@ class Irslackd { // Update presence subscriptions this.updatePresenceSubscriptions(ircUser); } - /** async onIrcWho(ircUser, msg) { - await this.onIrcWhois(ircUser, msg); - }*/ async onIrcWhois(ircUser, msg) { if (msg.args.length < 1) return; let ircNick = msg.args[0]; diff --git a/tests/test_invite.js b/tests/test_invite.js index 58c906a..8644d09 100644 --- a/tests/test_invite.js +++ b/tests/test_invite.js @@ -8,10 +8,6 @@ test('irc_invite', async(t) => { const c = await mocks.connectOneIrcClient(t); c.ircUser.mapIrcToSlack('fun_user', 'U1234USER'); c.ircUser.mapIrcToSlack('#fun_channel', 'C1234CHAN1'); - console.log('irctoslack:'); - for (var i = 0, keys = Object.keys(c.ircUser.ircToSlack), ii = keys.length; i < ii; i++) { - console.log(keys[i] + '|' + c.ircUser.ircToSlack[keys[i]].list); - } c.slackWeb.expect('conversations.invite', { users: 'U1234USER', channel: 'C1234CHAN1'}, { ok: true, @@ -28,11 +24,7 @@ test('irc_invite_not_in_cache', async(t) => { t.plan(1 + mocks.connectOneIrcClient.planCount); const c = await mocks.connectOneIrcClient(t); // c.ircUser.mapIrcToSlack('fun_user', 'U1234USER'); - c.ircUser.mapIrcToSlack('#fun_channel', 'C1234CHAN1'); - console.log('irctoslack:'); - for (var i = 0, keys = Object.keys(c.ircUser.ircToSlack), ii = keys.length; i < ii; i++) { - console.log(keys[i] + '|' + c.ircUser.ircToSlack[keys[i]].list); - } + // c.ircUser.mapIrcToSlack('#fun_channel', 'C1234CHAN1'); c.ircSocket.expect(':irslackd 371 test_slack_user :/INVITE failed->IRC nick not found in irslackd cache'); await c.daemon.onIrcInvite(c.ircUser, { args: ['fun_user', '#fun_channel'] }); t.end(); diff --git a/tests/test_who.js b/tests/test_who.js new file mode 100644 index 0000000..2741c1f --- /dev/null +++ b/tests/test_who.js @@ -0,0 +1,27 @@ +'use strict'; + +const test = require('tape'); +const mocks = require('./mocks'); + +test('irc_who', async(t) => { + t.plan(3 + mocks.connectOneIrcClient.planCount); + const c = await mocks.connectOneIrcClient(t); + c.ircUser.mapIrcToSlack('fun_user', 'U1234USER'); + c.slackWeb.expect('users.list', { + presence: false, + limit: 1000}, { + ok: true, + members: [ + { name: 'fun_user', + id: 'U1234USER', + profile: [ + {email: 'foo@example.com', + real_name: 'Foo Bar' }, + ]}, + ], + }); + c.ircSocket.expect(':irslackd 352 test_slack_user * U1234USER irslackd example.com fun_user nobody@example.com 0 Nobody'); + c.ircSocket.expect(':irslackd 315 test_slack_user :End of WHO'); + await c.daemon.onIrcWho(c.ircUser, { args: ['fun_user'] }); + t.end(); +});