import createMiddleware from "next-intl/middleware"; import { NextResponse } from "next/server"; import type { NextRequest } from "next/server"; import { routing } from "./i18n/routing"; import { getRequestHostname, isAdminHost, isInternalAdminPath, isLegacyAdminPath, toInternalAdminPath, } from "./lib/admin-routing"; const intlMiddleware = createMiddleware(routing); function isRootBasicAuthConfigured(): boolean { return Boolean(process.env.ROOT_BASIC_AUTH_USER && process.env.ROOT_BASIC_AUTH_PASS); } function isRootBasicAuthValid(request: NextRequest): boolean { if (!isRootBasicAuthConfigured()) { return false; } const header = request.headers.get("authorization"); if (!header || !header.startsWith("Basic ")) { return false; } try { const decoded = atob(header.slice(6)); const index = decoded.indexOf(":"); if (index === -1) { return false; } const user = decoded.slice(0, index); const pass = decoded.slice(index + 1); return ( user === process.env.ROOT_BASIC_AUTH_USER && pass === process.env.ROOT_BASIC_AUTH_PASS ); } catch { return false; } } export default async function middleware(request: NextRequest) { const { pathname } = request.nextUrl; const hostname = getRequestHostname( request.headers.get("x-forwarded-host") ?? request.headers.get("host") ?? request.nextUrl.hostname, ); const isAdminRequest = isAdminHost(hostname); const rootRobotsHeaders = { "X-Robots-Tag": "noindex, nofollow, noarchive, nosnippet, noimageindex", }; if (isInternalAdminPath(pathname) || isLegacyAdminPath(pathname)) { return new NextResponse("Not Found", { status: 404, }); } if (isAdminRequest) { if (isRootBasicAuthConfigured() && !isRootBasicAuthValid(request)) { return new NextResponse("Authentication required", { status: 401, headers: { "WWW-Authenticate": 'Basic realm="Root Area", charset="UTF-8"', ...rootRobotsHeaders, }, }); } const rewriteUrl = request.nextUrl.clone(); rewriteUrl.pathname = toInternalAdminPath(pathname); const response = NextResponse.rewrite(rewriteUrl); response.headers.set("X-Robots-Tag", rootRobotsHeaders["X-Robots-Tag"]); return response; } if (pathname === "/de" || pathname.startsWith("/de/")) { const redirectUrl = request.nextUrl.clone(); const nextPath = pathname.slice(3) || "/"; redirectUrl.pathname = nextPath; return NextResponse.redirect(redirectUrl, 308); } return intlMiddleware(request); } export const config = { matcher: ["/((?!api|trpc|_next|_vercel|.*\\..*).*)"], };