Refactor config out of Helper (#4558)

* Remove config from Helper

Helper is the usual util grab bag of useful stuff.
Somehow the config ended up there historically but
structurally that doesn't make any sense.

* Add cert folder to prettier ignore file
This commit is contained in:
Reto 2022-05-01 21:12:39 +02:00 committed by GitHub
parent 38f13525e6
commit d4cc2dd361
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 457 additions and 453 deletions

View File

@ -2,7 +2,7 @@
root: true
parserOptions:
ecmaVersion: 2020
ecmaVersion: 2022
env:
es6: true

View File

@ -1,6 +1,7 @@
coverage/
public/
test/fixtures/.thelounge/logs/
test/fixtures/.thelounge/certificates/
test/fixtures/.thelounge/storage/
*.log

View File

@ -7,7 +7,7 @@ const Chan = require("./models/chan");
const crypto = require("crypto");
const Msg = require("./models/msg");
const Network = require("./models/network");
const Helper = require("./helper");
const Config = require("./config");
const UAParser = require("ua-parser-js");
const {v4: uuidv4} = require("uuid");
const escapeRegExp = require("lodash/escapeRegExp");
@ -72,13 +72,13 @@ function Client(manager, name, config = {}) {
client.config.log = Boolean(client.config.log);
client.config.password = String(client.config.password);
if (!Helper.config.public && client.config.log) {
if (Helper.config.messageStorage.includes("sqlite")) {
if (!Config.values.public && client.config.log) {
if (Config.values.messageStorage.includes("sqlite")) {
client.messageProvider = new MessageStorage(client);
client.messageStorage.push(client.messageProvider);
}
if (Helper.config.messageStorage.includes("text")) {
if (Config.values.messageStorage.includes("text")) {
client.messageStorage.push(new TextFileMessageStorage(client));
}
@ -236,7 +236,7 @@ Client.prototype.connect = function (args, isStartup = false) {
const network = new Network({
uuid: args.uuid,
name: String(
args.name || (Helper.config.lockNetwork ? Helper.config.defaults.name : "") || ""
args.name || (Config.values.lockNetwork ? Config.values.defaults.name : "") || ""
),
host: String(args.host || ""),
port: parseInt(args.port, 10),
@ -759,7 +759,7 @@ Client.prototype.unregisterPushSubscription = function (token) {
Client.prototype.save = _.debounce(
function SaveClient() {
if (Helper.config.public) {
if (Config.values.public) {
return;
}

View File

@ -8,7 +8,7 @@ const fs = require("fs");
const path = require("path");
const Auth = require("./plugins/auth");
const Client = require("./client");
const Helper = require("./helper");
const Config = require("./config");
const WebPush = require("./plugins/webpush");
module.exports = ClientManager;
@ -22,12 +22,12 @@ ClientManager.prototype.init = function (identHandler, sockets) {
this.identHandler = identHandler;
this.webPush = new WebPush();
if (!Helper.config.public) {
if (!Config.values.public) {
this.loadUsers();
// LDAP does not have user commands, and users are dynamically
// created upon logon, so we don't need to watch for new files
if (!Helper.config.ldap.enable) {
if (!Config.values.ldap.enable) {
this.autoloadUsers();
}
}
@ -81,7 +81,7 @@ ClientManager.prototype.loadUsers = function () {
ClientManager.prototype.autoloadUsers = function () {
fs.watch(
Helper.getUsersPath(),
Config.getUsersPath(),
_.debounce(
() => {
const loaded = this.clients.map((c) => c.name);
@ -145,12 +145,12 @@ ClientManager.prototype.loadUser = function (name) {
};
ClientManager.prototype.getUsers = function () {
if (!fs.existsSync(Helper.getUsersPath())) {
if (!fs.existsSync(Config.getUsersPath())) {
return [];
}
return fs
.readdirSync(Helper.getUsersPath())
.readdirSync(Config.getUsersPath())
.filter((file) => file.endsWith(".json"))
.map((file) => file.slice(0, -5));
};
@ -160,7 +160,7 @@ ClientManager.prototype.addUser = function (name, password, enableLog) {
throw new Error(`${name} is an invalid username.`);
}
const userPath = Helper.getUserConfigPath(name);
const userPath = Config.getUserConfigPath(name);
if (fs.existsSync(userPath)) {
log.error(`User ${colors.green(name)} already exists.`);
@ -182,7 +182,7 @@ ClientManager.prototype.addUser = function (name, password, enableLog) {
}
try {
const userFolderStat = fs.statSync(Helper.getUsersPath());
const userFolderStat = fs.statSync(Config.getUsersPath());
const userFileStat = fs.statSync(userPath);
if (
@ -231,7 +231,7 @@ ClientManager.prototype.saveUser = function (client, callback) {
return;
}
const pathReal = Helper.getUserConfigPath(client.name);
const pathReal = Config.getUserConfigPath(client.name);
const pathTemp = pathReal + ".tmp";
try {
@ -253,7 +253,7 @@ ClientManager.prototype.saveUser = function (client, callback) {
};
ClientManager.prototype.removeUser = function (name) {
const userPath = Helper.getUserConfigPath(name);
const userPath = Config.getUserConfigPath(name);
if (!fs.existsSync(userPath)) {
log.error(`Tried to remove non-existing user ${colors.green(name)}.`);
@ -266,7 +266,7 @@ ClientManager.prototype.removeUser = function (name) {
};
function readUserConfig(name) {
const userPath = Helper.getUserConfigPath(name);
const userPath = Config.getUserConfigPath(name);
if (!fs.existsSync(userPath)) {
log.error(`Tried to read non-existing user ${colors.green(name)}`);

View File

@ -6,6 +6,7 @@ const path = require("path");
const colors = require("chalk");
const program = require("commander");
const Helper = require("../helper");
const Config = require("../config");
const Utils = require("./utils");
program
@ -20,7 +21,7 @@ program
// Parse options from `argv` returning `argv` void of these options.
const argvWithoutOptions = program.parseOptions(process.argv);
Helper.setHome(process.env.THELOUNGE_HOME || Utils.defaultHome());
Config.setHome(process.env.THELOUNGE_HOME || Utils.defaultHome());
// Check config file owner and warn if we're running under a different user
try {
@ -34,11 +35,11 @@ try {
createPackagesFolder();
// Merge config key-values passed as CLI options into the main config
Helper.mergeConfig(Helper.config, program.opts().config);
Config.merge(program.opts().config);
require("./start");
if (!Helper.config.public) {
if (!Config.values.public) {
require("./users");
}
@ -56,7 +57,7 @@ require("./outdated");
program.parse(argvWithoutOptions.operands.concat(argvWithoutOptions.unknown));
function createPackagesFolder() {
const packagesPath = Helper.getPackagesPath();
const packagesPath = Config.getPackagesPath();
const packagesConfig = path.join(packagesPath, "package.json");
// Create node_modules folder, otherwise yarn will start walking upwards to find one
@ -95,7 +96,7 @@ function verifyFileOwner() {
);
}
const configStat = fs.statSync(path.join(Helper.getHomePath(), "config.js"));
const configStat = fs.statSync(path.join(Config.getHomePath(), "config.js"));
if (configStat && configStat.uid !== uid) {
log.warn(

View File

@ -5,6 +5,7 @@ const colors = require("chalk");
const semver = require("semver");
const program = require("commander");
const Helper = require("../helper");
const Config = require("../config");
const Utils = require("./utils");
program
@ -17,8 +18,8 @@ program
const path = require("path");
const packageJson = require("package-json");
if (!fs.existsSync(Helper.getConfigPath())) {
log.error(`${Helper.getConfigPath()} does not exist.`);
if (!fs.existsSync(Config.getConfigPath())) {
log.error(`${Config.getConfigPath()} does not exist.`);
return;
}

View File

@ -5,7 +5,7 @@ const colors = require("chalk");
const fs = require("fs");
const path = require("path");
const program = require("commander");
const Helper = require("../helper");
const Config = require("../config");
const Utils = require("./utils");
program
@ -21,15 +21,15 @@ program
});
function initalizeConfig() {
if (!fs.existsSync(Helper.getConfigPath())) {
fs.mkdirSync(Helper.getHomePath(), {recursive: true});
fs.chmodSync(Helper.getHomePath(), "0700");
if (!fs.existsSync(Config.getConfigPath())) {
fs.mkdirSync(Config.getHomePath(), {recursive: true});
fs.chmodSync(Config.getHomePath(), "0700");
fs.copyFileSync(
path.resolve(path.join(__dirname, "..", "..", "defaults", "config.js")),
Helper.getConfigPath()
Config.getConfigPath()
);
log.info(`Configuration file created at ${colors.green(Helper.getConfigPath())}.`);
log.info(`Configuration file created at ${colors.green(Config.getConfigPath())}.`);
}
fs.mkdirSync(Helper.getUsersPath(), {recursive: true, mode: 0o700});
fs.mkdirSync(Config.getUsersPath(), {recursive: true, mode: 0o700});
}

View File

@ -3,7 +3,7 @@
const log = require("../log");
const colors = require("chalk");
const program = require("commander");
const Helper = require("../helper");
const Config = require("../config");
const Utils = require("./utils");
program
@ -14,7 +14,7 @@ program
const fs = require("fs");
const path = require("path");
const packagesConfig = path.join(Helper.getPackagesPath(), "package.json");
const packagesConfig = path.join(Config.getPackagesPath(), "package.json");
const packages = JSON.parse(fs.readFileSync(packagesConfig, "utf-8"));
if (

View File

@ -3,7 +3,7 @@
const log = require("../log");
const colors = require("chalk");
const program = require("commander");
const Helper = require("../helper");
const Config = require("../config");
const Utils = require("./utils");
program
@ -15,7 +15,7 @@ program
const path = require("path");
// Get paths to the location of packages directory
const packagesConfig = path.join(Helper.getPackagesPath(), "package.json");
const packagesConfig = path.join(Config.getPackagesPath(), "package.json");
const packagesList = JSON.parse(fs.readFileSync(packagesConfig, "utf-8")).dependencies;
const argsList = ["upgrade", "--latest"];

View File

@ -5,6 +5,7 @@ const colors = require("chalk");
const program = require("commander");
const fs = require("fs");
const Helper = require("../../helper");
const Config = require("../../config");
const Utils = require("../utils");
program
@ -14,8 +15,8 @@ program
.option("--password [password]", "new password, will be prompted if not specified")
.option("--save-logs", "if password is specified, this enables saving logs to disk")
.action(function (name, cmdObj) {
if (!fs.existsSync(Helper.getUsersPath())) {
log.error(`${Helper.getUsersPath()} does not exist.`);
if (!fs.existsSync(Config.getUsersPath())) {
log.error(`${Config.getUsersPath()} does not exist.`);
return;
}
@ -76,5 +77,5 @@ function add(manager, name, password, enableLog) {
manager.addUser(name, hash, enableLog);
log.info(`User ${colors.bold(name)} created.`);
log.info(`User file located at ${colors.green(Helper.getUserConfigPath(name))}.`);
log.info(`User file located at ${colors.green(Config.getUserConfigPath(name))}.`);
}

View File

@ -5,16 +5,16 @@ const program = require("commander");
const child = require("child_process");
const colors = require("chalk");
const fs = require("fs");
const Helper = require("../../helper");
const Config = require("../../config");
const Utils = require("../utils");
program
.command("edit <name>")
.description(`Edit user file located at ${colors.green(Helper.getUserConfigPath("<name>"))}`)
.description(`Edit user file located at ${colors.green(Config.getUserConfigPath("<name>"))}`)
.on("--help", Utils.extraHelp)
.action(function (name) {
if (!fs.existsSync(Helper.getUsersPath())) {
log.error(`${Helper.getUsersPath()} does not exist.`);
if (!fs.existsSync(Config.getUsersPath())) {
log.error(`${Config.getUsersPath()} does not exist.`);
return;
}
@ -33,12 +33,12 @@ program
const child_spawn = child.spawn(
process.env.EDITOR || "vi",
[Helper.getUserConfigPath(name)],
[Config.getUserConfigPath(name)],
{stdio: "inherit"}
);
child_spawn.on("error", function () {
log.error(
`Unable to open ${colors.green(Helper.getUserConfigPath(name))}. ${colors.bold(
`Unable to open ${colors.green(Config.getUserConfigPath(name))}. ${colors.bold(
"$EDITOR"
)} is not set, and ${colors.bold("vi")} was not found.`
);

View File

@ -1,6 +1,6 @@
"use strict";
if (!require("../../helper").config.ldap.enable) {
if (!require("../../config").values.ldap.enable) {
require("./add");
require("./reset");
}

View File

@ -4,7 +4,7 @@ const log = require("../../log");
const colors = require("chalk");
const program = require("commander");
const fs = require("fs");
const Helper = require("../../helper");
const Config = require("../../config");
const Utils = require("../utils");
program
@ -12,8 +12,8 @@ program
.description("Remove an existing user")
.on("--help", Utils.extraHelp)
.action(function (name) {
if (!fs.existsSync(Helper.getUsersPath())) {
log.error(`${Helper.getUsersPath()} does not exist.`);
if (!fs.existsSync(Config.getUsersPath())) {
log.error(`${Config.getUsersPath()} does not exist.`);
return;
}

View File

@ -5,6 +5,7 @@ const colors = require("chalk");
const program = require("commander");
const fs = require("fs");
const Helper = require("../../helper");
const Config = require("../../config");
const Utils = require("../utils");
program
@ -13,8 +14,8 @@ program
.on("--help", Utils.extraHelp)
.option("--password [password]", "new password, will be prompted if not specified")
.action(function (name, cmdObj) {
if (!fs.existsSync(Helper.getUsersPath())) {
log.error(`${Helper.getUsersPath()} does not exist.`);
if (!fs.existsSync(Config.getUsersPath())) {
log.error(`${Config.getUsersPath()} does not exist.`);
return;
}
@ -52,7 +53,7 @@ program
});
function change(name, password) {
const pathReal = Helper.getUserConfigPath(name);
const pathReal = Config.getUserConfigPath(name);
const pathTemp = pathReal + ".tmp";
const user = JSON.parse(fs.readFileSync(pathReal, "utf-8"));

View File

@ -5,6 +5,7 @@ const log = require("../log");
const colors = require("chalk");
const fs = require("fs");
const Helper = require("../helper");
const Config = require("../config");
const path = require("path");
let home;
@ -91,7 +92,7 @@ class Utils {
static executeYarnCommand(command, ...parameters) {
const yarn = require.resolve("yarn/bin/yarn.js");
const packagesPath = Helper.getPackagesPath();
const packagesPath = Config.getPackagesPath();
const cachePath = path.join(packagesPath, "package_manager_cache");
const staticParameters = [

182
src/config.js Normal file
View File

@ -0,0 +1,182 @@
"use strict";
const path = require("path");
const fs = require("fs");
const os = require("os");
const _ = require("lodash");
const colors = require("chalk");
const log = require("./log");
const Helper = require("./helper");
class Config {
values = require(path.resolve(path.join(__dirname, "..", "defaults", "config.js")));
#homePath;
getHomePath() {
return this.#homePath;
}
getConfigPath() {
return path.join(this.#homePath, "config.js");
}
getUserLogsPath() {
return path.join(this.#homePath, "logs");
}
getStoragePath() {
return path.join(this.#homePath, "storage");
}
getFileUploadPath() {
return path.join(this.#homePath, "uploads");
}
getUsersPath() {
return path.join(this.#homePath, "users");
}
getUserConfigPath(name) {
return path.join(this.getUsersPath(), `${name}.json`);
}
getClientCertificatesPath() {
return path.join(this.#homePath, "certificates");
}
getPackagesPath() {
return path.join(this.#homePath, "packages");
}
getPackageModulePath(packageName) {
return path.join(this.getPackagesPath(), "node_modules", packageName);
}
getDefaultNick() {
if (!this.values.defaults.nick) {
return "thelounge";
}
return this.values.defaults.nick.replace(/%/g, () => Math.floor(Math.random() * 10));
}
merge(newConfig) {
this._merge_config_objects(this.values, newConfig);
}
_merge_config_objects(oldConfig, newConfig) {
// semi exposed function so that we can test it
// it mutates the oldConfig, but returns it as a convenience for testing
for (const key in newConfig) {
if (!Object.prototype.hasOwnProperty.call(oldConfig, key)) {
log.warn(`Unknown key "${colors.bold(key)}", please verify your config.`);
}
}
return _.mergeWith(oldConfig, newConfig, (objValue, srcValue, key) => {
// Do not override config variables if the type is incorrect (e.g. object changed into a string)
if (
typeof objValue !== "undefined" &&
objValue !== null &&
typeof objValue !== typeof srcValue
) {
log.warn(`Incorrect type for "${colors.bold(key)}", please verify your config.`);
return objValue;
}
// For arrays, simply override the value with user provided one.
if (_.isArray(objValue)) {
return srcValue;
}
});
}
setHome(newPath) {
this.#homePath = Helper.expandHome(newPath);
// Reload config from new home location
const configPath = this.getConfigPath();
if (fs.existsSync(configPath)) {
const userConfig = require(configPath);
if (_.isEmpty(userConfig)) {
log.warn(
`The file located at ${colors.green(
configPath
)} does not appear to expose anything.`
);
log.warn(
`Make sure it is non-empty and the configuration is exported using ${colors.bold(
"module.exports = { ... }"
)}.`
);
log.warn("Using default configuration...");
}
this.merge(userConfig);
}
if (this.values.fileUpload.baseUrl) {
try {
new URL("test/file.png", this.values.fileUpload.baseUrl);
} catch (e) {
this.values.fileUpload.baseUrl = null;
log.warn(`The ${colors.bold("fileUpload.baseUrl")} you specified is invalid: ${e}`);
}
}
const manifestPath = path.resolve(
path.join(__dirname, "..", "public", "thelounge.webmanifest")
);
// Check if manifest exists, if not, the app most likely was not built
if (!fs.existsSync(manifestPath)) {
log.error(
`The client application was not built. Run ${colors.bold(
"NODE_ENV=production yarn build"
)} to resolve this.`
);
process.exit(1);
}
// Load theme color from the web manifest
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
this.values.themeColor = manifest.theme_color;
// log dir probably shouldn't be world accessible.
// Create it with the desired permission bits if it doesn't exist yet.
let logsStat = undefined;
const userLogsPath = this.getUserLogsPath();
try {
logsStat = fs.statSync(userLogsPath);
} catch {
// ignored on purpose, node v14.17.0 will give us {throwIfNoEntry: false}
}
if (!logsStat) {
try {
fs.mkdirSync(userLogsPath, {recursive: true, mode: 0o750});
} catch (e) {
log.error("Unable to create logs directory", e);
}
} else if (logsStat && logsStat.mode & 0o001) {
log.warn(
"contents of",
userLogsPath,
"can be accessed by any user, the log files may be exposed"
);
if (os.platform() !== "win32") {
log.warn(`run \`chmod o-x ${userLogsPath}\` to correct it`);
}
}
}
}
module.exports = new Config();

View File

@ -2,45 +2,20 @@
const pkg = require("../package.json");
const _ = require("lodash");
const log = require("./log");
const path = require("path");
const os = require("os");
const fs = require("fs");
const net = require("net");
const bcrypt = require("bcryptjs");
const colors = require("chalk");
const crypto = require("crypto");
let homePath;
let configPath;
let usersPath;
let storagePath;
let packagesPath;
let fileUploadPath;
let userLogsPath;
let clientCertificatesPath;
const Helper = {
config: null,
expandHome,
getHomePath,
getPackagesPath,
getPackageModulePath,
getStoragePath,
getConfigPath,
getFileUploadPath,
getUsersPath,
getUserConfigPath,
getUserLogsPath,
getClientCertificatesPath,
setHome,
getVersion,
getVersionCacheBust,
getVersionNumber,
getGitCommit,
ip2hex,
mergeConfig,
getDefaultNick,
parseHostmask,
compareHostmask,
compareWithWildcard,
@ -54,8 +29,6 @@ const Helper = {
module.exports = Helper;
Helper.config = require(path.resolve(path.join(__dirname, "..", "defaults", "config.js")));
function getVersion() {
const gitCommit = getGitCommit();
const version = `v${pkg.version}`;
@ -100,134 +73,6 @@ function getVersionCacheBust() {
return hash.substring(0, 10);
}
function setHome(newPath) {
homePath = expandHome(newPath);
configPath = path.join(homePath, "config.js");
usersPath = path.join(homePath, "users");
storagePath = path.join(homePath, "storage");
fileUploadPath = path.join(homePath, "uploads");
packagesPath = path.join(homePath, "packages");
userLogsPath = path.join(homePath, "logs");
clientCertificatesPath = path.join(homePath, "certificates");
// Reload config from new home location
if (fs.existsSync(configPath)) {
const userConfig = require(configPath);
if (_.isEmpty(userConfig)) {
log.warn(
`The file located at ${colors.green(
configPath
)} does not appear to expose anything.`
);
log.warn(
`Make sure it is non-empty and the configuration is exported using ${colors.bold(
"module.exports = { ... }"
)}.`
);
log.warn("Using default configuration...");
}
mergeConfig(this.config, userConfig);
}
if (this.config.fileUpload.baseUrl) {
try {
new URL("test/file.png", this.config.fileUpload.baseUrl);
} catch (e) {
this.config.fileUpload.baseUrl = null;
log.warn(`The ${colors.bold("fileUpload.baseUrl")} you specified is invalid: ${e}`);
}
}
const manifestPath = path.resolve(
path.join(__dirname, "..", "public", "thelounge.webmanifest")
);
// Check if manifest exists, if not, the app most likely was not built
if (!fs.existsSync(manifestPath)) {
log.error(
`The client application was not built. Run ${colors.bold(
"NODE_ENV=production yarn build"
)} to resolve this.`
);
process.exit(1);
}
// Load theme color from the web manifest
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
this.config.themeColor = manifest.theme_color;
// log dir probably shouldn't be world accessible.
// Create it with the desired permission bits if it doesn't exist yet.
let logsStat = undefined;
try {
logsStat = fs.statSync(userLogsPath);
} catch {
// ignored on purpose, node v14.17.0 will give us {throwIfNoEntry: false}
}
if (!logsStat) {
try {
fs.mkdirSync(userLogsPath, {recursive: true, mode: 0o750});
} catch (e) {
log.error("Unable to create logs directory", e);
}
} else if (logsStat && logsStat.mode & 0o001) {
log.warn(
"contents of",
userLogsPath,
"can be accessed by any user, the log files may be exposed"
);
if (os.platform() !== "win32") {
log.warn(`run \`chmod o-x ${userLogsPath}\` to correct it`);
}
}
}
function getHomePath() {
return homePath;
}
function getConfigPath() {
return configPath;
}
function getFileUploadPath() {
return fileUploadPath;
}
function getUsersPath() {
return usersPath;
}
function getUserConfigPath(name) {
return path.join(usersPath, name + ".json");
}
function getUserLogsPath() {
return userLogsPath;
}
function getClientCertificatesPath() {
return clientCertificatesPath;
}
function getStoragePath() {
return storagePath;
}
function getPackagesPath() {
return packagesPath;
}
function getPackageModulePath(packageName) {
return path.join(Helper.getPackagesPath(), "node_modules", packageName);
}
function ip2hex(address) {
// no ipv6 support
if (!net.isIPv4(address)) {
@ -271,40 +116,6 @@ function passwordCompare(password, expected) {
return bcrypt.compare(password, expected);
}
function getDefaultNick() {
if (!this.config.defaults.nick) {
return "thelounge";
}
return this.config.defaults.nick.replace(/%/g, () => Math.floor(Math.random() * 10));
}
function mergeConfig(oldConfig, newConfig) {
for (const key in newConfig) {
if (!Object.prototype.hasOwnProperty.call(oldConfig, key)) {
log.warn(`Unknown key "${colors.bold(key)}", please verify your config.`);
}
}
return _.mergeWith(oldConfig, newConfig, (objValue, srcValue, key) => {
// Do not override config variables if the type is incorrect (e.g. object changed into a string)
if (
typeof objValue !== "undefined" &&
objValue !== null &&
typeof objValue !== typeof srcValue
) {
log.warn(`Incorrect type for "${colors.bold(key)}", please verify your config.`);
return objValue;
}
// For arrays, simply override the value with user provided one.
if (_.isArray(objValue)) {
return srcValue;
}
});
}
function parseHostmask(hostmask) {
let nick = "";
let ident = "*";

View File

@ -5,20 +5,21 @@ const fs = require("fs");
const net = require("net");
const colors = require("chalk");
const Helper = require("./helper");
const Config = require("./config");
class Identification {
constructor(startedCallback) {
this.connectionId = 0;
this.connections = new Map();
if (typeof Helper.config.oidentd === "string") {
this.oidentdFile = Helper.expandHome(Helper.config.oidentd);
if (typeof Config.values.oidentd === "string") {
this.oidentdFile = Helper.expandHome(Config.values.oidentd);
log.info(`Oidentd file: ${colors.green(this.oidentdFile)}`);
this.refresh();
}
if (Helper.config.identd.enable) {
if (Config.values.identd.enable) {
if (this.oidentdFile) {
log.warn(
"Using both identd and oidentd at the same time, this is most likely not intended."
@ -33,8 +34,8 @@ class Identification {
server.listen(
{
port: Helper.config.identd.port || 113,
host: Helper.config.bind,
port: Config.values.identd.port || 113,
host: Config.values.bind,
},
() => {
const address = server.address();

View File

@ -2,7 +2,7 @@
const _ = require("lodash");
const log = require("../log");
const Helper = require("../helper");
const Config = require("../config");
const User = require("./user");
const Msg = require("./msg");
const storage = require("../plugins/storage");
@ -81,7 +81,7 @@ Chan.prototype.pushMessage = function (client, msg, increasesUnread) {
// Never store messages in public mode as the session
// is completely destroyed when the page gets closed
if (Helper.config.public) {
if (Config.values.public) {
return;
}
@ -92,19 +92,19 @@ Chan.prototype.pushMessage = function (client, msg, increasesUnread) {
this.writeUserLog(client, msg);
if (Helper.config.maxHistory >= 0 && this.messages.length > Helper.config.maxHistory) {
const deleted = this.messages.splice(0, this.messages.length - Helper.config.maxHistory);
if (Config.values.maxHistory >= 0 && this.messages.length > Config.values.maxHistory) {
const deleted = this.messages.splice(0, this.messages.length - Config.values.maxHistory);
// If maxHistory is 0, image would be dereferenced before client had a chance to retrieve it,
// so for now, just don't implement dereferencing for this edge case.
if (Helper.config.maxHistory > 0) {
if (Config.values.maxHistory > 0) {
this.dereferencePreviews(deleted);
}
}
};
Chan.prototype.dereferencePreviews = function (messages) {
if (!Helper.config.prefetch || !Helper.config.prefetchStorage) {
if (!Config.values.prefetch || !Config.values.prefetchStorage) {
return;
}

View File

@ -7,6 +7,7 @@ const Chan = require("./chan");
const Msg = require("./msg");
const Prefix = require("./prefix");
const Helper = require("../helper");
const Config = require("../config");
const STSPolicies = require("../plugins/sts");
const ClientCertificate = require("../plugins/clientCertificate");
@ -92,7 +93,7 @@ Network.prototype.validate = function (client) {
// Remove new lines and limit length
const cleanString = (str) => str.replace(/[\x00\r\n]/g, "").substring(0, 300);
this.setNick(cleanNick(String(this.nick || Helper.getDefaultNick())));
this.setNick(cleanNick(String(this.nick || Config.getDefaultNick())));
if (!this.username) {
// If username is empty, make one from the provided nick
@ -133,28 +134,28 @@ Network.prototype.validate = function (client) {
this.sasl = "";
}
if (Helper.config.lockNetwork) {
if (Config.values.lockNetwork) {
// This check is needed to prevent invalid user configurations
if (
!Helper.config.public &&
!Config.values.public &&
this.host &&
this.host.length > 0 &&
this.host !== Helper.config.defaults.host
this.host !== Config.values.defaults.host
) {
error(this, `The hostname you specified (${this.host}) is not allowed.`);
return false;
}
if (Helper.config.public) {
this.name = Helper.config.defaults.name;
if (Config.values.public) {
this.name = Config.values.defaults.name;
// Sync lobby channel name
this.channels[0].name = Helper.config.defaults.name;
this.channels[0].name = Config.values.defaults.name;
}
this.host = Helper.config.defaults.host;
this.port = Helper.config.defaults.port;
this.tls = Helper.config.defaults.tls;
this.rejectUnauthorized = Helper.config.defaults.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 (this.host.length === 0) {
@ -181,7 +182,7 @@ Network.prototype.validate = function (client) {
Network.prototype.createIrcFramework = function (client) {
this.irc = new IrcFramework.Client({
version: false, // We handle it ourselves
outgoing_addr: Helper.config.bind,
outgoing_addr: Config.values.bind,
enable_chghost: true,
enable_echomessage: true,
enable_setname: true,
@ -205,7 +206,7 @@ Network.prototype.setIrcFrameworkOptions = function (client) {
this.irc.options.port = this.port;
this.irc.options.password = this.password;
this.irc.options.nick = this.nick;
this.irc.options.username = Helper.config.useHexIp
this.irc.options.username = Config.values.useHexIp
? Helper.ip2hex(client.config.browser.ip)
: this.username;
this.irc.options.gecos = this.realname;
@ -243,14 +244,14 @@ Network.prototype.setIrcFrameworkOptions = function (client) {
Network.prototype.createWebIrc = function (client) {
if (
!Helper.config.webirc ||
!Object.prototype.hasOwnProperty.call(Helper.config.webirc, this.host)
!Config.values.webirc ||
!Object.prototype.hasOwnProperty.call(Config.values.webirc, this.host)
) {
return null;
}
const webircObject = {
password: Helper.config.webirc[this.host],
password: Config.values.webirc[this.host],
username: "thelounge",
address: client.config.browser.ip,
hostname: client.config.browser.hostname,
@ -263,9 +264,9 @@ Network.prototype.createWebIrc = function (client) {
};
}
if (typeof Helper.config.webirc[this.host] === "function") {
if (typeof Config.values.webirc[this.host] === "function") {
webircObject.password = null;
return Helper.config.webirc[this.host](webircObject, this);
return Config.values.webirc[this.host](webircObject, this);
}
return webircObject;
@ -462,7 +463,7 @@ Network.prototype.quit = function (quitMessage) {
// https://ircv3.net/specs/extensions/sts#rescheduling-expiry-on-disconnect
STSPolicies.refreshExpiration(this.host);
this.irc.quit(quitMessage || this.leaveMessage || Helper.config.leaveMessage);
this.irc.quit(quitMessage || this.leaveMessage || Config.values.leaveMessage);
};
Network.prototype.exportForEdit = function () {
@ -486,7 +487,7 @@ Network.prototype.exportForEdit = function () {
"proxyPassword",
];
if (!Helper.config.lockNetwork) {
if (!Config.values.lockNetwork) {
fieldsToReturn.push("host");
fieldsToReturn.push("port");
fieldsToReturn.push("tls");

View File

@ -1,12 +1,12 @@
"use strict";
const log = require("../../log");
const Helper = require("../../helper");
const Config = require("../../config");
const ldap = require("ldapjs");
const colors = require("chalk");
function ldapAuthCommon(user, bindDN, password, callback) {
const config = Helper.config;
const config = Config.values;
const ldapclient = ldap.createClient({
url: config.ldap.url,
@ -35,7 +35,7 @@ function simpleLdapAuth(user, password, callback) {
return callback(false);
}
const config = Helper.config;
const config = Config.values;
const userDN = user.replace(/([,\\/#+<>;"= ])/g, "\\$1");
const bindDN = `${config.ldap.primaryKey}=${userDN},${config.ldap.baseDN}`;
@ -53,7 +53,7 @@ function advancedLdapAuth(user, password, callback) {
return callback(false);
}
const config = Helper.config;
const config = Config.values;
const userDN = user.replace(/([,\\/#+<>;"= ])/g, "\\$1");
const ldapclient = ldap.createClient({
@ -132,7 +132,7 @@ function ldapAuth(manager, client, user, password, callback) {
let auth;
if ("baseDN" in Helper.config.ldap) {
if ("baseDN" in Config.values.ldap) {
auth = simpleLdapAuth;
} else {
auth = advancedLdapAuth;
@ -147,7 +147,7 @@ function ldapAuth(manager, client, user, password, callback) {
*/
function advancedLdapLoadUsers(users, callbackLoadUser) {
const config = Helper.config;
const config = Config.values;
const ldapclient = ldap.createClient({
url: config.ldap.url,
@ -212,7 +212,7 @@ function advancedLdapLoadUsers(users, callbackLoadUser) {
}
function ldapLoadUsers(users, callbackLoadUser) {
if ("baseDN" in Helper.config.ldap) {
if ("baseDN" in Config.values.ldap) {
// simple LDAP case can't test for user existence without access to the
// user's unhashed password, so indicate need to fallback to default
// loadUser behaviour by returning false
@ -223,7 +223,7 @@ function ldapLoadUsers(users, callbackLoadUser) {
}
function isLdapEnabled() {
return !Helper.config.public && Helper.config.ldap.enable;
return !Config.values.public && Config.values.ldap.enable;
}
module.exports = {

View File

@ -5,7 +5,7 @@ const fs = require("fs");
const crypto = require("crypto");
const {md, pki} = require("node-forge");
const log = require("../log");
const Helper = require("../helper");
const Config = require("../config");
module.exports = {
get,
@ -13,11 +13,11 @@ module.exports = {
};
function get(uuid) {
if (Helper.config.public) {
if (Config.values.public) {
return null;
}
const folderPath = Helper.getClientCertificatesPath();
const folderPath = Config.getClientCertificatesPath();
const paths = getPaths(folderPath, uuid);
if (!fs.existsSync(paths.privateKeyPath) || !fs.existsSync(paths.certificatePath)) {
@ -37,11 +37,11 @@ function get(uuid) {
}
function remove(uuid) {
if (Helper.config.public) {
if (Config.values.public) {
return null;
}
const paths = getPaths(Helper.getClientCertificatesPath(), uuid);
const paths = getPaths(Config.getClientCertificatesPath(), uuid);
try {
if (fs.existsSync(paths.privateKeyPath)) {

View File

@ -2,7 +2,7 @@
const Msg = require("../../models/msg");
const Chan = require("../../models/chan");
const Helper = require("../../helper");
const Config = require("../../config");
exports.commands = ["close", "leave", "part"];
exports.allowDisconnected = true;
@ -42,7 +42,7 @@ exports.input = function (network, chan, cmd, args) {
) {
this.part(network, target);
} else {
const partMessage = args.join(" ") || network.leaveMessage || Helper.config.leaveMessage;
const partMessage = args.join(" ") || network.leaveMessage || Config.values.leaveMessage;
network.irc.part(target.name, partMessage);
}

View File

@ -5,6 +5,7 @@ const log = require("../../log");
const Msg = require("../../models/msg");
const Chan = require("../../models/chan");
const Helper = require("../../helper");
const Config = require("../../config");
module.exports = function (irc, network) {
const client = this;
@ -93,7 +94,7 @@ module.exports = function (irc, network) {
irc.on("raw socket connected", function (socket) {
let ident = client.name || network.username;
if (Helper.config.useHexIp) {
if (Config.values.useHexIp) {
ident = Helper.ip2hex(client.config.browser.ip);
}
@ -138,7 +139,7 @@ module.exports = function (irc, network) {
sendStatus();
});
if (Helper.config.debug.ircFramework) {
if (Config.values.debug.ircFramework) {
irc.on("debug", function (message) {
log.debug(
`[${client.name} (${client.id}) on ${network.name} (${network.uuid}]`,
@ -147,7 +148,7 @@ module.exports = function (irc, network) {
});
}
if (Helper.config.debug.raw) {
if (Config.values.debug.raw) {
irc.on("raw", function (message) {
network.channels[0].pushMessage(
client,

View File

@ -1,7 +1,7 @@
"use strict";
const Msg = require("../../models/msg");
const Helper = require("../../helper");
const Config = require("../../config");
module.exports = function (irc, network) {
const client = this;
@ -36,7 +36,7 @@ module.exports = function (irc, network) {
irc.on("nick in use", function (data) {
let message = data.nick + ": " + (data.reason || "Nickname is already in use.");
if (irc.connection.registered === false && !Helper.config.public) {
if (irc.connection.registered === false && !Config.values.public) {
message += " An attempt to use it will be made when this nick quits.";
// Clients usually get nick in use on connect when reconnecting to a network
@ -81,7 +81,7 @@ module.exports = function (irc, network) {
lobby.pushMessage(client, msg, true);
if (irc.connection.registered === false) {
irc.changeNick(Helper.getDefaultNick());
irc.changeNick(Config.getDefaultNick());
}
client.emit("nick", {

View File

@ -4,7 +4,7 @@ const cheerio = require("cheerio");
const got = require("got");
const URL = require("url").URL;
const mime = require("mime-types");
const Helper = require("../../helper");
const Config = require("../../config");
const {findLinksWithSchema} = require("../../../client/js/helpers/ircmessageparser/findLinks");
const storage = require("../storage");
const currentFetchPromises = new Map();
@ -13,7 +13,7 @@ const mediaTypeRegex = /^(audio|video)\/.+/;
const log = require("../../log");
module.exports = function (client, chan, msg, cleanText) {
if (!Helper.config.prefetch) {
if (!Config.values.prefetch) {
return;
}
@ -90,7 +90,7 @@ function parseHtml(preview, res, client) {
preview.body = preview.body.substr(0, 300);
}
if (!Helper.config.prefetchStorage && Helper.config.disableMediaPreview) {
if (!Config.values.prefetchStorage && Config.values.disableMediaPreview) {
resolve(res);
return;
}
@ -113,7 +113,7 @@ function parseHtml(preview, res, client) {
if (
resThumb !== null &&
imageTypeRegex.test(resThumb.type) &&
resThumb.size <= Helper.config.prefetchMaxImageSize * 1024
resThumb.size <= Config.values.prefetchMaxImageSize * 1024
) {
preview.thumbActualUrl = thumb;
}
@ -130,7 +130,7 @@ function parseHtml(preview, res, client) {
function parseHtmlMedia($, preview, client) {
return new Promise((resolve, reject) => {
if (Helper.config.disableMediaPreview) {
if (Config.values.disableMediaPreview) {
reject();
return;
}
@ -226,14 +226,14 @@ function parse(msg, chan, preview, res, client) {
case "image/jxl":
case "image/webp":
case "image/avif":
if (!Helper.config.prefetchStorage && Helper.config.disableMediaPreview) {
if (!Config.values.prefetchStorage && Config.values.disableMediaPreview) {
return removePreview(msg, preview);
}
if (res.size > Helper.config.prefetchMaxImageSize * 1024) {
if (res.size > Config.values.prefetchMaxImageSize * 1024) {
preview.type = "error";
preview.error = "image-too-big";
preview.maxSize = Helper.config.prefetchMaxImageSize * 1024;
preview.maxSize = Config.values.prefetchMaxImageSize * 1024;
} else {
preview.type = "image";
preview.thumbActualUrl = preview.link;
@ -259,7 +259,7 @@ function parse(msg, chan, preview, res, client) {
break;
}
if (Helper.config.disableMediaPreview) {
if (Config.values.disableMediaPreview) {
return removePreview(msg, preview);
}
@ -276,7 +276,7 @@ function parse(msg, chan, preview, res, client) {
break;
}
if (Helper.config.disableMediaPreview) {
if (Config.values.disableMediaPreview) {
return removePreview(msg, preview);
}
@ -301,7 +301,7 @@ function handlePreview(client, chan, msg, preview, res) {
const thumb = preview.thumbActualUrl || "";
delete preview.thumbActualUrl;
if (!thumb.length || !Helper.config.prefetchStorage) {
if (!thumb.length || !Config.values.prefetchStorage) {
preview.thumb = thumb;
return emitPreview(client, chan, msg, preview);
}
@ -382,7 +382,7 @@ function fetch(uri, headers) {
return promise;
}
const prefetchTimeout = Helper.config.prefetchTimeout;
const prefetchTimeout = Config.values.prefetchTimeout;
if (!prefetchTimeout) {
log.warn(
@ -394,7 +394,7 @@ function fetch(uri, headers) {
let buffer = Buffer.from("");
let contentLength = 0;
let contentType;
let limit = Helper.config.prefetchMaxImageSize * 1024;
let limit = Config.values.prefetchMaxImageSize * 1024;
try {
const gotStream = got.stream(uri, {
@ -415,7 +415,7 @@ function fetch(uri, headers) {
// response is an image
// if Content-Length header reports a size exceeding the prefetch limit, abort fetch
// and if file is not to be stored we don't need to download further either
if (contentLength > limit || !Helper.config.prefetchStorage) {
if (contentLength > limit || !Config.values.prefetchStorage) {
gotStream.destroy();
}
} else if (mediaTypeRegex.test(contentType)) {
@ -426,8 +426,8 @@ function fetch(uri, headers) {
// twitter.com sends opengraph meta tags within ~20kb of data for individual tweets, the default is set to 50.
// for sites like Youtube the og tags are in the first 300K and hence this is configurable by the admin
limit =
"prefetchMaxSearchSize" in Helper.config
? Helper.config.prefetchMaxSearchSize * 1024
"prefetchMaxSearchSize" in Config.values
? Config.values.prefetchMaxSearchSize * 1024
: // set to the previous size if config option is unset
50 * 1024;
}

View File

@ -3,7 +3,7 @@
const log = require("../../log");
const path = require("path");
const fs = require("fs");
const Helper = require("../../helper");
const Config = require("../../config");
const Msg = require("../../models/msg");
let sqlite3;
@ -11,7 +11,7 @@ let sqlite3;
try {
sqlite3 = require("sqlite3");
} catch (e) {
Helper.config.messageStorage = Helper.config.messageStorage.filter((item) => item !== "sqlite");
Config.values.messageStorage = Config.values.messageStorage.filter((item) => item !== "sqlite");
log.error(
"Unable to load sqlite3 module. See https://github.com/mapbox/node-sqlite3/wiki/Binaries"
@ -35,7 +35,7 @@ class MessageStorage {
}
enable() {
const logsPath = Helper.getUserLogsPath();
const logsPath = Config.getUserLogsPath();
const sqlitePath = path.join(logsPath, `${this.client.name}.sqlite3`);
try {
@ -165,12 +165,12 @@ class MessageStorage {
* @param Chan channel - Channel object for which to load messages for
*/
getMessages(network, channel) {
if (!this.isEnabled || Helper.config.maxHistory === 0) {
if (!this.isEnabled || Config.values.maxHistory === 0) {
return Promise.resolve([]);
}
// If unlimited history is specified, load 100k messages
const limit = Helper.config.maxHistory < 0 ? 100000 : Helper.config.maxHistory;
const limit = Config.values.maxHistory < 0 ? 100000 : Config.values.maxHistory;
return new Promise((resolve, reject) => {
this.database.serialize(() =>

View File

@ -4,7 +4,7 @@ const log = require("../../log");
const fs = require("fs");
const path = require("path");
const filenamify = require("filenamify");
const Helper = require("../../helper");
const Config = require("../../config");
const Msg = require("../../models/msg");
class TextFileMessageStorage {
@ -31,7 +31,7 @@ class TextFileMessageStorage {
}
const logPath = path.join(
Helper.getUserLogsPath(),
Config.getUserLogsPath(),
this.client.name,
TextFileMessageStorage.getNetworkFolderName(network)
);
@ -117,7 +117,7 @@ class TextFileMessageStorage {
}
const logPath = path.join(
Helper.getUserLogsPath(),
Config.getUserLogsPath(),
this.client.name,
TextFileMessageStorage.getNetworkFolderName(network),
TextFileMessageStorage.getChannelFileName(channel)

View File

@ -6,6 +6,7 @@ const colors = require("chalk");
const path = require("path");
const semver = require("semver");
const Helper = require("../../helper");
const Config = require("../../config");
const themes = require("./themes");
const packageMap = new Map();
const inputs = require("../inputs");
@ -45,7 +46,7 @@ const packageApis = function (packageInfo) {
client.inputLine({target: targetId, text: command}),
},
Config: {
getConfig: () => Helper.config,
getConfig: () => Config.values,
getPersistentStorageDir: getPersistentStorageDir.bind(this, packageInfo.packageName),
},
Logger: {
@ -89,7 +90,7 @@ function getEnabledPackages(packageJson) {
}
function getPersistentStorageDir(packageName) {
const dir = path.join(Helper.getPackagesPath(), packageName);
const dir = path.join(Config.getPackagesPath(), packageName);
fs.mkdirSync(dir, {recursive: true}); // we don't care if it already exists or not
return dir;
}
@ -99,7 +100,7 @@ function loadPackage(packageName) {
let packageFile;
try {
const packagePath = Helper.getPackageModulePath(packageName);
const packagePath = Config.getPackageModulePath(packageName);
packageInfo = JSON.parse(fs.readFileSync(path.join(packagePath, "package.json"), "utf-8"));
@ -155,7 +156,7 @@ function loadPackage(packageName) {
}
function loadPackages() {
const packageJson = path.join(Helper.getPackagesPath(), "package.json");
const packageJson = path.join(Config.getPackagesPath(), "package.json");
const packages = getEnabledPackages(packageJson);
packages.forEach(loadPackage);
@ -193,7 +194,7 @@ async function outdated(cacheTimeout = TIME_TO_LIVE) {
}
// Get paths to the location of packages directory
const packagesPath = Helper.getPackagesPath();
const packagesPath = Config.getPackagesPath();
const packagesConfig = path.join(packagesPath, "package.json");
const packagesList = JSON.parse(fs.readFileSync(packagesConfig, "utf-8")).dependencies;
const argsList = [

View File

@ -1,7 +1,7 @@
"use strict";
const fs = require("fs");
const Helper = require("../../helper");
const Config = require("../../config");
const path = require("path");
const _ = require("lodash");
const themes = new Map();
@ -61,7 +61,7 @@ function makePackageThemeObject(moduleName, module) {
}
const themeColor = /^#[0-9A-F]{6}$/i.test(module.themeColor) ? module.themeColor : null;
const modulePath = Helper.getPackageModulePath(moduleName);
const modulePath = Config.getPackageModulePath(moduleName);
return {
displayName: module.name || moduleName,
filename: path.join(modulePath, module.css),

View File

@ -4,7 +4,7 @@ const log = require("../log");
const fs = require("fs");
const path = require("path");
const crypto = require("crypto");
const helper = require("../helper");
const Config = require("../config");
class Storage {
constructor() {
@ -16,7 +16,7 @@ class Storage {
// Deletes directory contents if the directory is not empty.
// If the directory does not exist, it is created.
const dir = helper.getStoragePath();
const dir = Config.getStoragePath();
let items;
try {
@ -44,7 +44,7 @@ class Storage {
this.references.delete(url);
// Drop "storage/" from url and join it with full storage path
const filePath = path.join(helper.getStoragePath(), url.substring(8));
const filePath = path.join(Config.getStoragePath(), url.substring(8));
fs.unlink(filePath, (err) => {
if (err) {
@ -57,7 +57,7 @@ class Storage {
const hash = crypto.createHash("sha256").update(data).digest("hex");
const a = hash.substring(0, 2);
const b = hash.substring(2, 4);
const folder = path.join(helper.getStoragePath(), a, b);
const folder = path.join(Config.getStoragePath(), a, b);
const filePath = path.join(folder, `${hash.substring(4)}.${extension}`);
const url = `storage/${a}/${b}/${hash.substring(4)}.${extension}`;

View File

@ -4,11 +4,11 @@ const _ = require("lodash");
const fs = require("fs");
const path = require("path");
const log = require("../log");
const Helper = require("../helper");
const Config = require("../config");
class STSPolicies {
constructor() {
this.stsFile = path.join(Helper.getHomePath(), "sts-policies.json");
this.stsFile = path.join(Config.getHomePath(), "sts-policies.json");
this.policies = new Map();
this.refresh = _.debounce(this.saveFile, 10000, {maxWait: 60000});

View File

@ -1,6 +1,6 @@
"use strict";
const Helper = require("../helper");
const Config = require("../config");
const busboy = require("@fastify/busboy");
const {v4: uuidv4} = require("uuid");
const path = require("path");
@ -86,7 +86,7 @@ class Uploader {
}
const folder = name.substring(0, 2);
const uploadPath = Helper.getFileUploadPath();
const uploadPath = Config.getFileUploadPath();
const filePath = path.join(uploadPath, folder, name);
let detectedMimeType = await Uploader.getFileType(filePath);
@ -207,7 +207,7 @@ class Uploader {
// that already exists on disk
do {
randomName = crypto.randomBytes(8).toString("hex");
destDir = path.join(Helper.getFileUploadPath(), randomName.substring(0, 2));
destDir = path.join(Config.getFileUploadPath(), randomName.substring(0, 2));
destPath = path.join(destDir, randomName);
} while (fs.existsSync(destPath));
@ -228,8 +228,8 @@ class Uploader {
busboyInstance.on("file", (fieldname, fileStream, filename) => {
uploadUrl = `${randomName}/${encodeURIComponent(filename)}`;
if (Helper.config.fileUpload.baseUrl) {
uploadUrl = new URL(uploadUrl, Helper.config.fileUpload.baseUrl).toString();
if (Config.values.fileUpload.baseUrl) {
uploadUrl = new URL(uploadUrl, Config.values.fileUpload.baseUrl).toString();
} else {
uploadUrl = `uploads/${uploadUrl}`;
}
@ -266,7 +266,7 @@ class Uploader {
}
static getMaxFileSize() {
const configOption = Helper.config.fileUpload.maxFileSize;
const configOption = Config.values.fileUpload.maxFileSize;
// Busboy uses Infinity to allow unlimited file size
if (configOption < 1) {

View File

@ -5,11 +5,11 @@ const log = require("../log");
const fs = require("fs");
const path = require("path");
const WebPushAPI = require("web-push");
const Helper = require("../helper");
const Config = require("../config");
class WebPush {
constructor() {
const vapidPath = path.join(Helper.getHomePath(), "vapid.json");
const vapidPath = path.join(Config.getHomePath(), "vapid.json");
let vapidStat = undefined;

View File

@ -12,6 +12,7 @@ const io = require("socket.io");
const dns = require("dns");
const Uploader = require("./plugins/uploader");
const Helper = require("./helper");
const Config = require("./config");
const colors = require("chalk");
const net = require("net");
const Identification = require("./identification");
@ -35,7 +36,7 @@ module.exports = function (options = {}) {
(Node.js ${colors.green(process.versions.node)} on ${colors.green(process.platform)} ${
process.arch
})`);
log.info(`Configuration file: ${colors.green(Helper.getConfigPath())}`);
log.info(`Configuration file: ${colors.green(Config.getConfigPath())}`);
const staticOptions = {
redirect: false,
@ -57,9 +58,9 @@ module.exports = function (options = {}) {
.get("/js/bundle.js.map", forceNoCacheRequest)
.get("/css/style.css.map", forceNoCacheRequest)
.use(express.static(path.join(__dirname, "..", "public"), staticOptions))
.use("/storage/", express.static(Helper.getStoragePath(), staticOptions));
.use("/storage/", express.static(Config.getStoragePath(), staticOptions));
if (Helper.config.fileUpload.enable) {
if (Config.values.fileUpload.enable) {
Uploader.router(app);
}
@ -87,25 +88,25 @@ module.exports = function (options = {}) {
return res.status(404).send("Not found");
}
const packagePath = Helper.getPackageModulePath(packageName);
const packagePath = Config.getPackageModulePath(packageName);
return res.sendFile(path.join(packagePath, fileName));
});
let server = null;
if (Helper.config.public && (Helper.config.ldap || {}).enable) {
if (Config.values.public && (Config.values.ldap || {}).enable) {
log.warn(
"Server is public and set to use LDAP. Set to private mode if trying to use LDAP authentication."
);
}
if (!Helper.config.https.enable) {
if (!Config.values.https.enable) {
server = require("http");
server = server.createServer(app);
} else {
const keyPath = Helper.expandHome(Helper.config.https.key);
const certPath = Helper.expandHome(Helper.config.https.certificate);
const caPath = Helper.expandHome(Helper.config.https.ca);
const keyPath = Helper.expandHome(Config.values.https.key);
const certPath = Helper.expandHome(Config.values.https.certificate);
const caPath = Helper.expandHome(Config.values.https.ca);
if (!keyPath.length || !fs.existsSync(keyPath)) {
log.error("Path to SSL key is invalid. Stopping server...");
@ -135,12 +136,12 @@ module.exports = function (options = {}) {
let listenParams;
if (typeof Helper.config.host === "string" && Helper.config.host.startsWith("unix:")) {
listenParams = Helper.config.host.replace(/^unix:/, "");
if (typeof Config.values.host === "string" && Config.values.host.startsWith("unix:")) {
listenParams = Config.values.host.replace(/^unix:/, "");
} else {
listenParams = {
port: Helper.config.port,
host: Helper.config.host,
port: Config.values.port,
host: Config.values.host,
};
}
@ -150,7 +151,7 @@ module.exports = function (options = {}) {
if (typeof listenParams === "string") {
log.info("Available on socket " + colors.green(listenParams));
} else {
const protocol = Helper.config.https.enable ? "https" : "http";
const protocol = Config.values.https.enable ? "https" : "http";
const address = server.address();
if (address.family === "IPv6") {
@ -160,7 +161,7 @@ module.exports = function (options = {}) {
log.info(
"Available at " +
colors.green(`${protocol}://${address.address}:${address.port}/`) +
` in ${colors.bold(Helper.config.public ? "public" : "private")} mode`
` in ${colors.bold(Config.values.public ? "public" : "private")} mode`
);
}
@ -168,14 +169,14 @@ module.exports = function (options = {}) {
wsEngine: require("ws").Server,
cookie: false,
serveClient: false,
transports: Helper.config.transports,
transports: Config.values.transports,
pingTimeout: 60000,
});
sockets.on("connect", (socket) => {
socket.on("error", (err) => log.error(`io socket error: ${err}`));
if (Helper.config.public) {
if (Config.values.public) {
performAuthentication.call(socket, {});
} else {
socket.on("auth:perform", performAuthentication);
@ -186,17 +187,17 @@ module.exports = function (options = {}) {
manager = new ClientManager();
packages.loadPackages();
const defaultTheme = themes.getByName(Helper.config.theme);
const defaultTheme = themes.getByName(Config.values.theme);
if (defaultTheme === undefined) {
log.warn(
`The specified default theme "${colors.red(
Helper.config.theme
Config.values.theme
)}" does not exist, verify your config.`
);
Helper.config.theme = "default";
Config.values.theme = "default";
} else if (defaultTheme.themeColor) {
Helper.config.themeColor = defaultTheme.themeColor;
Config.values.themeColor = defaultTheme.themeColor;
}
new Identification((identHandler, err) => {
@ -221,7 +222,7 @@ module.exports = function (options = {}) {
// Close all client and IRC connections
manager.clients.forEach((client) => client.quit());
if (Helper.config.prefetchStorage) {
if (Config.values.prefetchStorage) {
log.info("Clearing prefetch storage folder, this might take a while...");
require("./plugins/storage").emptyDir();
@ -241,7 +242,7 @@ module.exports = function (options = {}) {
process.on("SIGTERM", exitGracefully);
// Clear storage folder after server starts successfully
if (Helper.config.prefetchStorage) {
if (Config.values.prefetchStorage) {
require("./plugins/storage").emptyDir();
}
@ -265,7 +266,7 @@ function getClientLanguage(socket) {
function getClientIp(socket) {
let ip = socket.handshake.address || "127.0.0.1";
if (Helper.config.reverseProxy) {
if (Config.values.reverseProxy) {
const forwarded = (socket.handshake.headers["x-forwarded-for"] || "")
.split(/\s*,\s*/)
.filter(Boolean);
@ -281,7 +282,7 @@ function getClientIp(socket) {
function getClientSecure(socket) {
let secure = socket.handshake.secure;
if (Helper.config.reverseProxy && socket.handshake.headers["x-forwarded-proto"] === "https") {
if (Config.values.reverseProxy && socket.handshake.headers["x-forwarded-proto"] === "https") {
secure = true;
}
@ -310,7 +311,7 @@ function addSecurityHeaders(req, res, next) {
// If prefetch is enabled, but storage is not, we have to allow mixed content
// - https://user-images.githubusercontent.com is where we currently push our changelog screenshots
// - data: is required for the HTML5 video player
if (Helper.config.prefetchStorage || !Helper.config.prefetch) {
if (Config.values.prefetchStorage || !Config.values.prefetch) {
policies.push("img-src 'self' data: https://user-images.githubusercontent.com");
policies.unshift("block-all-mixed-content");
} else {
@ -367,7 +368,7 @@ function initializeClient(socket, client, token, lastMessage, openChannel) {
openChannel = client.lastActiveChannel;
}
if (Helper.config.fileUpload.enable) {
if (Config.values.fileUpload.enable) {
new Uploader(socket);
}
@ -436,7 +437,7 @@ function initializeClient(socket, client, token, lastMessage, openChannel) {
}
});
if (!Helper.config.public && !Helper.config.ldap.enable) {
if (!Config.values.public && !Config.values.ldap.enable) {
socket.on("change-password", (data) => {
if (_.isPlainObject(data)) {
const old = data.old_password;
@ -510,7 +511,7 @@ function initializeClient(socket, client, token, lastMessage, openChannel) {
// In public mode only one client can be connected,
// so there's no need to handle msg:preview:toggle
if (!Helper.config.public) {
if (!Config.values.public) {
socket.on("msg:preview:toggle", (data) => {
if (_.isPlainObject(data)) {
return;
@ -571,7 +572,7 @@ function initializeClient(socket, client, token, lastMessage, openChannel) {
client.mentions = [];
});
if (!Helper.config.public) {
if (!Config.values.public) {
socket.on("push:register", (subscription) => {
if (!Object.prototype.hasOwnProperty.call(client.config.sessions, token)) {
return;
@ -614,7 +615,7 @@ function initializeClient(socket, client, token, lastMessage, openChannel) {
socket.on("sessions:get", sendSessionList);
if (!Helper.config.public) {
if (!Config.values.public) {
socket.on("setting:set", (newSetting) => {
if (!_.isPlainObject(newSetting)) {
return;
@ -739,7 +740,7 @@ function initializeClient(socket, client, token, lastMessage, openChannel) {
socket.emit("commands", inputs.getCommands());
};
if (Helper.config.public) {
if (Config.values.public) {
sendInitEvent(null);
} else if (token === null) {
client.generateToken((newToken) => {
@ -757,16 +758,16 @@ function initializeClient(socket, client, token, lastMessage, openChannel) {
}
function getClientConfiguration() {
const config = _.pick(Helper.config, ["public", "lockNetwork", "useHexIp", "prefetch"]);
const config = _.pick(Config.values, ["public", "lockNetwork", "useHexIp", "prefetch"]);
config.fileUpload = Helper.config.fileUpload.enable;
config.ldapEnabled = Helper.config.ldap.enable;
config.fileUpload = Config.values.fileUpload.enable;
config.ldapEnabled = Config.values.ldap.enable;
if (!config.lockNetwork) {
config.defaults = _.clone(Helper.config.defaults);
config.defaults = _.clone(Config.values.defaults);
} else {
// Only send defaults that are visible on the client
config.defaults = _.pick(Helper.config.defaults, [
config.defaults = _.pick(Config.values.defaults, [
"name",
"nick",
"username",
@ -781,8 +782,8 @@ function getClientConfiguration() {
config.version = pkg.version;
config.gitCommit = Helper.getGitCommit();
config.themes = themes.getAll();
config.defaultTheme = Helper.config.theme;
config.defaults.nick = Helper.getDefaultNick();
config.defaultTheme = Config.values.theme;
config.defaults.nick = Config.getDefaultNick();
config.defaults.sasl = "";
config.defaults.saslAccount = "";
config.defaults.saslPassword = "";
@ -795,7 +796,7 @@ function getClientConfiguration() {
}
function getServerConfiguration() {
const config = _.clone(Helper.config);
const config = _.clone(Config.values);
config.stylesheets = packages.getStylesheets();
@ -833,7 +834,7 @@ function performAuthentication(data) {
};
// If webirc is enabled perform reverse dns lookup
if (Helper.config.webirc === null) {
if (Config.values.webirc === null) {
return finalInit();
}
@ -844,7 +845,7 @@ function performAuthentication(data) {
});
};
if (Helper.config.public) {
if (Config.values.public) {
client = new Client(manager);
manager.clients.push(client);

View File

@ -3,7 +3,7 @@
const fs = require("fs");
const home = require("path").join(__dirname, ".thelounge");
require("../../src/helper").setHome(home);
require("../../src/config").setHome(home);
const STSPolicies = require("../../src/plugins/sts"); // Must be imported *after* setHome

View File

@ -5,7 +5,7 @@ const Chan = require("../../src/models/chan");
const Msg = require("../../src/models/msg");
const User = require("../../src/models/user");
const Network = require("../../src/models/network");
const Helper = require("../../src/helper");
const Config = require("../../src/config");
const STSPolicies = require("../../src/plugins/sts");
const ClientCertificate = require("../../src/plugins/clientCertificate");
@ -126,7 +126,7 @@ describe("Network", function () {
describe("#validate()", function () {
it("should set correct defaults", function () {
Helper.config.defaults.nick = "";
Config.values.defaults.nick = "";
const network = new Network({
host: "localhost",
@ -147,10 +147,10 @@ describe("Network", function () {
});
it("should enforce lockNetwork", function () {
Helper.config.lockNetwork = true;
Config.values.lockNetwork = true;
// Make sure we lock in private mode
Helper.config.public = false;
Config.values.public = false;
const network = new Network({
host: "",
@ -165,7 +165,7 @@ describe("Network", function () {
expect(network.rejectUnauthorized).to.be.true;
// Make sure we lock in public mode (also resets public=true for other tests)
Helper.config.public = true;
Config.values.public = true;
const network2 = new Network({
host: "some.fake.tld",
@ -173,7 +173,7 @@ describe("Network", function () {
expect(network2.validate()).to.be.true;
expect(network2.host).to.equal("irc.example.com");
Helper.config.lockNetwork = false;
Config.values.lockNetwork = false;
});
it("should apply STS policies iff they match", function () {
@ -204,7 +204,7 @@ describe("Network", function () {
});
it("should not remove client certs if TLS is disabled", function () {
Helper.config.public = false;
Config.values.public = false;
const client = {idMsg: 1, emit() {}, messageStorage: []};
@ -221,11 +221,11 @@ describe("Network", function () {
expect(ClientCertificate.get(network.uuid)).to.deep.equal(client_cert); // Should be unchanged
ClientCertificate.remove(network.uuid);
Helper.config.public = true;
Config.values.public = true;
});
it("should not remove client certs if there is a STS policy", function () {
Helper.config.public = false;
Config.values.public = false;
const client = {idMsg: 1, emit() {}, messageStorage: []};
STSPolicies.update("irc.example.com", 7000, 3600);
@ -243,13 +243,13 @@ describe("Network", function () {
expect(ClientCertificate.get(network.uuid)).to.deep.equal(client_cert); // Should be unchanged
ClientCertificate.remove(network.uuid);
Helper.config.public = true;
Config.values.public = true;
});
});
describe("#createIrcFramework(client)", function () {
it("should generate and use a client certificate when using SASL external", function () {
Helper.config.public = false;
Config.values.public = false;
const client = {idMsg: 1, emit() {}};
STSPolicies.update("irc.example.com", 7000, 3600);
@ -265,7 +265,7 @@ describe("Network", function () {
expect(network.irc.options.client_certificate).to.not.be.null;
ClientCertificate.remove(network.uuid);
Helper.config.public = true;
Config.values.public = true;
});
});

View File

@ -2,7 +2,7 @@
const log = require("../../../src/log");
const ldapAuth = require("../../../src/plugins/auth/ldap");
const Helper = require("../../../src/helper");
const Config = require("../../../src/config");
const ldap = require("ldapjs");
const expect = require("chai").expect;
const stub = require("sinon").stub;
@ -23,7 +23,7 @@ function normalizeDN(dn) {
function startLdapServer(callback) {
const server = ldap.createServer();
const searchConf = Helper.config.ldap.searchDN;
const searchConf = Config.values.ldap.searchDN;
const userDN = primaryKey + "=" + user + "," + baseDN;
// Two users are authorized: john doe and the root user in case of
@ -143,34 +143,34 @@ describe("LDAP authentication plugin", function () {
});
beforeEach(function () {
Helper.config.public = false;
Helper.config.ldap.enable = true;
Helper.config.ldap.url = "ldap://localhost:" + String(serverPort);
Helper.config.ldap.primaryKey = primaryKey;
Config.values.public = false;
Config.values.ldap.enable = true;
Config.values.ldap.url = "ldap://localhost:" + String(serverPort);
Config.values.ldap.primaryKey = primaryKey;
});
afterEach(function () {
Helper.config.public = true;
Helper.config.ldap.enable = false;
Config.values.public = true;
Config.values.ldap.enable = false;
});
describe("LDAP authentication availability", function () {
it("checks that the configuration is correctly tied to isEnabled()", function () {
Helper.config.ldap.enable = true;
Config.values.ldap.enable = true;
expect(ldapAuth.isEnabled()).to.equal(true);
Helper.config.ldap.enable = false;
Config.values.ldap.enable = false;
expect(ldapAuth.isEnabled()).to.equal(false);
});
});
describe("Simple LDAP authentication (predefined DN pattern)", function () {
Helper.config.ldap.baseDN = baseDN;
Config.values.ldap.baseDN = baseDN;
testLdapAuth();
});
describe("Advanced LDAP authentication (DN found by a prior search query)", function () {
delete Helper.config.ldap.baseDN;
delete Config.values.ldap.baseDN;
testLdapAuth();
});
});

View File

@ -4,18 +4,18 @@ const fs = require("fs");
const path = require("path");
const {expect} = require("chai");
const ClientCertificate = require("../../src/plugins/clientCertificate");
const Helper = require("../../src/helper");
const Config = require("../../src/config");
describe("ClientCertificate", function () {
it("should not generate a client certificate in public mode", function () {
Helper.config.public = true;
Config.values.public = true;
const certificate = ClientCertificate.get("this-is-test-uuid");
expect(certificate).to.be.null;
});
it("should generate a client certificate", function () {
Helper.config.public = false;
Config.values.public = false;
const certificate = ClientCertificate.get("this-is-test-uuid");
expect(certificate.certificate).to.match(/^-----BEGIN CERTIFICATE-----/);
@ -25,18 +25,18 @@ describe("ClientCertificate", function () {
expect(certificate2.certificate).to.equal(certificate.certificate);
expect(certificate2.private_key).to.equal(certificate.private_key);
Helper.config.public = true;
Config.values.public = true;
});
it("should remove the client certificate files", function () {
Helper.config.public = false;
Config.values.public = false;
const privateKeyPath = path.join(
Helper.getClientCertificatesPath(),
Config.getClientCertificatesPath(),
`this-is-test-uuid.pem`
);
const certificatePath = path.join(
Helper.getClientCertificatesPath(),
Config.getClientCertificatesPath(),
`this-is-test-uuid.crt`
);
@ -48,6 +48,6 @@ describe("ClientCertificate", function () {
expect(fs.existsSync(privateKeyPath)).to.be.false;
expect(fs.existsSync(certificatePath)).to.be.false;
Helper.config.public = true;
Config.values.public = true;
});
});

View File

@ -3,7 +3,7 @@
const path = require("path");
const expect = require("chai").expect;
const util = require("../util");
const Helper = require("../../src/helper");
const Config = require("../../src/config");
const link = require("../../src/plugins/irc-events/link.js");
describe("Link plugin", function () {
@ -36,7 +36,7 @@ Vivamus bibendum vulputate tincidunt. Sed vitae ligula felis.`;
this.irc = util.createClient();
this.network = util.createNetwork();
Helper.config.prefetchStorage = false;
Config.values.prefetchStorage = false;
});
afterEach(function (done) {
@ -224,11 +224,11 @@ Vivamus bibendum vulputate tincidunt. Sed vitae ligula felis.`;
describe("test disableMediaPreview", function () {
beforeEach(function (done) {
Helper.config.disableMediaPreview = true;
Config.values.disableMediaPreview = true;
done();
});
afterEach(function (done) {
Helper.config.disableMediaPreview = false;
Config.values.disableMediaPreview = false;
done();
});
it("should ignore og:image if disableMediaPreview", function (done) {

View File

@ -5,7 +5,7 @@ const path = require("path");
const expect = require("chai").expect;
const util = require("../util");
const Msg = require("../../src/models/msg");
const Helper = require("../../src/helper");
const Config = require("../../src/config");
const MessageStorage = require("../../src/plugins/messageStorage/sqlite.js");
describe("SQLite Message Storage", function () {
@ -13,7 +13,7 @@ describe("SQLite Message Storage", function () {
this.timeout(util.isRunningOnCI() ? 25000 : 5000);
this.slow(300);
const expectedPath = path.join(Helper.getHomePath(), "logs", "testUser.sqlite3");
const expectedPath = path.join(Config.getHomePath(), "logs", "testUser.sqlite3");
let store;
before(function (done) {
@ -34,7 +34,7 @@ describe("SQLite Message Storage", function () {
// After tests run, remove the logs folder
// so we return to the clean state
fs.unlinkSync(expectedPath);
fs.rmdir(path.join(Helper.getHomePath(), "logs"), done);
fs.rmdir(path.join(Config.getHomePath(), "logs"), done);
});
it("should resolve an empty array when disabled", function () {
@ -127,10 +127,10 @@ describe("SQLite Message Storage", function () {
});
it("should retrieve latest LIMIT messages in order", function () {
const originalMaxHistory = Helper.config.maxHistory;
const originalMaxHistory = Config.values.maxHistory;
try {
Helper.config.maxHistory = 2;
Config.values.maxHistory = 2;
for (let i = 0; i < 200; ++i) {
store.index(
@ -150,15 +150,15 @@ describe("SQLite Message Storage", function () {
expect(messages.map((i) => i.text)).to.deep.equal(["msg 198", "msg 199"]);
});
} finally {
Helper.config.maxHistory = originalMaxHistory;
Config.values.maxHistory = originalMaxHistory;
}
});
it("should search messages", function () {
const originalMaxHistory = Helper.config.maxHistory;
const originalMaxHistory = Config.values.maxHistory;
try {
Helper.config.maxHistory = 2;
Config.values.maxHistory = 2;
return store
.search({
@ -177,7 +177,7 @@ describe("SQLite Message Storage", function () {
expect(messages.results.map((i) => i.text)).to.deep.equal(expectedMessages);
});
} finally {
Helper.config.maxHistory = originalMaxHistory;
Config.values.maxHistory = originalMaxHistory;
}
});
@ -193,10 +193,10 @@ describe("SQLite Message Storage", function () {
});
}
const originalMaxHistory = Helper.config.maxHistory;
const originalMaxHistory = Config.values.maxHistory;
try {
Helper.config.maxHistory = 3;
Config.values.maxHistory = 3;
store.index(
{uuid: "this-is-a-network-guid2"},
@ -239,7 +239,7 @@ describe("SQLite Message Storage", function () {
.then(() => assertResults("@", ["bar @ baz"]))
);
} finally {
Helper.config.maxHistory = originalMaxHistory;
Config.values.maxHistory = originalMaxHistory;
}
});

View File

@ -5,7 +5,7 @@ const path = require("path");
const crypto = require("crypto");
const expect = require("chai").expect;
const util = require("../util");
const Helper = require("../../src/helper");
const Config = require("../../src/config");
const storage = require("../../src/plugins/storage");
const link = require("../../src/plugins/irc-events/link.js");
@ -55,7 +55,7 @@ describe("Image storage", function () {
after(function (done) {
// After storage tests run, remove the remaining empty
// storage folder so we return to the clean state
const dir = Helper.getStoragePath();
const dir = Config.getStoragePath();
fs.rmdir(dir, done);
});
@ -63,11 +63,11 @@ describe("Image storage", function () {
this.irc = util.createClient();
this.network = util.createNetwork();
Helper.config.prefetchStorage = true;
Config.values.prefetchStorage = true;
});
afterEach(function () {
Helper.config.prefetchStorage = false;
Config.values.prefetchStorage = false;
});
it("should store the thumbnail", function (done) {
@ -135,7 +135,7 @@ describe("Image storage", function () {
});
it("should clear storage folder", function () {
const dir = Helper.getStoragePath();
const dir = Config.getStoragePath();
expect(fs.readdirSync(dir)).to.not.be.empty;
storage.emptyDir();

View File

@ -1,7 +1,7 @@
"use strict";
const log = require("../src/log");
const Helper = require("../src/helper");
const Config = require("../src/config");
const expect = require("chai").expect;
const stub = require("sinon").stub;
const got = require("got");
@ -28,7 +28,7 @@ describe("Server", function () {
changelog.checkForUpdates.restore();
});
const webURL = `http://${Helper.config.host}:${Helper.config.port}/`;
const webURL = `http://${Config.values.host}:${Config.values.port}/`;
describe("Express", () => {
it("should run a web server on " + webURL, async () => {
@ -84,7 +84,7 @@ describe("Server", function () {
nick: "test-user",
join: "#thelounge, #spam",
name: "Test Network",
host: Helper.config.host,
host: Config.values.host,
port: 6667,
});
});

View File

@ -3,7 +3,7 @@
const log = require("../../src/log");
const expect = require("chai").expect;
const stub = require("sinon").stub;
const mergeConfig = require("../../src/helper").mergeConfig;
const Config = require("../../src/config");
const TestUtil = require("../util");
describe("mergeConfig", function () {
@ -13,7 +13,7 @@ describe("mergeConfig", function () {
};
expect(
mergeConfig(config, {
Config._merge_config_objects(config, {
ip: "overridden",
})
).to.deep.equal({
@ -27,7 +27,7 @@ describe("mergeConfig", function () {
it("should merge new properties", function () {
expect(
mergeConfig(
Config._merge_config_objects(
{
ip: "default",
newProp: "this should appear too",
@ -44,7 +44,7 @@ describe("mergeConfig", function () {
it("should extend objects", function () {
expect(
mergeConfig(
Config._merge_config_objects(
{
tlsOptions: {},
},
@ -68,7 +68,7 @@ describe("mergeConfig", function () {
stub(log, "warn").callsFake(TestUtil.sanitizeLog((str) => (warning += str)));
expect(
mergeConfig(
Config._merge_config_objects(
{
optionOne: 123,
},
@ -88,7 +88,7 @@ describe("mergeConfig", function () {
it("should not warn for unknown second level keys", function () {
expect(
mergeConfig(
Config._merge_config_objects(
{
optionOne: {
subOne: 123,
@ -111,7 +111,7 @@ describe("mergeConfig", function () {
it("should allow changing nulls", function () {
expect(
mergeConfig(
Config._merge_config_objects(
{
oidentd: null,
},
@ -126,7 +126,7 @@ describe("mergeConfig", function () {
it("should allow changing nulls with objects", function () {
expect(
mergeConfig(
Config._merge_config_objects(
{
webirc: null,
},
@ -149,7 +149,7 @@ describe("mergeConfig", function () {
const callbackFunction = () => ({});
expect(
mergeConfig(
Config._merge_config_objects(
{
webirc: null,
},
@ -168,7 +168,7 @@ describe("mergeConfig", function () {
it("should keep new properties inside of objects", function () {
expect(
mergeConfig(
Config._merge_config_objects(
{
nestedOnce: {
ip: "default",
@ -206,7 +206,7 @@ describe("mergeConfig", function () {
it("should not merge arrays", function () {
expect(
mergeConfig(
Config._merge_config_objects(
{
test: ["sqlite", "text"],
},
@ -219,7 +219,7 @@ describe("mergeConfig", function () {
});
expect(
mergeConfig(
Config._merge_config_objects(
{
test: ["sqlite", "text"],
},
@ -234,7 +234,7 @@ describe("mergeConfig", function () {
it("should change order in arrays", function () {
expect(
mergeConfig(
Config._merge_config_objects(
{
test: ["sqlite", "text"],
},
@ -251,7 +251,7 @@ describe("mergeConfig", function () {
stub(log, "warn");
expect(
mergeConfig(
Config._merge_config_objects(
{
shouldBeObject: {
thing: "yes",
@ -268,7 +268,7 @@ describe("mergeConfig", function () {
});
expect(
mergeConfig(
Config._merge_config_objects(
{
shouldBeString: "string",
},