diff --git a/src/clientManager.js b/src/clientManager.js index b882fff8..c5fda846 100644 --- a/src/clientManager.js +++ b/src/clientManager.js @@ -43,7 +43,7 @@ ClientManager.prototype.autoloadUsers = function() { users.forEach((name) => this.loadUser(name)); - fs.watch(Helper.USERS_PATH, _.debounce(() => { + fs.watch(Helper.getUsersPath(), _.debounce(() => { const loaded = this.clients.map((c) => c.name); const updatedUsers = this.getUsers(); @@ -96,7 +96,7 @@ ClientManager.prototype.loadUser = function(name) { ClientManager.prototype.getUsers = function() { return fs - .readdirSync(Helper.USERS_PATH) + .readdirSync(Helper.getUsersPath()) .filter((file) => file.endsWith(".json")) .map((file) => file.slice(0, -5)); }; diff --git a/src/command-line/add.js b/src/command-line/add.js index 0f2de5ed..31945de9 100644 --- a/src/command-line/add.js +++ b/src/command-line/add.js @@ -11,8 +11,8 @@ program .description("Add a new user") .on("--help", Utils.extraHelp) .action(function(name) { - if (!fs.existsSync(Helper.USERS_PATH)) { - log.error(`${Helper.USERS_PATH} does not exist.`); + if (!fs.existsSync(Helper.getUsersPath())) { + log.error(`${Helper.getUsersPath()} does not exist.`); return; } diff --git a/src/command-line/config.js b/src/command-line/config.js index 9b601dc8..5c4c391f 100644 --- a/src/command-line/config.js +++ b/src/command-line/config.js @@ -9,20 +9,20 @@ const Utils = require("./utils"); program .command("config") - .description(`Edit configuration file located at ${colors.green(Helper.CONFIG_PATH)}.`) + .description(`Edit configuration file located at ${colors.green(Helper.getConfigPath())}.`) .on("--help", Utils.extraHelp) .action(function() { - if (!fs.existsSync(Helper.CONFIG_PATH)) { - log.error(`${Helper.CONFIG_PATH} does not exist.`); + if (!fs.existsSync(Helper.getConfigPath())) { + log.error(`${Helper.getConfigPath()} does not exist.`); return; } var child_spawn = child.spawn( process.env.EDITOR || "vi", - [Helper.CONFIG_PATH], + [Helper.getConfigPath()], {stdio: "inherit"} ); child_spawn.on("error", function() { - log.error(`Unable to open ${colors.green(Helper.CONFIG_PATH)}. ${colors.bold("$EDITOR")} is not set, and ${colors.bold("vi")} was not found.`); + log.error(`Unable to open ${colors.green(Helper.getConfigPath())}. ${colors.bold("$EDITOR")} is not set, and ${colors.bold("vi")} was not found.`); }); }); diff --git a/src/command-line/edit.js b/src/command-line/edit.js index 2b552f6b..23e552e7 100644 --- a/src/command-line/edit.js +++ b/src/command-line/edit.js @@ -12,8 +12,8 @@ program .description(`Edit user file located at ${colors.green(Helper.getUserConfigPath(""))}.`) .on("--help", Utils.extraHelp) .action(function(name) { - if (!fs.existsSync(Helper.USERS_PATH)) { - log.error(`${Helper.USERS_PATH} does not exist.`); + if (!fs.existsSync(Helper.getUsersPath())) { + log.error(`${Helper.getUsersPath()} does not exist.`); return; } diff --git a/src/command-line/install.js b/src/command-line/install.js index c62b81a1..90ddcb75 100644 --- a/src/command-line/install.js +++ b/src/command-line/install.js @@ -16,8 +16,8 @@ program const child = require("child_process"); const packageJson = require("package-json"); - if (!fs.existsSync(Helper.CONFIG_PATH)) { - log.error(`${Helper.CONFIG_PATH} does not exist.`); + if (!fs.existsSync(Helper.getConfigPath())) { + log.error(`${Helper.getConfigPath()} does not exist.`); return; } diff --git a/src/command-line/list.js b/src/command-line/list.js index 07c60528..6123ffd6 100644 --- a/src/command-line/list.js +++ b/src/command-line/list.js @@ -11,8 +11,8 @@ program .description("List all users") .on("--help", Utils.extraHelp) .action(function() { - if (!fs.existsSync(Helper.USERS_PATH)) { - log.error(`${Helper.USERS_PATH} does not exist.`); + if (!fs.existsSync(Helper.getUsersPath())) { + log.error(`${Helper.getUsersPath()} does not exist.`); return; } diff --git a/src/command-line/remove.js b/src/command-line/remove.js index beb3f3b1..d0cdb6f4 100644 --- a/src/command-line/remove.js +++ b/src/command-line/remove.js @@ -11,8 +11,8 @@ program .description("Remove an existing user") .on("--help", Utils.extraHelp) .action(function(name) { - if (!fs.existsSync(Helper.USERS_PATH)) { - log.error(`${Helper.USERS_PATH} does not exist.`); + if (!fs.existsSync(Helper.getUsersPath())) { + log.error(`${Helper.getUsersPath()} does not exist.`); return; } diff --git a/src/command-line/reset.js b/src/command-line/reset.js index 09d5735d..24f540dc 100644 --- a/src/command-line/reset.js +++ b/src/command-line/reset.js @@ -11,8 +11,8 @@ program .description("Reset user password") .on("--help", Utils.extraHelp) .action(function(name) { - if (!fs.existsSync(Helper.USERS_PATH)) { - log.error(`${Helper.USERS_PATH} does not exist.`); + if (!fs.existsSync(Helper.getUsersPath())) { + log.error(`${Helper.getUsersPath()} does not exist.`); return; } diff --git a/src/command-line/start.js b/src/command-line/start.js index fbec3f17..2cbaeb00 100644 --- a/src/command-line/start.js +++ b/src/command-line/start.js @@ -38,18 +38,18 @@ program }); function initalizeConfig() { - if (!fs.existsSync(Helper.CONFIG_PATH)) { - fsextra.ensureDirSync(Helper.HOME); - fs.chmodSync(Helper.HOME, "0700"); + if (!fs.existsSync(Helper.getConfigPath())) { + fsextra.ensureDirSync(Helper.getHomePath()); + fs.chmodSync(Helper.getHomePath(), "0700"); fsextra.copySync(path.resolve(path.join( __dirname, "..", "..", "defaults", "config.js" - )), Helper.CONFIG_PATH); - log.info(`Configuration file created at ${colors.green(Helper.CONFIG_PATH)}.`); + )), Helper.getConfigPath()); + log.info(`Configuration file created at ${colors.green(Helper.getConfigPath())}.`); } - fsextra.ensureDirSync(Helper.USERS_PATH); + fsextra.ensureDirSync(Helper.getUsersPath()); } diff --git a/src/command-line/utils.js b/src/command-line/utils.js index 5ca3d4d1..f9dd3ce8 100644 --- a/src/command-line/utils.js +++ b/src/command-line/utils.js @@ -2,6 +2,7 @@ const colors = require("colors/safe"); const fs = require("fs"); +const Helper = require("../helper"); const path = require("path"); let home; @@ -13,7 +14,7 @@ class Utils { "", " Environment variable:", "", - ` THELOUNGE_HOME Path for all configuration files and folders. Defaults to ${colors.green(Utils.defaultHome())}.`, + ` THELOUNGE_HOME Path for all configuration files and folders. Defaults to ${colors.green(Helper.expandHome(Utils.defaultHome()))}.`, "", ].forEach((e) => console.log(e)); // eslint-disable-line no-console } diff --git a/src/helper.js b/src/helper.js index 0f65d085..052e4115 100644 --- a/src/helper.js +++ b/src/helper.js @@ -9,18 +9,27 @@ var net = require("net"); var bcrypt = require("bcryptjs"); const colors = require("colors/safe"); -var Helper = { +let homePath; +let configPath; +let usersPath; +let storagePath; +let packagesPath; + +const Helper = { config: null, - expandHome: expandHome, - getPackagesPath: getPackagesPath, - getPackageModulePath: getPackageModulePath, - getStoragePath: getStoragePath, - getUserConfigPath: getUserConfigPath, - getUserLogsPath: getUserLogsPath, - setHome: setHome, - getVersion: getVersion, - getGitCommit: getGitCommit, - ip2hex: ip2hex, + expandHome, + getHomePath, + getPackagesPath, + getPackageModulePath, + getStoragePath, + getConfigPath, + getUsersPath, + getUserConfigPath, + getUserLogsPath, + setHome, + getVersion, + getGitCommit, + ip2hex, password: { hash: passwordHash, @@ -61,14 +70,16 @@ function getGitCommit() { } } -function setHome(homePath) { - this.HOME = expandHome(homePath); - this.CONFIG_PATH = path.join(this.HOME, "config.js"); - this.USERS_PATH = path.join(this.HOME, "users"); +function setHome(newPath) { + homePath = expandHome(newPath); + configPath = path.join(homePath, "config.js"); + usersPath = path.join(homePath, "users"); + storagePath = path.join(homePath, "storage"); + packagesPath = path.join(homePath, "packages", "node_modules"); // Reload config from new home location - if (fs.existsSync(this.CONFIG_PATH)) { - var userConfig = require(this.CONFIG_PATH); + if (fs.existsSync(configPath)) { + var userConfig = require(configPath); this.config = _.merge(this.config, userConfig); } @@ -91,26 +102,38 @@ function setHome(homePath) { // TODO: Remove in future release // Backwards compatibility for old way of specifying themes in settings if (this.config.theme.includes(".css")) { - log.warn(`Referring to CSS files in the ${colors.green("theme")} setting of ${colors.green(Helper.CONFIG_PATH)} is ${colors.bold("deprecated")} and will be removed in a future version.`); + log.warn(`Referring to CSS files in the ${colors.green("theme")} setting of ${colors.green(configPath)} is ${colors.bold("deprecated")} and will be removed in a future version.`); } else { this.config.theme = `themes/${this.config.theme}.css`; } } +function getHomePath() { + return homePath; +} + +function getConfigPath() { + return configPath; +} + +function getUsersPath() { + return usersPath; +} + function getUserConfigPath(name) { - return path.join(this.USERS_PATH, name + ".json"); + return path.join(usersPath, name + ".json"); } function getUserLogsPath(name, network) { - return path.join(this.HOME, "logs", name, network); + return path.join(homePath, "logs", name, network); } function getStoragePath() { - return path.join(this.HOME, "storage"); + return storagePath; } function getPackagesPath() { - return path.join(this.HOME, "packages", "node_modules"); + return packagesPath; } function getPackageModulePath(packageName) { @@ -134,6 +157,8 @@ function ip2hex(address) { }).join(""); } +// Expand ~ into the current user home dir. +// This does *not* support `~other_user/tmp` => `/home/other_user/tmp`. function expandHome(shortenedPath) { if (!shortenedPath) { return ""; diff --git a/src/plugins/webpush.js b/src/plugins/webpush.js index 4b867e95..0777483b 100644 --- a/src/plugins/webpush.js +++ b/src/plugins/webpush.js @@ -8,7 +8,7 @@ const Helper = require("../helper"); class WebPush { constructor() { - const vapidPath = path.join(Helper.HOME, "vapid.json"); + const vapidPath = path.join(Helper.getHomePath(), "vapid.json"); if (fs.existsSync(vapidPath)) { const data = fs.readFileSync(vapidPath, "utf-8"); diff --git a/src/server.js b/src/server.js index 9f42cbd0..744ed4a4 100644 --- a/src/server.js +++ b/src/server.js @@ -30,7 +30,7 @@ var manager = null; module.exports = function() { log.info(`The Lounge ${colors.green(Helper.getVersion())} \ (Node.js ${colors.green(process.versions.node)} on ${colors.green(process.platform)} ${process.arch})`); - log.info(`Configuration file: ${colors.green(Helper.CONFIG_PATH)}`); + log.info(`Configuration file: ${colors.green(Helper.getConfigPath())}`); var app = express() .disable("x-powered-by") diff --git a/test/src/helperTest.js b/test/src/helperTest.js new file mode 100644 index 00000000..36d1b518 --- /dev/null +++ b/test/src/helperTest.js @@ -0,0 +1,39 @@ +"use strict"; + +const expect = require("chai").expect; +const os = require("os"); +const Helper = require("../../src/helper"); + +describe("Helper", function() { + describe("#expandHome", function() { + it("should correctly expand a Unix path", function() { + expect([`${os.homedir()}/tmp`, `${os.homedir()}\\tmp`]) + .to.include(Helper.expandHome("~/tmp")); + }); + + it("should correctly expand a Windows path", function() { + expect(Helper.expandHome("~\\tmp")).to.equal(`${os.homedir()}\\tmp`); + }); + + it("should correctly expand when not given a specific path", function() { + expect(Helper.expandHome("~")).to.equal(os.homedir()); + }); + + it("should not expand paths not starting with tilde", function() { + expect(Helper.expandHome("/tmp")).to.match(/^\/tmp|[A-Z]:\\tmp$/); + }); + + it("should not expand a tilde in the middle of a string", function() { + expect(Helper.expandHome("/tmp/~foo")) + .to.match(/^\/tmp\/~foo|[A-Z]:\\tmp\\~foo$/); + }); + + it("should return an empty string when given an empty string", function() { + expect(Helper.expandHome("")).to.equal(""); + }); + + it("should return an empty string when given undefined", function() { + expect(Helper.expandHome(undefined)).to.equal(""); + }); + }); +});