forked from snxraven/sshChat-CLI
Refreactor to add a command handler
This commit is contained in:
174
sshChat.js
Normal file
174
sshChat.js
Normal file
@ -0,0 +1,174 @@
|
||||
const Hyperswarm = require('hyperswarm')
|
||||
const crypto = require('hypercore-crypto')
|
||||
const b4a = require('b4a')
|
||||
const readline = require('readline')
|
||||
const fs = require("fs");
|
||||
const { login } = require('./commands/login');
|
||||
const { execute } = require('./commands/exec');
|
||||
const { stop } = require('./commands/stop');
|
||||
const { start } = require('./commands/start');
|
||||
const { restart } = require('./commands/restart');
|
||||
const { stats } = require('./commands/stats');
|
||||
const { changeDir } = require('./commands/cd');
|
||||
const { AIRequest } = require('./commands/AI');
|
||||
|
||||
let rand = Math.floor(Math.random() * 99999).toString();
|
||||
|
||||
let USERPWD = "/"
|
||||
let DAPI_KEY
|
||||
let USERNAME = "anon" + rand
|
||||
let LOGGEDIN = false
|
||||
let MYKEY = []
|
||||
let conns = []
|
||||
|
||||
|
||||
|
||||
function sleep(ms) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(resolve, ms);
|
||||
});
|
||||
}
|
||||
|
||||
async function clearCursor() {
|
||||
readline.moveCursor(process.stdout, 0, -2) // up one line
|
||||
readline.clearLine(process.stdout, 0) // from cursor to end
|
||||
readline.moveCursor(process.stdout, 0, 2) // up one line
|
||||
}
|
||||
|
||||
// Generate a random public key
|
||||
const publicKey = crypto.randomBytes(32)
|
||||
|
||||
// Create the swarm and pass in the public key
|
||||
const swarm = new Hyperswarm()
|
||||
|
||||
const commandDir = './commands/';
|
||||
const commandFiles = fs.readdirSync(commandDir);
|
||||
|
||||
const commands = {}
|
||||
|
||||
for (const file of commandFiles) {
|
||||
const commandName = file.split(".")[0]
|
||||
require(`${commandDir}/${file}`)
|
||||
const command = require(`${commandDir}/${file}`);
|
||||
commands[commandName] = command;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function handleCommand(input) {
|
||||
if (input.startsWith("!") || input.startsWith(">")) {
|
||||
const command = input.split(" ")
|
||||
switch (command[0]) {
|
||||
case "!":
|
||||
AIRequest(command.slice(1).join(" "))
|
||||
break;
|
||||
case ">cd":
|
||||
USERPWD = await changeDir(command[1], USERPWD);
|
||||
console.log(USERPWD)
|
||||
break;
|
||||
case ">stats":
|
||||
stats(MYKEY[0])
|
||||
break;
|
||||
case ">":
|
||||
execute(MYKEY[0], command.slice(1), USERPWD);
|
||||
break;
|
||||
case ">restart":
|
||||
restart(MYKEY[0])
|
||||
break;
|
||||
case ">stop":
|
||||
stop(MYKEY[0])
|
||||
break;
|
||||
case ">start":
|
||||
start(MYKEY[0])
|
||||
break;
|
||||
case ">login":
|
||||
login(command[1], conns, MYKEY)
|
||||
break;
|
||||
default:
|
||||
console.log("Command not found.")
|
||||
}
|
||||
} else {
|
||||
for (const conn of conns)
|
||||
if (input.startsWith("!") || input.startsWith(">")){
|
||||
|
||||
}else {
|
||||
conn.write(`${USERNAME}: ${input}`)
|
||||
}
|
||||
}
|
||||
console.log(`${USERNAME}: ${input}`)
|
||||
clearCursor()
|
||||
|
||||
}
|
||||
|
||||
swarm.on('connection', conn => {
|
||||
|
||||
process.on('SIGINT', async () => {
|
||||
console.log("Sending close message...")
|
||||
for (let conn of conns) {
|
||||
conn.write(`CLOSED: ${publicKey.toString('hex')}`)
|
||||
}
|
||||
|
||||
await sleep(2000)
|
||||
process.exit()
|
||||
|
||||
})
|
||||
|
||||
const name = b4a.toString(conn.remotePublicKey, 'hex')
|
||||
console.log(`* got a connection from ${name} (${USERNAME}) *`)
|
||||
conns.push(conn)
|
||||
conn.once('close', () => conns.splice(conns.indexOf(conn), 1))
|
||||
conn.on('data', data => {
|
||||
if (data.toString().startsWith('CLOSED:')) {
|
||||
// Extract the key from the message string
|
||||
const key = data.toString().split(':')[1].trim();
|
||||
console.log(`Removing peer ${key}`);
|
||||
(async () => {
|
||||
|
||||
await sleep(5000)
|
||||
conns = conns.filter(c => c !== conn);
|
||||
conn.destroy();
|
||||
})();
|
||||
|
||||
} else {
|
||||
console.log(`${data}`)
|
||||
}
|
||||
// Use the USERNAME if it has been set, otherwise use the public key
|
||||
})
|
||||
})
|
||||
|
||||
swarm.on('error', (err) => {
|
||||
console.log('Error connecting to peer:', err);
|
||||
});
|
||||
|
||||
// Use readline to accept input from the user
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
})
|
||||
|
||||
// When the user inputs a line of text, broadcast it to all connections
|
||||
rl.on('line', input => {
|
||||
handleCommand(input)
|
||||
})
|
||||
|
||||
// Join a common topic
|
||||
const topic = process.argv[2] ? b4a.from(process.argv[2], 'hex') : crypto.randomBytes(32)
|
||||
|
||||
setTimeout(() => {
|
||||
const discovery = swarm.join(topic, {
|
||||
lookup: true,
|
||||
announce: true,
|
||||
timeout: 300000
|
||||
|
||||
});
|
||||
|
||||
// The flushed promise will resolve when the topic has been fully announced to the DHT
|
||||
discovery.flushed().then(() => {
|
||||
console.log(`joined topic: ${b4a.toString(topic, 'hex')}\n(Share this key to others so they may join.)`)
|
||||
console.log('You are now in a chatroom for your topic, feel free to chat.\n')
|
||||
console.log('Want to login to the SSH.SURF API? Type ">login [APIKEY]" to login.\n\n')
|
||||
})
|
||||
}, 1000);
|
||||
|
||||
|
Reference in New Issue
Block a user