ghost 6.0.8 → 6.0.10

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 (27) hide show
  1. package/components/tryghost-i18n-6.0.10.tgz +0 -0
  2. package/core/built/admin/assets/admin-x-activitypub/admin-x-activitypub.js +1 -1
  3. package/core/built/admin/assets/admin-x-activitypub/{index-1EXYCtPI.mjs → index-XhNX0QuF.mjs} +8144 -8115
  4. package/core/built/admin/assets/admin-x-activitypub/{index-If44c6h0.mjs → index-wBqnq7A5.mjs} +2 -2
  5. package/core/built/admin/assets/admin-x-settings/{CodeEditorView-CzXlGImM.mjs → CodeEditorView-BDBDWpWl.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-RKA3H0Lh.mjs → index-BB7hgOf0.mjs} +2 -2
  8. package/core/built/admin/assets/admin-x-settings/{index-D2pIApbM.mjs → index-DsbJfrQ7.mjs} +5494 -5426
  9. package/core/built/admin/assets/admin-x-settings/{modals-D0f6kxWg.mjs → modals-CCpr5VWU.mjs} +8807 -8799
  10. package/core/built/admin/assets/{chunk.397.1904882a4a78e2922f07.js → chunk.397.e5d027e53a68dff31d76.js} +2 -2
  11. package/core/built/admin/assets/{chunk.524.099dcd3975a0e60c5579.js → chunk.524.695215c994f8cbf547d3.js} +6 -6
  12. package/core/built/admin/assets/{chunk.582.6830378a89a17aeedd0b.js → chunk.582.a949b80543caba37906c.js} +9 -9
  13. package/core/built/admin/assets/{ghost-138bb4718f8b9d666bdd7a2b45330d58.js → ghost-9c608430440a10746540adb7d2cd0f31.js} +12 -13
  14. package/core/built/admin/assets/posts/posts.js +31626 -31100
  15. package/core/built/admin/assets/stats/stats.js +31848 -31322
  16. package/core/built/admin/index.html +4 -4
  17. package/core/server/lib/lexical.js +2 -1
  18. package/core/server/lib/request-external.js +7 -1
  19. package/core/server/services/email-service/EmailRenderer.js +7 -0
  20. package/core/server/services/koenig/node-renderers/html-renderer.js +8 -1
  21. package/core/server/services/oembed/OEmbedService.js +6 -11
  22. package/core/shared/labs.js +2 -1
  23. package/package.json +9 -9
  24. package/tsconfig.tsbuildinfo +1 -1
  25. package/yarn.lock +108 -140
  26. package/components/tryghost-i18n-6.0.8.tgz +0 -0
  27. /package/core/built/admin/assets/{chunk.397.1904882a4a78e2922f07.js.LICENSE.txt → chunk.397.e5d027e53a68dff31d76.js.LICENSE.txt} +0 -0
@@ -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%226.0%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%22eeba8b2d8c%22%2C%22adminXActivitypubFilename%22%3A%22admin-x-activitypub.js%22%2C%22adminXActivitypubHash%22%3A%2236cc1964d0%22%2C%22postsFilename%22%3A%22posts.js%22%2C%22postsHash%22%3A%221289bfe662%22%2C%22statsFilename%22%3A%22stats.js%22%2C%22statsHash%22%3A%220049e3950f%22%2C%22adminXActivitypubRemoteConfigUrl%22%3A%22%2F.ghost%2Factivitypub%2Fstable%2Fclient-config%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%226.0%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%22b272efcbc4%22%2C%22adminXActivitypubFilename%22%3A%22admin-x-activitypub.js%22%2C%22adminXActivitypubHash%22%3A%2258c4bfa71b%22%2C%22postsFilename%22%3A%22posts.js%22%2C%22postsHash%22%3A%22336ecd7f7c%22%2C%22statsFilename%22%3A%22stats.js%22%2C%22statsHash%22%3A%22a2e0991d78%22%2C%22adminXActivitypubRemoteConfigUrl%22%3A%22%2F.ghost%2Factivitypub%2Fstable%2Fclient-config%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" />
@@ -48,8 +48,8 @@
48
48
  <div id="ember-basic-dropdown-wormhole"></div>
49
49
 
50
50
  <script src="assets/vendor-aed0068cf9b67d042dd23a6343545b7b.js"></script>
51
- <script src="assets/chunk.397.1904882a4a78e2922f07.js"></script>
52
- <script src="assets/chunk.524.099dcd3975a0e60c5579.js"></script>
53
- <script src="assets/ghost-138bb4718f8b9d666bdd7a2b45330d58.js"></script>
51
+ <script src="assets/chunk.397.e5d027e53a68dff31d76.js"></script>
52
+ <script src="assets/chunk.524.695215c994f8cbf547d3.js"></script>
53
+ <script src="assets/ghost-9c608430440a10746540adb7d2cd0f31.js"></script>
54
54
  </body>
55
55
  </html>
@@ -93,7 +93,8 @@ module.exports = {
93
93
  },
94
94
  feature: {
95
95
  contentVisibility: labs.isSet('contentVisibility'),
96
- emailCustomization: true // force on until Koenig has been bumped
96
+ emailCustomization: true, // force on until Koenig has been bumped
97
+ emailUniqueid: labs.isSet('emailUniqueid')
97
98
  },
98
99
  nodeRenderers: this.customNodeRenderers
99
100
  }, userOptions);
@@ -1,4 +1,9 @@
1
- const got = require('got');
1
+ /**
2
+ * @typedef {import('got').Got} Got
3
+ * @typedef {import('got').ExtendOptions} ExtendOptions
4
+ */
5
+
6
+ const got = /** @type {Got} */ (/** @type {unknown} */ (require('got')));
2
7
  const dnsPromises = require('dns').promises;
3
8
  const errors = require('@tryghost/errors');
4
9
  const config = require('../../shared/config');
@@ -66,6 +71,7 @@ async function disableRetries(options) {
66
71
 
67
72
  // same as our normal request lib but if any request in a redirect chain resolves
68
73
  // to a private IP address it will be blocked before the request is made.
74
+ /** @type {ExtendOptions} */
69
75
  const gotOpts = {
70
76
  headers: {
71
77
  'user-agent': 'Ghost(https://github.com/TryGhost/Ghost)'
@@ -774,6 +774,13 @@ class EmailRenderer {
774
774
  return this.createUnsubscribeUrl(member.uuid, {newsletterUuid});
775
775
  },
776
776
  required: true // Used in email headers
777
+ },
778
+ // Unique ID used for ad images to bypass ESP image proxies
779
+ {
780
+ id: 'uniqueid',
781
+ getValue: () => {
782
+ return crypto.randomUUID();
783
+ }
777
784
  }
778
785
  ];
779
786
 
@@ -1,6 +1,7 @@
1
1
  const {addCreateDocumentOption} = require('../render-utils/add-create-document-option');
2
2
  const {renderEmptyContainer} = require('../render-utils/render-empty-container');
3
3
  const {renderWithVisibility} = require('../render-utils/visibility');
4
+ const {wrapReplacementStrings} = require('../render-utils/replacement-strings');
4
5
 
5
6
  function renderHtmlNode(node, options = {}) {
6
7
  addCreateDocumentOption(options);
@@ -12,7 +13,13 @@ function renderHtmlNode(node, options = {}) {
12
13
  return renderEmptyContainer(document);
13
14
  }
14
15
 
15
- const wrappedHtml = `\n<!--kg-card-begin: html-->\n${html}\n<!--kg-card-end: html-->\n`;
16
+ // Wrap replacement strings like {uniqueid} with %% for email processing
17
+ // Only wrap if emailUniqueid labs flag is enabled
18
+ let processedHtml = html;
19
+ if (options.feature?.emailUniqueid) {
20
+ processedHtml = wrapReplacementStrings(html);
21
+ }
22
+ const wrappedHtml = `\n<!--kg-card-begin: html-->\n${processedHtml}\n<!--kg-card-end: html-->\n`;
16
23
 
17
24
  const textarea = document.createElement('textarea');
18
25
  textarea.value = wrappedHtml;
@@ -1,3 +1,6 @@
1
+ // native fetch is not allowed in this file, use `this.externalRequest` instead to avoid SSRF
2
+ /* eslint no-restricted-globals: ["error", "fetch"] */
3
+
1
4
  const errors = require('@tryghost/errors');
2
5
  const tpl = require('@tryghost/tpl');
3
6
  const logging = require('@tryghost/logging');
@@ -59,7 +62,7 @@ const findUrlWithProvider = (url) => {
59
62
  */
60
63
 
61
64
  /**
62
- * @typedef {(url: string, config: Object) => Promise} IExternalRequest
65
+ * @typedef {import('got').GotRequestFunction} IExternalRequest
63
66
  */
64
67
 
65
68
  /**
@@ -128,20 +131,12 @@ class OEmbedService {
128
131
  }
129
132
 
130
133
  /**
131
- * Fetches the image buffer from a URL using fetch
134
+ * Fetches the image buffer from a URL using this.externalRequest
132
135
  * @param {String} imageUrl - URL of the image to fetch
133
136
  * @returns {Promise<Buffer>} - Promise resolving to the image buffer
134
137
  */
135
138
  async fetchImageBuffer(imageUrl) {
136
- const response = await fetch(imageUrl);
137
-
138
- if (!response.ok) {
139
- throw Error(`Failed to fetch image: ${response.statusText}`);
140
- }
141
-
142
- const arrayBuffer = await response.arrayBuffer();
143
-
144
- const buffer = Buffer.from(arrayBuffer);
139
+ const buffer = await this.externalRequest(imageUrl).buffer();
145
140
  return buffer;
146
141
  }
147
142
 
@@ -49,7 +49,8 @@ const PRIVATE_FEATURES = [
49
49
  'emailCustomization',
50
50
  'membersSigninOTC',
51
51
  'tagsX',
52
- 'utmTracking'
52
+ 'utmTracking',
53
+ 'emailUniqueid'
53
54
  ];
54
55
 
55
56
  module.exports.GA_KEYS = [...GA_FEATURES];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ghost",
3
- "version": "6.0.8",
3
+ "version": "6.0.10",
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-6.0.8.tgz",
89
+ "@tryghost/i18n": "file:components/tryghost-i18n-6.0.10.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",
@@ -144,7 +144,7 @@
144
144
  "csso": "5.0.5",
145
145
  "csv-writer": "1.6.0",
146
146
  "date-fns": "2.30.0",
147
- "dompurify": "3.2.6",
147
+ "dompurify": "3.2.7",
148
148
  "downsize": "0.0.8",
149
149
  "entities": "4.5.0",
150
150
  "express": "4.21.2",
@@ -196,7 +196,7 @@
196
196
  "moment": "2.24.0",
197
197
  "moment-timezone": "0.5.45",
198
198
  "multer": "2.0.2",
199
- "mysql2": "3.14.2",
199
+ "mysql2": "3.15.0",
200
200
  "nconf": "0.13.0",
201
201
  "node-fetch": "2.7.0",
202
202
  "node-jose": "2.2.0",
@@ -214,7 +214,7 @@
214
214
  "stripe": "8.222.0",
215
215
  "superagent": "5.3.1",
216
216
  "superagent-throttle": "1.0.1",
217
- "terser": "5.43.1",
217
+ "terser": "5.44.0",
218
218
  "tiny-glob": "0.2.9",
219
219
  "ua-parser-js": "1.0.41",
220
220
  "xml": "1.0.1"
@@ -225,14 +225,14 @@
225
225
  },
226
226
  "devDependencies": {
227
227
  "@actions/core": "1.11.1",
228
- "@playwright/test": "1.54.1",
228
+ "@playwright/test": "1.55.0",
229
229
  "@prettier/sync": "0.6.1",
230
230
  "@tryghost/express-test": "0.15.0",
231
231
  "@tryghost/webhook-mock-receiver": "0.2.17",
232
232
  "@types/bookshelf": "1.2.9",
233
233
  "@types/common-tags": "1.8.4",
234
234
  "@types/jsonwebtoken": "9.0.10",
235
- "@types/node": "22.18.3",
235
+ "@types/node": "22.18.6",
236
236
  "@types/node-jose": "1.1.13",
237
237
  "@types/nodemailer": "6.4.19",
238
238
  "@types/sinon": "17.0.4",
@@ -262,7 +262,7 @@
262
262
  "should": "13.2.3",
263
263
  "sinon": "18.0.1",
264
264
  "supertest": "6.3.4",
265
- "tmp": "0.2.3",
265
+ "tmp": "0.2.5",
266
266
  "toml": "3.0.0",
267
267
  "tsx": "4.20.5",
268
268
  "typescript": "5.8.3"
@@ -273,7 +273,7 @@
273
273
  "jackspeak": "2.3.6",
274
274
  "moment": "2.24.0",
275
275
  "moment-timezone": "0.5.45",
276
- "@tryghost/i18n": "file:components/tryghost-i18n-6.0.8.tgz"
276
+ "@tryghost/i18n": "file:components/tryghost-i18n-6.0.10.tgz"
277
277
  },
278
278
  "nx": {
279
279
  "targets": {