Use nodemailer template engine
This commit is contained in:
parent
2d510038cb
commit
3a6842c296
120
src/dao/email.js
120
src/dao/email.js
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
const log = require('npmlog');
|
const log = require('npmlog');
|
||||||
const util = require('../service/util');
|
const util = require('../service/util');
|
||||||
|
const message = require('./message.json');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple wrapper around Nodemailer to send verification emails
|
* A simple wrapper around Nodemailer to send verification emails
|
||||||
@ -35,12 +36,12 @@ class Email {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an instance of the reusable nodemailer SMTP transport.
|
* Create an instance of the reusable nodemailer SMTP transport.
|
||||||
* @param {string} host The SMTP server's hostname e.g. 'smtp.gmail.com'
|
* @param {string} host SMTP server's hostname: 'smtp.gmail.com'
|
||||||
* @param {Object} auth Auth credential e.g. { user:'user@gmail.com', pass:'pass' }
|
* @param {Object} auth Auth credential: { user:'user@gmail.com', pass:'pass' }
|
||||||
* @param {Object} sender The message 'FROM' field e.g. { name:'Your Support', email:'noreply@exmple.com' }
|
* @param {Object} sender message 'FROM' field: { name:'Your Support', email:'noreply@exmple.com' }
|
||||||
* @param {string} port (optional) The SMTP server's SMTP port. Defaults to 465.
|
* @param {string} port (optional) SMTP server's SMTP port. Defaults to 465.
|
||||||
* @param {boolean} secure (optional) If TSL should be used. Defaults to true.
|
* @param {boolean} secure (optional) if TSL should be used. Defaults to true.
|
||||||
* @param {boolean} requireTLS (optional) If TSL is mandatory. Defaults to true.
|
* @param {boolean} requireTLS (optional) if TSL is mandatory. Defaults to true.
|
||||||
*/
|
*/
|
||||||
init(options) {
|
init(options) {
|
||||||
this._transport = this._mailer.createTransport({
|
this._transport = this._mailer.createTransport({
|
||||||
@ -54,31 +55,38 @@ class Email {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A generic method to send an email message via nodemail.
|
* A generic method to send an email message via nodemailer.
|
||||||
* @param {Object} from The sender user id object e.g. { name:'Jon Smith', email:'j@smith.com' }
|
* @param {Object} from sender user id object: { name:'Jon Smith', email:'j@smith.com' }
|
||||||
* @param {Object} to The recipient user id object e.g. { name:'Jon Smith', email:'j@smith.com' }
|
* @param {Object} to recipient user id object: { name:'Jon Smith', email:'j@smith.com' }
|
||||||
* @param {string} subject The message subject
|
* @param {string} subject message subject
|
||||||
* @param {string} text The message plaintext body
|
* @param {string} text message plaintext body template
|
||||||
* @param {string} html The message html body
|
* @param {string} html message html body template
|
||||||
* @yield {Object} The reponse object containing SMTP info
|
* @param {Object} params (optional) nodermailer template parameters
|
||||||
|
* @yield {Object} reponse object containing SMTP info
|
||||||
*/
|
*/
|
||||||
*send(options) {
|
*send(options) {
|
||||||
let mailOptions = {
|
let template = {
|
||||||
from: {
|
|
||||||
name: options.from.name,
|
|
||||||
address: options.from.email
|
|
||||||
},
|
|
||||||
to: {
|
|
||||||
name: options.to.name,
|
|
||||||
address: options.to.email
|
|
||||||
},
|
|
||||||
subject: options.subject,
|
subject: options.subject,
|
||||||
text: options.text,
|
text: options.text,
|
||||||
html: options.html
|
html: options.html
|
||||||
};
|
};
|
||||||
|
let sender = {
|
||||||
|
from: {
|
||||||
|
name: options.from.name,
|
||||||
|
address: options.from.email
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let recipient = {
|
||||||
|
to: {
|
||||||
|
name: options.to.name,
|
||||||
|
address: options.to.email
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let params = options.params || {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let info = yield this._transport.sendMail(mailOptions);
|
let sendFn = this._transport.templateSender(template, sender);
|
||||||
|
let info = yield sendFn(recipient, params);
|
||||||
log.silly('email', 'Email sent.', info);
|
log.silly('email', 'Email sent.', info);
|
||||||
return info;
|
return info;
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
@ -92,32 +100,45 @@ class Email {
|
|||||||
* ownership. If the primary email address is provided, only one email
|
* ownership. If the primary email address is provided, only one email
|
||||||
* will be sent out. Otherwise all of the PGP key's user IDs will be
|
* will be sent out. Otherwise all of the PGP key's user IDs will be
|
||||||
* verified, resulting in an email sent per user ID.
|
* verified, resulting in an email sent per user ID.
|
||||||
* @param {Array} userIds The user id documents containing the nonces
|
* @param {Array} userIds user id documents containing the nonces
|
||||||
* @param {Array} primaryEmail (optional) The user's primary email address
|
* @param {Array} primaryEmail (optional) user's primary email address
|
||||||
* @param {Object} origin Required for links to the keyserver e.g. { protocol:'https', host:'openpgpkeys@example.com' }
|
* @param {Object} origin Required for links to the keyserver: { protocol:'https', host:'openpgpkeys@example.com' }
|
||||||
* @yield {undefined}
|
* @yield {undefined}
|
||||||
*/
|
*/
|
||||||
*sendVerification(options) {
|
*sendVerifyKey(options) {
|
||||||
let primaryEmail = options.primaryEmail, userIds = options.userIds, origin = options.origin;
|
let primaryEmail = options.primaryEmail, userIds = options.userIds, origin = options.origin;
|
||||||
let primaryUserId = userIds.find(uid => uid.email === primaryEmail);
|
let primaryUserId = userIds.find(uid => uid.email === primaryEmail);
|
||||||
if (primaryUserId) { // send only one email to the primary user id
|
if (primaryUserId) { // send only one email to the primary user id
|
||||||
return yield this._sendVerificationHelper(primaryUserId, origin);
|
return yield this._sendVerifyKeyHelper(primaryUserId, origin);
|
||||||
}
|
}
|
||||||
for (let uid of userIds) {
|
for (let uid of userIds) {
|
||||||
yield this._sendVerificationHelper(uid, origin);
|
yield this._sendVerifyKeyHelper(uid, origin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Help method to send a verification message
|
* Helper function to send a verification message
|
||||||
* @param {Object} userId The user id document
|
* @param {Object} userId user id document
|
||||||
* @param {Object} origin The origin of the server
|
* @param {Object} origin origin of the server
|
||||||
* @yield {Object} The send response from the SMTP server
|
* @yield {Object} send response from the SMTP server
|
||||||
*/
|
*/
|
||||||
*_sendVerificationHelper(userId, origin) {
|
*_sendVerifyKeyHelper(userId, origin) {
|
||||||
let message = this._createVerifyMessage(userId, origin);
|
let msg = {
|
||||||
|
from: this._sender,
|
||||||
|
to: userId,
|
||||||
|
subject: message.verifyKey.subject,
|
||||||
|
text: message.verifyKey.text,
|
||||||
|
html: message.verifyKey.html,
|
||||||
|
params: {
|
||||||
|
name: userId.name,
|
||||||
|
protocol: origin.protocol,
|
||||||
|
host: origin.host,
|
||||||
|
keyid: encodeURIComponent(userId.keyid),
|
||||||
|
nonce: encodeURIComponent(userId.nonce)
|
||||||
|
}
|
||||||
|
};
|
||||||
try {
|
try {
|
||||||
let info = yield this.send(message);
|
let info = yield this.send(msg);
|
||||||
if (!this._checkResponse(info)) {
|
if (!this._checkResponse(info)) {
|
||||||
log.warn('email', 'Verification mail may not have been received.', info);
|
log.warn('email', 'Verification mail may not have been received.', info);
|
||||||
}
|
}
|
||||||
@ -127,34 +148,11 @@ class Email {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function to create a verification message object.
|
|
||||||
* @param {Object} userId The user id document
|
|
||||||
* @param {Object} origin The origin of the server
|
|
||||||
* @return {Object} The message object
|
|
||||||
*/
|
|
||||||
_createVerifyMessage(userId, origin) {
|
|
||||||
let verifyLink = origin.protocol + '://' + origin.host +
|
|
||||||
'/api/v1/verify/?keyid=' + encodeURIComponent(userId.keyid) +
|
|
||||||
'&nonce=' + encodeURIComponent(userId.nonce);
|
|
||||||
let text = `Hey${userId.name ? ' ' + userId.name : ''},
|
|
||||||
|
|
||||||
please click here to verify your key: ${verifyLink}
|
|
||||||
`;
|
|
||||||
|
|
||||||
return {
|
|
||||||
from: this._sender,
|
|
||||||
to: userId,
|
|
||||||
subject: 'Verify Your Key',
|
|
||||||
text: text
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the message was sent successfully according to SMTP
|
* Check if the message was sent successfully according to SMTP
|
||||||
* reply codes: http://www.supermailer.de/smtp_reply_codes.htm
|
* reply codes: http://www.supermailer.de/smtp_reply_codes.htm
|
||||||
* @param {Object} info The info object return from nodemailer
|
* @param {Object} info info object return from nodemailer
|
||||||
* @return {boolean} If the message was received by the user
|
* @return {boolean} if the message was received by the user
|
||||||
*/
|
*/
|
||||||
_checkResponse(info) {
|
_checkResponse(info) {
|
||||||
return /^2/.test(info.response);
|
return /^2/.test(info.response);
|
||||||
|
7
src/dao/message.json
Normal file
7
src/dao/message.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"verifyKey": {
|
||||||
|
"subject": "Verify Your Key",
|
||||||
|
"text": "Hello {{name}},\n\nplease click here to verify your key: {{protocol}}://{{host}}/api/v1/verify/?keyid={{keyid}}&nonce={{nonce}}",
|
||||||
|
"html": ""
|
||||||
|
}
|
||||||
|
}
|
@ -48,7 +48,7 @@ describe('Email Integration Tests', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("sendVerification", function() {
|
describe("sendVerifyKey", function() {
|
||||||
it('should work', function *() {
|
it('should work', function *() {
|
||||||
let options = {
|
let options = {
|
||||||
userIds: [{
|
userIds: [{
|
||||||
@ -63,7 +63,7 @@ describe('Email Integration Tests', function() {
|
|||||||
host: 'localhost:' + config.server.port
|
host: 'localhost:' + config.server.port
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
yield email.sendVerification(options);
|
yield email.sendVerifyKey(options);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user