import { HttpError } from "./errors"; /* There is deliberately no authentication (access is controlled by firewall * rules). The one guard: mutating requests from a browser must originate * from this app, so a page on another site can't POST to the LAN service. */ function checkOrigin(req: Request): void { const origin = req.headers.get("origin"); if (!origin) return; // curl and other non-browser clients let originHost: string; try { originHost = new URL(origin).host; } catch { throw new HttpError(403, "bad origin"); } if (originHost !== req.headers.get("host")) throw new HttpError(403, "cross-origin request refused"); } /** Wraps a route handler: origin check for writes + HttpError -> JSON response. */ export function route(handler: (req: Request, ctx: C) => Promise) { return async (req: Request, ctx: C): Promise => { try { if (req.method !== "GET" && req.method !== "HEAD") checkOrigin(req); return await handler(req, ctx); } catch (err) { if (err instanceof HttpError) { return Response.json({ error: err.message, details: err.details }, { status: err.status }); } console.error("[blog-manager]", err); return Response.json({ error: "internal error" }, { status: 500 }); } }; } export async function readJson>(req: Request): Promise { try { return (await req.json()) as T; } catch { throw new HttpError(400, "request body must be JSON"); } }