twokeys-server
Version:
Server for 2Keys
168 lines (164 loc) • 7.48 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/**
Copyright 2018 Kishan Sambhi
This file is part of 2Keys.
2Keys is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
2Keys is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with 2Keys. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* @overview Adds the hotkeys server to windows startup
*/
const path_1 = require("path");
const mkdirp_1 = __importDefault(require("mkdirp"));
const constants_1 = require("../util/constants");
const logger_1 = __importDefault(require("../util/logger"));
const fs_1 = require("fs");
const child_process_1 = require("child_process");
const os_1 = require("os");
const config_1 = require("../util/config");
const Mustache = require("mustache");
const logger = new logger_1.default({
name: "startup"
});
/**
* Hacky way to generate daemon startup JS
* @param name Name of 2Keys project, from config
*/
function gen_startup_js(name) {
const output = Mustache.render(fs_1.readFileSync(constants_1.WINDOWS_DAEMON_FILE_JS_TEMPLATE).toString("utf8"), {
root: process.cwd().split("\\").join("\\\\"),
name,
default_local_twokeys: constants_1.DEFAULT_LOCAL_2KEYS,
daemon_pid_file: constants_1.WINDOWS_DAEMON_PID_FILE,
server_pid_file: constants_1.WINDOWS_SERVER_PID_FILE
});
return output;
}
/**
* Generates .vbs startup script for shell:startup
*/
function gen_startup_vbs(name) {
const output = Mustache.render(fs_1.readFileSync(constants_1.WINDOWS_DAEMON_FILE_VBS_TEMPLATE).toString("utf8"), {
daemon: path_1.join(process.cwd(), constants_1.DEFAULT_LOCAL_2KEYS, constants_1.WINDOWS_DAEMON_FILE),
name,
});
return output;
}
/**
* Stop 2Keys daemon
*/
function stop_daemon() {
return new Promise((resolve, reject) => {
logger.info("Stopping 2Keys startup daemon...");
logger.info("NB: You may need to run 2Keys daemon-gen to make sure you have the latest daemon files.");
logger.debug("Reading .pid files...");
fs_1.readFile(path_1.join(process.cwd(), constants_1.DEFAULT_LOCAL_2KEYS, constants_1.WINDOWS_SERVER_PID_FILE), (err, pid) => {
if (err)
logger.throw(err);
logger.debug(`Server PID: ${pid.toString()}`);
logger.debug("Killing...");
process.kill(parseInt(pid.toString()), "SIGINT");
fs_1.readFile(path_1.join(process.cwd(), constants_1.DEFAULT_LOCAL_2KEYS, constants_1.WINDOWS_DAEMON_PID_FILE), (err2, pid2) => {
if (err2)
logger.throw(err2);
logger.debug(`Daemon PID: ${pid2.toString()}`);
logger.debug("Killing...");
process.kill(parseInt(pid2.toString()));
resolve();
});
});
});
}
exports.stop_daemon = stop_daemon;
/**
* Starts 2Keys daemon
*/
function start_daemon() {
logger.info("Starting 2Keys daemon...");
logger.info(`See logs in ${path_1.join(process.cwd(), constants_1.DEFAULT_LOCAL_2KEYS)} for logs.`);
child_process_1.exec(path_1.join(process.cwd(), constants_1.DEFAULT_LOCAL_2KEYS, constants_1.WINDOWS_DAEMON_FILE_VBS), {}, (error, stdout, stderr) => {
if (error) {
logger.throw(error);
}
logger.info("2Keys daemon now running.");
});
}
exports.start_daemon = start_daemon;
/**
* Function to regenerate daemons
* @param argv CLI args
*/
async function regenerateDaemons(argv) {
logger.info("Regenerating daemon files...");
logger.warn("Deleting old files...");
try {
await fs_1.promises.unlink(path_1.join(process.cwd(), constants_1.DEFAULT_LOCAL_2KEYS, constants_1.WINDOWS_DAEMON_FILE)); // JS
await fs_1.promises.unlink(path_1.join(process.cwd(), constants_1.DEFAULT_LOCAL_2KEYS, constants_1.WINDOWS_DAEMON_FILE_VBS)); // VBS Script; Startup script not deleted
logger.debug("Grabbing config...");
const config = await config_1.config_loader();
logger.debug("Running generator...");
add_to_startup(config.name, argv);
}
catch (err) {
logger.throw(err);
}
}
exports.regenerateDaemons = regenerateDaemons;
/**
* Creates a new daemon
* Creates a daemon starter js file in root/.2Keys/daemon.js
* A daemon Visual Basic startup script in shell:startup/2Keys-name.vbs
* And symlinks the .vbs for the start, stop and restart commands
* @param name Name of 2Keys project, from config
*/
function add_to_startup(name, argv) {
logger.debug("Making files...");
// Create required dirs
try {
mkdirp_1.default.sync(path_1.join(process.cwd(), constants_1.DEFAULT_LOCAL_2KEYS));
logger.debug(`Made dir ${path_1.join(process.cwd(), constants_1.DEFAULT_LOCAL_2KEYS)}...`);
}
catch (err) {
logger.throw(err);
}
// NOTE: Even though there may not be a "Startup" folder, windows explorer may show a "Start-Up" folder
// 2Keys will still see "Startup"
const VBS_SCRIPT = path_1.join(os_1.homedir(), "AppData", "Roaming", "Microsoft", "Windows", "Start Menu", "Programs", "Startup", `${constants_1.WINDOWS_DAEMON_PREFIX}${name}.vbs`);
// Create service file
try {
logger.debug(`Creating daemon startup js file to start the server as ${constants_1.WINDOWS_DAEMON_PREFIX}${name}...`);
fs_1.writeFileSync(path_1.join(process.cwd(), constants_1.DEFAULT_LOCAL_2KEYS, constants_1.WINDOWS_DAEMON_FILE), gen_startup_js(name));
logger.debug("Adding a .vbs script to .2Keys to start daemon in the background...");
// writeFileSync(join(process.env.APPDATA, "Microsoft", "Windows", "Start Menu", "Programs", "Startup", `${WINDOWS_DAEMON_PREFIX}${name}.vbs`), gen_startup_vbs());
fs_1.writeFileSync(path_1.join(process.cwd(), constants_1.DEFAULT_LOCAL_2KEYS, constants_1.WINDOWS_DAEMON_FILE_VBS), gen_startup_vbs(name));
if (!argv.hasOwnProperty("startup")) { // If --no-startup given, startup set to false. Is undefined if not
logger.debug("Symlinking this .vbs script into user startup folder...");
fs_1.symlinkSync(path_1.join(process.cwd(), constants_1.DEFAULT_LOCAL_2KEYS, constants_1.WINDOWS_DAEMON_FILE_VBS), VBS_SCRIPT);
}
}
catch (err) {
if (err.code === "EEXIST") {
// Writing auto removes file, so only symlink could throw EEXIST
logger.warn("Symbolink already created, it still points at the correct place, but we can't replace it.");
logger.debug("Full error that caused this warning: ");
logger.debug(err.stack);
}
else {
logger.throw(err);
}
}
}
exports.default = add_to_startup;
//# sourceMappingURL=daemon.js.map