114 lines
3.3 KiB
JavaScript
114 lines
3.3 KiB
JavaScript
import { distance } from 'fastest-levenshtein';
|
|
|
|
import {
|
|
COMMON_EMAIL_PROVIDERS,
|
|
COUNTRY_CODE_KEY,
|
|
COUNTRY_DISPLAY_KEY,
|
|
DEFAULT_SERVICE_PROVIDER_DOMAINS,
|
|
DEFAULT_TOP_LEVEL_DOMAINS,
|
|
} from './constants';
|
|
|
|
function getLevenshteinSuggestion(word, knownWords, similarityThreshold = 4) {
|
|
if (!word) {
|
|
return null;
|
|
}
|
|
|
|
let minEditDistance = 100;
|
|
let mostSimilar = word;
|
|
|
|
for (let i = 0; i < knownWords.length; i++) {
|
|
const editDistance = distance(knownWords[i].toLowerCase(), word.toLowerCase());
|
|
if (editDistance < minEditDistance) {
|
|
minEditDistance = editDistance;
|
|
mostSimilar = knownWords[i];
|
|
}
|
|
}
|
|
|
|
return minEditDistance <= similarityThreshold && word !== mostSimilar ? mostSimilar : null;
|
|
}
|
|
|
|
export function getSuggestionForInvalidEmail(domain, username) {
|
|
if (!domain) {
|
|
return '';
|
|
}
|
|
|
|
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 '';
|
|
}
|
|
|
|
export function validateEmailAddress(value, username, domainName) {
|
|
let suggestion = null;
|
|
const validation = {
|
|
hasError: false,
|
|
suggestion: '',
|
|
type: '',
|
|
};
|
|
|
|
const hasMultipleSubdomains = value.match(/\./g).length > 1;
|
|
const [serviceLevelDomain, topLevelDomain] = domainName.split('.');
|
|
const tldSuggestion = !DEFAULT_TOP_LEVEL_DOMAINS.includes(topLevelDomain);
|
|
const serviceSuggestion = getLevenshteinSuggestion(serviceLevelDomain, DEFAULT_SERVICE_PROVIDER_DOMAINS, 2);
|
|
|
|
if (DEFAULT_SERVICE_PROVIDER_DOMAINS.includes(serviceSuggestion || serviceLevelDomain)) {
|
|
suggestion = `${username}@${serviceSuggestion || serviceLevelDomain}.com`;
|
|
}
|
|
|
|
if (!hasMultipleSubdomains && tldSuggestion) {
|
|
validation.suggestion = suggestion;
|
|
validation.type = 'error';
|
|
} else if (serviceSuggestion) {
|
|
validation.suggestion = suggestion;
|
|
validation.type = 'warning';
|
|
} else {
|
|
suggestion = getLevenshteinSuggestion(domainName, COMMON_EMAIL_PROVIDERS, 3);
|
|
if (suggestion) {
|
|
validation.suggestion = `${username}@${suggestion}`;
|
|
validation.type = 'warning';
|
|
}
|
|
}
|
|
|
|
if (!hasMultipleSubdomains && tldSuggestion) {
|
|
validation.hasError = true;
|
|
}
|
|
|
|
return validation;
|
|
}
|
|
|
|
export function validateCountryField(value, countryList, errorMessage) {
|
|
let countryCode = '';
|
|
let displayValue = value;
|
|
let error = errorMessage;
|
|
|
|
if (value) {
|
|
const normalizedValue = value.toLowerCase();
|
|
// Handling a case here where user enters a valid country code that needs to be
|
|
// evaluated and set its value as a valid value.
|
|
const selectedCountry = countryList.find(
|
|
(country) => (
|
|
// When translations apply extra space added in country value so we should
|
|
// trim that.
|
|
country[COUNTRY_DISPLAY_KEY].toLowerCase().trim() === normalizedValue
|
|
|| country[COUNTRY_CODE_KEY].toLowerCase().trim() === normalizedValue
|
|
),
|
|
);
|
|
if (selectedCountry) {
|
|
countryCode = selectedCountry[COUNTRY_CODE_KEY];
|
|
displayValue = selectedCountry[COUNTRY_DISPLAY_KEY];
|
|
error = '';
|
|
}
|
|
}
|
|
return { error, countryCode, displayValue };
|
|
}
|