Skip to content

Commit

Permalink
Merge branch 'server-selector'
Browse files Browse the repository at this point in the history
  • Loading branch information
f0x52 committed Oct 8, 2024
1 parent 31cc4e7 commit 1ef5b03
Show file tree
Hide file tree
Showing 10 changed files with 130 additions and 66 deletions.
34 changes: 12 additions & 22 deletions client/components/NetworkForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -178,31 +178,21 @@
<template v-else-if="config.lockNetwork && !store.state.serverConfiguration?.public">
<h2>Network settings</h2>
<div class="connect-row">
<label for="connect:name">Name</label>
<input
id="connect:name"
v-model.trim="defaults.name"
<label for="connect:name">Network</label>
<select
id="connect:name"
v-model="defaults.name"
class="input"
name="name"
maxlength="100"
/>
</div>
<div class="connect-row">
<label for="connect:password">Password</label>
<RevealPassword
v-slot:default="slotProps"
class="input-wrap password-container"
>
<input
id="connect:password"
v-model="defaults.password"
class="input"
:type="slotProps.isVisible ? 'text' : 'password'"
placeholder="Server password (optional)"
name="password"
maxlength="300"
/>
</RevealPassword>
<option
v-for="network in store.state.serverConfiguration?.networks"
:key="network"
:value="network"
>
{{ network }}
</option>
</select>
</div>
</template>
Expand Down
18 changes: 15 additions & 3 deletions defaults/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -264,10 +264,7 @@ module.exports = {
// ```
defaults: {
name: "Libera.Chat",
host: "irc.libera.chat",
port: 6697,
password: "",
tls: true,
rejectUnauthorized: true,
nick: "thelounge%%",
username: "thelounge",
Expand All @@ -285,6 +282,21 @@ module.exports = {
// This value is set to `false` by default.
lockNetwork: false,

networks: {
"Libera.Chat": {
host: "irc.libera.chat",
port: 6697,
tls: true,
rejectUnauthorized: true
},
"OFTC": {
host: "irc.oftc.net",
port: 6697,
tls: true,
rejectUnauthorized: true
}
},

// ## User management

// ### `messageStorage`
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "thelounge",
"description": "The self-hosted Web IRC client",
"version": "4.4.3",
"version": "4.4.3+revspace6",
"preferGlobal": true,
"bin": {
"thelounge": "index.js"
},
"repository": {
"type": "git",
"url": "https://github.com/thelounge/thelounge.git"
"url": "https://github.com/revspace/thelounge.git"
},
"homepage": "https://thelounge.chat/",
"scripts": {
Expand Down Expand Up @@ -64,7 +64,7 @@
"file-type": "16.5.4",
"filenamify": "4.3.0",
"got": "11.8.5",
"irc-framework": "4.13.1",
"irc-framework": "https://github.com/revspace/nodejs-irc-framework",
"is-utf8": "0.2.1",
"ldapjs": "2.3.1",
"linkify-it": "3.0.3",
Expand Down
1 change: 1 addition & 0 deletions server/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ class Client {
host: String(args.host || ""),
port: parseInt(String(args.port), 10),
tls: !!args.tls,
caCert: args.caCert,
userDisconnected: !!args.userDisconnected,
rejectUnauthorized: !!args.rejectUnauthorized,
password: String(args.password || ""),
Expand Down
5 changes: 5 additions & 0 deletions server/command-line/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,13 @@ const program = new Command("start");
program
.description("Start the server")
.option("--dev", "Development mode with hot module reloading")
.option("--configPath <file>", "config file path")
.on("--help", Utils.extraHelp)
.action(function (options) {
if (options.configPath !== undefined) {
Config.configPath = options.configPath;
}

initalizeConfig();

const newLocal = "../server";
Expand Down
51 changes: 45 additions & 6 deletions server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,7 @@ type FileUpload = {
export type Defaults = Pick<
Network,
| "name"
| "host"
| "port"
| "password"
| "tls"
| "rejectUnauthorized"
| "nick"
| "username"
| "realname"
Expand All @@ -46,6 +42,7 @@ export type Defaults = Pick<
| "saslPassword"
> & {
join: string;
network: string;
};

type Identd = {
Expand Down Expand Up @@ -83,6 +80,24 @@ type StoragePolicy = {
deletionPolicy: "statusOnly" | "everything";
};

type TemplateNetwork = {
name: string,
host: string,
port: number,
tls: boolean,
rejectUnauthorized: boolean,
caCert?: Buffer
};

type NetworkInConfig = {
name: string,
host: string,
port: number,
tls: boolean,
rejectUnauthorized?: boolean,
caCert?: string
};

export type ConfigType = {
public: boolean;
host: string | undefined;
Expand All @@ -103,6 +118,7 @@ export type ConfigType = {
leaveMessage: string;
defaults: Defaults;
lockNetwork: boolean;
networks: {[name: string]: NetworkInConfig};
messageStorage: string[];
storagePolicy: StoragePolicy;
useHexIp: boolean;
Expand All @@ -119,14 +135,15 @@ class Config {
path.join(__dirname, "..", "defaults", "config.js")
)) as ConfigType;
#homePath = "";
configPath: string | undefined;
networks: {[name: string]: TemplateNetwork} = this.parseNetworks();

getHomePath() {
return this.#homePath;
}

getConfigPath() {
// return path.join(this.#homePath, "config.js");
return "/etc/thelounge/config.js";
return this.configPath ?? path.join(this.#homePath, "config.js");
}

getUserLogsPath() {
Expand Down Expand Up @@ -171,8 +188,30 @@ class Config {
);
}

getNetworks() {
return this.networks;
}

getNetworkNames() {
return Object.keys(this.networks);
}

parseNetworks() {
return Object.fromEntries(Object.entries(this.values.networks).map(([name, network]) => {
return [name, <TemplateNetwork>{
name,
host: network.host,
port: network.port,
tls: network.tls !== undefined ? network.tls : true,
rejectUnauthorized: network.rejectUnauthorized !== undefined ? network.rejectUnauthorized : true,
caCert: network.caCert ? fs.readFileSync(network.caCert) : undefined
}];
}));
}

merge(newConfig: ConfigType) {
this._merge_config_objects(this.values, newConfig);
this.networks = this.parseNetworks();
}

_merge_config_objects(oldConfig: ConfigType, newConfig: ConfigType) {
Expand Down
32 changes: 17 additions & 15 deletions server/models/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type NetworkIrcOptions = {
username: string;
gecos: string;
tls: boolean;
ca_certificate?: Buffer;
rejectUnauthorized: boolean;
webirc: WebIRC | null;
client_certificate: ClientCertificateType | null;
Expand Down Expand Up @@ -94,6 +95,7 @@ class Network {
host!: string;
port!: number;
tls!: boolean;
caCert!: Buffer;
userDisconnected!: boolean;
rejectUnauthorized!: boolean;
password!: string;
Expand Down Expand Up @@ -246,26 +248,25 @@ class Network {

if (Config.values.lockNetwork) {
// This check is needed to prevent invalid user configurations
if (
!Config.values.public &&
this.host &&
this.host.length > 0 &&
this.host !== Config.values.defaults.host
) {

const allowedNetwork = Object.values(Config.getNetworks()).find((network) => {
return (this.name === network.name || this.host === network.host);
});

if (allowedNetwork === undefined) {
error(this, `The hostname you specified (${this.host}) is not allowed.`);
return false;
}

if (Config.values.public) {
this.name = Config.values.defaults.name;
// Sync lobby channel name
this.getLobby().name = Config.values.defaults.name;
}
this.name = allowedNetwork.name;
this.host = allowedNetwork.host;
this.port = allowedNetwork.port;
this.tls = allowedNetwork.tls;
this.rejectUnauthorized = allowedNetwork.rejectUnauthorized;

this.host = Config.values.defaults.host;
this.port = Config.values.defaults.port;
this.tls = Config.values.defaults.tls;
this.rejectUnauthorized = Config.values.defaults.rejectUnauthorized;
if (allowedNetwork.caCert !== undefined) {
this.caCert = allowedNetwork.caCert;
}
}

if (this.host.length === 0) {
Expand Down Expand Up @@ -324,6 +325,7 @@ class Network {
this.irc.options.gecos = this.realname;
this.irc.options.tls = this.tls;
this.irc.options.rejectUnauthorized = this.rejectUnauthorized;
this.irc.options.ca_certificate = this.caCert;
this.irc.options.webirc = this.createWebIrc(client);
this.irc.options.client_certificate = null;

Expand Down
11 changes: 11 additions & 0 deletions server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,7 @@ function getClientConfiguration(data: AuthPerformData): SharedConfiguration | Lo
useHexIp: Config.values.useHexIp,
prefetch: Config.values.prefetch,
fileUploadMaxFileSize: Uploader ? Uploader.getMaxFileSize() : undefined, // TODO can't be undefined?
networks: Config.getNetworkNames()
};

const defaultsOverride = {
Expand All @@ -889,8 +890,18 @@ function getClientConfiguration(data: AuthPerformData): SharedConfiguration | Lo
};

if (!Config.values.lockNetwork) {
const defaultNetwork = Config.values.networks[Config.values.defaults.name];

if (defaultNetwork.rejectUnauthorized === undefined) {
defaultNetwork.rejectUnauthorized = true;
}

const defaults: ConfigNetDefaults = {
..._.clone(Config.values.defaults),
host: defaultNetwork.host,
port: defaultNetwork.port,
tls: defaultNetwork.tls,
rejectUnauthorized: defaultNetwork.rejectUnauthorized,
...defaultsOverride,
};
const result: SharedConfiguration = {
Expand Down
10 changes: 10 additions & 0 deletions shared/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ export type ConfigTheme = {
name: string;
themeColor: string | null;
};

type NetworkTemplate = {
host: string,
port: number,
tls: boolean,
rejectUnauthorized: boolean // if TLS certificates are validated
};

type SharedConfigurationBase = {
public: boolean;
useHexIp: boolean;
Expand All @@ -16,6 +24,7 @@ type SharedConfigurationBase = {
themes: ConfigTheme[];
defaultTheme: string;
fileUploadMaxFileSize?: number;
networks: string[];
};

export type ConfigNetDefaults = {
Expand All @@ -34,6 +43,7 @@ export type ConfigNetDefaults = {
saslAccount: string;
saslPassword: string;
};

export type LockedConfigNetDefaults = Pick<
ConfigNetDefaults,
"name" | "nick" | "username" | "password" | "realname" | "join"
Expand Down
Loading

0 comments on commit 1ef5b03

Please sign in to comment.