diff --git a/client/src/core/client/admin/components/BanModal.spec.tsx b/client/src/core/client/admin/components/BanModal.spec.tsx index d17f8268c8..e13db4f96b 100644 --- a/client/src/core/client/admin/components/BanModal.spec.tsx +++ b/client/src/core/client/admin/components/BanModal.spec.tsx @@ -6,7 +6,6 @@ import { replaceHistoryLocation, } from "coral-framework/testHelpers"; -import { PROTECTED_EMAIL_DOMAINS } from "coral-common/common/lib/constants"; import { pureMerge } from "coral-common/common/lib/utils"; import { GQLNEW_USER_MODERATION, @@ -250,7 +249,7 @@ it("does not display ban domain option for moderated domain", async () => { }); it("does not display ban domain option for protected domain", async () => { - const protectedDomain = PROTECTED_EMAIL_DOMAINS.values().next().value; + const protectedDomain = "gmail.com"; const protectedEmailResolver = createResolversStub({ Query: { users: () => ({ diff --git a/client/src/core/client/admin/components/BanModal.tsx b/client/src/core/client/admin/components/BanModal.tsx index 05d8d807e7..c6553098fc 100644 --- a/client/src/core/client/admin/components/BanModal.tsx +++ b/client/src/core/client/admin/components/BanModal.tsx @@ -11,7 +11,6 @@ import { Form } from "react-final-form"; import { graphql } from "react-relay"; import NotAvailable from "coral-admin/components/NotAvailable"; -import { PROTECTED_EMAIL_DOMAINS } from "coral-common/common/lib/constants"; import { extractDomain } from "coral-common/common/lib/email"; import { isOrgModerator, @@ -77,6 +76,7 @@ interface Props { emailDomainModeration: UserStatusChangeContainer_settings["emailDomainModeration"]; userRole: string; isMultisite: boolean; + protectedEmailDomains: ReadonlyArray; } interface BanButtonProps { @@ -141,6 +141,7 @@ const BanModal: FunctionComponent = ({ userBanStatus, userRole, isMultisite, + protectedEmailDomains, }) => { const createDomainBan = useMutation(BanDomainMutation); const banUser = useMutation(BanUserMutation); @@ -233,7 +234,7 @@ const BanModal: FunctionComponent = ({ updateType !== UpdateType.NO_SITES && emailDomain && !domainIsConfigured && - !PROTECTED_EMAIL_DOMAINS.has(emailDomain); + !protectedEmailDomains.includes(emailDomain); useEffect(() => { if (viewerIsSingleSiteMod) { diff --git a/client/src/core/client/admin/components/ModerateCard/ModerateCardContainer.tsx b/client/src/core/client/admin/components/ModerateCard/ModerateCardContainer.tsx index 0832f6a47a..7e99bf2428 100644 --- a/client/src/core/client/admin/components/ModerateCard/ModerateCardContainer.tsx +++ b/client/src/core/client/admin/components/ModerateCard/ModerateCardContainer.tsx @@ -428,6 +428,7 @@ const ModerateCardContainer: FunctionComponent = ({ userEmail={comment.author.email} userRole={comment.author.role} isMultisite={settings.multisite} + protectedEmailDomains={settings.protectedEmailDomains} /> )} @@ -530,6 +531,7 @@ const enhanced = withFragmentContainer({ `, settings: graphql` fragment ModerateCardContainer_settings on Settings { + protectedEmailDomains locale wordList { banned diff --git a/client/src/core/client/admin/components/UserStatus/UserStatusChangeContainer.tsx b/client/src/core/client/admin/components/UserStatus/UserStatusChangeContainer.tsx index 4f53142908..2417920ea0 100644 --- a/client/src/core/client/admin/components/UserStatus/UserStatusChangeContainer.tsx +++ b/client/src/core/client/admin/components/UserStatus/UserStatusChangeContainer.tsx @@ -239,6 +239,7 @@ const UserStatusChangeContainer: FunctionComponent = ({ emailDomainModeration={settings.emailDomainModeration} userBanStatus={user.status.ban} userRole={user.role} + protectedEmailDomains={settings.protectedEmailDomains} /> )} @@ -286,6 +287,7 @@ const enhanced = withFragmentContainer({ newUserModeration } multisite + protectedEmailDomains } `, viewer: graphql` diff --git a/client/src/core/client/admin/routes/Configure/sections/Moderation/EmailDomainConfigContainer.css b/client/src/core/client/admin/routes/Configure/sections/Moderation/EmailDomainConfigContainer.css new file mode 100644 index 0000000000..05aeb1b77a --- /dev/null +++ b/client/src/core/client/admin/routes/Configure/sections/Moderation/EmailDomainConfigContainer.css @@ -0,0 +1,3 @@ +.textArea { + height: 150px; +} diff --git a/client/src/core/client/admin/routes/Configure/sections/Moderation/EmailDomainConfigContainer.tsx b/client/src/core/client/admin/routes/Configure/sections/Moderation/EmailDomainConfigContainer.tsx index eb9554dbec..a40efe74a7 100644 --- a/client/src/core/client/admin/routes/Configure/sections/Moderation/EmailDomainConfigContainer.tsx +++ b/client/src/core/client/admin/routes/Configure/sections/Moderation/EmailDomainConfigContainer.tsx @@ -1,23 +1,49 @@ import { Localized } from "@fluent/react/compat"; import React, { FunctionComponent, useState } from "react"; +import { Field } from "react-final-form"; import { graphql } from "relay-runtime"; +import { formatStringList, parseStringList } from "coral-framework/lib/form"; import { withFragmentContainer } from "coral-framework/lib/relay"; +import { validateEmailDomainList } from "coral-framework/lib/validation"; import { AddIcon, ButtonSvgIcon } from "coral-ui/components/icons"; -import { Button, Flex, FormFieldDescription } from "coral-ui/components/v2"; +import { + Button, + Flex, + FormField, + FormFieldDescription, + FormFieldHeader, + HelperText, + Label, + Textarea, +} from "coral-ui/components/v2"; import { EmailDomainConfigContainer_settings } from "coral-admin/__generated__/EmailDomainConfigContainer_settings.graphql"; import ConfigBox from "../../ConfigBox"; import Header from "../../Header"; - +import ValidationMessage from "../../ValidationMessage"; import EmailDomainTableContainer from "./EmailDomainTableContainer"; +import styles from "./EmailDomainConfigContainer.css"; + interface Props { settings: EmailDomainConfigContainer_settings; + disabled: boolean; } -const EmailDomainConfigContainer: FunctionComponent = ({ settings }) => { +// eslint-disable-next-line no-unused-expressions +graphql` + fragment EmailDomainConfigContainer_formValues on Settings { + protectedEmailDomains + } +`; + +const EmailDomainConfigContainer: FunctionComponent = ({ + settings, + disabled, +}) => { + const { protectedEmailDomains } = settings; const [showDomainList, setShowDomainList] = useState(false); return ( @@ -33,8 +59,7 @@ const EmailDomainConfigContainer: FunctionComponent = ({ settings }) => { Create rules to take action on accounts or comments based on the - account holder's email address domain. Action only applies to newly - created accounts. + account holder's email address domain. = ({ settings }) => { )} {showDomainList && } + + + + + + + + + These domains cannot be banned. Domains should be written without + www, for example `gmail.com`. Separate domains with a comma. + + + + {({ input, meta }) => ( + <> +