export declare const siteGateTemplate = "/**\n * Shared site-gate crypto. The gate cookie never stores the password itself -\n * it stores HMAC-SHA256(key=SITE_PASSWORD, data=GATE_MESSAGE) as hex. Uses Web\n * Crypto (crypto.subtle) so the same helpers run in both the Edge middleware\n * (proxy.ts) and the Node route handler (app/api/gate/route.ts).\n */\nexport const GATE_COOKIE_NAME = \"doccupine_gate\";\n\n// Bump the suffix to invalidate every previously issued cookie at once.\nconst GATE_MESSAGE = \"doccupine-gate-v1\";\n\nasync function hmacHex(key: string, data: string): Promise {\n const encoder = new TextEncoder();\n const cryptoKey = await crypto.subtle.importKey(\n \"raw\",\n encoder.encode(key),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n );\n const signature = await crypto.subtle.sign(\n \"HMAC\",\n cryptoKey,\n encoder.encode(data),\n );\n return Array.from(new Uint8Array(signature))\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n/** Derive the gate cookie token for a given password. */\nexport function gateToken(password: string): Promise {\n return hmacHex(password, GATE_MESSAGE);\n}\n\n/** Constant-time comparison so a mismatch never leaks token bytes via timing. */\nexport function timingSafeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n let mismatch = 0;\n for (let i = 0; i < a.length; i++) {\n mismatch |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return mismatch === 0;\n}\n\n/**\n * Whether the request carrying the given cookie value is allowed past the gate.\n * Returns true (open) when no password is configured.\n */\nexport async function isGateUnlocked(\n cookieValue: string | undefined,\n password: string | undefined = process.env.SITE_PASSWORD,\n): Promise {\n if (!password) return true;\n if (!cookieValue) return false;\n const expected = await gateToken(password);\n return timingSafeEqual(cookieValue, expected);\n}\n";