Merge pull request #17721 from mozilla/fxa-9546

feat(totp): Update TOTP signin screens
This commit is contained in:
Vijay Budhram 2024-10-01 10:17:25 -04:00 коммит произвёл GitHub
Родитель c2a8d5d413 7032326f7e
Коммит 02c1fca083
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
7 изменённых файлов: 62 добавлений и 47 удалений

Просмотреть файл

@ -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