sshChat-CLI/sshChat.mjs

283 lines
7.8 KiB
JavaScript
Raw Normal View History

2023-01-08 22:03:13 -05:00
import Hyperswarm from 'hyperswarm'
import goodbye from 'graceful-goodbye'
import crypto from 'hypercore-crypto'
import b4a from 'b4a'
import readline from 'readline'
import unirest from "unirest";
let rand = Math.floor(Math.random() * 99999).toString();
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
2023-01-08 22:03:13 -05:00
// Generate a random public key
const publicKey = crypto.randomBytes(32)
// Create the swarm and pass in the public key
const swarm = new Hyperswarm()
// goodbye(() => {
// const message = `CLOSED: ${publicKey.toString('hex')}`;
// for (let conn of conns) {
// conn.write(message);
// }
// });
2023-01-08 22:03:13 -05:00
// Keep track of all connections and USERNAMEs
const conns = []
2023-01-08 22:59:49 -05:00
let USERPWD = "/"
2023-01-08 22:03:13 -05:00
let DAPI_KEY = {}
let USERNAME = "anon" + rand
2023-01-08 22:03:13 -05:00
let LOGGEDIN = false
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
}
// API Functions
async function getUSERNAME(key) {
let requestUSERNAME = await unirest
.get('https://api.discord-linux.com/hello')
.headers({ 'Accept': 'application/json', 'Content-Type': 'application/json', 'x-discord-linux-auth': key })
return requestUSERNAME.body.message.replace("Hello, ", "").replace("!", "")
}
2023-01-08 22:59:49 -05:00
async function runCMD(key, cmd, pwd) {
2023-01-08 22:03:13 -05:00
let requestData = await unirest
2023-01-08 22:59:49 -05:00
.post('https://api.discord-linux.com/exec')
.headers({
'Accept': 'application/json', 'Content-Type': 'application/json',
'x-discord-linux-auth': key
})
.send({ "cmd": cmd, "pwd": pwd })
2023-01-08 22:03:13 -05:00
return requestData.body.stdout
}
2023-01-08 22:59:49 -05:00
async function startContainer(key) {
2023-01-08 22:03:13 -05:00
let startContainer = await unirest
2023-01-08 22:59:49 -05:00
.get('https://api.discord-linux.com/start')
.headers({
'Accept': 'application/json', 'Content-Type': 'application/json',
'x-discord-linux-auth': key
})
2023-01-08 23:39:13 -05:00
return startContainer.body
2023-01-08 22:03:13 -05:00
}
2023-01-08 22:59:49 -05:00
async function stopContainer(key) {
2023-01-08 22:03:13 -05:00
let stopContainer = await unirest
2023-01-08 22:59:49 -05:00
.get('https://api.discord-linux.com/stop')
.headers({
'Accept': 'application/json', 'Content-Type': 'application/json',
'x-discord-linux-auth': key
})
2023-01-08 23:39:13 -05:00
return stopContainer.body
2023-01-08 22:03:13 -05:00
}
2023-01-08 22:59:49 -05:00
async function restartContainer(key) {
2023-01-08 22:03:13 -05:00
let restartContainer = await unirest
2023-01-08 22:59:49 -05:00
.get('https://api.discord-linux.com/restart')
.headers({
'Accept': 'application/json', 'Content-Type': 'application/json',
'x-discord-linux-auth': key
})
2023-01-08 23:39:13 -05:00
return restartContainer.body
2023-01-08 22:03:13 -05:00
}
2023-01-08 22:59:49 -05:00
async function getStats(key) {
2023-01-08 22:03:13 -05:00
let getStats = await unirest
2023-01-08 23:39:13 -05:00
.get('https://api.discord-linux.com/stats')
2023-01-08 22:59:49 -05:00
.headers({
'Accept': 'application/json', 'Content-Type': 'application/json',
'x-discord-linux-auth': key
})
2023-01-08 23:39:13 -05:00
return getStats.body
2023-01-08 22:03:13 -05:00
}
2023-01-09 00:43:54 -05:00
async function AIRequest(prompt) {
let AIRequest = await unirest
.post('https://codex-ai-v9q6.onrender.com/')
.headers({ 'Accept': 'application/json', 'Content-Type': 'application/json' })
.send({ "prompt": prompt })
2023-01-09 00:43:54 -05:00
return AIRequest.body.bot
}
2023-01-08 22:03:13 -05:00
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()
})
2023-01-08 22:03:13 -05:00
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();
// Iterate through the conns array and remove the client with the matching key
for (let i = 0; i < conns.length; i++) {
if (conns[i].key === key) {
conns.splice(i, 1);
break;
}
}
} else {
console.log(`${data}`)
}
2023-01-08 22:03:13 -05:00
// Use the USERNAME if it has been set, otherwise use the public key
})
})
swarm.on('error', (err) => {
console.log('Error connecting to peer:', err);
});
2023-01-08 22:03:13 -05:00
// 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 => {
const signIn = input.match(/^\/login (\S+)$/)
if (signIn) {
const APIKEY = signIn[1]
DAPI_KEY = { "key": APIKEY }
getUSERNAME(APIKEY).then((data) => {
USERNAME = data
// const name = b4a.toString(publicKey, 'hex')
// names[name] = USERNAME
for (const conn of conns) {
conn.write(`${USERNAME} has logged in!`)
}
clearCursor()
2023-01-08 22:59:49 -05:00
console.log(`Welcome ${USERNAME} you are now logged in!`)
return LOGGEDIN = true
2023-01-08 22:03:13 -05:00
});
}
2023-01-08 22:59:49 -05:00
const changeDir = input.startsWith(">cd") || input.startsWith("> cd")
if (changeDir) {
const commandArgs = input.replace("> cd ", "").replace(">cd", "").replace(" ", "")
if (commandArgs.startsWith("/")) {
USERPWD = commandArgs;
console.log("Directory Changed to: " + USERPWD)
} else {
USERPWD = USERPWD + "/" + commandArgs;
console.log("Directory Changed to: " + USERPWD)
}
}
2023-01-08 22:03:13 -05:00
const execute = input.startsWith(">")
if (input.startsWith("/") || input.startsWith("!")) return
2023-01-08 22:03:13 -05:00
if (execute) {
let inputdata = input.split(2)
2023-01-08 22:59:49 -05:00
const cmdToRun = inputdata.join(" ").replace("> ", "").replace(">", "")
if (cmdToRun.includes("cd")) return
2023-01-08 23:43:46 -05:00
runCMD(DAPI_KEY.key, cmdToRun, USERPWD).then((data) => {
2023-01-08 22:03:13 -05:00
console.log(data)
for (const conn of conns) {
conn.write(`${USERNAME} ran ${cmdToRun}: \n` + data)
}
2023-01-08 22:59:49 -05:00
})
}
2023-01-08 22:03:13 -05:00
2023-01-09 00:43:54 -05:00
const AI = input.startsWith("!")
if (AI) {
let inputdata = input.split(2)
2023-01-09 00:45:56 -05:00
const prompt = inputdata.join(" ").replace("! ", "").replace("!", "")
2023-01-09 00:43:54 -05:00
AIRequest(prompt).then((data) => {
console.log(data)
for (const conn of conns) {
conn.write(`${USERNAME} ran ${cmdToRun}: \n` + data)
}
})
}
2023-01-08 23:39:13 -05:00
const start = input.startsWith("/start")
2023-01-08 22:59:49 -05:00
if (start) {
startContainer(DAPI_KEY.key).then((data) => {
2023-01-08 23:39:13 -05:00
console.log(data)
2023-01-08 22:59:49 -05:00
for (const conn of conns) {
2023-01-08 23:41:53 -05:00
conn.write(`${USERNAME} ran start.`)
2023-01-08 22:59:49 -05:00
}
})
}
2023-01-08 22:03:13 -05:00
2023-01-08 23:39:13 -05:00
const stop = input.startsWith("/stop")
2023-01-08 22:59:49 -05:00
if (stop) {
2023-01-08 23:47:16 -05:00
stopContainer(DAPI_KEY.key).then((data) => {
2023-01-08 23:39:13 -05:00
console.log(data)
2023-01-08 22:59:49 -05:00
for (const conn of conns) {
2023-01-08 23:41:53 -05:00
conn.write(`${USERNAME} ran stop.`)
2023-01-08 22:59:49 -05:00
}
})
}
2023-01-08 22:03:13 -05:00
2023-01-08 23:39:13 -05:00
const restart = input.startsWith("/restart")
2023-01-08 22:59:49 -05:00
if (restart) {
2023-01-09 00:43:54 -05:00
restartContainer(DAPI_KEY.key).then((data) => {
2023-01-08 23:39:13 -05:00
console.log(data)
2023-01-08 22:59:49 -05:00
for (const conn of conns) {
2023-01-08 23:41:53 -05:00
conn.write(`${USERNAME} ran restart.`)
2023-01-08 22:59:49 -05:00
}
})
}
2023-01-08 23:39:13 -05:00
const stats = input.startsWith("/stats")
2023-01-08 22:59:49 -05:00
if (stats) {
getStats(DAPI_KEY.key).then((data) => {
2023-01-08 23:39:13 -05:00
console.log(data)
2023-01-08 22:59:49 -05:00
for (const conn of conns) {
2023-01-08 23:41:53 -05:00
conn.write(`${USERNAME} ran stats.`)
2023-01-08 22:59:49 -05:00
}
})
}
2023-01-08 22:03:13 -05:00
else {
// if (!LOGGEDIN) return console.log("Please login using /login [API KEY]")
2023-01-09 00:43:54 -05:00
if (input.startsWith("/") || input.startsWith("!")) return
2023-01-08 22:03:13 -05:00
for (const conn of conns) {
conn.write(`${USERNAME}: ${input}`)
}
console.log(`${USERNAME}: ${input}`)
// Clear the input line\
clearCursor()
}
})
// 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);