update sign-in messages (#272)
This commit is contained in:
committed by
Waheed Ahmed
parent
9a621327e7
commit
7d179e4356
@@ -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 }
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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: {
|
||||
|
||||
Reference in New Issue
Block a user