diff --git a/packages/api/src/router/invite.ts b/packages/api/src/router/invite.ts index 80aa1ea..acb66f5 100644 --- a/packages/api/src/router/invite.ts +++ b/packages/api/src/router/invite.ts @@ -5,6 +5,7 @@ import { SystemRole } from "@capakraken/db"; import { createTRPCRouter, adminProcedure, publicProcedure } from "../trpc.js"; import { getAppBaseUrl } from "../lib/app-base-url.js"; import { sendEmail } from "../lib/email.js"; +import { authRateLimiter } from "../middleware/rate-limit.js"; const INVITE_TTL_MS = 72 * 60 * 60 * 1000; // 72 hours @@ -85,6 +86,14 @@ export const inviteRouter = createTRPCRouter({ getInvite: publicProcedure .input(z.object({ token: z.string() })) .query(async ({ ctx, input }) => { + const rl = await authRateLimiter(input.token); + if (!rl.allowed) { + throw new TRPCError({ + code: "TOO_MANY_REQUESTS", + message: "Too many attempts. Please wait before trying again.", + }); + } + const invite = await ctx.db.inviteToken.findUnique({ where: { token: input.token }, select: { email: true, role: true, expiresAt: true, usedAt: true }, @@ -104,6 +113,14 @@ export const inviteRouter = createTRPCRouter({ }), ) .mutation(async ({ ctx, input }) => { + const rl = await authRateLimiter(input.token); + if (!rl.allowed) { + throw new TRPCError({ + code: "TOO_MANY_REQUESTS", + message: "Too many attempts. Please wait before trying again.", + }); + } + const invite = await ctx.db.inviteToken.findUnique({ where: { token: input.token }, });