@lordbex/thelounge 4.4.3-blowfish
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.thelounge_home +1 -0
- package/LICENSE +22 -0
- package/README.md +95 -0
- package/client/index.html.tpl +69 -0
- package/dist/defaults/config.js +465 -0
- package/dist/package.json +174 -0
- package/dist/server/client.js +678 -0
- package/dist/server/clientManager.js +220 -0
- package/dist/server/command-line/index.js +85 -0
- package/dist/server/command-line/install.js +123 -0
- package/dist/server/command-line/outdated.js +30 -0
- package/dist/server/command-line/start.js +34 -0
- package/dist/server/command-line/storage.js +103 -0
- package/dist/server/command-line/uninstall.js +40 -0
- package/dist/server/command-line/upgrade.js +64 -0
- package/dist/server/command-line/users/add.js +67 -0
- package/dist/server/command-line/users/edit.js +39 -0
- package/dist/server/command-line/users/index.js +17 -0
- package/dist/server/command-line/users/list.js +53 -0
- package/dist/server/command-line/users/remove.js +37 -0
- package/dist/server/command-line/users/reset.js +64 -0
- package/dist/server/command-line/utils.js +177 -0
- package/dist/server/config.js +138 -0
- package/dist/server/helper.js +161 -0
- package/dist/server/identification.js +139 -0
- package/dist/server/index.js +3 -0
- package/dist/server/log.js +35 -0
- package/dist/server/models/chan.js +275 -0
- package/dist/server/models/msg.js +92 -0
- package/dist/server/models/network.js +546 -0
- package/dist/server/models/prefix.js +31 -0
- package/dist/server/models/user.js +42 -0
- package/dist/server/plugins/auth/ldap.js +188 -0
- package/dist/server/plugins/auth/local.js +41 -0
- package/dist/server/plugins/auth.js +70 -0
- package/dist/server/plugins/changelog.js +103 -0
- package/dist/server/plugins/clientCertificate.js +115 -0
- package/dist/server/plugins/dev-server.js +33 -0
- package/dist/server/plugins/inputs/action.js +54 -0
- package/dist/server/plugins/inputs/away.js +20 -0
- package/dist/server/plugins/inputs/ban.js +45 -0
- package/dist/server/plugins/inputs/blow.js +44 -0
- package/dist/server/plugins/inputs/connect.js +41 -0
- package/dist/server/plugins/inputs/ctcp.js +29 -0
- package/dist/server/plugins/inputs/disconnect.js +15 -0
- package/dist/server/plugins/inputs/ignore.js +74 -0
- package/dist/server/plugins/inputs/ignorelist.js +50 -0
- package/dist/server/plugins/inputs/index.js +105 -0
- package/dist/server/plugins/inputs/invite.js +31 -0
- package/dist/server/plugins/inputs/kick.js +26 -0
- package/dist/server/plugins/inputs/kill.js +13 -0
- package/dist/server/plugins/inputs/list.js +12 -0
- package/dist/server/plugins/inputs/mode.js +55 -0
- package/dist/server/plugins/inputs/msg.js +106 -0
- package/dist/server/plugins/inputs/mute.js +56 -0
- package/dist/server/plugins/inputs/nick.js +55 -0
- package/dist/server/plugins/inputs/notice.js +42 -0
- package/dist/server/plugins/inputs/part.js +46 -0
- package/dist/server/plugins/inputs/quit.js +27 -0
- package/dist/server/plugins/inputs/raw.js +13 -0
- package/dist/server/plugins/inputs/rejoin.js +25 -0
- package/dist/server/plugins/inputs/topic.js +24 -0
- package/dist/server/plugins/inputs/whois.js +19 -0
- package/dist/server/plugins/irc-events/away.js +59 -0
- package/dist/server/plugins/irc-events/cap.js +62 -0
- package/dist/server/plugins/irc-events/chghost.js +29 -0
- package/dist/server/plugins/irc-events/connection.js +152 -0
- package/dist/server/plugins/irc-events/ctcp.js +72 -0
- package/dist/server/plugins/irc-events/error.js +80 -0
- package/dist/server/plugins/irc-events/help.js +21 -0
- package/dist/server/plugins/irc-events/info.js +21 -0
- package/dist/server/plugins/irc-events/invite.js +27 -0
- package/dist/server/plugins/irc-events/join.js +53 -0
- package/dist/server/plugins/irc-events/kick.js +39 -0
- package/dist/server/plugins/irc-events/link.js +442 -0
- package/dist/server/plugins/irc-events/list.js +47 -0
- package/dist/server/plugins/irc-events/message.js +187 -0
- package/dist/server/plugins/irc-events/mode.js +124 -0
- package/dist/server/plugins/irc-events/modelist.js +67 -0
- package/dist/server/plugins/irc-events/motd.js +29 -0
- package/dist/server/plugins/irc-events/names.js +21 -0
- package/dist/server/plugins/irc-events/nick.js +45 -0
- package/dist/server/plugins/irc-events/part.js +35 -0
- package/dist/server/plugins/irc-events/quit.js +32 -0
- package/dist/server/plugins/irc-events/sasl.js +26 -0
- package/dist/server/plugins/irc-events/topic.js +42 -0
- package/dist/server/plugins/irc-events/unhandled.js +31 -0
- package/dist/server/plugins/irc-events/welcome.js +22 -0
- package/dist/server/plugins/irc-events/whois.js +57 -0
- package/dist/server/plugins/messageStorage/sqlite.js +454 -0
- package/dist/server/plugins/messageStorage/text.js +124 -0
- package/dist/server/plugins/packages/index.js +200 -0
- package/dist/server/plugins/packages/publicClient.js +66 -0
- package/dist/server/plugins/packages/themes.js +61 -0
- package/dist/server/plugins/storage.js +88 -0
- package/dist/server/plugins/sts.js +85 -0
- package/dist/server/plugins/uploader.js +267 -0
- package/dist/server/plugins/webpush.js +99 -0
- package/dist/server/server.js +857 -0
- package/dist/server/storageCleaner.js +131 -0
- package/dist/server/utils/fish.js +432 -0
- package/dist/shared/irc.js +19 -0
- package/dist/shared/linkify.js +81 -0
- package/dist/shared/types/chan.js +22 -0
- package/dist/shared/types/changelog.js +2 -0
- package/dist/shared/types/config.js +2 -0
- package/dist/shared/types/mention.js +2 -0
- package/dist/shared/types/msg.js +34 -0
- package/dist/shared/types/network.js +2 -0
- package/dist/shared/types/storage.js +2 -0
- package/dist/shared/types/user.js +2 -0
- package/dist/webpack.config.js +224 -0
- package/index.js +38 -0
- package/package.json +174 -0
- package/public/audio/pop.wav +0 -0
- package/public/css/style.css +12 -0
- package/public/css/style.css.map +1 -0
- package/public/favicon.ico +0 -0
- package/public/fonts/fa-solid-900.woff +0 -0
- package/public/fonts/fa-solid-900.woff2 +0 -0
- package/public/img/favicon-alerted.ico +0 -0
- package/public/img/icon-alerted-black-transparent-bg-72x72px.png +0 -0
- package/public/img/icon-alerted-grey-bg-192x192px.png +0 -0
- package/public/img/icon-black-transparent-bg.svg +1 -0
- package/public/img/logo-grey-bg-120x120px.png +0 -0
- package/public/img/logo-grey-bg-152x152px.png +0 -0
- package/public/img/logo-grey-bg-167x167px.png +0 -0
- package/public/img/logo-grey-bg-180x180px.png +0 -0
- package/public/img/logo-grey-bg-192x192px.png +0 -0
- package/public/img/logo-grey-bg-512x512px.png +0 -0
- package/public/img/logo-grey-bg.svg +1 -0
- package/public/img/logo-horizontal-transparent-bg-inverted.svg +1 -0
- package/public/img/logo-horizontal-transparent-bg.svg +1 -0
- package/public/img/logo-transparent-bg-inverted.svg +1 -0
- package/public/img/logo-transparent-bg.svg +1 -0
- package/public/img/logo-vertical-transparent-bg-inverted.svg +1 -0
- package/public/img/logo-vertical-transparent-bg.svg +1 -0
- package/public/js/bundle.js +2 -0
- package/public/js/bundle.js.map +1 -0
- package/public/js/bundle.vendor.js +3 -0
- package/public/js/bundle.vendor.js.LICENSE.txt +18 -0
- package/public/js/bundle.vendor.js.map +1 -0
- package/public/js/loading-error-handlers.js +1 -0
- package/public/robots.txt +2 -0
- package/public/service-worker.js +1 -0
- package/public/thelounge.webmanifest +53 -0
- package/public/themes/default.css +35 -0
- package/public/themes/morning.css +183 -0
|
@@ -0,0 +1,56 @@
|
|
|
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 msg_1 = __importDefault(require("../../models/msg"));
|
|
7
|
+
const msg_2 = require("../../../shared/types/msg");
|
|
8
|
+
const chan_1 = require("../../../shared/types/chan");
|
|
9
|
+
const commands = ["mute", "unmute"];
|
|
10
|
+
const allowDisconnected = true;
|
|
11
|
+
function args_to_channels(network, args) {
|
|
12
|
+
const targets = [];
|
|
13
|
+
for (const arg of args) {
|
|
14
|
+
const target = network.channels.find((c) => c.name === arg);
|
|
15
|
+
if (target) {
|
|
16
|
+
targets.push(target);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return targets;
|
|
20
|
+
}
|
|
21
|
+
function change_mute_state(client, target, valueToSet) {
|
|
22
|
+
if (target.type === chan_1.ChanType.SPECIAL) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
target.setMuteStatus(valueToSet);
|
|
26
|
+
client.emit("mute:changed", {
|
|
27
|
+
target: target.id,
|
|
28
|
+
status: valueToSet,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
const input = function (network, chan, cmd, args) {
|
|
32
|
+
const valueToSet = cmd === "mute" ? true : false;
|
|
33
|
+
const client = this;
|
|
34
|
+
if (args.length === 0) {
|
|
35
|
+
change_mute_state(client, chan, valueToSet);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const targets = args_to_channels(network, args);
|
|
39
|
+
if (targets.length !== args.length) {
|
|
40
|
+
const targetNames = targets.map((ch) => ch.name);
|
|
41
|
+
const missing = args.filter((x) => !targetNames.includes(x));
|
|
42
|
+
chan.pushMessage(client, new msg_1.default({
|
|
43
|
+
type: msg_2.MessageType.ERROR,
|
|
44
|
+
text: `No open ${missing.length === 1 ? "channel or user" : "channels or users"} found for ${missing.join(",")}`,
|
|
45
|
+
}));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
for (const target of targets) {
|
|
49
|
+
change_mute_state(client, target, valueToSet);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
exports.default = {
|
|
53
|
+
commands,
|
|
54
|
+
input,
|
|
55
|
+
allowDisconnected,
|
|
56
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
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 msg_1 = __importDefault(require("../../models/msg"));
|
|
7
|
+
const msg_2 = require("../../../shared/types/msg");
|
|
8
|
+
const commands = ["nick"];
|
|
9
|
+
const allowDisconnected = true;
|
|
10
|
+
const input = function (network, chan, cmd, args) {
|
|
11
|
+
if (args.length === 0) {
|
|
12
|
+
chan.pushMessage(this, new msg_1.default({
|
|
13
|
+
type: msg_2.MessageType.ERROR,
|
|
14
|
+
text: "Usage: /nick <your new nick>",
|
|
15
|
+
}));
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (args.length !== 1) {
|
|
19
|
+
chan.pushMessage(this, new msg_1.default({
|
|
20
|
+
type: msg_2.MessageType.ERROR,
|
|
21
|
+
text: "Nicknames may not contain spaces.",
|
|
22
|
+
}));
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const newNick = args[0];
|
|
26
|
+
if (newNick.length > 100) {
|
|
27
|
+
chan.pushMessage(this, new msg_1.default({
|
|
28
|
+
type: msg_2.MessageType.ERROR,
|
|
29
|
+
text: "Nicknames may not be this long.",
|
|
30
|
+
}));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
// If we were trying to keep a nick and user changes nick, stop trying to keep the old one
|
|
34
|
+
network.keepNick = null;
|
|
35
|
+
// If connected to IRC, send to server and wait for ACK
|
|
36
|
+
// otherwise update the nick and UI straight away
|
|
37
|
+
if (network.irc) {
|
|
38
|
+
if (network.irc.connected) {
|
|
39
|
+
network.irc.changeNick(newNick);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
network.irc.options.nick = network.irc.user.nick = newNick;
|
|
43
|
+
}
|
|
44
|
+
network.setNick(newNick);
|
|
45
|
+
this.emit("nick", {
|
|
46
|
+
network: network.uuid,
|
|
47
|
+
nick: newNick,
|
|
48
|
+
});
|
|
49
|
+
this.save();
|
|
50
|
+
};
|
|
51
|
+
exports.default = {
|
|
52
|
+
commands,
|
|
53
|
+
input,
|
|
54
|
+
allowDisconnected,
|
|
55
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const fish_1 = require("../../utils/fish");
|
|
4
|
+
const commands = ["notice"];
|
|
5
|
+
const input = function (network, chan, cmd, args) {
|
|
6
|
+
if (!args[1]) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
let targetName = args[0];
|
|
10
|
+
const message = args.slice(1).join(" ");
|
|
11
|
+
// Encrypt if a FiSH key is set for the target channel/query
|
|
12
|
+
const targetChan = network.getChannel(targetName) || (chan.name === targetName ? chan : undefined);
|
|
13
|
+
const key = targetChan?.blowfishKey;
|
|
14
|
+
const toSend = key ? "+OK " + (0, fish_1.fishEncryptPayload)(message, key) : message;
|
|
15
|
+
network.irc.notice(targetName, toSend);
|
|
16
|
+
// If the IRCd does not support echo-message, simulate the message
|
|
17
|
+
// being sent back to us.
|
|
18
|
+
if (!network.irc.network.cap.isEnabled("echo-message")) {
|
|
19
|
+
let targetGroup;
|
|
20
|
+
const parsedTarget = network.irc.network.extractTargetGroup(targetName);
|
|
21
|
+
if (parsedTarget) {
|
|
22
|
+
targetName = parsedTarget.target;
|
|
23
|
+
targetGroup = parsedTarget.target_group;
|
|
24
|
+
}
|
|
25
|
+
const targetChan2 = network.getChannel(targetName);
|
|
26
|
+
let displayMessage = toSend;
|
|
27
|
+
if (typeof targetChan2 === "undefined") {
|
|
28
|
+
displayMessage = "{to " + args[0] + "} " + message;
|
|
29
|
+
}
|
|
30
|
+
network.irc.emit("notice", {
|
|
31
|
+
nick: network.irc.user.nick,
|
|
32
|
+
target: targetName,
|
|
33
|
+
group: targetGroup,
|
|
34
|
+
message: displayMessage,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
};
|
|
39
|
+
exports.default = {
|
|
40
|
+
commands,
|
|
41
|
+
input,
|
|
42
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
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 msg_1 = __importDefault(require("../../models/msg"));
|
|
7
|
+
const config_1 = __importDefault(require("../../config"));
|
|
8
|
+
const msg_2 = require("../../../shared/types/msg");
|
|
9
|
+
const chan_1 = require("../../../shared/types/chan");
|
|
10
|
+
const commands = ["close", "leave", "part"];
|
|
11
|
+
const allowDisconnected = true;
|
|
12
|
+
const input = function (network, chan, cmd, args) {
|
|
13
|
+
let target = chan;
|
|
14
|
+
if (args.length > 0) {
|
|
15
|
+
const newTarget = network.getChannel(args[0]);
|
|
16
|
+
if (typeof newTarget !== "undefined") {
|
|
17
|
+
// If first argument is a channel user is in, part that channel
|
|
18
|
+
target = newTarget;
|
|
19
|
+
args.shift();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (target.type === chan_1.ChanType.LOBBY) {
|
|
23
|
+
chan.pushMessage(this, new msg_1.default({
|
|
24
|
+
type: msg_2.MessageType.ERROR,
|
|
25
|
+
text: "You can not part from networks, use /quit instead.",
|
|
26
|
+
}));
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
// If target is not a channel or we are not connected, instantly remove the channel
|
|
30
|
+
// Otherwise send part to the server and wait for response
|
|
31
|
+
if (target.type !== chan_1.ChanType.CHANNEL ||
|
|
32
|
+
target.state === chan_1.ChanState.PARTED ||
|
|
33
|
+
!network.irc.connected) {
|
|
34
|
+
this.part(network, target);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
const partMessage = args.join(" ") || network.leaveMessage || config_1.default.values.leaveMessage;
|
|
38
|
+
network.irc.part(target.name, partMessage);
|
|
39
|
+
}
|
|
40
|
+
return true;
|
|
41
|
+
};
|
|
42
|
+
exports.default = {
|
|
43
|
+
commands,
|
|
44
|
+
input,
|
|
45
|
+
allowDisconnected,
|
|
46
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
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 clientCertificate_1 = __importDefault(require("../clientCertificate"));
|
|
8
|
+
const commands = ["quit"];
|
|
9
|
+
const allowDisconnected = true;
|
|
10
|
+
const input = function (network, chan, cmd, args) {
|
|
11
|
+
const client = this;
|
|
12
|
+
client.networks = lodash_1.default.without(client.networks, network);
|
|
13
|
+
network.destroy();
|
|
14
|
+
client.save();
|
|
15
|
+
client.emit("quit", {
|
|
16
|
+
network: network.uuid,
|
|
17
|
+
});
|
|
18
|
+
const quitMessage = args[0] ? args.join(" ") : undefined;
|
|
19
|
+
network.quit(quitMessage);
|
|
20
|
+
clientCertificate_1.default.remove(network.uuid);
|
|
21
|
+
return true;
|
|
22
|
+
};
|
|
23
|
+
exports.default = {
|
|
24
|
+
commands,
|
|
25
|
+
input,
|
|
26
|
+
allowDisconnected,
|
|
27
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const commands = ["raw", "send", "quote"];
|
|
4
|
+
const input = function ({ irc }, chan, cmd, args) {
|
|
5
|
+
if (args.length !== 0) {
|
|
6
|
+
irc.raw(...args);
|
|
7
|
+
}
|
|
8
|
+
return true;
|
|
9
|
+
};
|
|
10
|
+
exports.default = {
|
|
11
|
+
commands,
|
|
12
|
+
input,
|
|
13
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
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 msg_1 = __importDefault(require("../../models/msg"));
|
|
7
|
+
const msg_2 = require("../../../shared/types/msg");
|
|
8
|
+
const chan_1 = require("../../../shared/types/chan");
|
|
9
|
+
const commands = ["cycle", "rejoin"];
|
|
10
|
+
const input = function ({ irc }, chan) {
|
|
11
|
+
if (chan.type !== chan_1.ChanType.CHANNEL) {
|
|
12
|
+
chan.pushMessage(this, new msg_1.default({
|
|
13
|
+
type: msg_2.MessageType.ERROR,
|
|
14
|
+
text: "You can only rejoin channels.",
|
|
15
|
+
}));
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
irc.part(chan.name, "Rejoining");
|
|
19
|
+
irc.join(chan.name);
|
|
20
|
+
return true;
|
|
21
|
+
};
|
|
22
|
+
exports.default = {
|
|
23
|
+
commands,
|
|
24
|
+
input,
|
|
25
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
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 msg_1 = __importDefault(require("../../models/msg"));
|
|
7
|
+
const msg_2 = require("../../../shared/types/msg");
|
|
8
|
+
const chan_1 = require("../../../shared/types/chan");
|
|
9
|
+
const commands = ["topic"];
|
|
10
|
+
const input = function ({ irc }, chan, cmd, args) {
|
|
11
|
+
if (chan.type !== chan_1.ChanType.CHANNEL) {
|
|
12
|
+
chan.pushMessage(this, new msg_1.default({
|
|
13
|
+
type: msg_2.MessageType.ERROR,
|
|
14
|
+
text: `${cmd} command can only be used in channels.`,
|
|
15
|
+
}));
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
irc.setTopic(chan.name, args.join(" "));
|
|
19
|
+
return true;
|
|
20
|
+
};
|
|
21
|
+
exports.default = {
|
|
22
|
+
commands,
|
|
23
|
+
input,
|
|
24
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const commands = ["whois"];
|
|
4
|
+
const input = function ({ irc }, chan, cmd, args) {
|
|
5
|
+
if (args.length === 1) {
|
|
6
|
+
// This queries server of the other user and not of the current user, which
|
|
7
|
+
// does not know idle time.
|
|
8
|
+
// See http://superuser.com/a/272069/208074.
|
|
9
|
+
irc.raw("WHOIS", args[0], args[0]);
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
// Re-assembling the command parsed in client.js
|
|
13
|
+
irc.raw(`${cmd} ${args.join(" ")}`);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
exports.default = {
|
|
17
|
+
commands,
|
|
18
|
+
input,
|
|
19
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
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 msg_1 = __importDefault(require("../../models/msg"));
|
|
7
|
+
const msg_2 = require("../../../shared/types/msg");
|
|
8
|
+
const chan_1 = require("../../../shared/types/chan");
|
|
9
|
+
exports.default = (function (irc, network) {
|
|
10
|
+
const client = this;
|
|
11
|
+
irc.on("away", (data) => handleAway(msg_2.MessageType.AWAY, data));
|
|
12
|
+
irc.on("back", (data) => handleAway(msg_2.MessageType.BACK, data));
|
|
13
|
+
function handleAway(type, data) {
|
|
14
|
+
const away = data.message;
|
|
15
|
+
if (data.self) {
|
|
16
|
+
const msg = new msg_1.default({
|
|
17
|
+
self: true,
|
|
18
|
+
type: type,
|
|
19
|
+
text: away,
|
|
20
|
+
time: data.time,
|
|
21
|
+
});
|
|
22
|
+
network.getLobby().pushMessage(client, msg, true);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
network.channels.forEach((chan) => {
|
|
26
|
+
let user;
|
|
27
|
+
switch (chan.type) {
|
|
28
|
+
case chan_1.ChanType.QUERY: {
|
|
29
|
+
if (data.nick.toLowerCase() !== chan.name.toLowerCase()) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (chan.userAway === away) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
// Store current away message on channel model,
|
|
36
|
+
// because query windows have no users
|
|
37
|
+
chan.userAway = away;
|
|
38
|
+
user = chan.getUser(data.nick);
|
|
39
|
+
const msg = new msg_1.default({
|
|
40
|
+
type: type,
|
|
41
|
+
text: away || "",
|
|
42
|
+
time: data.time,
|
|
43
|
+
from: user,
|
|
44
|
+
});
|
|
45
|
+
chan.pushMessage(client, msg);
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
case chan_1.ChanType.CHANNEL: {
|
|
49
|
+
user = chan.findUser(data.nick);
|
|
50
|
+
if (!user || user.away === away) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
user.away = away;
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
});
|
|
@@ -0,0 +1,62 @@
|
|
|
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 msg_1 = __importDefault(require("../../models/msg"));
|
|
7
|
+
const sts_1 = __importDefault(require("../sts"));
|
|
8
|
+
exports.default = (function (irc, network) {
|
|
9
|
+
const client = this;
|
|
10
|
+
irc.on("cap ls", (data) => {
|
|
11
|
+
handleSTS(data, true);
|
|
12
|
+
});
|
|
13
|
+
irc.on("cap new", (data) => {
|
|
14
|
+
handleSTS(data, false);
|
|
15
|
+
});
|
|
16
|
+
function handleSTS(data, shouldReconnect) {
|
|
17
|
+
if (!Object.prototype.hasOwnProperty.call(data.capabilities, "sts")) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const isSecure = irc.connection.transport.socket.encrypted;
|
|
21
|
+
const values = {};
|
|
22
|
+
data.capabilities.sts.split(",").map((value) => {
|
|
23
|
+
value = value.split("=", 2);
|
|
24
|
+
values[value[0]] = value[1];
|
|
25
|
+
});
|
|
26
|
+
if (isSecure) {
|
|
27
|
+
const duration = parseInt(values.duration, 10);
|
|
28
|
+
if (isNaN(duration)) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
sts_1.default.update(network.host, network.port, duration);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
const port = parseInt(values.port, 10);
|
|
35
|
+
if (isNaN(port)) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
network.getLobby().pushMessage(client, new msg_1.default({
|
|
39
|
+
text: `Server sent a strict transport security policy, reconnecting to ${network.host}:${port}…`,
|
|
40
|
+
}), true);
|
|
41
|
+
// Forcefully end the connection if STS is seen in CAP LS
|
|
42
|
+
// We will update the port and tls setting if we see CAP NEW,
|
|
43
|
+
// but will not force a reconnection
|
|
44
|
+
if (shouldReconnect) {
|
|
45
|
+
irc.connection.end();
|
|
46
|
+
}
|
|
47
|
+
// Update the port
|
|
48
|
+
network.port = port;
|
|
49
|
+
irc.options.port = port;
|
|
50
|
+
// Enable TLS
|
|
51
|
+
network.tls = true;
|
|
52
|
+
network.rejectUnauthorized = true;
|
|
53
|
+
irc.options.tls = true;
|
|
54
|
+
irc.options.rejectUnauthorized = true;
|
|
55
|
+
if (shouldReconnect) {
|
|
56
|
+
// Start a new connection
|
|
57
|
+
irc.connect();
|
|
58
|
+
}
|
|
59
|
+
client.save();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
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 msg_1 = __importDefault(require("../../models/msg"));
|
|
7
|
+
const msg_2 = require("../../../shared/types/msg");
|
|
8
|
+
exports.default = (function (irc, network) {
|
|
9
|
+
const client = this;
|
|
10
|
+
// If server supports CHGHOST cap, then changing the hostname does not require
|
|
11
|
+
// sending PART and JOIN, which means less work for us over all
|
|
12
|
+
irc.on("user updated", function (data) {
|
|
13
|
+
network.channels.forEach((chan) => {
|
|
14
|
+
const user = chan.findUser(data.nick);
|
|
15
|
+
if (typeof user === "undefined") {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const msg = new msg_1.default({
|
|
19
|
+
time: data.time,
|
|
20
|
+
type: msg_2.MessageType.CHGHOST,
|
|
21
|
+
new_ident: data.ident !== data.new_ident ? data.new_ident : "",
|
|
22
|
+
new_host: data.hostname !== data.new_hostname ? data.new_hostname : "",
|
|
23
|
+
self: data.nick === irc.user.nick,
|
|
24
|
+
from: user,
|
|
25
|
+
});
|
|
26
|
+
chan.pushMessage(client, msg);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
});
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
7
|
+
const log_1 = __importDefault(require("../../log"));
|
|
8
|
+
const msg_1 = __importDefault(require("../../models/msg"));
|
|
9
|
+
const helper_1 = __importDefault(require("../../helper"));
|
|
10
|
+
const config_1 = __importDefault(require("../../config"));
|
|
11
|
+
const msg_2 = require("../../../shared/types/msg");
|
|
12
|
+
const chan_1 = require("../../../shared/types/chan");
|
|
13
|
+
exports.default = (function (irc, network) {
|
|
14
|
+
const client = this;
|
|
15
|
+
network.getLobby().pushMessage(client, new msg_1.default({
|
|
16
|
+
text: "Network created, connecting to " + network.host + ":" + network.port + "...",
|
|
17
|
+
}), true);
|
|
18
|
+
irc.on("registered", function () {
|
|
19
|
+
if (network.irc.network.cap.enabled.length > 0) {
|
|
20
|
+
network.getLobby().pushMessage(client, new msg_1.default({
|
|
21
|
+
text: "Enabled capabilities: " + network.irc.network.cap.enabled.join(", "),
|
|
22
|
+
}), true);
|
|
23
|
+
}
|
|
24
|
+
// Always restore away message for this network
|
|
25
|
+
if (network.awayMessage) {
|
|
26
|
+
irc.raw("AWAY", network.awayMessage);
|
|
27
|
+
// Only set generic away message if there are no clients attached
|
|
28
|
+
}
|
|
29
|
+
else if (client.awayMessage && lodash_1.default.size(client.attachedClients) === 0) {
|
|
30
|
+
irc.raw("AWAY", client.awayMessage);
|
|
31
|
+
}
|
|
32
|
+
let delay = 1000;
|
|
33
|
+
if (Array.isArray(network.commands)) {
|
|
34
|
+
network.commands.forEach((cmd) => {
|
|
35
|
+
setTimeout(function () {
|
|
36
|
+
client.input({
|
|
37
|
+
target: network.getLobby().id,
|
|
38
|
+
text: cmd,
|
|
39
|
+
});
|
|
40
|
+
}, delay);
|
|
41
|
+
delay += 1000;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
network.channels.forEach((chan) => {
|
|
45
|
+
if (chan.type !== chan_1.ChanType.CHANNEL) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
setTimeout(function () {
|
|
49
|
+
network.irc.join(chan.name, chan.key);
|
|
50
|
+
}, delay);
|
|
51
|
+
delay += 1000;
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
irc.on("socket connected", function () {
|
|
55
|
+
if (irc.network.options.PREFIX) {
|
|
56
|
+
network.serverOptions.PREFIX.update(irc.network.options.PREFIX);
|
|
57
|
+
}
|
|
58
|
+
network.getLobby().pushMessage(client, new msg_1.default({
|
|
59
|
+
text: "Connected to the network.",
|
|
60
|
+
}), true);
|
|
61
|
+
sendStatus();
|
|
62
|
+
});
|
|
63
|
+
irc.on("close", function () {
|
|
64
|
+
network.getLobby().pushMessage(client, new msg_1.default({
|
|
65
|
+
text: "Disconnected from the network, and will not reconnect. Use /connect to reconnect again.",
|
|
66
|
+
}), true);
|
|
67
|
+
});
|
|
68
|
+
let identSocketId;
|
|
69
|
+
irc.on("raw socket connected", function (socket) {
|
|
70
|
+
let ident = client.name || network.username;
|
|
71
|
+
if (config_1.default.values.useHexIp) {
|
|
72
|
+
ident = helper_1.default.ip2hex(client.config.browser.ip);
|
|
73
|
+
}
|
|
74
|
+
identSocketId = client.manager.identHandler.addSocket(socket, ident);
|
|
75
|
+
});
|
|
76
|
+
irc.on("socket close", function (error) {
|
|
77
|
+
if (identSocketId > 0) {
|
|
78
|
+
client.manager.identHandler.removeSocket(identSocketId);
|
|
79
|
+
identSocketId = 0;
|
|
80
|
+
}
|
|
81
|
+
network.channels.forEach((chan) => {
|
|
82
|
+
chan.users = new Map();
|
|
83
|
+
chan.state = chan_1.ChanState.PARTED;
|
|
84
|
+
});
|
|
85
|
+
if (error) {
|
|
86
|
+
network.getLobby().pushMessage(client, new msg_1.default({
|
|
87
|
+
type: msg_2.MessageType.ERROR,
|
|
88
|
+
text: `Connection closed unexpectedly: ${String(error)}`,
|
|
89
|
+
}), true);
|
|
90
|
+
}
|
|
91
|
+
if (network.keepNick) {
|
|
92
|
+
// We disconnected without getting our original nick back yet, just set it back locally
|
|
93
|
+
irc.options.nick = irc.user.nick = network.keepNick;
|
|
94
|
+
network.setNick(network.keepNick);
|
|
95
|
+
network.keepNick = null;
|
|
96
|
+
client.emit("nick", {
|
|
97
|
+
network: network.uuid,
|
|
98
|
+
nick: network.nick,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
sendStatus();
|
|
102
|
+
});
|
|
103
|
+
if (config_1.default.values.debug.ircFramework) {
|
|
104
|
+
irc.on("debug", function (message) {
|
|
105
|
+
log_1.default.debug(`[${client.name} (${client.id}) on ${network.name} (${network.uuid}]`, message);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
if (config_1.default.values.debug.raw) {
|
|
109
|
+
irc.on("raw", function (message) {
|
|
110
|
+
network.getLobby().pushMessage(client, new msg_1.default({
|
|
111
|
+
self: !message.from_server,
|
|
112
|
+
type: msg_2.MessageType.RAW,
|
|
113
|
+
text: message.line,
|
|
114
|
+
}), true);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
irc.on("socket error", function (err) {
|
|
118
|
+
network.getLobby().pushMessage(client, new msg_1.default({
|
|
119
|
+
type: msg_2.MessageType.ERROR,
|
|
120
|
+
text: "Socket error: " + err,
|
|
121
|
+
}), true);
|
|
122
|
+
});
|
|
123
|
+
irc.on("reconnecting", function (data) {
|
|
124
|
+
network.getLobby().pushMessage(client, new msg_1.default({
|
|
125
|
+
text: `Disconnected from the network. Reconnecting in ${Math.round(data.wait / 1000)} seconds… (Attempt ${Number(data.attempt)})`,
|
|
126
|
+
}), true);
|
|
127
|
+
});
|
|
128
|
+
irc.on("ping timeout", function () {
|
|
129
|
+
network.getLobby().pushMessage(client, new msg_1.default({
|
|
130
|
+
text: "Ping timeout, disconnecting…",
|
|
131
|
+
}), true);
|
|
132
|
+
});
|
|
133
|
+
irc.on("server options", function (data) {
|
|
134
|
+
network.serverOptions.PREFIX.update(data.options.PREFIX);
|
|
135
|
+
if (data.options.CHANTYPES) {
|
|
136
|
+
network.serverOptions.CHANTYPES = data.options.CHANTYPES;
|
|
137
|
+
}
|
|
138
|
+
network.serverOptions.NETWORK = data.options.NETWORK;
|
|
139
|
+
client.emit("network:options", {
|
|
140
|
+
network: network.uuid,
|
|
141
|
+
serverOptions: network.serverOptions,
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
function sendStatus() {
|
|
145
|
+
const status = network.getNetworkStatus();
|
|
146
|
+
const toSend = {
|
|
147
|
+
...status,
|
|
148
|
+
network: network.uuid,
|
|
149
|
+
};
|
|
150
|
+
client.emit("network:status", toSend);
|
|
151
|
+
}
|
|
152
|
+
});
|