| const express = require('express'); |
| const http = require('http'); |
| const { Server } = require('socket.io'); |
| const Convert = require('ansi-to-html'); |
| const { exec } = require('child_process'); |
| const path = require('path'); |
|
|
| const app = express(); |
| const server = http.createServer(app); |
| const io = new Server(server, { |
| cors: { origin: "*" } |
| }); |
|
|
| const PORT = 7860; |
|
|
| |
| const convert = new Convert({ |
| fg: '#e2e8f0', |
| bg: '#0b1020', |
| newline: true, |
| escapeXML: true |
| }); |
|
|
| |
| let logs = []; |
| const MAX_LOGS = 10000; |
|
|
| function formatLog(data) { |
| return { |
| html: convert.toHtml(data.message || ''), |
| level: data.level || 'info', |
| timestamp: new Date() |
| }; |
| } |
|
|
| function addLog(log) { |
| logs.push(log); |
| if (logs.length > MAX_LOGS) logs.shift(); |
| } |
|
|
| |
| app.use(express.static(path.join(__dirname, 'public'))); |
|
|
| |
| app.get('/api/logs', (req, res) => { |
| const limit = parseInt(req.query.limit) || 50; |
| const offset = parseInt(req.query.offset) || 0; |
|
|
| const start = Math.max(logs.length - offset - limit, 0); |
| const end = logs.length - offset; |
|
|
| const slice = logs.slice(start, end); |
|
|
| res.json({ |
| logs: slice, |
| hasMore: start > 0 |
| }); |
| }); |
|
|
| |
| io.on('connection', (socket) => { |
| console.log('Client connected:', socket.id); |
|
|
| socket.on('log', (data) => { |
| const log = formatLog(data); |
| addLog(log); |
| io.emit('log', log); |
| }); |
|
|
| socket.on('command', (data) => { |
| const cmd = data.command.trim(); |
| if (!cmd) return; |
|
|
| if (cmd === "clear") { |
| logs = []; |
| return; |
| } |
|
|
| const blocked = ['rm', 'shutdown', 'reboot', 'mkfs']; |
| if (blocked.some(b => cmd.includes(b))) { |
| const log = formatLog({ |
| message: "\x1b[31mBlocked command!\x1b[0m", |
| level: "error" |
| }); |
| addLog(log); |
| return io.emit('log', log); |
| } |
|
|
| const cmdLog = formatLog({ |
| message: "\x1b[32m$ " + cmd + "\x1b[0m" |
| }); |
|
|
| addLog(cmdLog); |
| io.emit('log', cmdLog); |
|
|
| exec(cmd, { timeout: 20000 }, (error, stdout, stderr) => { |
|
|
| if (stdout) { |
| const outLog = formatLog({ message: stdout }); |
| addLog(outLog); |
| io.emit('log', outLog); |
| } |
|
|
| if (stderr) { |
| const errLog = formatLog({ |
| message: "\x1b[31m" + stderr + "\x1b[0m", |
| level: "error" |
| }); |
| addLog(errLog); |
| io.emit('log', errLog); |
| } |
|
|
| if (error) { |
| const errLog = formatLog({ |
| message: "\x1b[31m" + error.message + "\x1b[0m", |
| level: "error" |
| }); |
| addLog(errLog); |
| io.emit('log', errLog); |
| } |
| }); |
| }); |
| }); |
|
|
| server.listen(PORT, () => { |
| console.log('🚀 Server running on http://localhost:' + PORT); |
| }); |