spb/cancerindex
Public
TypeScript 97.2%
SQL 1.5%
CSS 0.6%
JavaScript 0.5%
1import { NextResponse, type NextRequest } from 'next/server';2import { createHash } from 'node:crypto';34const ADMIN_COOKIE = 'ci_admin';56/**7 * Request proxy (Next 16 name for middleware): exchanges `/admin…?token=<ADMIN_TOKEN>` for the8 * httpOnly admin cookie and redirects to the same URL without the token, so the token never stays9 * in the address bar or in server logs beyond the first hit.10 */11export function proxy(req: NextRequest) {12 const url = req.nextUrl;13 if (url.pathname.startsWith('/admin') && url.searchParams.has('token')) {14 const token = url.searchParams.get('token') ?? '';15 const expected = process.env.ADMIN_TOKEN ?? '';16 const clean = url.clone();17 clean.searchParams.delete('token');18 const res = NextResponse.redirect(clean);19 if (expected && token === expected) {20 res.cookies.set(ADMIN_COOKIE, createHash('sha256').update(token).digest('hex'), { httpOnly: true, sameSite: 'lax', secure: process.env.NODE_ENV === 'production', path: '/', maxAge: 60 * 60 * 12 });21 }22 return res;23 }24 return NextResponse.next();25}2627export const config = { matcher: ['/admin/:path*', '/admin'] };28