add mailto info link
This commit is contained in:
@@ -514,7 +514,7 @@ select.form-control {
|
||||
}
|
||||
|
||||
.one-rem-font {
|
||||
font-size: 1rem;
|
||||
font-size: 0.99rem;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
|
||||
@@ -143,10 +143,8 @@ const ForgotPasswordPage = (props) => {
|
||||
<Hyperlink id="forgot-password" className="btn btn-link font-weight-500 text-body" destination={getConfig().LOGIN_ISSUE_SUPPORT_LINK}>
|
||||
{intl.formatMessage(messages['need.help.sign.in.text'])}
|
||||
</Hyperlink>
|
||||
<p className="mt-5">{intl.formatMessage(
|
||||
messages['additional.help.text'],
|
||||
{ infoEmail: process.env.INFO_EMAIL },
|
||||
)}
|
||||
<p className="mt-5 one-rem-font">{intl.formatMessage(messages['additional.help.text'])}
|
||||
<span><Hyperlink destination={`mailto:${getConfig().INFO_EMAIL}`}>{getConfig().INFO_EMAIL}</Hyperlink></span>
|
||||
</p>
|
||||
</Form>
|
||||
</div>
|
||||
|
||||
@@ -86,7 +86,7 @@ const messages = defineMessages({
|
||||
},
|
||||
'additional.help.text': {
|
||||
id: 'additional.help.text',
|
||||
defaultMessage: 'For additional help, contact edX support at {infoEmail}',
|
||||
defaultMessage: 'For additional help, contact edX support at ',
|
||||
description: 'additional help text on forgot password page',
|
||||
},
|
||||
'sign.in.text': {
|
||||
|
||||
@@ -23,7 +23,7 @@ const LoginFailureMessage = (props) => {
|
||||
const { context, errorCode, value } = props.loginError;
|
||||
let errorList;
|
||||
let link;
|
||||
const resetLink = (
|
||||
let resetLink = (
|
||||
<>
|
||||
<Alert.Link href="/reset">
|
||||
{intl.formatMessage(messages['login.incorrect.credentials.error.reset.link.text'])}
|
||||
@@ -94,18 +94,23 @@ const LoginFailureMessage = (props) => {
|
||||
);
|
||||
break;
|
||||
case FAILED_LOGIN_ATTEMPT: {
|
||||
resetLink = (
|
||||
<>
|
||||
<Alert.Link href="/reset">
|
||||
{intl.formatMessage(messages['login.incorrect.credentials.error.before.account.blocked.text'])}
|
||||
</Alert.Link>
|
||||
</>
|
||||
);
|
||||
errorList = (
|
||||
<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."
|
||||
defaultMessage="The username, email or password you entered is incorrect. You have {remainingAttempts} more sign in
|
||||
attempts before your account is temporarily locked.{lineBreak}
|
||||
{lineBreak}If you've forgotten your password, {resetLink}"
|
||||
values={{
|
||||
lineBreak: <br />,
|
||||
remainingAttempts: <strong> {context.remainingAttempts}</strong>,
|
||||
warning: <strong>Warning: </strong>,
|
||||
allowedFailureAttempts: <strong>{context.allowedFailureAttempts} consecutive</strong>,
|
||||
remainingAttempts: context.remainingAttempts,
|
||||
resetLink,
|
||||
}}
|
||||
/>
|
||||
@@ -117,12 +122,11 @@ const LoginFailureMessage = (props) => {
|
||||
<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}"
|
||||
defaultMessage="To protect your account, its been temporarily locked. Try again in 30 minutes. {lineBreak}
|
||||
{lineBreak} To be on the safe side, you can {resetLink} before try again."
|
||||
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>,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@@ -169,7 +173,7 @@ const LoginFailureMessage = (props) => {
|
||||
<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 }
|
||||
<span className="one-rem-font">{ errorList }</span>
|
||||
</Alert>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -31,7 +31,7 @@ import { getThirdPartyAuthContext } from '../common-components/data/actions';
|
||||
import { thirdPartyAuthContextSelector } from '../common-components/data/selectors';
|
||||
import EnterpriseSSO from '../common-components/EnterpriseSSO';
|
||||
import {
|
||||
DEFAULT_STATE, ENTERPRISE_LOGIN_URL, PENDING_STATE, RESET_PAGE, VALID_EMAIL_REGEX,
|
||||
DEFAULT_STATE, ENTERPRISE_LOGIN_URL, PENDING_STATE, RESET_PAGE,
|
||||
} from '../data/constants';
|
||||
import {
|
||||
getTpaHint,
|
||||
@@ -91,21 +91,18 @@ class LoginPage extends React.Component {
|
||||
}
|
||||
|
||||
const payload = {
|
||||
email: emailOrUsername, password, ...this.queryParams,
|
||||
email_or_username: emailOrUsername, password, ...this.queryParams,
|
||||
};
|
||||
this.props.loginRequest(payload);
|
||||
}
|
||||
|
||||
validateEmail(email) {
|
||||
const { errors } = this.state;
|
||||
const regex = new RegExp(VALID_EMAIL_REGEX, 'i');
|
||||
|
||||
if (email === '') {
|
||||
errors.emailOrUsername = this.props.intl.formatMessage(messages['email.validation.message']);
|
||||
} else if (email.length < 3) {
|
||||
errors.emailOrUsername = this.props.intl.formatMessage(messages['email.format.validation.less.chars.message']);
|
||||
} else if (!regex.test(email)) {
|
||||
errors.emailOrUsername = this.props.intl.formatMessage(messages['email.format.validation.message']);
|
||||
} else {
|
||||
errors.emailOrUsername = '';
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ export async function loginRequest(creds) {
|
||||
|
||||
const { data } = await getAuthenticatedHttpClient()
|
||||
.post(
|
||||
`${getConfig().LMS_BASE_URL}/user_api/v1/account/login_session/`,
|
||||
`${getConfig().LMS_BASE_URL}/api/user/v2/account/login_session/`,
|
||||
querystring.stringify(creds),
|
||||
requestConfig,
|
||||
)
|
||||
|
||||
@@ -208,6 +208,11 @@ const messages = defineMessages({
|
||||
defaultMessage: 'reset your password',
|
||||
description: 'Reset password link text for incorrect email or password credentials',
|
||||
},
|
||||
'login.incorrect.credentials.error.before.account.blocked.text': {
|
||||
id: 'login.incorrect.credentials.error.before.account.blocked.text',
|
||||
defaultMessage: 'click here to reset it.',
|
||||
description: 'Reset password link text for incorrect email or password credentials before blocking account',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
|
||||
@@ -84,8 +84,8 @@ describe('LoginFailureMessage', () => {
|
||||
<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.';
|
||||
const expectedMessage = 'We couldn\'t sign you in.The username, email or password you entered is incorrect. '
|
||||
+ 'You have 3 more sign in attempts before your account is temporarily locked. If you\'ve forgotten your password, click here to reset it.';
|
||||
|
||||
expect(loginFailureMessage.find('#login-failure-alert').first().text()).toEqual(expectedMessage);
|
||||
});
|
||||
|
||||
@@ -91,7 +91,7 @@ describe('LoginPage', () => {
|
||||
loginPage.find('input#password').simulate('change', { target: { value: 'password' } });
|
||||
loginPage.find('button.btn-brand').simulate('click');
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(loginRequest({ email: 'test@example.com', password: 'password' }));
|
||||
expect(store.dispatch).toHaveBeenCalledWith(loginRequest({ email_or_username: 'test@example.com', password: 'password' }));
|
||||
});
|
||||
|
||||
it('should not dispatch loginRequest on empty form submission', () => {
|
||||
@@ -129,19 +129,6 @@ describe('LoginPage', () => {
|
||||
expect(loginPage.state('errors')).toEqual(errorState);
|
||||
});
|
||||
|
||||
it('should match the state for invalid email format on form submission', () => {
|
||||
const errorState = { emailOrUsername: 'The email address you\'ve provided isn\'t formatted correctly.', password: '' };
|
||||
store.dispatch = jest.fn(store.dispatch);
|
||||
|
||||
const loginPage = (mount(reduxWrapper(<IntlLoginPage {...props} />))).find('LoginPage');
|
||||
|
||||
loginPage.find('input#password').simulate('change', { target: { value: 'test', name: 'password' } });
|
||||
loginPage.find('input#email').simulate('change', { target: { value: 'test@', name: 'email' } });
|
||||
loginPage.find('button.btn-brand').simulate('click');
|
||||
|
||||
expect(loginPage.state('errors')).toEqual(errorState);
|
||||
});
|
||||
|
||||
// ******** test form buttons and links ********
|
||||
|
||||
it('should match default button state', () => {
|
||||
|
||||
@@ -252,6 +252,7 @@ class RegistrationPage extends React.Component {
|
||||
} else if (value.length <= 2 || !emailRegex.test(value)) {
|
||||
errors.email = intl.formatMessage(messages['email.invalid.format.error']);
|
||||
} else if (emailRegex.test(value)) {
|
||||
errors.email = '';
|
||||
let emailLexemes = value.split('@');
|
||||
let domainLexemes = emailLexemes[1].split('.');
|
||||
const serviceProvider = domainLexemes[0];
|
||||
|
||||
Reference in New Issue
Block a user