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
+
+
+
+
+ |
+
+
+
+
+
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);