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 <noreply@anthropic.com>
This commit is contained in:
parent
797c970d81
commit
c459b4411a
4 changed files with 14 additions and 48 deletions
|
|
@ -1 +0,0 @@
|
||||||
import { NextResponse } from "next/server"; export async function GET() { return NextResponse.json({ test: "success" }); }
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { NextResponse } from "next/server";
|
||||||
import { sql } from "@/db";
|
import { sql } from "@/db";
|
||||||
import { detectMedicalIntent, ESCALATION_RULES } from "@/lib/ai/medical-triggers";
|
import { detectMedicalIntent, ESCALATION_RULES } from "@/lib/ai/medical-triggers";
|
||||||
import { logAudit } from "@/lib/audit";
|
import { logAudit } from "@/lib/audit";
|
||||||
|
import { requireFamily } from "@/lib/auth";
|
||||||
|
|
||||||
const LITELLM_URL = process.env.LITELLM_BASE_URL;
|
const LITELLM_URL = process.env.LITELLM_BASE_URL;
|
||||||
const LITELLM_KEY = process.env.LITELLM_API_KEY;
|
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 });
|
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 body = await request.json();
|
||||||
const { messages, childId } = body;
|
const { messages, childId } = body;
|
||||||
|
|
||||||
|
|
@ -25,11 +35,10 @@ export async function POST(request: Request) {
|
||||||
// HARD GUARDRAIL: Check for medical intent BEFORE calling LLM
|
// HARD GUARDRAIL: Check for medical intent BEFORE calling LLM
|
||||||
const intent = detectMedicalIntent(lastUserMsg);
|
const intent = detectMedicalIntent(lastUserMsg);
|
||||||
if (intent.isMedical) {
|
if (intent.isMedical) {
|
||||||
// Fetch pediatrician phone
|
// Fetch pediatrician phone using familyId
|
||||||
const sessionToken = request.headers.get("cookie")?.match(/tia_session=([^;]+)/)?.[1] || "";
|
|
||||||
const families = await sql`
|
const families = await sql`
|
||||||
SELECT pediatrician_phone FROM families
|
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
|
LIMIT 1
|
||||||
`;
|
`;
|
||||||
const pediatricianPhone = families[0]?.pediatrician_phone;
|
const pediatricianPhone = families[0]?.pediatrician_phone;
|
||||||
|
|
@ -49,6 +58,8 @@ export async function POST(request: Request) {
|
||||||
action: "ai_medical_redirect",
|
action: "ai_medical_redirect",
|
||||||
metadata: { category: intent.category, keyword: intent.matchedKeyword },
|
metadata: { category: intent.category, keyword: intent.matchedKeyword },
|
||||||
request,
|
request,
|
||||||
|
userId: session.userId,
|
||||||
|
familyId,
|
||||||
});
|
});
|
||||||
|
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
@ -9,8 +9,6 @@ const publicRoutes = [
|
||||||
"/api/auth/signin",
|
"/api/auth/signin",
|
||||||
"/api/admin/auth",
|
"/api/admin/auth",
|
||||||
"/api/onboarding",
|
"/api/onboarding",
|
||||||
"/api/ai",
|
|
||||||
"/api/auth/debug",
|
|
||||||
];
|
];
|
||||||
|
|
||||||
// Protected API routes that need authentication
|
// Protected API routes that need authentication
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue