diff --git a/core/frontend/services/routing/controllers/unsubscribe.js b/core/frontend/services/routing/controllers/unsubscribe.js index cca2a07fa7..5d393505c6 100644 --- a/core/frontend/services/routing/controllers/unsubscribe.js +++ b/core/frontend/services/routing/controllers/unsubscribe.js @@ -1,11 +1,33 @@ const debug = require('@tryghost/debug')('services:routing:controllers:unsubscribe'); const path = require('path'); +const url = require('url'); + +const urlUtils = require('../../../../shared/url-utils'); const megaService = require('../../../../server/services/mega'); const renderer = require('../../rendering'); +const labs = require('../../../../shared/labs'); module.exports = async function unsubscribeController(req, res) { debug('unsubscribeController'); + if (labs.isSet('multipleNewslettersUI')) { + const {query} = url.parse(req.url, true); + + if (!query || !query.uuid) { + res.writeHead(400); + return res.end('Email address not found.'); + } + + const redirectUrl = new URL(urlUtils.urlFor('home', true)); + redirectUrl.searchParams.append('uuid', query.uuid); + if (query.newsletter) { + redirectUrl.searchParams.append('newsletter', query.newsletter); + } + redirectUrl.searchParams.append('action', 'unsubscribe'); + + return res.redirect(302, redirectUrl.href); + } + let data = {}; try { diff --git a/test/e2e-frontend/members.test.js b/test/e2e-frontend/members.test.js index 75b35f8b2f..139563f91b 100644 --- a/test/e2e-frontend/members.test.js +++ b/test/e2e-frontend/members.test.js @@ -9,6 +9,7 @@ const settingsCache = require('../../core/shared/settings-cache'); const DomainEvents = require('@tryghost/domain-events'); const {MemberPageViewEvent} = require('@tryghost/member-events'); const models = require('../../core/server/models'); +const {mockManager} = require('../utils/e2e-framework'); function assertContentIsPresent(res) { res.text.should.containEql('

markdown

'); @@ -129,6 +130,33 @@ describe('Front-end members behaviour', function () { }); }); + describe('Unsubscribe', function () { + beforeEach(function () { + mockManager.mockLabsEnabled('multipleNewslettersUI'); + }); + + afterEach(function () { + mockManager.restore(); + }); + + it('should redirect with uuid and action param', async function () { + await request.get('/unsubscribe/?uuid=XXX') + .expect(302) + .expect('Location', 'http://127.0.0.1:2369/?uuid=XXX&action=unsubscribe'); + }); + + it('should pass through an optional newsletter param', async function () { + await request.get('/unsubscribe/?uuid=XXX&newsletter=YYY') + .expect(302) + .expect('Location', 'http://127.0.0.1:2369/?uuid=XXX&newsletter=YYY&action=unsubscribe'); + }); + + it('should reject when missing a uuid', async function () { + await request.get('/unsubscribe/') + .expect(400); + }); + }); + describe('Price data', function () { it('Can be used as a number, and with the price helper', async function () { // Check out test/utils/fixtures/themes/price-data-test-theme/index.hbs