fix: 服务端验证强化 — 房间ID/坐标/swipe/盲盒竞态/空格

- #15: 房间 ID 扩展为 6 位字母数字,createRoom 用 P2002 重试替代 find-then-create
- #16: 盲盒编辑/删除改用 updateMany/deleteMany 原子操作,防止 TOCTOU
- #17: lat/lng 用 Number.isFinite + 范围校验 (-90~90, -180~180)
- #18: swipe action 必须为 'like' 或 'pass'
- #19: user PUT 的 JSON.parse(preferences) 加 try/catch
- #26: requireString 拒绝纯空格字符串
This commit is contained in:
2026-02-26 20:19:56 +08:00
parent 93f20747e4
commit dfb3cfa136
6 changed files with 41 additions and 31 deletions
+9 -13
View File
@@ -55,17 +55,14 @@ export const PUT = apiHandler(async (req) => {
requireString(ideaId, "ideaId");
const trimmedContent = validateIdeaContent(content);
const idea = await prisma.blindBoxIdea.findUnique({ where: { id: ideaId } });
if (!idea) throw new ApiError("想法不存在", 404);
if (idea.userId !== userId) throw new ApiError("只能编辑自己的想法", 403);
if (idea.status !== "in_pool") throw new ApiError("已抽中的想法不能编辑");
const updated = await prisma.blindBoxIdea.update({
where: { id: ideaId },
const { count } = await prisma.blindBoxIdea.updateMany({
where: { id: ideaId, userId, status: "in_pool" },
data: { content: trimmedContent },
});
return NextResponse.json({ id: updated.id, content: updated.content });
if (count === 0) throw new ApiError("想法不存在、已被抽中或无权编辑", 404);
return NextResponse.json({ id: ideaId, content: trimmedContent });
});
export const DELETE = apiHandler(async (req) => {
@@ -74,12 +71,11 @@ export const DELETE = apiHandler(async (req) => {
requireUserId(userId);
requireString(ideaId, "ideaId");
const idea = await prisma.blindBoxIdea.findUnique({ where: { id: ideaId } });
if (!idea) throw new ApiError("想法不存在", 404);
if (idea.userId !== userId) throw new ApiError("只能删除自己的想法", 403);
if (idea.status !== "in_pool") throw new ApiError("已抽中的想法不能删除");
const { count } = await prisma.blindBoxIdea.deleteMany({
where: { id: ideaId, userId, status: "in_pool" },
});
await prisma.blindBoxIdea.delete({ where: { id: ideaId } });
if (count === 0) throw new ApiError("想法不存在、已被抽中或无权删除", 404);
return NextResponse.json({ deleted: true });
});