Skip to content

Instantly share code, notes, and snippets.

@andrewhodel
Last active June 16, 2023 21:10
Show Gist options
  • Save andrewhodel/28e2cf1474d7d007ec65c270b538782c to your computer and use it in GitHub Desktop.
Save andrewhodel/28e2cf1474d7d007ec65c270b538782c to your computer and use it in GitHub Desktop.
world email and domain validation in javascript
var email_validate = function(s) {
if (typeof(s) !== 'string') {
return false;
}
var parts = s.split('@');
if (parts.length !== 2) {
// should be [email protected]
return false;
}
var local_part = parts[0];
if (local_part.length > 64) {
// local_part is too long
return false;
}
if (local_part[0] === '.' || local_part[local_part.length - 1] === '.') {
// . must not be the first or last character
return false;
}
var lp_m = local_part.match(/[\p{L}\p{N}\.!#\$%&'\\\*\+-/=\?\^_`\{\|\}~]/gu);
if (lp_m === null) {
// all invalid characters
return false;
} else if (lp_m.length !== local_part.length) {
// invalid character in local part
return false;
}
if (domain_validate(parts[1]) === false) {
// domain failed validation
return false;
}
return true;
}
var domain_validate = function(s) {
if (typeof(s) !== 'string') {
return false;
}
/*
The labels must follow the rules for ARPANET host names. They must
start with a letter, end with a letter or digit, and have as interior
characters only letters, digits, and hyphen. There are also some
restrictions on the length. Labels must be 63 characters or less.
*/
if (s.indexOf('..') !== -1) {
// a domain should never have two sequential dots because only one dot is used between subdomains
return false;
}
if (s.length > 255) {
// domain part is too long
return false;
}
var domain_parts = s.split('.');
if (domain_parts.length < 2) {
// must be at least 2 parts, domain.tld
// can include subdomains
return false
}
var tld = domain_parts[domain_parts.length - 1];
if (tld.length < 2 || tld.length > 63) {
// tld must be 2-63 characters long
return false;
}
var tld_m = tld.match(/[\p{L}]/gu);
if (tld_m === null) {
// all invalid
return false;
} else if (tld_m.length !== tld.length) {
// tld must be letters only
return false;
}
// domains contain letters, digits hyphens and dots
var domains = domain_parts.slice(0, domain_parts.length-1);
var c = 0;
while (c < domains.length) {
var domain_m = domains[c].match(/[\p{L}\p{N}-]/gu);
if (domain_m === null) {
// all invalid characters in domain part
return false;
} else if (domain_m.length !== domains[c].length) {
// invalid characters in domain part
return false;
} else if (domains[c][0] === '-' || domains[c][domains[c].length - 1] === '-') {
// - must not be the first or last character
return false;
} else if (domains[c].length > 63) {
// must be 63 characters or less
return false;
}
c++;
}
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment