@lordbex/thelounge 4.4.3-blowfish
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.thelounge_home +1 -0
- package/LICENSE +22 -0
- package/README.md +95 -0
- package/client/index.html.tpl +69 -0
- package/dist/defaults/config.js +465 -0
- package/dist/package.json +174 -0
- package/dist/server/client.js +678 -0
- package/dist/server/clientManager.js +220 -0
- package/dist/server/command-line/index.js +85 -0
- package/dist/server/command-line/install.js +123 -0
- package/dist/server/command-line/outdated.js +30 -0
- package/dist/server/command-line/start.js +34 -0
- package/dist/server/command-line/storage.js +103 -0
- package/dist/server/command-line/uninstall.js +40 -0
- package/dist/server/command-line/upgrade.js +64 -0
- package/dist/server/command-line/users/add.js +67 -0
- package/dist/server/command-line/users/edit.js +39 -0
- package/dist/server/command-line/users/index.js +17 -0
- package/dist/server/command-line/users/list.js +53 -0
- package/dist/server/command-line/users/remove.js +37 -0
- package/dist/server/command-line/users/reset.js +64 -0
- package/dist/server/command-line/utils.js +177 -0
- package/dist/server/config.js +138 -0
- package/dist/server/helper.js +161 -0
- package/dist/server/identification.js +139 -0
- package/dist/server/index.js +3 -0
- package/dist/server/log.js +35 -0
- package/dist/server/models/chan.js +275 -0
- package/dist/server/models/msg.js +92 -0
- package/dist/server/models/network.js +546 -0
- package/dist/server/models/prefix.js +31 -0
- package/dist/server/models/user.js +42 -0
- package/dist/server/plugins/auth/ldap.js +188 -0
- package/dist/server/plugins/auth/local.js +41 -0
- package/dist/server/plugins/auth.js +70 -0
- package/dist/server/plugins/changelog.js +103 -0
- package/dist/server/plugins/clientCertificate.js +115 -0
- package/dist/server/plugins/dev-server.js +33 -0
- package/dist/server/plugins/inputs/action.js +54 -0
- package/dist/server/plugins/inputs/away.js +20 -0
- package/dist/server/plugins/inputs/ban.js +45 -0
- package/dist/server/plugins/inputs/blow.js +44 -0
- package/dist/server/plugins/inputs/connect.js +41 -0
- package/dist/server/plugins/inputs/ctcp.js +29 -0
- package/dist/server/plugins/inputs/disconnect.js +15 -0
- package/dist/server/plugins/inputs/ignore.js +74 -0
- package/dist/server/plugins/inputs/ignorelist.js +50 -0
- package/dist/server/plugins/inputs/index.js +105 -0
- package/dist/server/plugins/inputs/invite.js +31 -0
- package/dist/server/plugins/inputs/kick.js +26 -0
- package/dist/server/plugins/inputs/kill.js +13 -0
- package/dist/server/plugins/inputs/list.js +12 -0
- package/dist/server/plugins/inputs/mode.js +55 -0
- package/dist/server/plugins/inputs/msg.js +106 -0
- package/dist/server/plugins/inputs/mute.js +56 -0
- package/dist/server/plugins/inputs/nick.js +55 -0
- package/dist/server/plugins/inputs/notice.js +42 -0
- package/dist/server/plugins/inputs/part.js +46 -0
- package/dist/server/plugins/inputs/quit.js +27 -0
- package/dist/server/plugins/inputs/raw.js +13 -0
- package/dist/server/plugins/inputs/rejoin.js +25 -0
- package/dist/server/plugins/inputs/topic.js +24 -0
- package/dist/server/plugins/inputs/whois.js +19 -0
- package/dist/server/plugins/irc-events/away.js +59 -0
- package/dist/server/plugins/irc-events/cap.js +62 -0
- package/dist/server/plugins/irc-events/chghost.js +29 -0
- package/dist/server/plugins/irc-events/connection.js +152 -0
- package/dist/server/plugins/irc-events/ctcp.js +72 -0
- package/dist/server/plugins/irc-events/error.js +80 -0
- package/dist/server/plugins/irc-events/help.js +21 -0
- package/dist/server/plugins/irc-events/info.js +21 -0
- package/dist/server/plugins/irc-events/invite.js +27 -0
- package/dist/server/plugins/irc-events/join.js +53 -0
- package/dist/server/plugins/irc-events/kick.js +39 -0
- package/dist/server/plugins/irc-events/link.js +442 -0
- package/dist/server/plugins/irc-events/list.js +47 -0
- package/dist/server/plugins/irc-events/message.js +187 -0
- package/dist/server/plugins/irc-events/mode.js +124 -0
- package/dist/server/plugins/irc-events/modelist.js +67 -0
- package/dist/server/plugins/irc-events/motd.js +29 -0
- package/dist/server/plugins/irc-events/names.js +21 -0
- package/dist/server/plugins/irc-events/nick.js +45 -0
- package/dist/server/plugins/irc-events/part.js +35 -0
- package/dist/server/plugins/irc-events/quit.js +32 -0
- package/dist/server/plugins/irc-events/sasl.js +26 -0
- package/dist/server/plugins/irc-events/topic.js +42 -0
- package/dist/server/plugins/irc-events/unhandled.js +31 -0
- package/dist/server/plugins/irc-events/welcome.js +22 -0
- package/dist/server/plugins/irc-events/whois.js +57 -0
- package/dist/server/plugins/messageStorage/sqlite.js +454 -0
- package/dist/server/plugins/messageStorage/text.js +124 -0
- package/dist/server/plugins/packages/index.js +200 -0
- package/dist/server/plugins/packages/publicClient.js +66 -0
- package/dist/server/plugins/packages/themes.js +61 -0
- package/dist/server/plugins/storage.js +88 -0
- package/dist/server/plugins/sts.js +85 -0
- package/dist/server/plugins/uploader.js +267 -0
- package/dist/server/plugins/webpush.js +99 -0
- package/dist/server/server.js +857 -0
- package/dist/server/storageCleaner.js +131 -0
- package/dist/server/utils/fish.js +432 -0
- package/dist/shared/irc.js +19 -0
- package/dist/shared/linkify.js +81 -0
- package/dist/shared/types/chan.js +22 -0
- package/dist/shared/types/changelog.js +2 -0
- package/dist/shared/types/config.js +2 -0
- package/dist/shared/types/mention.js +2 -0
- package/dist/shared/types/msg.js +34 -0
- package/dist/shared/types/network.js +2 -0
- package/dist/shared/types/storage.js +2 -0
- package/dist/shared/types/user.js +2 -0
- package/dist/webpack.config.js +224 -0
- package/index.js +38 -0
- package/package.json +174 -0
- package/public/audio/pop.wav +0 -0
- package/public/css/style.css +12 -0
- package/public/css/style.css.map +1 -0
- package/public/favicon.ico +0 -0
- package/public/fonts/fa-solid-900.woff +0 -0
- package/public/fonts/fa-solid-900.woff2 +0 -0
- package/public/img/favicon-alerted.ico +0 -0
- package/public/img/icon-alerted-black-transparent-bg-72x72px.png +0 -0
- package/public/img/icon-alerted-grey-bg-192x192px.png +0 -0
- package/public/img/icon-black-transparent-bg.svg +1 -0
- package/public/img/logo-grey-bg-120x120px.png +0 -0
- package/public/img/logo-grey-bg-152x152px.png +0 -0
- package/public/img/logo-grey-bg-167x167px.png +0 -0
- package/public/img/logo-grey-bg-180x180px.png +0 -0
- package/public/img/logo-grey-bg-192x192px.png +0 -0
- package/public/img/logo-grey-bg-512x512px.png +0 -0
- package/public/img/logo-grey-bg.svg +1 -0
- package/public/img/logo-horizontal-transparent-bg-inverted.svg +1 -0
- package/public/img/logo-horizontal-transparent-bg.svg +1 -0
- package/public/img/logo-transparent-bg-inverted.svg +1 -0
- package/public/img/logo-transparent-bg.svg +1 -0
- package/public/img/logo-vertical-transparent-bg-inverted.svg +1 -0
- package/public/img/logo-vertical-transparent-bg.svg +1 -0
- package/public/js/bundle.js +2 -0
- package/public/js/bundle.js.map +1 -0
- package/public/js/bundle.vendor.js +3 -0
- package/public/js/bundle.vendor.js.LICENSE.txt +18 -0
- package/public/js/bundle.vendor.js.map +1 -0
- package/public/js/loading-error-handlers.js +1 -0
- package/public/robots.txt +2 -0
- package/public/service-worker.js +1 -0
- package/public/thelounge.webmanifest +53 -0
- package/public/themes/default.css +35 -0
- package/public/themes/morning.css +183 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
7
|
+
const log_1 = __importDefault(require("../log"));
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const commander_1 = require("commander");
|
|
10
|
+
const config_1 = __importDefault(require("../config"));
|
|
11
|
+
const utils_1 = __importDefault(require("./utils"));
|
|
12
|
+
const program = new commander_1.Command("upgrade");
|
|
13
|
+
program
|
|
14
|
+
.arguments("[packages...]")
|
|
15
|
+
.description("Upgrade installed themes and packages to their latest versions")
|
|
16
|
+
.on("--help", utils_1.default.extraHelp)
|
|
17
|
+
.action(function (packages) {
|
|
18
|
+
const fs = require("fs");
|
|
19
|
+
const path = require("path");
|
|
20
|
+
// Get paths to the location of packages directory
|
|
21
|
+
const packagesConfig = path.join(config_1.default.getPackagesPath(), "package.json");
|
|
22
|
+
const packagesList = JSON.parse(fs.readFileSync(packagesConfig, "utf-8")).dependencies;
|
|
23
|
+
const argsList = ["upgrade", "--latest"];
|
|
24
|
+
let count = 0;
|
|
25
|
+
if (!Object.entries(packagesList).length) {
|
|
26
|
+
log_1.default.warn("There are no packages installed.");
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
// If a package names are supplied, check they exist
|
|
30
|
+
if (packages.length) {
|
|
31
|
+
log_1.default.info("Upgrading the following packages:");
|
|
32
|
+
packages.forEach((p) => {
|
|
33
|
+
log_1.default.info(`- ${chalk_1.default.green(p)}`);
|
|
34
|
+
if (Object.prototype.hasOwnProperty.call(packagesList, p)) {
|
|
35
|
+
argsList.push(p);
|
|
36
|
+
count++;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
log_1.default.error(`${chalk_1.default.green(p)} is not installed.`);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
log_1.default.info("Upgrading all packages...");
|
|
45
|
+
}
|
|
46
|
+
if (count === 0 && packages.length) {
|
|
47
|
+
log_1.default.warn("There are not any packages to upgrade.");
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const command = argsList.shift();
|
|
51
|
+
const params = argsList;
|
|
52
|
+
if (!command) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
return utils_1.default.executeYarnCommand(command, ...params)
|
|
56
|
+
.then(() => {
|
|
57
|
+
log_1.default.info("Package(s) have been successfully upgraded.");
|
|
58
|
+
})
|
|
59
|
+
.catch((code) => {
|
|
60
|
+
log_1.default.error(`Failed to upgrade package(s). Exit code ${String(code)}`);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
exports.default = program;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const log_1 = __importDefault(require("../../log"));
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const commander_1 = require("commander");
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const helper_1 = __importDefault(require("../../helper"));
|
|
11
|
+
const config_1 = __importDefault(require("../../config"));
|
|
12
|
+
const utils_1 = __importDefault(require("../utils"));
|
|
13
|
+
const program = new commander_1.Command("add");
|
|
14
|
+
program
|
|
15
|
+
.description("Add a new user")
|
|
16
|
+
.on("--help", utils_1.default.extraHelp)
|
|
17
|
+
.option("--password [password]", "new password, will be prompted if not specified")
|
|
18
|
+
.option("--save-logs", "if password is specified, this enables saving logs to disk")
|
|
19
|
+
.argument("<name>", "name of the user")
|
|
20
|
+
.action(function (name, cmdObj) {
|
|
21
|
+
if (!fs_1.default.existsSync(config_1.default.getUsersPath())) {
|
|
22
|
+
log_1.default.error(`${config_1.default.getUsersPath()} does not exist.`);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
26
|
+
const ClientManager = require("../../clientManager").default;
|
|
27
|
+
const manager = new ClientManager();
|
|
28
|
+
const users = manager.getUsers();
|
|
29
|
+
if (users === undefined) {
|
|
30
|
+
// There was an error, already logged
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (users.includes(name)) {
|
|
34
|
+
log_1.default.error(`User ${chalk_1.default.bold(name)} already exists.`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (cmdObj.password) {
|
|
38
|
+
add(manager, name, cmdObj.password, !!cmdObj.saveLogs);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
log_1.default.prompt({
|
|
42
|
+
text: "Enter password:",
|
|
43
|
+
silent: true,
|
|
44
|
+
}, function (err, password) {
|
|
45
|
+
if (!password) {
|
|
46
|
+
log_1.default.error("Password cannot be empty.");
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (!err) {
|
|
50
|
+
log_1.default.prompt({
|
|
51
|
+
text: "Save logs to disk?",
|
|
52
|
+
default: "yes",
|
|
53
|
+
}, function (err2, enableLog) {
|
|
54
|
+
if (!err2) {
|
|
55
|
+
add(manager, name, password, enableLog.charAt(0).toLowerCase() === "y");
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
function add(manager, name, password, enableLog) {
|
|
62
|
+
const hash = helper_1.default.password.hash(password);
|
|
63
|
+
manager.addUser(name, hash, enableLog);
|
|
64
|
+
log_1.default.info(`User ${chalk_1.default.bold(name)} created.`);
|
|
65
|
+
log_1.default.info(`User file located at ${chalk_1.default.green(config_1.default.getUserConfigPath(name))}.`);
|
|
66
|
+
}
|
|
67
|
+
exports.default = program;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const log_1 = __importDefault(require("../../log"));
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const child_process_1 = __importDefault(require("child_process"));
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const fs_1 = __importDefault(require("fs"));
|
|
11
|
+
const config_1 = __importDefault(require("../../config"));
|
|
12
|
+
const utils_1 = __importDefault(require("../utils"));
|
|
13
|
+
const program = new commander_1.Command("edit");
|
|
14
|
+
program
|
|
15
|
+
.description(`Edit user file located at ${chalk_1.default.green(config_1.default.getUserConfigPath("<name>"))}`)
|
|
16
|
+
.argument("<name>", "name of the user")
|
|
17
|
+
.on("--help", utils_1.default.extraHelp)
|
|
18
|
+
.action(function (name) {
|
|
19
|
+
if (!fs_1.default.existsSync(config_1.default.getUsersPath())) {
|
|
20
|
+
log_1.default.error(`${config_1.default.getUsersPath()} does not exist.`);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
24
|
+
const ClientManager = require("../../clientManager").default;
|
|
25
|
+
const users = new ClientManager().getUsers();
|
|
26
|
+
if (users === undefined) {
|
|
27
|
+
// There was an error, already logged
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (!users.includes(name)) {
|
|
31
|
+
log_1.default.error(`User ${chalk_1.default.bold(name)} does not exist.`);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const child_spawn = child_process_1.default.spawn(process.env.EDITOR || "vi", [config_1.default.getUserConfigPath(name)], { stdio: "inherit" });
|
|
35
|
+
child_spawn.on("error", function () {
|
|
36
|
+
log_1.default.error(`Unable to open ${chalk_1.default.green(config_1.default.getUserConfigPath(name))}. ${chalk_1.default.bold("$EDITOR")} is not set, and ${chalk_1.default.bold("vi")} was not found.`);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
exports.default = program;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const config_1 = __importDefault(require("../../config"));
|
|
7
|
+
let add, reset;
|
|
8
|
+
if (!config_1.default.values.ldap.enable) {
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
10
|
+
add = require("./add").default;
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
12
|
+
reset = require("./reset").default;
|
|
13
|
+
}
|
|
14
|
+
const list_1 = __importDefault(require("./list"));
|
|
15
|
+
const remove_1 = __importDefault(require("./remove"));
|
|
16
|
+
const edit_1 = __importDefault(require("./edit"));
|
|
17
|
+
exports.default = [list_1.default, remove_1.default, edit_1.default, add, reset];
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
const log_1 = __importDefault(require("../../log"));
|
|
30
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
31
|
+
const commander_1 = require("commander");
|
|
32
|
+
const utils_1 = __importDefault(require("../utils"));
|
|
33
|
+
const program = new commander_1.Command("list");
|
|
34
|
+
program
|
|
35
|
+
.description("List all users")
|
|
36
|
+
.on("--help", utils_1.default.extraHelp)
|
|
37
|
+
.action(async function () {
|
|
38
|
+
const ClientManager = (await Promise.resolve().then(() => __importStar(require("../../clientManager")))).default;
|
|
39
|
+
const users = new ClientManager().getUsers();
|
|
40
|
+
if (users === undefined) {
|
|
41
|
+
// There was an error, already logged
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (users.length === 0) {
|
|
45
|
+
log_1.default.info(`There are currently no users. Create one with ${chalk_1.default.bold("thelounge add <name>")}.`);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
log_1.default.info("Users:");
|
|
49
|
+
users.forEach((user, i) => {
|
|
50
|
+
log_1.default.info(`${i + 1}. ${chalk_1.default.bold(user)}`);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
exports.default = program;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const log_1 = __importDefault(require("../../log"));
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const commander_1 = require("commander");
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const config_1 = __importDefault(require("../../config"));
|
|
11
|
+
const utils_1 = __importDefault(require("../utils"));
|
|
12
|
+
const program = new commander_1.Command("remove");
|
|
13
|
+
program
|
|
14
|
+
.description("Remove an existing user")
|
|
15
|
+
.on("--help", utils_1.default.extraHelp)
|
|
16
|
+
.argument("<name>", "name of the user")
|
|
17
|
+
.action(function (name) {
|
|
18
|
+
if (!fs_1.default.existsSync(config_1.default.getUsersPath())) {
|
|
19
|
+
log_1.default.error(`${config_1.default.getUsersPath()} does not exist.`);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
23
|
+
const ClientManager = require("../../clientManager").default;
|
|
24
|
+
const manager = new ClientManager();
|
|
25
|
+
try {
|
|
26
|
+
if (manager.removeUser(name)) {
|
|
27
|
+
log_1.default.info(`User ${chalk_1.default.bold(name)} removed.`);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
log_1.default.error(`User ${chalk_1.default.bold(name)} does not exist.`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
// There was an error, already logged
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
exports.default = program;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const log_1 = __importDefault(require("../../log"));
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const commander_1 = require("commander");
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const helper_1 = __importDefault(require("../../helper"));
|
|
11
|
+
const config_1 = __importDefault(require("../../config"));
|
|
12
|
+
const utils_1 = __importDefault(require("../utils"));
|
|
13
|
+
const program = new commander_1.Command("reset");
|
|
14
|
+
program
|
|
15
|
+
.description("Reset user password")
|
|
16
|
+
.on("--help", utils_1.default.extraHelp)
|
|
17
|
+
.argument("<name>", "name of the user")
|
|
18
|
+
.option("--password [password]", "new password, will be prompted if not specified")
|
|
19
|
+
.action(function (name, cmdObj) {
|
|
20
|
+
if (!fs_1.default.existsSync(config_1.default.getUsersPath())) {
|
|
21
|
+
log_1.default.error(`${config_1.default.getUsersPath()} does not exist.`);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
25
|
+
const ClientManager = require("../../clientManager").default;
|
|
26
|
+
const users = new ClientManager().getUsers();
|
|
27
|
+
if (users === undefined) {
|
|
28
|
+
// There was an error, already logged
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (!users.includes(name)) {
|
|
32
|
+
log_1.default.error(`User ${chalk_1.default.bold(name)} does not exist.`);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (cmdObj.password) {
|
|
36
|
+
change(name, cmdObj.password);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
log_1.default.prompt({
|
|
40
|
+
text: "Enter new password:",
|
|
41
|
+
silent: true,
|
|
42
|
+
}, function (err, password) {
|
|
43
|
+
if (err) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
change(name, password);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
function change(name, password) {
|
|
50
|
+
const pathReal = config_1.default.getUserConfigPath(name);
|
|
51
|
+
const pathTemp = pathReal + ".tmp";
|
|
52
|
+
const user = JSON.parse(fs_1.default.readFileSync(pathReal, "utf-8"));
|
|
53
|
+
user.password = helper_1.default.password.hash(password);
|
|
54
|
+
user.sessions = {};
|
|
55
|
+
const newUser = JSON.stringify(user, null, "\t");
|
|
56
|
+
// Write to a temp file first, in case the write fails
|
|
57
|
+
// we do not lose the original file (for example when disk is full)
|
|
58
|
+
fs_1.default.writeFileSync(pathTemp, newUser, {
|
|
59
|
+
mode: 0o600,
|
|
60
|
+
});
|
|
61
|
+
fs_1.default.renameSync(pathTemp, pathReal);
|
|
62
|
+
log_1.default.info(`Successfully reset password for ${chalk_1.default.bold(name)}.`);
|
|
63
|
+
}
|
|
64
|
+
exports.default = program;
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
7
|
+
const log_1 = __importDefault(require("../log"));
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const helper_1 = __importDefault(require("../helper"));
|
|
11
|
+
const config_1 = __importDefault(require("../config"));
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const child_process_1 = require("child_process");
|
|
14
|
+
let home;
|
|
15
|
+
class Utils {
|
|
16
|
+
static extraHelp() {
|
|
17
|
+
[
|
|
18
|
+
"",
|
|
19
|
+
"Environment variable:",
|
|
20
|
+
` THELOUNGE_HOME Path for all configuration files and folders. Defaults to ${chalk_1.default.green(helper_1.default.expandHome(Utils.defaultHome()))}`,
|
|
21
|
+
"",
|
|
22
|
+
].forEach((e) => log_1.default.raw(e));
|
|
23
|
+
}
|
|
24
|
+
static defaultHome() {
|
|
25
|
+
if (home) {
|
|
26
|
+
return home;
|
|
27
|
+
}
|
|
28
|
+
const distConfig = Utils.getFileFromRelativeToRoot(".thelounge_home");
|
|
29
|
+
home = fs_1.default.readFileSync(distConfig, "utf-8").trim();
|
|
30
|
+
return home;
|
|
31
|
+
}
|
|
32
|
+
static getFileFromRelativeToRoot(...fileName) {
|
|
33
|
+
// e.g. /thelounge/server/command-line/utils.ts
|
|
34
|
+
if (process.env.NODE_ENV === "test" || process.env.NODE_ENV === "development") {
|
|
35
|
+
return path_1.default.resolve(path_1.default.join(__dirname, "..", "..", ...fileName));
|
|
36
|
+
}
|
|
37
|
+
// e.g. /thelounge/dist/server/command-line/utils.ts
|
|
38
|
+
return path_1.default.resolve(path_1.default.join(__dirname, "..", "..", "..", ...fileName));
|
|
39
|
+
}
|
|
40
|
+
// Parses CLI options such as `-c public=true`, `-c debug.raw=true`, etc.
|
|
41
|
+
static parseConfigOptions(val, memo) {
|
|
42
|
+
// Invalid option that is not of format `key=value`, do nothing
|
|
43
|
+
if (!val.includes("=")) {
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
45
|
+
return memo;
|
|
46
|
+
}
|
|
47
|
+
const parseValue = (value) => {
|
|
48
|
+
switch (value) {
|
|
49
|
+
case "true":
|
|
50
|
+
return true;
|
|
51
|
+
case "false":
|
|
52
|
+
return false;
|
|
53
|
+
case "undefined":
|
|
54
|
+
return undefined;
|
|
55
|
+
case "null":
|
|
56
|
+
return null;
|
|
57
|
+
default:
|
|
58
|
+
if (/^-?[0-9]+$/.test(value)) {
|
|
59
|
+
// Numbers like port
|
|
60
|
+
return parseInt(value, 10);
|
|
61
|
+
}
|
|
62
|
+
else if (/^\[.*\]$/.test(value)) {
|
|
63
|
+
// Arrays
|
|
64
|
+
// Supporting arrays `[a,b]` and `[a, b]`
|
|
65
|
+
const array = value.slice(1, -1).split(/,\s*/);
|
|
66
|
+
// If [] is given, it will be parsed as `[ "" ]`, so treat this as empty
|
|
67
|
+
if (array.length === 1 && array[0] === "") {
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
return array.map(parseValue); // Re-parses all values of the array
|
|
71
|
+
}
|
|
72
|
+
return value;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
// First time the option is parsed, memo is not set
|
|
76
|
+
if (memo === undefined) {
|
|
77
|
+
memo = {};
|
|
78
|
+
}
|
|
79
|
+
// Note: If passed `-c foo="bar=42"` (with single or double quotes), `val`
|
|
80
|
+
// will always be passed as `foo=bar=42`, never with quotes.
|
|
81
|
+
const position = val.indexOf("="); // Only split on the first = found
|
|
82
|
+
const key = val.slice(0, position);
|
|
83
|
+
const value = val.slice(position + 1);
|
|
84
|
+
const parsedValue = parseValue(value);
|
|
85
|
+
if (lodash_1.default.has(memo, key)) {
|
|
86
|
+
log_1.default.warn(`Configuration key ${chalk_1.default.bold(key)} was already specified, ignoring...`);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
memo = lodash_1.default.set(memo, key, parsedValue);
|
|
90
|
+
}
|
|
91
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
92
|
+
return memo;
|
|
93
|
+
}
|
|
94
|
+
static executeYarnCommand(command, ...parameters) {
|
|
95
|
+
const yarn = require.resolve("yarn/bin/yarn.js");
|
|
96
|
+
const packagesPath = config_1.default.getPackagesPath();
|
|
97
|
+
const cachePath = path_1.default.join(packagesPath, "package_manager_cache");
|
|
98
|
+
const staticParameters = [
|
|
99
|
+
"--cache-folder",
|
|
100
|
+
cachePath,
|
|
101
|
+
"--cwd",
|
|
102
|
+
packagesPath,
|
|
103
|
+
"--json",
|
|
104
|
+
"--ignore-scripts",
|
|
105
|
+
"--non-interactive",
|
|
106
|
+
];
|
|
107
|
+
const env = {
|
|
108
|
+
// We only ever operate in production mode
|
|
109
|
+
NODE_ENV: "production",
|
|
110
|
+
// If The Lounge runs from a user that does not have a home directory,
|
|
111
|
+
// yarn may fail when it tries to read certain folders,
|
|
112
|
+
// we give it an existing folder so the reads do not throw a permission error.
|
|
113
|
+
// Yarn uses os.homedir() to figure out the path, which internally reads
|
|
114
|
+
// from the $HOME env on unix. On Windows it uses $USERPROFILE, but
|
|
115
|
+
// the user folder should always exist on Windows, so we don't set it.
|
|
116
|
+
HOME: cachePath,
|
|
117
|
+
};
|
|
118
|
+
return new Promise((resolve, reject) => {
|
|
119
|
+
let success = false;
|
|
120
|
+
const add = (0, child_process_1.spawn)(process.execPath, [yarn, command, ...staticParameters, ...parameters], { env: env });
|
|
121
|
+
add.stdout.on("data", (data) => {
|
|
122
|
+
data.toString()
|
|
123
|
+
.trim()
|
|
124
|
+
.split("\n")
|
|
125
|
+
.forEach((line) => {
|
|
126
|
+
try {
|
|
127
|
+
const json = JSON.parse(line);
|
|
128
|
+
if (json.type === "success") {
|
|
129
|
+
success = true;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch (e) {
|
|
133
|
+
// Stdout buffer has limitations and yarn may print
|
|
134
|
+
// big package trees, for example in the upgrade command
|
|
135
|
+
// See https://github.com/thelounge/thelounge/issues/3679
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
add.stderr.on("data", (data) => {
|
|
140
|
+
data.toString()
|
|
141
|
+
.trim()
|
|
142
|
+
.split("\n")
|
|
143
|
+
.forEach((line) => {
|
|
144
|
+
try {
|
|
145
|
+
const json = JSON.parse(line);
|
|
146
|
+
switch (json.type) {
|
|
147
|
+
case "error":
|
|
148
|
+
log_1.default.error(json.data);
|
|
149
|
+
break;
|
|
150
|
+
case "warning":
|
|
151
|
+
// this includes pointless things like "ignored scripts due to flag"
|
|
152
|
+
// so let's hide it
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
catch (e) {
|
|
158
|
+
// we simply fall through and log at debug... chances are there's nothing the user can do about it
|
|
159
|
+
// as it includes things like deprecation warnings, but we might want to know as developers
|
|
160
|
+
}
|
|
161
|
+
log_1.default.debug(line);
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
add.on("error", (e) => {
|
|
165
|
+
log_1.default.error(`${e.message}:`, e.stack || "");
|
|
166
|
+
process.exit(1);
|
|
167
|
+
});
|
|
168
|
+
add.on("close", (code) => {
|
|
169
|
+
if (!success || code !== 0) {
|
|
170
|
+
return reject(code);
|
|
171
|
+
}
|
|
172
|
+
resolve(true);
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
exports.default = Utils;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const os_1 = __importDefault(require("os"));
|
|
10
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
11
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
12
|
+
const log_1 = __importDefault(require("./log"));
|
|
13
|
+
const helper_1 = __importDefault(require("./helper"));
|
|
14
|
+
const utils_1 = __importDefault(require("./command-line/utils"));
|
|
15
|
+
class Config {
|
|
16
|
+
values = require(path_1.default.resolve(path_1.default.join(__dirname, "..", "defaults", "config.js")));
|
|
17
|
+
#homePath = "";
|
|
18
|
+
getHomePath() {
|
|
19
|
+
return this.#homePath;
|
|
20
|
+
}
|
|
21
|
+
getConfigPath() {
|
|
22
|
+
return path_1.default.join(this.#homePath, "config.js");
|
|
23
|
+
}
|
|
24
|
+
getUserLogsPath() {
|
|
25
|
+
return path_1.default.join(this.#homePath, "logs");
|
|
26
|
+
}
|
|
27
|
+
getStoragePath() {
|
|
28
|
+
return path_1.default.join(this.#homePath, "storage");
|
|
29
|
+
}
|
|
30
|
+
getFileUploadPath() {
|
|
31
|
+
return path_1.default.join(this.#homePath, "uploads");
|
|
32
|
+
}
|
|
33
|
+
getUsersPath() {
|
|
34
|
+
return path_1.default.join(this.#homePath, "users");
|
|
35
|
+
}
|
|
36
|
+
getUserConfigPath(name) {
|
|
37
|
+
return path_1.default.join(this.getUsersPath(), `${name}.json`);
|
|
38
|
+
}
|
|
39
|
+
getClientCertificatesPath() {
|
|
40
|
+
return path_1.default.join(this.#homePath, "certificates");
|
|
41
|
+
}
|
|
42
|
+
getPackagesPath() {
|
|
43
|
+
return path_1.default.join(this.#homePath, "packages");
|
|
44
|
+
}
|
|
45
|
+
getPackageModulePath(packageName) {
|
|
46
|
+
return path_1.default.join(this.getPackagesPath(), "node_modules", packageName);
|
|
47
|
+
}
|
|
48
|
+
getDefaultNick() {
|
|
49
|
+
if (!this.values.defaults.nick) {
|
|
50
|
+
return "thelounge";
|
|
51
|
+
}
|
|
52
|
+
return this.values.defaults.nick.replace(/%/g, () => Math.floor(Math.random() * 10).toString());
|
|
53
|
+
}
|
|
54
|
+
merge(newConfig) {
|
|
55
|
+
this._merge_config_objects(this.values, newConfig);
|
|
56
|
+
}
|
|
57
|
+
_merge_config_objects(oldConfig, newConfig) {
|
|
58
|
+
// semi exposed function so that we can test it
|
|
59
|
+
// it mutates the oldConfig, but returns it as a convenience for testing
|
|
60
|
+
for (const key in newConfig) {
|
|
61
|
+
if (!Object.prototype.hasOwnProperty.call(oldConfig, key)) {
|
|
62
|
+
log_1.default.warn(`Unknown key "${chalk_1.default.bold(key)}", please verify your config.`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return lodash_1.default.mergeWith(oldConfig, newConfig, (objValue, srcValue, key) => {
|
|
66
|
+
// Do not override config variables if the type is incorrect (e.g. object changed into a string)
|
|
67
|
+
if (typeof objValue !== "undefined" &&
|
|
68
|
+
objValue !== null &&
|
|
69
|
+
typeof objValue !== typeof srcValue) {
|
|
70
|
+
log_1.default.warn(`Incorrect type for "${chalk_1.default.bold(key)}", please verify your config.`);
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
72
|
+
return objValue;
|
|
73
|
+
}
|
|
74
|
+
// For arrays, simply override the value with user provided one.
|
|
75
|
+
if (lodash_1.default.isArray(objValue)) {
|
|
76
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
77
|
+
return srcValue;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
setHome(newPath) {
|
|
82
|
+
this.#homePath = helper_1.default.expandHome(newPath);
|
|
83
|
+
// Reload config from new home location
|
|
84
|
+
const configPath = this.getConfigPath();
|
|
85
|
+
if (fs_1.default.existsSync(configPath)) {
|
|
86
|
+
const userConfig = require(configPath);
|
|
87
|
+
if (lodash_1.default.isEmpty(userConfig)) {
|
|
88
|
+
log_1.default.warn(`The file located at ${chalk_1.default.green(configPath)} does not appear to expose anything.`);
|
|
89
|
+
log_1.default.warn(`Make sure it is non-empty and the configuration is exported using ${chalk_1.default.bold("module.exports = { ... }")}.`);
|
|
90
|
+
log_1.default.warn("Using default configuration...");
|
|
91
|
+
}
|
|
92
|
+
this.merge(userConfig);
|
|
93
|
+
}
|
|
94
|
+
if (this.values.fileUpload.baseUrl) {
|
|
95
|
+
try {
|
|
96
|
+
new URL("test/file.png", this.values.fileUpload.baseUrl);
|
|
97
|
+
}
|
|
98
|
+
catch (e) {
|
|
99
|
+
this.values.fileUpload.baseUrl = undefined;
|
|
100
|
+
log_1.default.warn(`The ${chalk_1.default.bold("fileUpload.baseUrl")} you specified is invalid: ${String(e)}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const manifestPath = utils_1.default.getFileFromRelativeToRoot("public", "thelounge.webmanifest");
|
|
104
|
+
// Check if manifest exists, if not, the app most likely was not built
|
|
105
|
+
if (!fs_1.default.existsSync(manifestPath)) {
|
|
106
|
+
log_1.default.error(`The client application was not built. Run ${chalk_1.default.bold("NODE_ENV=production yarn build")} to resolve this.`);
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
// Load theme color from the web manifest
|
|
110
|
+
const manifest = JSON.parse(fs_1.default.readFileSync(manifestPath, "utf8"));
|
|
111
|
+
this.values.themeColor = manifest.theme_color;
|
|
112
|
+
// log dir probably shouldn't be world accessible.
|
|
113
|
+
// Create it with the desired permission bits if it doesn't exist yet.
|
|
114
|
+
let logsStat = undefined;
|
|
115
|
+
const userLogsPath = this.getUserLogsPath();
|
|
116
|
+
try {
|
|
117
|
+
logsStat = fs_1.default.statSync(userLogsPath);
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// ignored on purpose, node v14.17.0 will give us {throwIfNoEntry: false}
|
|
121
|
+
}
|
|
122
|
+
if (!logsStat) {
|
|
123
|
+
try {
|
|
124
|
+
fs_1.default.mkdirSync(userLogsPath, { recursive: true, mode: 0o750 });
|
|
125
|
+
}
|
|
126
|
+
catch (e) {
|
|
127
|
+
log_1.default.error("Unable to create logs directory", e);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
else if (logsStat && logsStat.mode & 0o001) {
|
|
131
|
+
log_1.default.warn(userLogsPath, "is world readable.", "The log files may be exposed. Please fix the permissions.");
|
|
132
|
+
if (os_1.default.platform() !== "win32") {
|
|
133
|
+
log_1.default.warn(`run \`chmod o-x "${userLogsPath}"\` to correct it.`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
exports.default = new Config();
|