ircgrampp
Version:
IRCGram++ is a complexly simple Telegram <-> IRC Gateway
468 lines (404 loc) • 12.1 kB
JavaScript
;
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);
});
}