mirror of
https://github.com/wassname/talk.git
synced 2026-07-06 05:17:19 +08:00
[CORL-516] forgot password flow in admin (#2558)
* add forgot password page and link to admin * add translations * update snaps * fix: install patch * fix: adapted localizations * fix: added email type to email field * fix: updated snapshots
This commit is contained in:
committed by
Wyatt Johnson
parent
2559d1c0e8
commit
a89dc4675a
@@ -16,6 +16,7 @@ import {
|
||||
OrganizationConfigRoute,
|
||||
WordListConfigRoute,
|
||||
} from "./routes/Configure/sections";
|
||||
import ForgotPasswordRoute from "./routes/ForgotPassword";
|
||||
import InviteRoute from "./routes/Invite";
|
||||
import LoginRoute from "./routes/Login";
|
||||
import ModerateRoute from "./routes/Moderate";
|
||||
@@ -79,5 +80,6 @@ export default makeRouteConfig(
|
||||
</Route>
|
||||
<Route path="invite" {...InviteRoute.routeConfig} />
|
||||
<Route path="login" {...LoginRoute.routeConfig} />
|
||||
<Route path="forgot-password" {...ForgotPasswordRoute.routeConfig} />
|
||||
</Route>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { Localized } from "fluent-react/compat";
|
||||
import React, { FunctionComponent } from "react";
|
||||
|
||||
import Main from "coral-auth/components/Main";
|
||||
import { HorizontalGutter, Typography } from "coral-ui/components";
|
||||
|
||||
interface Props {
|
||||
email: string;
|
||||
}
|
||||
|
||||
const CheckEmail: FunctionComponent<Props> = ({ email }) => (
|
||||
<div data-testid="forgotPassword-checkEmail-container">
|
||||
<Main data-testid="forgotPassword-checkEmail-main">
|
||||
<HorizontalGutter size="full">
|
||||
<Localized
|
||||
id="forgotPassword-checkEmail-receiveEmail"
|
||||
$email={email}
|
||||
strong={<strong />}
|
||||
>
|
||||
<Typography variant="bodyCopy">
|
||||
If there is an account associated with <strong>{email}</strong>, you
|
||||
will receive an email with a link to create a new password.
|
||||
</Typography>
|
||||
</Localized>
|
||||
</HorizontalGutter>
|
||||
</Main>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default CheckEmail;
|
||||
@@ -0,0 +1,11 @@
|
||||
.container {
|
||||
width: 350px;
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid var(--palette-grey-lighter);
|
||||
margin-top: 70px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.textLink {
|
||||
color: var(--palette-primary-main);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { Localized } from "fluent-react/compat";
|
||||
import { Link } from "found";
|
||||
import React, { FunctionComponent, useState } from "react";
|
||||
|
||||
import { Bar, SubBar, Title } from "coral-auth/components/Header";
|
||||
import { Flex, Typography } from "coral-ui/components";
|
||||
import CheckEmail from "./CheckEmail";
|
||||
import ForgotPasswordForm from "./ForgotPasswordForm";
|
||||
|
||||
import styles from "./ForgotPasswordContainer.css";
|
||||
|
||||
const ForgotPasswordContainer: FunctionComponent = () => {
|
||||
const [checkEmail, setCheckEmail] = useState<string | null>(null);
|
||||
return (
|
||||
<Flex justifyContent="center">
|
||||
<div className={styles.container}>
|
||||
<Bar>
|
||||
{!checkEmail ? (
|
||||
<Localized id="forgotPassword-forgotPasswordHeader">
|
||||
<Title>Forgot Password?</Title>
|
||||
</Localized>
|
||||
) : (
|
||||
<Localized id="forgotPassword-checkEmailHeader">
|
||||
<Title>Check Email</Title>
|
||||
</Localized>
|
||||
)}
|
||||
</Bar>
|
||||
<SubBar>
|
||||
<Typography variant="bodyCopy" container={Flex}>
|
||||
<Localized id="forgotPassword-gotBackToSignIn">
|
||||
<Link className={styles.textLink} to="/admin/login">
|
||||
Go back to sign in page
|
||||
</Link>
|
||||
</Localized>
|
||||
</Typography>
|
||||
</SubBar>
|
||||
{checkEmail ? (
|
||||
<CheckEmail email={checkEmail} />
|
||||
) : (
|
||||
<ForgotPasswordForm onCheckEmail={setCheckEmail} />
|
||||
)}
|
||||
</div>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export default ForgotPasswordContainer;
|
||||
@@ -0,0 +1,120 @@
|
||||
import { FORM_ERROR } from "final-form";
|
||||
import { Localized } from "fluent-react/compat";
|
||||
import React, { FunctionComponent, useCallback } from "react";
|
||||
import { Field, Form } from "react-final-form";
|
||||
|
||||
import Main from "coral-auth/components/Main";
|
||||
import { InvalidRequestError } from "coral-framework/lib/errors";
|
||||
import { colorFromMeta, ValidationMessage } from "coral-framework/lib/form";
|
||||
import { useMutation } from "coral-framework/lib/relay";
|
||||
import {
|
||||
composeValidators,
|
||||
required,
|
||||
validateEmail,
|
||||
} from "coral-framework/lib/validation";
|
||||
import {
|
||||
Button,
|
||||
CallOut,
|
||||
FormField,
|
||||
HorizontalGutter,
|
||||
InputLabel,
|
||||
TextField,
|
||||
Typography,
|
||||
} from "coral-ui/components";
|
||||
|
||||
import ForgotPasswordMutation from "./ForgotPasswordMutation";
|
||||
|
||||
interface FormProps {
|
||||
email: string;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
onCheckEmail: (email: string) => void;
|
||||
}
|
||||
|
||||
const ForgotPasswordForm: FunctionComponent<Props> = props => {
|
||||
const forgotPassword = useMutation(ForgotPasswordMutation);
|
||||
const onSubmit = useCallback(
|
||||
async (form: FormProps) => {
|
||||
try {
|
||||
await forgotPassword(form);
|
||||
props.onCheckEmail(form.email);
|
||||
} catch (error) {
|
||||
if (error instanceof InvalidRequestError) {
|
||||
return error.invalidArgs;
|
||||
}
|
||||
return { [FORM_ERROR]: error.message };
|
||||
}
|
||||
return;
|
||||
},
|
||||
[forgotPassword]
|
||||
);
|
||||
return (
|
||||
<div data-testid="admin-forgotPassword-container">
|
||||
<Main data-testid="admin-forgotPassword-main">
|
||||
<Form onSubmit={onSubmit}>
|
||||
{({ handleSubmit, submitting, submitError }) => (
|
||||
<form autoComplete="off" onSubmit={handleSubmit}>
|
||||
<HorizontalGutter size="full">
|
||||
<Localized id="forgotPassword-enterEmailAndGetALink">
|
||||
<Typography variant="bodyCopy">
|
||||
Enter your email address below and we will send you a link
|
||||
to reset your password.
|
||||
</Typography>
|
||||
</Localized>
|
||||
{submitError && (
|
||||
<CallOut color="error" fullWidth>
|
||||
{submitError}
|
||||
</CallOut>
|
||||
)}
|
||||
<Field
|
||||
name="email"
|
||||
validate={composeValidators(required, validateEmail)}
|
||||
>
|
||||
{({ input, meta }) => (
|
||||
<FormField>
|
||||
<Localized id="forgotPassword-emailAddressLabel">
|
||||
<InputLabel htmlFor={input.name}>
|
||||
Email Address
|
||||
</InputLabel>
|
||||
</Localized>
|
||||
<Localized
|
||||
id="forgotPassword-emailAddressTextField"
|
||||
attrs={{ placeholder: true }}
|
||||
>
|
||||
<TextField
|
||||
id={input.name}
|
||||
placeholder="Email Address"
|
||||
color={colorFromMeta(meta)}
|
||||
disabled={submitting}
|
||||
type="email"
|
||||
fullWidth
|
||||
{...input}
|
||||
/>
|
||||
</Localized>
|
||||
<ValidationMessage meta={meta} fullWidth />
|
||||
</FormField>
|
||||
)}
|
||||
</Field>
|
||||
<Localized id="forgotPassword-sendEmailButton">
|
||||
<Button
|
||||
variant="filled"
|
||||
color="primary"
|
||||
size="large"
|
||||
fullWidth
|
||||
type="submit"
|
||||
disabled={submitting}
|
||||
>
|
||||
Send Email
|
||||
</Button>
|
||||
</Localized>
|
||||
</HorizontalGutter>
|
||||
</form>
|
||||
)}
|
||||
</Form>
|
||||
</Main>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ForgotPasswordForm;
|
||||
@@ -0,0 +1,12 @@
|
||||
import { pick } from "lodash";
|
||||
|
||||
import { createMutation } from "coral-framework/lib/relay";
|
||||
import { forgotPassword, ForgotPasswordInput } from "coral-framework/rest";
|
||||
|
||||
const ForgotPasswordMutation = createMutation(
|
||||
"forgotPassword",
|
||||
(_, input: ForgotPasswordInput, { rest }) =>
|
||||
forgotPassword(rest, pick(input, ["email"]))
|
||||
);
|
||||
|
||||
export default ForgotPasswordMutation;
|
||||
@@ -0,0 +1,11 @@
|
||||
import { withRouteConfig } from "coral-framework/lib/router";
|
||||
import React from "react";
|
||||
import ForgotPasswordContainer from "./ForgotPasswordContainer";
|
||||
|
||||
const ForgotPasswordRoute: React.FunctionComponent = () => {
|
||||
return <ForgotPasswordContainer />;
|
||||
};
|
||||
|
||||
const enhanced = withRouteConfig({})(ForgotPasswordRoute);
|
||||
|
||||
export default enhanced;
|
||||
@@ -0,0 +1 @@
|
||||
export { default, default as ForgotPasswordRoute } from "./ForgotPasswordRoute";
|
||||
@@ -0,0 +1,4 @@
|
||||
.textLink {
|
||||
color: var(--palette-primary-main);
|
||||
text-decoration: underline;
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Localized } from "fluent-react/compat";
|
||||
import { Link } from "found";
|
||||
import React, { FunctionComponent } from "react";
|
||||
import { Field, Form } from "react-final-form";
|
||||
|
||||
@@ -13,13 +14,17 @@ import {
|
||||
Button,
|
||||
ButtonIcon,
|
||||
CallOut,
|
||||
Flex,
|
||||
FormField,
|
||||
HorizontalGutter,
|
||||
InputLabel,
|
||||
Typography,
|
||||
} from "coral-ui/components";
|
||||
|
||||
import EmailField from "../../EmailField";
|
||||
|
||||
import styles from "./SignInWithEmail.css";
|
||||
|
||||
interface FormProps {
|
||||
email: string;
|
||||
password: string;
|
||||
@@ -62,6 +67,18 @@ const SignInWithEmail: FunctionComponent<SignInWithEmailForm> = props => {
|
||||
/>
|
||||
</Localized>
|
||||
<ValidationMessage meta={meta} fullWidth />
|
||||
<Flex justifyContent="flex-end">
|
||||
<Typography>
|
||||
<Localized id="login-signIn-forgot-password">
|
||||
<Link
|
||||
className={styles.textLink}
|
||||
to="/admin/forgot-password"
|
||||
>
|
||||
Forgot your password?
|
||||
</Link>
|
||||
</Localized>
|
||||
</Typography>
|
||||
</Flex>
|
||||
</FormField>
|
||||
)}
|
||||
</Field>
|
||||
@@ -74,6 +91,7 @@ const SignInWithEmail: FunctionComponent<SignInWithEmailForm> = props => {
|
||||
fullWidth
|
||||
>
|
||||
<ButtonIcon size="md">email</ButtonIcon>
|
||||
|
||||
<Localized id="login-signIn-signInWithEmail">
|
||||
<span>Sign in with Email</span>
|
||||
</Localized>
|
||||
|
||||
@@ -94,6 +94,21 @@ exports[`accepts correct password 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="Box-root Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<p
|
||||
className="Box-root Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
<a
|
||||
className="SignInWithEmail-textLink"
|
||||
href="/admin/forgot-password"
|
||||
onClick={[Function]}
|
||||
>
|
||||
Forgot your password?
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorBrand Button-variantFilled Button-fullWidth"
|
||||
@@ -215,6 +230,21 @@ exports[`accepts valid email 1`] = `
|
||||
This field is required.
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="Box-root Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<p
|
||||
className="Box-root Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
<a
|
||||
className="SignInWithEmail-textLink"
|
||||
href="/admin/forgot-password"
|
||||
onClick={[Function]}
|
||||
>
|
||||
Forgot your password?
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorBrand Button-variantFilled Button-fullWidth"
|
||||
@@ -349,6 +379,21 @@ exports[`checks for invalid email 1`] = `
|
||||
This field is required.
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="Box-root Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<p
|
||||
className="Box-root Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
<a
|
||||
className="SignInWithEmail-textLink"
|
||||
href="/admin/forgot-password"
|
||||
onClick={[Function]}
|
||||
>
|
||||
Forgot your password?
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorBrand Button-variantFilled Button-fullWidth"
|
||||
@@ -504,6 +549,21 @@ exports[`renders sign in form 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="Box-root Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<p
|
||||
className="Box-root Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
<a
|
||||
className="SignInWithEmail-textLink"
|
||||
href="/admin/forgot-password"
|
||||
onClick={[Function]}
|
||||
>
|
||||
Forgot your password?
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorBrand Button-variantFilled Button-fullWidth"
|
||||
@@ -652,6 +712,21 @@ exports[`shows error when submitting empty form 1`] = `
|
||||
This field is required.
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="Box-root Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<p
|
||||
className="Box-root Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
<a
|
||||
className="SignInWithEmail-textLink"
|
||||
href="/admin/forgot-password"
|
||||
onClick={[Function]}
|
||||
>
|
||||
Forgot your password?
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorBrand Button-variantFilled Button-fullWidth"
|
||||
@@ -767,6 +842,21 @@ exports[`shows server error 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="Box-root Flex-root Flex-flex Flex-justifyFlexEnd"
|
||||
>
|
||||
<p
|
||||
className="Box-root Typography-root Typography-bodyCopy Typography-colorTextPrimary"
|
||||
>
|
||||
<a
|
||||
className="SignInWithEmail-textLink"
|
||||
href="/admin/forgot-password"
|
||||
onClick={[Function]}
|
||||
>
|
||||
Forgot your password?
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="BaseButton-root Button-root Button-sizeLarge Button-colorBrand Button-variantFilled Button-fullWidth"
|
||||
|
||||
@@ -245,7 +245,7 @@ each of your site’s stories.
|
||||
<p
|
||||
className="Box-root Typography-root Typography-bodyShort Typography-colorTextPrimary"
|
||||
>
|
||||
When enabled, there will be real-time loading and updating of comments.
|
||||
When enabled, there will be real-time loading and updating of comments.
|
||||
When disabled, users will have to refresh the page to see new comments.
|
||||
</p>
|
||||
<div>
|
||||
|
||||
@@ -211,9 +211,9 @@ exports[`renders configure general 1`] = `
|
||||
<p
|
||||
className="Box-root Typography-root Typography-bodyShort Typography-colorTextPrimary"
|
||||
>
|
||||
Open or close comment streams for new comments sitewide.
|
||||
When new comments are turned off, new comments cannot be
|
||||
submitted, but existing comments can continue to receive
|
||||
Open or close comment streams for new comments sitewide.
|
||||
When new comments are turned off, new comments cannot be
|
||||
submitted, but existing comments can continue to receive
|
||||
reactions, be reported, and be shared.
|
||||
</p>
|
||||
<fieldset
|
||||
@@ -386,9 +386,9 @@ reactions, be reported, and be shared.
|
||||
<p
|
||||
className="Box-root Typography-root Typography-fieldDescription Typography-colorTextSecondary"
|
||||
>
|
||||
This will appear above the comments sitewide.
|
||||
You can format the text using Markdown.
|
||||
More information on how to use Markdown
|
||||
This will appear above the comments sitewide.
|
||||
You can format the text using Markdown.
|
||||
More information on how to use Markdown
|
||||
|
||||
<a
|
||||
className="ExternalLink-root"
|
||||
@@ -858,7 +858,7 @@ moderation panel.
|
||||
className="Box-root Typography-root Typography-bodyShort Typography-colorTextPrimary"
|
||||
>
|
||||
Allow your community to engage with one another and express themselves
|
||||
with one-click reactions. By default, Coral allows commenters to "Respect"
|
||||
with one-click reactions. By default, Coral allows commenters to "Respect"
|
||||
each other's comments.
|
||||
</p>
|
||||
<div
|
||||
|
||||
@@ -318,9 +318,9 @@ approved by a moderator.
|
||||
<p
|
||||
className="Box-root Typography-root Typography-fieldDescription Typography-colorTextSecondary"
|
||||
>
|
||||
Prevents repeat offenders from publishing comments without approval.
|
||||
When a commenter's rejection rate is above the threshold, their
|
||||
comments are sent to Pending for moderator approval. This does not
|
||||
Prevents repeat offenders from publishing comments without approval.
|
||||
When a commenter's rejection rate is above the threshold, their
|
||||
comments are sent to Pending for moderator approval. This does not
|
||||
apply to Staff comments.
|
||||
</p>
|
||||
<div>
|
||||
@@ -385,8 +385,8 @@ apply to Staff comments.
|
||||
<p
|
||||
className="Box-root Typography-root Typography-fieldDescription Typography-colorTextSecondary"
|
||||
>
|
||||
Rejected comments ÷ (rejected comments + published comments)
|
||||
over the timeframe above, as a percentage. It does not include
|
||||
Rejected comments ÷ (rejected comments + published comments)
|
||||
over the timeframe above, as a percentage. It does not include
|
||||
comments pending for toxicity, spam or pre-moderation.
|
||||
</p>
|
||||
<div
|
||||
@@ -435,9 +435,9 @@ comments pending for toxicity, spam or pre-moderation.
|
||||
<p
|
||||
className="Box-root Typography-root Typography-bodyShort Typography-colorTextPrimary"
|
||||
>
|
||||
Using the Perspective API, the Toxic Comment filter warns users
|
||||
when comments exceed the predefined toxicity threshold.
|
||||
Comments with a toxicity score above the threshold
|
||||
Using the Perspective API, the Toxic Comment filter warns users
|
||||
when comments exceed the predefined toxicity threshold.
|
||||
Comments with a toxicity score above the threshold
|
||||
|
||||
<strong>
|
||||
will not be published
|
||||
@@ -447,7 +447,7 @@ the
|
||||
<strong>
|
||||
Pending Queue for review by a moderator
|
||||
</strong>
|
||||
.
|
||||
.
|
||||
If approved by a moderator, the comment will be published.
|
||||
</p>
|
||||
<fieldset
|
||||
@@ -566,7 +566,7 @@ comment is toxic, according to Perspective API. By default the threshold is set
|
||||
<p
|
||||
className="Box-root Typography-root Typography-fieldDescription Typography-colorTextSecondary"
|
||||
>
|
||||
Choose your Perspective Model. The default is TOXICITY.
|
||||
Choose your Perspective Model. The default is TOXICITY.
|
||||
You can find out more about model choices
|
||||
<a
|
||||
className="ExternalLink-root"
|
||||
@@ -783,9 +783,9 @@ improve the API over time.
|
||||
<p
|
||||
className="Box-root Typography-root Typography-bodyShort Typography-colorTextPrimary"
|
||||
>
|
||||
The Akismet API filter warns users when a comment is determined likely
|
||||
to be spam. Comments that Akismet thinks are spam will not be published
|
||||
and are placed in the Pending Queue for review by a moderator.
|
||||
The Akismet API filter warns users when a comment is determined likely
|
||||
to be spam. Comments that Akismet thinks are spam will not be published
|
||||
and are placed in the Pending Queue for review by a moderator.
|
||||
If approved by a moderator, the comment will be published.
|
||||
</p>
|
||||
<fieldset
|
||||
|
||||
@@ -119,6 +119,9 @@ class AddOrganizationStep extends React.Component<Props> {
|
||||
placeholder="Organization Contact Email"
|
||||
color={colorFromMeta(meta)}
|
||||
disabled={submitting}
|
||||
type="email"
|
||||
autoCapitalize="off"
|
||||
autoCorrect="off"
|
||||
fullWidth
|
||||
{...input}
|
||||
/>
|
||||
|
||||
@@ -89,6 +89,9 @@ class CreateYourAccountStep extends Component<Props> {
|
||||
placeholder="Email"
|
||||
color={colorFromMeta(meta)}
|
||||
disabled={submitting}
|
||||
type="email"
|
||||
autoCapitalize="off"
|
||||
autoCorrect="off"
|
||||
fullWidth
|
||||
{...input}
|
||||
/>
|
||||
@@ -121,6 +124,8 @@ class CreateYourAccountStep extends Component<Props> {
|
||||
placeholder="Username"
|
||||
color={colorFromMeta(meta)}
|
||||
disabled={submitting}
|
||||
autoCapitalize="off"
|
||||
autoCorrect="off"
|
||||
fullWidth
|
||||
{...input}
|
||||
/>
|
||||
|
||||
+41
-26
@@ -59,6 +59,7 @@ login-signIn-passwordTextField =
|
||||
|
||||
login-signIn-signInWithEmail = Sign in with Email
|
||||
login-signIn-orSeparator = Or
|
||||
login-signIn-forgot-password = Forgot your password?
|
||||
|
||||
login-signInWithFacebook = Sign in with Facebook
|
||||
login-signInWithGoogle = Sign in with Google
|
||||
@@ -87,9 +88,9 @@ configure-permissionField-dontAllow = Don't allow
|
||||
### General
|
||||
configure-general-guidelines-title = Community guidelines summary
|
||||
configure-general-guidelines-explanation =
|
||||
This will appear above the comments sitewide.
|
||||
You can format the text using Markdown.
|
||||
More information on how to use Markdown
|
||||
This will appear above the comments sitewide.
|
||||
You can format the text using Markdown.
|
||||
More information on how to use Markdown
|
||||
<externalLink>here</externalLink>.
|
||||
configure-general-guidelines-showCommunityGuidelines = Show community guidelines summary
|
||||
|
||||
@@ -100,9 +101,9 @@ configure-general-locale-chooseLanguage = Choose the language for your Coral com
|
||||
#### Sitewide Commenting
|
||||
configure-general-sitewideCommenting-title = Sitewide commenting
|
||||
configure-general-sitewideCommenting-explanation =
|
||||
Open or close comment streams for new comments sitewide.
|
||||
When new comments are turned off, new comments cannot be
|
||||
submitted, but existing comments can continue to receive
|
||||
Open or close comment streams for new comments sitewide.
|
||||
When new comments are turned off, new comments cannot be
|
||||
submitted, but existing comments can continue to receive
|
||||
reactions, be reported, and be shared.
|
||||
configure-general-sitewideCommenting-enableNewCommentsSitewide =
|
||||
Enable new comments sitewide
|
||||
@@ -242,7 +243,7 @@ configure-auth-oidc-tokenURL = Token URL
|
||||
configure-auth-oidc-jwksURI = JWKS URI
|
||||
configure-auth-oidc-useLoginOn = Use OpenID Connect login on
|
||||
|
||||
configure-auth-settings = Session settings
|
||||
configure-auth-settings = Session settings
|
||||
configure-auth-settings-session-duration-label = Session duration
|
||||
|
||||
### Moderation
|
||||
@@ -255,14 +256,14 @@ configure-moderation-recentCommentHistory-timeFrame-description =
|
||||
Amount of time to calculate a commenter's rejection rate.
|
||||
configure-moderation-recentCommentHistory-enabled = Recent history filter
|
||||
configure-moderation-recentCommentHistory-enabled-description =
|
||||
Prevents repeat offenders from publishing comments without approval.
|
||||
When a commenter's rejection rate is above the threshold, their
|
||||
comments are sent to Pending for moderator approval. This does not
|
||||
Prevents repeat offenders from publishing comments without approval.
|
||||
When a commenter's rejection rate is above the threshold, their
|
||||
comments are sent to Pending for moderator approval. This does not
|
||||
apply to Staff comments.
|
||||
configure-moderation-recentCommentHistory-triggerRejectionRate = Rejection rate threshold
|
||||
configure-moderation-recentCommentHistory-triggerRejectionRate-description =
|
||||
Rejected comments ÷ (rejected comments + published comments)
|
||||
over the timeframe above, as a percentage. It does not include
|
||||
Rejected comments ÷ (rejected comments + published comments)
|
||||
over the timeframe above, as a percentage. It does not include
|
||||
comments pending for toxicity, spam or pre-moderation.
|
||||
|
||||
#### Pre-Moderation
|
||||
@@ -279,9 +280,9 @@ configure-moderation-apiKey = API key
|
||||
|
||||
configure-moderation-akismet-title = Spam detection filter
|
||||
configure-moderation-akismet-explanation =
|
||||
The Akismet API filter warns users when a comment is determined likely
|
||||
to be spam. Comments that Akismet thinks are spam will not be published
|
||||
and are placed in the Pending Queue for review by a moderator.
|
||||
The Akismet API filter warns users when a comment is determined likely
|
||||
to be spam. Comments that Akismet thinks are spam will not be published
|
||||
and are placed in the Pending Queue for review by a moderator.
|
||||
If approved by a moderator, the comment will be published.
|
||||
|
||||
#### Akismet
|
||||
@@ -295,11 +296,11 @@ configure-moderation-akismet-siteURL = Site URL
|
||||
#### Perspective
|
||||
configure-moderation-perspective-title = Toxic comment filter
|
||||
configure-moderation-perspective-explanation =
|
||||
Using the Perspective API, the Toxic Comment filter warns users
|
||||
when comments exceed the predefined toxicity threshold.
|
||||
Comments with a toxicity score above the threshold
|
||||
Using the Perspective API, the Toxic Comment filter warns users
|
||||
when comments exceed the predefined toxicity threshold.
|
||||
Comments with a toxicity score above the threshold
|
||||
<strong>will not be published</strong> and are placed in
|
||||
the <strong>Pending Queue for review by a moderator</strong>.
|
||||
the <strong>Pending Queue for review by a moderator</strong>.
|
||||
If approved by a moderator, the comment will be published.
|
||||
configure-moderation-perspective-filter = Toxic comment filter
|
||||
configure-moderation-perspective-toxicityThreshold = Toxicity threshold
|
||||
@@ -308,7 +309,7 @@ configure-moderation-perspective-toxicityThresholdDescription =
|
||||
comment is toxic, according to Perspective API. By default the threshold is set to { $default }.
|
||||
configure-moderation-perspective-toxicityModel = Toxicity model
|
||||
configure-moderation-perspective-toxicityModelDescription =
|
||||
Choose your Perspective Model. The default is { $default }.
|
||||
Choose your Perspective Model. The default is { $default }.
|
||||
You can find out more about model choices <externalLink>here</externalLink>.
|
||||
configure-moderation-perspective-allowStoreCommentData = Allow Google to store comment data
|
||||
configure-moderation-perspective-allowStoreCommentDataDescription =
|
||||
@@ -337,7 +338,7 @@ configure-wordList-suspect-explanation =
|
||||
published (if comments are not pre-moderated).</strong>
|
||||
configure-wordList-suspect-wordList = Suspect word list
|
||||
configure-wordList-suspect-wordListDetail =
|
||||
Separate suspect words or phrases with a new line.
|
||||
Separate suspect words or phrases with a new line.
|
||||
|
||||
### Advanced
|
||||
configure-advanced-customCSS = Custom CSS
|
||||
@@ -352,7 +353,7 @@ configure-advanced-permittedDomains-description =
|
||||
|
||||
configure-advanced-liveUpdates = Comment stream live updates
|
||||
configure-advanced-liveUpdates-explanation =
|
||||
When enabled, there will be real-time loading and updating of comments.
|
||||
When enabled, there will be real-time loading and updating of comments.
|
||||
When disabled, users will have to refresh the page to see new comments.
|
||||
|
||||
configure-advanced-embedCode-title = Embed code
|
||||
@@ -524,7 +525,7 @@ moderate-user-drawer-recent-history-calculated =
|
||||
moderate-user-drawer-recent-history-rejected = Rejected
|
||||
moderate-user-drawer-recent-history-tooltip-title = How is this calculated?
|
||||
moderate-user-drawer-recent-history-tooltip-body =
|
||||
Rejected comments ÷ (rejected comments + published comments).
|
||||
Rejected comments ÷ (rejected comments + published comments).
|
||||
The threshold can be changed by administrators in Configure > Moderation.
|
||||
moderate-user-drawer-recent-history-tooltip-button =
|
||||
.aria-label = Toggle recent comment history tooltip
|
||||
@@ -736,8 +737,8 @@ userDetails-suspension-end = <strong>End:</strong> { $timestamp }
|
||||
configure-general-reactions-title = Reactions
|
||||
configure-general-reactions-explanation =
|
||||
Allow your community to engage with one another and express themselves
|
||||
with one-click reactions. By default, Coral allows commenters to "Respect"
|
||||
each other's comments.
|
||||
with one-click reactions. By default, Coral allows commenters to "Respect"
|
||||
each other's comments.
|
||||
configure-general-reactions-label = Reaction label
|
||||
configure-general-reactions-input =
|
||||
.placeholder = E.g. Respect
|
||||
@@ -766,7 +767,7 @@ configure-account-features-delete-account = Delete their account
|
||||
configure-account-features-delete-account-details =
|
||||
Removes all of their comment data, username, and email address from the site and the database.
|
||||
|
||||
configure-account-features-delete-account-fieldDescriptions =
|
||||
configure-account-features-delete-account-fieldDescriptions =
|
||||
Removes all of their comment data, username, and email
|
||||
address from the site and the database.
|
||||
|
||||
@@ -781,3 +782,17 @@ configure-advanced-stories-proxy-detail =
|
||||
When specified, allows scraping requests to use the provided
|
||||
proxy. All requests will then be passed through the appropriote
|
||||
proxy as parsed by the <externalLink>npm proxy-agent</externalLink> package.
|
||||
|
||||
forgotPassword-forgotPasswordHeader = Forgot password?
|
||||
forgotPassword-checkEmailHeader = Check your email
|
||||
forgotPassword-gotBackToSignIn = Go back to sign in page
|
||||
forgotPassword-checkEmail-receiveEmail =
|
||||
If there is an account associated with <strong>{ $email }</strong>,
|
||||
you will receive an email with a link to create a new password.
|
||||
forgotPassword-enterEmailAndGetALink =
|
||||
Enter your email address below and we will send you a link
|
||||
to reset your password.
|
||||
forgotPassword-emailAddressLabel = Email address
|
||||
forgotPassword-emailAddressTextField =
|
||||
.placeholder = Email Address
|
||||
forgotPassword-sendEmailButton = Send email
|
||||
|
||||
Reference in New Issue
Block a user