1 var wellKnownHosts = require("../wellknown"),
  2     simplesmtp = require("simplesmtp");
  3 
  4 // Expose to the world
  5 module.exports = SMTPTransport;
  6 
  7 /**
  8  * <p>Generates a Transport object for SMTP</p>
  9  * 
 10  * <p>NB! This is a pool of connections that try to keep themselves alive. The
 11  * connection is not closed to the server once the message is delivered.</p>
 12  * 
 13  * <p>Possible options can be the following:</p>
 14  * 
 15  * <ul>
 16  *     <li><b>service</b> - a well known service identifier ("Gmail", "Hotmail"
 17  *         etc.) for auto-completing host, port and secure connection settings</li>
 18  *     <li><b>host</b> - hostname of the SMTP server</li>
 19  *     <li><b>port</b> - port of the SMTP server</li>
 20  *     <li><b>secureConnection</b> - use SSL</li>
 21  *     <li><b>name</b> - the name of the client server</li>
 22  *     <li><b>auth</b> - authentication object as <code>{user:"...", pass:"..."}</code>
 23  *     <li><b>ignoreTLS</b> - ignore server support for STARTTLS</li>
 24  *     <li><b>debug</b> - output client and server messages to console</li>
 25  *     <li><b>maxConnections</b> - how many connections to keep in the pool</li>
 26  * </ul> 
 27  * 
 28  * @constructor
 29  * @param {Object} [options] SMTP options
 30  */
 31 function SMTPTransport(options){
 32     var keys, key, i, len;
 33     
 34     this.options = options || {};
 35     
 36     this.initOptions();
 37     
 38     this.pool = simplesmtp.createClientPool(this.options.port, 
 39         this.options.host, this.options);
 40 }
 41 
 42 /**
 43  * <p>Initializes the SMTP connection options. Needed mostly for legacy option
 44  * values and also for filling in the well known hosts data if needed.</p>
 45  */
 46 SMTPTransport.prototype.initOptions = function(){
 47     // provide support for legacy API
 48     if(this.options.use_authentication === false){
 49         this.options.auth = false;
 50     }else if(this.options.user || this.options.pass){
 51         if(!this.options.auth){
 52             this.options.auth = {};
 53         }
 54         this.options.auth.user = this.options.auth.user || this.options.user;
 55         this.options.auth.pass = this.options.auth.pass || this.options.pass;
 56     }
 57     
 58     if(this.options.ssl){
 59         this.options.secureConnection = true;
 60     }
 61     
 62     if(this.options.tls === false){
 63         this.options.ignoreTLS = true;
 64     }
 65     
 66     // lets be modest just in case
 67     this.options.maxConnections = this.options.maxConnections || 5;
 68     
 69     // use well known settings if service is defined
 70     if(this.options.service && wellKnownHosts[this.options.service]){
 71         keys = Object.keys(wellKnownHosts[this.options.service]);
 72         for(i=0, len=keys.length; i<len; i++){
 73             key = keys[i];
 74             this.options[key] = this.options[key] ||
 75                     wellKnownHosts[this.options.service][key];
 76         }
 77     }
 78 };
 79 
 80 /**
 81  * <p>Forwards the mailcomposer message object to the simplesmpt client pool</p>
 82  * 
 83  * @param {Object} emailMessage MailComposer object
 84  * @param {Function} callback Callback function to run when the sending is completed
 85  */
 86 SMTPTransport.prototype.sendMail = function(emailMessage, callback){
 87     // force SMTP encoding
 88     emailMessage.options.escapeSMTP = true;
 89     
 90     if(this.options.requiresAuth && 
 91       (!this.options.auth || !this.options.auth.user || !this.options.auth.pass)){
 92         return callback(new Error("Authentication required, invalid details provided"));
 93     }
 94     
 95     this.pool.sendMail(emailMessage, callback);
 96 };
 97 
 98 /**
 99  * <p>Closes the client pool</p>
100  * 
101  * @param {Function} callback Callback function to run once the pool is closed
102  */
103 SMTPTransport.prototype.close = function(callback){
104     this.pool.close(callback);
105 };