feat: add share pages comments and server actions

This commit is contained in:
2026-08-16 00:58:46 +07:00 Unverified
parent 5bf5d2a2c0
commit 9617d67c7c
14 changed files with 1157 additions and 108 deletions
-65
View File
@@ -1,65 +0,0 @@
import { getServerSession } from "next-auth";
import { eq } from "drizzle-orm";
import { db } from "@/db";
import { users } from "@/db/schema";
import { authOptions } from "@/lib/auth/auth-options";
import { getSessionDiscordId, type SessionWithDiscord } from "@/lib/auth/auth";
import { createShare } from "@/lib/share/create";
import { ShareHttpError, shareErrorResponse } from "@/lib/share/http-error";
import { enforceShareRateLimit } from "@/lib/share/rate-limit";
import {
validateOptionalImage,
validateShareDescription,
validateShareText,
} from "@/lib/share/validation";
export const dynamic = "force-dynamic";
export async function POST(request: Request) {
try {
const session = await getServerSession(authOptions);
const discordId = getSessionDiscordId(session);
const userId = (session as SessionWithDiscord | null)?.user?.id;
if (!discordId || !userId) {
throw new ShareHttpError("Unauthorized", 401);
}
const formData = await request.formData();
const content = validateShareText(formData.get("text"));
const description = validateShareDescription(formData.get("description"));
const image = await validateOptionalImage(formData.get("image"));
await enforceShareRateLimit({
key: `sender:${discordId}`,
limit: 10,
windowSeconds: 60 * 60,
});
const [user] = await db
.select({ id: users.id, name: users.name, image: users.image })
.from(users)
.where(eq(users.id, userId))
.limit(1);
if (!user) throw new ShareHttpError("Unauthorized", 401);
const share = await createShare({
content,
description,
image,
source: "web",
author: {
userId: user.id,
discordId,
displayName: user.name || session?.user?.name || "Discord user",
avatarUrl: user.image || session?.user?.image || null,
},
});
return Response.json(
{ success: true, share: { id: share.id, url: `/share/${share.id}` } },
{ status: 201 }
);
} catch (error) {
return shareErrorResponse(error);
}
}