Ghost/core/server/services/members/api.js
2019-11-08 17:21:20 +07:00

238 lines
7.3 KiB
JavaScript

const settingsCache = require('../settings/cache');
const MembersApi = require('@tryghost/members-api');
const common = require('../../lib/common');
const mail = require('../mail');
const models = require('../../models');
const signinEmail = require('./emails/signin');
const signupEmail = require('./emails/signup');
const subscribeEmail = require('./emails/subscribe');
const config = require('./config');
async function createMember({email, name, note}, options = {}) {
const model = await models.Member.add({
email,
name: name || null,
note: note || null
});
const member = model.toJSON(options);
return member;
}
async function getMember(data, options = {}) {
if (!data.email && !data.id && !data.uuid) {
return Promise.resolve(null);
}
const model = await models.Member.findOne(data, options);
if (!model) {
return null;
}
const member = model.toJSON(options);
return member;
}
async function setMetadata(module, metadata) {
if (module !== 'stripe') {
return;
}
if (metadata.customer) {
await models.MemberStripeCustomer.upsert(metadata.customer, {
customer_id: metadata.customer.customer_id
});
}
if (metadata.subscription) {
await models.StripeCustomerSubscription.upsert(metadata.subscription, {
subscription_id: metadata.subscription.subscription_id
});
}
return;
}
async function getMetadata(module, member) {
if (module !== 'stripe') {
return;
}
const customers = (await models.MemberStripeCustomer.findAll({
filter: `member_id:${member.id}`
})).toJSON();
const subscriptions = await customers.reduce(async (subscriptionsPromise, customer) => {
const customerSubscriptions = await models.StripeCustomerSubscription.findAll({
filter: `customer_id:${customer.customer_id}`
});
return (await subscriptionsPromise).concat(customerSubscriptions.toJSON());
}, []);
return {
customers: customers,
subscriptions: subscriptions
};
}
async function updateMember({name, note, subscribed}, options = {}) {
const attrs = {
name: name || null,
note: note || null
};
if (subscribed !== undefined) {
attrs.subscribed = subscribed;
}
const model = await models.Member.edit(attrs, options);
const member = model.toJSON(options);
return member;
}
function deleteMember(options) {
options = options || {};
return models.Member.destroy(options).catch(models.Member.NotFoundError, () => {
throw new common.errors.NotFoundError({
message: common.i18n.t('errors.api.resource.resourceNotFound', {
resource: 'Member'
})
});
});
}
function listMembers(options) {
return models.Member.findPage(options).then((models) => {
return {
members: models.data.map(model => model.toJSON(options)),
meta: models.meta
};
});
}
const ghostMailer = new mail.GhostMailer();
module.exports = createApiInstance;
function createApiInstance() {
const membersApiInstance = MembersApi({
tokenConfig: config.getTokenConfig(),
auth: {
getSigninURL: config.getSigninURL,
allowSelfSignup: config.getAllowSelfSignup(),
secret: config.getAuthSecret()
},
mail: {
transporter: {
sendMail(message) {
if (process.env.NODE_ENV !== 'production') {
common.logging.warn(message.text);
}
let msg = Object.assign({
from: config.getEmailFromAddress(),
subject: 'Signin',
forceTextContent: true
}, message);
return ghostMailer.send(msg);
}
},
getSubject(type) {
const siteTitle = settingsCache.get('title');
switch (type) {
case 'subscribe':
return `📫 Confirm your subscription to ${siteTitle}`;
case 'signup':
return `🙌 Complete your sign up to ${siteTitle}!`;
case 'signin':
default:
return `🔑 Secure sign in link for ${siteTitle}`;
}
},
getText(url, type, email) {
const siteTitle = settingsCache.get('title');
switch (type) {
case 'subscribe':
return `
Hey there,
You're one tap away from subscribing to ${siteTitle} — please confirm your email address with this link:
${url}
For your security, the link will expire in 10 minutes time.
All the best!
The team at ${siteTitle}
---
Sent to ${email}
If you did not make this request, you can simply delete this message. You will not be subscribed.
`;
case 'signup':
return `
Hey there!
Thanks for signing up for ${siteTitle} — use this link to complete the sign up process and be automatically signed in:
${url}
For your security, the link will expire in 10 minutes time.
See you soon!
The team at ${siteTitle}
---
Sent to ${email}
If you did not make this request, you can simply delete this message. You will not be signed up, and no account will be created for you.
`;
case 'signin':
default:
return `
Hey there,
Welcome back! Use this link to securely sign in to your ${siteTitle} account:
${url}
For your security, the link will expire in 10 minutes time.
See you soon!
The team at ${siteTitle}
---
Sent to ${email}
If you did not make this request, you can safely ignore this email.
`;
}
},
getHTML(url, type, email) {
const siteTitle = settingsCache.get('title');
switch (type) {
case 'subscribe':
return subscribeEmail({url, email, siteTitle});
case 'signup':
return signupEmail({url, email, siteTitle});
case 'signin':
default:
return signinEmail({url, email, siteTitle});
}
}
},
paymentConfig: {
stripe: config.getStripePaymentConfig()
},
setMetadata,
getMetadata,
createMember,
updateMember,
getMember,
deleteMember,
listMembers,
logger: common.logging
});
return membersApiInstance;
}