103 lines
2.3 KiB
JavaScript
103 lines
2.3 KiB
JavaScript
// server
|
|
// app/ssh.js
|
|
|
|
const SSH = require("ssh2").Client
|
|
const { createNamespacedDebug } = require("./logger")
|
|
const { SSHConnectionError, handleError } = require("./errors")
|
|
const { maskSensitiveData } = require("./utils")
|
|
|
|
const debug = createNamespacedDebug("ssh")
|
|
|
|
function SSHConnection(config) {
|
|
this.config = config
|
|
this.conn = null
|
|
this.stream = null
|
|
}
|
|
|
|
SSHConnection.prototype.connect = function(creds) {
|
|
const self = this
|
|
return new Promise(function(resolve, reject) {
|
|
debug("connect: %O", maskSensitiveData(creds))
|
|
|
|
if (self.conn) {
|
|
self.conn.end()
|
|
}
|
|
|
|
self.conn = new SSH()
|
|
|
|
const sshConfig = self.getSSHConfig(creds)
|
|
|
|
self.conn.on("ready", function() {
|
|
debug(`connect: ready: ${creds.host}`)
|
|
resolve()
|
|
})
|
|
|
|
self.conn.on("error", function(err) {
|
|
const error = new SSHConnectionError(
|
|
`SSH Connection error: ${err.message}`
|
|
)
|
|
handleError(error)
|
|
reject(error)
|
|
})
|
|
|
|
self.conn.connect(sshConfig)
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Gets the SSH configuration
|
|
* @param {Object} creds - The credentials object
|
|
* @returns {Object} The SSH configuration object
|
|
*/
|
|
SSHConnection.prototype.getSSHConfig = function(creds) {
|
|
return {
|
|
host: creds.host,
|
|
port: creds.port,
|
|
username: creds.username,
|
|
password: creds.password,
|
|
tryKeyboard: true,
|
|
algorithms: this.config.ssh.algorithms,
|
|
readyTimeout: this.config.ssh.readyTimeout,
|
|
keepaliveInterval: this.config.ssh.keepaliveInterval,
|
|
keepaliveCountMax: this.config.ssh.keepaliveCountMax,
|
|
debug: createNamespacedDebug("ssh2")
|
|
}
|
|
}
|
|
|
|
SSHConnection.prototype.shell = function(options) {
|
|
const self = this
|
|
return new Promise(function(resolve, reject) {
|
|
self.conn.shell(options, function(err, stream) {
|
|
if (err) {
|
|
reject(err)
|
|
} else {
|
|
self.stream = stream
|
|
resolve(stream)
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Resizes the terminal
|
|
* @param {number} rows - The number of rows
|
|
* @param {number} cols - The number of columns
|
|
*/
|
|
SSHConnection.prototype.resizeTerminal = function(rows, cols) {
|
|
if (this.stream) {
|
|
this.stream.setWindow(rows, cols)
|
|
}
|
|
}
|
|
|
|
SSHConnection.prototype.end = function() {
|
|
if (this.stream) {
|
|
this.stream.end()
|
|
this.stream = null
|
|
}
|
|
if (this.conn) {
|
|
this.conn.end()
|
|
this.conn = null
|
|
}
|
|
}
|
|
|
|
module.exports = SSHConnection
|