Use nodemailer-openpgp plugin to encrypt verification emails

This commit is contained in:
Tankred Hase
2016-06-02 16:19:54 +02:00
parent e98bd1b431
commit 7179afaf6f
10 changed files with 55 additions and 24 deletions

View File

@@ -24,6 +24,7 @@ const config = require('config');
const router = require('koa-router')();
const openpgp = require('openpgp');
const nodemailer = require('nodemailer');
const openpgpEncrypt = require('nodemailer-openpgp').openpgpEncrypt;
const Mongo = require('./dao/mongo');
const Email = require('./email/email');
const UserId = require('./service/user-id');
@@ -100,12 +101,13 @@ function injectDependencies() {
user: process.env.MONGO_USER || credentials.mongo.user,
password: process.env.MONGO_PASS || credentials.mongo.pass
});
email = new Email(nodemailer);
email = new Email(nodemailer, openpgpEncrypt);
email.init({
host: process.env.SMTP_HOST || credentials.smtp.host,
port: process.env.SMTP_PORT || credentials.smtp.port,
tls: (process.env.SMTP_TLS || credentials.smtp.tls) === 'true',
starttls: (process.env.SMTP_STARTTLS || credentials.smtp.starttls) === 'true',
pgp: (process.env.SMTP_PGP || credentials.smtp.pgp) === 'true',
auth: {
user: process.env.SMTP_USER || credentials.smtp.user,
pass: process.env.SMTP_PASS || credentials.smtp.pass

View File

@@ -29,8 +29,9 @@ class Email {
* Create an instance of the email object.
* @param {Object} mailer An instance of nodemailer
*/
constructor(mailer) {
constructor(mailer, openpgpEncrypt) {
this._mailer = mailer;
this._openpgpEncrypt = openpgpEncrypt;
}
/**
@@ -41,6 +42,7 @@ class Email {
* @param {string} port (optional) SMTP server's SMTP port. Defaults to 465.
* @param {boolean} tls (optional) if TSL should be used. Defaults to true.
* @param {boolean} starttls (optional) force STARTTLS to prevent downgrade attack. Defaults to true.
* @param {boolean} pgp (optional) if outgoing emails are encrypted to the user's public key.
*/
init(options) {
this._transport = this._mailer.createTransport({
@@ -50,6 +52,9 @@ class Email {
secure: (options.tls !== undefined) ? options.tls : true,
requireTLS: (options.starttls !== undefined) ? options.starttls : true,
});
if (options.pgp) {
this._transport.use('stream', this._openpgpEncrypt());
}
this._sender = options.sender;
}
@@ -92,7 +97,8 @@ class Email {
let template = {
subject: options.subject,
text: options.text,
html: options.html
html: options.html,
encryptionKeys: [options.to.publicKeyArmored]
};
let sender = {
from: {

View File

@@ -1,12 +1,12 @@
{
"verifyKey": {
"subject": "Verify Your Key",
"text": "Hello {{name}},\n\nplease click here to verify your key: {{baseUrl}}/api/v1/verify?keyid={{keyid}}&nonce={{nonce}}",
"text": "Hello {{name}},\n\nplease click here to verify your key:\n\n{{baseUrl}}/api/v1/verify?keyid={{keyid}}&nonce={{nonce}}",
"html": ""
},
"verifyRemove": {
"subject": "Verify Key Removal",
"text": "Hello {{name}},\n\nplease click here to verify the removal of your key: {{baseUrl}}/api/v1/verifyRemove?keyid={{keyid}}&nonce={{nonce}}",
"text": "Hello {{name}},\n\nplease click here to verify the removal of your key:\n\n{{baseUrl}}/api/v1/verifyRemove?keyid={{keyid}}&nonce={{nonce}}",
"html": ""
}
}

View File

@@ -69,7 +69,7 @@ class PublicKey {
// store key in database
let userIds = yield this._persisKey(publicKeyArmored, params);
// send mails to verify user ids (send only one if primary email is provided)
yield this._sendVerifyEmail(userIds, primaryEmail, origin);
yield this._sendVerifyEmail(userIds, primaryEmail, origin, publicKeyArmored);
}
/**
@@ -122,17 +122,19 @@ class PublicKey {
/**
* Send verification emails to the public keys user ids for verification.
* If a primary email address is provided only one email will be sent.
* @param {Array} userIds user id documents containg the verification nonces
* @param {string} primaryEmail the public key's primary email address
* @param {Object} origin the server's origin (required for email links)
* @param {Array} userIds user id documents containg the verification nonces
* @param {string} primaryEmail the public key's primary email address
* @param {Object} origin the server's origin (required for email links)
* @param {String} publicKeyArmored The ascii armored pgp key block
* @yield {undefined}
*/
*_sendVerifyEmail(userIds, primaryEmail, origin) {
*_sendVerifyEmail(userIds, primaryEmail, origin, publicKeyArmored) {
let primaryUserId = userIds.find(uid => uid.email === primaryEmail);
if (primaryUserId) {
userIds = [primaryUserId];
}
for (let userId of userIds) {
userId.publicKeyArmored = publicKeyArmored; // set key for encryption
yield this._email.send({ template:tpl.verifyKey, userId, origin });
}
}