VAN-598: update email warnings and errors (#376)

This commit is contained in:
Zainab Amir
2021-07-08 14:22:21 +05:00
committed by Waheed Ahmed
parent 6a65241bf4
commit 6dd39c562a
3 changed files with 51 additions and 22 deletions

View File

@@ -20,7 +20,7 @@ import {
clearUsernameSuggestions, registerNewUser, resetRegistrationForm, fetchRealtimeValidations,
} from './data/actions';
import {
FORM_SUBMISSION_ERROR, DEFAULT_SERVICE_PROVIDER_DOMAINS, DEFAULT_TOP_LEVEL_DOMAINS, COMMON_VALID_EMAIL_DOMAINS,
FORM_SUBMISSION_ERROR, DEFAULT_SERVICE_PROVIDER_DOMAINS, DEFAULT_TOP_LEVEL_DOMAINS, COMMON_EMAIL_PROVIDERS,
} from './data/constants';
import {
registrationErrorSelector, registrationRequestSelector, validationsSelector, usernameSuggestionsSelector,
@@ -44,7 +44,7 @@ import {
getTpaProvider, getTpaHint, getAllPossibleQueryParam, setSurveyCookie, setCookie,
} from '../data/utils';
import CountryDropdown from './CountryDropdown';
import getLevenshteinSuggestion from './utils';
import { getLevenshteinSuggestion, getSuggestionForInvalidEmail } from './utils';
class RegistrationPage extends React.Component {
constructor(props, context) {
@@ -302,36 +302,39 @@ class RegistrationPage extends React.Component {
} else if (value.length <= 2) {
errors.email = intl.formatMessage(messages['email.invalid.format.error']);
} else {
let borderClass = '';
let emailWarningSuggestion = null;
let emailErrorSuggestion = null;
const [username, domainName] = value.split('@');
const suggestion = getLevenshteinSuggestion(domainName, COMMON_VALID_EMAIL_DOMAINS);
// Check if email address is invalid. If we have a suggestion for invalid email provide that along with
// error message.
if (!emailRegex.test(value)) {
errors.email = intl.formatMessage(messages['email.invalid.format.error']);
emailErrorSuggestion = suggestion ? `${username}@${suggestion}` : null;
emailErrorSuggestion = getSuggestionForInvalidEmail(domainName, username);
} else {
let suggestion = null;
const hasMultipleSubdomains = value.match(/\./g).length > 1;
const [serviceLevelDomain, topLevelDomain] = domainName.split('.');
const tldSuggestion = getLevenshteinSuggestion(topLevelDomain, DEFAULT_TOP_LEVEL_DOMAINS, 2);
const tldSuggestion = !DEFAULT_TOP_LEVEL_DOMAINS.includes(topLevelDomain);
const serviceSuggestion = getLevenshteinSuggestion(serviceLevelDomain, DEFAULT_SERVICE_PROVIDER_DOMAINS, 2);
if (tldSuggestion) {
emailErrorSuggestion = suggestion ? `${username}@${suggestion}` : `${username}@${serviceSuggestion || serviceLevelDomain}.${tldSuggestion}`;
} else if (serviceSuggestion) {
borderClass = 'yellow-border';
emailWarningSuggestion = suggestion ? `${username}@${suggestion}` : `${username}@${serviceSuggestion}.${topLevelDomain}`;
} else if (suggestion) {
// If both TLD and service level domain are correct and we have a suggestion from common email domains,
// give preference to that choice.
borderClass = 'yellow-border';
emailWarningSuggestion = `${username}@${suggestion}`;
if (DEFAULT_SERVICE_PROVIDER_DOMAINS.includes(serviceSuggestion || serviceLevelDomain)) {
suggestion = `${username}@${serviceSuggestion || serviceLevelDomain}.com`;
}
if (tldSuggestion) {
if (!hasMultipleSubdomains && tldSuggestion) {
emailErrorSuggestion = suggestion;
} else if (serviceSuggestion) {
emailWarningSuggestion = suggestion;
} else {
suggestion = getLevenshteinSuggestion(domainName, COMMON_EMAIL_PROVIDERS, 3);
if (suggestion) {
emailWarningSuggestion = `${username}@${suggestion}`;
}
}
if (!hasMultipleSubdomains && tldSuggestion) {
errors.email = intl.formatMessage(messages['email.invalid.format.error']);
} else if (payload && statusCode !== 403) {
this.props.fetchRealtimeValidations(payload);
@@ -339,7 +342,11 @@ class RegistrationPage extends React.Component {
errors.email = '';
}
}
this.setState({ emailWarningSuggestion, emailErrorSuggestion, borderClass });
this.setState({
emailWarningSuggestion,
emailErrorSuggestion,
borderClass: emailWarningSuggestion ? 'yellow-border' : null,
});
}
break;
case 'name':

View File

@@ -34,11 +34,11 @@ export const GENDER_OPTIONS = ['', 'f', 'm', 'o'];
// Other constants
export const FORM_FIELDS = ['name', 'email', 'password', 'username', 'country'];
export const COMMON_VALID_EMAIL_DOMAINS = [
'edx.org', 'hotmail.com', 'yahoo.com', 'outlook.com', 'live.com', 'gmail.com',
export const COMMON_EMAIL_PROVIDERS = [
'hotmail.com', 'yahoo.com', 'outlook.com', 'live.com', 'gmail.com', 'aol.com',
];
export const DEFAULT_SERVICE_PROVIDER_DOMAINS = ['yahoo', 'hotmail', 'live', 'outlook', 'gmail', 'edx'];
export const DEFAULT_SERVICE_PROVIDER_DOMAINS = ['yahoo', 'aol', 'hotmail', 'live', 'outlook', 'gmail'];
export const DEFAULT_TOP_LEVEL_DOMAINS = [
'aaa', 'aarp', 'abarth', 'abb', 'abbott', 'abbvie', 'abc', 'able', 'abogado', 'abudhabi', 'ac', 'academy',

View File

@@ -1,6 +1,7 @@
import { distance } from 'fastest-levenshtein';
import { COMMON_EMAIL_PROVIDERS } from './data/constants';
export default function getLevenshteinSuggestion(word, knownWords, similarityThreshold = 4) {
export function getLevenshteinSuggestion(word, knownWords, similarityThreshold = 4) {
if (!word) {
return null;
}
@@ -18,3 +19,24 @@ export default function getLevenshteinSuggestion(word, knownWords, similarityThr
return minEditDistance <= similarityThreshold && word !== mostSimilar ? mostSimilar : null;
}
export function getSuggestionForInvalidEmail(domain, username) {
if (!domain) {
return null;
}
const defaultDomains = ['yahoo', 'aol', 'hotmail', 'live', 'outlook', 'gmail'];
const suggestion = getLevenshteinSuggestion(domain, COMMON_EMAIL_PROVIDERS);
if (suggestion) {
return `${username}@${suggestion}`;
}
for (let i = 0; i < defaultDomains.length; i++) {
if (domain.includes(defaultDomains[i])) {
return `${username}@${defaultDomains[i]}.com`;
}
}
return null;
}