From 7d735519ecfe7a28b61c991537f22ee5b9bc904d Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Thu, 26 Mar 2015 20:00:23 +0100 Subject: [PATCH 01/11] feat(email-unsubscription-page): create model to hold unsubscriptions --- website/src/models/emailUnsubscription.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 website/src/models/emailUnsubscription.js diff --git a/website/src/models/emailUnsubscription.js b/website/src/models/emailUnsubscription.js new file mode 100644 index 0000000000..cfc6b02502 --- /dev/null +++ b/website/src/models/emailUnsubscription.js @@ -0,0 +1,13 @@ +var mongoose = require("mongoose"); +var shared = require('../../../common'); + +var EmailUnsubscriptionSchema = new mongoose.Schema({ + _id: { + type: String, + 'default': shared.uuid + }, + email: String +}); + +module.exports.schema = EmailUnsubscriptionSchema; +module.exports.model = mongoose.model('EmailUnsubscription', EmailUnsubscriptionSchema); \ No newline at end of file From 71108ee935f58701ecadceb3bd43de26cd428eb9 Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Fri, 3 Apr 2015 13:26:20 +0200 Subject: [PATCH 02/11] feat(email): WIP start implementing unsubscription page and related features --- common/dist/scripts/habitrpg-shared.js | 1 - website/src/controllers/auth.js | 12 ++++-- website/src/controllers/unsubscription.js | 33 ++++++++++++++++ website/src/models/emailUnsubscription.js | 1 + website/src/routes/unsubscription.js | 8 ++++ website/src/server.js | 1 + website/src/utils.js | 46 +++++++++++++++++------ 7 files changed, 85 insertions(+), 17 deletions(-) create mode 100644 website/src/controllers/unsubscription.js create mode 100644 website/src/routes/unsubscription.js diff --git a/common/dist/scripts/habitrpg-shared.js b/common/dist/scripts/habitrpg-shared.js index e0c5bc83ce..d81443b13c 100644 --- a/common/dist/scripts/habitrpg-shared.js +++ b/common/dist/scripts/habitrpg-shared.js @@ -7437,7 +7437,6 @@ process.browser = true; process.env = {}; process.argv = []; process.version = ''; // empty string to avoid regexp issues -process.versions = {}; function noop() {} diff --git a/website/src/controllers/auth.js b/website/src/controllers/auth.js index 25681d9474..0add5f5aee 100644 --- a/website/src/controllers/auth.js +++ b/website/src/controllers/auth.js @@ -109,9 +109,11 @@ api.registerUser = function(req, res, next) { newUser.preferences = newUser.preferences || {}; newUser.preferences.language = req.language; // User language detected from browser, not saved var user = new User(newUser); - utils.txnEmail(user, 'welcome'); ga.event('register', 'Local').send(); - user.save(cb); + user.save(function(err, savedUser){ + utils.txnEmail(savedUser, 'welcome'); + cb(err, savedUser); + }); } }] }, function(err, data) { @@ -178,9 +180,11 @@ api.loginSocial = function(req, res, next) { }; user.auth[network] = prof; user = new User(user); - user.save(cb); + user.save(function(err, savedUser){ + utils.txnEmail(savedUser, 'welcome'); + cb(err, savedUser); + }); - utils.txnEmail(user, 'welcome'); ga.event('register', network).send(); }] }, function(err, results){ diff --git a/website/src/controllers/unsubscription.js b/website/src/controllers/unsubscription.js new file mode 100644 index 0000000000..fde41c3cee --- /dev/null +++ b/website/src/controllers/unsubscription.js @@ -0,0 +1,33 @@ +var User = require('../models/user'); +var EmailUnsubscription = require('../models/emailUnsubscription'); +var utils = require('../utils'); + +var api = module.exports = {}; + +api.unsubscribe = function(req, res, next){ + if(!req.query.code) return next(new Error('Missing unsubscription code.')); + + var data = JSON.parse(utils.decrypt(req.query.code)); + + if(data._id){ + User.update({_id: data._id}, { + $set: {} + }, {multi: false}, function(err, nAffected){ + if(err) return next(err); + if(nAffected !== 1) return next(new Error('User not found')); + + res.send('Unsubscribed!'); + }); + }else{ + EmailUnsubscription.findOne({email: data.email}, function(err, res){ + if(err) return next(err); + if(res) return next(new Error('Email address already unsubscribed')); + + EmailUnsubscription.create({email: data.email}, function(err, res){ + if(err) return next(err); + + res.send('Unsubscribed!'); + }) + }); + } +}; \ No newline at end of file diff --git a/website/src/models/emailUnsubscription.js b/website/src/models/emailUnsubscription.js index cfc6b02502..144417f3fc 100644 --- a/website/src/models/emailUnsubscription.js +++ b/website/src/models/emailUnsubscription.js @@ -1,6 +1,7 @@ var mongoose = require("mongoose"); var shared = require('../../../common'); +// A collection used to store mailing list unsubscription for non registered email addresses var EmailUnsubscriptionSchema = new mongoose.Schema({ _id: { type: String, diff --git a/website/src/routes/unsubscription.js b/website/src/routes/unsubscription.js new file mode 100644 index 0000000000..efd06f9197 --- /dev/null +++ b/website/src/routes/unsubscription.js @@ -0,0 +1,8 @@ +var express = require('express'); +var router = new express.Router(); +var i18n = require('../i18n'); +var unsubscription = require('../controllers/unsubscription'); + +router.get('/unsubscribe', i18n.getUserLanguage, unsubscription.unsubscribe); + +module.exports = router; \ No newline at end of file diff --git a/website/src/server.js b/website/src/server.js index 1c3484d776..1447823a4d 100644 --- a/website/src/server.js +++ b/website/src/server.js @@ -127,6 +127,7 @@ if (cores!==0 && cluster.isMaster && (isDev || isProd)) { app.use(require('./routes/payments').middleware); app.use(require('./routes/auth').middleware); app.use(require('./routes/coupon').middleware); + app.use(require('./routes/unsubscription').middleware); var v2 = express(); app.use('/api/v2', v2); app.use('/api/v1', require('./routes/apiv1').middleware); diff --git a/website/src/utils.js b/website/src/utils.js index 6349ca5d3e..0cfa22b5c7 100644 --- a/website/src/utils.js +++ b/website/src/utils.js @@ -44,6 +44,10 @@ function getUserInfo(user, fields) { } } + if(fields.indexOf('_id') != -1){ + info._id = user._id; + } + if(fields.indexOf('canSend') != -1){ info.canSend = user.preferences.emailNotifications.unsubscribeFromAll !== true; } @@ -62,37 +66,55 @@ module.exports.txnEmail = function(mailingInfoArray, emailType, variables, perso // It's important to pass at least a user with its `preferences` as we need to check if he unsubscribed mailingInfoArray = mailingInfoArray.map(function(mailingInfo){ - return mailingInfo._id ? getUserInfo(mailingInfo, ['email', 'name', 'canSend']) : mailingInfo; + return mailingInfo._id ? getUserInfo(mailingInfo, ['_id', 'email', 'name', 'canSend']) : mailingInfo; }).filter(function(mailingInfo){ // Always send reset-password emails return (mailingInfo.email && (mailingInfo.canSend || emailType === 'reset-password')); }); // Personal variables are personal to each email recipient, if they are missing - // we manually create a structure for them with RECIPIENT_NAME - // otherwise we just add RECIPIENT_NAME to the existing personal variables + // we manually create a structure for them with RECIPIENT_NAME and RECIPIENT_ID + // otherwise we just add RECIPIENT_NAME and RECIPIENT_ID to the existing personal variables if(!personalVariables || personalVariables.length === 0){ personalVariables = mailingInfoArray.map(function(mailingInfo){ return { rcpt: mailingInfo.email, - vars: [{ - name: 'RECIPIENT_NAME', - content: mailingInfo.name - }] + vars: [ + { + name: 'RECIPIENT_NAME', + content: mailingInfo.name + }, + { + name: 'RECIPIENT_UNSUB_URL_PARAM', + content: module.exports.encrypt(JSON.stringify({_id: mailingInfo._id, email: mailingInfo.email})) + } + ] } }); }else{ var temporaryPersonalVariables = {}; mailingInfoArray.forEach(function(mailingInfo){ - temporaryPersonalVariables[mailingInfo.email] = mailingInfo.name; + temporaryPersonalVariables[mailingInfo.email] = { + name: mailingInfo.name, + _id: mailingInfo._id + } }); personalVariables.forEach(function(singlePersonalVariables){ - singlePersonalVariables.vars.push({ - name: 'RECIPIENT_NAME', - content: temporaryPersonalVariables[singlePersonalVariables.rcpt] - }); + singlePersonalVariables.vars.push( + { + name: 'RECIPIENT_NAME', + content: temporaryPersonalVariables[singlePersonalVariables.rcpt].name + }, + { + name: 'RECIPIENT_UNSUB_URL_PARAM', + content: module.exports.encrypt(JSON.stringify({ + _id: temporaryPersonalVariables[singlePersonalVariables.rcpt]._id, + email: singlePersonalVariables.rcpt + })) + } + ) }); } From a7c789746aef19edb3514be62cfb351d337a93b0 Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Fri, 3 Apr 2015 14:48:30 +0200 Subject: [PATCH 03/11] fix error when signing up --- website/src/controllers/auth.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/src/controllers/auth.js b/website/src/controllers/auth.js index 0add5f5aee..f92122f0ba 100644 --- a/website/src/controllers/auth.js +++ b/website/src/controllers/auth.js @@ -112,7 +112,7 @@ api.registerUser = function(req, res, next) { ga.event('register', 'Local').send(); user.save(function(err, savedUser){ utils.txnEmail(savedUser, 'welcome'); - cb(err, savedUser); + cb.apply(this, arguments); }); } }] @@ -182,7 +182,7 @@ api.loginSocial = function(req, res, next) { user = new User(user); user.save(function(err, savedUser){ utils.txnEmail(savedUser, 'welcome'); - cb(err, savedUser); + cb.apply(this, arguments); }); ga.event('register', network).send(); From ab1b75b655b71e393e7a18fdc40b2d20bbf987c7 Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Fri, 3 Apr 2015 16:31:59 +0200 Subject: [PATCH 04/11] finalize unsubscription page --- common/locales/en/settings.json | 3 +++ website/src/controllers/unsubscription.js | 23 +++++++++++++---------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/common/locales/en/settings.json b/common/locales/en/settings.json index d182b5940b..db4bf0953e 100644 --- a/common/locales/en/settings.json +++ b/common/locales/en/settings.json @@ -98,6 +98,9 @@ "invitedQuest": "Invited to Quest", "kickedGroup": "Kicked from group", "remindersToLogin": "Reminders to check in to HabitRPG", + "unsubscribedSuccessfully": "Unsubscribed successfully!", + "unsubscribedTextUsers": "You have successfully unsubscribed from all HabitRPG emails. You can enable only the emails you want to receive from the settings (requires login).", + "unsubscribedTextOthers": "You won't receive any other email from HabitRPG.", "unsubscribeAllEmails": "Check to Unsubscribe from Emails", "unsubscribeAllEmailsText": "By checking this box, I certify that I understand that by unsubscribing from all emails, HabitRPG will never be able to notify me via email about important changes to the site or my account.", "correctlyUnsubscribedEmailType": "Correctly unsubscribed from \"<%= emailType %>\" emails.", diff --git a/website/src/controllers/unsubscription.js b/website/src/controllers/unsubscription.js index fde41c3cee..d0ef89f920 100644 --- a/website/src/controllers/unsubscription.js +++ b/website/src/controllers/unsubscription.js @@ -1,32 +1,35 @@ -var User = require('../models/user'); -var EmailUnsubscription = require('../models/emailUnsubscription'); +var User = require('../models/user').model; +var EmailUnsubscription = require('../models/emailUnsubscription').model; var utils = require('../utils'); +var i18n = require('../../../common').i18n; var api = module.exports = {}; api.unsubscribe = function(req, res, next){ - if(!req.query.code) return next(new Error('Missing unsubscription code.')); + if(!req.query.code) return res.json(500, {err: 'Missing unsubscription code.'}); var data = JSON.parse(utils.decrypt(req.query.code)); if(data._id){ User.update({_id: data._id}, { - $set: {} + $set: {'preferences.emailNotifications.unsubscribeFromAll': true} }, {multi: false}, function(err, nAffected){ if(err) return next(err); - if(nAffected !== 1) return next(new Error('User not found')); + if(nAffected !== 1) return res.json(404, {err: 'User not found'}); - res.send('Unsubscribed!'); + res.send('

' + i18n.t('unsubscribedSuccessfully', null, req.language) + '

' + i18n.t('unsubscribedTextUsers', null, req.language)); }); }else{ - EmailUnsubscription.findOne({email: data.email}, function(err, res){ + EmailUnsubscription.findOne({email: data.email}, function(err, doc){ if(err) return next(err); - if(res) return next(new Error('Email address already unsubscribed')); + var okRes = '

' + i18n.t('unsubscribedSuccessfully', null, req.language) + '

' + i18n.t('unsubscribedTextOthers', null, req.language); + + if(doc) return res.send(okRes); - EmailUnsubscription.create({email: data.email}, function(err, res){ + EmailUnsubscription.create({email: data.email}, function(err, doc){ if(err) return next(err); - res.send('Unsubscribed!'); + res.send(okRes); }) }); } From 9e95f9c17d266c9a0134ae6b6aefe8d73808ac34 Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Fri, 3 Apr 2015 16:37:40 +0200 Subject: [PATCH 05/11] pass entire unsubscription url to email server --- website/src/utils.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/website/src/utils.js b/website/src/utils.js index 0cfa22b5c7..e745b90090 100644 --- a/website/src/utils.js +++ b/website/src/utils.js @@ -85,8 +85,11 @@ module.exports.txnEmail = function(mailingInfoArray, emailType, variables, perso content: mailingInfo.name }, { - name: 'RECIPIENT_UNSUB_URL_PARAM', - content: module.exports.encrypt(JSON.stringify({_id: mailingInfo._id, email: mailingInfo.email})) + name: 'RECIPIENT_UNSUB_URL', + content: baseUrl + '/unsubscribe?code=' + module.exports.encrypt(JSON.stringify({ + _id: mailingInfo._id, + email: mailingInfo.email + })) } ] } @@ -108,9 +111,9 @@ module.exports.txnEmail = function(mailingInfoArray, emailType, variables, perso content: temporaryPersonalVariables[singlePersonalVariables.rcpt].name }, { - name: 'RECIPIENT_UNSUB_URL_PARAM', - content: module.exports.encrypt(JSON.stringify({ - _id: temporaryPersonalVariables[singlePersonalVariables.rcpt]._id, + name: 'RECIPIENT_UNSUB_URL', + content: baseUrl + '/unsubscribe?code=' + module.exports.encrypt(JSON.stringify({ + _id: temporaryPersonalVariables[singlePersonalVariables.rcpt]._id, email: singlePersonalVariables.rcpt })) } From e6c1a72c395c38875287476922e94646714bf1b2 Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Fri, 3 Apr 2015 16:55:56 +0200 Subject: [PATCH 06/11] use callback itself as context --- website/src/controllers/auth.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/src/controllers/auth.js b/website/src/controllers/auth.js index f92122f0ba..335b5baaa1 100644 --- a/website/src/controllers/auth.js +++ b/website/src/controllers/auth.js @@ -112,7 +112,7 @@ api.registerUser = function(req, res, next) { ga.event('register', 'Local').send(); user.save(function(err, savedUser){ utils.txnEmail(savedUser, 'welcome'); - cb.apply(this, arguments); + cb.apply(cb, arguments); }); } }] @@ -182,7 +182,7 @@ api.loginSocial = function(req, res, next) { user = new User(user); user.save(function(err, savedUser){ utils.txnEmail(savedUser, 'welcome'); - cb.apply(this, arguments); + cb.apply(cb, arguments); }); ga.event('register', network).send(); From 16e67ab7d467033d11581334aaf07c92c384bff6 Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Sat, 4 Apr 2015 12:52:47 +0200 Subject: [PATCH 07/11] put password resets back to email server, check for non registered users unsubscriptions --- website/src/controllers/auth.js | 11 ++++------- website/src/controllers/groups.js | 13 ++++++++++--- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/website/src/controllers/auth.js b/website/src/controllers/auth.js index 335b5baaa1..0eed586c94 100644 --- a/website/src/controllers/auth.js +++ b/website/src/controllers/auth.js @@ -221,13 +221,10 @@ api.resetPassword = function(req, res, next){ if (!user) return res.send(401, {err:"Couldn't find a user registered for email " + email}); user.auth.local.salt = salt; user.auth.local.hashed_password = hashed_password; - utils.sendEmail({ - from: "HabitRPG ", - to: email, - subject: "Password Reset for HabitRPG", - text: "Password for " + user.auth.local.username + " has been reset to " + newPassword + ". Log in at " + nconf.get('BASE_URL') + ". After you've logged in, head to "+nconf.get('BASE_URL')+"/#/options/settings/settings and change your password.", - html: "Password for " + user.auth.local.username + " has been reset to " + newPassword + ". Log in at " + nconf.get('BASE_URL') + ". After you've logged in, head to "+nconf.get('BASE_URL')+"/#/options/settings/settings and change your password." - }); + utils.txnEmail(user, 'reset-password', [ + {name: "NEW_PASSWORD", content: newPassword}, + {name: "USERNAME", content: user.auth.local.username} + ]); user.save(function(err){ if(err) return next(err); res.send('New password sent to '+ email); diff --git a/website/src/controllers/groups.js b/website/src/controllers/groups.js index 4e2a93d79f..248675ac8b 100644 --- a/website/src/controllers/groups.js +++ b/website/src/controllers/groups.js @@ -12,6 +12,7 @@ var shared = require('../../../common'); var User = require('./../models/user').model; var Group = require('./../models/group').model; var Challenge = require('./../models/challenge').model; +var EmailUnsubscription = require('./../models/emailUnsubscription').model; var isProd = nconf.get('NODE_ENV') === 'production'; var api = module.exports; @@ -623,10 +624,16 @@ var inviteByEmails = function(invites, group, req, res, next){ } // TODO implement "users can only be invited once" - invite.canSend = true; // Requested by utils.txnEmail - utils.txnEmail(invite, ('invite-friend' + (group.type == 'guild' ? '-guild' : '')), variables); + // Check for the email address not to be unsubscribed - cb(); + EmailUnsubscription.findOne({email: invite.email}, function(err, unsubscribed){ + if(err) return cb(err); + if(unsubscribed) return cb(); + + utils.txnEmail(invite, ('invite-friend' + (group.type == 'guild' ? '-guild' : '')), variables); + + cb(); + }) }); }else{ cb(); From b2ffbf4113f3cca68402aca7cbbff2738585dbb1 Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Tue, 7 Apr 2015 15:53:26 +0200 Subject: [PATCH 08/11] password resets back to nodemailer... --- website/src/controllers/auth.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/website/src/controllers/auth.js b/website/src/controllers/auth.js index 0eed586c94..335b5baaa1 100644 --- a/website/src/controllers/auth.js +++ b/website/src/controllers/auth.js @@ -221,10 +221,13 @@ api.resetPassword = function(req, res, next){ if (!user) return res.send(401, {err:"Couldn't find a user registered for email " + email}); user.auth.local.salt = salt; user.auth.local.hashed_password = hashed_password; - utils.txnEmail(user, 'reset-password', [ - {name: "NEW_PASSWORD", content: newPassword}, - {name: "USERNAME", content: user.auth.local.username} - ]); + utils.sendEmail({ + from: "HabitRPG ", + to: email, + subject: "Password Reset for HabitRPG", + text: "Password for " + user.auth.local.username + " has been reset to " + newPassword + ". Log in at " + nconf.get('BASE_URL') + ". After you've logged in, head to "+nconf.get('BASE_URL')+"/#/options/settings/settings and change your password.", + html: "Password for " + user.auth.local.username + " has been reset to " + newPassword + ". Log in at " + nconf.get('BASE_URL') + ". After you've logged in, head to "+nconf.get('BASE_URL')+"/#/options/settings/settings and change your password." + }); user.save(function(err){ if(err) return next(err); res.send('New password sent to '+ email); From d21fb41aeff3e72c6befa7c47a9012f96fd0a47b Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Tue, 7 Apr 2015 16:04:33 +0200 Subject: [PATCH 09/11] when signing up, delete previous email preferences --- website/src/controllers/auth.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/website/src/controllers/auth.js b/website/src/controllers/auth.js index 335b5baaa1..a21d4ebc76 100644 --- a/website/src/controllers/auth.js +++ b/website/src/controllers/auth.js @@ -7,6 +7,7 @@ var utils = require('../utils'); var nconf = require('nconf'); var request = require('request'); var User = require('../models/user').model; +var EmailUnsubscription = require('../models/emailUnsubscription').model; var ga = require('./../utils').ga; var i18n = require('./../i18n'); @@ -111,7 +112,10 @@ api.registerUser = function(req, res, next) { var user = new User(newUser); ga.event('register', 'Local').send(); user.save(function(err, savedUser){ - utils.txnEmail(savedUser, 'welcome'); + // Clean previous email preferences + EmailUnsubscription.remove({email: savedUser.auth.local.email}, function(){ + utils.txnEmail(savedUser, 'welcome'); + }); cb.apply(cb, arguments); }); } @@ -181,7 +185,12 @@ api.loginSocial = function(req, res, next) { user.auth[network] = prof; user = new User(user); user.save(function(err, savedUser){ - utils.txnEmail(savedUser, 'welcome'); + // Clean previous email preferences + if(savedUser.auth.facebook.emails && savedUser.auth.facebook.emails[0] && savedUser.auth.facebook.emails[0].value){ + EmailUnsubscription.remove({email: savedUser.auth.facebook.emails[0].value}, function(){ + utils.txnEmail(savedUser, 'welcome'); + }); + } cb.apply(cb, arguments); }); From f12f2b201ac0efcef1ed22cb083156d752f11903 Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Tue, 7 Apr 2015 16:07:52 +0200 Subject: [PATCH 10/11] typos --- website/src/controllers/groups.js | 3 +-- website/src/utils.js | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/website/src/controllers/groups.js b/website/src/controllers/groups.js index 248675ac8b..f93bf9c47f 100644 --- a/website/src/controllers/groups.js +++ b/website/src/controllers/groups.js @@ -625,7 +625,6 @@ var inviteByEmails = function(invites, group, req, res, next){ // TODO implement "users can only be invited once" // Check for the email address not to be unsubscribed - EmailUnsubscription.findOne({email: invite.email}, function(err, unsubscribed){ if(err) return cb(err); if(unsubscribed) return cb(); @@ -633,7 +632,7 @@ var inviteByEmails = function(invites, group, req, res, next){ utils.txnEmail(invite, ('invite-friend' + (group.type == 'guild' ? '-guild' : '')), variables); cb(); - }) + }); }); }else{ cb(); diff --git a/website/src/utils.js b/website/src/utils.js index e745b90090..bfb550e146 100644 --- a/website/src/utils.js +++ b/website/src/utils.js @@ -73,8 +73,8 @@ module.exports.txnEmail = function(mailingInfoArray, emailType, variables, perso }); // Personal variables are personal to each email recipient, if they are missing - // we manually create a structure for them with RECIPIENT_NAME and RECIPIENT_ID - // otherwise we just add RECIPIENT_NAME and RECIPIENT_ID to the existing personal variables + // we manually create a structure for them with RECIPIENT_NAME and RECIPIENT_UNSUB_URL + // otherwise we just add RECIPIENT_NAME and RECIPIENT_UNSUB_URL to the existing personal variables if(!personalVariables || personalVariables.length === 0){ personalVariables = mailingInfoArray.map(function(mailingInfo){ return { From 804b7b20c750754ae3694e2ccad33ecc3b337d67 Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Wed, 8 Apr 2015 19:07:36 +0200 Subject: [PATCH 11/11] fix email sending for non registered users --- website/src/utils.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/src/utils.js b/website/src/utils.js index bfb550e146..c2e0085087 100644 --- a/website/src/utils.js +++ b/website/src/utils.js @@ -69,7 +69,8 @@ module.exports.txnEmail = function(mailingInfoArray, emailType, variables, perso return mailingInfo._id ? getUserInfo(mailingInfo, ['_id', 'email', 'name', 'canSend']) : mailingInfo; }).filter(function(mailingInfo){ // Always send reset-password emails - return (mailingInfo.email && (mailingInfo.canSend || emailType === 'reset-password')); + // Don't check canSend for non registered users as already checked before + return (mailingInfo.email && ((!mailingInfo._id || mailingInfo.canSend) || emailType === 'reset-password')); }); // Personal variables are personal to each email recipient, if they are missing