webssh2/app/routes.js
2024-11-29 10:49:55 +00:00

122 lines
3.8 KiB
JavaScript

// server
// app/routes.js
const express = require("express")
const {
getValidatedHost,
getValidatedPort,
maskSensitiveData,
validateSshTerm
} = require("./utils")
const handleConnection = require("./connectionHandler")
const { createNamespacedDebug } = require("./logger")
const { createAuthMiddleware } = require("./middleware")
const { ConfigError, handleError } = require("./errors")
const { HTTP } = require("./constants")
const debug = createNamespacedDebug("routes")
module.exports = function(config) {
const router = express.Router()
const auth = createAuthMiddleware(config)
// Scenario 1: No auth required, uses websocket authentication instead
router.get("/", (req, res) => {
debug("router.get./: Accessed / route")
handleConnection(req, res)
})
/**
* Handles the "/host/" route, which requires authentication and uses the
* `auth` middleware function to handle HTTP Basic Authentication.
*
* This route validates the host and port parameters, sets the `sshCredentials`
* object in the session, and calls the `handleConnection` function to handle
* the connection.
*
* If the `config.ssh.host` is not set, it throws a `ConfigError` with the
* appropriate error message.
*
* @param {Object} req - The Express request object
* @param {Object} res - The Express response object
*/
router.get("/host/", auth, (req, res) => {
debug(`router.get.host: /ssh/host/ route`)
try {
if (!config.ssh.host) {
throw new ConfigError(
"Host parameter required when default host not configured"
)
}
const { host } = config.ssh
const port = getValidatedPort(req.query.port)
const sshterm = validateSshTerm(req.query.sshterm)
req.session.sshCredentials = req.session.sshCredentials || {}
req.session.sshCredentials.host = host
req.session.sshCredentials.port = port
if (req.query.sshterm) {
req.session.sshCredentials.term = sshterm
}
req.session.usedBasicAuth = true
const sanitizedCredentials = maskSensitiveData(
JSON.parse(JSON.stringify(req.session.sshCredentials))
)
debug("/ssh/host/ Credentials: ", sanitizedCredentials)
handleConnection(req, res, { host: host })
} catch (err) {
const error = new ConfigError(`Invalid configuration: ${err.message}`)
handleError(error, res)
}
})
// Scenario 2: Auth required, uses HTTP Basic Auth
router.get("/host/:host", auth, (req, res) => {
debug(`router.get.host: /ssh/host/${req.params.host} route`)
try {
const host = getValidatedHost(req.params.host)
const port = getValidatedPort(req.query.port)
// Validate and sanitize sshterm parameter if it exists
const sshterm = validateSshTerm(req.query.sshterm)
req.session.sshCredentials = req.session.sshCredentials || {}
req.session.sshCredentials.host = host
req.session.sshCredentials.port = port
if (req.query.sshterm) {
req.session.sshCredentials.term = sshterm
}
req.session.usedBasicAuth = true
// Sanitize and log the sshCredentials object
const sanitizedCredentials = maskSensitiveData(
JSON.parse(JSON.stringify(req.session.sshCredentials))
)
debug("/ssh/host/ Credentials: ", sanitizedCredentials)
handleConnection(req, res, { host: host })
} catch (err) {
const error = new ConfigError(`Invalid configuration: ${err.message}`)
handleError(error, res)
}
})
// Clear credentials route
router.get("/clear-credentials", (req, res) => {
req.session.sshCredentials = null
res.status(HTTP.OK).send(HTTP.CREDENTIALS_CLEARED)
})
router.get("/force-reconnect", (req, res) => {
req.session.sshCredentials = null
res.status(HTTP.UNAUTHORIZED).send(HTTP.AUTH_REQUIRED)
})
return router
}