const express = require("express"); const fs = require("fs"); const path = require("path"); const { exec } = require("child_process"); const bcrypt = require("bcrypt"); const app = express(); app.use(express.json()); app.use(express.static(path.join(__dirname, "public"))); const usersFile = path.join(__dirname, "users.json"); const usersDir = path.join(__dirname, "users"); // Ensure `users.json` and `users/` exist if (!fs.existsSync(usersFile)) fs.writeFileSync(usersFile, JSON.stringify([])); if (!fs.existsSync(usersDir)) fs.mkdirSync(usersDir); // Helper to write logs function appendLog(username, log) { const userDir = path.join(usersDir, username); const logFile = path.join(userDir, "logs.txt"); try { // Ensure the user directory exists if (!fs.existsSync(userDir)) { fs.mkdirSync(userDir, { recursive: true }); } // Append the log to logs.txt fs.appendFileSync(logFile, log + "\n"); } catch (error) { console.error(`Error appending log for user ${username}:`, error); } } // Endpoint to handle user sign-up app.post("/signup", async (req, res) => { const { username, password } = req.body; if (!username || !password) { return res.status(400).send("Username and password are required."); } try { // Ensure the users file exists if (!fs.existsSync(usersFile)) { fs.writeFileSync(usersFile, JSON.stringify([])); } const usersData = JSON.parse(fs.readFileSync(usersFile)); if (usersData.some((user) => user.username === username)) { return res.status(400).send("User already exists."); } // Hash the password const hashedPassword = await bcrypt.hash(password, 10); // Add new user usersData.push({ username, password: hashedPassword }); fs.writeFileSync(usersFile, JSON.stringify(usersData, null, 2)); // Create user directory and logs file const userDir = path.join(usersDir, username); if (!fs.existsSync(userDir)) { fs.mkdirSync(userDir, { recursive: true }); } fs.writeFileSync(path.join(userDir, "logs.txt"), ""); res.status(200).json({ message: "User signed up successfully." }); } catch (error) { console.error("Error during signup:", error); res.status(500).send("Internal server error."); } }); // Endpoint to handle terminal commands app.post("/execute", (req, res) => { const { username, command } = req.body; const userDir = path.join(usersDir, username); if (!fs.existsSync(userDir)) { return res.status(400).send("User not found."); } const logFile = path.join(userDir, "logs.txt"); const commandParts = command.split(" "); const mainCommand = commandParts[0]; const args = commandParts.slice(1); // Spawn a child process to execute the command const child = spawn(mainCommand, args, { cwd: userDir, shell: true }); child.stdout.on("data", (data) => { const output = data.toString().trim(); appendLog(username, output); }); child.stderr.on("data", (data) => { const errorOutput = data.toString().trim(); appendLog(username, errorOutput); }); child.on("close", (code) => { appendLog(username, `Process exited with code ${code}`); }); res.send("Command executed."); }); // Endpoint to get user logs app.get("/logs", async (req, res) => { const { username } = req.query; if (!username) { return res.status(400).send("Username is required."); } const userDir = path.join(usersDir, username); const logsFile = path.join(userDir, "logs.txt"); try { const logs = await fs.readFile(logsFile, "utf8"); res.send(logs); } catch (error) { console.error("Error fetching logs:", error); res.status(404).send("Logs not found."); } }); // Endpoint for "Deploy Kaizen" app.post("/deploy", (req, res) => { const { username, repoUrl } = req.body; const userDir = path.join(usersDir, username); if (!fs.existsSync(userDir)) fs.mkdirSync(userDir, { recursive: true }); // Clear the user's directory before deployment fs.rmdirSync(userDir, { recursive: true }); fs.mkdirSync(userDir); const cloneCommand = `git clone ${repoUrl} .`; const child = exec(cloneCommand, { cwd: userDir }); child.stdout.on("data", (data) => { appendLog(username, data.trim()); }); child.stderr.on("data", (data) => { appendLog(username, data.trim()); }); child.on("close", async (code) => { appendLog(username, `Clone process exited with code ${code}`); if (code !== 0) { res.status(500).send("Error cloning repository."); return; } // Ensure package.json exists if (!fs.existsSync(path.join(userDir, "package.json"))) { appendLog(username, "No package.json found. Initializing a default one."); execSync("yarn init -y", { cwd: userDir }); } // Run yarn install and start const installStartCommand = `yarn install && yarn start`; const installChild = exec(installStartCommand, { cwd: userDir }); installChild.stdout.on("data", (data) => { appendLog(username, data.trim()); }); installChild.stderr.on("data", (data) => { appendLog(username, data.trim()); }); installChild.on("close", (installCode) => { appendLog(username, `Install/Start process exited with code ${installCode}`); if (installCode === 0) { res.send("Deployment completed successfully."); } else { res.status(500).send("Error during deployment."); } }); }); }); // Start the server app.listen(7860, () => { console.log("Server running on http://localhost:3000"); });