import { spawn } from 'node-pty'; import { isUndefined } from 'lodash'; import events from './emitter.mjs'; const xterm = { name: 'xterm-256color', cols: 80, rows: 30, }; export default class Term { static spawn(socket, args) { 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') .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', () => { term.end(); term.destroy(); events.exited(); }); } static login(socket) { socket.emit('data', 'Enter your username: '); const term = spawn('/usr/bin/env', ['sh', '-c', 'read'], 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 => { term.write(input); buf = /\177/.exec(input) ? buf.slice(0, -1) : buf + input; }) .on('disconnect', () => { term.end(); term.destroy(); reject(); }); }); } }