Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 11 additions & 17 deletions app/(chat)/api/chat/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ import { editDocument } from "@/lib/ai/tools/edit-document";
import { getWeather } from "@/lib/ai/tools/get-weather";
import { requestSuggestions } from "@/lib/ai/tools/request-suggestions";
import { updateDocument } from "@/lib/ai/tools/update-document";
import {
requireOwnership,
requireSearchParam,
requireSession,
withErrorHandling,
} from "@/lib/api/route-helpers";
import { isProductionEnvironment } from "@/lib/constants";
import {
createStreamId,
Expand Down Expand Up @@ -444,27 +450,15 @@ export async function POST(request: Request) {
}
}

export async function DELETE(request: Request) {
const { searchParams } = new URL(request.url);
const id = searchParams.get("id");

if (!id) {
return new ChatbotError("bad_request:api").toResponse();
}

const session = await auth();

if (!session?.user) {
return new ChatbotError("unauthorized:chat").toResponse();
}
export const DELETE = withErrorHandling(async (request: Request) => {
const id = requireSearchParam(request, "id");
const session = await requireSession("chat");

const chat = await getChatById({ id });

if (chat?.userId !== session.user.id) {
return new ChatbotError("forbidden:chat").toResponse();
}
requireOwnership({ ownerId: chat?.userId, session, surface: "chat" });

const deletedChat = await deleteChatById({ id });

return Response.json(deletedChat, { status: 200 });
}
});
120 changes: 35 additions & 85 deletions app/(chat)/api/document/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { z } from "zod";
import { auth } from "@/app/(auth)/auth";
import type { ArtifactKind } from "@/components/chat/artifact";
import {
parseJsonBody,
requireOwnership,
requireSearchParam,
requireSession,
withErrorHandling,
} from "@/lib/api/route-helpers";
import {
deleteDocumentsByIdAfterTimestamp,
getDocumentsById,
Expand All @@ -16,22 +21,9 @@ const documentSchema = z.object({
title: z.string(),
});

export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const id = searchParams.get("id");

if (!id) {
return new ChatbotError(
"bad_request:api",
"Parameter id is missing"
).toResponse();
}

const session = await auth();

if (!session?.user) {
return new ChatbotError("unauthorized:document").toResponse();
}
export const GET = withErrorHandling(async (request: Request) => {
const id = requireSearchParam(request, "id");
const session = await requireSession("document");

const documents = await getDocumentsById({ id });

Expand All @@ -41,54 +33,30 @@ export async function GET(request: Request) {
return new ChatbotError("not_found:document").toResponse();
}

if (document.userId !== session.user.id) {
return new ChatbotError("forbidden:document").toResponse();
}
requireOwnership({
ownerId: document.userId,
session,
surface: "document",
});

return Response.json(documents, { status: 200 });
}

export async function POST(request: Request) {
const { searchParams } = new URL(request.url);
const id = searchParams.get("id");

if (!id) {
return new ChatbotError(
"bad_request:api",
"Parameter id is required."
).toResponse();
}
});

const session = await auth();
export const POST = withErrorHandling(async (request: Request) => {
const id = requireSearchParam(request, "id");
const session = await requireSession("document");

if (!session?.user) {
return new ChatbotError("not_found:document").toResponse();
}

let content: string;
let title: string;
let kind: ArtifactKind;
let isManualEdit: boolean | undefined;

try {
({ content, isManualEdit, kind, title } = documentSchema.parse(
await request.json()
));
} catch {
return new ChatbotError(
"bad_request:api",
"Invalid request body."
).toResponse();
}
const { content, isManualEdit, kind, title } = await parseJsonBody(
request,
documentSchema
);

const documents = await getDocumentsById({ id });

if (documents.length > 0) {
const [doc] = documents;

if (doc.userId !== session.user.id) {
return new ChatbotError("forbidden:document").toResponse();
}
requireOwnership({ ownerId: doc.userId, session, surface: "document" });
}

if (isManualEdit && documents.length > 0) {
Expand All @@ -105,40 +73,22 @@ export async function POST(request: Request) {
});

return Response.json(document, { status: 200 });
}

export async function DELETE(request: Request) {
const { searchParams } = new URL(request.url);
const id = searchParams.get("id");
const timestamp = searchParams.get("timestamp");

if (!id) {
return new ChatbotError(
"bad_request:api",
"Parameter id is required."
).toResponse();
}

if (!timestamp) {
return new ChatbotError(
"bad_request:api",
"Parameter timestamp is required."
).toResponse();
}

const session = await auth();
});

if (!session?.user) {
return new ChatbotError("unauthorized:document").toResponse();
}
export const DELETE = withErrorHandling(async (request: Request) => {
const id = requireSearchParam(request, "id");
const timestamp = requireSearchParam(request, "timestamp");
const session = await requireSession("document");

const documents = await getDocumentsById({ id });

const [document] = documents;

if (document.userId !== session.user.id) {
return new ChatbotError("forbidden:document").toResponse();
}
requireOwnership({
ownerId: document?.userId,
session,
surface: "document",
});

const parsedTimestamp = new Date(timestamp);

Expand All @@ -155,4 +105,4 @@ export async function DELETE(request: Request) {
});

return Response.json(documentsDeleted, { status: 200 });
}
});
22 changes: 7 additions & 15 deletions app/(chat)/api/history/route.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { NextRequest } from "next/server";
import { auth } from "@/app/(auth)/auth";
import { requireSession, withErrorHandling } from "@/lib/api/route-helpers";
import { deleteAllChatsByUserId, getChatsByUserId } from "@/lib/db/queries";
import { ChatbotError } from "@/lib/errors";

export async function GET(request: NextRequest) {
export const GET = withErrorHandling(async (request: NextRequest) => {
const { searchParams } = request.nextUrl;

const limit = Math.min(
Expand All @@ -20,11 +20,7 @@ export async function GET(request: NextRequest) {
).toResponse();
}

const session = await auth();

if (!session?.user) {
return new ChatbotError("unauthorized:chat").toResponse();
}
const session = await requireSession("chat");

const chats = await getChatsByUserId({
endingBefore,
Expand All @@ -34,16 +30,12 @@ export async function GET(request: NextRequest) {
});

return Response.json(chats);
}
});

export async function DELETE() {
const session = await auth();

if (!session?.user) {
return new ChatbotError("unauthorized:chat").toResponse();
}
export const DELETE = withErrorHandling(async () => {
const session = await requireSession("chat");

const result = await deleteAllChatsByUserId({ userId: session.user.id });

return Response.json(result, { status: 200 });
}
});
33 changes: 11 additions & 22 deletions app/(chat)/api/suggestions/route.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
import { auth } from "@/app/(auth)/auth";
import {
requireOwnership,
requireSearchParam,
requireSession,
withErrorHandling,
} from "@/lib/api/route-helpers";
import { getSuggestionsByDocumentId } from "@/lib/db/queries";
import { ChatbotError } from "@/lib/errors";

export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const documentId = searchParams.get("documentId");

if (!documentId) {
return new ChatbotError(
"bad_request:api",
"Parameter documentId is required."
).toResponse();
}

const session = await auth();

if (!session?.user) {
return new ChatbotError("unauthorized:suggestions").toResponse();
}
export const GET = withErrorHandling(async (request: Request) => {
const documentId = requireSearchParam(request, "documentId");
const session = await requireSession("suggestions");

const suggestions = await getSuggestionsByDocumentId({
documentId,
Expand All @@ -29,9 +20,7 @@ export async function GET(request: Request) {
return Response.json([], { status: 200 });
}

if (suggestion.userId !== session.user.id) {
return new ChatbotError("forbidden:api").toResponse();
}
requireOwnership({ ownerId: suggestion.userId, session, surface: "api" });

return Response.json(suggestions, { status: 200 });
}
});
Loading