import express from "express"; import cors from "cors"; import fs from "fs-extra"; import path from "path"; import { spawn, exec } from "child_process"; import httpProxy from "http-proxy"; const app = express(); /* ================= CONFIGURATION ================= */ const PORT = 7860; const VITE_PORT = parseInt(process.env.VITE_PORT || "5173"); const PROJECT_DIR = path.join(process.cwd(), "project"); const MASTER_KEY = "AVNEESH_GOD_MODE_777"; const ALLOWED_ORIGINS = [ "https://avneesh123-autodev-mark2.hf.space", "https://avneesh123-autodev-mark2-engine.hf.space", "https://avneesh123-autodev-mark2.hf.space/chat", "http://localhost:5173", "http://localhost:3000", "http://127.0.0.1:5173", ]; // ================= SECURE IFRAME LOCK ================= app.use((req, res, next) => { res.removeHeader("X-Frame-Options"); res.setHeader( "Content-Security-Policy", "frame-ancestors 'self' https://*.hf.space http://localhost:* http://127.0.0.1:*" ); next(); }); // --- Process Managers --- let viteProcess = null; let isBooting = false; let buildRetryCount = 0; const MAX_RETRIES = 3; const bgProcesses = new Map(); // ================= PERSISTENT LOCK FILES ================= const FOUNDATION_LOCK = path.join(process.cwd(), ".foundation_lock"); const DEPS_LOCK = path.join(process.cwd(), ".deps_lock"); /* ================= BINARY FILE EXTENSIONS ================= */ const BINARY_EXTS = [ ".png", ".jpg", ".jpeg", ".gif", ".webp", ".ico", ".svg", ".pdf", ".zip", ".tar", ".gz", ".ttf", ".woff", ".woff2", ".otf", ".eot", ".mp3", ".mp4", ".wav" ]; function isBinaryFile(filePath) { const ext = path.extname(filePath).toLowerCase(); return BINARY_EXTS.includes(ext); } /* ================= IDLE TRACKER ================= */ let lastActivityTime = Date.now(); const IDLE_TIMEOUT = 10 * 60 * 1000; const IGNORE_ACTIVITY_PATHS = ["/api/logs", "/health", "/api/status"]; function updateActivity(req) { if (!IGNORE_ACTIVITY_PATHS.some(p => req.path.startsWith(p))) { lastActivityTime = Date.now(); } } setInterval(async () => { const idleMs = Date.now() - lastActivityTime; if (idleMs > IDLE_TIMEOUT && viteProcess) { pushLog(`[IDLE] No activity for ${Math.round(idleMs / 60000)} min — stopping Vite to save resources`, "warning"); await killVite(); bgProcesses.forEach((_, id) => killBgProcess(id)); } }, 60 * 1000); /* ================= LOG STREAM ================= */ let logs = []; let clients = new Set(); function pushLog(message, type = "info") { const entry = { id: Date.now() + Math.random(), time: new Date().toLocaleTimeString(), timestamp: Date.now(), message, type }; logs.push(entry); if (logs.length > 500) logs.shift(); const payload = `data: ${JSON.stringify(entry)}\n\n`; clients.forEach(c => { try { c.write(payload); } catch { clients.delete(c); } }); console.log(`[${type.toUpperCase()}] ${message}`); } /* ================= MIDDLEWARE ================= */ app.use(cors({ origin: (origin, callback) => { if (!origin) return callback(null, true); if (ALLOWED_ORIGINS.includes(origin) || origin.endsWith(".hf.space")) return callback(null, true); pushLog(`[SECURITY] CORS DENIED — origin: ${origin}`, "error"); callback(new Error("ACTION_DENIED")); }, credentials: true })); app.use(express.json({ limit: "50mb" })); app.use((err, req, res, next) => { if (err.message === "ACTION_DENIED") { return res.status(403).json({ error: "ACTION_DENIED", message: "Origin not allowed" }); } next(err); }); if (!fs.existsSync(PROJECT_DIR)) { fs.mkdirSync(PROJECT_DIR, { recursive: true }); } /* ================= RATE LIMITER & TOKEN SECURITY ================= */ const rateLimitMap = new Map(); function rateLimit(req, res, maxRequests = 30, windowMs = 60000) { const ip = req.ip || req.socket.remoteAddress; const now = Date.now(); const windowStart = now - windowMs; if (!rateLimitMap.has(ip)) rateLimitMap.set(ip, []); const requests = rateLimitMap.get(ip).filter(t => t > windowStart); requests.push(now); rateLimitMap.set(ip, requests); if (requests.length > maxRequests) { pushLog(`[RATE LIMIT] IP ${ip} throttled`, "warning"); res.status(429).json({ error: "TOO_MANY_REQUESTS", retryAfter: 60 }); return false; } return true; } function verifyToken(req, res) { const token = req.body?.token || req.query?.token || req.headers?.["x-api-key"]; if (token !== MASTER_KEY) { pushLog(`[SECURITY] Unauthorized access attempt from ${req.ip}`, "error"); res.status(403).json({ error: "ACTION_DENIED", message: "Invalid token" }); return false; } return true; } /* ================= SSE LOG STREAM ================= */ app.get("/api/logs", (req, res) => { res.setHeader("Content-Type", "text/event-stream"); res.setHeader("Cache-Control", "no-cache"); res.setHeader("Connection", "keep-alive"); // BUG FIX #1: X-Accel-Buffering missing tha — HF/nginx ke peeche SSE buffer // ho jaata tha, logs real-time nahi aate the client tak res.setHeader("X-Accel-Buffering", "no"); const last = parseInt(req.query.last) || 50; logs.slice(-last).forEach(l => res.write(`data: ${JSON.stringify(l)}\n\n`)); // Heartbeat — 30s mein connection alive rakhne ke liye const heartbeat = setInterval(() => { try { res.write(`: heartbeat\n\n`); } catch { clearInterval(heartbeat); } }, 30000); clients.add(res); req.on("close", () => { clients.delete(res); clearInterval(heartbeat); }); }); /* ================= MULTI-SERVER MANAGER ================= */ function startBgProcess(id, command, port = null) { if (bgProcesses.has(id)) { pushLog(`[SERVER] Process ${id} is already running`, "warning"); return false; } pushLog(`[SERVER] Starting background process [${id}]: ${command}`, "system"); const proc = spawn(command, { cwd: PROJECT_DIR, shell: true, env: { ...process.env, PORT: port ? String(port) : undefined } }); proc.stdout.on("data", d => pushLog(`[${id.toUpperCase()}] ${d.toString().trim()}`, "info")); proc.stderr.on("data", d => pushLog(`[${id.toUpperCase()} ERROR] ${d.toString().trim()}`, "error")); proc.on("close", code => { pushLog(`[SERVER] Process ${id} stopped (code: ${code})`, "system"); bgProcesses.delete(id); }); bgProcesses.set(id, { process: proc, command, port }); return true; } function killBgProcess(id) { if (!bgProcesses.has(id)) return false; const { process: proc } = bgProcesses.get(id); proc.kill("SIGKILL"); bgProcesses.delete(id); pushLog(`[SERVER] Killed background process: ${id}`, "warning"); return true; } app.post("/api/process/start", (req, res) => { if (!verifyToken(req, res)) return; const { id, command, port } = req.body; if (!id || !command) return res.status(400).json({ error: "ID and command required" }); const success = startBgProcess(id, command, port); res.json({ success, message: success ? "Process started" : "Process already running" }); }); app.post("/api/process/stop", (req, res) => { if (!verifyToken(req, res)) return; const { id } = req.body; const success = killBgProcess(id); res.json({ success, message: success ? "Process stopped" : "Process not found" }); }); /* ================= VITE MANAGER ================= */ function killVite() { return new Promise((resolve) => { if (viteProcess) { pushLog("[SYSTEM] Killing existing Vite process", "system"); viteProcess.kill("SIGKILL"); viteProcess = null; } const killCmd = process.platform === "win32" ? `for /f "tokens=5" %a in ('netstat -aon ^| findstr :${VITE_PORT}') do taskkill /F /PID %a` : `fuser -k ${VITE_PORT}/tcp`; exec(killCmd, () => setTimeout(resolve, 1500)); }); } function startVite(forceRestart = false) { if (isBooting && !forceRestart) return; if (viteProcess && !forceRestart) return; if (forceRestart) { isBooting = true; killVite().then(() => bootVite()); } else { bootVite(); } } function bootVite() { pushLog("[SYSTEM] Starting Vite dev server...", "system"); isBooting = true; const nodeModules = path.join(PROJECT_DIR, "node_modules"); const boot = () => { viteProcess = spawn("pnpm", ["run", "dev", "--", "--host", "0.0.0.0", "--port", String(VITE_PORT)], { cwd: PROJECT_DIR, shell: true, env: { ...process.env, FORCE_COLOR: "0" } }); viteProcess.stdout.on("data", d => { const msg = d.toString().trim(); if (!msg) return; pushLog("[VITE] " + msg, "info"); if (msg.includes("Local:") || msg.includes("ready in") || msg.includes("localhost")) { isBooting = false; buildRetryCount = 0; pushLog("[SYSTEM] ✅ Vite is ready!", "success"); } }); viteProcess.stderr.on("data", d => { const msg = d.toString().trim(); if (!msg) return; pushLog("[VITE ERROR] " + msg, "error"); }); viteProcess.on("close", (code) => { pushLog(`[SYSTEM] Vite stopped (exit code: ${code})`, "system"); viteProcess = null; isBooting = false; if (code !== null && code !== 0 && buildRetryCount < MAX_RETRIES) { buildRetryCount++; pushLog(`[SYSTEM] Auto-restarting Vite (attempt ${buildRetryCount}/${MAX_RETRIES})...`, "warning"); setTimeout(() => killVite().then(() => bootVite()), 3000); } }); }; if (fs.existsSync(DEPS_LOCK) && fs.existsSync(nodeModules)) { pushLog("[INSTALL] ✅ Dependencies locked — skipping install", "success"); boot(); return; } pushLog("[INSTALL] Installing dependencies...", "system"); const install = spawn("pnpm", ["install"], { cwd: PROJECT_DIR, shell: true }); install.stdout.on("data", d => pushLog("[INSTALL] " + d.toString().trim(), "info")); install.stderr.on("data", d => pushLog("[INSTALL] " + d.toString().trim(), "warning")); install.on("close", code => { if (code === 0) { fs.writeFileSync(DEPS_LOCK, new Date().toISOString()); pushLog("[INSTALL] ✅ Dependencies installed!", "success"); boot(); } else { pushLog("[ERROR] ❌ pnpm install failed!", "error"); isBooting = false; } }); } /* ================= STATUS ================= */ app.get("/api/status", (req, res) => { res.json({ ready: !!viteProcess && !isBooting, booting: isBooting, viteRunning: !!viteProcess, activeBackgroundProcesses: Array.from(bgProcesses.keys()), uptime: process.uptime(), logCount: logs.length }); }); /* ================= FILE UPDATE ================= */ app.post("/api/update", async (req, res) => { if (!verifyToken(req, res)) return; if (!rateLimit(req, res, 20, 60000)) return; updateActivity(req); const foundationAlreadyWritten = fs.existsSync(FOUNDATION_LOCK); const { files, restart = false } = req.body; try { if (files && Object.keys(files).length > 0) { const updatedFiles = []; for (const [p, contentObj] of Object.entries(files)) { const safePath = path.normalize(p).replace(/^(\.\.[\/\\])+/, ""); const fp = path.join(PROJECT_DIR, safePath); if (!fp.startsWith(PROJECT_DIR)) { pushLog(`[SECURITY] Blocked path traversal: ${p}`, "error"); continue; } await fs.ensureDir(path.dirname(fp)); // BUG FIX #2: contentObj null/undefined hone par crash hota tha // typeof check se pehle null guard lagao const fileContent = contentObj == null ? "" : typeof contentObj === "string" ? contentObj : contentObj.content ?? ""; const isBase64 = contentObj?.isBase64 || isBinaryFile(safePath); if (isBase64 && fileContent) { await fs.writeFile(fp, Buffer.from(fileContent, "base64")); } else { await fs.writeFile(fp, fileContent, "utf-8"); } updatedFiles.push(safePath); } if (!foundationAlreadyWritten) { fs.writeFileSync(FOUNDATION_LOCK, new Date().toISOString()); } pushLog(`[FILES] ✅ Updated ${updatedFiles.length} files`, "success"); } if (restart) startVite(true); else startVite(); res.json({ success: true, filesUpdated: Object.keys(files || {}).length }); } catch (e) { pushLog("[ERROR] File update failed: " + e.message, "error"); res.status(500).json({ error: e.message }); } }); /* ================= FILE READ ================= */ app.post("/api/read", async (req, res) => { if (!verifyToken(req, res)) return; updateActivity(req); const { filePath } = req.body; try { const safePath = path.normalize(filePath).replace(/^(\.\.[\/\\])+/, ""); const fp = path.join(PROJECT_DIR, safePath); if (!fp.startsWith(PROJECT_DIR)) return res.status(403).json({ error: "Path traversal blocked" }); if (!fs.existsSync(fp)) return res.status(404).json({ error: "File not found" }); const isBinary = isBinaryFile(safePath); const content = isBinary ? await fs.readFile(fp, "base64") : await fs.readFile(fp, "utf-8"); res.json({ success: true, content, path: safePath, isBase64: isBinary }); } catch (e) { res.status(500).json({ error: e.message }); } }); /* ================= FILE LIST & DELETE ================= */ app.post("/api/files", async (req, res) => { if (!verifyToken(req, res)) return; updateActivity(req); async function walkDir(dir, base = "") { const items = []; try { const entries = await fs.readdir(dir, { withFileTypes: true }); for (const entry of entries) { if (["node_modules", ".git", "dist", ".cache"].includes(entry.name)) continue; const relPath = path.join(base, entry.name); if (entry.isDirectory()) { const children = await walkDir(path.join(dir, entry.name), relPath); items.push({ name: entry.name, path: relPath, type: "dir", children }); } else { items.push({ name: entry.name, path: relPath, type: "file" }); } } } catch {} return items; } const tree = await walkDir(PROJECT_DIR); res.json({ success: true, tree }); }); app.post("/api/delete", async (req, res) => { if (!verifyToken(req, res)) return; updateActivity(req); const { filePath } = req.body; try { const safePath = path.normalize(filePath).replace(/^(\.\.[\/\\])+/, ""); const fp = path.join(PROJECT_DIR, safePath); if (!fp.startsWith(PROJECT_DIR)) return res.status(403).json({ error: "Path traversal blocked" }); await fs.remove(fp); pushLog(`[FILES] Deleted: ${safePath}`, "warning"); res.json({ success: true }); } catch (e) { res.status(500).json({ error: e.message }); } }); /* ================= COMMAND EXEC ================= */ const BLOCKED_COMMANDS = ["rm -rf /", "mkfs", ":(){ :|:& };:", "shutdown", "reboot", "format"]; app.post("/api/execute", (req, res) => { if (!verifyToken(req, res)) return; if (!rateLimit(req, res, 15, 60000)) return; updateActivity(req); const { command, timeout = 30000 } = req.body; const isBlocked = BLOCKED_COMMANDS.some(cmd => command.includes(cmd)); if (isBlocked) { pushLog(`[SECURITY] Blocked dangerous command: ${command}`, "error"); return res.status(403).json({ error: "COMMAND_BLOCKED" }); } pushLog("[TERMINAL] $ " + command, "system"); const child = exec(command, { cwd: PROJECT_DIR, timeout, maxBuffer: 1024 * 1024 * 10 }, (err, stdout, stderr) => { const output = stdout || stderr || err?.message || ""; const success = !err; const exitCode = child.exitCode ?? (err ? 1 : 0); if (success) pushLog("[TERMINAL] ✅ Done", "success"); else pushLog("[TERMINAL] ❌ " + (err?.message || "Command failed"), "error"); res.json({ success, output, exitCode }); }); }); /* ================= HEALTH CHECK ================= */ app.get("/health", (req, res) => { res.json({ status: "ok", uptime: process.uptime(), memory: process.memoryUsage(), vite: !!viteProcess, timestamp: new Date().toISOString() }); }); /* ================= VITE CONTROL & RESET ================= */ app.post("/api/vite/restart", async (req, res) => { if (!verifyToken(req, res)) return; updateActivity(req); pushLog("[SYSTEM] Manual Vite restart requested", "system"); buildRetryCount = 0; startVite(true); res.json({ success: true, message: "Vite restart initiated" }); }); app.post("/api/vite/stop", async (req, res) => { if (!verifyToken(req, res)) return; await killVite(); res.json({ success: true, message: "Vite stopped" }); }); app.post("/api/reset", async (req, res) => { if (!verifyToken(req, res)) return; try { pushLog("[SYSTEM] Resetting project...", "warning"); await killVite(); bgProcesses.forEach((_, id) => killBgProcess(id)); await fs.remove(PROJECT_DIR); fs.mkdirSync(PROJECT_DIR, { recursive: true }); if (fs.existsSync(FOUNDATION_LOCK)) fs.removeSync(FOUNDATION_LOCK); if (fs.existsSync(DEPS_LOCK)) fs.removeSync(DEPS_LOCK); buildRetryCount = 0; pushLog("[SYSTEM] ✅ Project reset complete", "success"); res.json({ success: true }); } catch (e) { res.status(500).json({ error: e.message }); } }); /* ================= PROXY ================= */ const proxy = httpProxy.createProxyServer({ target: `http://127.0.0.1:${VITE_PORT}`, changeOrigin: true, ws: true }); const PREVIEW_SECRET = "AUTODEV_PREVIEW_777"; const ACCESS_DENIED_PAGE = `