2020-06-05 19:20:04 +03:00
|
|
|
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');
|
2021-06-15 17:36:27 +03:00
|
|
|
const logging = require('@tryghost/logging');
|
2020-06-05 19:20:04 +03:00
|
|
|
const mail = require('../mail');
|
|
|
|
const updateEmailTemplate = require('./emails/updateEmail');
|
2020-09-24 20:31:28 +03:00
|
|
|
const SingleUseTokenProvider = require('./SingleUseTokenProvider');
|
|
|
|
const models = require('../../models');
|
2020-09-30 12:53:35 +03:00
|
|
|
const MAGIC_LINK_TOKEN_VALIDITY = 24 * 60 * 60 * 1000;
|
2020-06-05 19:20:04 +03:00
|
|
|
|
|
|
|
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({
|
2020-08-26 11:00:16 +03:00
|
|
|
from: config.getAuthEmailFromAddress(),
|
2020-06-05 19:20:04 +03:00
|
|
|
subject: 'Update email address',
|
|
|
|
forceTextContent: true
|
|
|
|
}, message);
|
|
|
|
|
|
|
|
return ghostMailer.send(msg);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
getSubject() {
|
2020-06-11 15:44:37 +03:00
|
|
|
return `Confirm your email address`;
|
2020-06-05 19:20:04 +03:00
|
|
|
},
|
|
|
|
getText(url, type, email) {
|
|
|
|
return `
|
|
|
|
Hey there,
|
|
|
|
|
2020-06-11 15:44:37 +03:00
|
|
|
Please confirm your email address with this link:
|
2020-06-05 19:20:04 +03:00
|
|
|
|
|
|
|
${url}
|
|
|
|
|
2020-09-30 12:53:35 +03:00
|
|
|
For your security, the link will expire in 24 hours time.
|
2020-06-05 19:20:04 +03:00
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
Sent to ${email}
|
2020-06-11 15:44:37 +03:00
|
|
|
If you did not make this request, you can simply delete this message. This email address will not be used.
|
2020-06-05 19:20:04 +03:00
|
|
|
`;
|
|
|
|
},
|
|
|
|
getHTML(url, type, email) {
|
|
|
|
const siteTitle = settingsCache.get('title');
|
|
|
|
return updateEmailTemplate({url, email, siteTitle});
|
|
|
|
},
|
|
|
|
getSigninURL(token, type) {
|
2021-03-03 04:42:03 +03:00
|
|
|
const signinURL = new URL(getApiUrl({version: 'v4', type: 'admin'}));
|
2020-06-05 19:20:04 +03:00
|
|
|
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,
|
2020-09-24 20:31:28 +03:00
|
|
|
tokenProvider: new SingleUseTokenProvider(models.SingleUseToken, MAGIC_LINK_TOKEN_VALIDITY),
|
2020-06-05 19:20:04 +03:00
|
|
|
getSigninURL,
|
|
|
|
getText,
|
|
|
|
getHTML,
|
|
|
|
getSubject
|
|
|
|
});
|
|
|
|
|
2020-09-24 20:31:28 +03:00
|
|
|
const sendEmailAddressUpdateMagicLink = ({email, type = 'fromAddressUpdate'}) => {
|
2020-09-17 09:50:29 +03:00
|
|
|
const [,toDomain] = email.split('@');
|
|
|
|
let fromEmail = `noreply@${toDomain}`;
|
|
|
|
if (fromEmail === email) {
|
|
|
|
fromEmail = `no-reply@${toDomain}`;
|
|
|
|
}
|
2020-08-26 11:14:44 +03:00
|
|
|
magicLinkService.transporter = {
|
|
|
|
sendMail(message) {
|
|
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
|
|
logging.warn(message.text);
|
|
|
|
}
|
|
|
|
let msg = Object.assign({
|
2020-09-17 09:50:29 +03:00
|
|
|
from: fromEmail,
|
2020-08-26 11:14:44 +03:00
|
|
|
subject: 'Update email address',
|
|
|
|
forceTextContent: true
|
|
|
|
}, message);
|
|
|
|
|
|
|
|
return ghostMailer.send(msg);
|
|
|
|
}
|
|
|
|
};
|
2020-09-24 20:31:28 +03:00
|
|
|
return magicLinkService.sendMagicLink({email, tokenData: {email}, subject: email, type});
|
2020-06-05 19:20:04 +03:00
|
|
|
};
|
|
|
|
|
2020-09-24 20:31:28 +03:00
|
|
|
const getEmailFromToken = async ({token}) => {
|
|
|
|
const data = await magicLinkService.getDataFromToken(token);
|
|
|
|
return data.email;
|
2020-06-05 19:20:04 +03:00
|
|
|
};
|
|
|
|
|
2020-08-26 10:45:01 +03:00
|
|
|
const getAdminRedirectLink = ({type}) => {
|
2020-06-05 19:20:04 +03:00
|
|
|
const adminUrl = urlUtils.urlFor('admin', true);
|
2021-03-23 08:54:07 +03:00
|
|
|
return urlUtils.urlJoin(adminUrl, `#/settings/members-email/?${type}=success`);
|
2020-06-05 19:20:04 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
return {
|
2020-08-26 10:45:01 +03:00
|
|
|
sendEmailAddressUpdateMagicLink,
|
2020-06-05 19:20:04 +03:00
|
|
|
getEmailFromToken,
|
|
|
|
getAdminRedirectLink
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = createSettingsInstance;
|