update sign-in messages (#272)

This commit is contained in:
Uzair Rasheed
2021-05-11 20:03:57 +05:00
committed by Waheed Ahmed
parent 9a621327e7
commit 7d179e4356
3 changed files with 125 additions and 51 deletions

View File

@@ -23,6 +23,13 @@ const LoginFailureMessage = (props) => {
const { context, errorCode, value } = props.loginError;
let errorList;
let link;
const resetLink = (
<>
<Alert.Link href="/reset">
{intl.formatMessage(messages['login.incorrect.credentials.error.reset.link.text'])}
</Alert.Link>
</>
);
switch (errorCode) {
case NON_COMPLIANT_PASSWORD_EXCEPTION: {
@@ -87,60 +94,52 @@ const LoginFailureMessage = (props) => {
);
break;
case FAILED_LOGIN_ATTEMPT: {
const resetLink = (
<Alert.Link href="/reset">
{intl.formatMessage(messages['login.failed.link.text'])}
</Alert.Link>
);
errorList = (
<>
<li key={FAILED_LOGIN_ATTEMPT + 1}>
{intl.formatMessage(messages['login.incorrect.credentials.error'])}
</li>
<li key={FAILED_LOGIN_ATTEMPT + 2}>
{intl.formatMessage(messages['login.failed.attempt.error'], { remainingAttempts: context.remainingAttempts })}
</li>
<li key={FAILED_LOGIN_ATTEMPT + 3}>
<FormattedMessage
id="login.reset.password.message.with.link"
defaultMessage="If you've forgotten your password, click {resetLink} to reset."
description="Password reset user message with link"
values={{ resetLink }}
/>
</li>
</>
<FormattedMessage
id="login.incorrect.credentials.error.attempts.text"
description="Error message for incorrect email or password including attempts"
defaultMessage="The username, email or password you entered is incorrect. Please try again or {resetLink}{lineBreak}
{lineBreak}Attempts remaining:{remainingAttempts}
{lineBreak}{warning}After {allowedFailureAttempts} unsuccessful login attempts, your account will be locked."
values={{
lineBreak: <br />,
remainingAttempts: <strong> {context.remainingAttempts}</strong>,
warning: <strong>Warning: </strong>,
allowedFailureAttempts: <strong>{context.allowedFailureAttempts} consecutive</strong>,
resetLink,
}}
/>
);
break;
}
case ACCOUNT_LOCKED_OUT: {
const resetLink = (
<Alert.Link href="/reset">
{intl.formatMessage(messages['login.failed.link.text'])}
</Alert.Link>
);
errorList = (
<>
<li key={ACCOUNT_LOCKED_OUT + 1}>
{intl.formatMessage(messages['login.locked.out.error.message'], { lockedOutPeriod: context.lockedOutPeriod })}
</li>
<li key={FAILED_LOGIN_ATTEMPT + 2}>
<FormattedMessage
id="login.locked.reset.password.message.with.link"
defaultMessage="To be on the safe side, you can reset your password {resetLink} before you try again."
description="Password reset user message with link"
values={{ resetLink }}
/>
</li>
</>
<FormattedMessage
id="login.locked.out.error.message"
description="Account locked out user message"
defaultMessage="The username, email or password you entered is incorrect. Please try again or {resetLink}{lineBreak}
{lineBreak} {blockText}"
values={{
lineBreak: <br />,
resetLink,
blockText: <p className="text-danger"> Your account {props.loginError.email} is blocked for 30 minutes due to reaching the maximum {context.allowedFailureAttempts} failed login attempts.</p>,
}}
/>
);
break;
}
case INCORRECT_EMAIL_PASSWORD:
errorList = (
<li key={INCORRECT_EMAIL_PASSWORD}>
{intl.formatMessage(messages['login.incorrect.credentials.error'])}
</li>
);
if (context.failureCount <= 1) {
errorList = intl.formatMessage(messages['login.incorrect.credentials.error']);
} else if (context.failureCount === 2) {
errorList = (
<FormattedMessage
id="login.incorrect.credentials.error.with.reset.link"
defaultMessage="The username, email or password you entered is incorrect. Please try again or {resetLink}."
values={{ resetLink }}
/>
);
}
break;
default:
// TODO: use errorCode instead of processing error messages on frontend
@@ -167,7 +166,7 @@ const LoginFailureMessage = (props) => {
}
return (
<Alert id="login-failure-alert" variant="danger">
<Alert id="login-failure-alert" className="mb-5" variant="danger">
<Icon src={Info} className="alert-icon" />
<Alert.Heading>{intl.formatMessage(messages['login.failure.header.title'])}</Alert.Heading>
{ errorList }

View File

@@ -178,16 +178,16 @@ const messages = defineMessages({
defaultMessage: 'contact {platformName} support',
description: 'Link text used in inactive user error message to go to learner help center',
},
'login.failed.link.text': {
id: 'login.failed.link.text',
defaultMessage: 'here',
description: 'Link text used in failed login attempt user error message to reset password',
},
'login.incorrect.credentials.error': {
id: 'login.incorrect.credentials.error',
defaultMessage: 'Email or password is incorrect.',
defaultMessage: 'The username, email or password you entered is incorrect. Please try again.',
description: 'Error message for incorrect email or password',
},
'login.incorrect.credentials.error.with.reset.link': {
id: 'login.incorrect.credentials.error.with.reset.link',
defaultMessage: 'The username, email or password you entered is incorrect. Please try again or {resetLink}.',
description: 'Error message for incorrect email or password with reset link',
},
'login.failed.attempt.error': {
id: 'login.failed.attempt.error',
defaultMessage: 'You have {remainingAttempts} more sign in attempts before your account is temporarily locked.',
@@ -203,6 +203,11 @@ const messages = defineMessages({
defaultMessage: 'Please fill in the fields below.',
description: 'Login form empty input user message',
},
'login.incorrect.credentials.error.reset.link.text': {
id: 'login.incorrect.credentials.error.reset.link.text',
defaultMessage: 'reset your password',
description: 'Reset password link text for incorrect email or password credentials',
},
});
export default messages;

View File

@@ -10,6 +10,8 @@ import {
INTERNAL_SERVER_ERROR,
INVALID_FORM,
NON_COMPLIANT_PASSWORD_EXCEPTION,
FAILED_LOGIN_ATTEMPT,
INCORRECT_EMAIL_PASSWORD,
} from '../data/constants';
const IntlLoginFailureMessage = injectIntl(LoginFailureMessage);
@@ -64,6 +66,74 @@ describe('LoginFailureMessage', () => {
expect(loginFailureMessage.find('#login-failure-alert').find('a').props().href).toEqual('https://support.edx.org/');
});
it('test match failed login attempt error', () => {
props = {
loginError: {
email: 'text@example.com',
errorCode: FAILED_LOGIN_ATTEMPT,
context: {
remainingAttempts: 3,
allowedFailureAttempts: 6,
resetLink: '/reset',
},
},
};
const loginFailureMessage = mount(
<IntlProvider locale="en">
<IntlLoginFailureMessage {...props} />
</IntlProvider>,
);
const expectedMessage = 'We couldn\'t sign you in.The username, email or password you entered is incorrect. Please try again or '
+ 'reset your password Attempts remaining: 3 Warning: After 6 consecutive unsuccessful login attempts, your account will be locked.';
expect(loginFailureMessage.find('#login-failure-alert').first().text()).toEqual(expectedMessage);
});
it('test match failed login error first attempt', () => {
props = {
loginError: {
email: 'text@example.com',
errorCode: INCORRECT_EMAIL_PASSWORD,
context: {
failureCount: 1,
resetLink: '/reset',
},
},
};
const loginFailureMessage = mount(
<IntlProvider locale="en">
<IntlLoginFailureMessage {...props} />
</IntlProvider>,
);
const expectedMessage = 'We couldn\'t sign you in.The username, email or password you entered is incorrect. Please try again.';
expect(loginFailureMessage.find('#login-failure-alert').first().text()).toEqual(expectedMessage);
});
it('test match failed login error second attempt', () => {
props = {
loginError: {
email: 'text@example.com',
errorCode: INCORRECT_EMAIL_PASSWORD,
context: {
failureCount: 2,
resetLink: '/reset',
},
},
};
const loginFailureMessage = mount(
<IntlProvider locale="en">
<IntlLoginFailureMessage {...props} />
</IntlProvider>,
);
const expectedMessage = 'We couldn\'t sign you in.The username, email or password you entered is incorrect. Please try again or reset your password.';
expect(loginFailureMessage.find('#login-failure-alert').first().text()).toEqual(expectedMessage);
});
it('should match rate limit error message', () => {
props = {
loginError: {