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";
|