mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-19 15:48:04 +01:00
feat(email): WIP start implementing unsubscription page and related features
This commit is contained in:
1
common/dist/scripts/habitrpg-shared.js
vendored
1
common/dist/scripts/habitrpg-shared.js
vendored
@@ -7437,7 +7437,6 @@ process.browser = true;
|
||||
process.env = {};
|
||||
process.argv = [];
|
||||
process.version = ''; // empty string to avoid regexp issues
|
||||
process.versions = {};
|
||||
|
||||
function noop() {}
|
||||
|
||||
|
||||
@@ -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){
|
||||
|
||||
33
website/src/controllers/unsubscription.js
Normal file
33
website/src/controllers/unsubscription.js
Normal file
@@ -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!');
|
||||
})
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -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,
|
||||
|
||||
8
website/src/routes/unsubscription.js
Normal file
8
website/src/routes/unsubscription.js
Normal file
@@ -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;
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}))
|
||||
}
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user