ghost 5.130.0 → 5.130.2

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.
Files changed (31) hide show
  1. package/components/{tryghost-i18n-5.130.0.tgz → tryghost-i18n-5.130.2.tgz} +0 -0
  2. package/core/built/admin/assets/admin-x-activitypub/admin-x-activitypub.js +2 -2
  3. package/core/built/admin/assets/admin-x-activitypub/{index-rDFm98Ub.mjs → index-B8te98RZ.mjs} +22545 -16467
  4. package/core/built/admin/assets/admin-x-activitypub/{index-BhgdXgH_.mjs → index-C8qwgKWF.mjs} +2 -2
  5. package/core/built/admin/assets/admin-x-settings/{CodeEditorView-bO8i1M7l.mjs → CodeEditorView-CAtv7MlN.mjs} +2 -2
  6. package/core/built/admin/assets/admin-x-settings/admin-x-settings.js +1 -1
  7. package/core/built/admin/assets/admin-x-settings/{index-DIak5kz8.mjs → index-BVxh86CD.mjs} +180 -180
  8. package/core/built/admin/assets/admin-x-settings/{index-BeD9DTp3.mjs → index-DUhmXSBR.mjs} +2 -2
  9. package/core/built/admin/assets/admin-x-settings/{modals-DLPpqlUq.mjs → modals-B5dtfzsB.mjs} +310 -310
  10. package/core/built/admin/assets/{chunk.524.2443bfd380e6da0cbabd.js → chunk.524.1f2faf572078e5b86b09.js} +7 -7
  11. package/core/built/admin/assets/{chunk.582.434476dff5ddc79ed054.js → chunk.582.675905fe8f9be138fb19.js} +9 -9
  12. package/core/built/admin/assets/{chunk.728.214803966b81ffdb1acd.js → chunk.728.985c45ad584b4b91ca60.js} +124 -124
  13. package/core/built/admin/assets/{ghost-5d9c65b5c4ef960a664cd664b2616dea.js → ghost-280b83af263b51bc4d6ce5bd8f536096.js} +46 -53
  14. package/core/built/admin/assets/posts/posts.js +21688 -21763
  15. package/core/built/admin/assets/stats/stats.js +21635 -21706
  16. package/core/built/admin/assets/{vendor-c89102f24c3d9502e9db741509767580.js → vendor-aed0068cf9b67d042dd23a6343545b7b.js} +1 -1
  17. package/core/built/admin/index.html +5 -5
  18. package/core/frontend/web/middleware/frontend-caching.js +6 -1
  19. package/core/frontend/web/middleware/static-theme.js +3 -5
  20. package/core/server/data/tinybird/README.md +9 -14
  21. package/core/server/services/members/members-api/controllers/RouterController.js +28 -10
  22. package/core/server/services/members/members-api/utils/normalize-email.js +31 -0
  23. package/core/server/services/public-config/config.js +0 -1
  24. package/core/server/web/admin/app.js +5 -6
  25. package/core/server/web/shared/middleware/cache-control.js +2 -1
  26. package/core/shared/config/defaults.json +6 -0
  27. package/package.json +9 -9
  28. package/tsconfig.tsbuildinfo +1 -1
  29. package/yarn.lock +140 -95
  30. package/core/built/admin/assets/img/twitter-7a7a0ba12d9b5bfb8a2058764a827c31.svg +0 -4
  31. /package/core/built/admin/assets/{chunk.728.214803966b81ffdb1acd.js.LICENSE.txt → chunk.728.985c45ad584b4b91ca60.js.LICENSE.txt} +0 -0
@@ -9553,4 +9553,4 @@ e.default=class{constructor(e){if(this._data=new t.default,e)for(let t=0;t<e.len
9553
9553
  return this}get(e){let t=this._data[e]
9554
9554
  return t===r.UNDEFINED_KEY?void 0:t}set(e,t){return this._data[e]=t,this}delete(e){return this._data[e]=r.UNDEFINED_KEY,!0}}})
9555
9555
 
9556
- //# sourceMappingURL=vendor-1552b6fd843e2f460183ad9424be2a2d.map
9556
+ //# sourceMappingURL=vendor-326b46cbc2845d47f1e0af43ba21caec.map
@@ -6,7 +6,7 @@
6
6
  <title>Ghost</title>
7
7
 
8
8
 
9
- <meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%22%2C%22cdnUrl%22%3A%22%22%2C%22editorUrl%22%3A%22%22%2C%22rootURL%22%3A%22%22%2C%22locationType%22%3A%22trailing-hash%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%2C%22Array%22%3Atrue%2C%22String%22%3Atrue%2C%22Function%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_JQUERY_INTEGRATION%22%3Atrue%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%225.130%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22%40sentry%2Fember%22%3A%7B%22disablePerformance%22%3Atrue%2C%22sentry%22%3A%7B%7D%7D%2C%22ember-cli-mirage%22%3A%7B%22usingProxy%22%3Afalse%2C%22useDefaultPassthroughs%22%3Atrue%7D%2C%22exportApplicationGlobal%22%3Afalse%2C%22ember-load%22%3A%7B%22loadingIndicatorClass%22%3A%22ember-load-indicator%22%7D%2C%22editorFilename%22%3A%22koenig-lexical.umd.js%22%2C%22editorHash%22%3A%2237bd1e3e4d%22%2C%22adminXSettingsFilename%22%3A%22admin-x-settings.js%22%2C%22adminXSettingsHash%22%3A%2262b55e2aae%22%2C%22adminXActivitypubFilename%22%3A%22admin-x-activitypub.js%22%2C%22adminXActivitypubHash%22%3A%226d96d71fe8%22%2C%22postsFilename%22%3A%22posts.js%22%2C%22postsHash%22%3A%223ad9cd1892%22%2C%22statsFilename%22%3A%22stats.js%22%2C%22statsHash%22%3A%22701e8fc366%22%2C%22adminXActivitypubCustomUrl%22%3A%22https%3A%2F%2Fcdn.jsdelivr.net%2Fghost%2Fadmin-x-activitypub%400%2Fdist%2Fadmin-x-activitypub.js%22%7D" />
9
+ <meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%22%2C%22cdnUrl%22%3A%22%22%2C%22editorUrl%22%3A%22%22%2C%22rootURL%22%3A%22%22%2C%22locationType%22%3A%22trailing-hash%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%2C%22Array%22%3Atrue%2C%22String%22%3Atrue%2C%22Function%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_JQUERY_INTEGRATION%22%3Atrue%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%225.130%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22%40sentry%2Fember%22%3A%7B%22disablePerformance%22%3Atrue%2C%22sentry%22%3A%7B%7D%7D%2C%22ember-cli-mirage%22%3A%7B%22usingProxy%22%3Afalse%2C%22useDefaultPassthroughs%22%3Atrue%7D%2C%22exportApplicationGlobal%22%3Afalse%2C%22ember-load%22%3A%7B%22loadingIndicatorClass%22%3A%22ember-load-indicator%22%7D%2C%22editorFilename%22%3A%22koenig-lexical.umd.js%22%2C%22editorHash%22%3A%2237bd1e3e4d%22%2C%22adminXSettingsFilename%22%3A%22admin-x-settings.js%22%2C%22adminXSettingsHash%22%3A%223291c981c1%22%2C%22adminXActivitypubFilename%22%3A%22admin-x-activitypub.js%22%2C%22adminXActivitypubHash%22%3A%22b38d27bb5e%22%2C%22postsFilename%22%3A%22posts.js%22%2C%22postsHash%22%3A%229a7e1b885b%22%2C%22statsFilename%22%3A%22stats.js%22%2C%22statsHash%22%3A%225445ed6ca9%22%2C%22adminXActivitypubCustomUrl%22%3A%22https%3A%2F%2Fcdn.jsdelivr.net%2Fghost%2Fadmin-x-activitypub%400%2Fdist%2Fadmin-x-activitypub.js%22%7D" />
10
10
 
11
11
  <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1, minimal-ui, viewport-fit=cover" />
12
12
  <meta name="pinterest" content="nopin" />
@@ -47,9 +47,9 @@
47
47
 
48
48
  <div id="ember-basic-dropdown-wormhole"></div>
49
49
 
50
- <script src="assets/vendor-c89102f24c3d9502e9db741509767580.js"></script>
51
- <script src="assets/chunk.728.214803966b81ffdb1acd.js"></script>
52
- <script src="assets/chunk.524.2443bfd380e6da0cbabd.js"></script>
53
- <script src="assets/ghost-5d9c65b5c4ef960a664cd664b2616dea.js"></script>
50
+ <script src="assets/vendor-aed0068cf9b67d042dd23a6343545b7b.js"></script>
51
+ <script src="assets/chunk.728.985c45ad584b4b91ca60.js"></script>
52
+ <script src="assets/chunk.524.1f2faf572078e5b86b09.js"></script>
53
+ <script src="assets/ghost-280b83af263b51bc4d6ce5bd8f536096.js"></script>
54
54
  </body>
55
55
  </html>
@@ -51,6 +51,11 @@ const getMiddleware = async (getFreeTier = async () => {
51
51
  return shared.middleware.cacheControl('private')(req, res, next);
52
52
  }
53
53
 
54
+ // CASE: Never cache preview routes
55
+ if (req.path?.startsWith('/p/')) {
56
+ return shared.middleware.cacheControl('noCache')(req, res, next);
57
+ }
58
+
54
59
  // CASE: Cache member's content if this feature is enabled
55
60
  if (req.member && shouldCacheMembersContent) {
56
61
  // Set the 'cache-control' header to 'public'
@@ -74,4 +79,4 @@ const getMiddleware = async (getFreeTier = async () => {
74
79
  module.exports = {
75
80
  getMiddleware,
76
81
  calculateMemberTier // exported for testing
77
- };
82
+ };
@@ -59,12 +59,10 @@ function forwardToExpressStatic(req, res, next) {
59
59
  return next();
60
60
  }
61
61
 
62
- const configMaxAge = config.get('caching:theme:maxAge');
63
-
64
- // @NOTE: the maxAge config passed below are in milliseconds and the config
65
- // is specified in seconds. See https://github.com/expressjs/serve-static/issues/150 for more context
66
62
  express.static(themeEngine.getActive().path, {
67
- maxAge: (configMaxAge || configMaxAge === 0) ? configMaxAge : (365 * 24 * 60 * 60 * 1000) // Default to 1 year in ms
63
+ // @NOTE: the maxAge config passed below are in milliseconds and the config
64
+ // is specified in seconds. See https://github.com/expressjs/serve-static/issues/150 for more context
65
+ maxAge: config.get('caching:theme:maxAge') * 1000
68
66
  }
69
67
  )(req, res, next);
70
68
  }
@@ -31,7 +31,7 @@ with the following information.
31
31
 
32
32
  ### Config
33
33
  Sample config:
34
- ```json
34
+ ```jsonc
35
35
  {
36
36
  "someOtherConfigurationForEmail": {
37
37
  "transport": "SMTP",
@@ -40,25 +40,20 @@ Sample config:
40
40
  }
41
41
  },
42
42
  "tinybird": {
43
+ "workspaceId": "workspace-id-from-tinybird",
44
+ "adminToken": "admin-token-from-tinybird",
43
45
  "tracker": {
44
- "endpoint": "https://e.ghost.org/tb/web_analytics",
45
- "token": "xxxxx",
46
- "datasource": "analytics_events",
47
- "local": {
48
- "enabled": true,
49
- "token": "xxxxx",
50
- "endpoint": "http://localhost:7181/v0/events",
51
- "datasource": "analytics_events"
52
- }
46
+ // -- needs to be present, and required Traffic Analytics service running with correct setup
47
+ "endpoint": "http://localhost:3000/tb/web_analytics"
53
48
  },
54
49
  "stats": {
50
+ // -- optional override for site uuid
51
+ // "id": "106a623d-9792-4b63-acde-4a0c28ead3dc",
55
52
  "endpoint": "https://api.tinybird.co",
56
- "token": "xxxxx",
53
+ // -- tinybird local configuration (optional)
57
54
  "local": {
58
55
  "enabled": true,
59
- "token": "xxxxx",
60
- "endpoint": "http://localhost:7181",
61
- "datasource": "analytics_events"
56
+ "token": "local-stats-or-admin-token",
62
57
  }
63
58
  }
64
59
  }
@@ -4,6 +4,7 @@ const sanitizeHtml = require('sanitize-html');
4
4
  const {BadRequestError, NoPermissionError, UnauthorizedError, DisabledFeatureError, NotFoundError} = require('@tryghost/errors');
5
5
  const errors = require('@tryghost/errors');
6
6
  const {isEmail} = require('@tryghost/validator');
7
+ const normalizeEmail = require('../utils/normalize-email');
7
8
 
8
9
  const messages = {
9
10
  emailRequired: 'Email is required.',
@@ -585,6 +586,23 @@ module.exports = class RouterController {
585
586
  });
586
587
  }
587
588
 
589
+ // Normalize email to prevent homograph attacks
590
+ let normalizedEmail;
591
+
592
+ try {
593
+ normalizedEmail = normalizeEmail(email);
594
+
595
+ if (normalizedEmail !== email) {
596
+ logging.info(`Email normalized from ${email} to ${normalizedEmail} for magic link`);
597
+ }
598
+ } catch (err) {
599
+ logging.error(`Failed to normalize [${email}]: ${err.message}`);
600
+
601
+ throw new errors.BadRequestError({
602
+ message: tpl(messages.invalidEmail)
603
+ });
604
+ }
605
+
588
606
  if (honeypot) {
589
607
  logging.warn('Honeypot field filled, this is likely a bot');
590
608
 
@@ -606,9 +624,9 @@ module.exports = class RouterController {
606
624
 
607
625
  try {
608
626
  if (emailType === 'signup' || emailType === 'subscribe') {
609
- await this._handleSignup(req, referrer);
627
+ await this._handleSignup(req, normalizedEmail, referrer);
610
628
  } else {
611
- await this._handleSignin(req, referrer);
629
+ await this._handleSignin(req, normalizedEmail, referrer);
612
630
  }
613
631
 
614
632
  res.writeHead(201);
@@ -626,7 +644,7 @@ module.exports = class RouterController {
626
644
  }
627
645
  }
628
646
 
629
- async _handleSignup(req, referrer = null) {
647
+ async _handleSignup(req, normalizedEmail, referrer = null) {
630
648
  if (!this._allowSelfSignup()) {
631
649
  if (this._settingsCache.get('members_signup_access') === 'paid') {
632
650
  throw new errors.BadRequestError({
@@ -640,14 +658,14 @@ module.exports = class RouterController {
640
658
  }
641
659
 
642
660
  const blockedEmailDomains = this._settingsCache.get('all_blocked_email_domains');
643
- const emailDomain = req.body.email.split('@')[1]?.toLowerCase();
661
+ const emailDomain = normalizedEmail.split('@')[1]?.toLowerCase();
644
662
  if (emailDomain && blockedEmailDomains.includes(emailDomain)) {
645
663
  throw new errors.BadRequestError({
646
664
  message: tpl(messages.blockedEmailDomain)
647
665
  });
648
666
  }
649
667
 
650
- const {email, emailType} = req.body;
668
+ const {emailType} = req.body;
651
669
 
652
670
  const tokenData = {
653
671
  labels: req.body.labels,
@@ -657,13 +675,13 @@ module.exports = class RouterController {
657
675
  attribution: await this._memberAttributionService.getAttribution(req.body.urlHistory)
658
676
  };
659
677
 
660
- return await this._sendEmailWithMagicLink({email, tokenData, requestedType: emailType, referrer});
678
+ return await this._sendEmailWithMagicLink({email: normalizedEmail, tokenData, requestedType: emailType, referrer});
661
679
  }
662
680
 
663
- async _handleSignin(req, referrer = null) {
664
- const {email, emailType} = req.body;
681
+ async _handleSignin(req, normalizedEmail, referrer = null) {
682
+ const {emailType} = req.body;
665
683
 
666
- const member = await this._memberRepository.get({email});
684
+ const member = await this._memberRepository.get({email: normalizedEmail});
667
685
 
668
686
  if (!member) {
669
687
  throw new errors.BadRequestError({
@@ -672,7 +690,7 @@ module.exports = class RouterController {
672
690
  }
673
691
 
674
692
  const tokenData = {};
675
- return await this._sendEmailWithMagicLink({email, tokenData, requestedType: emailType, referrer});
693
+ return await this._sendEmailWithMagicLink({email: normalizedEmail, tokenData, requestedType: emailType, referrer});
676
694
  }
677
695
 
678
696
  /**
@@ -0,0 +1,31 @@
1
+ const punycode = require('punycode/');
2
+
3
+ /**
4
+ * Normalizes email addresses by converting Unicode domains to ASCII (punycode)
5
+ * This prevents homograph attacks where Unicode characters are used to spoof
6
+ * domains
7
+ *
8
+ * @param {string} email The email address to normalize
9
+ * @returns {string} The normalized email address
10
+ * @throws {Error} When punycode conversion fails
11
+ */
12
+ function normalizeEmail(email) {
13
+ if (!email || typeof email !== 'string') {
14
+ return null;
15
+ }
16
+
17
+ const atIndex = email.lastIndexOf('@');
18
+
19
+ if (atIndex === -1) {
20
+ return email;
21
+ }
22
+
23
+ const localPart = email.substring(0, atIndex);
24
+ const domainPart = email.substring(atIndex + 1);
25
+
26
+ const asciiDomain = punycode.toASCII(domainPart);
27
+
28
+ return `${localPart}@${asciiDomain}`;
29
+ }
30
+
31
+ module.exports = normalizeEmail;
@@ -29,7 +29,6 @@ module.exports = function getConfigProperties() {
29
29
  configProperties.exploreTestimonialsUrl = config.get('explore:testimonials_url');
30
30
  }
31
31
 
32
- // WIP tinybird stats feature - it's entirely config driven instead of using an alpha flag for now
33
32
  if (config.get('tinybird') && config.get('tinybird:stats')) {
34
33
  const statsConfig = config.get('tinybird:stats');
35
34
  const siteUuid = statsConfig.id || settingsCache.get('site_uuid');
@@ -19,16 +19,15 @@ module.exports = function setupAdminApp() {
19
19
  const adminApp = express('admin');
20
20
 
21
21
  // Admin assets
22
- // @TODO ensure this gets a local 404 error handler
23
- const configMaxAge = config.get('caching:admin:maxAge');
24
22
  // @NOTE: when we start working on HTTP/3 optimizations the immutable headers
25
23
  // produced below should be split into separate 'Cache-Control' entry.
26
24
  // For reference see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#validation_2
27
- // @NOTE: the maxAge config passed below are in milliseconds and the config
28
- // is specified in seconds. See https://github.com/expressjs/serve-static/issues/150 for more context
25
+
29
26
  adminApp.use('/assets', serveStatic(
30
27
  path.join(config.get('paths').adminAssets, 'assets'), {
31
- maxAge: (configMaxAge || configMaxAge === 0) ? configMaxAge : (365 * 24 * 60 * 60 * 1000), // Default to 1 year in ms
28
+ // @NOTE: the maxAge config passed below are in milliseconds and the config
29
+ // is specified in seconds. See https://github.com/expressjs/serve-static/issues/150 for more context
30
+ maxAge: config.get('caching:admin:maxAge') * 1000,
32
31
  immutable: true,
33
32
  fallthrough: false
34
33
  }
@@ -94,4 +93,4 @@ module.exports = function setupAdminApp() {
94
93
  debug('Admin setup end');
95
94
 
96
95
  return adminApp;
97
- };
96
+ };
@@ -9,7 +9,7 @@
9
9
  const isString = require('lodash/isString');
10
10
 
11
11
  /**
12
- * @param {'public'|'private'} profile Use "private" if you do not want caching
12
+ * @param {'public'|'private'|'noCache'} profile Use "private" if you do not want caching
13
13
  * @param {object} [options]
14
14
  * @param {number} [options.maxAge] The max-age in seconds to use when profile is "public"
15
15
  * @param {number} [options.staleWhileRevalidate] The stale-while-revalidate in seconds to use when profile is "public"
@@ -24,6 +24,7 @@ const cacheControl = (profile, options = {maxAge: 0}) => {
24
24
 
25
25
  const profiles = {
26
26
  public: publicOptions.filter(option => option).join(', '),
27
+ noCache: 'no-cache, max-age=0, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0',
27
28
  private: 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'
28
29
  };
29
30
 
@@ -168,6 +168,12 @@
168
168
  },
169
169
  "commentsCountAPI": {
170
170
  "maxAge": 0
171
+ },
172
+ "admin": {
173
+ "maxAge": 31536000
174
+ },
175
+ "theme": {
176
+ "maxAge": 31536000
171
177
  }
172
178
  },
173
179
  "optimization": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ghost",
3
- "version": "5.130.0",
3
+ "version": "5.130.2",
4
4
  "description": "The professional publishing platform",
5
5
  "author": "Ghost Foundation",
6
6
  "homepage": "https://ghost.org",
@@ -86,7 +86,7 @@
86
86
  "@tryghost/helpers": "1.1.97",
87
87
  "@tryghost/html-to-plaintext": "1.0.4",
88
88
  "@tryghost/http-cache-utils": "0.1.20",
89
- "@tryghost/i18n": "file:components/tryghost-i18n-5.130.0.tgz",
89
+ "@tryghost/i18n": "file:components/tryghost-i18n-5.130.2.tgz",
90
90
  "@tryghost/image-transform": "1.4.6",
91
91
  "@tryghost/job-manager": "1.0.3",
92
92
  "@tryghost/kg-card-factory": "5.1.2",
@@ -136,9 +136,9 @@
136
136
  "clsx": "2.1.1",
137
137
  "cluster-key-slot": "1.1.2",
138
138
  "common-tags": "1.8.2",
139
- "compression": "1.8.0",
139
+ "compression": "1.8.1",
140
140
  "connect-slashes": "1.4.0",
141
- "cookie-session": "2.1.0",
141
+ "cookie-session": "2.1.1",
142
142
  "cookies": "0.9.1",
143
143
  "cors": "2.8.5",
144
144
  "countries-and-timezones": "3.8.0",
@@ -155,9 +155,9 @@
155
155
  "express-lazy-router": "1.0.6",
156
156
  "express-query-boolean": "2.0.0",
157
157
  "express-queue": "0.0.13",
158
- "express-session": "1.18.1",
158
+ "express-session": "1.18.2",
159
159
  "file-type": "16.5.4",
160
- "form-data": "4.0.3",
160
+ "form-data": "4.0.4",
161
161
  "fs-extra": "11.3.0",
162
162
  "ghost-storage-base": "1.0.0",
163
163
  "glob": "8.1.0",
@@ -196,7 +196,7 @@
196
196
  "mime-types": "2.1.35",
197
197
  "moment": "2.24.0",
198
198
  "moment-timezone": "0.5.45",
199
- "multer": "2.0.1",
199
+ "multer": "2.0.2",
200
200
  "mysql2": "3.14.2",
201
201
  "nconf": "0.13.0",
202
202
  "node-fetch": "2.7.0",
@@ -245,7 +245,7 @@
245
245
  "detect-newline": "3.1.0",
246
246
  "expect": "29.7.0",
247
247
  "find-root": "1.1.0",
248
- "form-data": "4.0.3",
248
+ "form-data": "4.0.4",
249
249
  "html-minifier": "4.0.0",
250
250
  "html-validate": "8.29.0",
251
251
  "inquirer": "8.2.6",
@@ -274,7 +274,7 @@
274
274
  "jackspeak": "2.3.6",
275
275
  "moment": "2.24.0",
276
276
  "moment-timezone": "0.5.45",
277
- "@tryghost/i18n": "file:components/tryghost-i18n-5.130.0.tgz"
277
+ "@tryghost/i18n": "file:components/tryghost-i18n-5.130.2.tgz"
278
278
  },
279
279
  "nx": {
280
280
  "targets": {