зеркало из https://github.com/mozilla/fxa.git
Merge pull request #17721 from mozilla/fxa-9546
feat(totp): Update TOTP signin screens
This commit is contained in:
Коммит
02c1fca083
|
@ -10,7 +10,7 @@ export class SigninTotpCodePage extends BaseTokenCodePage {
|
|||
get codeInput() {
|
||||
this.checkPath();
|
||||
return this.page
|
||||
.getByLabel('Enter 6-digit code') // React
|
||||
.getByLabel('Enter code') // React
|
||||
.or(this.page.getByPlaceholder('Enter 6-digit code')); //Backbone
|
||||
}
|
||||
|
||||
|
|
|
@ -200,6 +200,7 @@ test.describe('recovery key promo', () => {
|
|||
settings,
|
||||
connectAnotherDevice,
|
||||
totp,
|
||||
signinTotpCode,
|
||||
},
|
||||
testAccountTracker,
|
||||
}) => {
|
||||
|
@ -226,8 +227,8 @@ test.describe('recovery key promo', () => {
|
|||
|
||||
await page.waitForURL(/signin_totp_code/);
|
||||
|
||||
const code = await getCode(secret);
|
||||
await signin.fillOutAuthenticationForm(code);
|
||||
const totpCode = await getCode(secret);
|
||||
await signinTotpCode.fillOutCodeForm(totpCode);
|
||||
|
||||
await inlineRecoveryKey.getInlineRecoveryHeader();
|
||||
await inlineRecoveryKey.clickCreateRecoveryKey();
|
||||
|
|
|
@ -16,7 +16,7 @@ test.describe('severity-1 #smoke', () => {
|
|||
});
|
||||
|
||||
test('add totp', async ({
|
||||
pages: { settings, totp, page, signin, signup },
|
||||
pages: { settings, totp, page, signin, signup, signinTotpCode },
|
||||
testAccountTracker,
|
||||
}) => {
|
||||
const credentials = await testAccountTracker.signUp();
|
||||
|
@ -41,8 +41,9 @@ test.describe('severity-1 #smoke', () => {
|
|||
await signin.goto();
|
||||
await signup.fillOutEmailForm(credentials.email);
|
||||
await signin.fillOutPasswordForm(credentials.password);
|
||||
const code = await getCode(secret);
|
||||
await signin.fillOutAuthenticationForm(code);
|
||||
await page.waitForURL(/signin_totp_code/);
|
||||
const totpCode = await getCode(secret);
|
||||
await signinTotpCode.fillOutCodeForm(totpCode);
|
||||
|
||||
await expect(page).toHaveURL(/settings/);
|
||||
await expect(settings.settingsHeading).toBeVisible();
|
||||
|
@ -59,6 +60,7 @@ test.describe('severity-1 #smoke', () => {
|
|||
page,
|
||||
signin,
|
||||
signup,
|
||||
signinTotpCode,
|
||||
},
|
||||
testAccountTracker,
|
||||
}) => {
|
||||
|
@ -90,8 +92,9 @@ test.describe('severity-1 #smoke', () => {
|
|||
|
||||
await signup.fillOutEmailForm(credentials.email);
|
||||
await signin.fillOutPasswordForm(credentials.password);
|
||||
const code = await getCode(secret);
|
||||
await signin.fillOutAuthenticationForm(code);
|
||||
await page.waitForURL(/signin_totp_code/);
|
||||
const totpCode = await getCode(secret);
|
||||
await signinTotpCode.fillOutCodeForm(totpCode);
|
||||
|
||||
await expect(page).toHaveURL(/pair/);
|
||||
|
||||
|
@ -102,7 +105,7 @@ test.describe('severity-1 #smoke', () => {
|
|||
});
|
||||
|
||||
test('error message when totp code is invalid', async ({
|
||||
pages: { settings, totp, signin, signup },
|
||||
pages: { page, settings, totp, signin, signup, signinTotpCode },
|
||||
testAccountTracker,
|
||||
}) => {
|
||||
const credentials = await testAccountTracker.signUp();
|
||||
|
@ -127,7 +130,9 @@ test.describe('severity-1 #smoke', () => {
|
|||
await signin.goto();
|
||||
await signup.fillOutEmailForm(credentials.email);
|
||||
await signin.fillOutPasswordForm(credentials.password);
|
||||
await signin.fillOutAuthenticationForm('111111');
|
||||
|
||||
await page.waitForURL(/signin_totp_code/);
|
||||
await signinTotpCode.fillOutCodeForm('111111');
|
||||
|
||||
await expect(signin.authenticationCodeTextboxTooltip).toHaveText(
|
||||
'Invalid two-step authentication code'
|
||||
|
@ -135,7 +140,7 @@ test.describe('severity-1 #smoke', () => {
|
|||
|
||||
// Required before teardown
|
||||
const code = await getCode(secret);
|
||||
await signin.fillOutAuthenticationForm(code);
|
||||
await signinTotpCode.fillOutCodeForm(code);
|
||||
await settings.disconnectTotp();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,18 +2,13 @@
|
|||
## TOTP (time-based one-time password) is a form of two-factor authentication (2FA).
|
||||
## Users that have set up two-factor authentication land on this page during sign-in.
|
||||
|
||||
# String within the <span> element appears on a separate line
|
||||
# If more appropriate in a locale, the string within the <span>, "to continue to account settings" can stand alone as "Continue to account settings"
|
||||
signin-totp-code-heading-w-default-service-v2 = Enter authentication code <span>to continue to account settings</span>
|
||||
# String within the <span> element appears on a separate line
|
||||
# If more appropriate in a locale, the string within the <span>, "to continue to { $serviceName }" can stand alone as "Continue to { $serviceName }"
|
||||
# { $serviceName } represents a product name (e.g., Mozilla VPN) that will be passed in as a variable
|
||||
signin-totp-code-heading-w-custom-service-v2 = Enter authentication code <span>to continue to { $serviceName }</span>
|
||||
signin-totp-code-instruction-v2 = Open your authentication app and enter the authentication code it provides.
|
||||
signin-totp-code-input-label-v2 = Enter 6-digit code
|
||||
signin-totp-code-subheader = Enter your two-factor authentication security code (2FA)
|
||||
signin-totp-code-instruction-v3 = Check your authenticator app to confirm your sign-in.
|
||||
signin-totp-code-input-label-v3 = Enter code
|
||||
|
||||
# Form button to confirm if the authentication code entered by the user is valid
|
||||
signin-totp-code-confirm-button = Confirm
|
||||
signin-totp-code-other-account-link = Use a different account
|
||||
signin-totp-code-recovery-code-link = Trouble entering code?
|
||||
# Error displayed in a tooltip when the form is submitted without a code
|
||||
signin-totp-code-required-error = Authentication code required
|
||||
signin-totp-code-required-error = Authentication code required
|
|
@ -78,11 +78,11 @@ describe('Sign in with TOTP code page', () => {
|
|||
renderWithLocalizationProvider(<Subject />);
|
||||
// testAllL10n(screen, bundle);
|
||||
|
||||
const headingEl = screen.getByRole('heading', { level: 1 });
|
||||
const headingEl = screen.getByRole('heading', { level: 2 });
|
||||
expect(headingEl).toHaveTextContent(
|
||||
'Enter authentication code to continue to account settings'
|
||||
'Enter your two-factor authentication security code (2FA)'
|
||||
);
|
||||
screen.getByLabelText('Enter 6-digit code');
|
||||
screen.getByLabelText('Enter code');
|
||||
|
||||
screen.getByRole('button', { name: 'Confirm' });
|
||||
screen.getByRole('link', { name: 'Use a different account' });
|
||||
|
@ -97,9 +97,9 @@ describe('Sign in with TOTP code page', () => {
|
|||
}}
|
||||
/>
|
||||
);
|
||||
const headingEl = screen.getByRole('heading', { level: 1 });
|
||||
const headingEl = screen.getByRole('heading', { level: 2 });
|
||||
expect(headingEl).toHaveTextContent(
|
||||
'Enter authentication code to continue to Mozilla VPN'
|
||||
'Enter your two-factor authentication security code (2FA)'
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -132,7 +132,7 @@ describe('Sign in with TOTP code page', () => {
|
|||
/>
|
||||
);
|
||||
|
||||
fireEvent.input(screen.getByLabelText('Enter 6-digit code'), {
|
||||
fireEvent.input(screen.getByLabelText('Enter code'), {
|
||||
target: { value: '123456' },
|
||||
});
|
||||
screen.getByRole('button', { name: 'Confirm' }).click();
|
||||
|
|
|
@ -7,8 +7,6 @@ import { Link, RouteComponentProps, useLocation } from '@reach/router';
|
|||
import { FtlMsg, hardNavigate } from 'fxa-react/lib/utils';
|
||||
import { useFtlMsgResolver } from '../../../models';
|
||||
import { logViewEvent } from '../../../lib/metrics';
|
||||
import { TwoFactorAuthImage } from '../../../components/images';
|
||||
import CardHeader from '../../../components/CardHeader';
|
||||
import FormVerifyCode, {
|
||||
FormAttributes,
|
||||
} from '../../../components/FormVerifyCode';
|
||||
|
@ -25,6 +23,7 @@ import {
|
|||
BeginSigninError,
|
||||
getLocalizedErrorMessage,
|
||||
} from '../../../lib/error-utils';
|
||||
import protectionShieldIcon from './protection-shield.svg';
|
||||
|
||||
// TODO: show a banner success message if a user is coming from reset password
|
||||
// in FXA-6491. This differs from content-server where currently, users only
|
||||
|
@ -75,8 +74,8 @@ export const SigninTotpCode = ({
|
|||
);
|
||||
|
||||
const formAttributes: FormAttributes = {
|
||||
inputFtlId: 'signin-totp-code-input-label-v2',
|
||||
inputLabelText: 'Enter 6-digit code',
|
||||
inputFtlId: 'signin-totp-code-input-label-v3',
|
||||
inputLabelText: 'Enter code',
|
||||
pattern: '[0-9]{6}',
|
||||
maxLength: 6,
|
||||
submitButtonFtlId: 'signin-totp-code-confirm-button',
|
||||
|
@ -141,25 +140,22 @@ export const SigninTotpCode = ({
|
|||
|
||||
return (
|
||||
<AppLayout>
|
||||
<CardHeader
|
||||
headingWithDefaultServiceFtlId="signin-totp-code-heading-w-default-service-v2"
|
||||
headingWithCustomServiceFtlId="signin-totp-code-heading-w-custom-service-v2"
|
||||
headingText="Enter authentication code"
|
||||
{...{ serviceName }}
|
||||
/>
|
||||
<h2 className="font-bold text-xl text-left">
|
||||
<FtlMsg id="signin-totp-code-subheader">
|
||||
Enter your two-factor authentication security code (2FA)
|
||||
</FtlMsg>
|
||||
</h2>
|
||||
|
||||
{bannerError && <Banner type={BannerType.error}>{bannerError}</Banner>}
|
||||
|
||||
<div className="flex justify-center mx-auto">
|
||||
<TwoFactorAuthImage className="w-3/5" />
|
||||
<div className="flex space-x-4">
|
||||
<img src={protectionShieldIcon} alt="" />
|
||||
<FtlMsg id="signin-totp-code-instruction-v3">
|
||||
<p id="totp-code-instruction" className="my-5 text-md text-left">
|
||||
Check your authenticator app to confirm your sign-in.
|
||||
</p>
|
||||
</FtlMsg>
|
||||
</div>
|
||||
|
||||
<FtlMsg id="signin-totp-code-instruction-v2">
|
||||
<p id="totp-code-instruction" className="my-5 text-sm">
|
||||
Open your authentication app and enter the authentication code it
|
||||
provides.
|
||||
</p>
|
||||
</FtlMsg>
|
||||
{bannerError && <Banner type={BannerType.error}>{bannerError}</Banner>}
|
||||
|
||||
<FormVerifyCode
|
||||
{...{
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M29.2 8C29.2 6.65 29.15 5.15 29.15 3.45C29.15 2.75 28.65 2.15 27.95 2L16.4 0H15.9L4.34998 2C3.64998 2.15 3.09998 2.75 3.14998 3.45C3.14998 5.15 3.14998 6.65 3.09998 8C3.04998 10.4 3.04998 12.15 3.14998 13.2C3.79998 20.1 5.24998 23.3 7.74998 26.7C9.74998 29.4 12.65 31.25 15.9 31.95C16 31.95 16.1 32 16.2 32C16.3 32 16.4 32 16.5 31.95C19.75 31.25 22.65 29.4 24.65 26.7C27.15 23.3 28.6 20.15 29.2 13.2C29.25 12.1 29.25 10.4 29.2 8Z"
|
||||
fill="#7542E5"/>
|
||||
<path d="M15.9 0.05L4.34998 2.05C3.64998 2.15 3.14998 2.75 3.14998 3.45C3.14998 5.15 3.09998 6.65 3.09998 8C3.04998 10.4 3.04998 12.15 3.14998 13.2C3.79998 20.15 5.24998 23.3 7.69998 26.7C9.69998 29.4 12.6 31.25 15.85 31.95C15.95 31.95 16.05 32 16.15 32V0C16.05 0 16 0 15.9 0.05Z"
|
||||
fill="#7542E5"/>
|
||||
<path d="M15.95 2.2502L6.24996 3.9002C5.64996 4.0002 5.24996 4.5002 5.24996 5.1002C5.24996 6.5502 5.24996 7.8002 5.19996 8.9002C5.14996 10.9002 5.14996 12.4002 5.24996 13.2502C5.74996 19.0502 6.99996 21.7502 9.04996 24.6002C10.7 26.8502 13.15 28.4502 15.9 29.0002H16.15V2.2002C16.1 2.2002 16 2.2002 15.95 2.2502Z"
|
||||
fill="#7542E5"/>
|
||||
<path d="M27.1 8.9C27.1 7.8 27.05 6.5 27.05 5.1C27.05 4.5 26.65 4 26.05 3.9L16.35 2.25H16.15V29.05H16.4C19.15 28.45 21.6 26.9 23.25 24.6C25.35 21.75 26.55 19.1 27.1 13.25C27.15 12.4 27.15 10.95 27.1 8.9Z"
|
||||
fill="#0090ED"/>
|
||||
<path d="M29.2 8C29.2 6.65 29.15 5.15 29.15 3.45C29.15 2.75 28.65 2.15 27.95 2L16.4 0H15.9L4.34998 2C3.64998 2.15 3.09998 2.75 3.14998 3.45C3.14998 5.15 3.14998 6.65 3.09998 8C3.04998 10.4 3.04998 12.15 3.14998 13.2C3.79998 20.1 5.24998 23.3 7.74998 26.7C9.74998 29.4 12.65 31.25 15.9 31.95C16 31.95 16.1 32 16.2 32C16.3 32 16.4 32 16.5 31.95C19.75 31.25 22.65 29.4 24.65 26.7C27.15 23.3 28.6 20.15 29.2 13.2C29.25 12.1 29.25 10.4 29.2 8Z"
|
||||
fill="#7542E5"/>
|
||||
<path d="M15.9 0.05L4.34998 2.05C3.64998 2.15 3.14998 2.75 3.14998 3.45C3.14998 5.15 3.09998 6.65 3.09998 8C3.04998 10.4 3.04998 12.15 3.14998 13.2C3.79998 20.15 5.24998 23.3 7.69998 26.7C9.69998 29.4 12.6 31.25 15.85 31.95C15.95 31.95 16.05 32 16.15 32V0C16.05 0 16 0 15.9 0.05Z"
|
||||
fill="#7542E5"/>
|
||||
<path d="M15.95 2.2502L6.24996 3.9002C5.64996 4.0002 5.24996 4.5002 5.24996 5.1002C5.24996 6.5502 5.24996 7.8002 5.19996 8.9002C5.14996 10.9002 5.14996 12.4002 5.24996 13.2502C5.74996 19.0502 6.99996 21.7502 9.04996 24.6002C10.7 26.8502 13.15 28.4502 15.9 29.0002H16.15V2.2002C16.1 2.2002 16 2.2002 15.95 2.2502Z"
|
||||
fill="#7542E5"/>
|
||||
<path d="M27.1 8.9C27.1 7.8 27.05 6.5 27.05 5.1C27.05 4.5 26.65 4 26.05 3.9L16.35 2.25H16.15V29.05H16.4C19.15 28.45 21.6 26.9 23.25 24.6C25.35 21.75 26.55 19.1 27.1 13.25C27.15 12.4 27.15 10.95 27.1 8.9Z"
|
||||
fill="#0090ED"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 2.8 KiB |
Загрузка…
Ссылка в новой задаче