diff options
Diffstat (limited to 'node_modules/nodemailer/lib')
| -rw-r--r-- | node_modules/nodemailer/lib/http-proxy.js | 128 | ||||
| -rw-r--r-- | node_modules/nodemailer/lib/nodemailer.js | 409 | ||||
| -rw-r--r-- | node_modules/nodemailer/lib/template-sender.js | 129 |
3 files changed, 0 insertions, 666 deletions
diff --git a/node_modules/nodemailer/lib/http-proxy.js b/node_modules/nodemailer/lib/http-proxy.js deleted file mode 100644 index 24279ba..0000000 --- a/node_modules/nodemailer/lib/http-proxy.js +++ /dev/null @@ -1,128 +0,0 @@ -'use strict'; - -/** - * Minimal HTTP/S proxy client - */ - -var net = require('net'); -var tls = require('tls'); -var urllib = require('url'); - -module.exports = proxyConnect; - -/** - * Establishes proxied connection to destinationPort - * - * proxyConnect("http://localhost:3128/", 80, "google.com", function(err, socket){ - * socket.write("GET / HTTP/1.0\r\n\r\n"); - * }); - * - * @param {String} proxyUrl proxy configuration, etg "http://proxy.host:3128/" - * @param {Number} destinationPort Port to open in destination host - * @param {String} destinationHost Destination hostname - * @param {Function} callback Callback to run with the rocket object once connection is established - */ -function proxyConnect(proxyUrl, destinationPort, destinationHost, callback) { - var proxy = urllib.parse(proxyUrl); - - // create a socket connection to the proxy server - var options; - var connect; - var socket; - - options = { - host: proxy.hostname, - port: Number(proxy.port) ? Number(proxy.port) : (proxy.protocol === 'https:' ? 443 : 80) - }; - - if (proxy.protocol === 'https:') { - // we can use untrusted proxies as long as we verify actual SMTP certificates - options.rejectUnauthorized = false; - connect = tls.connect.bind(tls); - } else { - connect = net.connect.bind(net); - } - - // Error harness for initial connection. Once connection is established, the responsibility - // to handle errors is passed to whoever uses this socket - var finished = false; - var tempSocketErr = function (err) { - if (finished) { - return; - } - finished = true; - try { - socket.destroy(); - } catch (E) { - // ignore - } - callback(err); - }; - - socket = connect(options, function () { - if (finished) { - return; - } - - var reqHeaders = { - Host: destinationHost + ':' + destinationPort, - Connection: 'close' - }; - if (proxy.auth) { - reqHeaders['Proxy-Authorization'] = 'Basic ' + new Buffer(proxy.auth).toString('base64'); - } - - socket.write( - // HTTP method - 'CONNECT ' + destinationHost + ':' + destinationPort + ' HTTP/1.1\r\n' + - - // HTTP request headers - Object.keys(reqHeaders).map(function (key) { - return key + ': ' + reqHeaders[key]; - }).join('\r\n') + - - // End request - '\r\n\r\n'); - - - var headers = ''; - var onSocketData = function (chunk) { - var match; - var remainder; - - if (finished) { - return; - } - - headers += chunk.toString('binary'); - if ((match = headers.match(/\r\n\r\n/))) { - socket.removeListener('data', onSocketData); - remainder = headers.substr(match.index + match[0].length); - headers = headers.substr(0, match.index); - if (remainder) { - socket.unshift(new Buffer(remainder, 'binary')); - } - // proxy connection is now established - finished = true; - - socket.removeListener('error', tempSocketErr); - - // check response code - match = headers.match(/^HTTP\/\d+\.\d+ (\d+)/i); - if (!match || (match[1] || '').charAt(0) !== '2') { - try { - socket.destroy(); - } catch (E) { - // ignore - } - return callback(new Error('Invalid response from proxy' + (match && ': ' + match[1] || ''))); - } - - return callback(null, socket); - } - }; - socket.on('data', onSocketData); - }); - - socket.once('error', tempSocketErr); -} diff --git a/node_modules/nodemailer/lib/nodemailer.js b/node_modules/nodemailer/lib/nodemailer.js deleted file mode 100644 index 9f0267b..0000000 --- a/node_modules/nodemailer/lib/nodemailer.js +++ /dev/null @@ -1,409 +0,0 @@ -'use strict'; - -var mailcomposer = require('mailcomposer'); -var EventEmitter = require('events').EventEmitter; -var util = require('util'); -var shared = require('nodemailer-shared'); -var directTransport = require('nodemailer-direct-transport'); -var smtpTransport = require('nodemailer-smtp-transport'); -var smtpPoolTransport = require('nodemailer-smtp-pool'); -var templateSender = require('./template-sender'); -var packageData = require('../package.json'); -var httpProxy = require('./http-proxy'); -var Socks = require('socks'); -var urllib = require('url'); - -// Export createTransport method -module.exports.createTransport = function (transporter, defaults) { - var urlConfig; - var options; - var mailer; - var proxyUrl; - - // if no transporter configuration is provided use direct as default - transporter = transporter || directTransport({ - debug: true - }); - - if ( - // provided transporter is a configuration object, not transporter plugin - (typeof transporter === 'object' && typeof transporter.send !== 'function') || - // provided transporter looks like a connection url - (typeof transporter === 'string' && /^(smtps?|direct):/i.test(transporter)) - ) { - - if ((urlConfig = typeof transporter === 'string' ? transporter : transporter.url)) { - // parse a configuration URL into configuration options - options = shared.parseConnectionUrl(urlConfig); - } else { - options = transporter; - } - - if (options.proxy && typeof options.proxy === 'string') { - proxyUrl = options.proxy; - } - - if (options.transport && typeof options.transport === 'string') { - try { - transporter = require('nodemailer-' + (options.transport).toLowerCase() + '-transport')(options); - } catch (E) { - // if transporter loader fails, return an error when sending mail - transporter = { - send: function (mail, callback) { - var errmsg = 'Requested transport plugin "nodemailer-' + (options.transport).toLowerCase() + '-transport" could not be initiated'; - var err = new Error(errmsg); - err.code = 'EINIT'; - setImmediate(function () { - return callback(err); - }); - } - }; - } - } else if (options.direct) { - transporter = directTransport(options); - } else if (options.pool) { - transporter = smtpPoolTransport(options); - } else { - transporter = smtpTransport(options); - } - } - - mailer = new Nodemailer(transporter, defaults); - - if (proxyUrl) { - setupProxy(mailer, proxyUrl); - } - - return mailer; -}; - -/** - * Sets up proxy handler for a Nodemailer object - * - * @param {Object} mailer Nodemailer instance to modify - * @param {String} proxyUrl Proxy configuration url - */ -function setupProxy(mailer, proxyUrl) { - var proxy = urllib.parse(proxyUrl); - - // setup socket handler for the mailer object - mailer.getSocket = function (options, callback) { - switch (proxy.protocol) { - - // Connect using a HTTP CONNECT method - case 'http:': - case 'https:': - httpProxy(proxy.href, options.port, options.host, function (err, socket) { - if (err) { - return callback(err); - } - return callback(null, { - connection: socket - }); - }); - return; - - // Connect using a SOCKS4/5 proxy - case 'socks:': - case 'socks5:': - case 'socks4:': - case 'socks4a:': - Socks.createConnection({ - proxy: { - ipaddress: proxy.hostname, - port: proxy.port, - type: Number(proxy.protocol.replace(/\D/g, '')) || 5 - }, - target: { - host: options.host, - port: options.port - }, - command: 'connect', - authentication: !proxy.auth ? false : { - username: decodeURIComponent(proxy.auth.split(':').shift()), - password: decodeURIComponent(proxy.auth.split(':').pop()) - } - }, function (err, socket) { - if (err) { - return callback(err); - } - return callback(null, { - connection: socket - }); - }); - return; - } - - callback(new Error('Unknown proxy configuration')); - }; -} - -/** - * Creates an object for exposing the Nodemailer API - * - * @constructor - * @param {Object} transporter Transport object instance to pass the mails to - */ -function Nodemailer(transporter, defaults) { - EventEmitter.call(this); - - this._defaults = defaults || {}; - - this._plugins = { - compile: [], - stream: [] - }; - - this.transporter = transporter; - this.logger = this.transporter.logger || shared.getLogger({ - logger: false - }); - - // setup emit handlers for the transporter - if (typeof transporter.on === 'function') { - - // deprecated log interface - this.transporter.on('log', function (log) { - this.logger.debug('%s: %s', log.type, log.message); - }.bind(this)); - - // transporter errors - this.transporter.on('error', function (err) { - this.logger.error('Transport Error: %s', err.message); - this.emit('error', err); - }.bind(this)); - - // indicates if the sender has became idle - this.transporter.on('idle', function () { - var args = Array.prototype.slice.call(arguments); - args.unshift('idle'); - this.emit.apply(this, args); - }.bind(this)); - } -} -util.inherits(Nodemailer, EventEmitter); - -/** - * Creates a template based sender function - * - * @param {Object} templates Object with string values where key is a message field and value is a template - * @param {Object} defaults Optional default message fields - * @return {Function} E-mail sender - */ -Nodemailer.prototype.templateSender = function (templates, defaults) { - return templateSender(this, templates, defaults); -}; - -Nodemailer.prototype.use = function (step, plugin) { - step = (step || '').toString(); - if (!this._plugins.hasOwnProperty(step)) { - this._plugins[step] = [plugin]; - } else { - this._plugins[step].push(plugin); - } -}; - -/** - * Optional methods passed to the underlying transport object - */ -['close', 'isIdle', 'verify'].forEach(function (method) { - Nodemailer.prototype[method] = function ( /* possible arguments */ ) { - var args = Array.prototype.slice.call(arguments); - if (typeof this.transporter[method] === 'function') { - return this.transporter[method].apply(this.transporter, args); - } else { - return false; - } - }; -}); - -/** - * Sends an email using the preselected transport object - * - * @param {Object} data E-data description - * @param {Function} callback Callback to run once the sending succeeded or failed - */ -Nodemailer.prototype.sendMail = function (data, callback) { - var promise; - - if (!callback && typeof Promise === 'function') { - promise = new Promise(function (resolve, reject) { - callback = shared.callbackPromise(resolve, reject); - }); - } - - if (typeof this.getSocket === 'function') { - this.transporter.getSocket = this.getSocket.bind(this); - this.getSocket = false; - } - - data = data || {}; - data.headers = data.headers || {}; - callback = callback || function () {}; - - // apply defaults - Object.keys(this._defaults).forEach(function (key) { - if (!(key in data)) { - data[key] = this._defaults[key]; - } else if (key === 'headers') { - // headers is a special case. Allow setting individual default headers - Object.keys(this._defaults.headers || {}).forEach(function (key) { - if (!(key in data.headers)) { - data.headers[key] = this._defaults.headers[key]; - } - }.bind(this)); - } - }.bind(this)); - - var mail = { - data: data, - message: null, - resolveContent: shared.resolveContent - }; - - if (typeof this.transporter === 'string') { - callback(new Error('Unsupported configuration, downgrade Nodemailer to v0.7.1 to use it')); - return promise; - } - - this.logger.info('Sending mail using %s/%s', this.transporter.name, this.transporter.version); - - this._processPlugins('compile', mail, function (err) { - if (err) { - this.logger.error('PluginCompile Error: %s', err.message); - return callback(err); - } - - mail.message = mailcomposer(mail.data); - - if (mail.data.xMailer !== false) { - mail.message.setHeader('X-Mailer', mail.data.xMailer || this._getVersionString()); - } - - if (mail.data.priority) { - switch ((mail.data.priority || '').toString().toLowerCase()) { - case 'high': - mail.message.setHeader('X-Priority', '1 (Highest)'); - mail.message.setHeader('X-MSMail-Priority', 'High'); - mail.message.setHeader('Importance', 'High'); - break; - case 'low': - mail.message.setHeader('X-Priority', '5 (Lowest)'); - mail.message.setHeader('X-MSMail-Priority', 'Low'); - mail.message.setHeader('Importance', 'Low'); - break; - default: - // do not add anything, since all messages are 'Normal' by default - } - } - - // add optional List-* headers - if (mail.data.list && typeof mail.data.list === 'object') { - this._getListHeaders(mail.data.list).forEach(function (listHeader) { - listHeader.value.forEach(function (value) { - mail.message.addHeader(listHeader.key, value); - }); - }); - } - - this._processPlugins('stream', mail, function (err) { - if (err) { - this.logger.error('PluginStream Error: %s', err.message); - return callback(err); - } - - this.transporter.send(mail, function () { - var args = Array.prototype.slice.call(arguments); - if (args[0]) { - this.logger.error('Send Error: %s', args[0].message); - } - callback.apply(null, args); - }.bind(this)); - }.bind(this)); - }.bind(this)); - - return promise; -}; - -Nodemailer.prototype._getVersionString = function () { - return util.format( - '%s (%s; +%s; %s/%s)', - packageData.name, - packageData.version, - packageData.homepage, - this.transporter.name, - this.transporter.version - ); -}; - -Nodemailer.prototype._processPlugins = function (step, mail, callback) { - step = (step || '').toString(); - - if (!this._plugins.hasOwnProperty(step) || !this._plugins[step].length) { - return callback(null); - } - - var plugins = Array.prototype.slice.call(this._plugins[step]); - - this.logger.debug('Using %s plugins for %s', plugins.length, step); - - var processPlugins = function () { - if (!plugins.length) { - return callback(null); - } - var plugin = plugins.shift(); - plugin(mail, function (err) { - if (err) { - return callback(err); - } - processPlugins(); - }); - }.bind(this); - - processPlugins(); -}; - -/** - * This method takes list headers structure and converts it into - * header list with key-value pairs - * - * @param {Object} listData Structured List-* headers - * @return {Array} An array of headers - */ -Nodemailer.prototype._getListHeaders = function (listData) { - // make sure an url looks like <protocol:url> - var formatListUrl = function (url) { - url = url.replace(/[\s<]+|[\s>]+/g, ''); - if (/^(https?|mailto|ftp):/.test(url)) { - return '<' + url + '>'; - } - if (/^[^@]+@[^@]+$/.test(url)) { - return '<mailto:' + url + '>'; - } - - return '<http://' + url + '>'; - }; - - return Object.keys(listData).map(function (key) { - return { - key: 'list-' + key.toLowerCase().trim(), - value: [].concat(listData[key] || []).map(function (value) { - if (typeof value === 'string') { - return formatListUrl(value); - } - return { - prepared: true, - value: [].concat(value || []).map(function (value) { - if (typeof value === 'string') { - return formatListUrl(value); - } - if (value && value.url) { - return formatListUrl(value.url) + (value.comment ? ' (' + value.comment + ')' : ''); - } - return ''; - }).join(', ') - }; - }) - }; - }); -}; diff --git a/node_modules/nodemailer/lib/template-sender.js b/node_modules/nodemailer/lib/template-sender.js deleted file mode 100644 index 8963ea0..0000000 --- a/node_modules/nodemailer/lib/template-sender.js +++ /dev/null @@ -1,129 +0,0 @@ -'use strict'; - -var shared = require('nodemailer-shared'); - -module.exports = templateSender; - -// expose for testing -module.exports.render = render; - -/** - * Create template based e-mail sender - * - * @param {Object} transport Nodemailer transport object to use for actual sending - * @param {Object} templates Either an object with template strings or an external renderer - * @param {Object} [defaults] Default fields set for every mail sent using this sender - * @return {Function} Template based sender - */ -function templateSender(transport, templates, defaults) { - templates = templates || {}; - defaults = defaults || {}; - - // built in renderer - var defaultRenderer = function (context, callback) { - var rendered = {}; - Object.keys(templates).forEach(function (key) { - rendered[key] = render(templates[key], { - escapeHtml: key === 'html' - }, context); - }); - callback(null, rendered); - }; - - // actual renderer - var renderer = (typeof templates.render === 'function' ? templates.render.bind(templates) : defaultRenderer); - - return function (fields, context, callback) { - - var promise; - - if (!callback && typeof Promise === 'function') { - promise = new Promise(function (resolve, reject) { - callback = shared.callbackPromise(resolve, reject); - }); - } - - // render data - renderer(context, function (err, rendered) { - if (err) { - return callback(err); - } - var mailData = mix(defaults, fields, rendered); - setImmediate(function () { - transport.sendMail(mailData, callback); - }); - }); - - return promise; - }; -} - -/** - * Merges multiple objects into one. Assumes single level, except 'headers' - */ -function mix( /* obj1, obj2, ..., objN */ ) { - var args = Array.prototype.slice.call(arguments); - var result = {}; - - args.forEach(function (arg) { - Object.keys(arg || {}).forEach(function (key) { - if (key === 'headers') { - if (!result.headers) { - result.headers = {}; - } - Object.keys(arg[key]).forEach(function (hKey) { - if (!(hKey in result.headers)) { - result.headers[hKey] = arg[key][hKey]; - } - }); - } else if (!(key in result)) { - result[key] = arg[key]; - } - }); - }); - - return result; -} - -/** - * Renders a template string using provided context. Values are marked as {{key}} in the template. - * - * @param {String} str Template string - * @param {Object} options Render options. options.escapeHtml=true escapes html specific characters - * @param {Object} context Key-value pairs for the template, eg {name: 'User Name'} - * @return {String} Rendered template - */ -function render(str, options, context) { - str = (str || '').toString(); - context = context || {}; - options = options || {}; - - var re = /\{\{[ ]*([^{}\s]+)[ ]*\}\}/g; - - return str.replace(re, function (match, key) { - var value; - if (context.hasOwnProperty(key)) { - value = context[key].toString(); - if (options.escapeHtml) { - value = value.replace(/["'&<>]/g, function (char) { - switch (char) { - case '&': - return '&'; - case '<': - return '<'; - case '>': - return '>'; - case '"': - return '"'; - case '\'': - return '''; - default: - return char; - } - }); - } - return value; - } - return match; - }); -} |
