ghost 4.48.3 → 4.48.5

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.
@@ -7,7 +7,7 @@ const config = require('../../../shared/config');
7
7
  const renderer = require('../../services/rendering');
8
8
 
9
9
  // @TODO: make this properly shared code
10
- const {prepareError, prepareStack} = require('@tryghost/mw-error-handler');
10
+ const {prepareError, prepareErrorCacheControl, prepareStack} = require('@tryghost/mw-error-handler');
11
11
 
12
12
  const messages = {
13
13
  oopsErrorTemplateHasError: 'Oops, seems there is an error in the error template.',
@@ -86,6 +86,8 @@ const themeErrorRenderer = (err, req, res, next) => {
86
86
  module.exports.handleThemeResponse = [
87
87
  // Make sure the error can be served
88
88
  prepareError,
89
+ // Add cache-control header
90
+ prepareErrorCacheControl(),
89
91
  // Handle the error in Sentry
90
92
  sentry.errorHandler,
91
93
  // Format the stack for the user
@@ -82,7 +82,7 @@ module.exports = function setupSiteApp(options = {}) {
82
82
  // /member/.well-known/* serves files (e.g. jwks.json) so it needs to be mounted before the prettyUrl mw to avoid trailing slashes
83
83
  siteApp.use(
84
84
  '/members/.well-known',
85
- shared.middleware.cacheControl('public', {maxAge: 60 * 60 * 24}),
85
+ shared.middleware.cacheControl('public', {maxAge: constants.ONE_DAY_S}),
86
86
  (req, res, next) => membersService.api.middleware.wellKnown(req, res, next)
87
87
  );
88
88
 
@@ -37,6 +37,8 @@ module.exports.contentVersion = (req, res, next) => {
37
37
  if (req.header('accept-version')) {
38
38
  res.header('Content-Version', `v${ghostVersion.safe}`);
39
39
  }
40
+
41
+ res.vary('Accept-Version');
40
42
  next();
41
43
  };
42
44
 
@@ -16,9 +16,15 @@ module.exports = function setupAdminApp() {
16
16
  // Admin assets
17
17
  // @TODO ensure this gets a local 404 error handler
18
18
  const configMaxAge = config.get('caching:admin:maxAge');
19
+ // @NOTE: when we start working on HTTP/3 optimizations the immutable headers
20
+ // produced below should be split into separate 'Cache-Control' entry.
21
+ // For reference see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#validation_2
19
22
  adminApp.use('/assets', serveStatic(
20
- config.get('paths').clientAssets,
21
- {maxAge: (configMaxAge || configMaxAge === 0) ? configMaxAge : constants.ONE_YEAR_MS, fallthrough: false}
23
+ config.get('paths').clientAssets, {
24
+ maxAge: (configMaxAge || configMaxAge === 0) ? configMaxAge : constants.ONE_YEAR_MS,
25
+ immutable: true,
26
+ fallthrough: false
27
+ }
22
28
  ));
23
29
 
24
30
  // Ember CLI's live-reload script
@@ -21,8 +21,10 @@ module.exports = function setupApiApp() {
21
21
  // Query parsing
22
22
  apiApp.use(boolParser());
23
23
 
24
- // API shouldn't be cached
25
- apiApp.use(shared.middleware.cacheControl('private'));
24
+ // Content API should allow public caching
25
+ apiApp.use(shared.middleware.cacheControl('public', {
26
+ maxAge: 0
27
+ }));
26
28
 
27
29
  // Routing
28
30
  apiApp.use(routes());
@@ -21,8 +21,10 @@ module.exports = function setupApiApp() {
21
21
  // Query parsing
22
22
  apiApp.use(boolParser());
23
23
 
24
- // API shouldn't be cached
25
- apiApp.use(shared.middleware.cacheControl('private'));
24
+ // Content API should allow public caching
25
+ apiApp.use(shared.middleware.cacheControl('public', {
26
+ maxAge: 0
27
+ }));
26
28
 
27
29
  // Routing
28
30
  apiApp.use(routes());
@@ -21,8 +21,10 @@ module.exports = function setupApiApp() {
21
21
  // Query parsing
22
22
  apiApp.use(boolParser());
23
23
 
24
- // API shouldn't be cached
25
- apiApp.use(shared.middleware.cacheControl('private'));
24
+ // Content API should allow public caching
25
+ apiApp.use(shared.middleware.cacheControl('public', {
26
+ maxAge: 0
27
+ }));
26
28
 
27
29
  // Routing
28
30
  apiApp.use(routes());
@@ -44,7 +44,7 @@ module.exports = function setupMembersApp() {
44
44
  membersApp.get('/api/session', middleware.getIdentityToken);
45
45
  membersApp.get('/api/offers/:id', middleware.getOfferData);
46
46
  membersApp.delete('/api/session', middleware.deleteSession);
47
- membersApp.get('/api/site', middleware.getMemberSiteData);
47
+ membersApp.get('/api/site', shared.middleware.cacheControl('noCacheDynamic'), middleware.getMemberSiteData);
48
48
 
49
49
  // NOTE: this is wrapped in a function to ensure we always go via the getter
50
50
  membersApp.post('/api/send-magic-link', bodyParser.json(), shared.middleware.brute.membersAuth, (req, res, next) => membersService.api.middleware.sendMagicLink(req, res, next));
@@ -29,26 +29,13 @@ module.exports = {
29
29
  })(req, res, next);
30
30
  },
31
31
  /**
32
- * block per user
33
- * username === email!
32
+ * block per ip
34
33
  */
35
34
  userLogin(req, res, next) {
36
35
  return spamPrevention.userLogin().getMiddleware({
37
36
  ignoreIP: false,
38
37
  key(_req, _res, _next) {
39
- if (_req.body.username) {
40
- return _next(`${_req.body.username}login`);
41
- }
42
-
43
- if (_req.body.authorizationCode) {
44
- return _next(`${_req.body.authorizationCode}login`);
45
- }
46
-
47
- if (_req.body.refresh_token) {
48
- return _next(`${_req.body.refresh_token}login`);
49
- }
50
-
51
- return _next();
38
+ return _next('user_login');
52
39
  }
53
40
  })(req, res, next);
54
41
  },
@@ -7,16 +7,18 @@
7
7
  // Allows each app to declare its own default caching rules
8
8
 
9
9
  const isString = require('lodash/isString');
10
+ const {cacheControlValues} = require('@tryghost/http-cache-utils');
10
11
 
11
12
  /**
12
- * @param {'public'|'private'} profile Use "private" if you do not want caching
13
+ * @param {'public'|'private'|'noCacheDynamic'} profile Use "private" if you do not want caching
13
14
  * @param {object} [options]
14
15
  * @param {number} [options.maxAge] The max-age in seconds to use when profile is "public"
15
16
  */
16
17
  const cacheControl = (profile, options = {maxAge: 0}) => {
17
18
  const profiles = {
18
19
  public: `public, max-age=${options.maxAge}`,
19
- private: 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'
20
+ private: 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0',
21
+ noCacheDynamic: cacheControlValues.noCacheDynamic
20
22
  };
21
23
 
22
24
  let output;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ghost",
3
- "version": "4.48.3",
3
+ "version": "4.48.5",
4
4
  "description": "The professional publishing platform",
5
5
  "author": "Ghost Foundation",
6
6
  "homepage": "https://ghost.org",
@@ -73,6 +73,7 @@
73
73
  "@tryghost/errors": "1.2.12",
74
74
  "@tryghost/express-dynamic-redirects": "0.2.11",
75
75
  "@tryghost/helpers": "1.1.64",
76
+ "@tryghost/http-cache-utils": "0.1.3",
76
77
  "@tryghost/image-transform": "1.0.30",
77
78
  "@tryghost/job-manager": "0.8.22",
78
79
  "@tryghost/kg-card-factory": "3.1.3",
@@ -93,7 +94,7 @@
93
94
  "@tryghost/metrics": "1.0.11",
94
95
  "@tryghost/minifier": "0.1.13",
95
96
  "@tryghost/mw-api-version-mismatch": "0.1.1",
96
- "@tryghost/mw-error-handler": "0.2.2",
97
+ "@tryghost/mw-error-handler": "0.2.5",
97
98
  "@tryghost/mw-session-from-token": "0.1.30",
98
99
  "@tryghost/nodemailer": "0.3.22",
99
100
  "@tryghost/nql": "0.9.2",
package/yarn.lock CHANGED
@@ -1983,6 +1983,11 @@
1983
1983
  "@tryghost/mobiledoc-kit" "^0.12.4-ghost.1"
1984
1984
  jsdom "^18.0.0"
1985
1985
 
1986
+ "@tryghost/http-cache-utils@0.1.3":
1987
+ version "0.1.3"
1988
+ resolved "https://registry.yarnpkg.com/@tryghost/http-cache-utils/-/http-cache-utils-0.1.3.tgz#a3a07e55dbe3a62b7d51e98f19c063d03a1ef804"
1989
+ integrity sha512-QganheP/zhcpFnDLPJYlQ4gBIhd+lAEMh8byx7ocCPM37nuEQ3zlmcM6KzDfUmKYwU+5oI/ya/0Wn0kmnyZ37A==
1990
+
1986
1991
  "@tryghost/http-stream@^0.1.8":
1987
1992
  version "0.1.8"
1988
1993
  resolved "https://registry.yarnpkg.com/@tryghost/http-stream/-/http-stream-0.1.8.tgz#a50bea2eff582c86aba08ecfa1c32b24902d8cfb"
@@ -2299,13 +2304,14 @@
2299
2304
  resolved "https://registry.yarnpkg.com/@tryghost/mw-api-version-mismatch/-/mw-api-version-mismatch-0.1.1.tgz#913c8941ebe274eac4c3ac872fbe6268534f0003"
2300
2305
  integrity sha512-N1H3P/ua7MCJTQrhFd6RjBFL95pjB+y3Ih1ZyKToBzicU3RShLUsgVlBC7YNaJVGFG/RYCImzlm09QCV8qwgpg==
2301
2306
 
2302
- "@tryghost/mw-error-handler@0.2.2":
2303
- version "0.2.2"
2304
- resolved "https://registry.yarnpkg.com/@tryghost/mw-error-handler/-/mw-error-handler-0.2.2.tgz#ab507e8b9079b6cbcbef2ac3fee4266342188165"
2305
- integrity sha512-9J6d1gce+PzdLkSGxap5oWjG3INb3J9QLoC4NHXOqIGZ+7GERlao3q6AFVBo5xUBoUzkd+Q7+3ZQfeLarNEwUA==
2307
+ "@tryghost/mw-error-handler@0.2.5":
2308
+ version "0.2.5"
2309
+ resolved "https://registry.yarnpkg.com/@tryghost/mw-error-handler/-/mw-error-handler-0.2.5.tgz#2a67fe0d8c5402e9261d270c47c76cfcdc71974d"
2310
+ integrity sha512-jl/CLpVFQygXGbjfuznQYe+VF6xT0YPixcT4LfFKN+H/Kpm+8/MIDLzfAAnxJDlIM4w5Ux1YQYAQMtsbU0rxqg==
2306
2311
  dependencies:
2307
2312
  "@tryghost/debug" "^0.1.9"
2308
2313
  "@tryghost/errors" "1.2.12"
2314
+ "@tryghost/http-cache-utils" "0.1.3"
2309
2315
  "@tryghost/tpl" "^0.1.8"
2310
2316
  lodash "^4.17.21"
2311
2317
  semver "^7.3.6"