UNPKG

irc-framework

Version:
421 lines (414 loc) 16.6 kB
'use strict'; require("core-js/modules/es.symbol.js"); require("core-js/modules/es.symbol.description.js"); require("core-js/modules/es.symbol.iterator.js"); require("core-js/modules/es.array.from.js"); require("core-js/modules/es.array.is-array.js"); require("core-js/modules/es.array.iterator.js"); require("core-js/modules/es.array.slice.js"); require("core-js/modules/es.date.to-string.js"); require("core-js/modules/es.function.name.js"); require("core-js/modules/es.object.to-string.js"); require("core-js/modules/es.regexp.to-string.js"); require("core-js/modules/es.string.iterator.js"); require("core-js/modules/web.dom-collections.iterator.js"); require("core-js/modules/es.array.index-of.js"); require("core-js/modules/es.array.map.js"); require("core-js/modules/es.object.assign.js"); require("core-js/modules/es.regexp.exec.js"); require("core-js/modules/es.string.match.js"); function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } var _ = { each: require('lodash/each'), map: require('lodash/map') }; var Helpers = require('../../helpers'); var handlers = { NICK: function NICK(command, handler) { // Check if we have a server-time var time = command.getServerTime(); handler.emit('nick', { nick: command.nick, ident: command.ident, hostname: command.hostname, new_nick: command.params[0], time: time, tags: command.tags, batch: command.batch }); }, ACCOUNT: function ACCOUNT(command, handler) { // Check if we have a server-time var time = command.getServerTime(); var account = command.params[0] === '*' ? false : command.params[0]; handler.emit('account', { nick: command.nick, ident: command.ident, hostname: command.hostname, account: account, time: time, tags: command.tags }); }, // If the chghost CAP is enabled and 'enable_chghost' option is true CHGHOST: function CHGHOST(command, handler) { // Check if we have a server-time var time = command.getServerTime(); handler.emit('user updated', { nick: command.nick, ident: command.ident, hostname: command.hostname, new_ident: command.params[0], new_hostname: command.params[1], time: time, tags: command.tags, batch: command.batch }); }, SETNAME: function SETNAME(command, handler) { // Check if we have a server-time var time = command.getServerTime(); handler.emit('user updated', { nick: command.nick, ident: command.ident, hostname: command.hostname, new_gecos: command.params[0], time: time, tags: command.tags, batch: command.batch }); }, AWAY: function AWAY(command, handler) { // Check if we have a server-time var time = command.getServerTime(); var message = command.params[command.params.length - 1] || ''; if (message === '') { // back handler.emit('back', { self: false, nick: command.nick, message: '', time: time, tags: command.tags }); } else { handler.emit('away', { self: false, nick: command.nick, message: message, time: time, tags: command.tags }); } }, RPL_NOWAWAY: function RPL_NOWAWAY(command, handler) { // Check if we have a server-time var time = command.getServerTime(); handler.emit('away', { self: true, nick: command.params[0], message: command.params[1] || '', time: time, tags: command.tags }); }, RPL_UNAWAY: function RPL_UNAWAY(command, handler) { // Check if we have a server-time var time = command.getServerTime(); handler.emit('back', { self: true, nick: command.params[0], message: command.params[1] || '', // example: "<nick> is now back." time: time, tags: command.tags }); }, RPL_ISON: function RPL_ISON(command, handler) { handler.emit('users online', { nicks: (command.params[command.params.length - 1] || '').split(' '), tags: command.tags }); }, ERR_NICKNAMEINUSE: function ERR_NICKNAMEINUSE(command, handler) { handler.emit('nick in use', { nick: command.params[1], reason: command.params[command.params.length - 1], tags: command.tags }); }, ERR_ERRONEOUSNICKNAME: function ERR_ERRONEOUSNICKNAME(command, handler) { handler.emit('nick invalid', { nick: command.params[1], reason: command.params[command.params.length - 1], tags: command.tags }); }, RPL_ENDOFWHOIS: function RPL_ENDOFWHOIS(command, handler) { var cache_key = command.params[1].toLowerCase(); var cache = handler.cache('whois.' + cache_key); if (!cache.nick) { cache.nick = command.params[1]; cache.error = 'not_found'; } handler.emit('whois', cache); cache.destroy(); }, RPL_AWAY: function RPL_AWAY(command, handler) { var cache_key = 'whois.' + command.params[1].toLowerCase(); var message = command.params[command.params.length - 1] || 'is away'; // RPL_AWAY may come as a response to PRIVMSG, and not be a part of whois // If so, emit away event separately for it if (!handler.hasCache(cache_key)) { // Check if we have a server-time var time = command.getServerTime(); handler.emit('away', { self: false, nick: command.params[1], message: message, time: time, tags: command.tags }); return; } var cache = handler.cache(cache_key); cache.away = message; }, RPL_WHOISUSER: function RPL_WHOISUSER(command, handler) { var cache_key = command.params[1].toLowerCase(); var cache = handler.cache('whois.' + cache_key); cache.nick = command.params[1]; cache.ident = command.params[2]; cache.hostname = command.params[3]; cache.real_name = command.params[5]; }, RPL_WHOISHELPOP: function RPL_WHOISHELPOP(command, handler) { var cache_key = command.params[1].toLowerCase(); var cache = handler.cache('whois.' + cache_key); cache.helpop = command.params[command.params.length - 1]; }, RPL_WHOISBOT: function RPL_WHOISBOT(command, handler) { var cache_key = command.params[1].toLowerCase(); var cache = handler.cache('whois.' + cache_key); cache.bot = command.params[command.params.length - 1]; }, RPL_WHOISSERVER: function RPL_WHOISSERVER(command, handler) { var cache_key = command.params[1].toLowerCase(); var cache = handler.cache('whois.' + cache_key); cache.server = command.params[2]; cache.server_info = command.params[command.params.length - 1]; }, RPL_WHOISOPERATOR: function RPL_WHOISOPERATOR(command, handler) { var cache_key = command.params[1].toLowerCase(); var cache = handler.cache('whois.' + cache_key); cache.operator = command.params[command.params.length - 1]; }, RPL_WHOISCHANNELS: function RPL_WHOISCHANNELS(command, handler) { var cache_key = command.params[1].toLowerCase(); var cache = handler.cache('whois.' + cache_key); if (cache.channels) { cache.channels += ' ' + command.params[command.params.length - 1]; } else { cache.channels = command.params[command.params.length - 1]; } }, RPL_WHOISMODES: function RPL_WHOISMODES(command, handler) { var cache_key = command.params[1].toLowerCase(); var cache = handler.cache('whois.' + cache_key); cache.modes = command.params[command.params.length - 1]; }, RPL_WHOISIDLE: function RPL_WHOISIDLE(command, handler) { var cache_key = command.params[1].toLowerCase(); var cache = handler.cache('whois.' + cache_key); cache.idle = command.params[2]; if (command.params[3]) { cache.logon = command.params[3]; } }, RPL_WHOISREGNICK: function RPL_WHOISREGNICK(command, handler) { var cache_key = command.params[1].toLowerCase(); var cache = handler.cache('whois.' + cache_key); cache.registered_nick = command.params[command.params.length - 1]; }, RPL_WHOISHOST: function RPL_WHOISHOST(command, handler) { var cache_key = command.params[1].toLowerCase(); var cache = handler.cache('whois.' + cache_key); var last_param = command.params[command.params.length - 1]; // <source> 378 <target> <nick> :is connecting from <user>@<host> <ip> var match = last_param.match(/.*@([^ ]+) ([^ ]+).*$/); // https://regex101.com/r/AQz7RE/2 if (!match) { return; } cache.actual_ip = match[2]; cache.actual_hostname = match[1]; }, RPL_WHOISSECURE: function RPL_WHOISSECURE(command, handler) { var cache_key = command.params[1].toLowerCase(); var cache = handler.cache('whois.' + cache_key); cache.secure = true; }, RPL_WHOISCERTFP: function RPL_WHOISCERTFP(command, handler) { var cache_key = command.params[1].toLowerCase(); var cache = handler.cache('whois.' + cache_key); var certfp = command.params[command.params.length - 1]; cache.certfp = cache.certfp || certfp; cache.certfps = cache.certfps || []; cache.certfps.push(certfp); }, RPL_WHOISACCOUNT: function RPL_WHOISACCOUNT(command, handler) { var cache_key = command.params[1].toLowerCase(); var cache = handler.cache('whois.' + cache_key); cache.account = command.params[2]; }, RPL_WHOISSPECIAL: function RPL_WHOISSPECIAL(command, handler) { var cache_key = command.params[1].toLowerCase(); var cache = handler.cache('whois.' + cache_key); cache.special = cache.special || []; cache.special.push(command.params[command.params.length - 1]); }, RPL_WHOISCOUNTRY: function RPL_WHOISCOUNTRY(command, handler) { var cache_key = command.params[1].toLowerCase(); var cache = handler.cache('whois.' + cache_key); cache.country = command.params[command.params.length - 1]; if (command.params.length === 4) { cache.country_code = command.params[2]; } }, RPL_WHOISASN: function RPL_WHOISASN(command, handler) { var cache_key = command.params[1].toLowerCase(); var cache = handler.cache('whois.' + cache_key); cache.asn = command.params[command.params.length - 1]; }, RPL_WHOISACTUALLY: function RPL_WHOISACTUALLY(command, handler) { var cache_key = command.params[1].toLowerCase(); var cache = handler.cache('whois.' + cache_key); // <source> 338 <target> <nick> [<user>@]<host> <ip> :Actual user@host, Actual IP var user_host = command.params[command.params.length - 3] || ''; var mask_sep = user_host.indexOf('@'); var user = user_host.substring(0, mask_sep) || undefined; var host = user_host.substring(mask_sep + 1); var ip = command.params[command.params.length - 2]; // UnrealIRCd uses this numeric for something else resulting in ip+host // to be empty, so ignore this is that's the case if (ip && host) { cache.actual_ip = ip; cache.actual_username = user; cache.actual_hostname = host; } }, RPL_WHOWASUSER: function RPL_WHOWASUSER(command, handler) { var cache_key = command.params[1].toLowerCase(); var whois_cache = handler.cache('whois.' + cache_key); // multiple RPL_WHOWASUSER replies are received prior to the RPL_ENDOFWHOWAS command // one for each timestamp the server is aware of, from newest to oldest. // They are optionally interleaved with various other numerics such as RPL_WHOISACTUALLY etc. // Hence if we already find something we are receiving older data and need to make sure that we // store anything already in the cache into its own entry var whowas_cache = handler.cache('whowas.' + cache_key); if (!whowas_cache.whowas) { // this will get populated by the next RPL_WHOWASUSER or RPL_ENDOFWHOWAS whowas_cache.whowas = []; } else { // push the previous event prior to modifying anything whowas_cache.whowas.push(whois_cache); // ensure we are starting with a clean cache for the next data whois_cache.destroy(); whois_cache = handler.cache('whois.' + cache_key); } whois_cache.nick = command.params[1]; whois_cache.ident = command.params[2]; whois_cache.hostname = command.params[3]; whois_cache.real_name = command.params[command.params.length - 1]; }, RPL_ENDOFWHOWAS: function RPL_ENDOFWHOWAS(command, handler) { // Because the WHOIS and WHOWAS numerics clash with eachother, // a cache key will have more than what is just in RPL_WHOWASUSER. // This is why we borrow from the whois.* cache key ID. // // This exposes some fields (that may or may not be set). // Valid keys that should always be set: nick, ident, hostname, real_name // Valid optional keys: actual_ip, actual_hostname, account, server, // server_info, actual_username // More optional fields MAY exist, depending on the type of ircd. var cache_key = command.params[1].toLowerCase(); var whois_cache = handler.cache('whois.' + cache_key); var whowas_cache = handler.cache('whowas.' + cache_key); // after all prior RPL_WHOWASUSER pushed newer events onto the history stack // push the last one to complete the set (server returns from newest to oldest) whowas_cache.whowas = whowas_cache.whowas || []; if (!whois_cache.error) { whowas_cache.whowas.push(whois_cache); Object.assign(whowas_cache, whowas_cache.whowas[0]); } else { Object.assign(whowas_cache, whois_cache); } handler.emit('whowas', whowas_cache); whois_cache.destroy(); whowas_cache.destroy(); }, ERR_WASNOSUCHNICK: function ERR_WASNOSUCHNICK(command, handler) { var cache_key = command.params[1].toLowerCase(); var cache = handler.cache('whois.' + cache_key); cache.nick = command.params[1]; cache.error = 'no_such_nick'; }, RPL_UMODEIS: function RPL_UMODEIS(command, handler) { var nick = command.params[0]; var raw_modes = command.params[1]; handler.emit('user info', { nick: nick, raw_modes: raw_modes, tags: command.tags }); }, RPL_HOSTCLOAKING: function RPL_HOSTCLOAKING(command, handler) { handler.emit('displayed host', { nick: command.params[0], hostname: command.params[1], tags: command.tags }); }, RPL_MONONLINE: function RPL_MONONLINE(command, handler) { var users = (command.params[command.params.length - 1] || '').split(','); var parsed = _.map(users, function (user) { return Helpers.parseMask(user).nick; }); handler.emit('users online', { nicks: parsed, tags: command.tags }); }, RPL_MONOFFLINE: function RPL_MONOFFLINE(command, handler) { var users = (command.params[command.params.length - 1] || '').split(','); handler.emit('users offline', { nicks: users, tags: command.tags }); }, RPL_MONLIST: function RPL_MONLIST(command, handler) { var _cache$nicks; var cache = handler.cache('monitorList.' + command.params[0]); if (!cache.nicks) { cache.nicks = []; } var users = command.params[command.params.length - 1].split(','); (_cache$nicks = cache.nicks).push.apply(_cache$nicks, _toConsumableArray(users)); }, RPL_ENDOFMONLIST: function RPL_ENDOFMONLIST(command, handler) { var cache = handler.cache('monitorList.' + command.params[0]); handler.emit('monitorList', { nicks: cache.nicks || [] }); cache.destroy(); } }; module.exports = function AddCommandHandlers(command_controller) { _.each(handlers, function (handler, handler_command) { command_controller.addHandler(handler_command, handler); }); };