Refactored members service logging and errors (#10919)
* Installed @tryghost/members-ssr@0.2.1 refs https://github.com/TryGhost/Members/issues/38 This updates allows for dynamic access of the membersApi, which will be used in future when replacing the membersApi instance with a newly configured one. * Set the membersApiInstance logger to use common.logging refs https://github.com/TryGhost/Members/issues/38 Passes the Ghost logger to the members api, so that we can keep an eye on errors produced by the api. * Refactored memberService use to always use getter refs https://github.com/TryGhost/Members/issues/38 This will allow us to switch out the membersApi and the consumers of it to have the updated reference by going through a getter. * Installed @tryghost/members-api@0.3.0 refs https://github.com/TryGhost/Members/issues/38 Adds support for setting the logger * Uninstalled stripe@7.0.0 refs https://github.com/TryGhost/Members/issues/38 The stripe module is now a dep of members-api, as it should be * Updated members service to reconfigure settings refs https://github.com/TryGhost/Members/issues/38 Previously we were unable to stop an invalidly configured members api instance, now that we create a new instance, we can wait for the ready or error event and only switch it out then.
This commit is contained in:
parent
d3ca12056f
commit
078060abdc
@ -1,4 +1,6 @@
|
||||
const memberUserObject = require('../../services/members').api.members;
|
||||
// NOTE: We must not cache references to membersService.api
|
||||
// as it is a getter and may change during runtime.
|
||||
const membersService = require('../../services/members');
|
||||
|
||||
const members = {
|
||||
docName: 'members',
|
||||
@ -14,7 +16,7 @@ const members = {
|
||||
permissions: true,
|
||||
validation: {},
|
||||
query(frame) {
|
||||
return memberUserObject.list(frame.options);
|
||||
return membersService.api.members.list(frame.options);
|
||||
}
|
||||
},
|
||||
|
||||
@ -27,7 +29,7 @@ const members = {
|
||||
validation: {},
|
||||
permissions: true,
|
||||
query(frame) {
|
||||
return memberUserObject.get(frame.data, frame.options);
|
||||
return membersService.api.members.get(frame.data, frame.options);
|
||||
}
|
||||
},
|
||||
|
||||
@ -47,7 +49,7 @@ const members = {
|
||||
permissions: true,
|
||||
query(frame) {
|
||||
frame.options.require = true;
|
||||
return memberUserObject.destroy(frame.options).return(null);
|
||||
return membersService.api.members.destroy(frame.options).return(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -23,7 +23,7 @@ function hideMembersOnlyContent(attrs, frame) {
|
||||
}
|
||||
|
||||
const memberHasPlan = !!(frame.original.context.member.plans || []).length;
|
||||
if (!membersService.api.isPaymentConfigured()) {
|
||||
if (!membersService.isPaymentConfigured()) {
|
||||
return PERMIT_CONTENT;
|
||||
}
|
||||
if (memberHasPlan) {
|
||||
|
@ -2,7 +2,6 @@ const url = require('url');
|
||||
const settingsCache = require('../settings/cache');
|
||||
const urlUtils = require('../../lib/url-utils');
|
||||
const MembersApi = require('@tryghost/members-api');
|
||||
const MembersSSR = require('@tryghost/members-ssr');
|
||||
const common = require('../../lib/common');
|
||||
const models = require('../../models');
|
||||
const mail = require('../mail');
|
||||
@ -182,50 +181,32 @@ const getSiteConfig = () => {
|
||||
};
|
||||
};
|
||||
|
||||
const membersApiInstance = MembersApi({
|
||||
authConfig: {
|
||||
issuer: membersApiUrl,
|
||||
ssoOrigin: adminOrigin,
|
||||
publicKey: settingsCache.get('members_public_key'),
|
||||
privateKey: settingsCache.get('members_private_key'),
|
||||
sessionSecret: settingsCache.get('members_session_secret'),
|
||||
accessControl
|
||||
},
|
||||
paymentConfig: {
|
||||
processors: getSubscriptionSettings().paymentProcessors
|
||||
},
|
||||
siteConfig: getSiteConfig(),
|
||||
createMember,
|
||||
getMember,
|
||||
deleteMember,
|
||||
listMembers,
|
||||
validateMember,
|
||||
updateMember,
|
||||
sendEmail
|
||||
});
|
||||
module.exports = createApiInstance;
|
||||
|
||||
const updateSettingFromModel = function updateSettingFromModel(settingModel) {
|
||||
if (!['members_subscription_settings', 'title', 'icon'].includes(settingModel.get('key'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
membersApiInstance.reconfigureSettings({
|
||||
function createApiInstance() {
|
||||
const membersApiInstance = MembersApi({
|
||||
authConfig: {
|
||||
issuer: membersApiUrl,
|
||||
ssoOrigin: adminOrigin,
|
||||
publicKey: settingsCache.get('members_public_key'),
|
||||
privateKey: settingsCache.get('members_private_key'),
|
||||
sessionSecret: settingsCache.get('members_session_secret'),
|
||||
accessControl
|
||||
},
|
||||
paymentConfig: {
|
||||
processors: getSubscriptionSettings().paymentProcessors
|
||||
},
|
||||
siteConfig: getSiteConfig()
|
||||
siteConfig: getSiteConfig(),
|
||||
createMember,
|
||||
getMember,
|
||||
deleteMember,
|
||||
listMembers,
|
||||
validateMember,
|
||||
updateMember,
|
||||
sendEmail
|
||||
});
|
||||
};
|
||||
|
||||
// Bind to events to automatically keep subscription info up-to-date from settings
|
||||
common.events.on('settings.edited', updateSettingFromModel);
|
||||
membersApiInstance.setLogger(common.logging);
|
||||
|
||||
module.exports = membersApiInstance;
|
||||
module.exports.ssr = MembersSSR({
|
||||
cookieSecure: urlUtils.isSSL(siteUrl),
|
||||
cookieKeys: [settingsCache.get('theme_session_secret')],
|
||||
membersApi: membersApiInstance
|
||||
});
|
||||
module.exports.isPaymentConfigured = function () {
|
||||
return getSubscriptionSettings().paymentProcessors.length !== 0;
|
||||
};
|
||||
return membersApiInstance;
|
||||
}
|
||||
|
@ -1,9 +0,0 @@
|
||||
const {static} = require('express');
|
||||
const path = require('path');
|
||||
|
||||
module.exports = static(
|
||||
path.join(
|
||||
require.resolve('@tryghost/members-auth-pages'),
|
||||
'../dist'
|
||||
)
|
||||
);
|
@ -1,9 +1,60 @@
|
||||
module.exports = {
|
||||
get api() {
|
||||
return require('./api');
|
||||
const {static} = require('express');
|
||||
const path = require('path');
|
||||
const MembersSSR = require('@tryghost/members-ssr');
|
||||
|
||||
const createMembersApiInstance = require('./api');
|
||||
const common = require('../../lib/common');
|
||||
const urlUtils = require('../../lib/url-utils');
|
||||
const settingsCache = require('../settings/cache');
|
||||
|
||||
let membersApi;
|
||||
|
||||
// Bind to events to automatically keep subscription info up-to-date from settings
|
||||
common.events.on('settings.edited', function updateSettingFromModel(settingModel) {
|
||||
if (!['members_subscription_settings', 'title', 'icon'].includes(settingModel.get('key'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
const reconfiguredMembersAPI = createMembersApiInstance();
|
||||
reconfiguredMembersAPI.bus.on('ready', function () {
|
||||
membersApi = reconfiguredMembersAPI;
|
||||
});
|
||||
reconfiguredMembersAPI.bus.on('error', function (err) {
|
||||
common.logging.error(err);
|
||||
});
|
||||
});
|
||||
|
||||
const membersService = {
|
||||
isPaymentConfigured() {
|
||||
const settings = settingsCache.get('members_subscription_settings');
|
||||
return !!settings && settings.isPaid && settings.paymentProcessors.length !== 0;
|
||||
},
|
||||
|
||||
get authPages() {
|
||||
return require('./authPages');
|
||||
}
|
||||
get api() {
|
||||
if (!membersApi) {
|
||||
membersApi = createMembersApiInstance();
|
||||
|
||||
membersApi.bus.on('error', function (err) {
|
||||
common.logging.error(err);
|
||||
});
|
||||
}
|
||||
return membersApi;
|
||||
},
|
||||
|
||||
ssr: MembersSSR({
|
||||
cookieSecure: urlUtils.isSSL(urlUtils.getSiteUrl()),
|
||||
cookieKeys: [settingsCache.get('theme_session_secret')],
|
||||
// This is passed as a function so that updates to the instance
|
||||
// are picked up in the ssr module
|
||||
membersApi: () => membersApi
|
||||
}),
|
||||
|
||||
authPages: static(
|
||||
path.join(
|
||||
require.resolve('@tryghost/members-auth-pages'),
|
||||
'../dist'
|
||||
)
|
||||
)
|
||||
};
|
||||
|
||||
module.exports = membersService;
|
||||
|
@ -15,7 +15,8 @@ module.exports = function setupMembersApiApp() {
|
||||
apiApp.use('/static/auth', membersService.authPages);
|
||||
|
||||
// Set up the api endpoints and the gateway
|
||||
apiApp.use(membersService.api);
|
||||
// NOTE: this is wrapped in a function to ensure we always go via the getter
|
||||
apiApp.use((req, res, next) => membersService.api(req, res, next));
|
||||
|
||||
// API error handling
|
||||
apiApp.use(shared.middlewares.errorHandler.resourceNotFound);
|
||||
|
@ -93,7 +93,7 @@ module.exports = function setupSiteApp(options = {}) {
|
||||
// @TODO only loads this stuff if members is enabled
|
||||
// Set req.member & res.locals.member if a cookie is set
|
||||
siteApp.post('/members/ssr', shared.middlewares.labs.members, function (req, res) {
|
||||
membersService.api.ssr.exchangeTokenForSession(req, res).then(() => {
|
||||
membersService.ssr.exchangeTokenForSession(req, res).then(() => {
|
||||
res.writeHead(200);
|
||||
res.end();
|
||||
}).catch((err) => {
|
||||
@ -102,7 +102,7 @@ module.exports = function setupSiteApp(options = {}) {
|
||||
});
|
||||
});
|
||||
siteApp.delete('/members/ssr', shared.middlewares.labs.members, function (req, res) {
|
||||
membersService.api.ssr.deleteSession(req, res).then(() => {
|
||||
membersService.ssr.deleteSession(req, res).then(() => {
|
||||
res.writeHead(204);
|
||||
res.end();
|
||||
}).catch((err) => {
|
||||
@ -111,7 +111,7 @@ module.exports = function setupSiteApp(options = {}) {
|
||||
});
|
||||
});
|
||||
siteApp.use(function (req, res, next) {
|
||||
membersService.api.ssr.getMemberDataFromSession(req, res).then((member) => {
|
||||
membersService.ssr.getMemberDataFromSession(req, res).then((member) => {
|
||||
req.member = member;
|
||||
next();
|
||||
}).catch(() => {
|
||||
|
@ -41,9 +41,9 @@
|
||||
"dependencies": {
|
||||
"@nexes/nql": "0.2.2",
|
||||
"@tryghost/helpers": "1.1.6",
|
||||
"@tryghost/members-api": "0.2.0",
|
||||
"@tryghost/members-api": "0.3.0",
|
||||
"@tryghost/members-auth-pages": "1.1.0",
|
||||
"@tryghost/members-ssr": "0.1.5",
|
||||
"@tryghost/members-ssr": "0.2.1",
|
||||
"@tryghost/members-theme-bindings": "0.2.3",
|
||||
"@tryghost/social-urls": "0.1.0",
|
||||
"@tryghost/string": "^0.1.3",
|
||||
@ -118,7 +118,6 @@
|
||||
"semver": "6.2.0",
|
||||
"simple-dom": "0.3.2",
|
||||
"simple-html-tokenizer": "0.5.7",
|
||||
"stripe": "^7.0.0",
|
||||
"uuid": "3.3.2",
|
||||
"validator": "6.3.0",
|
||||
"xml": "1.0.1"
|
||||
|
19
yarn.lock
19
yarn.lock
@ -149,10 +149,10 @@
|
||||
dependencies:
|
||||
"@tryghost/kg-clean-basic-html" "^0.1.1"
|
||||
|
||||
"@tryghost/members-api@0.2.0":
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/members-api/-/members-api-0.2.0.tgz#1f13dabc39015f8a5447a714dc05162426775027"
|
||||
integrity sha512-fLTQylyUz16ZL0KJ4kBvWnUsQbq1NkLFXVkQjOEo/xFV1SG0iJBKlkVtPWfyncSHyGBSXAv9TcQymiT+9vr7pQ==
|
||||
"@tryghost/members-api@0.3.0":
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/members-api/-/members-api-0.3.0.tgz#b1fe4c4853237c1af95065f5db2bfb2072a87524"
|
||||
integrity sha512-YtYjQwFGrN6uPuwWB8x1WqSuLe8c2m5wuPsyBpKXcV69yEqFz4QCyLMoYs4c6Y4lnfUf1lZAwnQSuDgczT46XQ==
|
||||
dependencies:
|
||||
bluebird "^3.5.4"
|
||||
body-parser "^1.19.0"
|
||||
@ -162,6 +162,7 @@
|
||||
jsonwebtoken "^8.5.1"
|
||||
lodash "^4.17.11"
|
||||
node-jose "^1.1.3"
|
||||
stripe "^7.4.0"
|
||||
|
||||
"@tryghost/members-auth-pages@1.1.0":
|
||||
version "1.1.0"
|
||||
@ -203,10 +204,10 @@
|
||||
ghost-ignition "^3.1.0"
|
||||
lodash "^4.17.11"
|
||||
|
||||
"@tryghost/members-ssr@0.1.5":
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/members-ssr/-/members-ssr-0.1.5.tgz#531a36233ac4d7e23b2582ec2e48698aba739c00"
|
||||
integrity sha512-nhceqbnoSZwJJN2xdEBPfRZu2fCDMuDnBLA84h+k8+RGoU+8qxzHDCLR1vgOlt8vVWUAP8HRS1/C4GyhuaUNXQ==
|
||||
"@tryghost/members-ssr@0.2.1":
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/members-ssr/-/members-ssr-0.2.1.tgz#156846832caeeaaa831206522dcc1e5b94e1335b"
|
||||
integrity sha512-pr3IYDymyDm++428LNJn3cfhZmW8j2Qtr/AmyPpmRIDSmpzbEk5wl28Dc+jWpH6ij36DbOwwfVUNZ9SW1Lwi3w==
|
||||
dependencies:
|
||||
bluebird "^3.5.3"
|
||||
concat-stream "^2.0.0"
|
||||
@ -7413,7 +7414,7 @@ strip-json-comments@2.0.1, strip-json-comments@^2.0.1, strip-json-comments@~2.0.
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
||||
|
||||
stripe@^7.0.0:
|
||||
stripe@^7.4.0:
|
||||
version "7.4.0"
|
||||
resolved "https://registry.yarnpkg.com/stripe/-/stripe-7.4.0.tgz#d40834f7763ebe775fe944db94bd3f31f291b0fc"
|
||||
integrity sha512-eurSZJw45MvnV7PjmFHMgJMkCihHgqGHr11OHpFdMh+5CCyYvbVlA5uP5VoVQakhYjSLCObs0dbXtGYhIAMKvw==
|
||||
|
Loading…
Reference in New Issue
Block a user