Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

zb-email-verifier

Package Overview
Dependencies
Maintainers
1
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

zb-email-verifier - npm Package Compare versions

Comparing version 0.2.0 to 0.5.0

lib/netsend.js

222

index.js
'use strict';
const dns = require('dns');
const net = require('net');
const P = require('bluebird');
const _ = require('lodash');
const netsend = require('./lib/netsend');
class VerifyError extends Error {
constructor ( message, extra ) {
super()
Error.captureStackTrace( this, this.constructor )
this.name = 'CustomError'
this.message = message
if ( extra ) this.extra = extra;
}
}
P.config({cancellation: true});
const dnsResolveMx = P.promisify(dns.resolveMx, {context: dns});
const netConnect = (options => {
return new P((resolve, reject) => {
let fnNetEnd;
module.exports = {
verify(opts) {
const emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; // eslint-disable-line
const responseQueue = (() => {
let msgQueue = [];
let evtResolve = null;
return {
add(msg) {
if(evtResolve) {
evtResolve([msg]);
evtResolve = null;
} else {
msgQueue.push(msg);
}
},
flush() {
return new P((resolve, reject) => {
if(msgQueue.length) {
const results = _.clone(msgQueue);
msgQueue = [];
return resolve(results);
}
evtResolve = resolve;
});
}
};
})();
if(!emailRegex.test(opts.to)) {
return P.resolve('INVALID');
}
const connOption = {
port: options.port,
host: options.host
};
const emailSplited = opts.to.split('@');
const emailHost = emailSplited[1];
const timeOut = options.timeout ? options.timeout : 0;
const debug = opts.debug ? (_.isFunction(opts.debug) ? opts.debug : console.info) : () => {};
const timeout = opts.timeout ? opts.timeout : 5000;
const client = net.createConnection(connOption, () => {
return resolve({
write: (msg) => {
client.write(msg + '\r\n');
},
end: () => {
return new P((resolve, reject) => {
client.end();
fnNetEnd = resolve;
});
},
response: responseQueue.flush
return new P((resolve, reject) => {
const jobDnsResolveMx = dnsResolveMx(emailHost).then(results => {
if(_.isEmpty(results)) {
throw new VerifyError('','MXRECORD_FAIL');
}
return results;
},() => {
throw new VerifyError('','MXRECORD_FAIL');
});
}).on('error', (err) => {
reject(err);
});
client.setTimeout(timeOut, () => {
client.end();
client.destroy(new Error('timeout'));
});
const jobNetConnect = jobDnsResolveMx.then(results => {
debug('RESOLVE MX RECORD');
client.on('data', (() => {
let response = '';
return (data) => {
response += data.toString();
if(response.slice(-1) === '\n') {
responseQueue.add(response.substr(0, response.length - 2));
response = '';
}
};
})());
const exchange = _(results).sortBy(v => v.priority).take(1).value()[0].exchange;
debug('\t' + exchange);
client.on('end', () => {
fnNetEnd();
});
});
});
return netsend({port: 25, host: exchange}).catch(() => {
throw new VerifyError('','CONN_FAIL');
});
});
const jobVerify = jobNetConnect.then(netConn => {
debug('CONNECTED SMTP SERVER');
module.exports = {
verify(opts) {
return netConn.response().then(resmsg => {
debug('\t' + resmsg[0]);
const emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; // eslint-disable-line
if(resmsg[0].substr(0, 3) !== '220') {
throw new VerifyError('','VERIFY_FAIL');
}
if(!emailRegex.test(opts.to)) {
return P.resolve('INVALID');
}
const writeMsg = 'HELO ' + opts.helo;
debug(writeMsg);
netConn.write(writeMsg);
const emailSplited = opts.to.split('@');
const emailHost = emailSplited[1];
return netConn.response();
}).then(resmsg => {
debug('\t' + resmsg[0]);
const debug = opts.debug ? (_.isFunction(opts.debug) ? opts.debug : console.info) : () => {};
if(resmsg[0].substr(0, 3) !== '250') {
throw new VerifyError('','VERIFY_FAIL');
}
return dnsResolveMx(emailHost).then(results => {
debug('RESOLVE MX RECORD');
const writeMsg = `MAIL FROM: <${opts.from}>`;
debug(writeMsg);
netConn.write(writeMsg);
const exchange = _(results).sortBy(v => v.priority).take(1).value()[0].exchange;
debug('\t' + exchange);
return netConn.response();
}).then(resmsg => {
debug('\t' + resmsg[0]);
return netConnect({port: 25, host: exchange, timeout: opts.timeout});
}).then(netConn => {
if(resmsg[0].substr(0, 3) !== '250') {
throw new VerifyError('','VERIFY_FAIL');
}
const writeMsg = `RCPT TO: <${opts.to}>`;
debug(writeMsg);
netConn.write(writeMsg);
debug('CONNECTED SMTP SERVER');
return netConn.response();
}).then(resmsg => {
debug('\t' + resmsg[0]);
if(resmsg[0].substr(0, 3) === '250') {
return 'EXIST';
} else {
return 'NOT_EXIST';
}
}).finally(() => {
netConn.end();
});
});
return netConn.response().then(resmsg => {
debug('\t' + resmsg[0]);
const mainJob = jobVerify.then(results => {
resolve(results);
}).catch(VerifyError,(err) => {
resolve(err.extra);
}).catch((err) => {
debug(err);
resolve('UNKNOWN');
});
if(resmsg[0].substr(0, 3) !== '220') {
return P.resolve('BLOCK');
const mainJobTimeout = setTimeout(() => {
mainJob.cancel();
if(jobDnsResolveMx.isPending()) {
return resolve('MXRECORD_TIMEOUT');
}
const writeMsg = 'HELO ' + opts.helo;
debug(writeMsg);
netConn.write(writeMsg);
if(jobNetConnect.isPending()) {
return resolve('CONN_TIMEOUT');
}
return netConn.response();
}).then(resmsg => {
debug('\t' + resmsg[0]);
if(resmsg[0].substr(0, 3) !== '250') {
return P.resolve('BLOCK');
if(jobVerify.isPending()) {
return resolve('VERIFY_TIMEOUT');
}
const writeMsg = `MAIL FROM: <${opts.from}>`;
debug(writeMsg);
netConn.write(writeMsg);
return resolve('UNKNOWN');
}, timeout);
return netConn.response();
}).then(resmsg => {
debug('\t' + resmsg[0]);
if(resmsg[0].substr(0, 3) !== '250') {
return P.resolve('BLOCK');
mainJob.finally(() => {
if(!mainJob.isCancelled()) {
clearTimeout(mainJobTimeout);
}
const writeMsg = `RCPT TO: <${opts.to}>`;
debug(writeMsg);
netConn.write(writeMsg);
return netConn.response();
}).then(resmsg => {
debug('\t' + resmsg[0]);
if(resmsg[0].substr(0, 3) === '250') {
return 'EXIST';
} else {
return 'NOT_EXIST';
}
}).finally(() => {
netConn.end();
});
}).catch(() => {
return 'CONN_FAIL';
});
}
};
{
"name": "zb-email-verifier",
"description": "Promise-based library for verify an email address existence via SMTP",
"version": "0.2.0",
"version": "0.5.0",
"author": {

@@ -6,0 +6,0 @@ "name": "ZIGBANG",

@@ -12,3 +12,3 @@ 'use strict';

debug: true,
timeout: 500
timeout: 1500
}).then(result => {

@@ -23,7 +23,12 @@ if(result === 'EXIST') {

// INVALID
// MXRECORD_TIMEOUT
// MXRECORD_FAIL
// CONN_FAIL
// CONN_TIMEOUT
// VERIFY_TIMEOUT
// VERIFY_FAIL
// EXIST
// NOT_EXIST
// INVALID
// BLOCK
// CONN_FAIL
// UNKNOWN
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc