mirror of
https://github.com/lukevella/rallly.git
synced 2025-04-30 18:56:45 +02:00
🔒️ Limit max participants in a poll (#1450)
This commit is contained in:
parent
9b606bdbdc
commit
387e83922d
1 changed files with 28 additions and 16 deletions
|
@ -8,6 +8,8 @@ import { createToken } from "@/utils/session";
|
||||||
import { publicProcedure, rateLimitMiddleware, router } from "../../trpc";
|
import { publicProcedure, rateLimitMiddleware, router } from "../../trpc";
|
||||||
import type { DisableNotificationsPayload } from "../../types";
|
import type { DisableNotificationsPayload } from "../../types";
|
||||||
|
|
||||||
|
const MAX_PARTICIPANTS = 1000;
|
||||||
|
|
||||||
export const participants = router({
|
export const participants = router({
|
||||||
list: publicProcedure
|
list: publicProcedure
|
||||||
.input(
|
.input(
|
||||||
|
@ -73,19 +75,21 @@ export const participants = router({
|
||||||
.mutation(async ({ ctx, input: { pollId, votes, name, email } }) => {
|
.mutation(async ({ ctx, input: { pollId, votes, name, email } }) => {
|
||||||
const { user } = ctx;
|
const { user } = ctx;
|
||||||
|
|
||||||
const poll = await prisma.poll.findUnique({
|
const participant = await prisma.$transaction(async (prisma) => {
|
||||||
where: { id: pollId },
|
const participantCount = await prisma.participant.count({
|
||||||
select: {
|
where: {
|
||||||
id: true,
|
pollId,
|
||||||
title: true,
|
deleted: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!poll) {
|
if (participantCount >= MAX_PARTICIPANTS) {
|
||||||
throw new TRPCError({ code: "BAD_REQUEST", message: "Poll not found" });
|
throw new TRPCError({
|
||||||
|
code: "BAD_REQUEST",
|
||||||
|
message: `This poll has reached its maximum limit of ${MAX_PARTICIPANTS} participants`,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const participant = await prisma.$transaction(async (prisma) => {
|
|
||||||
const participant = await prisma.participant.create({
|
const participant = await prisma.participant.create({
|
||||||
data: {
|
data: {
|
||||||
pollId: pollId,
|
pollId: pollId,
|
||||||
|
@ -94,6 +98,14 @@ export const participants = router({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
locale: user.locale ?? undefined,
|
locale: user.locale ?? undefined,
|
||||||
},
|
},
|
||||||
|
include: {
|
||||||
|
poll: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
title: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await prisma.vote.createMany({
|
await prisma.vote.createMany({
|
||||||
|
@ -121,9 +133,9 @@ export const participants = router({
|
||||||
.queueTemplate("NewParticipantConfirmationEmail", {
|
.queueTemplate("NewParticipantConfirmationEmail", {
|
||||||
to: email,
|
to: email,
|
||||||
props: {
|
props: {
|
||||||
title: poll.title,
|
title: participant.poll.title,
|
||||||
editSubmissionUrl: absoluteUrl(
|
editSubmissionUrl: absoluteUrl(
|
||||||
`/invite/${poll.id}?token=${token}`,
|
`/invite/${participant.poll.id}?token=${token}`,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -155,11 +167,11 @@ export const participants = router({
|
||||||
to: email,
|
to: email,
|
||||||
props: {
|
props: {
|
||||||
participantName: participant.name,
|
participantName: participant.name,
|
||||||
pollUrl: absoluteUrl(`/poll/${poll.id}`),
|
pollUrl: absoluteUrl(`/poll/${participant.poll.id}`),
|
||||||
disableNotificationsUrl: absoluteUrl(
|
disableNotificationsUrl: absoluteUrl(
|
||||||
`/auth/disable-notifications?token=${token}`,
|
`/auth/disable-notifications?token=${token}`,
|
||||||
),
|
),
|
||||||
title: poll.title,
|
title: participant.poll.title,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue