[next] Email/Password Improvements (#2400)

* feat: improved some password/email fields

- All secret fields are now "hidden" by default
- All email fields now have autocomplete/spellcheck disabled with
  correct typings

* feat: add additional email validation
This commit is contained in:
Wyatt Johnson
2019-07-12 21:07:14 +00:00
committed by GitHub
parent f95b705585
commit bc0b0d0339
18 changed files with 584 additions and 190 deletions
@@ -4,7 +4,7 @@ import React, { FunctionComponent } from "react";
import { Field } from "react-final-form";
import { Validator } from "coral-framework/lib/validation";
import { FormField, InputLabel, TextField } from "coral-ui/components";
import { FormField, InputLabel, PasswordField } from "coral-ui/components";
import ValidationMessage from "../../ValidationMessage";
@@ -31,15 +31,14 @@ const ClientSecretField: FunctionComponent<Props> = ({
>
{({ input, meta }) => (
<>
<TextField
<PasswordField
name={input.name}
onChange={input.onChange}
value={input.value}
disabled={disabled}
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
spellCheck={false}
// TODO: (wyattjoh) figure out how to add translations to these props
hidePasswordTitle="Show Client Secret"
showPasswordTitle="Hide Client Secret"
/>
{meta.touched && (meta.error || meta.submitError) && (
<ValidationMessage>
@@ -7,7 +7,7 @@ import {
FormField,
Icon,
InputLabel,
TextField,
PasswordField,
Typography,
} from "coral-ui/components";
@@ -31,7 +31,14 @@ const SSOKeyField: FunctionComponent<Props> = ({
<InputLabel>Key</InputLabel>
</Localized>
<Flex direction="row" itemGutter="half" alignItems="center">
<TextField name="key" value={generatedKey} readOnly />
<PasswordField
name="key"
value={generatedKey}
readOnly
// TODO: (wyattjoh) figure out how to add translations to these props
hidePasswordTitle="Show SSO Key"
showPasswordTitle="Hide SSO Key"
/>
<Localized id="configure-auth-sso-regenerate">
<Button
id="configure-auth-sso-regenerate"
@@ -4,7 +4,7 @@ import React, { FunctionComponent } from "react";
import { Field } from "react-final-form";
import { Validator } from "coral-framework/lib/validation";
import { FormField, InputLabel, TextField } from "coral-ui/components";
import { FormField, InputLabel, PasswordField } from "coral-ui/components";
import ValidationMessage from "../../ValidationMessage";
@@ -28,16 +28,15 @@ const APIKeyField: FunctionComponent<Props> = ({
API Key
</InputLabel>
</Localized>
<TextField
<PasswordField
id={`configure-moderation-${input.name}`}
name={input.name}
onChange={input.onChange}
value={input.value}
disabled={disabled}
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
spellCheck={false}
// TODO: (wyattjoh) figure out how to add translations to these props
hidePasswordTitle="Show API Key"
showPasswordTitle="Hide API Key"
/>
{meta.touched && (meta.error || meta.submitError) && (
<ValidationMessage>
@@ -35,12 +35,16 @@ we require users to create a password.
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorError PasswordField-fullWidth PasswordField-input"
disabled={false}
id="password"
name="password"
onChange={[Function]}
placeholder="Password"
spellCheck={false}
type="password"
value="x"
/>
@@ -154,12 +158,16 @@ we require users to create a password.
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorRegular PasswordField-fullWidth PasswordField-input"
disabled={false}
id="password"
name="password"
onChange={[Function]}
placeholder="Password"
spellCheck={false}
type="password"
value=""
/>
@@ -236,12 +244,16 @@ we require users to create a password.
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorError PasswordField-fullWidth PasswordField-input"
disabled={false}
id="password"
name="password"
onChange={[Function]}
placeholder="Password"
spellCheck={false}
type="password"
value=""
/>
@@ -340,12 +352,16 @@ GraphQL request (4:3)
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorRegular PasswordField-fullWidth PasswordField-input"
disabled={false}
id="password"
name="password"
onChange={[Function]}
placeholder="Password"
spellCheck={false}
type="password"
value="secretpassword"
/>
@@ -417,12 +433,16 @@ we require users to create a password.
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorRegular PasswordField-fullWidth PasswordField-input"
disabled={false}
id="password"
name="password"
onChange={[Function]}
placeholder="Password"
spellCheck={false}
type="password"
value=""
/>
@@ -61,12 +61,16 @@ exports[`accepts correct password 1`] = `
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorRegular PasswordField-fullWidth PasswordField-input"
disabled={false}
id="password"
name="password"
onChange={[Function]}
placeholder="Password"
spellCheck={false}
type="password"
value="testtest"
/>
@@ -159,12 +163,16 @@ exports[`accepts valid email 1`] = `
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorError PasswordField-fullWidth PasswordField-input"
disabled={false}
id="password"
name="password"
onChange={[Function]}
placeholder="Password"
spellCheck={false}
type="password"
value=""
/>
@@ -283,12 +291,16 @@ exports[`checks for invalid email 1`] = `
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorError PasswordField-fullWidth PasswordField-input"
disabled={false}
id="password"
name="password"
onChange={[Function]}
placeholder="Password"
spellCheck={false}
type="password"
value=""
/>
@@ -471,12 +483,16 @@ exports[`renders sign in form 1`] = `
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorRegular PasswordField-fullWidth PasswordField-input"
disabled={false}
id="password"
name="password"
onChange={[Function]}
placeholder="Password"
spellCheck={false}
type="password"
value=""
/>
@@ -596,12 +612,16 @@ exports[`shows error when submitting empty form 1`] = `
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorError PasswordField-fullWidth PasswordField-input"
disabled={false}
id="password"
name="password"
onChange={[Function]}
placeholder="Password"
spellCheck={false}
type="password"
value=""
/>
@@ -714,12 +734,16 @@ exports[`shows server error 1`] = `
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorRegular PasswordField-fullWidth PasswordField-input"
disabled={false}
id="password"
name="password"
onChange={[Function]}
placeholder="Password"
spellCheck={false}
type="password"
value="testtest"
/>
@@ -181,21 +181,39 @@ needs to be displayed, e.g. “Log in with &lt;Facebook&gt;”.
Client Secret
</label>
<div
className="TextField-root"
className="PasswordField-root"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="TextField-input TextField-colorRegular"
disabled={true}
name="auth.integrations.oidc.clientSecret"
onChange={[Function]}
placeholder=""
spellCheck={false}
type="text"
value="clientSecret"
/>
<div
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorRegular PasswordField-input"
disabled={true}
name="auth.integrations.oidc.clientSecret"
onChange={[Function]}
placeholder=""
spellCheck={false}
type="password"
value="clientSecret"
/>
<div
className="PasswordField-icon"
onClick={[Function]}
role="button"
tabIndex={0}
title="Hide Client Secret"
>
<span
aria-hidden="true"
className="Icon-root Icon-sm"
>
visibility
</span>
</div>
</div>
</div>
</div>
<div
@@ -592,21 +610,39 @@ For more information visit:
Client Secret
</label>
<div
className="TextField-root"
className="PasswordField-root"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="TextField-input TextField-colorRegular"
disabled={false}
name="auth.integrations.facebook.clientSecret"
onChange={[Function]}
placeholder=""
spellCheck={false}
type="text"
value="myClientSecret"
/>
<div
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorRegular PasswordField-input"
disabled={false}
name="auth.integrations.facebook.clientSecret"
onChange={[Function]}
placeholder=""
spellCheck={false}
type="password"
value="myClientSecret"
/>
<div
className="PasswordField-icon"
onClick={[Function]}
role="button"
tabIndex={0}
title="Hide Client Secret"
>
<span
aria-hidden="true"
className="Icon-root Icon-sm"
>
visibility
</span>
</div>
</div>
</div>
</div>
<div
@@ -904,21 +940,39 @@ needs to be displayed, e.g. “Log in with &lt;Facebook&gt;”.
Client Secret
</label>
<div
className="TextField-root"
className="PasswordField-root"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="TextField-input TextField-colorRegular"
disabled={false}
name="auth.integrations.oidc.clientSecret"
onChange={[Function]}
placeholder=""
spellCheck={false}
type="text"
value=""
/>
<div
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorRegular PasswordField-input"
disabled={false}
name="auth.integrations.oidc.clientSecret"
onChange={[Function]}
placeholder=""
spellCheck={false}
type="password"
value=""
/>
<div
className="PasswordField-icon"
onClick={[Function]}
role="button"
tabIndex={0}
title="Hide Client Secret"
>
<span
aria-hidden="true"
className="Icon-root Icon-sm"
>
visibility
</span>
</div>
</div>
</div>
</div>
<div
@@ -1370,21 +1424,39 @@ needs to be displayed, e.g. “Log in with &lt;Facebook&gt;”.
Client Secret
</label>
<div
className="TextField-root"
className="PasswordField-root"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="TextField-input TextField-colorRegular"
disabled={false}
name="auth.integrations.oidc.clientSecret"
onChange={[Function]}
placeholder=""
spellCheck={false}
type="text"
value=""
/>
<div
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorRegular PasswordField-input"
disabled={false}
name="auth.integrations.oidc.clientSecret"
onChange={[Function]}
placeholder=""
spellCheck={false}
type="password"
value=""
/>
<div
className="PasswordField-icon"
onClick={[Function]}
role="button"
tabIndex={0}
title="Hide Client Secret"
>
<span
aria-hidden="true"
className="Icon-root Icon-sm"
>
visibility
</span>
</div>
</div>
</div>
<div
className="Message-root Message-colorError ValidationMessage-root"
@@ -1721,16 +1793,38 @@ exports[`regenerate sso key 1`] = `
className="Box-root Flex-root Flex-flex Flex-halfItemGutter Flex-alignCenter Flex-directionRow gutter"
>
<div
className="TextField-root"
className="PasswordField-root"
>
<input
className="TextField-input TextField-colorRegular"
name="key"
placeholder=""
readOnly={true}
type="text"
value="==GENERATED_KEY=="
/>
<div
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorRegular PasswordField-input"
name="key"
placeholder=""
readOnly={true}
spellCheck={false}
type="password"
value="==GENERATED_KEY=="
/>
<div
className="PasswordField-icon"
onClick={[Function]}
role="button"
tabIndex={0}
title="Hide SSO Key"
>
<span
aria-hidden="true"
className="Icon-root Icon-sm"
>
visibility
</span>
</div>
</div>
</div>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantFilled"
@@ -2228,21 +2322,39 @@ needs to be displayed, e.g. “Log in with &lt;Facebook&gt;”.
Client Secret
</label>
<div
className="TextField-root"
className="PasswordField-root"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="TextField-input TextField-colorRegular"
disabled={true}
name="auth.integrations.oidc.clientSecret"
onChange={[Function]}
placeholder=""
spellCheck={false}
type="text"
value=""
/>
<div
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorRegular PasswordField-input"
disabled={true}
name="auth.integrations.oidc.clientSecret"
onChange={[Function]}
placeholder=""
spellCheck={false}
type="password"
value=""
/>
<div
className="PasswordField-icon"
onClick={[Function]}
role="button"
tabIndex={0}
title="Hide Client Secret"
>
<span
aria-hidden="true"
className="Icon-root Icon-sm"
>
visibility
</span>
</div>
</div>
</div>
</div>
<div
@@ -2547,15 +2659,37 @@ integration to register for a new account.
className="Box-root Flex-root Flex-flex Flex-halfItemGutter Flex-alignCenter Flex-directionRow gutter"
>
<div
className="TextField-root"
className="PasswordField-root"
>
<input
className="TextField-input TextField-colorRegular"
name="key"
placeholder=""
readOnly={true}
type="text"
/>
<div
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorRegular PasswordField-input"
name="key"
placeholder=""
readOnly={true}
spellCheck={false}
type="password"
/>
<div
className="PasswordField-icon"
onClick={[Function]}
role="button"
tabIndex={0}
title="Hide SSO Key"
>
<span
aria-hidden="true"
className="Icon-root Icon-sm"
>
visibility
</span>
</div>
</div>
</div>
<button
className="BaseButton-root Button-root Button-sizeSmall Button-colorPrimary Button-variantFilled Button-disabled"
@@ -2857,21 +2991,39 @@ to create and set up a web application. For more information visit:
Client Secret
</label>
<div
className="TextField-root"
className="PasswordField-root"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="TextField-input TextField-colorRegular"
disabled={true}
name="auth.integrations.google.clientSecret"
onChange={[Function]}
placeholder=""
spellCheck={false}
type="text"
value=""
/>
<div
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorRegular PasswordField-input"
disabled={true}
name="auth.integrations.google.clientSecret"
onChange={[Function]}
placeholder=""
spellCheck={false}
type="password"
value=""
/>
<div
className="PasswordField-icon"
onClick={[Function]}
role="button"
tabIndex={0}
title="Hide Client Secret"
>
<span
aria-hidden="true"
className="Icon-root Icon-sm"
>
visibility
</span>
</div>
</div>
</div>
</div>
<div
@@ -3137,21 +3289,39 @@ For more information visit:
Client Secret
</label>
<div
className="TextField-root"
className="PasswordField-root"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="TextField-input TextField-colorRegular"
disabled={true}
name="auth.integrations.facebook.clientSecret"
onChange={[Function]}
placeholder=""
spellCheck={false}
type="text"
value=""
/>
<div
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorRegular PasswordField-input"
disabled={true}
name="auth.integrations.facebook.clientSecret"
onChange={[Function]}
placeholder=""
spellCheck={false}
type="password"
value=""
/>
<div
className="PasswordField-icon"
onClick={[Function]}
role="button"
tabIndex={0}
title="Hide Client Secret"
>
<span
aria-hidden="true"
className="Icon-root Icon-sm"
>
visibility
</span>
</div>
</div>
</div>
</div>
<div
@@ -501,22 +501,40 @@ improve the API over time.
API Key
</label>
<div
className="TextField-root"
className="PasswordField-root"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="TextField-input TextField-colorRegular"
disabled={false}
id="configure-moderation-integrations.perspective.key"
name="integrations.perspective.key"
onChange={[Function]}
placeholder=""
spellCheck={false}
type="text"
value=""
/>
<div
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorRegular PasswordField-input"
disabled={false}
id="configure-moderation-integrations.perspective.key"
name="integrations.perspective.key"
onChange={[Function]}
placeholder=""
spellCheck={false}
type="password"
value=""
/>
<div
className="PasswordField-icon"
onClick={[Function]}
role="button"
tabIndex={0}
title="Hide API Key"
>
<span
aria-hidden="true"
className="Icon-root Icon-sm"
>
visibility
</span>
</div>
</div>
</div>
</div>
<div
@@ -670,22 +688,40 @@ in your Akismet account:
API Key
</label>
<div
className="TextField-root"
className="PasswordField-root"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="TextField-input TextField-colorRegular"
disabled={false}
id="configure-moderation-integrations.akismet.key"
name="integrations.akismet.key"
onChange={[Function]}
placeholder=""
spellCheck={false}
type="text"
value=""
/>
<div
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorRegular PasswordField-input"
disabled={false}
id="configure-moderation-integrations.akismet.key"
name="integrations.akismet.key"
onChange={[Function]}
placeholder=""
spellCheck={false}
type="password"
value=""
/>
<div
className="PasswordField-icon"
onClick={[Function]}
role="button"
tabIndex={0}
title="Hide API Key"
>
<span
aria-hidden="true"
className="Icon-root Icon-sm"
>
visibility
</span>
</div>
</div>
</div>
</div>
<div
@@ -159,12 +159,16 @@ exports[`renders form 1`] = `
className="PasswordField-wrapper"
>
<input
autoCapitalize="off"
autoComplete="off"
autoCorrect="off"
className="PasswordField-colorRegular PasswordField-fullWidth PasswordField-input"
disabled={false}
id="password"
name="password"
onChange={[Function]}
placeholder="Password"
spellCheck={false}
type="password"
value=""
/>