import { handleAttachmentRoutes } from "./attachments";
import { viewerFromSessionCookie } from "./auth";
import { handleAvatarRoutes } from "./avatars";
import { handleCamoRoutes } from "./camo";
import { handleRawRoutes } from "./raw";
import { userContentUrl } from "./usercontent-grant";
import { forgeOriginFor, isUserContentOrigin, userContentOriginFor } from "./usercontent-origin";
import { isPublicUserContentPath, isUserContentPath, USERCONTENT_GRANT_PARAM } from "./usercontent-policy";
const READ_METHODS = new Set(["GET", "HEAD"]);
const PUBLIC_HOP_CACHE = "public, max-age=3600";
/** Headers every user-content response carries, whatever the handler set: no sniffing, no scripts, no cookies. */
function harden(response: Response, forgeOrigin: string): Response {
const headers = new Headers(response.headers);
headers.delete("set-cookie");
headers.set("x-content-type-options", "nosniff");
if (!headers.has("content-security-policy")) headers.set("content-security-policy", "default-src 'none'; sandbox");
headers.set("referrer-policy", "no-referrer");
headers.set("cross-origin-resource-policy", "cross-origin");
headers.set("access-control-allow-origin", forgeOrigin);
headers.set("vary", [headers.get("vary"), "Origin"].filter(Boolean).join(", "));
return new Response(response.body, { status: response.status, statusText: response.statusText, headers });
}
/**
* Requests on the user-content origin: only the read-only serving routes exist there. Anything else (pages,
* server functions, uploads, APIs) is a 404, so a payload that lands on this origin finds nothing to call.
*/
export async function handleUserContentOrigin(request: Request, url: URL): Promise<Response | null> {
if (!isUserContentOrigin(url)) return null;
const forgeOrigin = forgeOriginFor(url);
if (request.method === "OPTIONS") {
return new Response(null, {
status: 204,
headers: {
"access-control-allow-origin": forgeOrigin,
"access-control-allow-methods": "GET, HEAD",
"access-control-max-age": "86400",
},