Initial commit

This commit is contained in:
Zoe
2026-08-07 22:13:25 -05:00
commit 8006fd67f3
40 changed files with 11017 additions and 0 deletions

55
server/utils/http.ts Normal file
View File

@@ -0,0 +1,55 @@
import type { H3Event } from "h3";
import { createError, getRequestHeader } from "h3";
export async function readBounded(
event: H3Event,
max: number,
): Promise<Buffer> {
const declared = getRequestHeader(event, "content-length");
if (declared && (!/^\d+$/u.test(declared) || Number(declared) > max))
throw createError({
statusCode: 413,
statusMessage: "Request body exceeds the limit.",
});
const chunks: Buffer[] = [];
let total = 0;
for await (const value of event.node.req) {
const chunk = Buffer.isBuffer(value) ? value : Buffer.from(value);
total += chunk.byteLength;
if (total > max)
throw createError({
statusCode: 413,
statusMessage: "Request body exceeds the limit.",
});
chunks.push(chunk);
}
return Buffer.concat(chunks, total);
}
export async function readJson<T>(event: H3Event, max: number): Promise<T> {
const body = await readBounded(event, max);
try {
return JSON.parse(body.toString("utf8")) as T;
} catch {
throw createError({ statusCode: 400, statusMessage: "Malformed JSON." });
}
}
export function requireContentType(event: H3Event, expected: string) {
const type = (
(getRequestHeader(event, "content-type") || "").split(";", 1)[0] || ""
)
.trim()
.toLowerCase();
if (type !== expected)
throw createError({
statusCode: 415,
statusMessage: `Content-Type must be ${expected}.`,
});
}
export function bearerToken(event: H3Event): string | undefined {
const value = getRequestHeader(event, "authorization") || "";
return /^Bearer ([A-Za-z0-9_-]{20,})$/u.exec(value)?.[1];
}
export function publicHeaders(event: H3Event) {
event.node.res.setHeader("cache-control", "no-store");
event.node.res.setHeader("referrer-policy", "no-referrer");
event.node.res.setHeader("x-content-type-options", "nosniff");
}