Spaces:
Running
Running
| import { NextResponse } from 'next/server'; | |
| /** | |
| * Next.js Middleware — runs before every matched request. | |
| * Enforces authentication (hf_user cookie) on write API endpoints. | |
| */ | |
| // Routes that require authentication (write operations) | |
| const PROTECTED_ROUTES = [ | |
| '/api/annotate', // POST: add annotation, DELETE: remove, PUT: update | |
| '/api/validate', // PUT: validate mention, DELETE: remove mention | |
| ]; | |
| export function middleware(request) { | |
| const { pathname } = request.nextUrl; | |
| // Only protect write endpoints | |
| const isProtected = PROTECTED_ROUTES.some(route => pathname.startsWith(route)); | |
| if (!isProtected) return NextResponse.next(); | |
| // Allow GET requests (reads are OK without auth) | |
| if (request.method === 'GET') return NextResponse.next(); | |
| // Check for hf_user cookie | |
| const userCookie = request.cookies.get('hf_user'); | |
| if (!userCookie?.value) { | |
| return NextResponse.json( | |
| { error: 'Authentication required. Please sign in with HuggingFace.' }, | |
| { status: 401 } | |
| ); | |
| } | |
| // Parse and verify user is in allowed list | |
| try { | |
| const user = JSON.parse(userCookie.value); | |
| const username = user.username; | |
| if (!username) { | |
| return NextResponse.json( | |
| { error: 'Invalid session. Please sign in again.' }, | |
| { status: 401 } | |
| ); | |
| } | |
| // Check ALLOWED_USERS if set | |
| const allowedUsers = process.env.ALLOWED_USERS; | |
| if (allowedUsers) { | |
| const allowlist = allowedUsers.split(',').map(u => u.trim().toLowerCase()); | |
| if (!allowlist.includes(username.toLowerCase())) { | |
| return NextResponse.json( | |
| { error: `Access denied. User "${username}" is not authorized.` }, | |
| { status: 403 } | |
| ); | |
| } | |
| } | |
| } catch (e) { | |
| return NextResponse.json( | |
| { error: 'Invalid session cookie. Please sign in again.' }, | |
| { status: 401 } | |
| ); | |
| } | |
| return NextResponse.next(); | |
| } | |
| // Only run middleware on API routes | |
| export const config = { | |
| matcher: '/api/:path*', | |
| }; | |