160 lines
5.1 KiB
JavaScript
160 lines
5.1 KiB
JavaScript
// server
|
|
// app/config.js
|
|
|
|
const path = require("path")
|
|
const fs = require("fs")
|
|
const readConfig = require("read-config-ng")
|
|
const { deepMerge, validateConfig } = require("./utils")
|
|
const { generateSecureSecret } = require("./crypto-utils")
|
|
const { createNamespacedDebug } = require("./logger")
|
|
const { ConfigError, handleError } = require("./errors")
|
|
const { DEFAULTS } = require("./constants")
|
|
|
|
const debug = createNamespacedDebug("config")
|
|
|
|
const defaultConfig = {
|
|
listen: {
|
|
ip: "0.0.0.0",
|
|
port: DEFAULTS.LISTEN_PORT
|
|
},
|
|
http: {
|
|
origins: ["*:*"]
|
|
},
|
|
user: {
|
|
name: null,
|
|
password: null
|
|
},
|
|
ssh: {
|
|
host: null,
|
|
port: DEFAULTS.SSH_PORT,
|
|
term: DEFAULTS.SSH_TERM,
|
|
readyTimeout: 20000,
|
|
keepaliveInterval: 120000,
|
|
keepaliveCountMax: 10,
|
|
alwaysSendKeyboardInteractivePrompts: false,
|
|
},
|
|
header: {
|
|
text: null,
|
|
background: "green"
|
|
},
|
|
options: {
|
|
challengeButton: true,
|
|
autoLog: false,
|
|
allowReauth: true,
|
|
allowReconnect: true,
|
|
allowReplay: true
|
|
},
|
|
algorithms: {
|
|
kex: [
|
|
"ecdh-sha2-nistp256",
|
|
"ecdh-sha2-nistp384",
|
|
"ecdh-sha2-nistp521",
|
|
"diffie-hellman-group-exchange-sha256",
|
|
"diffie-hellman-group14-sha1"
|
|
],
|
|
cipher: [
|
|
"aes128-ctr",
|
|
"aes192-ctr",
|
|
"aes256-ctr",
|
|
"aes128-gcm",
|
|
"aes128-gcm@openssh.com",
|
|
"aes256-gcm",
|
|
"aes256-gcm@openssh.com",
|
|
"aes256-cbc"
|
|
],
|
|
hmac: ["hmac-sha2-256", "hmac-sha2-512", "hmac-sha1"],
|
|
compress: ["none", "zlib@openssh.com", "zlib"]
|
|
},
|
|
session: {
|
|
secret: process.env.WEBSSH_SESSION_SECRET || generateSecureSecret(),
|
|
name: "webssh2.sid"
|
|
}
|
|
}
|
|
|
|
function getConfigPath() {
|
|
const nodeRoot = path.dirname(require.main.filename)
|
|
return path.join(nodeRoot, "config.json")
|
|
}
|
|
|
|
function loadConfig() {
|
|
const configPath = getConfigPath()
|
|
|
|
try {
|
|
if (fs.existsSync(configPath)) {
|
|
const providedConfig = readConfig.sync(configPath)
|
|
const mergedConfig = deepMerge(
|
|
JSON.parse(JSON.stringify(defaultConfig)),
|
|
providedConfig
|
|
)
|
|
|
|
if (process.env.PORT) {
|
|
mergedConfig.listen.port = parseInt(process.env.PORT, 10)
|
|
debug("Using PORT from environment: %s", mergedConfig.listen.port)
|
|
}
|
|
|
|
const validatedConfig = validateConfig(mergedConfig)
|
|
debug("Merged and validated configuration")
|
|
return validatedConfig
|
|
}
|
|
debug("Missing config.json for webssh. Using default config")
|
|
return defaultConfig
|
|
} catch (err) {
|
|
const error = new ConfigError(
|
|
`Problem loading config.json for webssh: ${err.message}`
|
|
)
|
|
handleError(error)
|
|
return defaultConfig
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Configuration for the application.
|
|
*
|
|
* @returns {Object} config
|
|
* @property {Object} listen - Configuration for listening IP and port.
|
|
* @property {string} listen.ip - The IP address to listen on.
|
|
* @property {number} listen.port - The port number to listen on.
|
|
* @property {Object} http - Configuration for HTTP settings.
|
|
* @property {string[]} http.origins - The allowed origins for HTTP requests.
|
|
* @property {Object} user - Configuration for user settings.
|
|
* @property {string|null} user.name - The name of the user.
|
|
* @property {string|null} user.password - The password of the user.
|
|
* @property {Object} ssh - Configuration for SSH settings.
|
|
* @property {string|null} ssh.host - The SSH host.
|
|
* @property {number} ssh.port - The SSH port.
|
|
* @property {string} ssh.term - The SSH terminal type.
|
|
* @property {number} ssh.readyTimeout - The SSH ready timeout.
|
|
* @property {number} ssh.keepaliveInterval - The SSH keepalive interval.
|
|
* @property {number} ssh.keepaliveCountMax - The SSH keepalive count maximum.
|
|
* @property {Object} header - Configuration for header settings.
|
|
* @property {string|null} header.text - The header text.
|
|
* @property {string} header.background - The header background color.
|
|
* @property {Object} options - Configuration for options settings.
|
|
* @property {boolean} options.challengeButton - Whether to show the challenge button.
|
|
* @property {boolean} options.autoLog - Whether to automatically log.
|
|
* @property {boolean} options.allowReauth - Whether to allow reauthentication.
|
|
* @property {boolean} options.allowReconnect - Whether to allow reconnection.
|
|
* @property {boolean} options.allowReplay - Whether to allow replay.
|
|
* @property {Object} algorithms - Configuration for algorithms settings.
|
|
* @property {string[]} algorithms.kex - The key exchange algorithms.
|
|
* @property {string[]} algorithms.cipher - The cipher algorithms.
|
|
* @property {string[]} algorithms.hmac - The HMAC algorithms.
|
|
* @property {string[]} algorithms.compress - The compression algorithms.
|
|
* @property {Object} session - Configuration for session settings.
|
|
* @property {string} session.secret - The session secret.
|
|
* @property {string} session.name - The session name.
|
|
*/
|
|
const config = loadConfig()
|
|
|
|
function getCorsConfig() {
|
|
return {
|
|
origin: config.http.origins,
|
|
methods: ["GET", "POST"],
|
|
credentials: true
|
|
}
|
|
}
|
|
|
|
// Extend the config object with the getCorsConfig function
|
|
config.getCorsConfig = getCorsConfig
|
|
|
|
module.exports = config
|