UNPKG

ghost

Version:

The professional publishing platform

83 lines (73 loc) 3.31 kB
const debug = require('@tryghost/debug')('services:routing:controllers:unsubscribe'); const url = require('url'); const members = require('../../../../server/services/members'); const urlUtils = require('../../../../shared/url-utils'); const logging = require('@tryghost/logging'); const settingsHelpers = require('../../../../server/services/settings-helpers'); const crypto = require('crypto'); module.exports = async function unsubscribeController(req, res) { debug('unsubscribeController'); const {query} = url.parse(req.url, true); if (!query || !query.uuid) { res.writeHead(400); return res.end('Email address not found.'); } if (req.method === 'POST') { logging.info('[List-Unsubscribe] Received POST unsubscribe for ' + query.uuid + ', newsletter: ' + (query.newsletter ?? 'null') + ', comments: ' + (query.comments ?? 'false')); // Do an actual unsubscribe try { if (!query.key) { logging.warn('[List-Unsubscribe] Unsubscribe failed due to missing verification key for ' + query.uuid); return res.status(400).end(); } const membersKey = settingsHelpers.getMembersValidationKey(); const memberHmac = crypto.createHmac('sha256', membersKey).update(query.uuid).digest('hex'); if (memberHmac !== query.key) { logging.warn('[List-Unsubscribe] Unsubscribe failed due to invalid key for ' + query.uuid); return res.status(400).end(); } const member = await members.api.members.get({uuid: query.uuid}, {withRelated: ['newsletters']}); if (member) { if (query.comments) { // Unsubscribe from comments await members.api.members.update({ enable_comment_notifications: false }, { id: member.id }); } else { const filteredNewsletters = query.newsletter ? member.related('newsletters').models .filter(n => n.get('uuid') !== query.newsletter) .map(n => ({id: n.id})) : []; await members.api.members.update({ newsletters: filteredNewsletters }, { id: member.id }); } } } catch (e) { logging.error({ err: e, message: '[List-Unsubscribe] Failed POST unsubscribe for ' + query.uuid }); return res.status(400).end(); } return res.status(201).end(); } const redirectUrl = new URL(urlUtils.urlFor('home', true)); redirectUrl.searchParams.append('uuid', query.uuid); if (query.newsletter) { redirectUrl.searchParams.append('newsletter', query.newsletter); } if (query.comments) { redirectUrl.searchParams.append('comments', query.comments); } if (query.key) { redirectUrl.searchParams.append('key', query.key); } redirectUrl.searchParams.append('action', 'unsubscribe'); return res.redirect(302, redirectUrl.href); };