diff --git a/app/api/gate/route.ts b/app/api/gate/route.ts deleted file mode 100644 index 6cd1b78..0000000 --- a/app/api/gate/route.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { NextResponse } from 'next/server'; - -// Verifies the temporary site password (see middleware.ts) and, on success, -// sets an httpOnly cookie that the middleware checks. Reads the password from -// SITE_PASSWORD; nothing is hardcoded. - -export const runtime = 'nodejs'; - -const COOKIE = 'site_gate'; -const MAX_AGE_SECONDS = 60 * 60 * 24 * 7; // 7 days - -export async function POST(request: Request) { - const password = process.env.SITE_PASSWORD; - - // Gate disabled (no password configured) -> nothing to verify. - if (!password) { - return NextResponse.json({ ok: true }); - } - - let provided = ''; - try { - const body: unknown = await request.json(); - if (body && typeof body === 'object' && 'password' in body) { - provided = String((body as { password: unknown }).password); - } - } catch { - provided = ''; - } - - if (provided !== password) { - return NextResponse.json({ ok: false }, { status: 401 }); - } - - const res = NextResponse.json({ ok: true }); - res.cookies.set(COOKIE, password, { - httpOnly: true, - secure: true, - sameSite: 'strict', - path: '/', - maxAge: MAX_AGE_SECONDS, - }); - return res; -} diff --git a/middleware.ts b/middleware.ts index d78502c..f9a62b0 100644 --- a/middleware.ts +++ b/middleware.ts @@ -2,21 +2,6 @@ import { NextRequest, NextResponse } from 'next/server'; import { disabledRoutePrefixes } from './deploy.config.mjs'; -// TEMPORARY site-wide password gate. -// -// Active only when SITE_PASSWORD is set. Set it in Vercel's Production -// environment so the gate shows on production only; leave it unset for local -// dev and preview. The password itself is never committed — it lives in the -// env var. -// -// The gate covers UI pages only. /api/* is intentionally left public so the -// snapshots API stays reachable by external consumers. -// -// To remove the gate later: delete this file and app/api/gate/route.ts, and -// unset SITE_PASSWORD in Vercel. - -const COOKIE = 'site_gate'; - export function middleware(req: NextRequest) { // Surfaces not shipped to this build target (deploy.config.mjs) 404 at the // edge. This is the authoritative status block: a disabled section's page may @@ -30,83 +15,10 @@ export function middleware(req: NextRequest) { } } - const password = process.env.SITE_PASSWORD; - - // No password configured (local dev / preview) -> no gate. - if (!password || process.env.NODE_ENV === 'development') { - return NextResponse.next(); - } - - if (req.cookies.get(COOKIE)?.value === password) { - return NextResponse.next(); - } - - return new NextResponse(gateHtml(), { - status: 401, - headers: { - 'content-type': 'text/html; charset=utf-8', - 'cache-control': 'no-store', - }, - }); + return NextResponse.next(); } // Match everything except the public API, Next internals, and static assets. export const config = { matcher: ['/((?!api/|_next/static|_next/image|favicon.ico|robots.txt|sitemap.xml).*)'], }; - -// Self-contained gate screen (no app layout / external assets), posts the -// password to /api/gate and reloads on success. -function gateHtml(): string { - return ` - -
- - - -