@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.
Files changed (148) hide show
  1. package/.thelounge_home +1 -0
  2. package/LICENSE +22 -0
  3. package/README.md +95 -0
  4. package/client/index.html.tpl +69 -0
  5. package/dist/defaults/config.js +465 -0
  6. package/dist/package.json +174 -0
  7. package/dist/server/client.js +678 -0
  8. package/dist/server/clientManager.js +220 -0
  9. package/dist/server/command-line/index.js +85 -0
  10. package/dist/server/command-line/install.js +123 -0
  11. package/dist/server/command-line/outdated.js +30 -0
  12. package/dist/server/command-line/start.js +34 -0
  13. package/dist/server/command-line/storage.js +103 -0
  14. package/dist/server/command-line/uninstall.js +40 -0
  15. package/dist/server/command-line/upgrade.js +64 -0
  16. package/dist/server/command-line/users/add.js +67 -0
  17. package/dist/server/command-line/users/edit.js +39 -0
  18. package/dist/server/command-line/users/index.js +17 -0
  19. package/dist/server/command-line/users/list.js +53 -0
  20. package/dist/server/command-line/users/remove.js +37 -0
  21. package/dist/server/command-line/users/reset.js +64 -0
  22. package/dist/server/command-line/utils.js +177 -0
  23. package/dist/server/config.js +138 -0
  24. package/dist/server/helper.js +161 -0
  25. package/dist/server/identification.js +139 -0
  26. package/dist/server/index.js +3 -0
  27. package/dist/server/log.js +35 -0
  28. package/dist/server/models/chan.js +275 -0
  29. package/dist/server/models/msg.js +92 -0
  30. package/dist/server/models/network.js +546 -0
  31. package/dist/server/models/prefix.js +31 -0
  32. package/dist/server/models/user.js +42 -0
  33. package/dist/server/plugins/auth/ldap.js +188 -0
  34. package/dist/server/plugins/auth/local.js +41 -0
  35. package/dist/server/plugins/auth.js +70 -0
  36. package/dist/server/plugins/changelog.js +103 -0
  37. package/dist/server/plugins/clientCertificate.js +115 -0
  38. package/dist/server/plugins/dev-server.js +33 -0
  39. package/dist/server/plugins/inputs/action.js +54 -0
  40. package/dist/server/plugins/inputs/away.js +20 -0
  41. package/dist/server/plugins/inputs/ban.js +45 -0
  42. package/dist/server/plugins/inputs/blow.js +44 -0
  43. package/dist/server/plugins/inputs/connect.js +41 -0
  44. package/dist/server/plugins/inputs/ctcp.js +29 -0
  45. package/dist/server/plugins/inputs/disconnect.js +15 -0
  46. package/dist/server/plugins/inputs/ignore.js +74 -0
  47. package/dist/server/plugins/inputs/ignorelist.js +50 -0
  48. package/dist/server/plugins/inputs/index.js +105 -0
  49. package/dist/server/plugins/inputs/invite.js +31 -0
  50. package/dist/server/plugins/inputs/kick.js +26 -0
  51. package/dist/server/plugins/inputs/kill.js +13 -0
  52. package/dist/server/plugins/inputs/list.js +12 -0
  53. package/dist/server/plugins/inputs/mode.js +55 -0
  54. package/dist/server/plugins/inputs/msg.js +106 -0
  55. package/dist/server/plugins/inputs/mute.js +56 -0
  56. package/dist/server/plugins/inputs/nick.js +55 -0
  57. package/dist/server/plugins/inputs/notice.js +42 -0
  58. package/dist/server/plugins/inputs/part.js +46 -0
  59. package/dist/server/plugins/inputs/quit.js +27 -0
  60. package/dist/server/plugins/inputs/raw.js +13 -0
  61. package/dist/server/plugins/inputs/rejoin.js +25 -0
  62. package/dist/server/plugins/inputs/topic.js +24 -0
  63. package/dist/server/plugins/inputs/whois.js +19 -0
  64. package/dist/server/plugins/irc-events/away.js +59 -0
  65. package/dist/server/plugins/irc-events/cap.js +62 -0
  66. package/dist/server/plugins/irc-events/chghost.js +29 -0
  67. package/dist/server/plugins/irc-events/connection.js +152 -0
  68. package/dist/server/plugins/irc-events/ctcp.js +72 -0
  69. package/dist/server/plugins/irc-events/error.js +80 -0
  70. package/dist/server/plugins/irc-events/help.js +21 -0
  71. package/dist/server/plugins/irc-events/info.js +21 -0
  72. package/dist/server/plugins/irc-events/invite.js +27 -0
  73. package/dist/server/plugins/irc-events/join.js +53 -0
  74. package/dist/server/plugins/irc-events/kick.js +39 -0
  75. package/dist/server/plugins/irc-events/link.js +442 -0
  76. package/dist/server/plugins/irc-events/list.js +47 -0
  77. package/dist/server/plugins/irc-events/message.js +187 -0
  78. package/dist/server/plugins/irc-events/mode.js +124 -0
  79. package/dist/server/plugins/irc-events/modelist.js +67 -0
  80. package/dist/server/plugins/irc-events/motd.js +29 -0
  81. package/dist/server/plugins/irc-events/names.js +21 -0
  82. package/dist/server/plugins/irc-events/nick.js +45 -0
  83. package/dist/server/plugins/irc-events/part.js +35 -0
  84. package/dist/server/plugins/irc-events/quit.js +32 -0
  85. package/dist/server/plugins/irc-events/sasl.js +26 -0
  86. package/dist/server/plugins/irc-events/topic.js +42 -0
  87. package/dist/server/plugins/irc-events/unhandled.js +31 -0
  88. package/dist/server/plugins/irc-events/welcome.js +22 -0
  89. package/dist/server/plugins/irc-events/whois.js +57 -0
  90. package/dist/server/plugins/messageStorage/sqlite.js +454 -0
  91. package/dist/server/plugins/messageStorage/text.js +124 -0
  92. package/dist/server/plugins/packages/index.js +200 -0
  93. package/dist/server/plugins/packages/publicClient.js +66 -0
  94. package/dist/server/plugins/packages/themes.js +61 -0
  95. package/dist/server/plugins/storage.js +88 -0
  96. package/dist/server/plugins/sts.js +85 -0
  97. package/dist/server/plugins/uploader.js +267 -0
  98. package/dist/server/plugins/webpush.js +99 -0
  99. package/dist/server/server.js +857 -0
  100. package/dist/server/storageCleaner.js +131 -0
  101. package/dist/server/utils/fish.js +432 -0
  102. package/dist/shared/irc.js +19 -0
  103. package/dist/shared/linkify.js +81 -0
  104. package/dist/shared/types/chan.js +22 -0
  105. package/dist/shared/types/changelog.js +2 -0
  106. package/dist/shared/types/config.js +2 -0
  107. package/dist/shared/types/mention.js +2 -0
  108. package/dist/shared/types/msg.js +34 -0
  109. package/dist/shared/types/network.js +2 -0
  110. package/dist/shared/types/storage.js +2 -0
  111. package/dist/shared/types/user.js +2 -0
  112. package/dist/webpack.config.js +224 -0
  113. package/index.js +38 -0
  114. package/package.json +174 -0
  115. package/public/audio/pop.wav +0 -0
  116. package/public/css/style.css +12 -0
  117. package/public/css/style.css.map +1 -0
  118. package/public/favicon.ico +0 -0
  119. package/public/fonts/fa-solid-900.woff +0 -0
  120. package/public/fonts/fa-solid-900.woff2 +0 -0
  121. package/public/img/favicon-alerted.ico +0 -0
  122. package/public/img/icon-alerted-black-transparent-bg-72x72px.png +0 -0
  123. package/public/img/icon-alerted-grey-bg-192x192px.png +0 -0
  124. package/public/img/icon-black-transparent-bg.svg +1 -0
  125. package/public/img/logo-grey-bg-120x120px.png +0 -0
  126. package/public/img/logo-grey-bg-152x152px.png +0 -0
  127. package/public/img/logo-grey-bg-167x167px.png +0 -0
  128. package/public/img/logo-grey-bg-180x180px.png +0 -0
  129. package/public/img/logo-grey-bg-192x192px.png +0 -0
  130. package/public/img/logo-grey-bg-512x512px.png +0 -0
  131. package/public/img/logo-grey-bg.svg +1 -0
  132. package/public/img/logo-horizontal-transparent-bg-inverted.svg +1 -0
  133. package/public/img/logo-horizontal-transparent-bg.svg +1 -0
  134. package/public/img/logo-transparent-bg-inverted.svg +1 -0
  135. package/public/img/logo-transparent-bg.svg +1 -0
  136. package/public/img/logo-vertical-transparent-bg-inverted.svg +1 -0
  137. package/public/img/logo-vertical-transparent-bg.svg +1 -0
  138. package/public/js/bundle.js +2 -0
  139. package/public/js/bundle.js.map +1 -0
  140. package/public/js/bundle.vendor.js +3 -0
  141. package/public/js/bundle.vendor.js.LICENSE.txt +18 -0
  142. package/public/js/bundle.vendor.js.map +1 -0
  143. package/public/js/loading-error-handlers.js +1 -0
  144. package/public/robots.txt +2 -0
  145. package/public/service-worker.js +1 -0
  146. package/public/thelounge.webmanifest +53 -0
  147. package/public/themes/default.css +35 -0
  148. 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();