butlerx
4 years ago
26 changed files with 272 additions and 103 deletions
@ -0,0 +1,27 @@ |
|||
{ |
|||
ssh: { |
|||
// user: 'username', // default user to use when ssh-ing |
|||
host: 'localhost', // Server to ssh to |
|||
auth: 'password', // shh authentication, method. Defaults to "password", you can use "publickey,password" instead' |
|||
// pass: "password", // Password to use when sshing |
|||
// key: "", // path to an optional client private key, connection will be password-less and insecure! |
|||
port: 22, // Port to ssh to |
|||
knownHosts: '/dev/null', // ssh knownHosts file to use |
|||
}, |
|||
server: { |
|||
base: '/wetty/', // URL base to serve resources from |
|||
port: 3000, // Port to listen on |
|||
host: '0.0.0.0', // address to listen on |
|||
title: 'WeTTy - The Web Terminal Emulator', // Page title |
|||
bypassHelmet: false, // Disable Helmet security checks |
|||
}, |
|||
|
|||
forceSSH: false, // Force sshing to local machine over login if running as root |
|||
command: 'login', // Command to run on server. Login will use ssh if connecting to different server |
|||
/* |
|||
ssl:{ |
|||
key: 'ssl.key', |
|||
cert: 'ssl.cert', |
|||
} |
|||
*/ |
|||
} |
@ -0,0 +1,126 @@ |
|||
import fs from 'fs-extra'; |
|||
import path from 'path'; |
|||
import JSON5 from 'json5'; |
|||
import isUndefined from 'lodash/isUndefined.js'; |
|||
|
|||
import type { Config, SSH, Server } from './interfaces'; |
|||
import { |
|||
sshDefault, |
|||
serverDefault, |
|||
forceSSHDefault, |
|||
defaultCommand, |
|||
} from './defaults.js'; |
|||
|
|||
/** |
|||
* Cast given value to boolean |
|||
* |
|||
* @param value - variable to cast |
|||
* @returns variable cast to boolean |
|||
*/ |
|||
function ensureBoolean(value: any): boolean { |
|||
switch (value) { |
|||
case true: |
|||
case 'true': |
|||
case 1: |
|||
case '1': |
|||
case 'on': |
|||
case 'yes': |
|||
return true; |
|||
default: |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Load JSON5 config from file and merge with default args |
|||
* If no path is provided the default config is returned |
|||
* |
|||
* @param filepath - path to config to load |
|||
* @returns variable cast to boolean |
|||
*/ |
|||
export async function loadConfigFile(filepath?: string): Promise<Config> { |
|||
if (isUndefined(filepath)) { |
|||
return { |
|||
ssh: sshDefault, |
|||
server: serverDefault, |
|||
command: defaultCommand, |
|||
forceSSH: forceSSHDefault, |
|||
}; |
|||
} |
|||
const content = await fs.readFile(path.resolve(filepath)); |
|||
const parsed = JSON5.parse(content.toString()) as Config; |
|||
return { |
|||
ssh: isUndefined(parsed.ssh) |
|||
? sshDefault |
|||
: Object.assign(sshDefault, parsed.ssh), |
|||
server: isUndefined(parsed.server) |
|||
? serverDefault |
|||
: Object.assign(serverDefault, parsed.server), |
|||
command: isUndefined(parsed.command) ? defaultCommand : `${parsed.command}`, |
|||
forceSSH: isUndefined(parsed.forceSSH) |
|||
? forceSSHDefault |
|||
: ensureBoolean(parsed.forceSSH), |
|||
ssl: parsed.ssl, |
|||
}; |
|||
} |
|||
|
|||
/** |
|||
* Merge 2 objects removing undefined fields |
|||
* |
|||
* @param target - base object |
|||
* @param source - object to get new values from |
|||
* @returns merged object |
|||
* |
|||
*/ |
|||
const objectAssign = ( |
|||
target: Record<string, any>, |
|||
source: Record<string, any>, |
|||
): Record<string, any> => |
|||
Object.fromEntries( |
|||
Object.entries(source).map(([key, value]) => [ |
|||
key, |
|||
isUndefined(source[key]) ? target[key] : value, |
|||
]), |
|||
); |
|||
|
|||
/** |
|||
* Merge cli arguemens with config object |
|||
* |
|||
* @param opts - Object containing cli args |
|||
* @param config - Config object |
|||
* @returns merged configuration |
|||
* |
|||
*/ |
|||
export function mergeCliConf( |
|||
opts: Record<string, any>, |
|||
config: Config, |
|||
): Config { |
|||
const ssl = { |
|||
key: opts['ssl-key'], |
|||
cert: opts['ssl-cert'], |
|||
...config.ssl, |
|||
}; |
|||
return { |
|||
ssh: objectAssign(config.ssh, { |
|||
user: opts['ssh-user'], |
|||
host: opts['ssh-host'], |
|||
auth: opts['ssh-auth'], |
|||
port: opts['ssh-port'], |
|||
pass: opts['ssh-pass'], |
|||
key: opts['ssh-key'], |
|||
knownHosts: opts['known-hosts'], |
|||
}) as SSH, |
|||
server: objectAssign(config.server, { |
|||
base: opts.base, |
|||
host: opts.host, |
|||
port: opts.port, |
|||
title: opts.title, |
|||
bypassHelmet: opts['bypass-helmet'], |
|||
}) as Server, |
|||
command: isUndefined(opts.command) ? config.command : opts.command, |
|||
forceSSH: isUndefined(opts['force-ssh']) |
|||
? config.forceSSH |
|||
: opts['force-ssh'], |
|||
ssl: isUndefined(ssl.key) || isUndefined(ssl.cert) ? undefined : ssl, |
|||
}; |
|||
} |
Loading…
Reference in new issue