forked from syntaxbullet/AuroraBot-discord
50 lines
1.9 KiB
TypeScript
50 lines
1.9 KiB
TypeScript
import { homeRoute } from "./routes/home";
|
|
import { healthRoute } from "./routes/health";
|
|
import { dashboardRoute } from "./routes/dashboard";
|
|
import { file } from "bun";
|
|
import { join, resolve } from "path";
|
|
|
|
export async function router(request: Request): Promise<Response> {
|
|
const url = new URL(request.url);
|
|
const method = request.method;
|
|
|
|
// Resolve the absolute path to the public directory
|
|
const publicDir = resolve(import.meta.dir, "public");
|
|
|
|
if (method === "GET") {
|
|
// Handle Static Files
|
|
// We handle requests starting with /public/ OR containing an extension (like /style.css)
|
|
if (url.pathname.startsWith("/public/") || url.pathname.includes(".")) {
|
|
// Normalize path: remove /public prefix if present so that
|
|
// /public/style.css and /style.css both map to .../public/style.css
|
|
const relativePath = url.pathname.replace(/^\/public/, "");
|
|
|
|
// Resolve full path
|
|
const normalizedRelative = relativePath.startsWith("/") ? "." + relativePath : relativePath;
|
|
const requestedPath = resolve(publicDir, normalizedRelative);
|
|
|
|
// Security Check: Block Path Traversal
|
|
if (requestedPath.startsWith(publicDir)) {
|
|
const staticFile = file(requestedPath);
|
|
if (await staticFile.exists()) {
|
|
return new Response(staticFile);
|
|
}
|
|
} else {
|
|
return new Response("Forbidden", { status: 403 });
|
|
}
|
|
}
|
|
|
|
if (url.pathname === "/" || url.pathname === "/index.html") {
|
|
return homeRoute();
|
|
}
|
|
if (url.pathname === "/health") {
|
|
return healthRoute();
|
|
}
|
|
if (url.pathname === "/dashboard") {
|
|
return dashboardRoute();
|
|
}
|
|
}
|
|
|
|
return new Response("Not Found", { status: 404 });
|
|
}
|