sitegen/src/friend-auth.ts

76 lines
2.1 KiB
TypeScript
Raw Normal View History

2025-07-07 20:58:02 -07:00
let friendPassword = "";
try {
friendPassword = require("./friends/hardcoded-password.ts").friendPassword;
} catch {}
export const app = new Hono();
const cookieAge = 60 * 60 * 24 * 30; // 1 month
function checkFriendsCookie(c: Context) {
const cookie = c.req.header("Cookie");
if (!cookie) return false;
const cookies = cookie.split("; ").map((x) => x.split("="));
return cookies.some(
(kv) =>
kv[0].trim() === "friends_password" &&
kv[1].trim() &&
kv[1].trim() === friendPassword,
);
}
export function requireFriendAuth(c: Context) {
const k = c.req.query("password") || c.req.query("k");
if (k) {
if (k === friendPassword) {
return c.body(null, 303, {
Location: "/friends",
"Set-Cookie":
`friends_password=${k}; Path=/; HttpOnly; SameSite=Strict; Max-Age=${cookieAge}`,
});
} else {
return c.body(null, 303, {
Location: "/friends",
});
}
}
if (checkFriendsCookie(c)) {
return undefined;
} else {
return serveAsset(c, "/friends/auth", 403);
}
}
app.get("/friends", (c) => {
const friendAuthChallenge = requireFriendAuth(c);
if (friendAuthChallenge) return friendAuthChallenge;
return serveAsset(c, "/friends", 200);
});
let incorrectMap: Record<string, boolean> = {};
app.post("/friends", async (c) => {
const ip = c.header("X-Forwarded-For") ?? getConnInfo(c).remote.address ??
"unknown";
if (incorrectMap[ip]) {
return serveAsset(c, "/friends/auth/fail", 403);
}
const data = await c.req.formData();
const k = data.get("password");
if (k === friendPassword) {
return c.body(null, 303, {
Location: "/friends",
"Set-Cookie":
`friends_password=${k}; Path=/; HttpOnly; SameSite=Strict; Max-Age=${cookieAge}`,
});
}
incorrectMap[ip] = true;
await setTimeout(2500);
incorrectMap[ip] = false;
return serveAsset(c, "/friends/auth/fail", 403);
});
import { type Context, Hono } from "hono";
import { serveAsset } from "#sitegen/assets";
import { setTimeout } from "node:timers/promises";
import { getConnInfo } from "#hono/conninfo";