diff --git a/ghost/core/core/frontend/services/routing/controllers/unsubscribe.js b/ghost/core/core/frontend/services/routing/controllers/unsubscribe.js
index a13e5a846b..41d4396d82 100644
--- a/ghost/core/core/frontend/services/routing/controllers/unsubscribe.js
+++ b/ghost/core/core/frontend/services/routing/controllers/unsubscribe.js
@@ -18,6 +18,9 @@ module.exports = async function unsubscribeController(req, res) {
if (query.newsletter) {
redirectUrl.searchParams.append('newsletter', query.newsletter);
}
+ if (query.comments) {
+ redirectUrl.searchParams.append('comments', query.comments);
+ }
redirectUrl.searchParams.append('action', 'unsubscribe');
return res.redirect(302, redirectUrl.href);
diff --git a/ghost/core/core/server/services/bulk-email/bulk-email-processor.js b/ghost/core/core/server/services/bulk-email/bulk-email-processor.js
index d27a9fd352..37a8f3d753 100644
--- a/ghost/core/core/server/services/bulk-email/bulk-email-processor.js
+++ b/ghost/core/core/server/services/bulk-email/bulk-email-processor.js
@@ -234,7 +234,7 @@ module.exports = {
// static data for every recipient
const data = {
unique_id: recipient.member_uuid,
- unsubscribe_url: postEmailSerializer.createUnsubscribeUrl(recipient.member_uuid, newsletterUuid)
+ unsubscribe_url: postEmailSerializer.createUnsubscribeUrl(recipient.member_uuid, {newsletterUuid})
};
// computed properties on recipients - TODO: better way of handling these
diff --git a/ghost/core/core/server/services/comments/email-templates/new-comment-reply.hbs b/ghost/core/core/server/services/comments/email-templates/new-comment-reply.hbs
index c29d3c37d9..a06eee5ac5 100644
--- a/ghost/core/core/server/services/comments/email-templates/new-comment-reply.hbs
+++ b/ghost/core/core/server/services/comments/email-templates/new-comment-reply.hbs
@@ -174,7 +174,7 @@
- Manage your email preferences
+ Unsubscribe from comment reply notifications
|
diff --git a/ghost/core/core/server/services/comments/email-templates/new-comment-reply.txt.js b/ghost/core/core/server/services/comments/email-templates/new-comment-reply.txt.js
index c215d4c219..d31a6e81df 100644
--- a/ghost/core/core/server/services/comments/email-templates/new-comment-reply.txt.js
+++ b/ghost/core/core/server/services/comments/email-templates/new-comment-reply.txt.js
@@ -9,5 +9,5 @@ ${data.postUrl}#ghost-comments
---
Sent to ${data.toEmail} from ${data.siteDomain}.
-You can manage your notification preferences at ${data.profileUrl}.`;
+You can unsubscribe from these notifications at ${data.profileUrl}.`;
};
diff --git a/ghost/core/core/server/services/comments/emails.js b/ghost/core/core/server/services/comments/emails.js
index 98decd507e..ca739dbafa 100644
--- a/ghost/core/core/server/services/comments/emails.js
+++ b/ghost/core/core/server/services/comments/emails.js
@@ -2,6 +2,7 @@ const {promises: fs} = require('fs');
const path = require('path');
const moment = require('moment');
const htmlToPlaintext = require('@tryghost/html-to-plaintext');
+const postEmailSerializer = require('../mega/post-email-serializer');
class CommentsServiceEmails {
constructor({config, logging, models, mailer, settingsCache, urlService, urlUtils}) {
@@ -93,7 +94,7 @@ class CommentsServiceEmails {
accentColor: this.settingsCache.get('accent_color'),
fromEmail: this.notificationFromAddress,
toEmail: to,
- profileUrl: `${this.urlUtils.getSiteUrl()}#/portal/account/profile`
+ profileUrl: postEmailSerializer.createUnsubscribeUrl(member.get('uuid'), {comments: true})
};
const {html, text} = await this.renderEmailTemplate('new-comment-reply', templateData);
diff --git a/ghost/core/core/server/services/mega/post-email-serializer.js b/ghost/core/core/server/services/mega/post-email-serializer.js
index dad330e4b8..a96d5281e4 100644
--- a/ghost/core/core/server/services/mega/post-email-serializer.js
+++ b/ghost/core/core/server/services/mega/post-email-serializer.js
@@ -59,9 +59,11 @@ const getSite = () => {
* In case of no member uuid, generates the preview unsubscribe url - `?preview=1`
*
* @param {string} uuid post uuid
- * @param {string} newsletterUuid newsletter uuid
+ * @param {Object} [options]
+ * @param {string} [options.newsletterUuid] newsletter uuid
+ * @param {boolean} [options.comments] Unsubscribe from comment emails
*/
-const createUnsubscribeUrl = (uuid, newsletterUuid) => {
+const createUnsubscribeUrl = (uuid, options = {}) => {
const siteUrl = urlUtils.getSiteUrl();
const unsubscribeUrl = new URL(siteUrl);
unsubscribeUrl.pathname = `${unsubscribeUrl.pathname}/unsubscribe/`.replace('//', '/');
@@ -70,8 +72,11 @@ const createUnsubscribeUrl = (uuid, newsletterUuid) => {
} else {
unsubscribeUrl.searchParams.set('preview', '1');
}
- if (newsletterUuid) {
- unsubscribeUrl.searchParams.set('newsletter', newsletterUuid);
+ if (options.newsletterUuid) {
+ unsubscribeUrl.searchParams.set('newsletter', options.newsletterUuid);
+ }
+ if (options.comments) {
+ unsubscribeUrl.searchParams.set('comments', '1');
}
return unsubscribeUrl.href;
diff --git a/ghost/core/core/shared/config/defaults.json b/ghost/core/core/shared/config/defaults.json
index a1b40629f5..7b11e98591 100644
--- a/ghost/core/core/shared/config/defaults.json
+++ b/ghost/core/core/shared/config/defaults.json
@@ -137,7 +137,7 @@
},
"portal": {
"url": "https://cdn.jsdelivr.net/npm/@tryghost/portal@~{version}/umd/portal.min.js",
- "version": "2.7"
+ "version": "2.8"
},
"sodoSearch": {
"url": "https://cdn.jsdelivr.net/npm/@tryghost/sodo-search@~{version}/umd/sodo-search.min.js",
diff --git a/ghost/core/test/unit/server/services/mega/post-email-serializer.test.js b/ghost/core/test/unit/server/services/mega/post-email-serializer.test.js
index b30e27049f..edb56214ed 100644
--- a/ghost/core/test/unit/server/services/mega/post-email-serializer.test.js
+++ b/ghost/core/test/unit/server/services/mega/post-email-serializer.test.js
@@ -236,16 +236,22 @@ describe('Post Email Serializer', function () {
unsubscribeUrl.should.eql('https://site.com/blah/unsubscribe/?preview=1');
});
- it('generates unsubscribe url with only post uuid', function () {
+ it('generates unsubscribe url with only member uuid', function () {
sinon.stub(urlUtils, 'getSiteUrl').returns('https://site.com/blah');
- const unsubscribeUrl = createUnsubscribeUrl('post-abcd');
- unsubscribeUrl.should.eql('https://site.com/blah/unsubscribe/?uuid=post-abcd');
+ const unsubscribeUrl = createUnsubscribeUrl('member-abcd');
+ unsubscribeUrl.should.eql('https://site.com/blah/unsubscribe/?uuid=member-abcd');
});
it('generates unsubscribe url with both post and newsletter uuid', function () {
sinon.stub(urlUtils, 'getSiteUrl').returns('https://site.com/blah');
- const unsubscribeUrl = createUnsubscribeUrl('post-abcd', 'newsletter-abcd');
- unsubscribeUrl.should.eql('https://site.com/blah/unsubscribe/?uuid=post-abcd&newsletter=newsletter-abcd');
+ const unsubscribeUrl = createUnsubscribeUrl('member-abcd', {newsletterUuid: 'newsletter-abcd'});
+ unsubscribeUrl.should.eql('https://site.com/blah/unsubscribe/?uuid=member-abcd&newsletter=newsletter-abcd');
+ });
+
+ it('generates unsubscribe url with comments', function () {
+ sinon.stub(urlUtils, 'getSiteUrl').returns('https://site.com/blah');
+ const unsubscribeUrl = createUnsubscribeUrl('member-abcd', {comments: true});
+ unsubscribeUrl.should.eql('https://site.com/blah/unsubscribe/?uuid=member-abcd&comments=1');
});
});