From c459b4411a12cd5fe20bb0349e585efd7bdecd28 Mon Sep 17 00:00:00 2001 From: Mannu Date: Sun, 17 May 2026 16:41:47 +0530 Subject: [PATCH] fix: secure /api/ai endpoint and remove debug routes - Add auth to /api/ai via requireFamily middleware - Remove /api/ai and /api/auth/debug from public routes - Delete debug/test routes that expose internal state Co-Authored-By: Claude Opus 4.7 --- src/app/api/admin/test/route.ts | 1 - src/app/api/ai/route.ts | 17 ++++++++++--- src/app/api/auth/debug/route.ts | 42 --------------------------------- src/middleware.ts | 2 -- 4 files changed, 14 insertions(+), 48 deletions(-) delete mode 100644 src/app/api/admin/test/route.ts delete mode 100644 src/app/api/auth/debug/route.ts diff --git a/src/app/api/admin/test/route.ts b/src/app/api/admin/test/route.ts deleted file mode 100644 index 4aa7116..0000000 --- a/src/app/api/admin/test/route.ts +++ /dev/null @@ -1 +0,0 @@ -import { NextResponse } from "next/server"; export async function GET() { return NextResponse.json({ test: "success" }); } diff --git a/src/app/api/ai/route.ts b/src/app/api/ai/route.ts index 8e3f10a..6a85235 100644 --- a/src/app/api/ai/route.ts +++ b/src/app/api/ai/route.ts @@ -2,6 +2,7 @@ import { NextResponse } from "next/server"; import { sql } from "@/db"; import { detectMedicalIntent, ESCALATION_RULES } from "@/lib/ai/medical-triggers"; import { logAudit } from "@/lib/audit"; +import { requireFamily } from "@/lib/auth"; const LITELLM_URL = process.env.LITELLM_BASE_URL; const LITELLM_KEY = process.env.LITELLM_API_KEY; @@ -13,6 +14,15 @@ export async function POST(request: Request) { return NextResponse.json({ error: "AI service not configured" }, { status: 503 }); } + // Require authentication + const auth = await requireFamily(); + if (!auth.success) { + return NextResponse.json({ error: auth.error }, { status: auth.status }); + } + + const session = auth.session!; + const familyId = session.familyId!; + const body = await request.json(); const { messages, childId } = body; @@ -25,11 +35,10 @@ export async function POST(request: Request) { // HARD GUARDRAIL: Check for medical intent BEFORE calling LLM const intent = detectMedicalIntent(lastUserMsg); if (intent.isMedical) { - // Fetch pediatrician phone - const sessionToken = request.headers.get("cookie")?.match(/tia_session=([^;]+)/)?.[1] || ""; + // Fetch pediatrician phone using familyId const families = await sql` SELECT pediatrician_phone FROM families - WHERE id IN (SELECT family_id FROM family_members WHERE user_id IN (SELECT user_id FROM sessions WHERE session_token = ${sessionToken})) + WHERE id = ${familyId} LIMIT 1 `; const pediatricianPhone = families[0]?.pediatrician_phone; @@ -49,6 +58,8 @@ export async function POST(request: Request) { action: "ai_medical_redirect", metadata: { category: intent.category, keyword: intent.matchedKeyword }, request, + userId: session.userId, + familyId, }); return NextResponse.json({ diff --git a/src/app/api/auth/debug/route.ts b/src/app/api/auth/debug/route.ts deleted file mode 100644 index 3704028..0000000 --- a/src/app/api/auth/debug/route.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { NextResponse } from "next/server"; -import { sql } from "@/db"; -import { cookies } from "next/headers"; - -export async function GET() { - const sessionToken = (await cookies()).get("tia_session")?.value; - - if (!sessionToken) { - return NextResponse.json({ error: "no cookie" }); - } - - // Get user from session - const sessions = await sql.unsafe( - `SELECT s.user_id FROM sessions s WHERE s.session_token = $1`, - [sessionToken] - ); - - const userId = sessions?.[0]?.user_id; - - // Check families table - const families = await sql.unsafe( - `SELECT id, name FROM families ORDER BY created_at DESC LIMIT 5` - ); - - // Check family_members table - const members = await sql.unsafe( - `SELECT id, family_id, user_id, role FROM family_members ORDER BY created_at DESC LIMIT 5` - ); - - // Check children table - const children = await sql.unsafe( - `SELECT id, family_id, name FROM children ORDER BY created_at DESC LIMIT 5` - ); - - return NextResponse.json({ - cookie: sessionToken?.slice(0, 20) + "...", - userId, - families, - members, - children - }); -} \ No newline at end of file diff --git a/src/middleware.ts b/src/middleware.ts index 2cc183f..cc5082e 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -9,8 +9,6 @@ const publicRoutes = [ "/api/auth/signin", "/api/admin/auth", "/api/onboarding", - "/api/ai", - "/api/auth/debug", ]; // Protected API routes that need authentication