fix: address security review findings, implement real cache clearing, and fix lifecycle promises

This commit is contained in:
syntaxbullet
2026-01-08 21:29:09 +01:00
parent 0f6cce9b6e
commit 19206b5cc7
11 changed files with 176 additions and 47 deletions

View File

@@ -100,7 +100,16 @@ export async function createWebServer(config: WebServerConfig = {}): Promise<Web
// Administrative Actions
if (url.pathname.startsWith("/api/actions/") && req.method === "POST") {
try {
// Security Check: Token-based authentication
const { env } = await import("@shared/lib/env");
const authHeader = req.headers.get("Authorization");
if (authHeader !== `Bearer ${env.ADMIN_TOKEN}`) {
console.warn(`⚠️ [API] Unauthorized administrative action attempt from ${req.headers.get("x-forwarded-for") || "unknown"}`);
return new Response("Unauthorized", { status: 401 });
}
const { actionService } = await import("@shared/modules/admin/action.service");
const { MaintenanceModeSchema } = await import("@shared/modules/dashboard/dashboard.types");
if (url.pathname === "/api/actions/reload-commands") {
const result = await actionService.reloadCommands();
@@ -113,8 +122,14 @@ export async function createWebServer(config: WebServerConfig = {}): Promise<Web
}
if (url.pathname === "/api/actions/maintenance-mode") {
const body = await req.json() as { enabled: boolean; reason?: string };
const result = await actionService.toggleMaintenanceMode(body.enabled, body.reason);
const rawBody = await req.json();
const parsed = MaintenanceModeSchema.safeParse(rawBody);
if (!parsed.success) {
return Response.json({ error: "Invalid payload", issues: parsed.error.issues }, { status: 400 });
}
const result = await actionService.toggleMaintenanceMode(parsed.data.enabled, parsed.data.reason);
return Response.json(result);
}
} catch (error) {
@@ -141,19 +156,30 @@ export async function createWebServer(config: WebServerConfig = {}): Promise<Web
const fileRef = Bun.file(safePath);
if (await fileRef.exists()) {
// If serving index.html, inject env vars for frontend
if (pathName === "/index.html") {
let html = await fileRef.text();
const { env } = await import("@shared/lib/env");
const envScript = `<script>window.AURORA_ENV = { ADMIN_TOKEN: "${env.ADMIN_TOKEN}" };</script>`;
html = html.replace("</head>", `${envScript}</head>`);
return new Response(html, { headers: { "Content-Type": "text/html" } });
}
return new Response(fileRef);
}
// SPA Fallback: Serve index.html for unknown non-file routes
// If the path looks like a file (has extension), return 404
// Otherwise serve index.html
const parts = pathName.split("/");
const lastPart = parts[parts.length - 1];
if (lastPart?.includes(".")) {
return new Response("Not Found", { status: 404 });
}
return new Response(Bun.file(join(distDir, "index.html")));
const indexFile = Bun.file(join(distDir, "index.html"));
let indexHtml = await indexFile.text();
const { env: sharedEnv } = await import("@shared/lib/env");
const script = `<script>window.AURORA_ENV = { ADMIN_TOKEN: "${sharedEnv.ADMIN_TOKEN}" };</script>`;
indexHtml = indexHtml.replace("</head>", `${script}</head>`);
return new Response(indexHtml, { headers: { "Content-Type": "text/html" } });
},
websocket: {