From d9fdb8b35ec08d9cd1cee6b56fc69b83a52c9030 Mon Sep 17 00:00:00 2001 From: Mathias Wagner Date: Thu, 1 Jun 2023 18:10:23 +0200 Subject: [PATCH] Created the app handler --- server/handler/app.js | 80 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 server/handler/app.js diff --git a/server/handler/app.js b/server/handler/app.js new file mode 100644 index 0000000..dba51be --- /dev/null +++ b/server/handler/app.js @@ -0,0 +1,80 @@ +const {Client} = require("ssh2"); +const fs = require("fs"); + +const services = fs.readdirSync(__dirname + "/apps").map((item) => item.replace(".js", "")); +module.exports = (io, socket) => { + let session = new Client(); + let connected = false; + let queue = []; + + socket.on("disconnect", () => session.end()); + + socket.on("login", (msg) => { + if (session._sock || connected) return; + + session.on("ready", () => { + connected = true; + socket.emit("login", {status: "success"}); + }).connect({host: msg.host, port: msg.port || 22, username: msg.username || "root", + password: msg.password, privateKey: msg.privateKey + }).on("error", (err) => { + socket.emit("login", {status: "failed", message: err.message}); + }); + }); + + const execQueue = () => { + if (queue.length === 0) { + socket.emit("install", {status: "finished"}); + return; + } + + const {command, step} = queue[0]; + + session.exec(command, (err, stream) => { + if (err) return socket.emit("install", {status: "failed", message: err.message, step}); + stream.on("close", (code) => { + if (code !== 0) { + queue = []; + return socket.emit("install", {status: "failed", message: "Error while installing", step}); + } + socket.emit("install", {status: "success", step}); + queue.shift(); + execQueue(); + }).on("data", () => {}); + }); + } + + socket.on("install", (msg) => { + if (!connected) return socket.emit("install", {status: "failed", message: "Not connected"}); + if (queue.length > 0) return socket.emit("install", {status: "failed", message: "Another installation is in progress"}); + + const serviceName = msg.name.toLowerCase(); + + if (!services.includes(serviceName)) return socket.emit("install", {status: "failed", message: "Service not found"}); + + const app = require(`./apps/${serviceName}`); + + let infoData = []; + + app.steps.map((mappedItem, index) => { + let item = {...mappedItem}; + Object.keys(app.variables).map((key) => { + item.command = item.command.replace(new RegExp(`{${key}}`, "g"), msg.data[key] || app.variables[key]); + }); + + if (item.condition) { + const [key, value] = item.condition.split("="); + if (msg?.data[key] !== value) return; + } + + queue.push({...item, step: index+1}); + + if (item.description) + infoData.push({description: item.description, step: index+1}); + }); + + socket.emit("install", {status: "info", data: infoData}); + + execQueue(); + }); +} \ No newline at end of file