| 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"); |
|
|
| |
| if (!fs.existsSync(usersFile)) fs.writeFileSync(usersFile, JSON.stringify([])); |
| if (!fs.existsSync(usersDir)) fs.mkdirSync(usersDir); |
|
|
| |
| function appendLog(username, log) { |
| const userDir = path.join(usersDir, username); |
| const logFile = path.join(userDir, "logs.txt"); |
|
|
| try { |
| |
| if (!fs.existsSync(userDir)) { |
| fs.mkdirSync(userDir, { recursive: true }); |
| } |
|
|
| |
| fs.appendFileSync(logFile, log + "\n"); |
| } catch (error) { |
| console.error(`Error appending log for user ${username}:`, error); |
| } |
| } |
|
|
| |
| 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 { |
| |
| 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."); |
| } |
|
|
| |
| const hashedPassword = await bcrypt.hash(password, 10); |
|
|
| |
| usersData.push({ username, password: hashedPassword }); |
| fs.writeFileSync(usersFile, JSON.stringify(usersData, null, 2)); |
|
|
| |
| 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."); |
| } |
| }); |
|
|
| |
| 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); |
|
|
| |
| 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."); |
| }); |
|
|
| |
| 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."); |
| } |
| }); |
|
|
| |
| 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 }); |
|
|
| |
| 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; |
| } |
|
|
| |
| if (!fs.existsSync(path.join(userDir, "package.json"))) { |
| appendLog(username, "No package.json found. Initializing a default one."); |
| execSync("yarn init -y", { cwd: userDir }); |
| } |
|
|
| |
| 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."); |
| } |
| }); |
| }); |
| }); |
|
|
| |
| app.listen(7860, () => { |
| console.log("Server running on http://localhost:3000"); |
| }); |