From 7923a7e07116abd628a36c28bc83b89e1575f3b0 Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Mon, 8 Aug 2022 11:02:37 +0200 Subject: [PATCH] Enforce user invites/request on server --- app/scenes/Invite.tsx | 9 ++++----- server/routes/api/users.ts | 3 ++- shared/validations.ts | 5 +++++ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/app/scenes/Invite.tsx b/app/scenes/Invite.tsx index 0c829be7a..0a32348f7 100644 --- a/app/scenes/Invite.tsx +++ b/app/scenes/Invite.tsx @@ -5,6 +5,7 @@ import { useTranslation, Trans } from "react-i18next"; import { Link } from "react-router-dom"; import styled from "styled-components"; import { Role } from "@shared/types"; +import { UserValidation } from "@shared/validations"; import Button from "~/components/Button"; import CopyToClipboard from "~/components/CopyToClipboard"; import Flex from "~/components/Flex"; @@ -19,8 +20,6 @@ import usePolicy from "~/hooks/usePolicy"; import useStores from "~/hooks/useStores"; import useToasts from "~/hooks/useToasts"; -const MAX_INVITES = 20; - type Props = { onSubmit: () => void; }; @@ -97,10 +96,10 @@ function Invite({ onSubmit }: Props) { }, []); const handleAdd = React.useCallback(() => { - if (invites.length >= MAX_INVITES) { + if (invites.length >= UserValidation.maxInvitesPerRequest) { showToast( t("Sorry, you can only send {{MAX_INVITES}} invites at a time", { - MAX_INVITES, + MAX_INVITES: UserValidation.maxInvitesPerRequest, }), { type: "warning", @@ -241,7 +240,7 @@ function Invite({ onSubmit }: Props) { ))} - {invites.length <= MAX_INVITES ? ( + {invites.length <= UserValidation.maxInvitesPerRequest ? ( diff --git a/server/routes/api/users.ts b/server/routes/api/users.ts index f3215854e..7ee06b5be 100644 --- a/server/routes/api/users.ts +++ b/server/routes/api/users.ts @@ -1,6 +1,7 @@ import crypto from "crypto"; import Router from "koa-router"; import { Op, WhereOptions } from "sequelize"; +import { UserValidation } from "@shared/validations"; import userDemoter from "@server/commands/userDemoter"; import userDestroyer from "@server/commands/userDestroyer"; import userInviter from "@server/commands/userInviter"; @@ -316,7 +317,7 @@ router.post("users.invite", auth(), async (ctx) => { const response = await userInviter({ user, - invites, + invites: invites.slice(0, UserValidation.maxInvitesPerRequest), ip: ctx.request.ip, }); diff --git a/shared/validations.ts b/shared/validations.ts index 0ca55c566..efa510239 100644 --- a/shared/validations.ts +++ b/shared/validations.ts @@ -42,6 +42,11 @@ export const TeamValidation = { maxDomains: 10, }; +export const UserValidation = { + /** The maximum number of invites per request */ + maxInvitesPerRequest: 20, +}; + export const WebhookSubscriptionValidation = { /** The maximum number of webhooks per team */ maxSubscriptions: 10,