From 074dc52e784ee34c5b560270ae8f1a4acb9a57fc Mon Sep 17 00:00:00 2001 From: Esteban Ordano Date: Mon, 27 Oct 2014 10:45:47 -0300 Subject: [PATCH] Add email templates for copay --- package.json | 1 + plugins/config-emailstore.js | 5 +- plugins/emailTemplates/copay.html | 193 +++++++++++++++++++++++++++++ plugins/emailTemplates/copay.plain | 27 ++++ plugins/emailstore.js | 95 ++++++++++---- 5 files changed, 294 insertions(+), 27 deletions(-) create mode 100644 plugins/emailTemplates/copay.html create mode 100644 plugins/emailTemplates/copay.plain diff --git a/package.json b/package.json index 756dc6c..4bf0386 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "glob": "*", "leveldown": "~0.10.0", "levelup": "~0.19.0", + "lodash": "^2.4.1", "microtime": "^0.6.0", "mkdirp": "^0.5.0", "moment": "~2.5.0", diff --git a/plugins/config-emailstore.js b/plugins/config-emailstore.js index dfccb7a..22b8804 100644 --- a/plugins/config-emailstore.js +++ b/plugins/config-emailstore.js @@ -1,9 +1,10 @@ module.exports = { + confirmEmailHost: 'https://insight.bitpay.com', email: { service: 'Gmail', auth: { - user: 'john@gmail.com', - pass: 'mypassword' + user: '', + pass: '' } } }; diff --git a/plugins/emailTemplates/copay.html b/plugins/emailTemplates/copay.html new file mode 100644 index 0000000..0901396 --- /dev/null +++ b/plugins/emailTemplates/copay.html @@ -0,0 +1,193 @@ + + + + + + <%= title%> + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + +

Hi, <%= email %>

+ +

You are now using Insight to store an encrypted Copay backup. This is a free +service that we are providing that you can turn off from Copay's preferences.

+ +

In order to prevent abuse, we need you to confirm that this email is valid and +that you requested this backup. Please follow this link if you agree on +backing up your Copay profile within our servers:

+ +

+ + Confirm your email (click here). +

+

If the above link doesn't work, head to: <%= confirm_url %>

+ +

We would also like you to know that:

+
    + +
  • We only store information encrypted by your Copay app. We can't retrieve your private keys, help you remember the password, or collect any information about your wallet.
  • + +
  • In case that one of our servers is compromised, intruders may be able to brute-force their way into your private keys unless you use a strong password.
  • + +
  • Our code is open source and can be audited here: +
      +
    • https://github.com/bitpay/insight
    • +
    • https://github.com/bitpay/copay
    • +
    +
  • +
+ +

Thanks!

+ +

The Copay Team

+ + + Copay + +
+ + + diff --git a/plugins/emailTemplates/copay.plain b/plugins/emailTemplates/copay.plain new file mode 100644 index 0000000..f6ee162 --- /dev/null +++ b/plugins/emailTemplates/copay.plain @@ -0,0 +1,27 @@ +Hi, <%= email %> + +You are now using Insight to store an encrypted Copay backup. This is a free +service that we are providing that you can turn off from Copay's preferences. + +In order to prevent abuse, we need you to confirm that this email is valid and +that you requested this backup. Please follow this link if you agree on +backing up your Copay profile within our servers: + + <%= confirm_url %> + +We would also like you to take note of these: + + * We only store information encrypted by your Copay app. We can't retrieve + your private keys, help you remember the password, or collect any information + about your wallet. + + * In case of a service compromise, intruders may be able to brute-force their + way into your private keys. Please use a strong password to avoid this. + + * Our code is open source and can be audited here: + https://github.com/bitpay/insight + https://github.com/bitpay/copay + +Thanks! + +The Copay Team diff --git a/plugins/emailstore.js b/plugins/emailstore.js index 18bd0a8..ba6d43c 100644 --- a/plugins/emailstore.js +++ b/plugins/emailstore.js @@ -39,13 +39,15 @@ 'use strict'; -var logger = require('../lib/logger').logger, - levelup = require('levelup'), - async = require('async'), - crypto = require('crypto'), - querystring = require('querystring'), - nodemailer = require('nodemailer'), - globalConfig = require('../config/config'); +var logger = require('../lib/logger').logger; +var levelup = require('levelup'); +var async = require('async'); +var crypto = require('crypto'); +var querystring = require('querystring'); +var nodemailer = require('nodemailer'); +var globalConfig = require('../config/config'); +var _ = require('lodash'); +var fs = require('fs'); var emailPlugin = {}; @@ -104,6 +106,14 @@ emailPlugin.init = function (expressApp, config) { emailPlugin.email = config.emailTransport || nodemailer.createTransport(config.email); + emailPlugin.textTemplate = config.textTemplate || 'copay.plain'; + emailPlugin.htmlTemplate = config.htmlTemplate || 'copay.html'; + emailPlugin.confirmUrl = ( + (config.confirmEmailHost || 'https://insight.bitpay.com') + + globalConfig.apiPrefix + + '/email/validate' + ); + expressApp.post(globalConfig.apiPrefix + '/email/register', emailPlugin.post); expressApp.get(globalConfig.apiPrefix + '/email/retrieve/:email', emailPlugin.get); expressApp.post(globalConfig.apiPrefix + '/email/validate', emailPlugin.validate); @@ -133,27 +143,63 @@ emailPlugin.returnError = function (error, response) { */ emailPlugin.sendVerificationEmail = function (email, secret) { - var emailBody = 'Activation code is ' + secret; // TODO: Use a template! - var emailBodyHTML = '

Activation code is ' + secret + '

'; // TODO: Use a template! - - var mailOptions = { - from: 'Insight Services ', - to: email, - subject: 'Your Insight account has been created', - text: emailBody, - html: emailBodyHTML - }; - - // send mail with defined transport object - emailPlugin.email.sendMail(mailOptions, function (err, info) { - if (err) { - logger.error('An error occurred when trying to send email to ' + email, err); - } else { - logger.debug('Message sent: ' + info.response); + async.series([ + function(callback) { + emailPlugin.makeEmailBody({ + email: email, + confirm_url: emailPlugin.makeConfirmUrl(secret) + }, callback); + }, + function(callback) { + emailPlugin.makeEmailHTMLBody({ + email: email, + confirm_url: emailPlugin.makeConfirmUrl(secret), + title: 'Your wallet backup needs confirmation' + }, callback); } + ], function(err, results) { + var emailBody = results[0]; + var emailBodyHTML = results[1]; + var mailOptions = { + from: 'Insight Services ', + to: email, + subject: '[Copay] Your wallet backup needs confirmation', + text: emailBody, + html: emailBodyHTML + }; + + // send mail with defined transport object + emailPlugin.email.sendMail(mailOptions, function (err, info) { + if (err) { + logger.error('An error occurred when trying to send email to ' + email, err); + } else { + logger.error('Message sent: ' + info.response); + } + }); }); }; +emailPlugin.makeConfirmUrl = function(secret) { + return emailPlugin.confirmUrl + '?secret='+secret; +}; + +/** + * Returns a function that reads an underscore template and uses the `opts` param + * to build an email body + */ +var applyTemplate = function(templateFilename) { + return function(opts, callback) { + fs.readFile(__dirname + '/emailTemplates/' + emailPlugin[templateFilename], + function(err, template) { + return callback(err, _.template(template, opts)); + } + ); + }; +}; + +emailPlugin.makeEmailBody = applyTemplate('textTemplate'); +emailPlugin.makeEmailHTMLBody = applyTemplate('htmlTemplate'); + /** * @param {string} email * @param {Function(err, boolean)} callback @@ -402,7 +448,6 @@ emailPlugin.validate = function (request, response) { } emailPlugin.db.get(VALIDATION_NAMESPACE + email, function (err, value) { - logger.info('Recibido: ' + value); if (err) { if (err.notFound) { return emailPlugin.returnError(emailPlugin.errors.NOT_FOUND, response);