@lordbex/thelounge 4.4.4-blowfish → 4.5.1-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 (140) hide show
  1. package/README.md +2 -2
  2. package/dist/defaults/config.js +31 -2
  3. package/dist/package.json +93 -91
  4. package/dist/server/client.js +188 -194
  5. package/dist/server/clientManager.js +65 -63
  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 +88 -86
  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 +75 -96
  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 +7 -14
  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 +93 -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/service-worker.js +1 -1
  138. package/public/themes/default.css +1 -1
  139. package/public/themes/morning.css +1 -1
  140. package/dist/webpack.config.js +0 -224
@@ -1,5 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
1
  class Prefix {
4
2
  prefix;
5
3
  modeToSymbol;
@@ -14,10 +12,9 @@ class Prefix {
14
12
  // clean out the old cruft
15
13
  this.modeToSymbol = {};
16
14
  this.symbols = [];
17
- const that = this;
18
- this.prefix.forEach(function (p) {
19
- that.modeToSymbol[p.mode] = p.symbol;
20
- that.symbols.push(p.symbol);
15
+ this.prefix.forEach((p) => {
16
+ this.modeToSymbol[p.mode] = p.symbol;
17
+ this.symbols.push(p.symbol);
21
18
  });
22
19
  }
23
20
  update(prefix) {
@@ -28,4 +25,4 @@ class Prefix {
28
25
  return this.prefix.forEach(f);
29
26
  }
30
27
  }
31
- exports.default = Prefix;
28
+ export default Prefix;
@@ -1,10 +1,5 @@
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 prefix_1 = __importDefault(require("./prefix"));
1
+ import _ from "lodash";
2
+ import Prefix from "./prefix.js";
8
3
  class User {
9
4
  modes;
10
5
  // Users in the channel have only one mode assigned
@@ -13,7 +8,7 @@ class User {
13
8
  nick;
14
9
  lastMessage;
15
10
  constructor(attr, prefix) {
16
- lodash_1.default.defaults(this, attr, {
11
+ _.defaults(this, attr, {
17
12
  modes: [],
18
13
  away: "",
19
14
  nick: "",
@@ -25,7 +20,7 @@ class User {
25
20
  return this.modes[0] || "";
26
21
  },
27
22
  });
28
- this.setModes(this.modes, prefix || new prefix_1.default([]));
23
+ this.setModes(this.modes, prefix || new Prefix([]));
29
24
  }
30
25
  setModes(modes, prefix) {
31
26
  // irc-framework sets character mode, but The Lounge works with symbols
@@ -39,4 +34,4 @@ class User {
39
34
  };
40
35
  }
41
36
  }
42
- exports.default = User;
37
+ export default User;
@@ -0,0 +1,8 @@
1
+ import { fileURLToPath } from "node:url";
2
+ import { dirname } from "node:path";
3
+ export function getDirname(importMetaUrl) {
4
+ return dirname(fileURLToPath(importMetaUrl));
5
+ }
6
+ export function getFilename(importMetaUrl) {
7
+ return fileURLToPath(importMetaUrl);
8
+ }
@@ -1,102 +1,153 @@
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 ldapjs_1 = __importDefault(require("ldapjs"));
7
- const chalk_1 = __importDefault(require("chalk"));
8
- const log_1 = __importDefault(require("../../log"));
9
- const config_1 = __importDefault(require("../../config"));
10
- function ldapAuthCommon(user, bindDN, password, callback) {
11
- const config = config_1.default.values;
12
- const ldapclient = ldapjs_1.default.createClient({
1
+ import { Client, InvalidCredentialsError } from "ldapts";
2
+ import colors from "chalk";
3
+ import log from "../../log.js";
4
+ import Config from "../../config.js";
5
+ const CONNECTION_ERROR_CODES = new Set([
6
+ "ECONNREFUSED",
7
+ "ECONNRESET",
8
+ "ENOTFOUND",
9
+ "ETIMEDOUT",
10
+ "EHOSTUNREACH",
11
+ "EAI_AGAIN",
12
+ ]);
13
+ function errorToString(err) {
14
+ if (err instanceof Error) {
15
+ return err.toString();
16
+ }
17
+ return String(err);
18
+ }
19
+ function isConnectionError(err) {
20
+ if (!err || typeof err !== "object") {
21
+ return false;
22
+ }
23
+ const code = err.code;
24
+ if (code && CONNECTION_ERROR_CODES.has(code)) {
25
+ return true;
26
+ }
27
+ if (typeof err.message === "string") {
28
+ const message = err.message;
29
+ for (const possibleCode of CONNECTION_ERROR_CODES) {
30
+ if (message.includes(possibleCode)) {
31
+ return true;
32
+ }
33
+ }
34
+ }
35
+ return false;
36
+ }
37
+ async function safeUnbind(client) {
38
+ try {
39
+ await client.unbind();
40
+ }
41
+ catch {
42
+ // Ignore unbind errors
43
+ }
44
+ }
45
+ async function ldapAuthCommon(user, bindDN, password, callback) {
46
+ const config = Config.values;
47
+ const ldapclient = new Client({
13
48
  url: config.ldap.url,
14
49
  tlsOptions: config.ldap.tlsOptions,
15
50
  });
16
- ldapclient.on("error", function (err) {
17
- log_1.default.error(`Unable to connect to LDAP server: ${err.toString()}`);
18
- callback(false);
19
- });
20
- ldapclient.bind(bindDN, password, function (err) {
21
- ldapclient.unbind();
22
- if (err) {
23
- log_1.default.error(`LDAP bind failed: ${err.toString()}`);
24
- callback(false);
51
+ let success = false;
52
+ let caughtError;
53
+ try {
54
+ await ldapclient.bind(bindDN, password);
55
+ success = true;
56
+ }
57
+ catch (err) {
58
+ caughtError = err;
59
+ }
60
+ await safeUnbind(ldapclient);
61
+ if (success) {
62
+ callback(true);
63
+ return;
64
+ }
65
+ if (caughtError) {
66
+ if (isConnectionError(caughtError)) {
67
+ log.error(`Unable to connect to LDAP server: ${errorToString(caughtError)}`);
25
68
  }
26
69
  else {
27
- callback(true);
70
+ log.error(`LDAP bind failed: ${errorToString(caughtError)}`);
28
71
  }
29
- });
72
+ }
73
+ else {
74
+ log.error("LDAP bind failed");
75
+ }
76
+ callback(false);
30
77
  }
31
78
  function simpleLdapAuth(user, password, callback) {
32
79
  if (!user || !password) {
33
80
  return callback(false);
34
81
  }
35
- const config = config_1.default.values;
82
+ const config = Config.values;
36
83
  const userDN = user.replace(/([,\\/#+<>;"= ])/g, "\\$1");
37
84
  const bindDN = `${config.ldap.primaryKey}=${userDN},${config.ldap.baseDN || ""}`;
38
- log_1.default.info(`Auth against LDAP ${config.ldap.url} with provided bindDN ${bindDN}`);
39
- ldapAuthCommon(user, bindDN, password, callback);
85
+ log.info(`Auth against LDAP ${config.ldap.url} with provided bindDN ${bindDN}`);
86
+ void ldapAuthCommon(user, bindDN, password, callback);
40
87
  }
41
88
  /**
42
89
  * LDAP auth using initial DN search (see config comment for ldap.searchDN)
43
90
  */
44
91
  function advancedLdapAuth(user, password, callback) {
45
92
  if (!user || !password) {
46
- return callback(false);
93
+ callback(false);
94
+ return;
47
95
  }
48
- const config = config_1.default.values;
96
+ const config = Config.values;
49
97
  const userDN = user.replace(/([,\\/#+<>;"= ])/g, "\\$1");
50
- const ldapclient = ldapjs_1.default.createClient({
51
- url: config.ldap.url,
52
- tlsOptions: config.ldap.tlsOptions,
53
- });
54
- const base = config.ldap.searchDN.base;
55
- const searchOptions = {
56
- scope: config.ldap.searchDN.scope,
57
- filter: `(&(${config.ldap.primaryKey}=${userDN})${config.ldap.searchDN.filter})`,
58
- attributes: ["dn"],
59
- };
60
- ldapclient.on("error", function (err) {
61
- log_1.default.error(`Unable to connect to LDAP server: ${err.toString()}`);
62
- callback(false);
63
- });
64
- ldapclient.bind(config.ldap.searchDN.rootDN, config.ldap.searchDN.rootPassword, function (err) {
65
- if (err) {
66
- log_1.default.error("Invalid LDAP root credentials");
67
- ldapclient.unbind();
98
+ void (async () => {
99
+ const ldapclient = new Client({
100
+ url: config.ldap.url,
101
+ tlsOptions: config.ldap.tlsOptions,
102
+ });
103
+ const base = config.ldap.searchDN.base;
104
+ const searchOptions = {
105
+ scope: config.ldap.searchDN.scope,
106
+ filter: `(&(${config.ldap.primaryKey}=${userDN})${config.ldap.searchDN.filter})`,
107
+ attributes: ["dn"],
108
+ };
109
+ try {
110
+ await ldapclient.bind(config.ldap.searchDN.rootDN, config.ldap.searchDN.rootPassword);
111
+ }
112
+ catch (err) {
113
+ if (err instanceof InvalidCredentialsError) {
114
+ log.error("Invalid LDAP root credentials");
115
+ }
116
+ else if (isConnectionError(err)) {
117
+ log.error(`Unable to connect to LDAP server: ${errorToString(err)}`);
118
+ }
119
+ else {
120
+ log.error(`LDAP error: ${errorToString(err)}`);
121
+ }
122
+ await safeUnbind(ldapclient);
68
123
  callback(false);
69
124
  return;
70
125
  }
71
- ldapclient.search(base, searchOptions, function (err2, res) {
72
- if (err2) {
73
- log_1.default.warn(`LDAP User not found: ${userDN}`);
74
- ldapclient.unbind();
75
- callback(false);
76
- return;
126
+ let searchResult;
127
+ try {
128
+ searchResult = await ldapclient.search(base, searchOptions);
129
+ }
130
+ catch (err) {
131
+ if (isConnectionError(err)) {
132
+ log.error(`Unable to connect to LDAP server: ${errorToString(err)}`);
77
133
  }
78
- let found = false;
79
- res.on("searchEntry", function (entry) {
80
- found = true;
81
- const bindDN = entry.objectName;
82
- log_1.default.info(`Auth against LDAP ${config.ldap.url} with found bindDN ${bindDN || ""}`);
83
- ldapclient.unbind();
84
- // TODO: Fix type !
85
- ldapAuthCommon(user, bindDN, password, callback);
86
- });
87
- res.on("error", function (err3) {
88
- log_1.default.error(`LDAP error: ${err3.toString()}`);
89
- callback(false);
90
- });
91
- res.on("end", function (result) {
92
- ldapclient.unbind();
93
- if (!found) {
94
- log_1.default.warn(`LDAP Search did not find anything for: ${userDN} (${result?.status.toString() || "unknown"})`);
95
- callback(false);
96
- }
97
- });
98
- });
99
- });
134
+ else {
135
+ log.warn(`LDAP User not found: ${userDN}`);
136
+ }
137
+ await safeUnbind(ldapclient);
138
+ callback(false);
139
+ return;
140
+ }
141
+ await safeUnbind(ldapclient);
142
+ if (!searchResult.searchEntries.length) {
143
+ log.warn(`LDAP Search did not find anything for: ${userDN}`);
144
+ callback(false);
145
+ return;
146
+ }
147
+ const bindDN = searchResult.searchEntries[0].dn;
148
+ log.info(`Auth against LDAP ${config.ldap.url} with found bindDN ${bindDN}`);
149
+ void ldapAuthCommon(user, bindDN, password, callback);
150
+ })();
100
151
  }
101
152
  const ldapAuth = (manager, client, user, password, callback) => {
102
153
  // TODO: Enable the use of starttls() as an alternative to ldaps
@@ -109,7 +160,7 @@ const ldapAuth = (manager, client, user, password, callback) => {
109
160
  callback(valid);
110
161
  }
111
162
  let auth;
112
- if ("baseDN" in config_1.default.values.ldap) {
163
+ if ("baseDN" in Config.values.ldap) {
113
164
  auth = simpleLdapAuth;
114
165
  }
115
166
  else {
@@ -122,54 +173,68 @@ const ldapAuth = (manager, client, user, password, callback) => {
122
173
  * via the supplied callback function.
123
174
  */
124
175
  function advancedLdapLoadUsers(users, callbackLoadUser) {
125
- const config = config_1.default.values;
126
- const ldapclient = ldapjs_1.default.createClient({
127
- url: config.ldap.url,
128
- tlsOptions: config.ldap.tlsOptions,
129
- });
130
- const base = config.ldap.searchDN.base;
131
- ldapclient.on("error", function (err) {
132
- log_1.default.error(`Unable to connect to LDAP server: ${err.toString()}`);
133
- });
134
- ldapclient.bind(config.ldap.searchDN.rootDN, config.ldap.searchDN.rootPassword, function (err) {
135
- if (err) {
136
- log_1.default.error("Invalid LDAP root credentials");
137
- return true;
176
+ const config = Config.values;
177
+ void (async () => {
178
+ const ldapclient = new Client({
179
+ url: config.ldap.url,
180
+ tlsOptions: config.ldap.tlsOptions,
181
+ });
182
+ try {
183
+ await ldapclient.bind(config.ldap.searchDN.rootDN, config.ldap.searchDN.rootPassword);
184
+ }
185
+ catch (err) {
186
+ if (err instanceof InvalidCredentialsError) {
187
+ log.error("Invalid LDAP root credentials");
188
+ }
189
+ else if (isConnectionError(err)) {
190
+ log.error(`Unable to connect to LDAP server: ${errorToString(err)}`);
191
+ }
192
+ else {
193
+ log.error(`LDAP error: ${errorToString(err)}`);
194
+ }
195
+ await safeUnbind(ldapclient);
196
+ return;
138
197
  }
139
198
  const remainingUsers = new Set(users);
199
+ const base = config.ldap.searchDN.base;
140
200
  const searchOptions = {
141
201
  scope: config.ldap.searchDN.scope,
142
202
  filter: `${config.ldap.searchDN.filter}`,
143
203
  attributes: [config.ldap.primaryKey],
144
204
  paged: true,
145
205
  };
146
- ldapclient.search(base, searchOptions, function (err2, res) {
147
- if (err2) {
148
- log_1.default.error(`LDAP search error: ${err2?.toString()}`);
149
- return true;
206
+ let searchResult;
207
+ try {
208
+ searchResult = await ldapclient.search(base, searchOptions);
209
+ }
210
+ catch (err) {
211
+ if (isConnectionError(err)) {
212
+ log.error(`Unable to connect to LDAP server: ${errorToString(err)}`);
213
+ }
214
+ else {
215
+ log.error(`LDAP search error: ${errorToString(err)}`);
216
+ }
217
+ await safeUnbind(ldapclient);
218
+ return;
219
+ }
220
+ await safeUnbind(ldapclient);
221
+ for (const entry of searchResult.searchEntries) {
222
+ const userAttr = entry[config.ldap.primaryKey];
223
+ const user = Array.isArray(userAttr) ? userAttr[0] : userAttr;
224
+ const userStr = typeof user === "string" ? user : String(user);
225
+ if (remainingUsers.has(userStr)) {
226
+ remainingUsers.delete(userStr);
227
+ callbackLoadUser(userStr);
150
228
  }
151
- res.on("searchEntry", function (entry) {
152
- const user = entry.attributes[0].vals[0].toString();
153
- if (remainingUsers.has(user)) {
154
- remainingUsers.delete(user);
155
- callbackLoadUser(user);
156
- }
157
- });
158
- res.on("error", function (err3) {
159
- log_1.default.error(`LDAP error: ${err3.toString()}`);
160
- });
161
- res.on("end", function () {
162
- remainingUsers.forEach((user) => {
163
- log_1.default.warn(`No account info in LDAP for ${chalk_1.default.bold(user)} but user config file exists`);
164
- });
165
- });
229
+ }
230
+ remainingUsers.forEach((user) => {
231
+ log.warn(`No account info in LDAP for ${colors.bold(user)} but user config file exists`);
166
232
  });
167
- ldapclient.unbind();
168
- });
233
+ })();
169
234
  return true;
170
235
  }
171
236
  function ldapLoadUsers(users, callbackLoadUser) {
172
- if ("baseDN" in config_1.default.values.ldap) {
237
+ if ("baseDN" in Config.values.ldap) {
173
238
  // simple LDAP case can't test for user existence without access to the
174
239
  // user's unhashed password, so indicate need to fallback to default
175
240
  // loadUser behaviour by returning false
@@ -178,9 +243,9 @@ function ldapLoadUsers(users, callbackLoadUser) {
178
243
  return advancedLdapLoadUsers(users, callbackLoadUser);
179
244
  }
180
245
  function isLdapEnabled() {
181
- return !config_1.default.values.public && config_1.default.values.ldap.enable;
246
+ return !Config.values.public && Config.values.ldap.enable;
182
247
  }
183
- exports.default = {
248
+ export default {
184
249
  moduleName: "ldap",
185
250
  auth: ldapAuth,
186
251
  isEnabled: isLdapEnabled,
@@ -1,11 +1,6 @@
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 log_1 = __importDefault(require("../../log"));
8
- const helper_1 = __importDefault(require("../../helper"));
1
+ import colors from "chalk";
2
+ import log from "../../log.js";
3
+ import Helper from "../../helper.js";
9
4
  const localAuth = (_manager, client, user, password, callback) => {
10
5
  // If no user is found, or if the client has not provided a password,
11
6
  // fail the authentication straight away
@@ -14,27 +9,27 @@ const localAuth = (_manager, client, user, password, callback) => {
14
9
  }
15
10
  // If this user has no password set, fail the authentication
16
11
  if (!client.config.password) {
17
- log_1.default.error(`User ${chalk_1.default.bold(user)} with no local password set tried to sign in. (Probably a LDAP user)`);
12
+ log.error(`User ${colors.bold(user)} with no local password set tried to sign in. (Probably a LDAP user)`);
18
13
  return callback(false);
19
14
  }
20
- helper_1.default.password
15
+ Helper.password
21
16
  .compare(password, client.config.password)
22
17
  .then((matching) => {
23
- if (matching && helper_1.default.password.requiresUpdate(client.config.password)) {
24
- const hash = helper_1.default.password.hash(password);
18
+ if (matching && Helper.password.requiresUpdate(client.config.password)) {
19
+ const hash = Helper.password.hash(password);
25
20
  client.setPassword(hash, (success) => {
26
21
  if (success) {
27
- log_1.default.info(`User ${chalk_1.default.bold(client.name)} logged in and their hashed password has been updated to match new security requirements`);
22
+ log.info(`User ${colors.bold(client.name)} logged in and their hashed password has been updated to match new security requirements`);
28
23
  }
29
24
  });
30
25
  }
31
26
  callback(matching);
32
27
  })
33
28
  .catch((error) => {
34
- log_1.default.error(`Error while checking users password. Error: ${error}`);
29
+ log.error(`Error while checking users password. Error: ${error}`);
35
30
  });
36
31
  };
37
- exports.default = {
32
+ export default {
38
33
  moduleName: "local",
39
34
  auth: localAuth,
40
35
  isEnabled: () => true,
@@ -1,36 +1,8 @@
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 chalk_1 = __importDefault(require("chalk"));
30
- const log_1 = __importDefault(require("../log"));
1
+ import colors from "chalk";
2
+ import log from "../log.js";
31
3
  // The order defines priority: the first available plugin is used.
32
4
  // Always keep 'local' auth plugin at the end of the list; it should always be enabled.
33
- const plugins = [Promise.resolve().then(() => __importStar(require("./auth/ldap"))), Promise.resolve().then(() => __importStar(require("./auth/local")))];
5
+ const plugins = [import("./auth/ldap.js"), import("./auth/local.js")];
34
6
  const toExport = {
35
7
  moduleName: "<module with no name>",
36
8
  // Must override: implements authentication mechanism
@@ -42,7 +14,6 @@ const toExport = {
42
14
  loadUsers: () => false,
43
15
  // local auth should always be enabled, but check here to verify
44
16
  initialized: false,
45
- // TODO: fix typing
46
17
  async initialize() {
47
18
  if (toExport.initialized) {
48
19
  return;
@@ -59,12 +30,12 @@ const toExport = {
59
30
  }
60
31
  }
61
32
  if (!toExport.initialized) {
62
- log_1.default.error("None of the auth plugins is enabled");
33
+ log.error("None of the auth plugins is enabled");
63
34
  }
64
35
  },
65
36
  };
66
37
  function unimplemented(funcName) {
67
- log_1.default.debug(`Auth module ${chalk_1.default.bold(toExport.moduleName)} doesn't implement function ${chalk_1.default.bold(funcName)}`);
38
+ log.debug(`Auth module ${colors.bold(toExport.moduleName)} doesn't implement function ${colors.bold(funcName)}`);
68
39
  }
69
40
  // Default API implementations
70
- exports.default = toExport;
41
+ export default toExport;
@@ -1,23 +1,19 @@
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 got_1 = __importDefault(require("got"));
7
- const chalk_1 = __importDefault(require("chalk"));
8
- const log_1 = __importDefault(require("../log"));
9
- const package_json_1 = __importDefault(require("../../package.json"));
10
- const config_1 = __importDefault(require("../config"));
1
+ import colors from "chalk";
2
+ import log from "../log.js";
3
+ import pkg from "../../package.json" with { type: "json" };
11
4
  const TIME_TO_LIVE = 15 * 60 * 1000; // 15 minutes, in milliseconds
12
- exports.default = {
5
+ let updateCheckTimeout = null;
6
+ const changelog = {
13
7
  isUpdateAvailable: false,
14
8
  fetch,
15
9
  checkForUpdates,
10
+ stopUpdateChecks,
16
11
  };
12
+ export default changelog;
17
13
  const versions = {
18
14
  current: {
19
15
  prerelease: false,
20
- version: `v${package_json_1.default.version}`,
16
+ version: `v${pkg.version}`,
21
17
  changelog: undefined,
22
18
  url: "", // TODO: properly init
23
19
  },
@@ -32,31 +28,32 @@ async function fetch() {
32
28
  return versions;
33
29
  }
34
30
  try {
35
- const response = await (0, got_1.default)("https://api.github.com/repos/lordbex/thelounge/releases", {
31
+ const fetchOptions = {
36
32
  headers: {
37
33
  Accept: "application/vnd.github.v3.html", // Request rendered markdown
38
- "User-Agent": package_json_1.default.name + "; +" + package_json_1.default.repository.url, // Identify the client
34
+ "User-Agent": pkg.name + "; +" + pkg.repository.url, // Identify the client
39
35
  },
40
- localAddress: config_1.default.values.bind,
41
- });
42
- if (response.statusCode !== 200) {
36
+ };
37
+ const response = await globalThis.fetch("https://api.github.com/repos/lordbex/thelounge/releases", fetchOptions);
38
+ if (response.status !== 200) {
43
39
  return versions;
44
40
  }
45
- updateVersions(response);
46
- // Add expiration date to the data to send to the client for later refresh
41
+ const body = await response.text();
42
+ updateVersions(body);
43
+ // Add the expiration date to the data to send to the client for later refresh
47
44
  versions.expiresAt = time + TIME_TO_LIVE;
48
45
  }
49
46
  catch (error) {
50
47
  // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
51
- log_1.default.error(`Failed to fetch changelog: ${error}`);
48
+ log.error(`Failed to fetch changelog: ${error}`);
52
49
  }
53
50
  return versions;
54
51
  }
55
- function updateVersions(response) {
52
+ function updateVersions(responseBody) {
56
53
  let i;
57
54
  let release;
58
55
  let prerelease = false;
59
- const body = JSON.parse(response.body);
56
+ const body = JSON.parse(responseBody);
60
57
  // Find the current release among releases on GitHub
61
58
  for (i = 0; i < body.length; i++) {
62
59
  release = body[i];
@@ -72,7 +69,7 @@ function updateVersions(response) {
72
69
  release = body[j];
73
70
  // Find latest release or pre-release if current version is also a pre-release
74
71
  if (!release.prerelease || release.prerelease === prerelease) {
75
- module.exports.isUpdateAvailable = true;
72
+ changelog.isUpdateAvailable = true;
76
73
  versions.latest = {
77
74
  prerelease: release.prerelease,
78
75
  version: release.tag_name,
@@ -86,18 +83,24 @@ function updateVersions(response) {
86
83
  function checkForUpdates(manager) {
87
84
  fetch()
88
85
  .then((versionData) => {
89
- if (!module.exports.isUpdateAvailable) {
86
+ if (!changelog.isUpdateAvailable) {
90
87
  // Check for updates every 24 hours + random jitter of <3 hours
91
- setTimeout(() => checkForUpdates(manager), 24 * 3600 * 1000 + Math.floor(Math.random() * 10000000));
88
+ updateCheckTimeout = setTimeout(() => checkForUpdates(manager), 24 * 3600 * 1000 + Math.floor(Math.random() * 10000000));
92
89
  }
93
90
  if (!versionData.latest) {
94
91
  return;
95
92
  }
96
- log_1.default.info(`The Lounge ${chalk_1.default.green(versionData.latest.version)} is available. Read more on GitHub: ${versionData.latest.url}`);
93
+ log.info(`The Lounge ${colors.green(versionData.latest.version)} is available. Read more on GitHub: ${versionData.latest.url}`);
97
94
  // Notify all connected clients about the new version
98
95
  manager.clients.forEach((client) => client.emit("changelog:newversion"));
99
96
  })
100
97
  .catch((error) => {
101
- log_1.default.error(`Failed to check for updates: ${error.message}`);
98
+ log.error(`Failed to check for updates: ${error.message}`);
102
99
  });
103
100
  }
101
+ function stopUpdateChecks() {
102
+ if (updateCheckTimeout) {
103
+ clearTimeout(updateCheckTimeout);
104
+ updateCheckTimeout = null;
105
+ }
106
+ }