From 387e83922d07dc5f7c98240b9a62e5e643a5fd2f Mon Sep 17 00:00:00 2001 From: Luke Vella Date: Sun, 1 Dec 2024 18:41:24 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=92=EF=B8=8F=20Limit=20max=20participa?= =?UTF-8?q?nts=20in=20a=20poll=20(#1450)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/trpc/routers/polls/participants.ts | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/apps/web/src/trpc/routers/polls/participants.ts b/apps/web/src/trpc/routers/polls/participants.ts index fb063bf87..1b2f5066d 100644 --- a/apps/web/src/trpc/routers/polls/participants.ts +++ b/apps/web/src/trpc/routers/polls/participants.ts @@ -8,6 +8,8 @@ import { createToken } from "@/utils/session"; import { publicProcedure, rateLimitMiddleware, router } from "../../trpc"; import type { DisableNotificationsPayload } from "../../types"; +const MAX_PARTICIPANTS = 1000; + export const participants = router({ list: publicProcedure .input( @@ -73,19 +75,21 @@ export const participants = router({ .mutation(async ({ ctx, input: { pollId, votes, name, email } }) => { const { user } = ctx; - const poll = await prisma.poll.findUnique({ - where: { id: pollId }, - select: { - id: true, - title: true, - }, - }); - - if (!poll) { - throw new TRPCError({ code: "BAD_REQUEST", message: "Poll not found" }); - } - const participant = await prisma.$transaction(async (prisma) => { + const participantCount = await prisma.participant.count({ + where: { + pollId, + deleted: false, + }, + }); + + if (participantCount >= MAX_PARTICIPANTS) { + throw new TRPCError({ + code: "BAD_REQUEST", + message: `This poll has reached its maximum limit of ${MAX_PARTICIPANTS} participants`, + }); + } + const participant = await prisma.participant.create({ data: { pollId: pollId, @@ -94,6 +98,14 @@ export const participants = router({ userId: user.id, locale: user.locale ?? undefined, }, + include: { + poll: { + select: { + id: true, + title: true, + }, + }, + }, }); await prisma.vote.createMany({ @@ -121,9 +133,9 @@ export const participants = router({ .queueTemplate("NewParticipantConfirmationEmail", { to: email, props: { - title: poll.title, + title: participant.poll.title, editSubmissionUrl: absoluteUrl( - `/invite/${poll.id}?token=${token}`, + `/invite/${participant.poll.id}?token=${token}`, ), }, }); @@ -155,11 +167,11 @@ export const participants = router({ to: email, props: { participantName: participant.name, - pollUrl: absoluteUrl(`/poll/${poll.id}`), + pollUrl: absoluteUrl(`/poll/${participant.poll.id}`), disableNotificationsUrl: absoluteUrl( `/auth/disable-notifications?token=${token}`, ), - title: poll.title, + title: participant.poll.title, }, }); }