import { NextRequest, NextResponse } from "next/server"; /** * Защита для локальной разработки. * Если задана env ALLOWED_IPS — пропускает только эти IP. * Если задана env DEV_ACCESS_KEY — требует ?key=... или cookie dev_access_key. * В проде (DOMAIN задан) — middleware пропускает всё. */ export function middleware(req: NextRequest) { // В проде — пропускаем if (process.env.DOMAIN) { return NextResponse.next(); } const devAccessKey = process.env.DEV_ACCESS_KEY; const allowedIps = process.env.ALLOWED_IPS; // "192.168.1.10,192.168.1.11" // Проверка IP whitelist if (allowedIps) { const clientIp = req.headers.get("x-forwarded-for")?.split(",")[0]?.trim() || req.headers.get("x-real-ip") || "unknown"; const allowed = allowedIps.split(",").map((ip) => ip.trim()); // localhost всегда разрешён if ( !allowed.includes(clientIp) && clientIp !== "127.0.0.1" && clientIp !== "::1" && clientIp !== "unknown" ) { return new NextResponse("Forbidden", { status: 403 }); } } // Проверка access key if (devAccessKey) { const url = new URL(req.url); const keyParam = url.searchParams.get("key"); const keyCookie = req.cookies.get("dev_access_key")?.value; // Если ключ в query — ставим cookie и редиректим без key if (keyParam === devAccessKey) { url.searchParams.delete("key"); const res = NextResponse.redirect(url); res.cookies.set("dev_access_key", devAccessKey, { httpOnly: true, maxAge: 60 * 60 * 24 * 7, // 7 дней path: "/", }); return res; } // Если нет валидной cookie — блокируем if (keyCookie !== devAccessKey) { return new NextResponse( "Access denied. Add ?key=YOUR_DEV_ACCESS_KEY to URL.", { status: 403 } ); } } return NextResponse.next(); } export const config = { // Защищаем всё кроме статики и API вебхуков matcher: ["/((?!_next/static|_next/image|favicon.ico|api/livekit/webhook).*)"], };