fixed auto fit and column/row settings for SSH, added experimental client-side logging

line wrapping should work correctly now.
experimental client side logging.
This commit is contained in:
billchurch 2017-03-23 18:12:30 -04:00
parent 3b8182fb3f
commit 17233f11de
4 changed files with 103 additions and 23 deletions

View file

@ -12,10 +12,12 @@ var io = require('socket.io')(server);
var path = require('path');
var basicAuth = require('basic-auth');
var ssh = require('ssh2');
var ssh = require('ssh2').Client;
var readConfig = require('read-config'),
config = readConfig(__dirname + '/config.json');
var myError = " - ";
var termCols;
var termRows;
function logErrors(err, req, res, next) {
console.error(err.stack);
@ -64,6 +66,10 @@ app.use(express.static(__dirname + '/public')).use(function(req, res, next) {
io.on('connection', function(socket) {
var conn = new ssh();
socket.on('geometry', function (cols, rows) {
termCols = cols;
termRows = rows;
});
conn.on('banner', function(d) {
//need to convert to cr/lf for proper formatting
d = d.replace(/\r?\n/g, "\r\n");
@ -76,7 +82,8 @@ io.on('connection', function(socket) {
socket.emit('status', 'SSH CONNECTION ESTABLISHED');
socket.emit('statusBackground', 'green');
socket.emit('allowreplay', config.options.allowreplay);
conn.shell( { term: config.ssh.term }, function(err, stream) {
conn.shell( { term: config.ssh.term, cols: termCols, rows: termRows }, function(err, stream) {
if (err) {
console.log (err.message);
myError = myError + err.message;
@ -99,6 +106,7 @@ io.on('connection', function(socket) {
}).on('close', function(code, signal) {
console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
conn.end();
socket.disconnect();
}).stderr.on('data', function(data) {
console.log('STDERR: ' + data);
});
@ -106,9 +114,11 @@ io.on('connection', function(socket) {
}).on('end', function() {
socket.emit('status', 'SSH CONNECTION CLOSED BY HOST' + myError);
socket.emit('statusBackground', 'red');
socket.disconnect();
}).on('close', function() {
socket.emit('status', 'SSH CONNECTION CLOSE' + myError);
socket.emit('statusBackground', 'red');
socket.disconnect();
}).on('error', function(err) {
myError = myError + err;
socket.emit('status', 'SSH CONNECTION ERROR' + myError);

View file

@ -15,7 +15,9 @@
<div id="bottomdiv">
<div id="footer"></div>
<div id="status"></div>
<div id="credentials"><a class="credentials" href="" onclick="return false;">CREDENTIALS</a></div>
<div id="credentials"><a class="credentials" href="javascript:void(0);" onclick="replayCredentials()">CREDENTIALS</a></div>
<div id="downloadLog"><a class="downloadLog" href="javascript:void(0);" onclick="downloadLog()">Download Log</a></div>
<div id="startLog"><a class="startLog" href="javascript:void(0);" onclick="startLog();">Start Log</a></div>
</div>
</div>
</body>

View file

@ -1,13 +1,17 @@
var sessionLog,
sessionLogEnable = false,
sessionFooter,
logDate;
document.getElementById('downloadLog').style.display = 'none';
var terminalContainer = document.getElementById('terminal-container'),
term = new Terminal({
cursorBlink: true
cursorBlink: true
}),
socket,
termid;
term.open(terminalContainer);
term.fit();
var cols = term.cols,
rows = term.rows;
if (document.location.pathname) {
var parts = document.location.pathname.split('/'),
base = parts.slice(0, parts.length - 1).join('/') + '/',
@ -18,22 +22,52 @@ if (document.location.pathname) {
} else {
socket = io.connect();
}
var credentialReplay = document.getElementById('credentials')
credentialReplay.onclick = replayCredentials;
function replayCredentials() {
socket.emit('control', 'replayCredentials');
//term.writeln('sending credentials');
return true;
console.log("replaying credentials");
return false;
}
function startLog() {
if (sessionLogEnable == true) {
sessionLogEnable = false;
document.getElementById('startLog').innerHTML = '<a class="startLog" href="javascript:void(0);" onclick="startLog();">Start Log</a>';
console.log("stopping log, " + sessionLogEnable);
currentDate = new Date();
sessionLog = sessionLog + "\r\n\r\nLog End for " + sessionFooter + ": " + currentDate.getFullYear() + "/" + (currentDate.getMonth() + 1) + "/" + currentDate.getDate() + " @ " + currentDate.getHours() + ":" + currentDate.getMinutes() + ":" + currentDate.getSeconds() + "\r\n";
logDate = currentDate;
return false;
} else {
sessionLogEnable = true;
document.getElementById('startLog').innerHTML = '<a class="startLog" href="javascript:void(0)" onclick="startLog();">Logging - STOP LOG</a>';
document.getElementById('downloadLog').style.display = 'inline';
console.log("starting log, " + sessionLogEnable);
currentDate = new Date();
sessionLog = "Log Start for " + sessionFooter + ": " + currentDate.getFullYear() + "/" + (currentDate.getMonth() + 1) + "/" + currentDate.getDate() + " @ " + currentDate.getHours() + ":" + currentDate.getMinutes() + ":" + currentDate.getSeconds() + "\r\n\r\n";
logDate = currentDate;
return false;
}
}
function downloadLog() {
myFile = "WebSSH2-" + logDate.getFullYear() + (logDate.getMonth() + 1) + logDate.getDate() + "_" + logDate.getHours() + logDate.getMinutes() + logDate.getSeconds() + ".log";
var blob = new Blob([sessionLog], {
type: 'text/plain'
});
if (window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveBlob(blob, myFile);
} else {
var elem = window.document.createElement('a');
elem.href = window.URL.createObjectURL(blob);
elem.download = myFile;
document.body.appendChild(elem);
elem.click();
document.body.removeChild(elem);
}
}
socket.emit('create', term.cols, term.rows, function(err, data) {
if (err) return self._destroy();
self.pty = data.pty;
self.id = data.id;
termid = self.id;
term.emit('open tab', self);
});
socket.on('connect', function() {
socket.emit('geometry', term.cols, term.rows);
term.on('data', function(data) {
socket.emit('data', data);
});
@ -46,26 +80,28 @@ socket.on('connect', function() {
}).on('header', function(data) {
document.getElementById('header').innerHTML = data;
}).on('footer', function(data) {
sessionFooter = data;
document.getElementById('footer').innerHTML = data;
}).on('statusBackground', function(data) {
document.getElementById('status').style.backgroundColor = data;
}).on('allowreplay', function(data) {
console.log ('allowreplay: ' + data);
if (data == 'true') {
console.log('allowreplay: ' + data);
document.getElementById('credentials').style.display = 'inline';
console.log ('display: block');
} else {
document.getElementById('credentials').style.display = 'none';
console.log ('display: none');
}
}).on('data', function(data) {
term.write(data);
if (sessionLogEnable) {
sessionLog = sessionLog + data;
}
}).on('disconnect', function() {
document.getElementById('status').style.backgroundColor = 'red';
document.getElementById('status').innerHTML = 'WEBSOCKET SERVER DISCONNECTED';
document.getElementById('status').innerHTML = 'WEBSOCKET SERVER DISCONNECTED' + err;
socket.io.reconnection(false);
}).on('error', function(err) {
document.getElementById('status').style.backgroundColor = 'red';
document.getElementById('status').innerHTML = 'ERROR ' + err;
});
});
});

View file

@ -89,4 +89,36 @@ body {
a.credentials {
color: rgb(51, 51, 51);
text-decoration: none;
}
}
#downloadLog {
display: inline-block;
color: rgb(240, 240, 240);
background-color: rgb(255, 127, 0);
padding-left: 10px;
padding-right: 10px;
border-color: white;
border-style: none solid none none;
border-width: 1px;
text-align: left;
z-index: 100;
}
a.downloadLog {
color: rgb(240, 240, 240);
text-decoration: none;
}
#startLog {
display: inline-block;
color: rgb(240, 240, 240);
background-color: rgb(0, 127, 0);
padding-left: 10px;
padding-right: 10px;
border-color: white;
border-style: none solid none none;
border-width: 1px;
text-align: left;
z-index: 100;
}
a.startLog {
color: rgb(240, 240, 240);
text-decoration: none;
}