@lordbex/thelounge 4.4.3-blowfish → 4.5.0-blowfish-pre

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 (141) hide show
  1. package/README.md +31 -7
  2. package/dist/defaults/config.js +31 -2
  3. package/dist/package.json +94 -91
  4. package/dist/server/client.js +188 -194
  5. package/dist/server/clientManager.js +75 -72
  6. package/dist/server/command-line/index.js +44 -43
  7. package/dist/server/command-line/install.js +37 -70
  8. package/dist/server/command-line/outdated.js +12 -17
  9. package/dist/server/command-line/start.js +25 -26
  10. package/dist/server/command-line/storage.js +26 -31
  11. package/dist/server/command-line/uninstall.js +16 -23
  12. package/dist/server/command-line/upgrade.js +20 -26
  13. package/dist/server/command-line/users/add.js +33 -40
  14. package/dist/server/command-line/users/edit.js +18 -24
  15. package/dist/server/command-line/users/index.js +12 -16
  16. package/dist/server/command-line/users/list.js +11 -39
  17. package/dist/server/command-line/users/remove.js +16 -22
  18. package/dist/server/command-line/users/reset.js +34 -35
  19. package/dist/server/command-line/utils.js +231 -87
  20. package/dist/server/config.js +61 -52
  21. package/dist/server/helper.js +29 -28
  22. package/dist/server/identification.js +39 -34
  23. package/dist/server/index.js +1 -3
  24. package/dist/server/log.js +19 -16
  25. package/dist/server/models/chan.js +36 -33
  26. package/dist/server/models/msg.js +15 -19
  27. package/dist/server/models/network.js +102 -104
  28. package/dist/server/models/prefix.js +4 -7
  29. package/dist/server/models/user.js +5 -10
  30. package/dist/server/path-helper.js +8 -0
  31. package/dist/server/plugins/auth/ldap.js +177 -112
  32. package/dist/server/plugins/auth/local.js +10 -15
  33. package/dist/server/plugins/auth.js +6 -35
  34. package/dist/server/plugins/changelog.js +30 -27
  35. package/dist/server/plugins/clientCertificate.js +33 -37
  36. package/dist/server/plugins/dev-server.js +15 -21
  37. package/dist/server/plugins/inputs/action.js +9 -14
  38. package/dist/server/plugins/inputs/away.js +1 -3
  39. package/dist/server/plugins/inputs/ban.js +9 -14
  40. package/dist/server/plugins/inputs/blow.js +9 -14
  41. package/dist/server/plugins/inputs/connect.js +5 -10
  42. package/dist/server/plugins/inputs/ctcp.js +7 -12
  43. package/dist/server/plugins/inputs/disconnect.js +1 -3
  44. package/dist/server/plugins/inputs/ignore.js +23 -29
  45. package/dist/server/plugins/inputs/ignorelist.js +12 -18
  46. package/dist/server/plugins/inputs/index.js +8 -34
  47. package/dist/server/plugins/inputs/invite.js +7 -12
  48. package/dist/server/plugins/inputs/kick.js +7 -12
  49. package/dist/server/plugins/inputs/kill.js +1 -3
  50. package/dist/server/plugins/inputs/list.js +1 -3
  51. package/dist/server/plugins/inputs/mode.js +10 -15
  52. package/dist/server/plugins/inputs/msg.js +13 -18
  53. package/dist/server/plugins/inputs/mute.js +9 -15
  54. package/dist/server/plugins/inputs/nick.js +9 -14
  55. package/dist/server/plugins/inputs/notice.js +5 -7
  56. package/dist/server/plugins/inputs/part.js +11 -16
  57. package/dist/server/plugins/inputs/quit.js +7 -13
  58. package/dist/server/plugins/inputs/rainbow.js +55 -0
  59. package/dist/server/plugins/inputs/raw.js +1 -3
  60. package/dist/server/plugins/inputs/rejoin.js +7 -12
  61. package/dist/server/plugins/inputs/topic.js +7 -12
  62. package/dist/server/plugins/inputs/whois.js +1 -3
  63. package/dist/server/plugins/irc-events/away.js +14 -20
  64. package/dist/server/plugins/irc-events/cap.js +16 -22
  65. package/dist/server/plugins/irc-events/chghost.js +14 -13
  66. package/dist/server/plugins/irc-events/connection.js +61 -63
  67. package/dist/server/plugins/irc-events/ctcp.js +22 -28
  68. package/dist/server/plugins/irc-events/error.js +20 -26
  69. package/dist/server/plugins/irc-events/help.js +7 -13
  70. package/dist/server/plugins/irc-events/info.js +7 -13
  71. package/dist/server/plugins/irc-events/invite.js +7 -13
  72. package/dist/server/plugins/irc-events/join.js +30 -27
  73. package/dist/server/plugins/irc-events/kick.js +21 -17
  74. package/dist/server/plugins/irc-events/link.js +122 -109
  75. package/dist/server/plugins/irc-events/list.js +23 -26
  76. package/dist/server/plugins/irc-events/message.js +46 -52
  77. package/dist/server/plugins/irc-events/mode.js +66 -63
  78. package/dist/server/plugins/irc-events/modelist.js +29 -35
  79. package/dist/server/plugins/irc-events/motd.js +10 -16
  80. package/dist/server/plugins/irc-events/names.js +3 -6
  81. package/dist/server/plugins/irc-events/nick.js +26 -23
  82. package/dist/server/plugins/irc-events/part.js +19 -15
  83. package/dist/server/plugins/irc-events/quit.js +17 -14
  84. package/dist/server/plugins/irc-events/sasl.js +9 -15
  85. package/dist/server/plugins/irc-events/spgroups.js +38 -0
  86. package/dist/server/plugins/irc-events/spjoin.js +52 -0
  87. package/dist/server/plugins/irc-events/topic.js +12 -18
  88. package/dist/server/plugins/irc-events/unhandled.js +12 -12
  89. package/dist/server/plugins/irc-events/welcome.js +7 -13
  90. package/dist/server/plugins/irc-events/whois.js +20 -24
  91. package/dist/server/plugins/massEventAggregator.js +214 -0
  92. package/dist/server/plugins/messageStorage/sqlite.js +322 -141
  93. package/dist/server/plugins/messageStorage/text.js +21 -26
  94. package/dist/server/plugins/packages/index.js +105 -74
  95. package/dist/server/plugins/packages/publicClient.js +7 -16
  96. package/dist/server/plugins/packages/themes.js +11 -16
  97. package/dist/server/plugins/storage.js +28 -33
  98. package/dist/server/plugins/sts.js +12 -17
  99. package/dist/server/plugins/uploader.js +40 -43
  100. package/dist/server/plugins/webpush.js +23 -51
  101. package/dist/server/server.js +318 -271
  102. package/dist/server/storageCleaner.js +29 -37
  103. package/dist/server/utils/fish.js +349 -389
  104. package/dist/shared/irc.js +3 -6
  105. package/dist/shared/linkify.js +7 -14
  106. package/dist/shared/types/chan.js +6 -9
  107. package/dist/shared/types/changelog.js +1 -2
  108. package/dist/shared/types/config.js +1 -2
  109. package/dist/shared/types/mention.js +1 -2
  110. package/dist/shared/types/msg.js +3 -5
  111. package/dist/shared/types/network.js +1 -2
  112. package/dist/shared/types/storage.js +1 -2
  113. package/dist/shared/types/user.js +1 -2
  114. package/index.js +14 -10
  115. package/package.json +94 -91
  116. package/public/css/style.css +9 -6
  117. package/public/css/style.css.map +1 -1
  118. package/public/fonts/font-awesome/fa-brands-400.ttf +0 -0
  119. package/public/fonts/font-awesome/fa-brands-400.woff2 +0 -0
  120. package/public/fonts/font-awesome/fa-duotone-900.ttf +0 -0
  121. package/public/fonts/font-awesome/fa-duotone-900.woff2 +0 -0
  122. package/public/fonts/font-awesome/fa-light-300.ttf +0 -0
  123. package/public/fonts/font-awesome/fa-light-300.woff2 +0 -0
  124. package/public/fonts/font-awesome/fa-regular-400.ttf +0 -0
  125. package/public/fonts/font-awesome/fa-regular-400.woff2 +0 -0
  126. package/public/fonts/font-awesome/fa-solid-900.ttf +0 -0
  127. package/public/fonts/font-awesome/fa-solid-900.woff2 +0 -0
  128. package/public/fonts/font-awesome/fa-thin-100.ttf +0 -0
  129. package/public/fonts/font-awesome/fa-thin-100.woff2 +0 -0
  130. package/public/fonts/font-awesome/fa-v4compatibility.ttf +0 -0
  131. package/public/fonts/font-awesome/fa-v4compatibility.woff2 +0 -0
  132. package/public/js/bundle.js +1 -1
  133. package/public/js/bundle.js.map +1 -1
  134. package/public/js/bundle.vendor.js +1 -1
  135. package/public/js/bundle.vendor.js.LICENSE.txt +24 -6
  136. package/public/js/bundle.vendor.js.map +1 -1
  137. package/public/js/loading-error-handlers.js +1 -1
  138. package/public/service-worker.js +1 -1
  139. package/public/themes/default.css +1 -1
  140. package/public/themes/morning.css +1 -1
  141. package/dist/webpack.config.js +0 -224
@@ -1,49 +1,45 @@
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"));
1
+ import path from "node:path";
2
+ import fs from "node:fs";
3
+ import os from "node:os";
4
+ import _ from "lodash";
5
+ import colors from "chalk";
6
+ import { pathToFileURL } from "node:url";
7
+ import log from "./log.js";
8
+ import Helper from "./helper.js";
9
+ import Utils from "./command-line/utils.js";
10
+ import defaultConfig from "../defaults/config.js";
15
11
  class Config {
16
- values = require(path_1.default.resolve(path_1.default.join(__dirname, "..", "defaults", "config.js")));
12
+ values = { ..._.cloneDeep(defaultConfig), themeColor: "" };
17
13
  #homePath = "";
18
14
  getHomePath() {
19
15
  return this.#homePath;
20
16
  }
21
17
  getConfigPath() {
22
- return path_1.default.join(this.#homePath, "config.js");
18
+ return path.join(this.#homePath, "config.js");
23
19
  }
24
20
  getUserLogsPath() {
25
- return path_1.default.join(this.#homePath, "logs");
21
+ return path.join(this.#homePath, "logs");
26
22
  }
27
23
  getStoragePath() {
28
- return path_1.default.join(this.#homePath, "storage");
24
+ return path.join(this.#homePath, "storage");
29
25
  }
30
26
  getFileUploadPath() {
31
- return path_1.default.join(this.#homePath, "uploads");
27
+ return path.join(this.#homePath, "uploads");
32
28
  }
33
29
  getUsersPath() {
34
- return path_1.default.join(this.#homePath, "users");
30
+ return path.join(this.#homePath, "users");
35
31
  }
36
32
  getUserConfigPath(name) {
37
- return path_1.default.join(this.getUsersPath(), `${name}.json`);
33
+ return path.join(this.getUsersPath(), `${name}.json`);
38
34
  }
39
35
  getClientCertificatesPath() {
40
- return path_1.default.join(this.#homePath, "certificates");
36
+ return path.join(this.#homePath, "certificates");
41
37
  }
42
38
  getPackagesPath() {
43
- return path_1.default.join(this.#homePath, "packages");
39
+ return path.join(this.#homePath, "packages");
44
40
  }
45
41
  getPackageModulePath(packageName) {
46
- return path_1.default.join(this.getPackagesPath(), "node_modules", packageName);
42
+ return path.join(this.getPackagesPath(), "node_modules", packageName);
47
43
  }
48
44
  getDefaultNick() {
49
45
  if (!this.values.defaults.nick) {
@@ -59,37 +55,45 @@ class Config {
59
55
  // it mutates the oldConfig, but returns it as a convenience for testing
60
56
  for (const key in newConfig) {
61
57
  if (!Object.prototype.hasOwnProperty.call(oldConfig, key)) {
62
- log_1.default.warn(`Unknown key "${chalk_1.default.bold(key)}", please verify your config.`);
58
+ log.warn(`Unknown key "${colors.bold(key)}", please verify your config.`);
63
59
  }
64
60
  }
65
- return lodash_1.default.mergeWith(oldConfig, newConfig, (objValue, srcValue, key) => {
61
+ return _.mergeWith(oldConfig, newConfig, (objValue, srcValue, key) => {
66
62
  // Do not override config variables if the type is incorrect (e.g. object changed into a string)
67
63
  if (typeof objValue !== "undefined" &&
68
64
  objValue !== null &&
69
65
  typeof objValue !== typeof srcValue) {
70
- log_1.default.warn(`Incorrect type for "${chalk_1.default.bold(key)}", please verify your config.`);
66
+ log.warn(`Incorrect type for "${colors.bold(key)}", please verify your config.`);
71
67
  // eslint-disable-next-line @typescript-eslint/no-unsafe-return
72
68
  return objValue;
73
69
  }
74
70
  // For arrays, simply override the value with user provided one.
75
- if (lodash_1.default.isArray(objValue)) {
71
+ if (_.isArray(objValue)) {
76
72
  // eslint-disable-next-line @typescript-eslint/no-unsafe-return
77
73
  return srcValue;
78
74
  }
79
75
  });
80
76
  }
81
- setHome(newPath) {
82
- this.#homePath = helper_1.default.expandHome(newPath);
77
+ async setHome(newPath) {
78
+ this.#homePath = Helper.expandHome(newPath);
83
79
  // Reload config from new home location
84
80
  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...");
81
+ if (fs.existsSync(configPath)) {
82
+ try {
83
+ const configUrl = pathToFileURL(configPath).href;
84
+ const userConfigModule = await import(configUrl);
85
+ const userConfig = userConfigModule.default || userConfigModule;
86
+ if (_.isEmpty(userConfig)) {
87
+ log.warn(`The file located at ${colors.green(configPath)} does not appear to expose anything.`);
88
+ log.warn(`Make sure it is non-empty and the configuration is exported using ${colors.bold("export default { ... }")}.`);
89
+ log.warn("Using default configuration...");
90
+ }
91
+ this.merge(userConfig);
92
+ }
93
+ catch (error) {
94
+ log.error(`Failed to load config from ${configPath}:`, String(error));
95
+ log.warn("Using default configuration...");
91
96
  }
92
- this.merge(userConfig);
93
97
  }
94
98
  if (this.values.fileUpload.baseUrl) {
95
99
  try {
@@ -97,42 +101,47 @@ class Config {
97
101
  }
98
102
  catch (e) {
99
103
  this.values.fileUpload.baseUrl = undefined;
100
- log_1.default.warn(`The ${chalk_1.default.bold("fileUpload.baseUrl")} you specified is invalid: ${String(e)}`);
104
+ log.warn(`The ${colors.bold("fileUpload.baseUrl")} you specified is invalid: ${String(e)}`);
101
105
  }
102
106
  }
103
- const manifestPath = utils_1.default.getFileFromRelativeToRoot("public", "thelounge.webmanifest");
107
+ const manifestPath = Utils.getFileFromRelativeToRoot("public", "thelounge.webmanifest");
104
108
  // 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);
109
+ // Skip this check in test environment
110
+ if (!fs.existsSync(manifestPath)) {
111
+ if (process.env.NODE_ENV !== "test") {
112
+ log.error(`The client application was not built. Run ${colors.bold("NODE_ENV=production yarn build")} to resolve this.`);
113
+ process.exit(1);
114
+ }
115
+ }
116
+ else {
117
+ // Load theme color from the web manifest
118
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
119
+ this.values.themeColor = manifest.theme_color;
108
120
  }
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
121
  // log dir probably shouldn't be world accessible.
113
122
  // Create it with the desired permission bits if it doesn't exist yet.
114
123
  let logsStat = undefined;
115
124
  const userLogsPath = this.getUserLogsPath();
116
125
  try {
117
- logsStat = fs_1.default.statSync(userLogsPath);
126
+ logsStat = fs.statSync(userLogsPath);
118
127
  }
119
128
  catch {
120
129
  // ignored on purpose, node v14.17.0 will give us {throwIfNoEntry: false}
121
130
  }
122
131
  if (!logsStat) {
123
132
  try {
124
- fs_1.default.mkdirSync(userLogsPath, { recursive: true, mode: 0o750 });
133
+ fs.mkdirSync(userLogsPath, { recursive: true, mode: 0o750 });
125
134
  }
126
135
  catch (e) {
127
- log_1.default.error("Unable to create logs directory", e);
136
+ log.error("Unable to create logs directory", String(e));
128
137
  }
129
138
  }
130
139
  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.`);
140
+ log.warn(userLogsPath, "is world readable.", "The log files may be exposed. Please fix the permissions.");
141
+ if (os.platform() !== "win32") {
142
+ log.warn(`run \`chmod o-x "${userLogsPath}"\` to correct it.`);
134
143
  }
135
144
  }
136
145
  }
137
146
  }
138
- exports.default = new Config();
147
+ export default new Config();
@@ -1,15 +1,11 @@
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 package_json_1 = __importDefault(require("../package.json"));
7
- const lodash_1 = __importDefault(require("lodash"));
8
- const path_1 = __importDefault(require("path"));
9
- const os_1 = __importDefault(require("os"));
10
- const net_1 = __importDefault(require("net"));
11
- const bcryptjs_1 = __importDefault(require("bcryptjs"));
12
- const crypto_1 = __importDefault(require("crypto"));
1
+ import pkg from "../package.json" with { type: "json" };
2
+ import _ from "lodash";
3
+ import path from "node:path";
4
+ import os from "node:os";
5
+ import net from "node:net";
6
+ import bcrypt from "bcryptjs";
7
+ import crypto from "node:crypto";
8
+ import { execSync } from "node:child_process";
13
9
  const Helper = {
14
10
  expandHome,
15
11
  getVersion,
@@ -21,20 +17,21 @@ const Helper = {
21
17
  compareHostmask,
22
18
  compareWithWildcard,
23
19
  catch_to_error,
20
+ toTrimmedString,
24
21
  password: {
25
22
  hash: passwordHash,
26
23
  compare: passwordCompare,
27
24
  requiresUpdate: passwordRequiresUpdate,
28
25
  },
29
26
  };
30
- exports.default = Helper;
27
+ export default Helper;
31
28
  function getVersion() {
32
29
  const gitCommit = getGitCommit();
33
- const version = `v${package_json_1.default.version}`;
30
+ const version = `v${pkg.version}`;
34
31
  return gitCommit ? `source (${gitCommit} / ${version})` : version;
35
32
  }
36
33
  function getVersionNumber() {
37
- return package_json_1.default.version;
34
+ return pkg.version;
38
35
  }
39
36
  let _fetchedGitCommit = false;
40
37
  let _gitCommit = null;
@@ -46,27 +43,25 @@ function getGitCommit() {
46
43
  // --git-dir ".git" makes git only check current directory for `.git`, and not travel upwards
47
44
  // We set cwd to the location of `index.js` as soon as the process is started
48
45
  try {
49
- // eslint-disable-next-line @typescript-eslint/no-var-requires
50
- _gitCommit = require("child_process")
51
- .execSync('git --git-dir ".git" rev-parse --short HEAD', // Returns hash of current commit
46
+ _gitCommit = execSync('git --git-dir ".git" rev-parse --short HEAD', // Returns hash of current commit
52
47
  { stdio: ["ignore", "pipe", "ignore"] })
53
48
  .toString()
54
49
  .trim();
55
50
  return _gitCommit;
56
51
  }
57
- catch (e) {
52
+ catch {
58
53
  // Not a git repository or git is not installed
59
54
  _gitCommit = null;
60
55
  return null;
61
56
  }
62
57
  }
63
58
  function getVersionCacheBust() {
64
- const hash = crypto_1.default.createHash("sha256").update(Helper.getVersion()).digest("hex");
59
+ const hash = crypto.createHash("sha256").update(Helper.getVersion()).digest("hex");
65
60
  return hash.substring(0, 10);
66
61
  }
67
62
  function ip2hex(address) {
68
63
  // no ipv6 support
69
- if (!net_1.default.isIPv4(address)) {
64
+ if (!net.isIPv4(address)) {
70
65
  return "00000000";
71
66
  }
72
67
  return address
@@ -86,17 +81,17 @@ function expandHome(shortenedPath) {
86
81
  if (!shortenedPath) {
87
82
  return "";
88
83
  }
89
- const home = os_1.default.homedir().replace("$", "$$$$");
90
- return path_1.default.resolve(shortenedPath.replace(/^~($|\/|\\)/, home + "$1"));
84
+ const home = os.homedir().replace("$", "$$$$");
85
+ return path.resolve(shortenedPath.replace(/^~($|\/|\\)/, home + "$1"));
91
86
  }
92
87
  function passwordRequiresUpdate(password) {
93
- return bcryptjs_1.default.getRounds(password) !== 11;
88
+ return bcrypt.getRounds(password) !== 11;
94
89
  }
95
90
  function passwordHash(password) {
96
- return bcryptjs_1.default.hashSync(password, bcryptjs_1.default.genSaltSync(11));
91
+ return bcrypt.hashSync(password, bcrypt.genSaltSync(11));
97
92
  }
98
93
  function passwordCompare(password, expected) {
99
- return bcryptjs_1.default.compare(password, expected);
94
+ return bcrypt.compare(password, expected);
100
95
  }
101
96
  function parseHostmask(hostmask) {
102
97
  let nick = "";
@@ -139,7 +134,7 @@ function compareWithWildcard(a, b) {
139
134
  // so we tokenize and join with the proper char back together,
140
135
  // escaping any other regex modifier
141
136
  const wildmany_split = a.split("*").map((sub) => {
142
- const wildone_split = sub.split("?").map((p) => lodash_1.default.escapeRegExp(p));
137
+ const wildone_split = sub.split("?").map((p) => _.escapeRegExp(p));
143
138
  return wildone_split.join(".");
144
139
  });
145
140
  const user_regex = wildmany_split.join(".*");
@@ -155,7 +150,13 @@ function catch_to_error(prefix, err) {
155
150
  msg = err;
156
151
  }
157
152
  else {
158
- msg = err.toString();
153
+ msg = String(err);
159
154
  }
160
155
  return new Error(`${prefix}: ${msg}`);
161
156
  }
157
+ function toTrimmedString(value) {
158
+ if (typeof value !== "string") {
159
+ return "";
160
+ }
161
+ return String(value ?? "").trim();
162
+ }
@@ -1,44 +1,41 @@
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 fs_1 = __importDefault(require("fs"));
7
- const net_1 = __importDefault(require("net"));
8
- const chalk_1 = __importDefault(require("chalk"));
9
- const helper_1 = __importDefault(require("./helper"));
10
- const config_1 = __importDefault(require("./config"));
11
- const log_1 = __importDefault(require("./log"));
1
+ import fs from "fs";
2
+ import net from "net";
3
+ import colors from "chalk";
4
+ import Helper from "./helper.js";
5
+ import Config from "./config.js";
6
+ import log from "./log.js";
12
7
  class Identification {
13
8
  connectionId;
14
9
  connections;
15
10
  oidentdFile;
11
+ identdServer;
16
12
  constructor(startedCallback) {
17
13
  this.connectionId = 0;
18
14
  this.connections = new Map();
19
- if (typeof config_1.default.values.oidentd === "string") {
20
- this.oidentdFile = helper_1.default.expandHome(config_1.default.values.oidentd);
21
- log_1.default.info(`Oidentd file: ${chalk_1.default.green(this.oidentdFile)}`);
15
+ if (typeof Config.values.oidentd === "string") {
16
+ this.oidentdFile = Helper.expandHome(Config.values.oidentd);
17
+ log.info(`Oidentd file: ${colors.green(this.oidentdFile)}`);
22
18
  this.refresh();
23
19
  }
24
- if (config_1.default.values.identd.enable) {
20
+ if (Config.values.identd.enable) {
25
21
  if (this.oidentdFile) {
26
- log_1.default.warn("Using both identd and oidentd at the same time, this is most likely not intended.");
22
+ log.warn("Using both identd and oidentd at the same time, this is most likely not intended.");
27
23
  }
28
- const server = net_1.default.createServer(this.serverConnection.bind(this));
24
+ this.identdServer = net.createServer(this.serverConnection.bind(this));
25
+ const server = this.identdServer;
29
26
  server.on("error", (err) => {
30
27
  startedCallback(this, err);
31
28
  });
32
29
  server.listen({
33
- port: config_1.default.values.identd.port || 113,
34
- host: config_1.default.values.bind,
30
+ port: Config.values.identd.port || 113,
31
+ host: Config.values.bind,
35
32
  }, () => {
36
33
  const address = server.address();
37
34
  if (typeof address === "string") {
38
- log_1.default.info(`Identd server available on ${chalk_1.default.green(address)}`);
35
+ log.info(`Identd server available on ${colors.green(address)}`);
39
36
  }
40
37
  else if (address?.address) {
41
- log_1.default.info(`Identd server available on ${chalk_1.default.green(address.address + ":" + address.port.toString())}`);
38
+ log.info(`Identd server available on ${colors.green(address.address + ":" + address.port.toString())}`);
42
39
  }
43
40
  startedCallback(this);
44
41
  });
@@ -48,9 +45,9 @@ class Identification {
48
45
  }
49
46
  }
50
47
  serverConnection(socket) {
51
- socket.on("error", (err) => log_1.default.error(`Identd socket error: ${err}`));
48
+ socket.on("error", (err) => log.error(`Identd socket error: ${err}`));
52
49
  socket.setTimeout(5000, () => {
53
- log_1.default.warn(`identd: no data received, closing connection to ${socket.remoteAddress || "undefined"}`);
50
+ log.warn(`identd: no data received, closing connection to ${socket.remoteAddress || "undefined"}`);
54
51
  socket.destroy();
55
52
  });
56
53
  socket.once("data", (data) => {
@@ -60,17 +57,17 @@ class Identification {
60
57
  }
61
58
  respondToIdent(socket, buffer) {
62
59
  if (!socket.remoteAddress) {
63
- log_1.default.warn("identd: no remote address");
60
+ log.warn("identd: no remote address");
64
61
  return;
65
62
  }
66
63
  const data = buffer.toString().split(",");
67
64
  const lport = parseInt(data[0], 10) || 0;
68
65
  const fport = parseInt(data[1], 10) || 0;
69
66
  if (lport < 1 || fport < 1 || lport > 65535 || fport > 65535) {
70
- log_1.default.warn(`identd: bogus request from ${socket.remoteAddress}`);
67
+ log.warn(`identd: bogus request from ${socket.remoteAddress}`);
71
68
  return;
72
69
  }
73
- log_1.default.debug(`identd: remote ${socket.remoteAddress} query ${lport}, ${fport}`);
70
+ log.debug(`identd: remote ${socket.remoteAddress} query ${lport}, ${fport}`);
74
71
  for (const connection of this.connections.values()) {
75
72
  // we only want to respond if all the ip,port tuples match, to avoid user enumeration
76
73
  if (connection.socket.remotePort === fport &&
@@ -78,13 +75,13 @@ class Identification {
78
75
  socket.remoteAddress === connection.socket.remoteAddress &&
79
76
  socket.localAddress === connection.socket.localAddress) {
80
77
  const reply = `${lport}, ${fport} : USERID : TheLounge : ${connection.user}\r\n`;
81
- log_1.default.debug(`identd: reply is ${reply.trimEnd()}`);
78
+ log.debug(`identd: reply is ${reply.trimEnd()}`);
82
79
  socket.write(reply);
83
80
  return;
84
81
  }
85
82
  }
86
83
  const reply = `${lport}, ${fport} : ERROR : NO-USER\r\n`;
87
- log_1.default.debug(`identd: reply is ${reply.trimEnd()}`);
84
+ log.debug(`identd: reply is ${reply.trimEnd()}`);
88
85
  socket.write(reply);
89
86
  }
90
87
  addSocket(socket, user) {
@@ -108,15 +105,15 @@ class Identification {
108
105
  // Race condition: this can happen when more than one socket gets disconnected at
109
106
  // once, since we `refresh()` for each one being added/removed. This results
110
107
  // in there possibly being one or more disconnected sockets remaining when we get here.
111
- log_1.default.warn(`oidentd: socket has no remote or local port (id=${id}). See https://github.com/thelounge/thelounge/pull/4695.`);
108
+ log.warn(`oidentd: socket has no remote or local port (id=${id}). See https://github.com/lordbex/thelounge/pull/4695.`);
112
109
  return;
113
110
  }
114
111
  if (!connection.socket.remoteAddress) {
115
- log_1.default.warn(`oidentd: socket has no remote address, will not respond to queries`);
112
+ log.warn(`oidentd: socket has no remote address, will not respond to queries`);
116
113
  return;
117
114
  }
118
115
  if (!connection.socket.localAddress) {
119
- log_1.default.warn(`oidentd: socket has no local address, will not respond to queries`);
116
+ log.warn(`oidentd: socket has no local address, will not respond to queries`);
120
117
  return;
121
118
  }
122
119
  // we only want to respond if all the ip,port tuples match, to avoid user enumeration
@@ -128,12 +125,20 @@ class Identification {
128
125
  ` { reply "${connection.user}" }\n`;
129
126
  });
130
127
  if (this.oidentdFile) {
131
- fs_1.default.writeFile(this.oidentdFile, file, { flag: "w+" }, function (err) {
128
+ fs.writeFile(this.oidentdFile, file, { flag: "w+" }, function (err) {
132
129
  if (err) {
133
- log_1.default.error("Failed to update oidentd file!", err.message);
130
+ log.error("Failed to update oidentd file!", err.message);
134
131
  }
135
132
  });
136
133
  }
137
134
  }
135
+ close(callback) {
136
+ if (this.identdServer) {
137
+ this.identdServer.close(callback);
138
+ }
139
+ else {
140
+ callback();
141
+ }
142
+ }
138
143
  }
139
- exports.default = Identification;
144
+ export default Identification;
@@ -1,3 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- require("./command-line");
1
+ import "./command-line/index.js";
@@ -1,35 +1,38 @@
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 chalk_1 = __importDefault(require("chalk"));
7
- const read_1 = __importDefault(require("read"));
1
+ import colors from "chalk";
2
+ import { read } from "read";
3
+ import Config from "./config.js";
8
4
  function timestamp() {
9
5
  const datetime = new Date().toISOString().split(".")[0].replace("T", " ");
10
- return chalk_1.default.dim(datetime);
6
+ return colors.dim(datetime);
11
7
  }
12
8
  const log = {
13
9
  /* eslint-disable no-console */
14
10
  error(...args) {
15
- console.error(timestamp(), chalk_1.default.red("[ERROR]"), ...args);
11
+ console.error(timestamp(), colors.red("[ERROR]"), ...args);
16
12
  },
17
13
  warn(...args) {
18
- console.error(timestamp(), chalk_1.default.yellow("[WARN]"), ...args);
14
+ console.error(timestamp(), colors.yellow("[WARN]"), ...args);
19
15
  },
20
16
  info(...args) {
21
- console.log(timestamp(), chalk_1.default.blue("[INFO]"), ...args);
17
+ console.log(timestamp(), colors.blue("[INFO]"), ...args);
22
18
  },
23
19
  debug(...args) {
24
- console.log(timestamp(), chalk_1.default.green("[DEBUG]"), ...args);
20
+ if (!Config.values.debug.logs)
21
+ return;
22
+ console.log(timestamp(), colors.green("[DEBUG]"), ...args);
25
23
  },
26
24
  raw(...args) {
27
25
  console.log(...args);
28
26
  },
29
27
  /* eslint-enable no-console */
30
- prompt(options, callback) {
31
- options.prompt = [timestamp(), chalk_1.default.cyan("[PROMPT]"), options.text].join(" ");
32
- (0, read_1.default)(options, callback);
28
+ async prompt(options) {
29
+ const promptText = [timestamp(), colors.cyan("[PROMPT]"), options.text].join(" ");
30
+ const result = await read({
31
+ default: options.default,
32
+ prompt: promptText,
33
+ silent: options.silent,
34
+ });
35
+ return String(result);
33
36
  },
34
37
  };
35
- exports.default = log;
38
+ export default log;