diff options
Diffstat (limited to 'web/source/settings/views/moderation')
8 files changed, 124 insertions, 26 deletions
diff --git a/web/source/settings/views/moderation/accounts/detail/actions.tsx b/web/source/settings/views/moderation/accounts/detail/actions.tsx index 4132b778a..ddcb1a5de 100644 --- a/web/source/settings/views/moderation/accounts/detail/actions.tsx +++ b/web/source/settings/views/moderation/accounts/detail/actions.tsx @@ -78,14 +78,21 @@ function ModerateAccount({ account }: { account: AdminAccount }) { > <h3 id="account-moderation-actions">Account Moderation Actions</h3> <div> - Currently only the "suspend" action is implemented.<br/> - Suspending an account will delete it from your server, and remove all of its media, posts, relationships, etc.<br/> - If the suspended account is local, suspending will also send out a "delete" message to other servers, requesting them to remove its data from their instance as well.<br/> + Currently only the "suspend" action is implemented. + <br/> + Suspending an account will delete it from your server, + and remove all of its media, posts, relationships, etc. + <br/> + If the suspended account is local, suspending will also + send out a "delete" message to other servers, requesting + them to remove its data from their instance as well. + <br/> <b>Account suspension cannot be reversed.</b> </div> <TextInput field={form.reason} placeholder="Reason for this action" + autoCapitalize="sentences" /> <div className="action-buttons"> <MutationButton diff --git a/web/source/settings/views/moderation/accounts/index.tsx b/web/source/settings/views/moderation/accounts/index.tsx index 946ed323d..8464c8489 100644 --- a/web/source/settings/views/moderation/accounts/index.tsx +++ b/web/source/settings/views/moderation/accounts/index.tsx @@ -23,12 +23,16 @@ import { AccountSearchForm } from "./search"; export default function AccountsSearch({ }) { return ( <div className="accounts-view"> - <h1>Accounts Search</h1> - <span> - You can perform actions on an account by clicking - its name in a report, or by searching for the account - using the form below and clicking on its name. - </span> + <div className="form-section-docs"> + <h1>Accounts Search</h1> + <p> + You can perform actions on an account by clicking + its name in a report, or by searching for the account + using the form below and clicking on its name. + <br/> + All fields in the below form are optional. + </p> + </div> <AccountSearchForm /> </div> ); diff --git a/web/source/settings/views/moderation/accounts/pending/index.tsx b/web/source/settings/views/moderation/accounts/pending/index.tsx index d47363954..f03c4800c 100644 --- a/web/source/settings/views/moderation/accounts/pending/index.tsx +++ b/web/source/settings/views/moderation/accounts/pending/index.tsx @@ -44,7 +44,23 @@ export default function AccountsPending() { return ( <div className="accounts-view"> - <h1>Pending Accounts</h1> + <div className="form-section-docs"> + <h1>Pending Accounts</h1> + <p> + You can see a list of pending account sign-ups below. + <br/> + To approve or reject a sign-up, click on the account's name in the + list, and use the controls at the bottom of the account detail view. + </p> + <a + href="https://docs.gotosocial.org/en/latest/admin/signups/" + target="_blank" + className="docslink" + rel="noreferrer" + > + Learn more about account sign-ups (opens in a new tab) + </a> + </div> <PageableList isLoading={searchRes.isLoading} isFetching={searchRes.isFetching} diff --git a/web/source/settings/views/moderation/accounts/search/index.tsx b/web/source/settings/views/moderation/accounts/search/index.tsx index f37e22a66..504746adc 100644 --- a/web/source/settings/views/moderation/accounts/search/index.tsx +++ b/web/source/settings/views/moderation/accounts/search/index.tsx @@ -27,6 +27,7 @@ import MutationButton from "../../../../components/form/mutation-button"; import { useLocation, useSearch } from "wouter"; import { AdminAccount } from "../../../../lib/types/account"; import Username from "../../../../components/username"; +import isValidDomain from "is-valid-domain"; export function AccountSearchForm() { const [ location, setLocation ] = useLocation(); @@ -42,7 +43,31 @@ export function AccountSearchForm() { permissions: useTextInput("permissions", { defaultValue: urlQueryParams.get("permissions") ?? ""}), username: useTextInput("username", { defaultValue: urlQueryParams.get("username") ?? ""}), display_name: useTextInput("display_name", { defaultValue: urlQueryParams.get("display_name") ?? ""}), - by_domain: useTextInput("by_domain", { defaultValue: urlQueryParams.get("by_domain") ?? ""}), + by_domain: useTextInput("by_domain", { + defaultValue: urlQueryParams.get("by_domain") ?? "", + validator: (v: string) => { + if (v.length === 0) { + return ""; + } + + if (v[v.length-1] === ".") { + return "invalid domain"; + } + + const valid = isValidDomain(v, { + subdomain: true, + wildcard: false, + allowUnicode: true, + topLevel: false, + }); + + if (valid) { + return ""; + } + + return "invalid domain"; + } + }), email: useTextInput("email", { defaultValue: urlQueryParams.get("email") ?? ""}), ip: useTextInput("ip", { defaultValue: urlQueryParams.get("ip") ?? ""}), limit: useTextInput("limit", { defaultValue: urlQueryParams.get("limit") ?? "50"}) @@ -109,13 +134,17 @@ export function AccountSearchForm() { > <TextInput field={form.username} - label={"(Optional) username (without leading '@' symbol)"} + label={`Username (without "@" prefix) - case sensitive`} placeholder="someone" + autoCapitalize="none" + spellCheck="false" /> <TextInput field={form.by_domain} - label={"(Optional) domain"} + label={`Domain (without "https://" prefix)`} placeholder="example.org" + autoCapitalize="none" + spellCheck="false" /> <Select field={form.origin} @@ -130,15 +159,18 @@ export function AccountSearchForm() { ></Select> <TextInput field={form.email} - label={"(Optional) email address (local accounts only)"} + label={"Email address (local accounts only)"} placeholder={"someone@example.org"} // Get email validation for free. - {...{type: "email"}} + type="email" /> <TextInput field={form.ip} - label={"(Optional) IP address (local accounts only)"} + label={"IP address (local accounts only)"} placeholder={"198.51.100.0"} + autoCapitalize="none" + spellCheck="false" + className="monospace" /> <Select field={form.status} diff --git a/web/source/settings/views/moderation/domain-permissions/detail.tsx b/web/source/settings/views/moderation/domain-permissions/detail.tsx index 47072b8cb..2b27b534d 100644 --- a/web/source/settings/views/moderation/domain-permissions/detail.tsx +++ b/web/source/settings/views/moderation/domain-permissions/detail.tsx @@ -39,6 +39,7 @@ import { NoArg } from "../../../lib/types/query"; import { Error } from "../../../components/error"; import { useBaseUrl } from "../../../lib/navigation/util"; import { PermType } from "../../../lib/types/perm"; +import isValidDomain from "is-valid-domain"; export default function DomainPermDetail() { const baseUrl = useBaseUrl(); @@ -139,7 +140,32 @@ function DomainPermForm({ defaultDomain, perm, permType }: DomainPermFormProps) }; const form = { - domain: useTextInput("domain", { source: perm, defaultValue: defaultDomain }), + domain: useTextInput("domain", { + source: perm, + defaultValue: defaultDomain, + validator: (v: string) => { + if (v.length === 0) { + return ""; + } + + if (v[v.length-1] === ".") { + return "invalid domain"; + } + + const valid = isValidDomain(v, { + subdomain: true, + wildcard: false, + allowUnicode: true, + topLevel: false, + }); + + if (valid) { + return ""; + } + + return "invalid domain"; + } + }), obfuscate: useBoolInput("obfuscate", { source: perm }), commentPrivate: useTextInput("private_comment", { source: perm }), commentPublic: useTextInput("public_comment", { source: perm }) @@ -208,6 +234,8 @@ function DomainPermForm({ defaultDomain, perm, permType }: DomainPermFormProps) field={form.domain} label="Domain" placeholder="example.com" + autoCapitalize="none" + spellCheck="false" {...disabledForm} /> @@ -220,6 +248,7 @@ function DomainPermForm({ defaultDomain, perm, permType }: DomainPermFormProps) <TextArea field={form.commentPrivate} label="Private comment" + autoCapitalize="sentences" rows={3} {...disabledForm} /> @@ -227,6 +256,7 @@ function DomainPermForm({ defaultDomain, perm, permType }: DomainPermFormProps) <TextArea field={form.commentPublic} label="Public comment" + autoCapitalize="sentences" rows={3} {...disabledForm} /> diff --git a/web/source/settings/views/moderation/domain-permissions/form.tsx b/web/source/settings/views/moderation/domain-permissions/form.tsx index ea7fdbc23..204e9510c 100644 --- a/web/source/settings/views/moderation/domain-permissions/form.tsx +++ b/web/source/settings/views/moderation/domain-permissions/form.tsx @@ -80,9 +80,12 @@ export default function ImportExportForm({ form, submitParse, parseResult }: Imp <div className="import-export"> <TextArea field={form.domains} - label="Domains" + label="Domains (newline-separated)" placeholder={`google.com\nfacebook.com`} rows={8} + autoCapitalize="none" + spellCheck="false" + className={"monospace"} /> <RadioGroup diff --git a/web/source/settings/views/moderation/domain-permissions/overview.tsx b/web/source/settings/views/moderation/domain-permissions/overview.tsx index 1c919c14d..78560ba34 100644 --- a/web/source/settings/views/moderation/domain-permissions/overview.tsx +++ b/web/source/settings/views/moderation/domain-permissions/overview.tsx @@ -66,9 +66,11 @@ export default function DomainPermissionsOverview() { } return ( - <> - <h1>Domain {permTypeUpper}s</h1> - { permType == "block" ? <BlockHelperText/> : <AllowHelperText/> } + <div className={`domain-${permType}`}> + <div className="form-section-docs"> + <h1>Domain {permTypeUpper}s</h1> + { permType == "block" ? <BlockHelperText/> : <AllowHelperText/> } + </div> <DomainPermsList data={data} permType={permType} @@ -77,7 +79,7 @@ export default function DomainPermissionsOverview() { <Link to={`~${baseUrl}/import-export`}> Or use the bulk import/export interface </Link> - </> + </div> ); } diff --git a/web/source/settings/views/moderation/reports/detail.tsx b/web/source/settings/views/moderation/reports/detail.tsx index 7d6e542fb..298b5bd37 100644 --- a/web/source/settings/views/moderation/reports/detail.tsx +++ b/web/source/settings/views/moderation/reports/detail.tsx @@ -213,14 +213,18 @@ function ReportActionForm({ report }) { This is useful for providing an explanation about what action was taken (if any) before the report was marked as resolved. <br /> - <b> - Any comment made here will be visible - to the user that created the report! - </b> + <div className="info"> + <i className="fa fa-fw fa-exclamation-triangle" aria-hidden="true"></i> + <b> + If the report was created by a local account, then any + comment made here will be emailed to that account's user! + </b> + </div> </> <TextArea field={form.comment} label="Comment" + autoCapitalize="sentences" /> <MutationButton disabled={false} |