You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
2.0 KiB
80 lines
2.0 KiB
import { spawn } from 'node-pty';
|
|
import { isUndefined } from 'lodash';
|
|
import events from './emitter';
|
|
|
|
const xterm = {
|
|
name: 'xterm-256color',
|
|
cols: 80,
|
|
rows: 30,
|
|
cwd: process.cwd(),
|
|
env: process.env,
|
|
};
|
|
|
|
export default class Term {
|
|
public static spawn(socket: SocketIO.Socket, args: string[]): void {
|
|
const term = spawn('/usr/bin/env', args, xterm);
|
|
const address = args[0] === 'ssh' ? args[1] : 'localhost';
|
|
events.spawned(term.pid, address);
|
|
socket.emit('login');
|
|
term.on('exit', code => {
|
|
events.exited(code, term.pid);
|
|
socket.emit('logout');
|
|
socket
|
|
.removeAllListeners('disconnect')
|
|
.removeAllListeners('resize')
|
|
.removeAllListeners('input');
|
|
});
|
|
term.on('data', data => {
|
|
socket.emit('data', data);
|
|
});
|
|
socket
|
|
.on('resize', ({ cols, rows }) => {
|
|
term.resize(cols, rows);
|
|
})
|
|
.on('input', input => {
|
|
if (!isUndefined(term)) term.write(input);
|
|
})
|
|
.on('disconnect', () => {
|
|
const { pid } = term;
|
|
term.kill();
|
|
events.exited(0, pid);
|
|
});
|
|
}
|
|
|
|
public static login(socket: SocketIO.Socket): Promise<string> {
|
|
|
|
// Check request-header for username
|
|
const remoteUser = socket.request.headers['remote-user'];
|
|
if (remoteUser) {
|
|
return new Promise(resolve => {
|
|
resolve(remoteUser);
|
|
});
|
|
}
|
|
|
|
// Request carries no username information
|
|
// Create terminal and ask user for username
|
|
const term = spawn(
|
|
'/usr/bin/env',
|
|
['node', `${__dirname}/buffer.js`],
|
|
xterm
|
|
);
|
|
let buf = '';
|
|
return new Promise((resolve, reject) => {
|
|
term.on('exit', () => {
|
|
resolve(buf);
|
|
});
|
|
term.on('data', data => {
|
|
socket.emit('data', data);
|
|
});
|
|
socket
|
|
.on('input', (input: string) => {
|
|
term.write(input);
|
|
buf = /\177/.exec(input) ? buf.slice(0, -1) : buf + input;
|
|
})
|
|
.on('disconnect', () => {
|
|
term.kill();
|
|
reject();
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|