Skip to content
This repository has been archived by the owner on Jan 12, 2025. It is now read-only.

Commit

Permalink
chore: backport container auth to main
Browse files Browse the repository at this point in the history
  • Loading branch information
IncognitoTGT committed Oct 30, 2024
1 parent c5231f4 commit f6ce0bd
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 68 deletions.
182 changes: 115 additions & 67 deletions server/index.ts
Original file line number Diff line number Diff line change
@@ -1,84 +1,132 @@
#!/usr/bin/env tsx
if (!(await userCheck())) process.exit(1);
import { execSync } from "node:child_process";
import fs from "node:fs";
import os from "node:os";
import { homedir, hostname, tmpdir } from "node:os";
import path from "node:path";
import fastifyStatic from "@fastify/static";
import Fastify from "fastify";
async function userCheck() {
return (
await fetch(
`http://stardust-host:${process.env.STARDUST_PORT}/api/container-auth`,
{
headers: {
authorization: `${process.env.USER_ID}:${hostname()}`,
},
},
)
).ok;
}
function gateway() {
const data = fs.readFileSync("/proc/net/route", "utf8");
const lines = data.split("\n");
let defaultGateway = null;
for (const line of lines) {
const columns = line.trim().split(/\s+/);
if (columns[1] === "00000000") {
defaultGateway = columns[2];
break;
}
}

if (defaultGateway) {
return [
Number.parseInt(defaultGateway.slice(6, 8), 16),
Number.parseInt(defaultGateway.slice(4, 6), 16),
Number.parseInt(defaultGateway.slice(2, 4), 16),
Number.parseInt(defaultGateway.slice(0, 2), 16),
].join(".");
}
}
const app = Fastify({
logger: true,
logger: true,
});
const home = os.homedir();
const tmp = os.tmpdir();

app.get("/healthcheck", (_req, res) => res.send({ message: "Stardust Container Agent is running" }));
app.get("/password", (_req, res) => res.send(process.env.VNCPASSWORD));
app.get("/screenshot", async (_req, res) => {
fs.mkdirSync(`${tmp}/screenshots`, { recursive: true });
const path = `${tmp}/screenshots/window.png`;
execSync(`DISPLAY=:1 import -window root ${path}`);
const image = fs.readFileSync(path);
fs.unlinkSync(path);
res.header("Content-Type", "image/png").send(image);
app.addHook("onRequest", async (req, res) => {
const check = await userCheck();
const allowedHosts = [gateway(), "127.0.0.1"];
if (!check) {
return res.code(404).send({ error: "Not found" });
}
if (!allowedHosts.includes(req.ip)) {
return res.code(404).send({ error: "Not found" });
}
return req;
});
app.get("/healthcheck", (_req, res) =>
res.send({ message: "Stardust Container Agent is running" }),
);
app.get("/password", async (_req, res) => res.send(process.env.VNCPASSWORD));
app.get("/screenshot", (_req, res) => {
fs.mkdirSync(`${tmpdir()}/screenshots`, { recursive: true });
const path = `${tmpdir()}/screenshots/window.png`;
execSync(`DISPLAY=:1 import -window root ${path}`);
const image = fs.readFileSync(path);
fs.unlinkSync(path);
res.header("Content-Type", "image/png").send(image);
});
app.get("/files/list", () => {
fs.mkdirSync(`${home}/Downloads`, { recursive: true });
const files = fs.readdirSync(`${home}/Downloads`);
return files;
fs.mkdirSync(`${homedir()}/Downloads`, { recursive: true });
const files = fs.readdirSync(`${homedir()}/Downloads`);
return files;
});
app.get("/files/download/:name", (req, res) => {
const { name: fileName } = req.params as { name: string };
if (!fileName) {
console.log("No file name provided");
return res.code(404).send({ error: "No file name provided" });
}
try {
const file = fs.readFileSync(`${home}/Downloads/${fileName}`);
res.send(file);
} catch (e) {
console.log(e);
res.code(500).send({ error: "File not found" });
}
const { name: fileName } = req.params as { name: string };
if (!fileName) {
console.log("No file name provided");
return res.code(404).send({ error: "No file name provided" });
}
try {
const file = fs.readFileSync(`${homedir()}/Downloads/${fileName}`);
res.send(file);
} catch (e) {
console.log(e);
res.code(404).send({ error: "File not found" });
}
});
app.addContentTypeParser("*", (_request, payload, done) => done(null, payload));
app.put("/files/upload/:name", async (req, res) => {
const { name: fileName } = req.params as { name: string };
if (!fileName) {
console.log("No file name provided");
return res.code(404).send({ error: "No file name provided" });
}
app
.put("/files/upload/:name", async (req, res) => {
const { name: fileName } = req.params as { name: string };
if (!fileName) {
console.log("No file name provided");
return res.code(404).send({ error: "No file name provided" });
}

try {
fs.mkdirSync(`${home}/Uploads`, { recursive: true });
const fileStream = fs.createWriteStream(`${home}/Uploads/${fileName}`);
await new Promise<void>((resolve, reject) => {
req.raw.on("data", (chunk) => {
fileStream.write(chunk);
});
req.raw.on("end", () => {
fileStream.end();
resolve();
});
req.raw.on("error", (err) => {
console.log(err);
fileStream.end();
fs.unlinkSync(`${home}/Uploads/${fileName}`);
reject(err);
});
});
console.log(`File ${fileName} uploaded`);
res.send({ success: true });
} catch (e) {
console.log(e);
res.status(500).send({ error: "Upload failed" });
}
});
app.register(fastifyStatic, {
root: path.join(import.meta.dirname, "static"),
});
try {
fs.mkdirSync(`${homedir()}/Uploads`, { recursive: true });
const fileStream = fs.createWriteStream(
`${homedir()}/Uploads/${fileName}`,
);
await new Promise<void>((resolve, reject) => {
req.raw
.on("data", (chunk) => {
fileStream.write(chunk);
})
.on("end", () => {
fileStream.end();
resolve();
})
.on("error", (err) => {
console.log(err);
fileStream.end();
fs.unlinkSync(`${homedir()}/Uploads/${fileName}`);
reject(err);
});
});
console.log(`File ${fileName} uploaded`);
res.send({ success: true });
} catch (e) {
console.log(e);
res.status(500).send({ error: "Upload failed" });
}
})
.register(fastifyStatic, {
root: path.join(import.meta.dirname, "static"),
});
try {
await app.listen({ port: 6080, host: "0.0.0.0" });
await app.listen({ port: 6080, host: "0.0.0.0" });
} catch (err) {
app.log.error(err);
process.exit(1);
}
app.log.error(err);
process.exit(1);
}
2 changes: 1 addition & 1 deletion server/static/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ window.addEventListener("load", () => {
.then((res) => res.json())
.then((/** @type {String[]} */ data) => {
if (data.length === 0) {
document.getElementById("fileslist").innerHTML = `
document.getElementById("fileslist").innerHTML =`
<div class="relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground">
<i data-lucide="info" class="size-4"></i>
<p class="mb-1 font-medium leading-none tracking-tight">There are no files in the container.</p>
Expand Down

0 comments on commit f6ce0bd

Please sign in to comment.