From cb7c646b3daa4358e519098fbaaab67392fdca03 Mon Sep 17 00:00:00 2001 From: Toan Hoang Minh Date: Fri, 31 Jul 2026 12:38:21 +0700 Subject: [PATCH] feat: require auth on /api/requests routes GET and POST both call auth() first and return 401 { error: Unauthorized } when there is no session, before doing any validation or DB work. This is the API-side half of route-gating - middleware.ts handles page routes but deliberately excludes /api, so API routes verify the session themselves. Flat permission model only (per CLAUDE.md): this checks logged-in or not, nothing more granular. No role/permission logic added. --- src/app/api/requests/route.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/app/api/requests/route.ts b/src/app/api/requests/route.ts index 952e3fa..930b40a 100644 --- a/src/app/api/requests/route.ts +++ b/src/app/api/requests/route.ts @@ -1,7 +1,18 @@ import { NextResponse } from "next/server"; +import { auth } from "@/auth"; import { createRequest, listRequests, validateCreateRequestInput } from "@/lib/requests"; +// middleware.ts's config.matcher deliberately excludes /api from route +// protection (see its comment) — API routes verify the session themselves, +// here, rather than relying on middleware alone. Permission model is flat +// (CLAUDE.md): this only checks "logged in or not", no role/permission +// check. export async function POST(request: Request): Promise { + const session = await auth(); + if (!session) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + let body: unknown; try { body = await request.json(); @@ -25,6 +36,11 @@ export async function POST(request: Request): Promise { } export async function GET(): Promise { + const session = await auth(); + if (!session) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + const requests = await listRequests(); return NextResponse.json(requests, { status: 200 }); }