342 lines
11 KiB
JavaScript
342 lines
11 KiB
JavaScript
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Comcarde Node.js Mailer Functionality
|
|
// Provides -Bridge- pay functionality.
|
|
// Copyright 2014 Comcarde
|
|
// Written by Keith Symington
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Includes
|
|
var nodemailer = require('nodemailer');
|
|
var log = require(global.pathPrefix + 'log.js');
|
|
var Q = require('q');
|
|
var templates = require(global.pathPrefix + '../utils/templates.js');
|
|
var formattingUtils = require(global.pathPrefix + '../utils/formatting.js');
|
|
var references = require(global.pathPrefix + '../utils/references.js');
|
|
var debug = require('debug')('utils:mailer');
|
|
|
|
/**
|
|
* Set up the exports
|
|
*/
|
|
module.exports = {
|
|
sendEmail: sendEmail,
|
|
sendEmailByID: sendEmailByID,
|
|
sendWelcomeEmail: sendWelcomeEmail,
|
|
sendEmailChangedEmails: sendEmailChangedEmails,
|
|
sendEmailRevertedEmails: sendEmailRevertedEmails
|
|
};
|
|
|
|
/**
|
|
* Define the email transport options
|
|
*/
|
|
const TRANSPORTER = nodemailer.createTransport({
|
|
service: 'Gmail',
|
|
auth: {
|
|
user: 'admin@comcarde.com',
|
|
pass: 'xnasacgwvfvskvlj'
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Generic function to send emails
|
|
*
|
|
* @param {String} mode - 'Test' to not send
|
|
* @param {String} destination - email address to send to
|
|
* @param {String} subject - email subject
|
|
* @param {String} htmlBody - email body in prepared HTML
|
|
* @param {String} caller - name of the caller for logging purposes
|
|
* @param {function} [next] - callback for success (if needed)
|
|
*/
|
|
function sendEmail(mode, destination, subject, htmlBody, caller, next) {
|
|
// Create the log data structure.
|
|
var mailOptions = {
|
|
from: 'admin@comcarde.com', // sender address
|
|
to: destination, // list of receivers
|
|
subject: subject, // Subject line
|
|
html: htmlBody // html body
|
|
};
|
|
|
|
if (mode !== 'Test') {
|
|
// Sent the e-mail using the transporter.
|
|
TRANSPORTER.sendMail(mailOptions, function(err, info) {
|
|
if (err) {
|
|
log.system(
|
|
'CRITICAL',
|
|
('Unable to send e-mail. ' + err),
|
|
caller,
|
|
'',
|
|
'System',
|
|
'127.0.0.1');
|
|
if (next) {
|
|
next(err);
|
|
}
|
|
} else {
|
|
log.system(
|
|
'INFO',
|
|
('E-mail sent to ' + destination + ' (' + info.response + ').'),
|
|
caller,
|
|
'',
|
|
'System',
|
|
'127.0.0.1');
|
|
if (next) {
|
|
next(null);
|
|
}
|
|
}
|
|
});
|
|
} else {
|
|
// Simply call back in test mode.
|
|
log.system(
|
|
'WARNING',
|
|
('E-mail test to ' + destination + ' (e-mail not sent).'),
|
|
caller,
|
|
'',
|
|
'System',
|
|
'127.0.0.1');
|
|
if (next) {
|
|
next(null);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generic function to send emails to a client identified by an ID.
|
|
* This will lookup the client's email address from the database and then pass
|
|
* it on to the basic function for completion.
|
|
*
|
|
* @param {String} mode - 'Test' to not send
|
|
* @param {String} clientID - ID of the client to send email to
|
|
* @param {String} subject - email subject
|
|
* @param {String} htmlBody - email body in prepared HTML
|
|
* @param {String} caller - name of the caller for logging purposes
|
|
* @param {function} [next] - callback for success (if needed)
|
|
*/
|
|
function sendEmailByID(mode, clientID, subject, htmlBody, caller, next) {
|
|
references.getEmailAddress(clientID)
|
|
.then(function(email) {
|
|
sendEmail(mode, email, subject, htmlBody, caller, next);
|
|
})
|
|
.catch(function(err) {
|
|
log.system(
|
|
'CRITICAL',
|
|
('Unable to find client to send e-mail to. ' + err),
|
|
caller,
|
|
'',
|
|
'System',
|
|
'127.0.0.1');
|
|
if (next) {
|
|
next(err);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Sends the welcome email to the client.
|
|
*
|
|
* @param {Client} newClient - The newly added client
|
|
* @param {String} mode - 'test' to not actually send the email
|
|
* @param {String} caller - The name of the caller for logging purposed
|
|
* @param {Function} next - Callback function for callers who don't want promises
|
|
*
|
|
* @returns {Promise} - A promise for the result of sending the email
|
|
*/
|
|
function sendWelcomeEmail(newClient, mode, caller, next) {
|
|
//
|
|
// Get the email parameters
|
|
//
|
|
var token = newClient.EMailValidationToken;
|
|
var email = newClient.ClientName;
|
|
var query = {
|
|
code: token,
|
|
email: email
|
|
};
|
|
var confirmUrl = formattingUtils.formatPortalUrl('confirmemail-link', query);
|
|
var denyEmailUrl = formattingUtils.formatPortalUrl('denyemail-link', query);
|
|
|
|
debug('- send welcome email to: [%s], token [%s] ', email, token);
|
|
|
|
//
|
|
// Render the email
|
|
//
|
|
var htmlEmail = templates.render(
|
|
'bridge-welcome',
|
|
{
|
|
emailValidationCode: token,
|
|
confirmEmailUrl: confirmUrl,
|
|
denyEmailUrl: denyEmailUrl
|
|
});
|
|
var subject = 'Welcome to Bridge';
|
|
|
|
//
|
|
// Pass it to the mailer to send (wrapped in a Q.nfcall to turn it into
|
|
// a promise).
|
|
// When the promise completes, call any callback defined
|
|
//
|
|
return Q.nfcall(sendEmail, mode, email, subject, htmlEmail, caller)
|
|
.then(function() {
|
|
// Success has no return values
|
|
if (next) {
|
|
next();
|
|
}
|
|
})
|
|
.catch(function(err) {
|
|
if (next) {
|
|
next(err);
|
|
}
|
|
return Q.reject(err); // Pass on the error
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Sends the emails related to an email change.
|
|
* This sends an email to the old address so they can revert if neccessary,
|
|
* and an address to the new address to confirm the email
|
|
*
|
|
* @param {String} oldEmail - the old email address being changed away from
|
|
* @param {String} newEmail - the new email address being changed to
|
|
* @param {Object} revertToken - The token to use to revert the email change
|
|
* @param {String} revertToken.token - the token
|
|
* @param {Object} confirmToken - The token to use to confirm the new email address
|
|
* @param {String} confirmToken.token - the token
|
|
* @param {String} mode - 'test' to not actually send the email
|
|
* @param {String} caller - The name of the caller for logging purposed
|
|
* @param {Function} next - Callback function for callers who don't want promises
|
|
*
|
|
* @returns {Promise} - A promise for the result of sending the email
|
|
*/
|
|
function sendEmailChangedEmails(oldEmail, newEmail, revertToken, confirmToken, mode, caller, next) {
|
|
//
|
|
// Build the urls.
|
|
//
|
|
var revertQuery = {
|
|
code: revertToken.token,
|
|
email: oldEmail
|
|
};
|
|
var confirmQuery = {
|
|
code: confirmToken.token,
|
|
email: newEmail
|
|
};
|
|
var baseRevertUrl = formattingUtils.formatPortalUrl('revert-changed-email-link');
|
|
var revertUrl = formattingUtils.formatPortalUrl('revert-changed-email-link', revertQuery);
|
|
|
|
var confirmChangeUrl = formattingUtils.formatPortalUrl('confirmemail-link', confirmQuery);
|
|
|
|
debug('- send email changed emails to: [%s] -> [%s] ', oldEmail, newEmail);
|
|
|
|
//
|
|
// Render the emails
|
|
//
|
|
var revertEmailBody = templates.render(
|
|
'email-changed-old',
|
|
{
|
|
oldEmail: oldEmail,
|
|
newEmail: newEmail,
|
|
revertEmailChangeUrl: revertUrl,
|
|
revertEmailChangeBaseUrl: baseRevertUrl,
|
|
revertValidationCode: revertQuery.code
|
|
});
|
|
var revertEmailSubject = 'Important: Email changed on Bridge Account';
|
|
|
|
var confirmEmailBody = templates.render(
|
|
'email-changed-new',
|
|
{
|
|
confirmChangedEmailUrl: confirmChangeUrl,
|
|
emailValidationCode: confirmQuery.code
|
|
});
|
|
var confirmEmailSubject = 'Please confirm your email address';
|
|
|
|
//
|
|
// Pass it to the mailer to send (wrapped in a Q.nfcall to turn it into
|
|
// a promise).
|
|
// When the promise completes, call any callback defined
|
|
//
|
|
var sendRevertEmail = Q.nfcall(
|
|
sendEmail,
|
|
mode,
|
|
oldEmail,
|
|
revertEmailSubject,
|
|
revertEmailBody,
|
|
caller
|
|
);
|
|
var sendConfirmEmail = Q.nfcall(
|
|
sendEmail,
|
|
mode,
|
|
newEmail,
|
|
confirmEmailSubject,
|
|
confirmEmailBody,
|
|
caller
|
|
);
|
|
return Q.all([sendRevertEmail, sendConfirmEmail])
|
|
.then(function() {
|
|
// Success has no return values
|
|
if (next) {
|
|
next();
|
|
}
|
|
})
|
|
.catch(function(err) {
|
|
if (next) {
|
|
next(err);
|
|
}
|
|
return Q.reject(err); // Pass on the error
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Sends the emails related to an email change.
|
|
* This sends an email to the old address so they can revert if neccessary,
|
|
* and an address to the new address to confirm the email
|
|
*
|
|
* @param {String} revertToEmail - the old email address being reverted back to
|
|
* @param {String} revertFromEmail - the new email address being reverted from
|
|
* @param {String} mode - 'test' to not actually send the email
|
|
* @param {String} caller - The name of the caller for logging purposed
|
|
* @param {Function} next - Callback function for callers who don't want promises
|
|
*
|
|
* @returns {Promise} - A promise for the result of sending the email
|
|
*/
|
|
function sendEmailRevertedEmails(revertToEmail, revertFromEmail, mode, caller, next) {
|
|
debug('- send email reverted emails to: [%s] -> [%s] ', revertToEmail, revertFromEmail);
|
|
|
|
//
|
|
// Render the emails
|
|
//
|
|
var revertToEmailBody = templates.render('email-reverted-to', {});
|
|
var revertToEmailSubject = 'Email change reverted on Bridge Account';
|
|
|
|
var revertFromEmailBody = templates.render('email-reverted-from', {});
|
|
var revertFromEmailSubject = 'Email change reverted on Bridge Account';
|
|
|
|
//
|
|
// Pass it to the mailer to send (wrapped in a Q.nfcall to turn it into
|
|
// a promise).
|
|
// When the promise completes, call any callback defined
|
|
//
|
|
var sendRevertToEmail = Q.nfcall(
|
|
sendEmail,
|
|
mode,
|
|
revertToEmail,
|
|
revertToEmailSubject,
|
|
revertToEmailBody,
|
|
caller
|
|
);
|
|
var sendRevertFromEmail = Q.nfcall(
|
|
sendEmail,
|
|
mode,
|
|
revertFromEmail,
|
|
revertFromEmailSubject,
|
|
revertFromEmailBody,
|
|
caller
|
|
);
|
|
return Q.all([sendRevertToEmail, sendRevertFromEmail])
|
|
.then(function() {
|
|
// Success has no return values
|
|
if (next) {
|
|
next();
|
|
}
|
|
})
|
|
.catch(function(err) {
|
|
if (next) {
|
|
next(err);
|
|
}
|
|
return Q.reject(err); // Pass on the error
|
|
});
|
|
}
|