UNPKG

email-validation

Version:

Email validation that follows the specs.

74 lines (69 loc) 4.26 kB
var util = require('util'); var email = module.exports = function() {}; var strToObj = function(str) { var obj = {}; for(var i = 0; i < str.length; i++) { obj[str[i]] = str.charCodeAt(i); } return obj; }; var chars = strToObj("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&'*+-/=?^_`{|}~."); var specialchars = strToObj("\\\"(),:;<>@[\] "); var escapers = strToObj('\\"'); var hostchars = strToObj("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-"); email.parse = function(address, dothrow, callback) { callback = (typeof callback == 'undefined' && typeof dothrow == 'function') ? dothrow : null; var userland = true; var quotation = false; var escaped = false; var _user = "", _domain = ""; var hostisip = false; var hoststartpos = 0; try { if(address.length >= 254) throw util.format("[Error parsing email address: address is longer than 253, actual]", address.length); for(var i = 0; i < address.length; i++) { //console.log(i, address[i]) if(userland) { if(address[i] == '"' && i == 0) { quotation = true; _user += address[i]; continue; } if(typeof chars[address[i]] != 'undefined') { //needed I'm sure. _user += address[i]; continue; } else if(typeof specialchars[address[i]] != 'undefined') { if(quotation) { if(!escaped && address[i] == "\\") { escaped = true; _user += address[i]; continue; } if(!escaped && address[i] == '"' && address[i+1] == "@") { userland = false; hoststartpos = i+2; _user += address[i]; i+=1; continue; } if(escaped && typeof escapers[address[i]] != 'undefined') { escaped = false; _user += address[i]; continue; } if(!escaped && typeof escapers[address[i]] != 'undefined') throw util.format("[Error parsing email address: invalid use of %s (pos: %s)]", address[i], i, address); } else if(address[i] == "@" && !quotation) { userland = false; hoststartpos = i+1; continue; } else { throw util.format("[Error parsing email address: special character '%s' (pos: %s) used without quotation marks]", address[i], i); } } else { throw util.format("[Error parsing email address: character '%s' (pos: %s) is not allowed in an email address user space.]", address[i], i, address); } _user += address[i]; } else { //parsing hostname. Probably could be done with regex. if(i == hoststartpos && address[i] == '[') { hostisip = true; hostchars['['] = '['; hostchars[']'] = ']'; hostchars[':'] = ':'; _domain += address[i]; continue; } if(typeof hostchars[address[i]] == 'undefined') throw util.format("[Error parsing email address: character '%s' (pos: %s) is not allowed in the hostname section]", address[i], i); if(i >= hoststartpos && /[@\.]/.test(address[i - 1]) && !/[a-z0-9]/i.test(address[i])) throw util.format("[Error parsing email address: All domain segments must start with a letter or number, never a symbol like '%s'.") _domain += address[i]; } } if(_domain === '') throw util.format("[Error parseing email address: no domain part]", address); if(hostisip && !require('net').isIP(address.substring(hoststartpos+1,address.length-1))) throw util.format("[Error parsing email address: invalid IP address]"); if(hostisip && address[address.length-1] != "]") throw util.format("[Error parsing email address: IP address notation must end with a ']']"); if(!hostisip && (/^.+@([a-z0-9]{64,}(|\.))/i).test(address)) throw util.format("[Error parsing email address: hostname has elements greater than 63 characters]"); if(userland) throw util.format("[Error parsing email address: quotation mark not closed]" , address); } catch (err) { if(callback) callback(err); if(typeof dothrow != 'undefined' && typeof dothrow != 'function') throw err; return false; //redundant? } if(callback) callback(null, {user: _user, domain: _domain}); else return {user: _user, domain: _domain}; } email.valid = function(address, dothrow, callback) { return !!email.parse(address, dothrow, callback); }