import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; // Basic Auth configuration const AUTH_USERNAME = process.env.AUTH_USERNAME || 'admin'; const AUTH_PASSWORD = process.env.AUTH_PASSWORD || 'openclaw'; // Skip auth for public routes (if any) const publicRoutes = ['/api/status']; // Allow status API without auth for health checks function basicAuth(req: NextRequest) { const authHeader = req.headers.get('authorization'); if (!authHeader) { return false; } const [type, credentials] = authHeader.split(' '); if (type !== 'Basic') { return false; } const decoded = Buffer.from(credentials, 'base64').toString('utf-8'); const [username, password] = decoded.split(':'); return username === AUTH_USERNAME && password === AUTH_PASSWORD; } export function middleware(req: NextRequest) { // Skip auth for public routes if (publicRoutes.some(route => req.nextUrl.pathname.startsWith(route))) { return NextResponse.next(); } if (!basicAuth(req)) { return new NextResponse( 'Authentication required', { status: 401, headers: { 'WWW-Authenticate': 'Basic realm="OpenClaw Dashboard"', }, } ); } return NextResponse.next(); } export const config = { matcher: [ /* * Match all request paths except for the ones starting with: * - _next/static (static files) * - _next/image (image optimization files) * - favicon.ico (favicon file) */ '/((?!_next/static|_next/image|favicon.ico).*)', ], };