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