import express from "express"; import { readFile } from "node:fs/promises"; import { execSync } from "node:child_process"; import { Server } from "socket.io"; import { io } from "socket.io-client"; import { build_html } from "har-analyzer" import fileUpload from "express-fileupload"; const app = express(); import multer from "multer" const upload = multer(); async function sleep(time) { return new Promise((resolve) => setTimeout(resolve, time)); } console.log("Waiting for full boot..."); // bidirectional forwarding // Wait untill the connection const back = io("ws://android:3000", { reconnectionAttempts: 1000000, reconnectionDelay: 100, }); while (!back.connected) { await sleep(100); } console.log("Boot detected! activating endpoints"); app.use(express.urlencoded({ extended: false })); app.use(express.static("/code/dist")); //GET app.get("/favicon.ico", function (_req, res) { res.sendFile("/code/favicon.ico"); }); app.get("/htmx.js", function (_req, res) { res.sendFile("/code/node_modules/htmx.org/dist/htmx.min.js"); }); app.get("/socket.io.js", function (_req, res) { res.sendFile("/code/node_modules/socket.io/client-dist/socket.io.js"); }); app.get("/", async function (req, res) { let fileData = (await readFile("/code/index.html")).toString(); fileData = fileData.replace( "___screenshotDelayMs___", process.env.screenshotDelayMs ); res.setHeader("Content-Type", "text/html"); res.setHeader("Content-Disposition", "inline"); res.send(fileData); }); //POST app.use(express.text({limit: "100mb"})); app.post("/inspect_har", upload.none(), function (req, res) { let body = req.body; let har = body.har; let private_data; if (body.private_data) private_data = JSON.parse(body.private_data); res.setHeader("Content-Type", "text/html"); console.log(private_data); res.send(build_html(har, private_data)); }); app.use(fileUpload()); app.post("/upload_apk", async function (req, res) { if (!req.files || Object.keys(req.files).length === 0) { return res.status(400).send("No files were uploaded."); } execSync("rm -rf /shared_buffer/*"); if (Array.isArray(req.files.app)) { for (const [idx, file] of req.files.app.entries()) { let uploadPath = "/shared_buffer/app" + idx + ".apk"; await file.mv(uploadPath); } } else { let uploadPath = "/shared_buffer/app" + 0 + ".apk"; await req.files.app.mv(uploadPath); } back.emit("install"); res.send("Files uploaded!"); }); let server = app.listen(8080, () => console.log("Listening in port 8080")); const front = new Server(server); // forwarding the messages front.on("connection", (socket) => { socket.onAny((event, ...args) => { if (back.connected) { back.emit(event, ...args); } else { console.log("Front tried to send: ", event, ...args); } }); }); back.onAny((event, ...args) => { front.emit(event, ...args); });