ghost 4.22.4 → 4.25.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +39 -0
- package/content/themes/casper/assets/built/casper.js +1 -1
- package/content/themes/casper/assets/built/casper.js.map +1 -1
- package/content/themes/casper/assets/built/global.css +1 -1
- package/content/themes/casper/assets/built/global.css.map +1 -1
- package/content/themes/casper/assets/built/screen.css +1 -1
- package/content/themes/casper/assets/built/screen.css.map +1 -1
- package/content/themes/casper/assets/css/global.css +6 -1
- package/content/themes/casper/assets/css/screen.css +32 -216
- package/content/themes/casper/default.hbs +2 -2
- package/content/themes/casper/package.json +3 -2
- package/content/themes/casper/post.hbs +1 -1
- package/content/themes/casper/yarn.lock +173 -123
- package/core/app.js +12 -1
- package/core/boot.js +33 -19
- package/core/bridge.js +10 -10
- package/core/built/assets/ghost-dark-f67240a9636407594be38571c615629c.css +1 -0
- package/core/built/assets/{ghost.min-2e3e64eb258cf424c59c3e308b4bc6e6.js → ghost.min-3441c3282e390002626a2dc1d7586185.js} +544 -619
- package/core/built/assets/ghost.min-ee5bd95a831378b4c8ccefb37d26eac0.css +1 -0
- package/core/built/assets/icons/audio-upload.svg +8 -0
- package/core/built/assets/{vendor.min-c9002845b6c30ac978abdadde9f33d7c.js → vendor.min-6fc912d1248c906f95efad2cb3eebb7d.js} +2656 -2118
- package/core/frontend/apps/amp/lib/helpers/amp_content.js +2 -2
- package/core/frontend/apps/amp/lib/views/amp.hbs +70 -0
- package/core/frontend/apps/private-blogging/index.js +1 -1
- package/core/frontend/helpers/url.js +18 -1
- package/core/frontend/services/apps/index.js +1 -1
- package/core/frontend/services/apps/loader.js +3 -3
- package/core/frontend/services/card-assets/index.js +0 -12
- package/core/frontend/services/card-assets/service.js +22 -21
- package/core/frontend/services/helpers/handlebars.js +1 -1
- package/core/frontend/services/theme-engine/middleware/ensure-active-theme.js +34 -0
- package/core/frontend/services/theme-engine/middleware/index.js +6 -0
- package/core/frontend/services/theme-engine/middleware/update-global-template-options.js +116 -0
- package/core/frontend/services/theme-engine/middleware/update-local-template-data.js +9 -0
- package/core/frontend/services/theme-engine/middleware/update-local-template-options.js +57 -0
- package/core/frontend/src/cards/css/blockquote.css +29 -0
- package/core/frontend/src/cards/css/bookmark.css +7 -0
- package/core/frontend/src/cards/css/button.css +4 -0
- package/core/frontend/src/cards/css/callout.css +23 -15
- package/core/frontend/src/cards/css/gallery.css +13 -3
- package/core/frontend/src/cards/css/toggle.css +36 -16
- package/core/frontend/web/middleware/error-handler.js +93 -0
- package/core/frontend/web/middleware/handle-image-sizes.js +3 -6
- package/core/frontend/web/middleware/index.js +1 -0
- package/core/frontend/web/middleware/serve-public-file.js +25 -8
- package/core/frontend/web/site.js +2 -5
- package/core/server/adapters/scheduling/SchedulingDefault.js +2 -2
- package/core/server/adapters/storage/LocalStorageBase.js +2 -2
- package/core/server/api/canary/db.js +2 -2
- package/core/server/api/canary/media.js +3 -2
- package/core/server/api/canary/oembed.js +16 -1
- package/core/server/api/canary/session.js +1 -1
- package/core/server/api/canary/slugs.js +1 -1
- package/core/server/api/canary/utils/permissions.js +2 -2
- package/core/server/api/canary/utils/serializers/output/config.js +2 -6
- package/core/server/api/v2/db.js +2 -2
- package/core/server/api/v2/session.js +1 -1
- package/core/server/api/v2/slugs.js +1 -1
- package/core/server/api/v2/utils/permissions.js +2 -2
- package/core/server/api/v3/db.js +2 -2
- package/core/server/api/v3/session.js +1 -1
- package/core/server/api/v3/slugs.js +1 -1
- package/core/server/api/v3/utils/permissions.js +2 -2
- package/core/server/data/db/state-manager.js +4 -4
- package/core/server/data/exporter/export-filename.js +1 -1
- package/core/server/data/importer/handlers/json.js +1 -1
- package/core/server/data/importer/import-manager.js +1 -1
- package/core/server/data/importer/importers/data/base.js +1 -1
- package/core/server/data/migrations/utils.js +2 -2
- package/core/server/data/migrations/versions/1.25/1-update-koenig-beta-html.js +1 -0
- package/core/server/data/migrations/versions/3.1/08-add-uuid-values-to-members.js +1 -0
- package/core/server/data/migrations/versions/3.22/02-settings-key-renames.js +2 -0
- package/core/server/data/migrations/versions/3.22/05-migrate-members-subscription-settings.js +3 -0
- package/core/server/data/migrations/versions/3.22/06-migrate-stripe-connect-settings.js +2 -0
- package/core/server/data/migrations/versions/3.23/01-migrate-bulk-email-settings.js +1 -0
- package/core/server/data/migrations/versions/3.29/01-remove-duplicate-subscriptions.js +2 -0
- package/core/server/data/migrations/versions/3.29/02-remove-duplicate-customers.js +2 -0
- package/core/server/data/migrations/versions/3.38/04-populate-recipient-filter-column.js +2 -0
- package/core/server/data/migrations/versions/4.0/01-update-mobiledoc.js +2 -0
- package/core/server/data/migrations/versions/4.0/03-populate-status-column-for-members.js +4 -0
- package/core/server/data/migrations/versions/4.0/06-populate-members-subscribe-events-table.js +1 -0
- package/core/server/data/migrations/versions/4.0/17-populate-members-status-events-table.js +1 -0
- package/core/server/data/migrations/versions/4.0/18-transform-urls-absolute-to-transform-ready.js +5 -0
- package/core/server/data/migrations/versions/4.0/22-solve-orphaned-webhooks.js +1 -0
- package/core/server/data/migrations/versions/4.0/23-regenerate-posts-html.js +1 -0
- package/core/server/data/migrations/versions/4.0/25-populate-members-paid-subscription-events-table.js +2 -1
- package/core/server/data/migrations/versions/4.12/02-fix-member-statuses.js +1 -0
- package/core/server/data/migrations/versions/4.14/01-fix-comped-member-statuses.js +3 -0
- package/core/server/data/migrations/versions/4.14/02-fix-free-members-status-events.js +1 -0
- package/core/server/data/migrations/versions/4.20/05-remove-not-null-constraint-from-portal-title.js +2 -0
- package/core/server/data/migrations/versions/4.23/01-truncate-offer-names.js +59 -0
- package/core/server/data/migrations/versions/4.3/04-attach-members-to-product.js +1 -0
- package/core/server/data/migrations/versions/4.4/01-restore-free-members-signup-setting-from-backup.js +1 -0
- package/core/server/data/migrations/versions/4.6/01-remove-comped-status.js +1 -0
- package/core/server/data/migrations/versions/4.8/04-migrate-show-newsletter-header-setting.js +1 -0
- package/core/server/data/migrations/versions/4.9/05-fix-missed-mobiledoc-url-transforms.js +1 -0
- package/core/server/data/migrations/versions/4.9/06-add-comped-status.js +1 -0
- package/core/server/data/migrations/versions/4.9/07-update-comped-members-status-events.js +1 -0
- package/core/server/data/schema/commands.js +2 -2
- package/core/server/ghost-server.js +2 -2
- package/core/server/lib/image/image-size.js +2 -2
- package/core/server/models/base/listeners.js +2 -2
- package/core/server/models/member-email-change-event.js +2 -2
- package/core/server/models/member-login-event.js +2 -2
- package/core/server/models/member-paid-subscription-event.js +3 -3
- package/core/server/models/member-payment-event.js +3 -3
- package/core/server/models/member-product-event.js +6 -6
- package/core/server/models/member-status-event.js +5 -3
- package/core/server/models/member-subscribe-event.js +9 -3
- package/core/server/models/relations/authors.js +1 -1
- package/core/server/models/settings.js +1 -1
- package/core/server/services/auth/passwordreset.js +1 -1
- package/core/server/services/auth/setup.js +1 -1
- package/core/server/services/email-analytics/jobs/index.js +1 -1
- package/core/server/services/mega/mega.js +6 -4
- package/core/server/services/mega/template.js +31 -12
- package/core/server/services/members/api.js +22 -0
- package/core/server/services/members/config.js +1 -1
- package/core/server/services/members/emails/signup-paid.js +168 -0
- package/core/server/services/members/service.js +6 -2
- package/core/server/services/members/stripe-connect.js +4 -2
- package/core/server/services/nft-oembed.js +6 -1
- package/core/server/services/oembed.js +36 -28
- package/core/server/services/permissions/can-this.js +1 -1
- package/core/server/services/redirects/api.js +20 -25
- package/core/server/services/redirects/index.js +18 -10
- package/core/server/services/redirects/utils.js +14 -0
- package/core/server/services/redirects/validation.js +10 -0
- package/core/server/services/route-settings/default-settings-manager.js +1 -1
- package/core/server/services/route-settings/index.js +40 -17
- package/core/server/services/route-settings/route-settings.js +120 -115
- package/core/server/services/route-settings/settings-loader.js +18 -36
- package/core/server/services/route-settings/yaml-parser.js +1 -1
- package/core/server/services/slack.js +1 -1
- package/core/server/services/themes/activation-bridge.js +3 -3
- package/core/server/services/themes/storage.js +2 -2
- package/core/server/services/twitter-embed.js +80 -0
- package/core/server/services/url/LocalFileCache.js +75 -0
- package/core/server/services/url/UrlService.js +15 -47
- package/core/server/services/url/index.js +17 -4
- package/core/server/services/xmlrpc.js +2 -2
- package/core/server/web/admin/app.js +2 -5
- package/core/server/web/admin/controller.js +35 -12
- package/core/server/web/admin/middleware/redirect-admin-urls.js +15 -0
- package/core/server/web/admin/views/default-prod.html +4 -4
- package/core/server/web/admin/views/default.html +4 -4
- package/core/server/web/api/canary/admin/app.js +0 -3
- package/core/server/web/api/canary/admin/middleware.js +1 -1
- package/core/server/web/api/canary/content/app.js +0 -3
- package/core/server/web/api/v2/admin/app.js +0 -3
- package/core/server/web/api/v2/admin/middleware.js +1 -1
- package/core/server/web/api/v2/content/app.js +0 -3
- package/core/server/web/api/v3/admin/app.js +0 -3
- package/core/server/web/api/v3/admin/middleware.js +1 -1
- package/core/server/web/api/v3/content/app.js +0 -3
- package/core/server/web/members/app.js +0 -3
- package/core/server/web/oauth/app.js +0 -4
- package/core/server/web/parent/app.js +17 -8
- package/core/server/web/shared/middleware/error-handler.js +57 -162
- package/core/server/web/shared/middleware/index.js +0 -4
- package/core/shared/config/defaults.json +7 -1
- package/core/shared/labs.js +10 -5
- package/core/shared/sentry.js +1 -1
- package/package.json +43 -42
- package/yarn.lock +802 -923
- package/content/themes/casper/assets/js/gallery-card.js +0 -24
- package/core/built/assets/ghost-dark-42cf6e0c730578940ec069bda45aea41.css +0 -1
- package/core/built/assets/ghost.min-fcf6a0738421f86c47c55f20d00c5ba9.css +0 -1
- package/core/frontend/services/theme-engine/middleware.js +0 -209
- package/core/server/web/shared/middleware/maintenance.js +0 -25
|
@@ -2,7 +2,6 @@ const debug = require('@tryghost/debug')('web:oauth:app');
|
|
|
2
2
|
const {URL} = require('url');
|
|
3
3
|
const express = require('../../../shared/express');
|
|
4
4
|
const urlUtils = require('../../../shared/url-utils');
|
|
5
|
-
const shared = require('../shared');
|
|
6
5
|
const settingsCache = require('../../../shared/settings-cache');
|
|
7
6
|
const models = require('../../models');
|
|
8
7
|
const auth = require('../../services/auth');
|
|
@@ -24,9 +23,6 @@ module.exports = function setupOAuthApp() {
|
|
|
24
23
|
}
|
|
25
24
|
oauthApp.use(labsMiddleware);
|
|
26
25
|
|
|
27
|
-
// send 503 json response in case of maintenance
|
|
28
|
-
oauthApp.use(shared.middleware.maintenance);
|
|
29
|
-
|
|
30
26
|
/**
|
|
31
27
|
* Configure the passport.authenticate middleware
|
|
32
28
|
* We need to configure it on each request because clientId and secret
|
|
@@ -5,7 +5,13 @@ const compress = require('compression');
|
|
|
5
5
|
const mw = require('./middleware');
|
|
6
6
|
const vhost = require('@tryghost/vhost-middleware');
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* @param {Object} options
|
|
10
|
+
* @param {Boolean} [options.start]
|
|
11
|
+
* @param {Boolean} [options.backend]
|
|
12
|
+
* @param {Boolean} [options.frontend]
|
|
13
|
+
*/
|
|
14
|
+
module.exports = function setupParentApp({start, frontend = true, backend = true}) {
|
|
9
15
|
debug('ParentApp setup start');
|
|
10
16
|
const parentApp = express('parent');
|
|
11
17
|
|
|
@@ -26,14 +32,17 @@ module.exports = function setupParentApp(options = {}) {
|
|
|
26
32
|
|
|
27
33
|
// Mount the express apps on the parentApp
|
|
28
34
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const frontendApp = require('./frontend')(options);
|
|
35
|
-
parentApp.use(vhost(config.getFrontendMountPath(), frontendApp));
|
|
35
|
+
if (backend) {
|
|
36
|
+
debug('Mounting bakcend: ADMIN + API');
|
|
37
|
+
const backendApp = require('./backend')();
|
|
38
|
+
parentApp.use(vhost(config.getBackendMountPath(), backendApp));
|
|
39
|
+
}
|
|
36
40
|
|
|
41
|
+
if (frontend) {
|
|
42
|
+
debug('Mounting frontend: SITE + MEMBERS');
|
|
43
|
+
const frontendApp = require('./frontend')({start});
|
|
44
|
+
parentApp.use(vhost(config.getFrontendMountPath(), frontendApp));
|
|
45
|
+
}
|
|
37
46
|
debug('ParentApp setup end');
|
|
38
47
|
|
|
39
48
|
return parentApp;
|
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
const hbs = require('express-hbs');
|
|
2
1
|
const _ = require('lodash');
|
|
3
2
|
const debug = require('@tryghost/debug')('error-handler');
|
|
4
3
|
const errors = require('@tryghost/errors');
|
|
5
4
|
const tpl = require('@tryghost/tpl');
|
|
6
|
-
const config = require('../../../../shared/config');
|
|
7
|
-
const helpers = require('../../../../frontend/services/routing/helpers');
|
|
8
5
|
const sentry = require('../../../../shared/sentry');
|
|
9
6
|
|
|
10
7
|
const messages = {
|
|
11
|
-
oopsErrorTemplateHasError: 'Oops, seems there is an error in the error template.',
|
|
12
|
-
encounteredError: 'Encountered the error: ',
|
|
13
|
-
whilstTryingToRender: 'whilst trying to render an error page for the error: ',
|
|
14
8
|
pageNotFound: 'Page not found',
|
|
15
9
|
resourceNotFound: 'Resource not found',
|
|
16
10
|
actions: {
|
|
@@ -45,36 +39,44 @@ const messages = {
|
|
|
45
39
|
}
|
|
46
40
|
};
|
|
47
41
|
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
const errorHandler = {};
|
|
42
|
+
const updateStack = (err) => {
|
|
43
|
+
let stackbits = err.stack.split(/\n/g);
|
|
51
44
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
45
|
+
// We build this up backwards, so we always insert at position 1
|
|
46
|
+
|
|
47
|
+
if (process.env.NODE_ENV === 'production' || err.statusCode === 404) {
|
|
48
|
+
// In production mode, remove the stack trace
|
|
49
|
+
stackbits.splice(1, stackbits.length - 1);
|
|
50
|
+
} else {
|
|
51
|
+
// In dev mode, clearly mark the strack trace
|
|
52
|
+
stackbits.splice(1, 0, `Stack Trace:`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Add in our custom cotext and help methods
|
|
59
56
|
|
|
60
|
-
|
|
57
|
+
if (err.help) {
|
|
58
|
+
stackbits.splice(1, 0, `${err.help}`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (err.context) {
|
|
62
|
+
stackbits.splice(1, 0, `${err.context}`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return stackbits.join('\n');
|
|
61
66
|
};
|
|
62
67
|
|
|
63
68
|
/**
|
|
64
69
|
* Get an error ready to be shown the the user
|
|
65
|
-
*
|
|
66
|
-
* @TODO: support multiple errors within one single error, see https://github.com/TryGhost/Ghost/issues/7116#issuecomment-252231809
|
|
67
70
|
*/
|
|
68
|
-
|
|
71
|
+
module.exports.prepareError = (err, req, res, next) => {
|
|
69
72
|
debug(err);
|
|
70
73
|
|
|
71
74
|
if (Array.isArray(err)) {
|
|
72
75
|
err = err[0];
|
|
73
76
|
}
|
|
74
77
|
|
|
75
|
-
if (!errors.utils.
|
|
78
|
+
if (!errors.utils.isGhostError(err)) {
|
|
76
79
|
// We need a special case for 404 errors
|
|
77
|
-
// @TODO look at adding this to the GhostError class
|
|
78
80
|
if (err.statusCode && err.statusCode === 404) {
|
|
79
81
|
err = new errors.NotFoundError({
|
|
80
82
|
err: err
|
|
@@ -88,7 +90,7 @@ _private.prepareError = (err, req, res, next) => {
|
|
|
88
90
|
statusCode: err.statusCode
|
|
89
91
|
});
|
|
90
92
|
} else {
|
|
91
|
-
err = new errors.
|
|
93
|
+
err = new errors.InternalServerError({
|
|
92
94
|
err: err,
|
|
93
95
|
message: err.message,
|
|
94
96
|
statusCode: err.statusCode
|
|
@@ -102,6 +104,8 @@ _private.prepareError = (err, req, res, next) => {
|
|
|
102
104
|
// alternative for res.status();
|
|
103
105
|
res.statusCode = err.statusCode;
|
|
104
106
|
|
|
107
|
+
err.stack = updateStack(err);
|
|
108
|
+
|
|
105
109
|
// never cache errors
|
|
106
110
|
res.set({
|
|
107
111
|
'Cache-Control': 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'
|
|
@@ -110,7 +114,7 @@ _private.prepareError = (err, req, res, next) => {
|
|
|
110
114
|
next(err);
|
|
111
115
|
};
|
|
112
116
|
|
|
113
|
-
|
|
117
|
+
const jsonErrorRenderer = (err, req, res, next) => { // eslint-disable-line no-unused-vars
|
|
114
118
|
res.json({
|
|
115
119
|
errors: [{
|
|
116
120
|
message: err.message,
|
|
@@ -123,7 +127,24 @@ _private.JSONErrorRenderer = (err, req, res, next) => { // eslint-disable-line n
|
|
|
123
127
|
});
|
|
124
128
|
};
|
|
125
129
|
|
|
126
|
-
|
|
130
|
+
const jsonErrorRendererV2 = (err, req, res, next) => { // eslint-disable-line no-unused-vars
|
|
131
|
+
const userError = prepareUserMessage(err, req);
|
|
132
|
+
|
|
133
|
+
res.json({
|
|
134
|
+
errors: [{
|
|
135
|
+
message: userError.message || null,
|
|
136
|
+
context: userError.context || null,
|
|
137
|
+
type: err.errorType || null,
|
|
138
|
+
details: err.errorDetails || null,
|
|
139
|
+
property: err.property || null,
|
|
140
|
+
help: err.help || null,
|
|
141
|
+
code: err.code || null,
|
|
142
|
+
id: err.id || null
|
|
143
|
+
}]
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const prepareUserMessage = (err, res) => {
|
|
127
148
|
const userError = {
|
|
128
149
|
message: err.message,
|
|
129
150
|
context: err.context
|
|
@@ -169,161 +190,35 @@ _private.prepareUserMessage = (err, res) => {
|
|
|
169
190
|
return userError;
|
|
170
191
|
};
|
|
171
192
|
|
|
172
|
-
|
|
173
|
-
const userError = _private.prepareUserMessage(err, req);
|
|
174
|
-
|
|
175
|
-
res.json({
|
|
176
|
-
errors: [{
|
|
177
|
-
message: userError.message || null,
|
|
178
|
-
context: userError.context || null,
|
|
179
|
-
type: err.errorType || null,
|
|
180
|
-
details: err.errorDetails || null,
|
|
181
|
-
property: err.property || null,
|
|
182
|
-
help: err.help || null,
|
|
183
|
-
code: err.code || null,
|
|
184
|
-
id: err.id || null
|
|
185
|
-
}]
|
|
186
|
-
});
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
_private.ErrorFallbackMessage = err => `<h1>${tpl(messages.oopsErrorTemplateHasError)}</h1>
|
|
190
|
-
<p>${tpl(messages.encounteredError)}</p>
|
|
191
|
-
<pre>${escapeExpression(err.message || err)}</pre>
|
|
192
|
-
<br ><p>${tpl(messages.whilstTryingToRender)}</p>
|
|
193
|
-
${err.statusCode} <pre>${escapeExpression(err.message || err)}</pre>`;
|
|
194
|
-
|
|
195
|
-
_private.ThemeErrorRenderer = (err, req, res, next) => {
|
|
196
|
-
// If the error code is explicitly set to STATIC_FILE_NOT_FOUND,
|
|
197
|
-
// Skip trying to render an HTML error, and move on to the basic error renderer
|
|
198
|
-
// We do this because customised 404 templates could reference the image that's missing
|
|
199
|
-
// A better long term solution might be to do this based on extension
|
|
200
|
-
if (err.code === 'STATIC_FILE_NOT_FOUND') {
|
|
201
|
-
return next(err);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// Renderer begin
|
|
205
|
-
// Format Data
|
|
206
|
-
const data = {
|
|
207
|
-
message: err.message,
|
|
208
|
-
// @deprecated Remove in Ghost 5.0
|
|
209
|
-
code: err.statusCode,
|
|
210
|
-
statusCode: err.statusCode,
|
|
211
|
-
errorDetails: err.errorDetails || []
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
// Template
|
|
215
|
-
// @TODO: very dirty !!!!!!
|
|
216
|
-
helpers.templates.setTemplate(req, res);
|
|
217
|
-
|
|
218
|
-
// It can be that something went wrong with the theme or otherwise loading handlebars
|
|
219
|
-
// This ensures that no matter what res.render will work here
|
|
220
|
-
// @TODO: split the error handler for assets, admin & theme to refactor this away
|
|
221
|
-
if (_.isEmpty(req.app.engines)) {
|
|
222
|
-
res._template = 'error';
|
|
223
|
-
req.app.engine('hbs', _private.createHbsEngine());
|
|
224
|
-
req.app.set('view engine', 'hbs');
|
|
225
|
-
req.app.set('views', config.get('paths').defaultViews);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// @TODO use renderer here?!
|
|
229
|
-
// Render Call - featuring an error handler for what happens if rendering fails
|
|
230
|
-
res.render(res._template, data, (_err, html) => {
|
|
231
|
-
if (!_err) {
|
|
232
|
-
return res.send(html);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// re-attach new error e.g. error template has syntax error or misusage
|
|
236
|
-
req.err = _err;
|
|
237
|
-
|
|
238
|
-
// And then try to explain things to the user...
|
|
239
|
-
// Cheat and output the error using handlebars escapeExpression
|
|
240
|
-
return res.status(500).send(_private.ErrorFallbackMessage(_err));
|
|
241
|
-
});
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
_private.HTMLErrorRenderer = (err, req, res, next) => { // eslint-disable-line no-unused-vars
|
|
245
|
-
const data = {
|
|
246
|
-
message: err.message,
|
|
247
|
-
statusCode: err.statusCode,
|
|
248
|
-
errorDetails: err.errorDetails || []
|
|
249
|
-
};
|
|
250
|
-
|
|
251
|
-
// e.g. if you serve the admin /ghost and Ghost returns a 503 because it generates the urls at the moment.
|
|
252
|
-
// This ensures that no matter what res.render will work here
|
|
253
|
-
// @TODO: put to prepare error function?
|
|
254
|
-
if (_.isEmpty(req.app.engines)) {
|
|
255
|
-
res._template = 'error';
|
|
256
|
-
req.app.engine('hbs', _private.createHbsEngine());
|
|
257
|
-
req.app.set('view engine', 'hbs');
|
|
258
|
-
req.app.set('views', config.get('paths').defaultViews);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
res.render('error', data, (_err, html) => {
|
|
262
|
-
if (!_err) {
|
|
263
|
-
return res.send(html);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
// re-attach new error e.g. error template has syntax error or misusage
|
|
267
|
-
req.err = _err;
|
|
268
|
-
|
|
269
|
-
// And then try to explain things to the user...
|
|
270
|
-
// Cheat and output the error using handlebars escapeExpression
|
|
271
|
-
return res.status(500).send(_private.ErrorFallbackMessage(_err));
|
|
272
|
-
});
|
|
273
|
-
};
|
|
274
|
-
|
|
275
|
-
_private.BasicErrorRenderer = (err, req, res, next) => { // eslint-disable-line no-unused-vars
|
|
276
|
-
return res.send(res.statusCode + ' ' + err.message);
|
|
277
|
-
};
|
|
278
|
-
|
|
279
|
-
errorHandler.resourceNotFound = (req, res, next) => {
|
|
280
|
-
// TODO, handle unknown resources & methods differently, so that we can also produce
|
|
281
|
-
// 405 Method Not Allowed
|
|
193
|
+
module.exports.resourceNotFound = (req, res, next) => {
|
|
282
194
|
next(new errors.NotFoundError({message: tpl(messages.resourceNotFound)}));
|
|
283
195
|
};
|
|
284
196
|
|
|
285
|
-
|
|
197
|
+
module.exports.pageNotFound = (req, res, next) => {
|
|
286
198
|
next(new errors.NotFoundError({message: tpl(messages.pageNotFound)}));
|
|
287
199
|
};
|
|
288
200
|
|
|
289
|
-
|
|
201
|
+
module.exports.handleJSONResponse = [
|
|
290
202
|
// Make sure the error can be served
|
|
291
|
-
|
|
203
|
+
module.exports.prepareError,
|
|
292
204
|
// Handle the error in Sentry
|
|
293
205
|
sentry.errorHandler,
|
|
294
206
|
// Render the error using JSON format
|
|
295
|
-
|
|
207
|
+
jsonErrorRenderer
|
|
296
208
|
];
|
|
297
209
|
|
|
298
|
-
|
|
210
|
+
module.exports.handleJSONResponseV2 = [
|
|
299
211
|
// Make sure the error can be served
|
|
300
|
-
|
|
212
|
+
module.exports.prepareError,
|
|
301
213
|
// Handle the error in Sentry
|
|
302
214
|
sentry.errorHandler,
|
|
303
215
|
// Render the error using JSON format
|
|
304
|
-
|
|
216
|
+
jsonErrorRendererV2
|
|
305
217
|
];
|
|
306
218
|
|
|
307
|
-
|
|
219
|
+
module.exports.handleHTMLResponse = [
|
|
308
220
|
// Make sure the error can be served
|
|
309
|
-
|
|
221
|
+
module.exports.prepareError,
|
|
310
222
|
// Handle the error in Sentry
|
|
311
|
-
sentry.errorHandler
|
|
312
|
-
// Render the error using HTML format
|
|
313
|
-
_private.HTMLErrorRenderer,
|
|
314
|
-
// Fall back to basic if HTML is not explicitly accepted
|
|
315
|
-
_private.BasicErrorRenderer
|
|
223
|
+
sentry.errorHandler
|
|
316
224
|
];
|
|
317
|
-
|
|
318
|
-
errorHandler.handleThemeResponse = [
|
|
319
|
-
// Make sure the error can be served
|
|
320
|
-
_private.prepareError,
|
|
321
|
-
// Handle the error in Sentry
|
|
322
|
-
sentry.errorHandler,
|
|
323
|
-
// Render the error using theme template
|
|
324
|
-
_private.ThemeErrorRenderer,
|
|
325
|
-
// Fall back to basic if HTML is not explicitly accepted
|
|
326
|
-
_private.BasicErrorRenderer
|
|
327
|
-
];
|
|
328
|
-
|
|
329
|
-
module.exports = errorHandler;
|
|
@@ -131,7 +131,13 @@
|
|
|
131
131
|
"version": "1.12"
|
|
132
132
|
},
|
|
133
133
|
"tenor": {
|
|
134
|
-
"
|
|
134
|
+
"publicReadOnlyApiKey": null,
|
|
135
135
|
"contentFilter": "off"
|
|
136
|
+
},
|
|
137
|
+
"opensea": {
|
|
138
|
+
"privateReadOnlyApiKey": null
|
|
139
|
+
},
|
|
140
|
+
"twitter": {
|
|
141
|
+
"privateReadOnlyToken": null
|
|
136
142
|
}
|
|
137
143
|
}
|
package/core/shared/labs.js
CHANGED
|
@@ -15,7 +15,8 @@ const messages = {
|
|
|
15
15
|
|
|
16
16
|
// flags in this list always return `true`, allows quick global enable prior to full flag removal
|
|
17
17
|
const GA_FEATURES = [
|
|
18
|
-
'customThemeSettings'
|
|
18
|
+
'customThemeSettings',
|
|
19
|
+
'nftCard'
|
|
19
20
|
];
|
|
20
21
|
|
|
21
22
|
// NOTE: this allowlist is meant to be used to filter out any unexpected
|
|
@@ -33,11 +34,14 @@ const ALPHA_FEATURES = [
|
|
|
33
34
|
'mediaAPI',
|
|
34
35
|
'filesAPI',
|
|
35
36
|
'membersAutoLogin',
|
|
36
|
-
'buttonCard',
|
|
37
37
|
'calloutCard',
|
|
38
|
-
'nftCard',
|
|
39
38
|
'accordionCard',
|
|
40
|
-
'
|
|
39
|
+
'fileCard',
|
|
40
|
+
'audioCard',
|
|
41
|
+
'videoCard',
|
|
42
|
+
'productCard',
|
|
43
|
+
'quoteStyles',
|
|
44
|
+
'beforeAfterCard'
|
|
41
45
|
];
|
|
42
46
|
|
|
43
47
|
module.exports.GA_KEYS = [...GA_FEATURES];
|
|
@@ -47,7 +51,7 @@ module.exports.getAll = () => {
|
|
|
47
51
|
const labs = _.cloneDeep(settingsCache.get('labs')) || {};
|
|
48
52
|
|
|
49
53
|
ALPHA_FEATURES.forEach((alphaKey) => {
|
|
50
|
-
if (labs[alphaKey] && !(config.get('enableDeveloperExperiments') || process.env.NODE_ENV.
|
|
54
|
+
if (labs[alphaKey] && !(config.get('enableDeveloperExperiments') || process.env.NODE_ENV.startsWith('test'))) {
|
|
51
55
|
delete labs[alphaKey];
|
|
52
56
|
}
|
|
53
57
|
});
|
|
@@ -102,6 +106,7 @@ module.exports.enabledHelper = function enabledHelper(options, callback) {
|
|
|
102
106
|
});
|
|
103
107
|
errDetails.help = tpl(options.errorHelp || messages.errorHelp, {url: options.helpUrl});
|
|
104
108
|
|
|
109
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
105
110
|
logging.error(new errors.DisabledFeatureError(errDetails));
|
|
106
111
|
|
|
107
112
|
const {SafeString} = require('express-hbs');
|
package/core/shared/sentry.js
CHANGED
|
@@ -18,7 +18,7 @@ if (sentryConfig && !sentryConfig.disabled) {
|
|
|
18
18
|
shouldHandleError(error) {
|
|
19
19
|
// Sometimes non-Ghost issues will come into here but they won't
|
|
20
20
|
// have a statusCode so we should always handle them
|
|
21
|
-
if (!errors.utils.
|
|
21
|
+
if (!errors.utils.isGhostError(error)) {
|
|
22
22
|
return true;
|
|
23
23
|
}
|
|
24
24
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ghost",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.25.1",
|
|
4
4
|
"description": "The professional publishing platform",
|
|
5
5
|
"author": "Ghost Foundation",
|
|
6
6
|
"homepage": "https://ghost.org",
|
|
@@ -55,56 +55,57 @@
|
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@nexes/nql": "0.6.0",
|
|
57
57
|
"@sentry/node": "6.15.0",
|
|
58
|
-
"@tryghost/adapter-manager": "0.2.
|
|
58
|
+
"@tryghost/adapter-manager": "0.2.24",
|
|
59
59
|
"@tryghost/admin-api-schema": "2.6.1",
|
|
60
|
-
"@tryghost/bookshelf-plugins": "0.3.
|
|
61
|
-
"@tryghost/bootstrap-socket": "0.2.
|
|
60
|
+
"@tryghost/bookshelf-plugins": "0.3.5",
|
|
61
|
+
"@tryghost/bootstrap-socket": "0.2.14",
|
|
62
62
|
"@tryghost/color-utils": "0.1.5",
|
|
63
63
|
"@tryghost/config-url-helpers": "0.1.3",
|
|
64
64
|
"@tryghost/constants": "1.0.0",
|
|
65
65
|
"@tryghost/custom-theme-settings-service": "0.3.1",
|
|
66
66
|
"@tryghost/debug": "0.1.9",
|
|
67
|
-
"@tryghost/email-analytics-provider-mailgun": "1.0.
|
|
68
|
-
"@tryghost/email-analytics-service": "1.0.
|
|
69
|
-
"@tryghost/errors": "0.
|
|
70
|
-
"@tryghost/express-dynamic-redirects": "0.2.
|
|
67
|
+
"@tryghost/email-analytics-provider-mailgun": "1.0.6",
|
|
68
|
+
"@tryghost/email-analytics-service": "1.0.5",
|
|
69
|
+
"@tryghost/errors": "1.0.4",
|
|
70
|
+
"@tryghost/express-dynamic-redirects": "0.2.2",
|
|
71
71
|
"@tryghost/helpers": "1.1.54",
|
|
72
|
-
"@tryghost/image-transform": "1.0.
|
|
73
|
-
"@tryghost/job-manager": "0.8.
|
|
72
|
+
"@tryghost/image-transform": "1.0.24",
|
|
73
|
+
"@tryghost/job-manager": "0.8.16",
|
|
74
74
|
"@tryghost/kg-card-factory": "3.1.0",
|
|
75
75
|
"@tryghost/kg-default-atoms": "3.1.0",
|
|
76
|
-
"@tryghost/kg-default-cards": "5.
|
|
76
|
+
"@tryghost/kg-default-cards": "5.9.2",
|
|
77
77
|
"@tryghost/kg-markdown-html-renderer": "5.1.0",
|
|
78
|
-
"@tryghost/kg-mobiledoc-html-renderer": "5.
|
|
79
|
-
"@tryghost/limit-service": "1.0.
|
|
80
|
-
"@tryghost/logging": "1.0.
|
|
78
|
+
"@tryghost/kg-mobiledoc-html-renderer": "5.3.0",
|
|
79
|
+
"@tryghost/limit-service": "1.0.6",
|
|
80
|
+
"@tryghost/logging": "1.0.2",
|
|
81
81
|
"@tryghost/magic-link": "1.0.14",
|
|
82
|
-
"@tryghost/members-api": "2.
|
|
83
|
-
"@tryghost/members-csv": "1.
|
|
84
|
-
"@tryghost/members-importer": "0.3.
|
|
85
|
-
"@tryghost/members-offers": "0.10.
|
|
86
|
-
"@tryghost/members-ssr": "1.0.
|
|
82
|
+
"@tryghost/members-api": "2.8.4",
|
|
83
|
+
"@tryghost/members-csv": "1.2.0",
|
|
84
|
+
"@tryghost/members-importer": "0.3.5",
|
|
85
|
+
"@tryghost/members-offers": "0.10.3",
|
|
86
|
+
"@tryghost/members-ssr": "1.0.16",
|
|
87
87
|
"@tryghost/metrics": "1.0.1",
|
|
88
|
-
"@tryghost/minifier": "0.1.
|
|
88
|
+
"@tryghost/minifier": "0.1.7",
|
|
89
89
|
"@tryghost/mw-session-from-token": "0.1.26",
|
|
90
|
-
"@tryghost/nodemailer": "0.3.
|
|
91
|
-
"@tryghost/package-json": "1.0.
|
|
90
|
+
"@tryghost/nodemailer": "0.3.8",
|
|
91
|
+
"@tryghost/package-json": "1.0.12",
|
|
92
92
|
"@tryghost/promise": "0.1.13",
|
|
93
|
-
"@tryghost/request": "0.1.
|
|
93
|
+
"@tryghost/request": "0.1.10",
|
|
94
94
|
"@tryghost/root-utils": "0.3.7",
|
|
95
95
|
"@tryghost/security": "0.2.13",
|
|
96
|
-
"@tryghost/session-service": "0.1.
|
|
96
|
+
"@tryghost/session-service": "0.1.34",
|
|
97
|
+
"@tryghost/settings-path-manager": "0.1.2",
|
|
97
98
|
"@tryghost/social-urls": "0.1.27",
|
|
98
99
|
"@tryghost/string": "0.1.21",
|
|
99
100
|
"@tryghost/tpl": "0.1.8",
|
|
100
101
|
"@tryghost/update-check-service": "0.2.5",
|
|
101
102
|
"@tryghost/url-utils": "2.0.4",
|
|
102
|
-
"@tryghost/validator": "0.1.
|
|
103
|
+
"@tryghost/validator": "0.1.9",
|
|
103
104
|
"@tryghost/version": "0.1.7",
|
|
104
105
|
"@tryghost/vhost-middleware": "1.0.19",
|
|
105
106
|
"@tryghost/zip": "1.1.18",
|
|
106
107
|
"amperize": "0.6.1",
|
|
107
|
-
"analytics-node": "
|
|
108
|
+
"analytics-node": "6.0.0",
|
|
108
109
|
"bluebird": "3.7.2",
|
|
109
110
|
"body-parser": "1.19.0",
|
|
110
111
|
"bookshelf": "1.2.0",
|
|
@@ -129,7 +130,7 @@
|
|
|
129
130
|
"ghost-storage-base": "1.0.0",
|
|
130
131
|
"glob": "7.2.0",
|
|
131
132
|
"got": "9.6.0",
|
|
132
|
-
"gscan": "4.
|
|
133
|
+
"gscan": "4.15.2",
|
|
133
134
|
"html-to-text": "5.1.1",
|
|
134
135
|
"image-size": "1.0.0",
|
|
135
136
|
"intl": "1.2.5",
|
|
@@ -144,28 +145,28 @@
|
|
|
144
145
|
"lodash": "4.17.21",
|
|
145
146
|
"luxon": "2.1.1",
|
|
146
147
|
"mailgun-js": "0.22.0",
|
|
147
|
-
"metascraper": "5.25.
|
|
148
|
-
"metascraper-author": "5.25.
|
|
149
|
-
"metascraper-description": "5.25.
|
|
150
|
-
"metascraper-image": "5.25.
|
|
151
|
-
"metascraper-logo": "5.25.
|
|
152
|
-
"metascraper-logo-favicon": "5.25.
|
|
153
|
-
"metascraper-publisher": "5.25.
|
|
154
|
-
"metascraper-title": "5.25.
|
|
155
|
-
"metascraper-url": "5.25.
|
|
148
|
+
"metascraper": "5.25.4",
|
|
149
|
+
"metascraper-author": "5.25.4",
|
|
150
|
+
"metascraper-description": "5.25.4",
|
|
151
|
+
"metascraper-image": "5.25.4",
|
|
152
|
+
"metascraper-logo": "5.25.4",
|
|
153
|
+
"metascraper-logo-favicon": "5.25.4",
|
|
154
|
+
"metascraper-publisher": "5.25.4",
|
|
155
|
+
"metascraper-title": "5.25.4",
|
|
156
|
+
"metascraper-url": "5.25.4",
|
|
156
157
|
"moment": "2.24.0",
|
|
157
158
|
"moment-timezone": "0.5.23",
|
|
158
159
|
"multer": "1.4.3",
|
|
159
160
|
"mysql": "2.18.1",
|
|
160
161
|
"nconf": "0.11.3",
|
|
161
162
|
"node-jose": "2.0.0",
|
|
162
|
-
"oembed-parser": "1.
|
|
163
|
+
"oembed-parser": "1.4.9",
|
|
163
164
|
"passport": "0.5.0",
|
|
164
165
|
"passport-google-oauth": "2.0.0",
|
|
165
166
|
"path-match": "1.2.4",
|
|
166
167
|
"probe-image-size": "5.0.0",
|
|
167
168
|
"rss": "1.2.2",
|
|
168
|
-
"sanitize-html": "2.
|
|
169
|
+
"sanitize-html": "2.6.0",
|
|
169
170
|
"semver": "7.3.5",
|
|
170
171
|
"stoppable": "1.1.0",
|
|
171
172
|
"tough-cookie": "4.0.0",
|
|
@@ -173,16 +174,16 @@
|
|
|
173
174
|
"xml": "1.0.1"
|
|
174
175
|
},
|
|
175
176
|
"optionalDependencies": {
|
|
176
|
-
"@tryghost/html-to-mobiledoc": "1.
|
|
177
|
+
"@tryghost/html-to-mobiledoc": "1.4.1",
|
|
177
178
|
"sqlite3": "5.0.2"
|
|
178
179
|
},
|
|
179
180
|
"devDependencies": {
|
|
180
181
|
"@lodder/grunt-postcss": "3.1.1",
|
|
181
182
|
"c8": "7.10.0",
|
|
182
183
|
"coffeescript": "2.6.1",
|
|
183
|
-
"cssnano": "5.0.
|
|
184
|
+
"cssnano": "5.0.12",
|
|
184
185
|
"eslint": "7.32.0",
|
|
185
|
-
"eslint-plugin-ghost": "2.
|
|
186
|
+
"eslint-plugin-ghost": "2.11.0",
|
|
186
187
|
"grunt": "1.4.1",
|
|
187
188
|
"grunt-bg-shell": "2.3.3",
|
|
188
189
|
"grunt-contrib-clean": "2.0.0",
|
|
@@ -200,7 +201,7 @@
|
|
|
200
201
|
"mock-knex": "0.4.10",
|
|
201
202
|
"nock": "13.2.1",
|
|
202
203
|
"papaparse": "5.3.1",
|
|
203
|
-
"postcss": "8.
|
|
204
|
+
"postcss": "8.4.4",
|
|
204
205
|
"rewire": "5.0.0",
|
|
205
206
|
"should": "13.2.3",
|
|
206
207
|
"sinon": "11.1.2",
|