Source: email-service-provider.js

'use strict';

const autoBind = require('auto-bind');
const nodemailer = require('nodemailer');
const EmailServiceError = require('./email-service-error');

class EmailServiceProvider {

  /**
   * EmailServiceProvider constructor to configure the SMTP connection.
   * @private
   * @param {Object} config - Configuration for the nodemailer transporter object
   * @param {string} config.user - SMTP username
   * @param {string} config.pass - SMTP password
   * @param {string} config.host - SMTP hostname
   * @param {number} config.port - SMTP port
   * @param {boolean} config.secure - true if using TLS
   */
  constructor(config) {
    if (!config.user) {
      throw new EmailServiceError('Username is required for authentication.');
    }
    if (!config.pass) {
      throw new EmailServiceError('Password is required for authentication.');
    }
    this.transporter = nodemailer.createTransport({
      host: config.host,
      port: config.port,
      secure: config.secure,
      auth: {
        user: config.user,
        pass: config.pass
      }
    });
    autoBind(this);
  }

  /**
   * Function to send an email.
   * @param {Object} details - Email message options
   * @param {string} details.from - The email address of the sender
   * @param {string|string[]} details.to - Comma separated list or an array of recipients email addresses that will appear on the To: field
   * @param {string|string[]} [details.cc] - Comma separated list or an array of recipients email addresses that will appear on the Cc: field
   * @param {string|string[]} [details.bcc] - Comma separated list or an array of recipients email addresses that will appear on the Bcc: field
   * @param {string} [details.subj] - The subject of the email
   * @param {string} [details.text] - The plaintext version of the message
   * @param {string} [details.html] - The HTML version of the message
   * @return {Promise.<{result: Object, errors: EmailServiceError[]}>} - A promise for sending the Email.
   * @reject {EmailServiceError} - EmailService Error which occurred..
   */
  sendEmail(details) {
    if (!(details === null || typeof details === 'object')) {
      throw new EmailServiceError('No argument found in the sendEmail function.');
    }
    if (!(typeof details.from === 'string' || details.from instanceof String)) {
      throw new EmailServiceError('\'from\' string is required in the details argument.');
    }
    if (!(typeof details.to === 'string' || details.to instanceof String || Array.isArray(details.to))) {
      throw new EmailServiceError('\'to\' array/string is required in the details argument.');
    }
    return this.transporter.sendMail({
      from: details.from,
      to: details.to,
      cc: details.cc,
      bcc: details.bcc,
      subject: details.subject,
      text: details.text,
      html: details.html
    })
    .catch(err => {
      throw new EmailServiceError(err.message);
    });
  }

}

module.exports = EmailServiceProvider;