From c0e364e1c2213b668381f06c67ad474d9d7ed1e1 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Sat, 1 Apr 2017 11:33:17 +0300 Subject: [PATCH] Store channel keys --- src/client.js | 3 +- src/models/chan.js | 1 + src/models/network.js | 3 +- src/plugins/irc-events/connection.js | 2 +- src/plugins/irc-events/join.js | 3 ++ src/plugins/irc-events/mode.js | 70 ++++++++++++++++++++-------- test/models/network.js | 12 +++-- 7 files changed, 68 insertions(+), 26 deletions(-) diff --git a/src/client.js b/src/client.js index 00f3eb35..27387778 100644 --- a/src/client.js +++ b/src/client.js @@ -159,7 +159,8 @@ Client.prototype.connect = function(args) { } channels.push(new Chan({ - name: chan.name + name: chan.name, + key: chan.key || "", })); }); diff --git a/src/models/chan.js b/src/models/chan.js index 69e582ab..1448be06 100644 --- a/src/models/chan.js +++ b/src/models/chan.js @@ -19,6 +19,7 @@ function Chan(attr) { id: id++, messages: [], name: "", + key: "", topic: "", type: Chan.Type.CHANNEL, firstUnread: 0, diff --git a/src/models/network.js b/src/models/network.js index 4484ed96..f5576133 100644 --- a/src/models/network.js +++ b/src/models/network.js @@ -87,7 +87,8 @@ Network.prototype.export = function() { }) .map(function(chan) { return _.pick(chan, [ - "name" + "name", + "key", ]); }); diff --git a/src/plugins/irc-events/connection.js b/src/plugins/irc-events/connection.js index 4e34a154..47cb331c 100644 --- a/src/plugins/irc-events/connection.js +++ b/src/plugins/irc-events/connection.js @@ -47,7 +47,7 @@ module.exports = function(irc, network) { } setTimeout(function() { - network.irc.join(chan.name); + network.irc.join(chan.name, chan.key); }, delay); delay += 1000; }); diff --git a/src/plugins/irc-events/join.js b/src/plugins/irc-events/join.js index c7f91ec9..1ad88e6f 100644 --- a/src/plugins/irc-events/join.js +++ b/src/plugins/irc-events/join.js @@ -18,6 +18,9 @@ module.exports = function(irc, network) { network: network.id, chan: chan }); + + // Request channels' modes + network.irc.raw("MODE", chan.name); } chan.users.push(new User({nick: data.nick})); chan.sortUsers(irc); diff --git a/src/plugins/irc-events/mode.js b/src/plugins/irc-events/mode.js index b47985c9..44db8a73 100644 --- a/src/plugins/irc-events/mode.js +++ b/src/plugins/irc-events/mode.js @@ -1,13 +1,40 @@ "use strict"; -var _ = require("lodash"); -var Chan = require("../../models/chan"); -var Msg = require("../../models/msg"); +const _ = require("lodash"); +const Chan = require("../../models/chan"); +const Msg = require("../../models/msg"); module.exports = function(irc, network) { - var client = this; + const client = this; + + // The following saves the channel key based on channel mode instead of + // extracting it from `/join #channel key`. This lets us not have to + // temporarily store the key until successful join, but also saves the key + // if a key is set or changed while being on the channel. + irc.on("channel info", function(data) { + if (!data.modes) { + return; + } + + const targetChan = network.getChannel(data.channel); + if (typeof targetChan === "undefined") { + return; + } + + data.modes.forEach(mode => { + const text = mode.mode; + const add = text[0] === "+"; + const char = text[1]; + + if (char === "k") { + targetChan.key = add ? mode.param : ""; + client.save(); + } + }); + }); + irc.on("mode", function(data) { - var targetChan; + let targetChan; if (data.target === irc.user.nick) { targetChan = network.channels[0]; @@ -18,23 +45,29 @@ module.exports = function(irc, network) { } } - var usersUpdated; - var supportsMultiPrefix = network.irc.network.cap.isEnabled("multi-prefix"); - var userModeSortPriority = {}; + let usersUpdated; + let userModeSortPriority = {}; + const supportsMultiPrefix = network.irc.network.cap.isEnabled("multi-prefix"); irc.network.options.PREFIX.forEach((prefix, index) => { userModeSortPriority[prefix.symbol] = index; }); - for (var i = 0; i < data.modes.length; i++) { - var mode = data.modes[i]; - var text = mode.mode; + data.modes.forEach(mode => { + let text = mode.mode; + const add = text[0] === "+"; + const char = text[1]; + + if (char === "k") { + targetChan.key = add ? mode.param : ""; + client.save(); + } if (mode.param) { text += " " + mode.param; } - var msg = new Msg({ + const msg = new Msg({ time: data.time, type: Msg.Type.MODE, mode: (targetChan.type !== Chan.Type.LOBBY && targetChan.getMode(data.nick)) || "", @@ -45,22 +78,21 @@ module.exports = function(irc, network) { targetChan.pushMessage(client, msg); if (!mode.param) { - continue; + return; } - var user = _.find(targetChan.users, {name: mode.param}); + const user = _.find(targetChan.users, {name: mode.param}); if (!user) { - continue; + return; } usersUpdated = true; if (!supportsMultiPrefix) { - continue; + return; } - var add = mode.mode[0] === "+"; - var changedMode = network.prefixLookup[mode.mode[1]]; + const changedMode = network.prefixLookup[char]; if (!add) { _.pull(user.modes, changedMode); @@ -73,7 +105,7 @@ module.exports = function(irc, network) { // TODO: remove in future user.mode = (user.modes && user.modes[0]) || ""; - } + }); if (!usersUpdated) { return; diff --git a/test/models/network.js b/test/models/network.js index a5ebb5e4..1727580c 100644 --- a/test/models/network.js +++ b/test/models/network.js @@ -13,8 +13,10 @@ describe("Network", function() { awayMessage: "I am away", name: "networkName", channels: [ - new Chan({name: "#thelounge"}), - new Chan({name: "&foobar"}), + new Chan({name: "#thelounge", key: ""}), + new Chan({name: "&foobar", key: ""}), + new Chan({name: "#secret", key: "foo"}), + new Chan({name: "&secure", key: "bar"}), new Chan({name: "Channel List", type: Chan.Type.SPECIAL}), new Chan({name: "PrivateChat", type: Chan.Type.QUERY}), ] @@ -35,8 +37,10 @@ describe("Network", function() { ip: null, hostname: null, channels: [ - {name: "#thelounge"}, - {name: "&foobar"}, + {name: "#thelounge", key: ""}, + {name: "&foobar", key: ""}, + {name: "#secret", key: "foo"}, + {name: "&secure", key: "bar"}, ] }); });