Ghost/core/server/services/members/settings.js
Rish 806d0f8e21 Updated sender address for ownership verification emails to new address
no issue

- We used existing "from" address as sender for mails sent to new email address for verification, but that breaks the flow to update if the current "from" address has DMARC policy set.
- This updates the flow to always send the ownership verification email TO the new address and FROM the new address which both verifies the email deliverability for new address and ownership
2020-08-31 18:09:38 +05:30

108 lines
3.4 KiB
JavaScript

const MagicLink = require('@tryghost/magic-link');
const {URL} = require('url');
const path = require('path');
const urlUtils = require('../../../shared/url-utils');
const settingsCache = require('../settings/cache');
const logging = require('../../../shared/logging');
const mail = require('../mail');
const updateEmailTemplate = require('./emails/updateEmail');
const ghostMailer = new mail.GhostMailer();
function createSettingsInstance(config) {
const {transporter, getSubject, getText, getHTML, getSigninURL} = {
transporter: {
sendMail(message) {
if (process.env.NODE_ENV !== 'production') {
logging.warn(message.text);
}
let msg = Object.assign({
from: config.getAuthEmailFromAddress(),
subject: 'Update email address',
forceTextContent: true
}, message);
return ghostMailer.send(msg);
}
},
getSubject() {
return `Confirm your email address`;
},
getText(url, type, email) {
return `
Hey there,
Please confirm your email address with this link:
${url}
For your security, the link will expire in 10 minutes time.
---
Sent to ${email}
If you did not make this request, you can simply delete this message. This email address will not be used.
`;
},
getHTML(url, type, email) {
const siteTitle = settingsCache.get('title');
return updateEmailTemplate({url, email, siteTitle});
},
getSigninURL(token, type) {
const signinURL = new URL(getApiUrl({version: 'v3', type: 'admin'}));
signinURL.pathname = path.join(signinURL.pathname, '/settings/members/email/');
signinURL.searchParams.set('token', token);
signinURL.searchParams.set('action', type);
return signinURL.href;
}
};
const getApiUrl = ({version, type}) => {
return urlUtils.urlFor('api', {version: version, versionType: type}, true);
};
const magicLinkService = new MagicLink({
transporter,
secret: config.getAuthSecret(),
getSigninURL,
getText,
getHTML,
getSubject
});
const sendEmailAddressUpdateMagicLink = ({email, payload = {}, type = 'fromAddressUpdate'}) => {
magicLinkService.transporter = {
sendMail(message) {
if (process.env.NODE_ENV !== 'production') {
logging.warn(message.text);
}
let msg = Object.assign({
from: email,
subject: 'Update email address',
forceTextContent: true
}, message);
return ghostMailer.send(msg);
}
};
return magicLinkService.sendMagicLink({email, payload, subject: email, type});
};
const getEmailFromToken = ({token}) => {
return magicLinkService.getUserFromToken(token);
};
const getAdminRedirectLink = ({type}) => {
const adminUrl = urlUtils.urlFor('admin', true);
return urlUtils.urlJoin(adminUrl, `#/settings/labs/?${type}=success`);
};
return {
sendEmailAddressUpdateMagicLink,
getEmailFromToken,
getAdminRedirectLink
};
}
module.exports = createSettingsInstance;