Enforce user invites/request on server
This commit is contained in:
@@ -5,6 +5,7 @@ import { useTranslation, Trans } from "react-i18next";
|
|||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { Role } from "@shared/types";
|
import { Role } from "@shared/types";
|
||||||
|
import { UserValidation } from "@shared/validations";
|
||||||
import Button from "~/components/Button";
|
import Button from "~/components/Button";
|
||||||
import CopyToClipboard from "~/components/CopyToClipboard";
|
import CopyToClipboard from "~/components/CopyToClipboard";
|
||||||
import Flex from "~/components/Flex";
|
import Flex from "~/components/Flex";
|
||||||
@@ -19,8 +20,6 @@ import usePolicy from "~/hooks/usePolicy";
|
|||||||
import useStores from "~/hooks/useStores";
|
import useStores from "~/hooks/useStores";
|
||||||
import useToasts from "~/hooks/useToasts";
|
import useToasts from "~/hooks/useToasts";
|
||||||
|
|
||||||
const MAX_INVITES = 20;
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
onSubmit: () => void;
|
onSubmit: () => void;
|
||||||
};
|
};
|
||||||
@@ -97,10 +96,10 @@ function Invite({ onSubmit }: Props) {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleAdd = React.useCallback(() => {
|
const handleAdd = React.useCallback(() => {
|
||||||
if (invites.length >= MAX_INVITES) {
|
if (invites.length >= UserValidation.maxInvitesPerRequest) {
|
||||||
showToast(
|
showToast(
|
||||||
t("Sorry, you can only send {{MAX_INVITES}} invites at a time", {
|
t("Sorry, you can only send {{MAX_INVITES}} invites at a time", {
|
||||||
MAX_INVITES,
|
MAX_INVITES: UserValidation.maxInvitesPerRequest,
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
type: "warning",
|
type: "warning",
|
||||||
@@ -241,7 +240,7 @@ function Invite({ onSubmit }: Props) {
|
|||||||
))}
|
))}
|
||||||
|
|
||||||
<Flex justify="space-between">
|
<Flex justify="space-between">
|
||||||
{invites.length <= MAX_INVITES ? (
|
{invites.length <= UserValidation.maxInvitesPerRequest ? (
|
||||||
<Button type="button" onClick={handleAdd} neutral>
|
<Button type="button" onClick={handleAdd} neutral>
|
||||||
<Trans>Add another</Trans>…
|
<Trans>Add another</Trans>…
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import crypto from "crypto";
|
import crypto from "crypto";
|
||||||
import Router from "koa-router";
|
import Router from "koa-router";
|
||||||
import { Op, WhereOptions } from "sequelize";
|
import { Op, WhereOptions } from "sequelize";
|
||||||
|
import { UserValidation } from "@shared/validations";
|
||||||
import userDemoter from "@server/commands/userDemoter";
|
import userDemoter from "@server/commands/userDemoter";
|
||||||
import userDestroyer from "@server/commands/userDestroyer";
|
import userDestroyer from "@server/commands/userDestroyer";
|
||||||
import userInviter from "@server/commands/userInviter";
|
import userInviter from "@server/commands/userInviter";
|
||||||
@@ -316,7 +317,7 @@ router.post("users.invite", auth(), async (ctx) => {
|
|||||||
|
|
||||||
const response = await userInviter({
|
const response = await userInviter({
|
||||||
user,
|
user,
|
||||||
invites,
|
invites: invites.slice(0, UserValidation.maxInvitesPerRequest),
|
||||||
ip: ctx.request.ip,
|
ip: ctx.request.ip,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,11 @@ export const TeamValidation = {
|
|||||||
maxDomains: 10,
|
maxDomains: 10,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const UserValidation = {
|
||||||
|
/** The maximum number of invites per request */
|
||||||
|
maxInvitesPerRequest: 20,
|
||||||
|
};
|
||||||
|
|
||||||
export const WebhookSubscriptionValidation = {
|
export const WebhookSubscriptionValidation = {
|
||||||
/** The maximum number of webhooks per team */
|
/** The maximum number of webhooks per team */
|
||||||
maxSubscriptions: 10,
|
maxSubscriptions: 10,
|
||||||
|
|||||||
Reference in New Issue
Block a user