135 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| const { Client: SSHClient } = require('ssh2');
 | |
| 
 | |
| let sshConnection = null;
 | |
| 
 | |
| module.exports = {
 | |
|     name: 'ssh',
 | |
|     description: 'Manage an SSH connection. Subcommands: connect, exec, disconnect',
 | |
|     async execute(message, args, deleteTimeout) {
 | |
|         if (!args.length) {
 | |
|             return message.channel
 | |
|                 .send("Usage: `.ssh <connect|exec|disconnect> ...`")
 | |
|                 .then((msg) => setTimeout(() => msg.delete().catch(() => { }), deleteTimeout));
 | |
|         }
 | |
| 
 | |
|         const subcommand = args.shift().toLowerCase();
 | |
| 
 | |
|         if (subcommand === 'connect') {
 | |
|             if (args.length < 3) {
 | |
|                 return message.channel
 | |
|                     .send("Usage: `.ssh connect <host> <username> <password> [port]`")
 | |
|                     .then((msg) => setTimeout(() => msg.delete().catch(() => { }), deleteTimeout));
 | |
|             }
 | |
| 
 | |
|             if (sshConnection) {
 | |
|                 return message.channel
 | |
|                     .send("Already connected. Disconnect first using `.ssh disconnect`.")
 | |
|                     .then((msg) => setTimeout(() => msg.delete().catch(() => { }), deleteTimeout));
 | |
|             }
 | |
| 
 | |
|             const host = args[0];
 | |
|             const username = args[1];
 | |
|             const password = args[2];
 | |
|             const port = args[3] ? parseInt(args[3]) : 22;
 | |
| 
 | |
|             sshConnection = new SSHClient();
 | |
| 
 | |
|             sshConnection
 | |
|                 .on('ready', () => {
 | |
|                     message.channel
 | |
|                         .send(`Connected to ${host}`)
 | |
|                         .then((msg) => setTimeout(() => msg.delete().catch(() => { }), deleteTimeout));
 | |
|                 })
 | |
|                 .on('error', (err) => {
 | |
|                     message.channel
 | |
|                         .send(`SSH Connection error: ${err.message}`)
 | |
|                         .then((msg) => setTimeout(() => msg.delete().catch(() => { }), deleteTimeout));
 | |
|                     sshConnection = null;
 | |
|                 })
 | |
|                 .on('close', () => {
 | |
|                     message.channel
 | |
|                         .send(`SSH Connection closed.`)
 | |
|                         .then((msg) => setTimeout(() => msg.delete().catch(() => { }), deleteTimeout));
 | |
|                     sshConnection = null;
 | |
|                 });
 | |
| 
 | |
|             sshConnection.connect({ host, port, username, password });
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         else if (subcommand === 'exec') {
 | |
|             if (!sshConnection) {
 | |
|                 return message.channel
 | |
|                     .send("No active SSH connection. Connect first using `.ssh connect ...`")
 | |
|                     .then((msg) => setTimeout(() => msg.delete().catch(() => { }), deleteTimeout));
 | |
|             }
 | |
|             if (!args.length) {
 | |
|                 return message.channel
 | |
|                     .send("Usage: `.ssh exec <command>`")
 | |
|                     .then((msg) => setTimeout(() => msg.delete().catch(() => { }), deleteTimeout));
 | |
|             }
 | |
| 
 | |
|             const cmd = args.join(' ');
 | |
| 
 | |
|             sshConnection.exec(cmd, (err, stream) => {
 | |
|                 if (err) {
 | |
|                     return message.channel
 | |
|                         .send(`Error executing command: ${err.message}`)
 | |
|                         .then((msg) => setTimeout(() => msg.delete().catch(() => { }), deleteTimeout));
 | |
|                 }
 | |
| 
 | |
|                 let outputBuffer = '';
 | |
| 
 | |
|                 message.channel.send(`Executing command: \`${cmd}\`\n\`\`\`\n...\n\`\`\``)
 | |
|                     .then((sentMsg) => {
 | |
|                         const updateInterval = setInterval(() => {
 | |
|                             let display = outputBuffer;
 | |
|                             if (display.length > 1900) {
 | |
|                                 display = display.slice(-1900);
 | |
|                             }
 | |
|                             sentMsg.edit(`Executing command: \`${cmd}\`\n\`\`\`\n${display}\n\`\`\``)
 | |
|                                 .catch(() => { });
 | |
|                         }, 2000);
 | |
| 
 | |
|                         stream.on('data', (data) => {
 | |
|                             outputBuffer += data.toString();
 | |
|                         });
 | |
|                         stream.stderr.on('data', (data) => {
 | |
|                             outputBuffer += data.toString();
 | |
|                         });
 | |
|                         stream.on('close', (code, signal) => {
 | |
|                             clearInterval(updateInterval);
 | |
|                             outputBuffer += `\nProcess exited with code ${code}${signal ? ' and signal ' + signal : ''}`;
 | |
|                             let display = outputBuffer;
 | |
|                             if (display.length > 1900) {
 | |
|                                 display = display.slice(-1900);
 | |
|                             }
 | |
|                             sentMsg.edit(`Executing command: \`${cmd}\`\n\`\`\`\n${display}\n\`\`\``)
 | |
|                                 .catch(() => { });
 | |
|                         });
 | |
|                     })
 | |
|                     .catch(console.error);
 | |
|             });
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         else if (subcommand === 'disconnect') {
 | |
|             if (!sshConnection) {
 | |
|                 return message.channel
 | |
|                     .send("No active SSH connection.")
 | |
|                     .then((msg) => setTimeout(() => msg.delete().catch(() => { }), deleteTimeout));
 | |
|             }
 | |
|             sshConnection.end();
 | |
|             sshConnection = null;
 | |
|             return message.channel
 | |
|                 .send("Disconnecting SSH...")
 | |
|                 .then((msg) => setTimeout(() => msg.delete().catch(() => { }), deleteTimeout));
 | |
|         }
 | |
| 
 | |
|         else {
 | |
|             return message.channel
 | |
|                 .send("Unknown subcommand. Use `connect`, `exec`, or `disconnect`.")
 | |
|                 .then((msg) => setTimeout(() => msg.delete().catch(() => { }), deleteTimeout));
 | |
|         }
 | |
|     },
 | |
| }; |