Fixed an issue with broken archive link. Added plaintext versions for transactional messages

This commit is contained in:
Andris Reinman 2016-04-08 15:00:54 +03:00
parent 4584c85b4b
commit 06d5e0d9bf
11 changed files with 144 additions and 63 deletions

View file

@ -38,24 +38,39 @@ module.exports.sendMail = (mail, template, callback) => {
}); });
} }
if (!template || !template.template) { getTemplate(template.html, (err, htmlRenderer) => {
return module.exports.transport.sendMail(mail, callback);
}
getTemplate(template.template, (err, renderer) => {
if (err) { if (err) {
return callback(err); return callback(err);
} }
mail.html = renderer(template.data || {});
module.exports.transport.sendMail(mail, callback); if (htmlRenderer) {
mail.html = htmlRenderer(template.data || {});
}
getTemplate(template.text, (err, textRenderer) => {
if (err) {
return callback(err);
}
if (textRenderer) {
mail.text = textRenderer(template.data || {});
}
module.exports.transport.sendMail(mail, callback);
});
}); });
}; };
function getTemplate(template, callback) { function getTemplate(template, callback) {
if (!template) {
return callback(null, false);
}
if (templates.has(template)) { if (templates.has(template)) {
return callback(null, templates.get(template)); return callback(null, templates.get(template));
} }
fs.readFile(path.join(__dirname, '..', 'views', template), 'utf-8', (err, source) => { fs.readFile(path.join(__dirname, '..', 'views', template), 'utf-8', (err, source) => {
if (err) { if (err) {
return callback(err); return callback(err);

View file

@ -218,8 +218,10 @@ module.exports.sendReset = (username, callback) => {
}, },
subject: 'Mailer password change request' subject: 'Mailer password change request'
}, { }, {
template: 'emails/password-reset.hbs', html: 'emails/password-reset-html.hbs',
text: 'emails/password-reset-text.hbs',
data: { data: {
title: 'Mailtrain',
username: rows[0].username, username: rows[0].username,
confirmUrl: urllib.resolve(configItems.serviceUrl, '/users/reset') + '?token=' + encodeURIComponent(resetToken) + '&username=' + encodeURIComponent(rows[0].username) confirmUrl: urllib.resolve(configItems.serviceUrl, '/users/reset') + '?token=' + encodeURIComponent(resetToken) + '&username=' + encodeURIComponent(rows[0].username)
} }

View file

@ -19,8 +19,8 @@
"node" : ">=5.0.0" "node" : ">=5.0.0"
}, },
"devDependencies": { "devDependencies": {
"grunt": "^0.4.5", "grunt": "^1.0.1",
"grunt-cli": "^1.1.0", "grunt-cli": "^1.2.0",
"grunt-contrib-nodeunit": "^1.0.0", "grunt-contrib-nodeunit": "^1.0.0",
"grunt-eslint": "^18.0.0" "grunt-eslint": "^18.0.0"
}, },
@ -28,13 +28,13 @@
"bcrypt-nodejs": "0.0.3", "bcrypt-nodejs": "0.0.3",
"body-parser": "^1.15.0", "body-parser": "^1.15.0",
"compression": "^1.6.1", "compression": "^1.6.1",
"config": "^1.19.0", "config": "^1.20.0",
"connect-flash": "^0.1.1", "connect-flash": "^0.1.1",
"connect-redis": "^3.0.2", "connect-redis": "^3.0.2",
"content-security-policy": "^0.2.0", "content-security-policy": "^0.2.0",
"cookie-parser": "^1.4.1", "cookie-parser": "^1.4.1",
"csurf": "^1.8.3", "csurf": "^1.8.3",
"csv-parse": "^1.0.2", "csv-parse": "^1.0.4",
"escape-html": "^1.0.3", "escape-html": "^1.0.3",
"express": "^4.13.4", "express": "^4.13.4",
"express-session": "^1.13.0", "express-session": "^1.13.0",
@ -46,13 +46,13 @@
"morgan": "^1.7.0", "morgan": "^1.7.0",
"multer": "^1.1.0", "multer": "^1.1.0",
"mysql": "^2.10.2", "mysql": "^2.10.2",
"nodemailer": "^2.3.0", "nodemailer": "^2.3.1",
"npmlog": "^2.0.3", "npmlog": "^2.0.3",
"passport": "^0.3.2", "passport": "^0.3.2",
"passport-local": "^1.0.0", "passport-local": "^1.0.0",
"request": "^2.69.0", "request": "^2.70.0",
"serve-favicon": "^2.3.0", "serve-favicon": "^2.3.0",
"shortid": "^2.2.4", "shortid": "^2.2.6",
"slugify": "^0.1.1", "slugify": "^0.1.1",
"smtp-server": "^1.9.0", "smtp-server": "^1.9.0",
"striptags": "^2.1.1", "striptags": "^2.1.1",

View file

@ -4,6 +4,7 @@ let settings = require('../lib/models/settings');
let campaigns = require('../lib/models/campaigns'); let campaigns = require('../lib/models/campaigns');
let lists = require('../lib/models/lists'); let lists = require('../lib/models/lists');
let subscriptions = require('../lib/models/subscriptions'); let subscriptions = require('../lib/models/subscriptions');
let fields = require('../lib/models/fields');
let tools = require('../lib/tools'); let tools = require('../lib/tools');
let express = require('express'); let express = require('express');
let router = new express.Router(); let router = new express.Router();
@ -51,24 +52,50 @@ router.get('/:campaign/:list/:subscription', (req, res, next) => {
return next(err); return next(err);
} }
campaigns.getMail(campaign.id, list.id, subscription.id, (err, mail) => { fields.list(list.id, (err, fieldList) => {
if (err) { if (err || !fieldList) {
req.flash('danger', err.message || err); return fieldList = [];
return res.redirect('/');
} }
if (!mail) { subscription.mergeTags = {
err = new Error('Not Found'); EMAIL: subscription.email,
err.status = 404; FIRST_NAME: subscription.firstName,
return next(err); LAST_NAME: subscription.lastName,
} FULL_NAME: [].concat(subscription.firstName || []).concat(subscription.lastName || []).join(' ')
};
res.render('archive/view', { fields.getRow(fieldList, subscription, true, true).forEach(field => {
layout: 'archive/layout', if (field.mergeTag) {
message: tools.formatMessage(serviceUrl, campaign, list, subscription, campaign.html), subscription.mergeTags[field.mergeTag] = field.mergeValue || '';
campaign, }
list, if (field.options) {
subscription field.options.forEach(subField => {
if (subField.mergeTag) {
subscription.mergeTags[subField.mergeTag] = subField.mergeValue || '';
}
});
}
});
campaigns.getMail(campaign.id, list.id, subscription.id, (err, mail) => {
if (err) {
req.flash('danger', err.message || err);
return res.redirect('/');
}
if (!mail) {
err = new Error('Not Found');
err.status = 404;
return next(err);
}
res.render('archive/view', {
layout: 'archive/layout',
message: tools.formatMessage(serviceUrl, campaign, list, subscription, campaign.html),
campaign,
list,
subscription
});
}); });
}); });
}); });

View file

@ -209,7 +209,8 @@ router.post('/:cid/subscribe', passport.parseForm, passport.csrfProtection, (req
}, },
subject: list.name + ': Please Confirm Subscription' subject: list.name + ': Please Confirm Subscription'
}, { }, {
template: 'emails/confirm-mail.hbs', html: 'emails/confirm-html.hbs',
text: 'emails/confirm-text.hbs',
data: { data: {
title: list.name, title: list.name,
contactAddress: configItems.defaultAddress, contactAddress: configItems.defaultAddress,

View file

@ -0,0 +1,26 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>{{title}}: Please Confirm Subscription</title>
</head>
<body>
<h1>{{title}}</h1>
<h2>Please Confirm Subscription</h2>
<hr>
<p><a href="{{confirmUrl}}" class="btn-primary" itemprop="url" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; color: #FFF; text-decoration: none; line-height: 2em; font-weight: bold; text-align: center; cursor: pointer; display: inline-block; border-radius: 5px; text-transform: capitalize; background-color: #348eda; margin: 0; border-color: #348eda; border-style: solid; border-width: 10px 20px;">Yes, subscribe me to this list</a></p>
<p>If you received this email by mistake, simply delete it. You won't be subscribed if you don't click the confirmation link above.</p>
<p>For questions about this list, please contact:
<br/>{{contactAddress}}</p>
</body>
</html>

View file

@ -1,18 +0,0 @@
<h1>{{title}}</h1>
<h2>Please Confirm Subscription</h2>
<hr>
<p>
<a href="{{confirmUrl}}" class="btn-primary" itemprop="url" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; color: #FFF; text-decoration: none; line-height: 2em; font-weight: bold; text-align: center; cursor: pointer; display: inline-block; border-radius: 5px; text-transform: capitalize; background-color: #348eda; margin: 0; border-color: #348eda; border-style: solid; border-width: 10px 20px;">Yes, subscribe me to this list</a>
</p>
<p>
If you received this email by mistake, simply delete it. You won't be subscribed if you don't click the confirmation link above.
</p>
<p>
For questions about this list, please contact:
<br/>{{contactAddress}}
</p>

View file

@ -0,0 +1,10 @@
{{{title}}}
Please Confirm Subscription
===========================
Yes, subscribe me to this list: {{{confirmUrl}}}
If you received this email by mistake, simply delete it. You won't be subscribed if you don't click the confirmation link above.
For questions about this list, please contact:
{{{contactAddress}}}

View file

@ -0,0 +1,23 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Change your password</title>
</head>
<body>
<h2>Change your password</h2>
<hr>
<p>We have received a password change request for your Mailtrain account ({{username}}).</p>
<p><a href="{{confirmUrl}}" class="btn-primary" itemprop="url" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; color: #FFF; text-decoration: none; line-height: 2em; font-weight: bold; text-align: center; cursor: pointer; display: inline-block; border-radius: 5px; text-transform: capitalize; background-color: #348eda; margin: 0; border-color: #348eda; border-style: solid; border-width: 10px 20px;">Reset password</a></p>
<p>If you did not ask to change your password, then you can ignore this email and your password will not be changed.</p>
</body>
</html>

View file

@ -0,0 +1,9 @@
{{{title}}}
Change your password
====================
We have received a password change request for your Mailtrain account ({{{username}}}).
Reset password: {{{confirmUrl}}}
If you did not ask to change your password, then you can ignore this email and your password will not be changed.

View file

@ -1,14 +0,0 @@
<h2>Change your password</h2>
<hr>
<p>
We have received a password change request for your Mailtrain account ({{username}}).
</p>
<p>
<a href="{{confirmUrl}}" class="btn-primary" itemprop="url" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; color: #FFF; text-decoration: none; line-height: 2em; font-weight: bold; text-align: center; cursor: pointer; display: inline-block; border-radius: 5px; text-transform: capitalize; background-color: #348eda; margin: 0; border-color: #348eda; border-style: solid; border-width: 10px 20px;">Reset password</a>
</p>
<p>
If you did not ask to change your password, then you can ignore this email and your password will not be changed.
</p>