775ac7b58c
you must login with an BTP account in order to see the app
180 lines
No EOL
5.5 KiB
JavaScript
180 lines
No EOL
5.5 KiB
JavaScript
import assertString from './util/assertString';
|
|
import merge from './util/merge';
|
|
import isByteLength from './isByteLength';
|
|
import isFQDN from './isFQDN';
|
|
import isIP from './isIP';
|
|
var default_email_options = {
|
|
allow_display_name: false,
|
|
require_display_name: false,
|
|
allow_utf8_local_part: true,
|
|
require_tld: true,
|
|
blacklisted_chars: '',
|
|
ignore_max_length: false,
|
|
host_blacklist: []
|
|
};
|
|
/* eslint-disable max-len */
|
|
|
|
/* eslint-disable no-control-regex */
|
|
|
|
var splitNameAddress = /^([^\x00-\x1F\x7F-\x9F\cX]+)</i;
|
|
var emailUserPart = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~]+$/i;
|
|
var gmailUserPart = /^[a-z\d]+$/;
|
|
var quotedEmailUser = /^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f]))*$/i;
|
|
var emailUserUtf8Part = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+$/i;
|
|
var quotedEmailUserUtf8 = /^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))*$/i;
|
|
var defaultMaxEmailLength = 254;
|
|
/* eslint-enable max-len */
|
|
|
|
/* eslint-enable no-control-regex */
|
|
|
|
/**
|
|
* Validate display name according to the RFC2822: https://tools.ietf.org/html/rfc2822#appendix-A.1.2
|
|
* @param {String} display_name
|
|
*/
|
|
|
|
function validateDisplayName(display_name) {
|
|
var display_name_without_quotes = display_name.replace(/^"(.+)"$/, '$1'); // display name with only spaces is not valid
|
|
|
|
if (!display_name_without_quotes.trim()) {
|
|
return false;
|
|
} // check whether display name contains illegal character
|
|
|
|
|
|
var contains_illegal = /[\.";<>]/.test(display_name_without_quotes);
|
|
|
|
if (contains_illegal) {
|
|
// if contains illegal characters,
|
|
// must to be enclosed in double-quotes, otherwise it's not a valid display name
|
|
if (display_name_without_quotes === display_name) {
|
|
return false;
|
|
} // the quotes in display name must start with character symbol \
|
|
|
|
|
|
var all_start_with_back_slash = display_name_without_quotes.split('"').length === display_name_without_quotes.split('\\"').length;
|
|
|
|
if (!all_start_with_back_slash) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
export default function isEmail(str, options) {
|
|
assertString(str);
|
|
options = merge(options, default_email_options);
|
|
|
|
if (options.require_display_name || options.allow_display_name) {
|
|
var display_email = str.match(splitNameAddress);
|
|
|
|
if (display_email) {
|
|
var display_name = display_email[1]; // Remove display name and angle brackets to get email address
|
|
// Can be done in the regex but will introduce a ReDOS (See #1597 for more info)
|
|
|
|
str = str.replace(display_name, '').replace(/(^<|>$)/g, ''); // sometimes need to trim the last space to get the display name
|
|
// because there may be a space between display name and email address
|
|
// eg. myname <address@gmail.com>
|
|
// the display name is `myname` instead of `myname `, so need to trim the last space
|
|
|
|
if (display_name.endsWith(' ')) {
|
|
display_name = display_name.substr(0, display_name.length - 1);
|
|
}
|
|
|
|
if (!validateDisplayName(display_name)) {
|
|
return false;
|
|
}
|
|
} else if (options.require_display_name) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (!options.ignore_max_length && str.length > defaultMaxEmailLength) {
|
|
return false;
|
|
}
|
|
|
|
var parts = str.split('@');
|
|
var domain = parts.pop();
|
|
var lower_domain = domain.toLowerCase();
|
|
|
|
if (options.host_blacklist.includes(lower_domain)) {
|
|
return false;
|
|
}
|
|
|
|
var user = parts.join('@');
|
|
|
|
if (options.domain_specific_validation && (lower_domain === 'gmail.com' || lower_domain === 'googlemail.com')) {
|
|
/*
|
|
Previously we removed dots for gmail addresses before validating.
|
|
This was removed because it allows `multiple..dots@gmail.com`
|
|
to be reported as valid, but it is not.
|
|
Gmail only normalizes single dots, removing them from here is pointless,
|
|
should be done in normalizeEmail
|
|
*/
|
|
user = user.toLowerCase(); // Removing sub-address from username before gmail validation
|
|
|
|
var username = user.split('+')[0]; // Dots are not included in gmail length restriction
|
|
|
|
if (!isByteLength(username.replace(/\./g, ''), {
|
|
min: 6,
|
|
max: 30
|
|
})) {
|
|
return false;
|
|
}
|
|
|
|
var _user_parts = username.split('.');
|
|
|
|
for (var i = 0; i < _user_parts.length; i++) {
|
|
if (!gmailUserPart.test(_user_parts[i])) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (options.ignore_max_length === false && (!isByteLength(user, {
|
|
max: 64
|
|
}) || !isByteLength(domain, {
|
|
max: 254
|
|
}))) {
|
|
return false;
|
|
}
|
|
|
|
if (!isFQDN(domain, {
|
|
require_tld: options.require_tld
|
|
})) {
|
|
if (!options.allow_ip_domain) {
|
|
return false;
|
|
}
|
|
|
|
if (!isIP(domain)) {
|
|
if (!domain.startsWith('[') || !domain.endsWith(']')) {
|
|
return false;
|
|
}
|
|
|
|
var noBracketdomain = domain.substr(1, domain.length - 2);
|
|
|
|
if (noBracketdomain.length === 0 || !isIP(noBracketdomain)) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (user[0] === '"') {
|
|
user = user.slice(1, user.length - 1);
|
|
return options.allow_utf8_local_part ? quotedEmailUserUtf8.test(user) : quotedEmailUser.test(user);
|
|
}
|
|
|
|
var pattern = options.allow_utf8_local_part ? emailUserUtf8Part : emailUserPart;
|
|
var user_parts = user.split('.');
|
|
|
|
for (var _i = 0; _i < user_parts.length; _i++) {
|
|
if (!pattern.test(user_parts[_i])) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (options.blacklisted_chars) {
|
|
if (user.search(new RegExp("[".concat(options.blacklisted_chars, "]+"), 'g')) !== -1) return false;
|
|
}
|
|
|
|
return true;
|
|
} |