|
|
@@ -9,6 +9,12 @@ const app = new Hono<{ Bindings: CloudflareBindings; Variables: Variables }>();
|
|
|
|
|
|
const LIMITS = { name: 50, question: 280, option: 100, constraint: 200, constraints: 8 } as const;
|
|
|
const HAND_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
|
+const SECURITY_HEADERS = {
|
|
|
+ "Content-Security-Policy": "default-src 'self'; script-src 'self'; connect-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'self'",
|
|
|
+ "Permissions-Policy": "camera=(), microphone=(), geolocation=()",
|
|
|
+ "Referrer-Policy": "no-referrer",
|
|
|
+ "X-Content-Type-Options": "nosniff",
|
|
|
+} as const;
|
|
|
|
|
|
async function jsonBody(c: any): Promise<Record<string, unknown> | null> {
|
|
|
try {
|
|
|
@@ -30,6 +36,7 @@ app.use("*", async (c, next) => {
|
|
|
const session = await auth.api.getSession({ headers: c.req.raw.headers }).catch(() => null);
|
|
|
c.set("me", session ? { id: session.user.id, name: session.user.name || "anon" } : null);
|
|
|
await next();
|
|
|
+ for (const [name, value] of Object.entries(SECURITY_HEADERS)) c.header(name, value);
|
|
|
});
|
|
|
|
|
|
app.all("/api/auth/*", c => c.get("auth").handler(c.req.raw));
|