Created
October 26, 2016 10:12
-
-
Save antonpirker/56a9aaca2321d8fec78886ad186e742f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<script> | |
// Based on RFC 2822 section 3.2.4 / RFC 5322 section 3.2.3, these | |
// characters are permitted in email addresses (not taking into | |
// account internationalization): | |
var ATEXT = "a-zA-Z0-9_!#\\$%&\\'\\*\\+\\-\/=\\?\\^`\\{\\|\\}~"; | |
// A "dot atom text", per RFC 2822 3.2.4: | |
var DOT_ATOM_TEXT = '[' + ATEXT + ']+(?:\\.[' + ATEXT + ']+)*'; | |
// RFC 6531 section 3.3 extends the allowed characters in internationalized | |
// addresses to also include three specific ranges of UTF8 defined in | |
// RFC3629 section 4, which appear to be the Unicode code points from | |
// U+0080 to U+10FFFF. | |
var ATEXT_UTF8 = ATEXT + '\u{0080}-\u{0010FFFF}'; | |
var DOT_ATOM_TEXT_UTF8 = '[' + ATEXT_UTF8 + ']+(?:\\.[' + ATEXT_UTF8 + ']+)*'; | |
// The domain part of the email address, after IDNA (ASCII) encoding, | |
// must also satisfy the requirements of RFC 952/RFC 1123 which restrict | |
// the allowed characters of hostnames further. The hyphen cannot be at | |
// the beginning or end of a *dot-atom component* of a hostname either. | |
var ATEXT_HOSTNAME = '(?:(?:[a-zA-Z0-9][a-zA-Z0-9\\-]*)?[a-zA-Z0-9])'; | |
function validateEmailLocalPart(localPart) { | |
if(!localPart || localPart.length == 0) { | |
throw 'There must be something before the @-sign.'; | |
} | |
// RFC 5321 4.5.3.1.1 | |
if(localPart.length > 64) { | |
throw 'The email address is too long before the @-sign.'; | |
} | |
// Check the local part against the regular expression for the older ASCII requirements. | |
var re = new RegExp('^' + DOT_ATOM_TEXT + '$'); | |
var found = null; | |
found = localPart.match(re); | |
if(!found) { | |
var re = new RegExp('^' + DOT_ATOM_TEXT_UTF8 + '$'); | |
var found1 = null; | |
found1 = localPart.match(re); | |
if(!found1) { | |
var badChars = ''; | |
var re1 = new RegExp('^['+ATEXT_UTF8+']'); | |
for(var i=0; i<localPart.length; i++) { | |
var c = localPart[i]; | |
var found2 = null; | |
found2 = c.match(re1); | |
if(!found2) { | |
badChars += c; | |
} | |
} | |
throw 'The email address contains invalid characters before the @-sign: "' + badChars + '"'; | |
} | |
} | |
return localPart; | |
} | |
function validateEmailDomainPart(domainPart) { | |
if(!domainPart || domainPart.length == 0) { | |
throw 'There must be something after the @-sign.'; | |
} | |
if(domainPart.endsWith('.')) { | |
throw 'An email address cannot end with a period.'; | |
} | |
if(domainPart.startsWith('.')) { | |
throw 'An email address cannot have a period immediately after the @-sign.'; | |
} | |
if(domainPart.indexOf('..') != -1) { | |
throw 'An email address cannot have two periods in a row.'; | |
} | |
if(domainPart.length > 255) { | |
throw 'The email address is too long after the @-sign.'; | |
} | |
// A "dot atom text", per RFC 2822 3.2.4, but using the restricted | |
// characters allowed in a hostname (see ATEXT_HOSTNAME above). | |
DOT_ATOM_TEXT_2 = ATEXT_HOSTNAME + '(?:\.' + ATEXT_HOSTNAME + ')*' | |
// Check the regular expression. This is probably entirely redundant | |
// with idna.decode, which also checks this format. | |
var re = new RegExp('^' + DOT_ATOM_TEXT_2 + '$'); | |
var found = domainPart.match(re); | |
if(!found) { | |
throw 'The email address contains invalid characters after the @-sign.'; | |
} | |
// All publicly deliverable addresses have domain named with at least | |
// one period. We also know that all TLDs end with a letter. | |
if(domainPart.indexOf('.') == -1) { | |
throw 'The domain name ' + domainPart + ' is not valid. It should have a period.'; | |
} | |
var re = new RegExp('[A-Za-z]$'); | |
var found = domainPart.search(re); | |
if(!found) { | |
throw 'The domain name ' + domainPart + ' is not valid. It is not within a valid top-level domain.'; | |
} | |
return domainPart; | |
} | |
function isValidEmail(email) { | |
if(!email) { | |
return false; | |
} | |
var isValid = true; | |
var error = ''; | |
var parts = email.split('@'); | |
if(parts.length != 2) { | |
isValid = false; | |
error = 'The email address is not valid. It must have exactly one @-sign.'; | |
return isValid; | |
} | |
var ret = []; | |
ret['local'] = validateEmailLocalPart(parts[0]); | |
ret['domain'] = validateEmailDomainPart(parts[1]); | |
return isValid; | |
} | |
function testEmails() { | |
var emails = [ | |
'anton pirker@bla.com', | |
'nijole.s@hotmail.de', | |
'anton@ignaz.at', | |
'ööö@bbb.com', | |
'bbb@ööö.com', | |
'anton pirker@bla.com', | |
'anton@@anton.com', | |
'bla.@bla.com', | |
'adsf', | |
'.@.', | |
'.@.com', | |
'bla@.com', | |
'..@bla.com', | |
'bla@bla..com', | |
'', | |
' ', | |
'_!#$%&\'*+-/=?^`{|}~@bla.com', | |
'@bla.com', | |
] | |
for(var i=0; i<emails.length; i++) { | |
console.log('"' + emails[i] + '"'); | |
var res = ''; | |
try { | |
res = isValidEmail(emails[i]); | |
if(res) { | |
res = '[true]'; | |
} | |
} catch(ex) { | |
res = '[false] ' + ex; | |
} | |
console.log('---> ', res); | |
} | |
} | |
testEmails(); | |
</script> | |
</head> | |
<body> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment