chore: refactor jsmasker calls
chore: implement constants
This commit is contained in:
parent
47910dd066
commit
2c3a89b5dc
7 changed files with 91 additions and 53 deletions
|
@ -5,25 +5,9 @@ const fs = require("fs")
|
|||
const path = require("path")
|
||||
const { createNamespacedDebug } = require("./logger")
|
||||
const { HTTP, MESSAGES, DEFAULTS } = require("./constants")
|
||||
const { modifyHtml } = require("./utils")
|
||||
|
||||
const debug = createNamespacedDebug("connectionHandler")
|
||||
/**
|
||||
* Modify the HTML content by replacing certain placeholders with dynamic values.
|
||||
* @param {string} html - The original HTML content.
|
||||
* @param {Object} config - The configuration object to inject into the HTML.
|
||||
* @returns {string} - The modified HTML content.
|
||||
*/
|
||||
function modifyHtml(html, config) {
|
||||
const modifiedHtml = html.replace(
|
||||
/(src|href)="(?!http|\/\/)/g,
|
||||
'$1="/ssh/assets/'
|
||||
)
|
||||
|
||||
return modifiedHtml.replace(
|
||||
"window.webssh2Config = null;",
|
||||
`window.webssh2Config = ${JSON.stringify(config)};`
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle reading the file and processing the response.
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// server
|
||||
// app/constants.js
|
||||
|
||||
const crypto = require("crypto")
|
||||
const path = require("path")
|
||||
|
||||
/**
|
||||
|
@ -14,7 +13,9 @@ const MESSAGES = {
|
|||
CONFIG_ERROR: "CONFIG_ERROR",
|
||||
UNEXPECTED_ERROR: "An unexpected error occurred",
|
||||
EXPRESS_APP_CONFIG_ERROR: "Failed to configure Express app",
|
||||
CLIENT_FILE_ERROR: "Error loading client file"
|
||||
CLIENT_FILE_ERROR: "Error loading client file",
|
||||
FAILED_SESSION_SAVE: "Failed to save session",
|
||||
CONFIG_VALIDATION_ERROR: "Config validation error"
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,20 +39,6 @@ const DEFAULTS = {
|
|||
CLIENT_FILE: "client.htm"
|
||||
}
|
||||
|
||||
/**
|
||||
* Socket events
|
||||
*/
|
||||
const SOCKET_EVENTS = {
|
||||
CONNECTION: "connection",
|
||||
DISCONNECT: "disconnect",
|
||||
AUTHENTICATE: "authenticate",
|
||||
AUTHENTICATION: "authentication",
|
||||
TERMINAL: "terminal",
|
||||
DATA: "data",
|
||||
RESIZE: "resize",
|
||||
CONTROL: "control"
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP Related
|
||||
*/
|
||||
|
@ -66,12 +53,11 @@ const HTTP = {
|
|||
PATH: "/ssh/host/",
|
||||
SAMESITE: "Strict",
|
||||
SESSION_SID: "webssh2_sid",
|
||||
CREDS_CLEARED: "Credentials cleared."
|
||||
CREDS_CLEARED: "Credentials cleared.",
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
MESSAGES,
|
||||
DEFAULTS,
|
||||
SOCKET_EVENTS,
|
||||
HTTP
|
||||
}
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
|
||||
const express = require("express")
|
||||
const basicAuth = require("basic-auth")
|
||||
const maskObject = require("jsmasker")
|
||||
const validator = require("validator")
|
||||
const {
|
||||
getValidatedHost,
|
||||
getValidatedPort,
|
||||
maskSensitiveData,
|
||||
validateSshTerm
|
||||
} = require("./utils")
|
||||
const handleConnection = require("./connectionHandler")
|
||||
|
@ -61,7 +61,7 @@ router.get("/host/:host", auth, function(req, res) {
|
|||
req.session.usedBasicAuth = true
|
||||
|
||||
// Sanitize and log the sshCredentials object
|
||||
const sanitizedCredentials = maskObject(
|
||||
const sanitizedCredentials = maskSensitiveData(
|
||||
JSON.parse(JSON.stringify(req.session.sshCredentials))
|
||||
)
|
||||
debug("/ssh/host/ Credentials: ", sanitizedCredentials)
|
||||
|
|
|
@ -16,7 +16,7 @@ function createServer(app) {
|
|||
* @param {Error} err - The error object
|
||||
*/
|
||||
function handleServerError(err) {
|
||||
console.error("WebSSH2 server.listen ERROR:", err.code)
|
||||
console.error("HTTP Server ERROR: %O", err)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
// server
|
||||
// app/socket.js
|
||||
|
||||
const maskObject = require("jsmasker")
|
||||
const validator = require("validator")
|
||||
const SSHConnection = require("./ssh")
|
||||
const { createNamespacedDebug } = require("./logger")
|
||||
const { SSHConnectionError, handleError } = require("./errors")
|
||||
|
||||
const debug = createNamespacedDebug("socket")
|
||||
const { validateSshTerm, isValidCredentials } = require("./utils")
|
||||
const {
|
||||
isValidCredentials,
|
||||
maskSensitiveData,
|
||||
validateSshTerm
|
||||
} = require("./utils")
|
||||
const { MESSAGES } = require("./constants")
|
||||
|
||||
class WebSSH2Socket {
|
||||
constructor(socket, config) {
|
||||
|
@ -38,7 +42,7 @@ class WebSSH2Socket {
|
|||
const creds = this.socket.handshake.session.sshCredentials
|
||||
debug(
|
||||
`handleConnection: ${this.socket.id}, Host: ${creds.host}: HTTP Basic Credentials Exist, creds: %O`,
|
||||
maskObject(creds)
|
||||
maskSensitiveData(creds)
|
||||
)
|
||||
this.handleAuthenticate(creds)
|
||||
} else if (!this.sessionState.authenticated) {
|
||||
|
@ -67,7 +71,7 @@ class WebSSH2Socket {
|
|||
}
|
||||
|
||||
handleAuthenticate(creds) {
|
||||
debug(`handleAuthenticate: ${this.socket.id}, %O`, maskObject(creds))
|
||||
debug(`handleAuthenticate: ${this.socket.id}, %O`, maskSensitiveData(creds))
|
||||
|
||||
if (isValidCredentials(creds)) {
|
||||
this.sessionState.term = validateSshTerm(creds.term)
|
||||
|
@ -86,7 +90,7 @@ class WebSSH2Socket {
|
|||
initializeConnection(creds) {
|
||||
debug(
|
||||
`initializeConnection: ${this.socket.id}, INITIALIZING SSH CONNECTION: Host: ${creds.host}, creds: %O`,
|
||||
maskObject(creds)
|
||||
maskSensitiveData(creds)
|
||||
)
|
||||
|
||||
this.ssh
|
||||
|
@ -278,7 +282,10 @@ class WebSSH2Socket {
|
|||
|
||||
this.socket.handshake.session.save(err => {
|
||||
if (err)
|
||||
console.error(`Failed to save session for ${this.socket.id}:`, err)
|
||||
console.error(
|
||||
`clearSessionCredentials: ${MESSAGES.FAILED_SESSION_SAVE} ${this.socket.id}:`,
|
||||
err
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
14
app/ssh.js
14
app/ssh.js
|
@ -2,9 +2,9 @@
|
|||
// app/ssh.js
|
||||
|
||||
const SSH = require("ssh2").Client
|
||||
const maskObject = require("jsmasker")
|
||||
const { createNamespacedDebug } = require("./logger")
|
||||
const { SSHConnectionError, handleError } = require("./errors")
|
||||
const { maskSensitiveData } = require("./utils")
|
||||
|
||||
const debug = createNamespacedDebug("ssh")
|
||||
|
||||
|
@ -17,7 +17,7 @@ function SSHConnection(config) {
|
|||
SSHConnection.prototype.connect = function(creds) {
|
||||
const self = this
|
||||
return new Promise(function(resolve, reject) {
|
||||
debug("connect: %O", maskObject(creds))
|
||||
debug("connect: %O", maskSensitiveData(creds))
|
||||
|
||||
if (self.conn) {
|
||||
self.conn.end()
|
||||
|
@ -51,12 +51,10 @@ SSHConnection.prototype.getSSHConfig = function(creds) {
|
|||
username: creds.username,
|
||||
password: creds.password,
|
||||
tryKeyboard: true,
|
||||
algorithms: creds.algorithms || this.config.ssh.algorithms,
|
||||
readyTimeout: creds.readyTimeout || this.config.ssh.readyTimeout,
|
||||
keepaliveInterval:
|
||||
creds.keepaliveInterval || this.config.ssh.keepaliveInterval,
|
||||
keepaliveCountMax:
|
||||
creds.keepaliveCountMax || this.config.ssh.keepaliveCountMax,
|
||||
algorithms: this.config.ssh.algorithms,
|
||||
readyTimeout: this.config.ssh.readyTimeout,
|
||||
keepaliveInterval: this.config.ssh.keepaliveInterval,
|
||||
keepaliveCountMax: this.config.ssh.keepaliveCountMax,
|
||||
debug: createNamespacedDebug("ssh2")
|
||||
}
|
||||
}
|
||||
|
|
65
app/utils.js
65
app/utils.js
|
@ -2,8 +2,11 @@
|
|||
// /app/utils.js
|
||||
const validator = require("validator")
|
||||
const crypto = require("crypto")
|
||||
const Ajv = require("ajv")
|
||||
const maskObject = require("jsmasker")
|
||||
const { createNamespacedDebug } = require("./logger")
|
||||
const { DEFAULTS } = require("./constants")
|
||||
const { DEFAULTS, MESSAGES } = require("./constants")
|
||||
const { configSchema } = require("./config")
|
||||
|
||||
const debug = createNamespacedDebug("utils")
|
||||
|
||||
|
@ -127,11 +130,71 @@ function validateSshTerm(term) {
|
|||
return validatedSshTerm ? term : null
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the given configuration object.
|
||||
*
|
||||
* @param {Object} config - The configuration object to validate.
|
||||
* @throws {Error} If the configuration object fails validation.
|
||||
* @returns {Object} The validated configuration object.
|
||||
*/
|
||||
function validateConfig(config) {
|
||||
const ajv = new Ajv()
|
||||
const validate = ajv.compile(configSchema)
|
||||
const valid = validate(config)
|
||||
if (!valid) {
|
||||
throw new Error(
|
||||
`${MESSAGES.CONFIG_VALIDATION_ERROR}: ${ajv.errorsText(validate.errors)}`
|
||||
)
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the HTML content by replacing certain placeholders with dynamic values.
|
||||
* @param {string} html - The original HTML content.
|
||||
* @param {Object} config - The configuration object to inject into the HTML.
|
||||
* @returns {string} - The modified HTML content.
|
||||
*/
|
||||
function modifyHtml(html, config) {
|
||||
debug("modifyHtml")
|
||||
const modifiedHtml = html.replace(
|
||||
/(src|href)="(?!http|\/\/)/g,
|
||||
'$1="/ssh/assets/'
|
||||
)
|
||||
|
||||
return modifiedHtml.replace(
|
||||
"window.webssh2Config = null;",
|
||||
`window.webssh2Config = ${JSON.stringify(config)};`
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Masks sensitive information in an object
|
||||
* @param {Object} obj - The object to mask
|
||||
* @param {Object} [options] - Optional configuration for masking
|
||||
* @returns {Object} The masked object
|
||||
*/
|
||||
function maskSensitiveData(obj, options) {
|
||||
const defaultOptions = {
|
||||
// Add any default masking options here
|
||||
// For example:
|
||||
// password: true,
|
||||
// token: true
|
||||
}
|
||||
|
||||
const maskingOptions = Object.assign({}, defaultOptions, options || {})
|
||||
|
||||
return maskObject(obj, maskingOptions)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
deepMerge,
|
||||
generateSecureSecret,
|
||||
getValidatedHost,
|
||||
getValidatedPort,
|
||||
isValidCredentials,
|
||||
maskSensitiveData,
|
||||
modifyHtml,
|
||||
validateConfig,
|
||||
validateSshTerm
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue