Add prompt validation to ai-event (non-empty string, max 2000 chars) and events array length validation to ai-summary (max 100 items) to prevent abuse and injection attacks.
65 lines
1.6 KiB
TypeScript
65 lines
1.6 KiB
TypeScript
import { NextResponse } from "next/server";
|
|
import { auth } from "@/auth";
|
|
import { headers } from "next/headers";
|
|
|
|
export async function POST(request: Request) {
|
|
const session = await auth.api.getSession({
|
|
headers: await headers(),
|
|
});
|
|
|
|
if (!session?.user) {
|
|
return NextResponse.json(
|
|
{ error: "Authentication required" },
|
|
{ status: 401 },
|
|
);
|
|
}
|
|
|
|
try {
|
|
const { events } = await request.json();
|
|
|
|
if (!events || !Array.isArray(events)) {
|
|
return NextResponse.json(
|
|
{ error: "Invalid events array" },
|
|
{ status: 400 },
|
|
);
|
|
}
|
|
if (events.length > 100) {
|
|
return NextResponse.json(
|
|
{ error: "Events array must contain 100 or fewer items" },
|
|
{ status: 400 },
|
|
);
|
|
}
|
|
|
|
const res = await fetch("https://openrouter.ai/api/v1/chat/completions", {
|
|
method: "POST",
|
|
headers: {
|
|
Authorization: `Bearer ${process.env.OPENROUTER_API_KEY}`, // Server-side only
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({
|
|
model: "@preset/i-cal-editor-summarize", // FREE model
|
|
messages: [
|
|
{
|
|
role: "system",
|
|
content: `You summarize a list of events in natural language. Include date, time, and title. Be concise.`,
|
|
},
|
|
{ role: "user", content: JSON.stringify(events) },
|
|
],
|
|
temperature: 0.4,
|
|
// max_tokens: 300,
|
|
}),
|
|
});
|
|
|
|
const data = await res.json();
|
|
const summary =
|
|
data?.choices?.[0]?.message?.content || "No summary generated.";
|
|
return NextResponse.json({ summary });
|
|
} catch (error) {
|
|
console.error(error);
|
|
return NextResponse.json(
|
|
{ error: "Failed to summarize events" },
|
|
{ status: 500 },
|
|
);
|
|
}
|
|
}
|