UNPKG

ircgrampp

Version:

IRCGram++ is a complexly simple Telegram <-> IRC Gateway

468 lines (404 loc) 12.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = _default; var _inquirer = _interopRequireDefault(require("inquirer")); var _debug = _interopRequireDefault(require("debug")); var _etc = _interopRequireDefault(require("etc")); var _lodash = require("lodash"); var _config = require("../config"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var Promise = require("bluebird"); // RFC1459 const IRC_NICK_RE = /^[a-z_\-\[\]\\^{}|`][a-z0-9_\-\[\]\\^{}|`]{2,15}$/i; /*eslint no-control-regex: "off"*/ const IRC_CHAN_RE = /^([#&][^\x07\x2C\s]{0,200})$/i; const debug = (0, _debug.default)("cli-config"); const CancelSignal = function () {}; const options = [{ key: "globals", text: "(re)Configure global settings" }, { key: "editb", text: "Edit bridge config" }, { key: "createb", text: "Create new bridge config" }, { key: "deleteb", text: "Delete bridge(s)" }, { key: "exit", text: "Exit" }]; const generateConfigQuestions = function (defaults = {}, options = {}) { let defaultsOptions = (0, _lodash.assignIn)({}, { "user": _config.config.get("user") || undefined, "group": _config.config.get("group") || undefined, "telegram:token": _config.config.get("telegram:token") || undefined, "irc:server": _config.config.get("irc:server") || undefined, "irc:port": _config.config.get("irc:port") || 6697, "irc:nick": _config.config.get("irc:nick") || undefined, "irc:secure": _config.config.get("irc:secure") === false ? false : _config.config.get("irc:secure"), "useIrcColors": _config.config.get("useIrcColors") || true, "oneConnectionByUser": _config.config.get("oneConnectionByUser") || false, "ircScapeCharacter": _config.config.get("ircScapeCharacter") || "", "showJoinLeft": _config.config.get("showJoinLeft") || true, "prefix": _config.config.get("prefix") || "telegram_", "suffix": _config.config.get("suffix") || "" }, defaults); let suQuestions = []; if (process.getuid() === 0 && !options.ignoreSuQuestions) { suQuestions = [{ type: "input", name: "user", message: "Daemon UID", default: defaultsOptions["user"] }, { type: "input", name: "group", message: "Daemon GID", default: defaultsOptions["group"] }]; } return [...suQuestions, { type: "input", name: "telegram:token", message: "Telegram token", default: defaultsOptions["telegram:token"] }, { type: "input", name: "irc:server", message: "IRC server ip or nameserver?", default: defaultsOptions["irc:server"] }, { type: "input", name: "irc:port", message: "IRC server port?", default: defaultsOptions["irc:port"], validate(value) { value = parseInt(value); return value > 0 && value < 65535; } }, { type: "input", name: "irc:nick", message: "IRC nickname", default: defaultsOptions["irc:nick"], validate(value) { if (!options.ircNickNameRequired && value === "") { return true; } if (value.match(IRC_NICK_RE)) { return true; } else { return "Invalid IRC nick"; } } }, { type: "confirm", name: "irc:secure", message: "IRC server uses SSL?", default: defaultsOptions["irc:secure"] }, { type: "confirm", name: "oneConnectionByUser", message: "Do you use one new IRC connection by telgram user?", default: defaultsOptions["oneConnectionByUser"] }, { type: "confirm", name: "useIrcColors", message: "Do you use colors in IRC?", default: defaultsOptions["useIrcColors"] }, { type: "input", name: "ircScapeCharacter", message: "Do you use one especial character for IRC bots?", default: defaultsOptions["ircScapeCharacter"] }, { type: "confirm", name: "showJoinLeft", message: "Do you want to show who join or left irc channel in Telegram?", default: defaultsOptions["showJoinLeft"] }, { type: "input", name: "prefix", message: "Prefix for IRC users?", default: defaultsOptions["prefix"], validate(value) { return !!value.match(/^[a-z0-9_]{0,10}$/i); } }, { type: "input", name: "suffix", message: "Suffix for IRC users?", default: defaultsOptions["suffix"], validate(value) { return !!value.match(/^[a-z0-9_]{0,10}$/i); } }]; }; const generateBridgeConfigQuestions = function (defaults = {}) { let defaultsOptions = (0, _lodash.assignIn)({}, { "enable": true }, defaults); return [{ type: "input", name: "name", message: "Bridge name", default: defaultsOptions["name"], validate(value) { let bridges = _config.config.get("bridges").map(x => x.name); if (bridges.indexOf(value) !== -1 && value !== defaults.name) { return "Bridge already exists"; } if (value.match(/^[a-z0-9]{3,20}$/i)) { return true; } else { return "Bridge name can be letters, numbers and _ " + "character, and a length from 3 to 20"; } } }, ...generateConfigQuestions(defaultsOptions, { ircNickNameRequired: true, ignoreSuQuestions: true }), { type: "input", name: "irc:channel", message: "IRC channel", default: defaultsOptions["irc:channel"], validate(val) { if (val.match(IRC_CHAN_RE)) { return true; } else { return "Invalid IRC channel name"; } } }, { type: "input", name: "telegram:channel", message: "Telegram channel name or id", default: defaultsOptions["telegram:channel"], validate(val) { if (!val || val === "") { return "You need to define a Telegram channel"; } return true; } }, { type: "confirm", name: "enable", message: "Bridge is enable?", default: defaultsOptions["enable"] }]; }; const confirm = function (text) { return _inquirer.default.prompt({ type: "confirm", name: "res", message: text }).then(res => { return res.res; }); }; const initConfig = function () { return new Promise(resolve => { return resolve((0, _config.checkConfigDir)()); }).then(configExists => { if (!configExists) { return confirm("Config directory does not exists, you can to create it?"); } else { return false; } }).then(doesCreateConfigDir => { if (doesCreateConfigDir) { return (0, _config.createConfigDir)(); } else { return false; } }).then(() => { return (0, _config.checkDataDir)(); }).then(dataDirExists => { if (!dataDirExists) { return confirm("Data directory does not exists, you can to create it?"); } else { return false; } }).then(doesCreateDataDir => { if (doesCreateDataDir) { return (0, _config.createDataDir)(); } else { return false; } }).then(() => { if (!(0, _config.checkConfigDir)() || !(0, _config.checkDataDir)()) { throw new CancelSignal(); } }); }; const showMenu = function () { return _inquirer.default.prompt({ type: "list", name: "menu", message: "What do you want?", choices: options.map(o => o.text) }).then(res => { return options.find(o => o.text === res.menu).key; }); }; const configGlobals = function () { return _inquirer.default.prompt(generateConfigQuestions()).then(gconfig => { for (let i in gconfig) { let v = gconfig[i]; if (v === "") { continue; } _config.config.set(i, gconfig[i]); } debug("RR", _config.config.toJSON()); let configResult = (0, _config.renderConfigFile)(); process.stdout.write(configResult); process.stdout.write(`\n\n`); return confirm("Confirm save?"); }).then(save => { if (save) { return (0, _config.saveConfig)(); } else { throw new CancelSignal(); } }); }; const addNewBridge = function () { let bconfig = (0, _etc.default)(); let questions = generateBridgeConfigQuestions(); return _inquirer.default.prompt(questions).then(gconfig => { for (let i in gconfig) { let v = gconfig[i]; if (v === "") { continue; } bconfig.set(i, v); } debug("RR", bconfig.toJSON()); let configResult = (0, _config.renderConfigFile)(bconfig.toJSON()); process.stdout.write(configResult); process.stdout.write(`\n\n`); return confirm("Confirm save?"); }).then(save => { if (save) { return (0, _config.saveBridgeConfig)(bconfig.toJSON()); } else { throw new CancelSignal(); } }); }; const editBridge = function () { let bridges = _config.config.get("bridges").map(x => x.name); let bconfig = (0, _etc.default)(); let originalName; debug("Edit bridge menu", bridges); if (!bridges.length) { return Promise.reject(new Error('No bridges to edit')); } return _inquirer.default.prompt({ type: "list", name: "bridge", choices: bridges, message: "Select bridge to edit" }).then(res => { debug("select", res); let bridgeConfig = (0, _config.getBridgeConfig)(res.bridge); originalName = res.bridge; bconfig.add(bridgeConfig); let defaultsOptions = { "name": bconfig.get("name"), "enable": bconfig.get("enable"), "telegram:token": bconfig.get("telegram:token"), "telegram:channel": bconfig.get("telegram:channel"), "irc:server": bconfig.get("irc:server"), "irc:port": bconfig.get("irc:port"), "irc:nick": bconfig.get("irc:nick"), "irc:channel": bconfig.get("irc:channel"), "irc:secure": bconfig.get("irc:secure") === false ? false : bconfig.get("irc:secure"), "oneConnectionByUser": bconfig.get("oneConnectionByUser"), "useIrcColors": bconfig.get("useIrcColors"), "ircScapeCharacter": bconfig.get("ircScapeCharacter"), "showJoinLeft": bconfig.get("showJoinLeft"), "prefix": bconfig.get("prefix"), "suffix": bconfig.get("suffix") }; return _inquirer.default.prompt(generateBridgeConfigQuestions(defaultsOptions)); }).then(gconfig => { for (let i in gconfig) { let v = gconfig[i]; if (v === "") { continue; } bconfig.set(i, v); } debug("RR", bconfig.toJSON()); let configResult = (0, _config.renderConfigFile)(bconfig.toJSON()); process.stdout.write(configResult); process.stdout.write(`\n\n`); return confirm("Confirm save?"); }).then(save => { if (save) { (0, _config.deleteBridgeConfig)(originalName); return (0, _config.saveBridgeConfig)(bconfig.toJSON()); } else { throw new CancelSignal(); } }); }; const deleteBridges = function () { let bridges = _config.config.get("bridges").map(x => x.name); debug("Delete bridges menu"); if (!bridges.length) { debug("No bridges to delete"); return Promise.reject(new Error('No bridges to delete')); } return _inquirer.default.prompt({ type: "checkbox", name: "bridges", choices: bridges, message: "Select bridges to delete", validate(val) { return !!val.length; } }).then(res => { return _inquirer.default.prompt({ type: "confirm", name: "deleteall", default: false, message: "You are going to delete the next bridges " + "configurations: " + res.bridges.join(", ") + ". Are you sure?" }).then(cres => { if (cres.deleteall) { res.bridges.map(b => (0, _config.deleteBridgeConfig)(b)); } else { throw new CancelSignal(); } }); }); }; function _default() { return initConfig().then(() => { return showMenu(); }).then(res => { switch (res) { case "globals": return configGlobals(); case "createb": return addNewBridge(); case "editb": return editBridge(); case "deleteb": return deleteBridges(); case "exit": return; } }).catch(CancelSignal, () => { process.exit(0); }).catch(err => { process.stderr.write(`${err.message}\n`); process.exit(1); }); }