Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix config typing and make Client easier to test #4711

Merged
merged 4 commits into from
Mar 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
40 changes: 27 additions & 13 deletions server/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import inputs from "./plugins/inputs";
import PublicClient from "./plugins/packages/publicClient";
import SqliteMessageStorage from "./plugins/messageStorage/sqlite";
import TextFileMessageStorage from "./plugins/messageStorage/text";
import Network, {IgnoreListItem, NetworkWithIrcFramework} from "./models/network";
import Network, {IgnoreListItem, NetworkConfig, NetworkWithIrcFramework} from "./models/network";
import ClientManager from "./clientManager";
import {MessageStorage, SearchQuery, SearchResponse} from "./plugins/messageStorage/types";

Expand Down Expand Up @@ -78,6 +78,7 @@ export type UserConfig = {
hostname?: string;
isSecure?: boolean;
};
networks?: NetworkConfig[];
};

export type Mention = {
Expand All @@ -95,9 +96,7 @@ class Client {
attachedClients!: {
[socketId: string]: {token: string; openChannel: number};
};
config!: UserConfig & {
networks?: Network[];
};
config!: UserConfig;
id!: number;
idMsg!: number;
idChan!: number;
Expand Down Expand Up @@ -176,8 +175,16 @@ class Client {
this.registerPushSubscription(session, session.pushSubscription, true);
}
});
}

(client.config.networks || []).forEach((network) => client.connect(network, true));
connect() {
const client = this;

if (client.networks.length !== 0) {
throw new Error(`${client.name} is already connected`);
}

(client.config.networks || []).forEach((network) => client.connectToNetwork(network, true));

// Networks are stored directly in the client object
// We don't need to keep it in the config object
Expand All @@ -188,7 +195,7 @@ class Client {

// Networks are created instantly, but to reduce server load on startup
// We randomize the IRC connections and channel log loading
let delay = manager.clients.length * 500;
let delay = client.manager.clients.length * 500;
client.networks.forEach((network) => {
setTimeout(() => {
network.channels.forEach((channel) => channel.loadMessages(client, network));
Expand All @@ -201,7 +208,7 @@ class Client {
delay += 1000 + Math.floor(Math.random() * 1000);
});

client.fileHash = manager.getDataToSave(client).newHash;
client.fileHash = client.manager.getDataToSave(client).newHash;
}
}

Expand Down Expand Up @@ -238,12 +245,10 @@ class Client {
return false;
}

connect(args: Record<string, any>, isStartup = false) {
networkFromConfig(args: Record<string, any>): Network {
const client = this;
let channels: Chan[] = [];

// Get channel id for lobby before creating other channels for nicer ids
const lobbyChannelId = client.idChan++;
let channels: Chan[] = [];

if (Array.isArray(args.channels)) {
let badName = false;
Expand Down Expand Up @@ -291,7 +296,7 @@ class Client {
}

// TODO; better typing for args
const network = new Network({
return new Network({
uuid: args.uuid,
name: String(
args.name || (Config.values.lockNetwork ? Config.values.defaults.name : "") || ""
Expand Down Expand Up @@ -319,6 +324,15 @@ class Client {
proxyUsername: String(args.proxyUsername || ""),
proxyPassword: String(args.proxyPassword || ""),
});
}

connectToNetwork(args: Record<string, any>, isStartup = false) {
const client = this;

// Get channel id for lobby before creating other channels for nicer ids
const lobbyChannelId = client.idChan++;

const network = this.networkFromConfig(args);

// Set network lobby channel id
network.getLobby().id = lobbyChannelId;
Expand Down Expand Up @@ -359,7 +373,7 @@ class Client {

if (!isStartup) {
client.save();
channels.forEach((channel) => channel.loadMessages(client, network));
network.channels.forEach((channel) => channel.loadMessages(client, network));
}
}

Expand Down
2 changes: 2 additions & 0 deletions server/clientManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import path from "path";
import Auth from "./plugins/auth";
import Client, {UserConfig} from "./client";
import Config from "./config";
import {NetworkConfig} from "./models/network";
import WebPush from "./plugins/webpush";
import log from "./log";
import {Server} from "socket.io";
Expand Down Expand Up @@ -144,6 +145,7 @@ class ClientManager {
}
} else {
client = new Client(this, name, userConfig);
client.connect();
this.clients.push(client);
}

Expand Down
7 changes: 7 additions & 0 deletions server/models/chan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ export type FilteredChannel = Chan & {
totalMessages: number;
};

export type ChanConfig = {
name: string;
key?: string;
muted?: boolean;
type?: string;
};

class Chan {
id: number;
messages: Msg[];
Expand Down
30 changes: 29 additions & 1 deletion server/models/network.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import _ from "lodash";
import {v4 as uuidv4} from "uuid";
import IrcFramework, {Client as IRCClient} from "irc-framework";
import Chan, {Channel, ChanType} from "./chan";
import Chan, {ChanConfig, Channel, ChanType} from "./chan";
import Msg, {MessageType} from "./msg";
import Prefix from "./prefix";
import Helper, {Hostmask} from "../helper";
Expand Down Expand Up @@ -67,6 +67,34 @@ export type NetworkWithIrcFramework = Network & {
};
};

export type NetworkConfig = {
nick: string;
name: string;
host: string;
port: number;
tls: boolean;
userDisconnected: boolean;
rejectUnauthorized: boolean;
password: string;
awayMessage: string;
commands: any[];
username: string;
realname: string;
leaveMessage: string;
sasl: string;
saslAccount: string;
saslPassword: string;
channels: ChanConfig[];
uuid: string;
proxyHost: string;
proxyPort: number;
proxyUsername: string;
proxyPassword: string;
proxyEnabled: boolean;
highlightRegex?: string;
ignoreList: any[];
};

class Network {
nick: string;
name: string;
Expand Down
2 changes: 1 addition & 1 deletion server/plugins/inputs/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const input: PluginInputHandler = function (network, chan, cmd, args) {
}

const host = args[0];
this.connect({host, port, tls});
this.connectToNetwork({host, port, tls});

return true;
};
Expand Down
3 changes: 2 additions & 1 deletion server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ function initializeClient(
data.commands = null;
data.ignoreList = null;

client.connect(data);
client.connectToNetwork(data);
}
});

Expand Down Expand Up @@ -948,6 +948,7 @@ function performAuthentication(this: Socket, data) {

if (Config.values.public) {
client = new Client(manager!);
client.connect();
manager!.clients.push(client);

socket.on("disconnect", function () {
Expand Down
2 changes: 1 addition & 1 deletion test/models/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe("Network", function () {
expect(network1.uuid).to.not.equal(network2.uuid);
});

it("lobby should be at the top", function () {
it("should keep the lobby at the top", function () {
const network = new Network({
name: "Super Nice Network",
channels: [
Expand Down
1 change: 1 addition & 0 deletions test/tests/customhighlights.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ describe("Custom highlights", function () {
},
} as any
);
client.connect();
logInfoStub.restore();
expect(userLoadedLog).to.equal("User test loaded\n");

Expand Down