@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,20 +1,15 @@
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 uuid_1 = require("uuid");
8
- const irc_framework_1 = __importDefault(require("irc-framework"));
9
- const chan_1 = __importDefault(require("./chan"));
10
- const msg_1 = __importDefault(require("./msg"));
11
- const prefix_1 = __importDefault(require("./prefix"));
12
- const helper_1 = __importDefault(require("../helper"));
13
- const config_1 = __importDefault(require("../config"));
14
- const sts_1 = __importDefault(require("../plugins/sts"));
15
- const clientCertificate_1 = __importDefault(require("../plugins/clientCertificate"));
16
- const msg_2 = require("../../shared/types/msg");
17
- const chan_2 = require("../../shared/types/chan");
1
+ import _ from "lodash";
2
+ import { v4 as uuidv4 } from "uuid";
3
+ import IrcFramework from "irc-framework";
4
+ import Chan from "./chan.js";
5
+ import Msg from "./msg.js";
6
+ import Prefix from "./prefix.js";
7
+ import Helper from "../helper.js";
8
+ import Config from "../config.js";
9
+ import STSPolicies from "../plugins/sts.js";
10
+ import ClientCertificate from "../plugins/clientCertificate.js";
11
+ import { MessageType } from "../../shared/types/msg.js";
12
+ import { ChanType } from "../../shared/types/chan.js";
18
13
  class Network {
19
14
  nick;
20
15
  name;
@@ -52,7 +47,7 @@ class Network {
52
47
  // TODO: this is only available on export
53
48
  hasSTSPolicy;
54
49
  constructor(attr) {
55
- lodash_1.default.defaults(this, attr, {
50
+ _.defaults(this, attr, {
56
51
  name: "",
57
52
  nick: "",
58
53
  host: "",
@@ -73,7 +68,7 @@ class Network {
73
68
  irc: null,
74
69
  serverOptions: {
75
70
  CHANTYPES: ["#", "&"],
76
- PREFIX: new prefix_1.default([
71
+ PREFIX: new Prefix([
77
72
  { symbol: "!", mode: "Y" },
78
73
  { symbol: "@", mode: "o" },
79
74
  { symbol: "%", mode: "h" },
@@ -94,18 +89,18 @@ class Network {
94
89
  keepNick: null,
95
90
  });
96
91
  if (!this.uuid) {
97
- this.uuid = (0, uuid_1.v4)();
92
+ this.uuid = uuidv4();
98
93
  }
99
94
  if (!this.name) {
100
95
  this.name = this.host;
101
96
  }
102
- this.channels.unshift(new chan_1.default({
97
+ this.channels.unshift(new Chan({
103
98
  name: this.name,
104
- type: chan_2.ChanType.LOBBY,
99
+ type: ChanType.LOBBY,
105
100
  // The lobby only starts as muted if every channel (unless it's special) is muted.
106
101
  // This is A) easier to implement and B) stops some confusion on startup.
107
102
  muted: this.channels.length >= 1 &&
108
- this.channels.every((chan) => chan.muted || chan.type === chan_2.ChanType.SPECIAL),
103
+ this.channels.every((chan) => chan.muted || chan.type === ChanType.SPECIAL),
109
104
  }));
110
105
  // Ensure FiSH keys are applied to any pre-existing channels loaded from disk
111
106
  this.applyBlowKeysToChannels();
@@ -115,7 +110,7 @@ class Network {
115
110
  const cleanNick = (str) => str.replace(/[\x00\s:!@]/g, "_").substring(0, 100);
116
111
  // Remove new lines and limit length
117
112
  const cleanString = (str) => str.replace(/[\x00\r\n]/g, "").substring(0, 300);
118
- this.setNick(cleanNick(String(this.nick || config_1.default.getDefaultNick())));
113
+ this.setNick(cleanNick(String(this.nick || Config.getDefaultNick())));
119
114
  if (!this.username) {
120
115
  // If username is empty, make one from the provided nick
121
116
  this.username = this.nick.replace(/[^a-zA-Z0-9]/g, "");
@@ -134,8 +129,8 @@ class Network {
134
129
  this.proxyPassword = cleanString(this.proxyPassword);
135
130
  this.proxyEnabled = !!this.proxyEnabled;
136
131
  const error = function (network, text) {
137
- network.getLobby().pushMessage(client, new msg_1.default({
138
- type: msg_2.MessageType.ERROR,
132
+ network.getLobby().pushMessage(client, new Msg({
133
+ type: MessageType.ERROR,
139
134
  text: text,
140
135
  }), true);
141
136
  };
@@ -145,30 +140,30 @@ class Network {
145
140
  if (!["", "plain", "external"].includes(this.sasl)) {
146
141
  this.sasl = "";
147
142
  }
148
- if (config_1.default.values.lockNetwork) {
143
+ if (Config.values.lockNetwork) {
149
144
  // This check is needed to prevent invalid user configurations
150
- if (!config_1.default.values.public &&
145
+ if (!Config.values.public &&
151
146
  this.host &&
152
147
  this.host.length > 0 &&
153
- this.host !== config_1.default.values.defaults.host) {
148
+ this.host !== Config.values.defaults.host) {
154
149
  error(this, `The hostname you specified (${this.host}) is not allowed.`);
155
150
  return false;
156
151
  }
157
- if (config_1.default.values.public) {
158
- this.name = config_1.default.values.defaults.name;
152
+ if (Config.values.public) {
153
+ this.name = Config.values.defaults.name;
159
154
  // Sync lobby channel name
160
- this.getLobby().name = config_1.default.values.defaults.name;
155
+ this.getLobby().name = Config.values.defaults.name;
161
156
  }
162
- this.host = config_1.default.values.defaults.host;
163
- this.port = config_1.default.values.defaults.port;
164
- this.tls = config_1.default.values.defaults.tls;
165
- this.rejectUnauthorized = config_1.default.values.defaults.rejectUnauthorized;
157
+ this.host = Config.values.defaults.host;
158
+ this.port = Config.values.defaults.port;
159
+ this.tls = Config.values.defaults.tls;
160
+ this.rejectUnauthorized = Config.values.defaults.rejectUnauthorized;
166
161
  }
167
162
  if (this.host.length === 0) {
168
163
  error(this, "You must specify a hostname to connect.");
169
164
  return false;
170
165
  }
171
- const stsPolicy = sts_1.default.get(this.host);
166
+ const stsPolicy = STSPolicies.get(this.host);
172
167
  if (stsPolicy && !this.tls) {
173
168
  error(this, `${this.host} has an active strict transport security policy, will connect to port ${stsPolicy.port} over a secure connection.`);
174
169
  this.port = stsPolicy.port;
@@ -178,9 +173,9 @@ class Network {
178
173
  return true;
179
174
  }
180
175
  createIrcFramework(client) {
181
- this.irc = new irc_framework_1.default.Client({
176
+ this.irc = new IrcFramework.Client({
182
177
  version: false, // We handle it ourselves
183
- outgoing_addr: config_1.default.values.bind,
178
+ outgoing_addr: Config.values.bind,
184
179
  enable_chghost: true,
185
180
  enable_echomessage: true,
186
181
  enable_setname: true,
@@ -191,18 +186,21 @@ class Network {
191
186
  // TODO: this type should be set after setIrcFrameworkOptions
192
187
  });
193
188
  this.setIrcFrameworkOptions(client);
194
- this.irc.requestCap([
189
+ // Request custom capabilities
190
+ const customCaps = [
195
191
  "znc.in/self-message", // Legacy echo-message for ZNC
196
192
  "znc.in/playback", // See http://wiki.znc.in/Playback
197
- ]);
193
+ "seedpool/enhanced", // THC enhanced client features
194
+ ];
195
+ this.irc.requestCap(customCaps);
198
196
  }
199
197
  setIrcFrameworkOptions(client) {
200
198
  this.irc.options.host = this.host;
201
199
  this.irc.options.port = this.port;
202
200
  this.irc.options.password = this.password;
203
201
  this.irc.options.nick = this.nick;
204
- this.irc.options.username = config_1.default.values.useHexIp
205
- ? helper_1.default.ip2hex(client.config.browser.ip)
202
+ this.irc.options.username = Config.values.useHexIp
203
+ ? Helper.ip2hex(client.config.browser.ip)
206
204
  : this.username;
207
205
  this.irc.options.gecos = this.realname;
208
206
  this.irc.options.tls = this.tls;
@@ -222,12 +220,15 @@ class Network {
222
220
  }
223
221
  if (!this.sasl) {
224
222
  delete this.irc.options.sasl_mechanism;
225
- delete this.irc.options.account;
223
+ // irc-framework has a funny fallback where it uses nick + server pw
224
+ // in the sasl handshake, if account is undefined, so we need an empty
225
+ // object here to really turn it off
226
+ this.irc.options.account = {};
226
227
  }
227
228
  else if (this.sasl === "external") {
228
229
  this.irc.options.sasl_mechanism = "EXTERNAL";
229
230
  this.irc.options.account = {};
230
- this.irc.options.client_certificate = clientCertificate_1.default.get(this.uuid);
231
+ this.irc.options.client_certificate = ClientCertificate.get(this.uuid);
231
232
  }
232
233
  else if (this.sasl === "plain") {
233
234
  delete this.irc.options.sasl_mechanism;
@@ -247,19 +248,19 @@ class Network {
247
248
  }
248
249
  applyBlowKeysToChannels() {
249
250
  for (const c of this.channels) {
250
- if (c.type !== chan_2.ChanType.CHANNEL && c.type !== chan_2.ChanType.QUERY) {
251
+ if (c.type !== ChanType.CHANNEL && c.type !== ChanType.QUERY) {
251
252
  continue;
252
253
  }
253
254
  c.blowfishKey = this.resolveBlowKeyFor(c.name);
254
255
  }
255
256
  }
256
257
  createWebIrc(client) {
257
- if (!config_1.default.values.webirc ||
258
- !Object.prototype.hasOwnProperty.call(config_1.default.values.webirc, this.host)) {
258
+ if (!Config.values.webirc ||
259
+ !Object.prototype.hasOwnProperty.call(Config.values.webirc, this.host)) {
259
260
  return null;
260
261
  }
261
262
  const webircObject = {
262
- password: config_1.default.values.webirc[this.host],
263
+ password: Config.values.webirc[this.host],
263
264
  username: "thelounge",
264
265
  address: client.config.browser?.ip,
265
266
  hostname: client.config.browser?.hostname,
@@ -271,9 +272,9 @@ class Network {
271
272
  secure: true,
272
273
  };
273
274
  }
274
- if (typeof config_1.default.values.webirc[this.host] === "function") {
275
+ if (typeof Config.values.webirc[this.host] === "function") {
275
276
  webircObject.password = null;
276
- return config_1.default.values.webirc[this.host](webircObject, this);
277
+ return Config.values.webirc[this.host](webircObject, this);
277
278
  }
278
279
  return webircObject;
279
280
  }
@@ -282,52 +283,49 @@ class Network {
282
283
  const oldNick = this.nick;
283
284
  const oldRealname = this.realname;
284
285
  this.keepNick = null;
285
- this.nick = args.nick;
286
- this.host = String(args.host || "");
287
- this.name = String(args.name || "") || this.host;
288
- this.port = parseInt(args.port, 10);
286
+ this.nick = String(args.nick ?? "");
287
+ this.host = String(args.host ?? "");
288
+ this.name = String(args.name ?? "") || this.host;
289
+ this.port = parseInt(String(args.port ?? 6667), 10);
289
290
  this.tls = !!args.tls;
290
291
  this.rejectUnauthorized = !!args.rejectUnauthorized;
291
- this.password = String(args.password || "");
292
- this.username = String(args.username || "");
293
- this.realname = String(args.realname || "");
294
- this.leaveMessage = String(args.leaveMessage || "");
295
- this.sasl = String(args.sasl || "");
296
- this.saslAccount = String(args.saslAccount || "");
297
- this.saslPassword = String(args.saslPassword || "");
298
- this.proxyHost = String(args.proxyHost || "");
299
- this.proxyPort = parseInt(args.proxyPort, 10);
300
- this.proxyUsername = String(args.proxyUsername || "");
301
- this.proxyPassword = String(args.proxyPassword || "");
292
+ this.password = String(args.password ?? "");
293
+ this.username = String(args.username ?? "");
294
+ this.realname = String(args.realname ?? "");
295
+ this.leaveMessage = String(args.leaveMessage ?? "");
296
+ this.sasl = String(args.sasl ?? "");
297
+ this.saslAccount = String(args.saslAccount ?? "");
298
+ this.saslPassword = String(args.saslPassword ?? "");
299
+ this.proxyHost = String(args.proxyHost ?? "");
300
+ this.proxyPort = parseInt(String(args.proxyPort ?? 1080), 10);
301
+ this.proxyUsername = String(args.proxyUsername ?? "");
302
+ this.proxyPassword = String(args.proxyPassword ?? "");
302
303
  this.proxyEnabled = !!args.proxyEnabled;
303
304
  // Split commands into an array
304
- this.commands = String(args.commands || "")
305
+ const commandsStr = Array.isArray(args.commands)
306
+ ? args.commands.join("\n")
307
+ : String(args.commands ?? "");
308
+ this.commands = commandsStr
305
309
  .replace(/\r\n|\r|\n/g, "\n")
306
310
  .split("\n")
307
311
  .filter((command) => command.length > 0);
308
312
  // FiSH: read global key and per-target keys (only update when provided)
309
313
  if (Object.prototype.hasOwnProperty.call(args, "fishGlobalKey")) {
310
- this.fishGlobalKey = String(args.fishGlobalKey || "").trim();
314
+ this.fishGlobalKey = Helper.toTrimmedString(args.fishGlobalKey || "");
311
315
  }
312
- if (Object.prototype.hasOwnProperty.call(args, "fishKeysText")) {
313
- const fishKeysText = String(args.fishKeysText || "").replace(/\r\n|\r|\n/g, "\n");
316
+ // FiSH: read per-target keys (only update when provided)
317
+ if (Object.prototype.hasOwnProperty.call(args, "fishKeys")) {
318
+ const value = args.fishKeys;
314
319
  const map = {};
315
- fishKeysText.split("\n").forEach((line) => {
316
- const trimmed = line.trim();
317
- if (!trimmed) {
318
- return;
319
- }
320
- const spaceIdx = trimmed.indexOf(" ");
321
- if (spaceIdx === -1) {
322
- return;
320
+ if (value && typeof value === "object") {
321
+ for (const [rawName, rawKey] of Object.entries(value)) {
322
+ const name = Helper.toTrimmedString(rawName).toLowerCase();
323
+ const key = Helper.toTrimmedString(rawKey);
324
+ if (name && key) {
325
+ map[name] = key;
326
+ }
323
327
  }
324
- const name = trimmed.substring(0, spaceIdx).toLowerCase();
325
- const key = trimmed.substring(spaceIdx + 1).trim();
326
- if (!name || !key) {
327
- return;
328
- }
329
- map[name] = key;
330
- });
328
+ }
331
329
  this.fishKeys = map;
332
330
  }
333
331
  // Sync lobby channel name
@@ -383,7 +381,7 @@ class Network {
383
381
  // Do not match characters and numbers (unless IRC color)
384
382
  "(?:^|[^a-z0-9]|\x03[0-9]{1,2})" +
385
383
  // Escape nickname, as it may contain regex stuff
386
- lodash_1.default.escapeRegExp(nick) +
384
+ _.escapeRegExp(nick) +
387
385
  // Do not match characters and numbers
388
386
  "(?:[^a-z0-9]|$)",
389
387
  // Case insensitive search
@@ -413,7 +411,7 @@ class Network {
413
411
  if (this.irc && this.irc.connection && this.irc.connection.transport) {
414
412
  const transport = this.irc.connection.transport;
415
413
  if (transport.socket) {
416
- const isLocalhost = transport.socket.remoteAddress === "127.0.0.1";
414
+ const isLocalhost = ["127.0.0.1", "::1"].includes(transport.socket.remoteAddress);
417
415
  const isAuthorized = transport.socket.encrypted && transport.socket.authorized;
418
416
  status.connected = transport.isConnected();
419
417
  status.secure = isAuthorized || isLocalhost;
@@ -423,12 +421,12 @@ class Network {
423
421
  }
424
422
  addChannel(newChan) {
425
423
  // Assign FiSH key based on network configuration when adding
426
- if (newChan && (newChan.type === chan_2.ChanType.CHANNEL || newChan.type === chan_2.ChanType.QUERY)) {
424
+ if (newChan && (newChan.type === ChanType.CHANNEL || newChan.type === ChanType.QUERY)) {
427
425
  newChan.blowfishKey = this.resolveBlowKeyFor(newChan.name);
428
426
  }
429
427
  let index = this.channels.length; // Default to putting as the last item in the array
430
428
  // Don't sort special channels in amongst channels/users.
431
- if (newChan.type === chan_2.ChanType.CHANNEL || newChan.type === chan_2.ChanType.QUERY) {
429
+ if (newChan.type === ChanType.CHANNEL || newChan.type === ChanType.QUERY) {
432
430
  // We start at 1 so we don't test against the lobby
433
431
  for (let i = 1; i < this.channels.length; i++) {
434
432
  const compareChan = this.channels[i];
@@ -436,7 +434,7 @@ class Network {
436
434
  if (newChan.name.localeCompare(compareChan.name, undefined, {
437
435
  sensitivity: "base",
438
436
  }) <= 0 ||
439
- (compareChan.type !== chan_2.ChanType.CHANNEL && compareChan.type !== chan_2.ChanType.QUERY)) {
437
+ (compareChan.type !== ChanType.CHANNEL && compareChan.type !== ChanType.QUERY)) {
440
438
  index = i;
441
439
  break;
442
440
  }
@@ -450,8 +448,8 @@ class Network {
450
448
  return;
451
449
  }
452
450
  // https://ircv3.net/specs/extensions/sts#rescheduling-expiry-on-disconnect
453
- sts_1.default.refreshExpiration(this.host);
454
- this.irc.quit(quitMessage || this.leaveMessage || config_1.default.values.leaveMessage);
451
+ STSPolicies.refreshExpiration(this.host);
452
+ this.irc.quit(quitMessage || this.leaveMessage || Config.values.leaveMessage);
455
453
  }
456
454
  exportForEdit() {
457
455
  const fieldsToReturn = [
@@ -472,22 +470,21 @@ class Network {
472
470
  "proxyUsername",
473
471
  "proxyPassword",
474
472
  ];
475
- if (!config_1.default.values.lockNetwork) {
473
+ if (!Config.values.lockNetwork) {
476
474
  fieldsToReturn.push("host");
477
475
  fieldsToReturn.push("port");
478
476
  fieldsToReturn.push("tls");
479
477
  fieldsToReturn.push("rejectUnauthorized");
480
478
  }
481
- const data = lodash_1.default.pick(this, fieldsToReturn);
482
- data.hasSTSPolicy = !!sts_1.default.get(this.host);
479
+ const data = _.pick(this, fieldsToReturn);
480
+ data.hasSTSPolicy = !!STSPolicies.get(this.host);
483
481
  // Include FiSH fields for editing UI
484
482
  data.fishGlobalKey = this.fishGlobalKey || "";
485
- const lines = Object.entries(this.fishKeys || {}).map(([name, key]) => `${name} ${key}`);
486
- data.fishKeysText = lines.join("\n");
483
+ data.fishKeys = { ...(this.fishKeys || {}) };
487
484
  return data;
488
485
  }
489
486
  export() {
490
- const network = lodash_1.default.pick(this, [
487
+ const network = _.pick(this, [
491
488
  "uuid",
492
489
  "awayMessage",
493
490
  "nick",
@@ -517,24 +514,25 @@ class Network {
517
514
  ]);
518
515
  network.channels = this.channels
519
516
  .filter(function (channel) {
520
- return channel.type === chan_2.ChanType.CHANNEL || channel.type === chan_2.ChanType.QUERY;
517
+ return channel.type === ChanType.CHANNEL || channel.type === ChanType.QUERY;
521
518
  })
522
519
  .map(function (chan) {
523
520
  const keys = ["name", "muted"];
524
- if (chan.type === chan_2.ChanType.CHANNEL) {
521
+ if (chan.type === ChanType.CHANNEL) {
525
522
  keys.push("key");
526
523
  }
527
- else if (chan.type === chan_2.ChanType.QUERY) {
524
+ else if (chan.type === ChanType.QUERY) {
528
525
  keys.push("type");
526
+ keys.push("pinned");
529
527
  }
530
- return lodash_1.default.pick(chan, keys);
528
+ return _.pick(chan, keys);
531
529
  // Override the type because we're omitting ID
532
530
  });
533
531
  return network;
534
532
  }
535
533
  getChannel(name) {
536
534
  name = name.toLowerCase();
537
- return lodash_1.default.find(this.channels, function (that, i) {
535
+ return _.find(this.channels, function (that, i) {
538
536
  // Skip network lobby (it's always unshifted into first position)
539
537
  return i > 0 && that.name.toLowerCase() === name;
540
538
  });
@@ -543,4 +541,4 @@ class Network {
543
541
  return this.channels[0];
544
542
  }
545
543
  }
546
- exports.default = Network;
544
+ export default Network;
@@ -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
+ }