cp dines
This commit is contained in:
parent
0904cbcfbb
commit
17d9c480cf
4 changed files with 80 additions and 56 deletions
BIN
app/client/public/favicon.ico
Normal file
BIN
app/client/public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
File diff suppressed because one or more lines are too long
|
@ -44,10 +44,22 @@ term.loadAddon(fitAddon);
|
||||||
term.open(terminalContainer);
|
term.open(terminalContainer);
|
||||||
term.focus();
|
term.focus();
|
||||||
fitAddon.fit();
|
fitAddon.fit();
|
||||||
|
//get uri param for devbox
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const devboxId = urlParams.get('devboxId');
|
||||||
|
const sessionId = urlParams.get('sessionId');
|
||||||
|
|
||||||
const socket = io({
|
const socket = io({
|
||||||
path: '/ssh/socket.io',
|
path: '/ssh/socket.io',
|
||||||
transports: ['websocket'],
|
transports: ['websocket'],
|
||||||
|
extraHeaders: {
|
||||||
|
Authorization: `Bearer ${localStorage.getItem('token')}`,
|
||||||
|
DevboxId: devboxId,
|
||||||
|
},
|
||||||
|
query: {
|
||||||
|
sessionId,
|
||||||
|
devboxId,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// cross browser method to "download" an element to the local system
|
// cross browser method to "download" an element to the local system
|
||||||
|
|
|
@ -27,14 +27,16 @@ function tlsProxyConnect(hostname, callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main function to establish the SSH connection over the TLS proxy
|
// Main function to establish the SSH connection over the TLS proxy
|
||||||
async function establishConnection(conn, targetDevbox, bearerToken) {
|
async function establishConnection(conn, socket, targetDevbox, bearerToken) {
|
||||||
const runloop = new Runloop({
|
const runloop = new Runloop({
|
||||||
baseURL: 'https://api.runloop.pro',
|
baseURL: 'https://api.runloop.pro',
|
||||||
// This is gotten by just inspecting the browser cookies on platform.runloop.pro
|
// This is gotten by just inspecting the browser cookies on platform.runloop.pro
|
||||||
bearerToken,
|
bearerToken,
|
||||||
});
|
});
|
||||||
|
try {
|
||||||
|
console.log(`Creating SSH key for devbox ${targetDevbox}`);
|
||||||
const sshKeyCreateResp = await runloop.devboxes.createSSHKey(targetDevbox);
|
const sshKeyCreateResp = await runloop.devboxes.createSSHKey(targetDevbox);
|
||||||
|
|
||||||
const hostname = sshKeyCreateResp.url;
|
const hostname = sshKeyCreateResp.url;
|
||||||
|
|
||||||
// SS KEY
|
// SS KEY
|
||||||
|
@ -68,6 +70,10 @@ async function establishConnection(conn, targetDevbox, bearerToken) {
|
||||||
debug: debug('ssh2'),
|
debug: debug('ssh2'),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
socket.disconnect(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO deal with
|
//TODO deal with
|
||||||
|
@ -76,7 +82,7 @@ let termRows;
|
||||||
|
|
||||||
// public
|
// public
|
||||||
module.exports = function appSocket(socket) {
|
module.exports = function appSocket(socket) {
|
||||||
const conn = new Client();
|
const connection = new Client();
|
||||||
async function setupConnection() {
|
async function setupConnection() {
|
||||||
// TODO AUTH?
|
// TODO AUTH?
|
||||||
// if websocket connection arrives without an express session, kill it
|
// if websocket connection arrives without an express session, kill it
|
||||||
|
@ -91,16 +97,16 @@ module.exports = function appSocket(socket) {
|
||||||
termCols = cols;
|
termCols = cols;
|
||||||
termRows = rows;
|
termRows = rows;
|
||||||
});
|
});
|
||||||
conn.on('banner', (data) => {
|
connection.on('banner', (data) => {
|
||||||
// need to convert to cr/lf for proper formatting
|
// need to convert to cr/lf for proper formatting
|
||||||
socket.emit('data', data.replace(/\r?\n/g, '\r\n').toString('utf-8'));
|
socket.emit('data', data.replace(/\r?\n/g, '\r\n').toString('utf-8'));
|
||||||
});
|
});
|
||||||
|
|
||||||
conn.on('ready', () => {
|
connection.on('ready', () => {
|
||||||
// debugWebSSH2(
|
// debugWebSSH2(
|
||||||
// `WebSSH2 Login: user=${socket.request.session.username} from=${socket.handshake.address} host=${socket.request.session.ssh.host} port=${socket.request.session.ssh.port} sessionID=${socket.request.sessionID}/${socket.id} mrhsession=${socket.request.session.ssh.mrhsession} allowreplay=${socket.request.session.ssh.allowreplay} term=${socket.request.session.ssh.term}`,
|
// `WebSSH2 Login: user=${socket.request.session.username} from=${socket.handshake.address} host=${socket.request.session.ssh.host} port=${socket.request.session.ssh.port} sessionID=${socket.request.sessionID}/${socket.id} mrhsession=${socket.request.session.ssh.mrhsession} allowreplay=${socket.request.session.ssh.allowreplay} term=${socket.request.session.ssh.term}`,
|
||||||
// );
|
// );
|
||||||
conn.shell(
|
connection.shell(
|
||||||
{
|
{
|
||||||
term: 'xterm-color',
|
term: 'xterm-color',
|
||||||
cols: termCols,
|
cols: termCols,
|
||||||
|
@ -109,8 +115,8 @@ module.exports = function appSocket(socket) {
|
||||||
(err, stream) => {
|
(err, stream) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
// SSHerror(`EXEC ERROR${err}`);
|
// SSHerror(`EXEC ERROR${err}`);
|
||||||
socket.close();
|
socket.disconnect(true);
|
||||||
conn.end();
|
connection.end();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
socket.on('data', (data) => {
|
socket.on('data', (data) => {
|
||||||
|
@ -136,16 +142,16 @@ module.exports = function appSocket(socket) {
|
||||||
});
|
});
|
||||||
socket.on('disconnect', (reason) => {
|
socket.on('disconnect', (reason) => {
|
||||||
debugWebSSH2(`SOCKET DISCONNECT: ${reason}`);
|
debugWebSSH2(`SOCKET DISCONNECT: ${reason}`);
|
||||||
//const errMsg = { message: reason };
|
// const errMsg = { message: reason };
|
||||||
// SSHerror('CLIENT SOCKET DISCONNECT', errMsg);
|
// SSHerror('CLIENT SOCKET DISCONNECT', errMsg);
|
||||||
socket.close();
|
socket.disconnect(true);
|
||||||
conn.end();
|
connection.end();
|
||||||
// socket.request.session.destroy()
|
// socket.request.session.destroy()
|
||||||
});
|
});
|
||||||
socket.on('error', (errMsg) => {
|
socket.on('error', (errMsg) => {
|
||||||
// SSHerror('SOCKET ERROR', errMsg);
|
// SSHerror('SOCKET ERROR', errMsg);
|
||||||
socket.close();
|
socket.disconnect(true);
|
||||||
conn.end();
|
connection.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
stream.on('data', (data) => {
|
stream.on('data', (data) => {
|
||||||
|
@ -160,9 +166,9 @@ module.exports = function appSocket(socket) {
|
||||||
(signal ? `SIGNAL: ${signal}` : '')
|
(signal ? `SIGNAL: ${signal}` : '')
|
||||||
: undefined,
|
: undefined,
|
||||||
};
|
};
|
||||||
//SSHerror('STREAM CLOSE', errMsg);
|
// SSHerror('STREAM CLOSE', errMsg);
|
||||||
socket.close();
|
socket.disconnect(true);
|
||||||
conn.end();
|
connection.end();
|
||||||
});
|
});
|
||||||
stream.stderr.on('data', (data) => {
|
stream.stderr.on('data', (data) => {
|
||||||
console.error(`STDERR: ${data}`);
|
console.error(`STDERR: ${data}`);
|
||||||
|
@ -171,13 +177,13 @@ module.exports = function appSocket(socket) {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
conn.on('end', (err) => {
|
connection.on('end', (err) => {
|
||||||
//SSHerror('CONN END BY HOST', err);
|
//SSHerror('CONN END BY HOST', err);
|
||||||
});
|
});
|
||||||
conn.on('close', (err) => {
|
connection.on('close', (err) => {
|
||||||
//SSHerror('CONN CLOSE', err);
|
//SSHerror('CONN CLOSE', err);
|
||||||
});
|
});
|
||||||
conn.on('error', (err) => {
|
connection.on('error', (err) => {
|
||||||
//SSHerror('CONN ERROR', err);
|
//SSHerror('CONN ERROR', err);
|
||||||
});
|
});
|
||||||
// conn.on('keyboard-interactive', (name, instructions, instructionsLang, prompts, finish) => {
|
// conn.on('keyboard-interactive', (name, instructions, instructionsLang, prompts, finish) => {
|
||||||
|
@ -200,12 +206,18 @@ module.exports = function appSocket(socket) {
|
||||||
// keepaliveCountMax: socket.request.session.ssh.keepaliveCountMax,
|
// keepaliveCountMax: socket.request.session.ssh.keepaliveCountMax,
|
||||||
// debug: debug('ssh2'),
|
// debug: debug('ssh2'),
|
||||||
// });
|
// });
|
||||||
|
const devboxId = socket.request._query.devboxId;
|
||||||
await establishConnection(
|
if (!devboxId) {
|
||||||
conn,
|
console.error('No devboxId');
|
||||||
'dbx_2xb6oS1G1e6TAihVMtjn6',
|
throw new Error('No devboxId');
|
||||||
'ss_eyJhbGciOiJIUzI1NiIsImtpZCI6IkEyZExNNUlheFE4L29acW4iLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2t5aGpvaG1xbXFrdmZxc2t4dnNkLnN1cGFiYXNlLmNvL2F1dGgvdjEiLCJzdWIiOiI5NmRlMTVjZC1lZWJmLTRjNzctODQwNy1jZTkwNzNlZTZkMjIiLCJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzI1NDg1NTQwLCJpYXQiOjE3MjU0ODE5NDAsImVtYWlsIjoiYWxleEBydW5sb29wLmFpIiwicGhvbmUiOiIiLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCIsInByb3ZpZGVycyI6WyJlbWFpbCIsImdpdGh1YiJdfSwidXNlcl9tZXRhZGF0YSI6eyJhdmF0YXJfdXJsIjoiaHR0cHM6Ly9hdmF0YXJzLmdpdGh1YnVzZXJjb250ZW50LmNvbS91LzE2MDA3NzkyND92PTQiLCJlbWFpbCI6ImFsZXhAcnVubG9vcC5haSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJmdWxsX25hbWUiOiJBbGV4YW5kZXIgRGluZXMiLCJpc3MiOiJodHRwczovL2FwaS5naXRodWIuY29tIiwibmFtZSI6IkFsZXhhbmRlciBEaW5lcyIsInBob25lX3ZlcmlmaWVkIjpmYWxzZSwicHJlZmVycmVkX3VzZXJuYW1lIjoiZGluZXMtcmwiLCJwcm92aWRlcl9pZCI6IjE2MDA3NzkyNCIsInN1YiI6IjE2MDA3NzkyNCIsInVzZXJfbmFtZSI6ImRpbmVzLXJsIn0sInJvbGUiOiJhdXRoZW50aWNhdGVkIiwiYWFsIjoiYWFsMSIsImFtciI6W3sibWV0aG9kIjoib2F1dGgiLCJ0aW1lc3RhbXAiOjE3MjM1OTAxODB9XSwic2Vzc2lvbl9pZCI6IjU5MjhkZTIxLTI3M2ItNDkzNC1iMGFmLThlYWE3MDUxOGE3MiIsImlzX2Fub255bW91cyI6ZmFsc2V9.Qby46q2eDZUWjpPPSvmyzQ5bGKGEkpg2r9zBAUTpc3Q',
|
}
|
||||||
);
|
const sessionId = socket.request._query.sessionId;
|
||||||
|
if (!sessionId) {
|
||||||
|
console.error('No sessionId');
|
||||||
|
throw new Error('No sessionId');
|
||||||
|
}
|
||||||
|
console.log(sessionId);
|
||||||
|
await establishConnection(connection, socket, devboxId, sessionId);
|
||||||
}
|
}
|
||||||
setupConnection();
|
setupConnection();
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue