ghost 5.75.2 → 5.76.0

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 (175) hide show
  1. package/PRIVACY.md +1 -5
  2. package/components/tryghost-adapter-cache-memory-ttl-5.76.0.tgz +0 -0
  3. package/components/{tryghost-adapter-cache-redis-5.75.2.tgz → tryghost-adapter-cache-redis-5.76.0.tgz} +0 -0
  4. package/components/{tryghost-adapter-manager-5.75.2.tgz → tryghost-adapter-manager-5.76.0.tgz} +0 -0
  5. package/components/tryghost-announcement-bar-settings-5.76.0.tgz +0 -0
  6. package/components/{tryghost-api-framework-5.75.2.tgz → tryghost-api-framework-5.76.0.tgz} +0 -0
  7. package/components/tryghost-api-version-compatibility-service-5.76.0.tgz +0 -0
  8. package/components/tryghost-audience-feedback-5.76.0.tgz +0 -0
  9. package/components/tryghost-bookshelf-repository-5.76.0.tgz +0 -0
  10. package/components/{tryghost-bootstrap-socket-5.75.2.tgz → tryghost-bootstrap-socket-5.76.0.tgz} +0 -0
  11. package/components/tryghost-collections-5.76.0.tgz +0 -0
  12. package/components/tryghost-constants-5.76.0.tgz +0 -0
  13. package/components/tryghost-custom-theme-settings-service-5.76.0.tgz +0 -0
  14. package/components/tryghost-data-generator-5.76.0.tgz +0 -0
  15. package/components/tryghost-domain-events-5.76.0.tgz +0 -0
  16. package/components/tryghost-donations-5.76.0.tgz +0 -0
  17. package/components/tryghost-dynamic-routing-events-5.76.0.tgz +0 -0
  18. package/components/tryghost-email-addresses-5.76.0.tgz +0 -0
  19. package/components/{tryghost-email-analytics-provider-mailgun-5.75.2.tgz → tryghost-email-analytics-provider-mailgun-5.76.0.tgz} +0 -0
  20. package/components/tryghost-email-analytics-service-5.76.0.tgz +0 -0
  21. package/components/tryghost-email-content-generator-5.76.0.tgz +0 -0
  22. package/components/{tryghost-email-events-5.75.2.tgz → tryghost-email-events-5.76.0.tgz} +0 -0
  23. package/components/tryghost-email-service-5.76.0.tgz +0 -0
  24. package/components/tryghost-email-suppression-list-5.76.0.tgz +0 -0
  25. package/components/tryghost-event-aware-cache-wrapper-5.76.0.tgz +0 -0
  26. package/components/tryghost-express-dynamic-redirects-5.76.0.tgz +0 -0
  27. package/components/tryghost-external-media-inliner-5.76.0.tgz +0 -0
  28. package/components/tryghost-extract-api-key-5.76.0.tgz +0 -0
  29. package/components/tryghost-html-to-plaintext-5.76.0.tgz +0 -0
  30. package/components/tryghost-i18n-5.76.0.tgz +0 -0
  31. package/components/tryghost-importer-handler-content-files-5.76.0.tgz +0 -0
  32. package/components/tryghost-importer-revue-5.76.0.tgz +0 -0
  33. package/components/tryghost-in-memory-repository-5.76.0.tgz +0 -0
  34. package/components/{tryghost-job-manager-5.75.2.tgz → tryghost-job-manager-5.76.0.tgz} +0 -0
  35. package/components/tryghost-link-redirects-5.76.0.tgz +0 -0
  36. package/components/tryghost-link-replacer-5.76.0.tgz +0 -0
  37. package/components/tryghost-link-tracking-5.76.0.tgz +0 -0
  38. package/components/{tryghost-magic-link-5.75.2.tgz → tryghost-magic-link-5.76.0.tgz} +0 -0
  39. package/components/tryghost-mail-events-5.76.0.tgz +0 -0
  40. package/components/{tryghost-mailgun-client-5.75.2.tgz → tryghost-mailgun-client-5.76.0.tgz} +0 -0
  41. package/components/{tryghost-member-attribution-5.75.2.tgz → tryghost-member-attribution-5.76.0.tgz} +0 -0
  42. package/components/{tryghost-member-events-5.75.2.tgz → tryghost-member-events-5.76.0.tgz} +0 -0
  43. package/components/{tryghost-members-api-5.75.2.tgz → tryghost-members-api-5.76.0.tgz} +0 -0
  44. package/components/tryghost-members-csv-5.76.0.tgz +0 -0
  45. package/components/{tryghost-members-events-service-5.75.2.tgz → tryghost-members-events-service-5.76.0.tgz} +0 -0
  46. package/components/tryghost-members-importer-5.76.0.tgz +0 -0
  47. package/components/{tryghost-members-offers-5.75.2.tgz → tryghost-members-offers-5.76.0.tgz} +0 -0
  48. package/components/{tryghost-members-payments-5.75.2.tgz → tryghost-members-payments-5.76.0.tgz} +0 -0
  49. package/components/tryghost-members-ssr-5.76.0.tgz +0 -0
  50. package/components/{tryghost-members-stripe-service-5.75.2.tgz → tryghost-members-stripe-service-5.76.0.tgz} +0 -0
  51. package/components/tryghost-mentions-email-report-5.76.0.tgz +0 -0
  52. package/components/tryghost-milestones-5.76.0.tgz +0 -0
  53. package/components/tryghost-minifier-5.76.0.tgz +0 -0
  54. package/components/tryghost-model-to-domain-event-interceptor-5.76.0.tgz +0 -0
  55. package/components/tryghost-mw-api-version-mismatch-5.76.0.tgz +0 -0
  56. package/components/tryghost-mw-cache-control-5.76.0.tgz +0 -0
  57. package/components/{tryghost-mw-error-handler-5.75.2.tgz → tryghost-mw-error-handler-5.76.0.tgz} +0 -0
  58. package/components/tryghost-mw-session-from-token-5.76.0.tgz +0 -0
  59. package/components/tryghost-mw-update-user-last-seen-5.76.0.tgz +0 -0
  60. package/components/tryghost-mw-version-match-5.76.0.tgz +0 -0
  61. package/components/tryghost-mw-vhost-5.76.0.tgz +0 -0
  62. package/components/{tryghost-nql-filter-expansions-5.75.2.tgz → tryghost-nql-filter-expansions-5.76.0.tgz} +0 -0
  63. package/components/tryghost-oembed-service-5.76.0.tgz +0 -0
  64. package/components/{tryghost-package-json-5.75.2.tgz → tryghost-package-json-5.76.0.tgz} +0 -0
  65. package/components/tryghost-post-events-5.76.0.tgz +0 -0
  66. package/components/tryghost-post-revisions-5.76.0.tgz +0 -0
  67. package/components/tryghost-posts-service-5.76.0.tgz +0 -0
  68. package/components/tryghost-recommendations-5.76.0.tgz +0 -0
  69. package/components/tryghost-referrers-5.76.0.tgz +0 -0
  70. package/components/{tryghost-security-5.75.2.tgz → tryghost-security-5.76.0.tgz} +0 -0
  71. package/components/{tryghost-session-service-5.75.2.tgz → tryghost-session-service-5.76.0.tgz} +0 -0
  72. package/components/tryghost-settings-path-manager-5.76.0.tgz +0 -0
  73. package/components/tryghost-slack-notifications-5.76.0.tgz +0 -0
  74. package/components/{tryghost-staff-service-5.75.2.tgz → tryghost-staff-service-5.76.0.tgz} +0 -0
  75. package/components/tryghost-stats-service-5.76.0.tgz +0 -0
  76. package/components/tryghost-tiers-5.76.0.tgz +0 -0
  77. package/components/{tryghost-update-check-service-5.75.2.tgz → tryghost-update-check-service-5.76.0.tgz} +0 -0
  78. package/components/tryghost-verification-trigger-5.76.0.tgz +0 -0
  79. package/components/tryghost-version-notifications-data-service-5.76.0.tgz +0 -0
  80. package/components/{tryghost-webmentions-5.75.2.tgz → tryghost-webmentions-5.76.0.tgz} +0 -0
  81. package/core/app.js +3 -1
  82. package/core/boot.js +4 -1
  83. package/core/built/admin/assets/admin-x-demo/admin-x-demo.js +2 -2
  84. package/core/built/admin/assets/admin-x-demo/{index-46cd6bae.mjs → index-3d0e9e6b.mjs} +1337 -1319
  85. package/core/built/admin/assets/admin-x-demo/{modals-e3fd0bee.mjs → modals-f20fa267.mjs} +2 -2
  86. package/core/built/admin/assets/admin-x-settings/{CodeEditorView-3275fab6.mjs → CodeEditorView-d4ee416e.mjs} +264 -261
  87. package/core/built/admin/assets/admin-x-settings/admin-x-settings.js +2 -2
  88. package/core/built/admin/assets/admin-x-settings/{index-147f4a79.mjs → index-02f4e117.mjs} +2 -2
  89. package/core/built/admin/assets/admin-x-settings/{index-02a155fd.mjs → index-3fd88924.mjs} +5821 -5670
  90. package/core/built/admin/assets/admin-x-settings/{modals-b9d9ac8e.mjs → modals-5adb4a9f.mjs} +6284 -6230
  91. package/core/built/admin/assets/{chunk.143.3bd2e0f4f76f9b3424bd.js → chunk.143.f5d2319ca15f1acb9a3e.js} +5 -5
  92. package/core/built/admin/assets/{chunk.178.33f9c955f0d6abb8e0db.js → chunk.178.3fb4456b91e5d6c7c24d.js} +4 -4
  93. package/core/built/admin/assets/{chunk.214.611b4f2521fabe34eea8.js → chunk.664.0bd9e83a6b03130112ae.js} +2126 -2046
  94. package/core/built/admin/assets/ghost-0704a125141af505d40c5f71e84f33ab.css +1 -0
  95. package/core/built/admin/assets/{ghost-2fe51d0831dd1694a4e88abd5f38e2fb.js → ghost-971615b195b524bf97f678a350865195.js} +141 -126
  96. package/core/built/admin/assets/ghost-dark-6ad8cac49f53901201e9210bc1999eeb.css +1 -0
  97. package/core/built/admin/assets/koenig-lexical/index.css +1 -1
  98. package/core/built/admin/assets/koenig-lexical/koenig-lexical.js +26588 -27408
  99. package/core/built/admin/assets/koenig-lexical/koenig-lexical.umd.js +187 -188
  100. package/core/built/admin/assets/{vendor-f6856af9fcd8ab6533f2a4339ececbc8.js → vendor-6b83da0c6e6fede335947219c59e1543.js} +2 -2
  101. package/core/built/admin/index.html +6 -6
  102. package/core/cli/generate-data.js +31 -2
  103. package/core/frontend/apps/private-blogging/lib/middleware.js +1 -2
  104. package/core/frontend/helpers/excerpt.js +2 -0
  105. package/core/frontend/public/robots.txt +1 -0
  106. package/core/server/api/endpoints/utils/serializers/input/settings.js +1 -0
  107. package/core/server/data/db/connection.js +10 -0
  108. package/core/server/data/migrations/versions/5.76/2023-12-05-11-00-add-portal-default-plan-setting.js +8 -0
  109. package/core/server/data/schema/default-settings/default-settings.json +8 -0
  110. package/core/server/services/public-config/site.js +7 -1
  111. package/core/shared/SentryKnexTracingIntegration.js +67 -0
  112. package/core/shared/config/defaults.json +1 -1
  113. package/core/shared/labs.js +2 -4
  114. package/core/shared/sentry.js +48 -6
  115. package/core/shared/settings-cache/public.js +1 -0
  116. package/package.json +169 -168
  117. package/yarn.lock +1941 -1726
  118. package/components/tryghost-adapter-cache-memory-ttl-5.75.2.tgz +0 -0
  119. package/components/tryghost-announcement-bar-settings-5.75.2.tgz +0 -0
  120. package/components/tryghost-api-version-compatibility-service-5.75.2.tgz +0 -0
  121. package/components/tryghost-audience-feedback-5.75.2.tgz +0 -0
  122. package/components/tryghost-bookshelf-repository-5.75.2.tgz +0 -0
  123. package/components/tryghost-collections-5.75.2.tgz +0 -0
  124. package/components/tryghost-constants-5.75.2.tgz +0 -0
  125. package/components/tryghost-custom-theme-settings-service-5.75.2.tgz +0 -0
  126. package/components/tryghost-data-generator-5.75.2.tgz +0 -0
  127. package/components/tryghost-domain-events-5.75.2.tgz +0 -0
  128. package/components/tryghost-donations-5.75.2.tgz +0 -0
  129. package/components/tryghost-dynamic-routing-events-5.75.2.tgz +0 -0
  130. package/components/tryghost-email-addresses-5.75.2.tgz +0 -0
  131. package/components/tryghost-email-analytics-service-5.75.2.tgz +0 -0
  132. package/components/tryghost-email-content-generator-5.75.2.tgz +0 -0
  133. package/components/tryghost-email-service-5.75.2.tgz +0 -0
  134. package/components/tryghost-email-suppression-list-5.75.2.tgz +0 -0
  135. package/components/tryghost-event-aware-cache-wrapper-5.75.2.tgz +0 -0
  136. package/components/tryghost-express-dynamic-redirects-5.75.2.tgz +0 -0
  137. package/components/tryghost-external-media-inliner-5.75.2.tgz +0 -0
  138. package/components/tryghost-extract-api-key-5.75.2.tgz +0 -0
  139. package/components/tryghost-html-to-plaintext-5.75.2.tgz +0 -0
  140. package/components/tryghost-i18n-5.75.2.tgz +0 -0
  141. package/components/tryghost-importer-handler-content-files-5.75.2.tgz +0 -0
  142. package/components/tryghost-importer-revue-5.75.2.tgz +0 -0
  143. package/components/tryghost-in-memory-repository-5.75.2.tgz +0 -0
  144. package/components/tryghost-link-redirects-5.75.2.tgz +0 -0
  145. package/components/tryghost-link-replacer-5.75.2.tgz +0 -0
  146. package/components/tryghost-link-tracking-5.75.2.tgz +0 -0
  147. package/components/tryghost-mail-events-5.75.2.tgz +0 -0
  148. package/components/tryghost-members-csv-5.75.2.tgz +0 -0
  149. package/components/tryghost-members-importer-5.75.2.tgz +0 -0
  150. package/components/tryghost-members-ssr-5.75.2.tgz +0 -0
  151. package/components/tryghost-mentions-email-report-5.75.2.tgz +0 -0
  152. package/components/tryghost-milestones-5.75.2.tgz +0 -0
  153. package/components/tryghost-minifier-5.75.2.tgz +0 -0
  154. package/components/tryghost-model-to-domain-event-interceptor-5.75.2.tgz +0 -0
  155. package/components/tryghost-mw-api-version-mismatch-5.75.2.tgz +0 -0
  156. package/components/tryghost-mw-cache-control-5.75.2.tgz +0 -0
  157. package/components/tryghost-mw-session-from-token-5.75.2.tgz +0 -0
  158. package/components/tryghost-mw-update-user-last-seen-5.75.2.tgz +0 -0
  159. package/components/tryghost-mw-version-match-5.75.2.tgz +0 -0
  160. package/components/tryghost-mw-vhost-5.75.2.tgz +0 -0
  161. package/components/tryghost-oembed-service-5.75.2.tgz +0 -0
  162. package/components/tryghost-post-events-5.75.2.tgz +0 -0
  163. package/components/tryghost-post-revisions-5.75.2.tgz +0 -0
  164. package/components/tryghost-posts-service-5.75.2.tgz +0 -0
  165. package/components/tryghost-recommendations-5.75.2.tgz +0 -0
  166. package/components/tryghost-referrers-5.75.2.tgz +0 -0
  167. package/components/tryghost-settings-path-manager-5.75.2.tgz +0 -0
  168. package/components/tryghost-slack-notifications-5.75.2.tgz +0 -0
  169. package/components/tryghost-stats-service-5.75.2.tgz +0 -0
  170. package/components/tryghost-tiers-5.75.2.tgz +0 -0
  171. package/components/tryghost-verification-trigger-5.75.2.tgz +0 -0
  172. package/components/tryghost-version-notifications-data-service-5.75.2.tgz +0 -0
  173. package/core/built/admin/assets/ghost-0456ea5c74bd1b27239c11706d1acae9.css +0 -1
  174. package/core/built/admin/assets/ghost-dark-29863e517e1917a3b0df74979a6cf03f.css +0 -1
  175. /package/core/built/admin/assets/{chunk.214.611b4f2521fabe34eea8.js.LICENSE.txt → chunk.664.0bd9e83a6b03130112ae.js.LICENSE.txt} +0 -0
@@ -9312,7 +9312,7 @@ e.default={content:'<path d="M1.061 2.56v6.257a3 3 0 00.878 2.121L13.5 22.5a1.5
9312
9312
  Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
9313
9313
  e.default={content:'<path clip-rule="evenodd" d="M8 2.706a1 1 0 011-1h15a1 1 0 01.707.293l21 21a1 1 0 01-1.414 1.414L23.586 3.706H9a1 1 0 01-1-1z"/><path clip-rule="evenodd" d="M3.172 8.878A4 4 0 016 7.706h12.258a4 4 0 012.827 1.17l18.328 18.327a4.001 4.001 0 01-1.424 6.573l-7.213 2.707-2.71 7.21a4.002 4.002 0 01-6.573 1.424L3.171 26.791A4 4 0 012 23.962V11.706a4 4 0 011.172-2.828zM6 9.706a2 2 0 00-2 2v12.256a2.003 2.003 0 00.585 1.415l18.322 18.326a2 2 0 003.287-.712l2.87-7.637a1 1 0 01.585-.584l7.638-2.866a2 2 0 00.712-3.287L19.67 10.291a2 2 0 00-1.413-.585H6z"/><path d="M12.25 15.956a2 2 0 100 4 2 2 0 000-4"/>',attrs:{fill:"none",viewBox:"0 0 48 48"}}})),define("ember-svg-jar/inlined/thumbs-down",["exports"],(function(e){"use strict"
9314
9314
  Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
9315
- e.default={content:'<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M2 14.429h3.444a1.906 1.906 0 011.543.794l4.617 7.095a1.622 1.622 0 001.992.537 1.597 1.597 0 00.894-1.87l-.833-3.142a1.867 1.867 0 01.993-2.164 1.91 1.91 0 01.833-.193h4.63a1.882 1.882 0 001.806-2.426v-.011l-1.8-6.008v-.016c-.733-2.36-1.992-3.97-4.469-3.97-5.934 0-5.595-.684-12.524 2.818-.377.188-.752.379-1.126.572V16.5"/>',attrs:{fill:"none",viewBox:"0 0 24 24"}}})),define("ember-svg-jar/inlined/thumbs-up",["exports"],(function(e){"use strict"
9315
+ e.default={content:'<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M22 14.429h-3.445a1.905 1.905 0 00-1.543.794l-4.617 7.095a1.622 1.622 0 01-2.783-.233 1.597 1.597 0 01-.103-1.1l.833-3.142a1.867 1.867 0 00-.993-2.164 1.911 1.911 0 00-.833-.193h-4.63A1.881 1.881 0 012.08 13.06v-.011l1.8-6.008v-.016c.733-2.36 1.992-3.97 4.47-3.97 5.933 0 5.594-.684 12.523 2.818.377.188.752.379 1.126.572V16.5"/>',attrs:{fill:"none",viewBox:"0 0 24 24"}}})),define("ember-svg-jar/inlined/thumbs-up",["exports"],(function(e){"use strict"
9316
9316
  Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
9317
9317
  e.default={content:'<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M2.001 10.571h3.443a1.907 1.907 0 001.543-.794l4.618-7.095a1.62 1.62 0 011.992-.537 1.598 1.598 0 01.892 1.871l-.832 3.14a1.867 1.867 0 00.993 2.165c.259.127.544.193.832.194h4.63a1.883 1.883 0 011.807 2.426v.011l-1.8 6.008v.015c-.733 2.36-1.993 3.97-4.47 3.97-5.933 0-5.593.684-12.524-2.818-.375-.188-.75-.38-1.125-.57v-9.89"/>',attrs:{fill:"none",viewBox:"0 0 24 24"}}})),define("ember-svg-jar/inlined/trash",["exports"],(function(e){"use strict"
9318
9318
  Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
@@ -9914,4 +9914,4 @@ e.default=class{constructor(e){if(this._data=new t.default,e)for(let t=0;t<e.len
9914
9914
  return this}get(e){let t=this._data[e]
9915
9915
  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}}}))
9916
9916
 
9917
- //# sourceMappingURL=vendor-ffd7d22c69e5aabc538c4d6a09afe243.map
9917
+ //# sourceMappingURL=vendor-0462eb4577b6a717a7cadbacd0d3b276.map
@@ -8,7 +8,7 @@
8
8
  <title>Ghost Admin</title>
9
9
 
10
10
 
11
- <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.75%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22ember-websockets%22%3A%7B%22socketIO%22%3Atrue%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%226db67756e6%22%2C%22adminXDemoFilename%22%3A%22admin-x-demo.js%22%2C%22adminXDemoHash%22%3A%22b092dea02b%22%2C%22adminXSettingsFilename%22%3A%22admin-x-settings.js%22%2C%22adminXSettingsHash%22%3A%2290920a9a6f%22%7D" />
11
+ <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.76%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22ember-websockets%22%3A%7B%22socketIO%22%3Atrue%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%22a27d96c707%22%2C%22adminXDemoFilename%22%3A%22admin-x-demo.js%22%2C%22adminXDemoHash%22%3A%22ace375b522%22%2C%22adminXSettingsFilename%22%3A%22admin-x-settings.js%22%2C%22adminXSettingsHash%22%3A%22bc3086cb53%22%7D" />
12
12
 
13
13
  <meta name="HandheldFriendly" content="True" />
14
14
  <meta name="MobileOptimized" content="320" />
@@ -37,7 +37,7 @@
37
37
  </style>
38
38
 
39
39
  <link integrity="" rel="stylesheet" href="assets/vendor-0ede59da8efb5e28fa929557f7ff7154.css">
40
- <link integrity="" rel="stylesheet" href="assets/ghost-0456ea5c74bd1b27239c11706d1acae9.css" title="light">
40
+ <link integrity="" rel="stylesheet" href="assets/ghost-0704a125141af505d40c5f71e84f33ab.css" title="light">
41
41
 
42
42
 
43
43
  </head>
@@ -56,9 +56,9 @@
56
56
 
57
57
  <div id="ember-basic-dropdown-wormhole"></div>
58
58
 
59
- <script src="assets/vendor-f6856af9fcd8ab6533f2a4339ececbc8.js"></script>
60
- <script src="assets/chunk.214.611b4f2521fabe34eea8.js"></script>
61
- <script src="assets/chunk.143.3bd2e0f4f76f9b3424bd.js"></script>
62
- <script src="assets/ghost-2fe51d0831dd1694a4e88abd5f38e2fb.js"></script>
59
+ <script src="assets/vendor-6b83da0c6e6fede335947219c59e1543.js"></script>
60
+ <script src="assets/chunk.664.0bd9e83a6b03130112ae.js"></script>
61
+ <script src="assets/chunk.143.f5d2319ca15f1acb9a3e.js"></script>
62
+ <script src="assets/ghost-971615b195b524bf97f678a350865195.js"></script>
63
63
  </body>
64
64
  </html>
@@ -1,15 +1,20 @@
1
+ /* eslint-disable ghost/filenames/match-exported-class */
1
2
  const Command = require('./command');
2
3
  const DataGenerator = require('@tryghost/data-generator');
3
4
  const config = require('../shared/config');
4
5
 
6
+ const schemaTables = require('../server/data/schema').tables;
7
+
5
8
  module.exports = class DataGeneratorCommand extends Command {
6
9
  setup() {
7
10
  this.help('Generates random data to populate the database for development & testing');
8
11
  this.argument('--base-data-pack', {type: 'string', defaultValue: '', desc: 'Base data pack file location, imported instead of random content'});
9
- this.argument('--quantity', {type: 'number', desc: 'When importing a single table, the quantity to import'});
10
12
  this.argument('--clear-database', {type: 'boolean', defaultValue: false, desc: 'Clear all entries in the database before importing'});
11
13
  this.argument('--tables', {type: 'string', desc: 'Only import the specified list of tables, where quantities can be specified by appending a colon followed by the quantity for each table. Example: --tables=members:1000,posts,tags,members_login_events'});
14
+ this.argument('--quantities', {type: 'string', desc: 'Allows you to specify different default quantities for specific tables without affecting the tables that are generated. Example: --quantities=members:1000'});
12
15
  this.argument('--with-default', {type: 'boolean', defaultValue: false, desc: 'Include default tables as well as those specified (simply override quantities)'});
16
+ this.argument('--print-dependencies', {type: 'boolean', defaultValue: false, desc: 'Prints the dependency tree for the data generator and exits'});
17
+ this.argument('--seed', {type: 'number', defaultValue: '', desc: 'Use a seed to reliably generate the same data on multiple runs (timestamps will still change a little bit to remain up to date)'});
13
18
  }
14
19
 
15
20
  initializeContext(context) {
@@ -29,6 +34,8 @@ module.exports = class DataGeneratorCommand extends Command {
29
34
  }
30
35
 
31
36
  async handle(argv = {}) {
37
+ // If we can't stream, throw an error while creating the connection
38
+ process.env.REQUIRE_INFILE_STREAM = '1';
32
39
  const knex = require('../server/data/db/connection');
33
40
 
34
41
  const tables = (argv.tables ? argv.tables.split(',') : []).map(table => ({
@@ -36,6 +43,24 @@ module.exports = class DataGeneratorCommand extends Command {
36
43
  quantity: parseInt(table.split(':')[1]) || undefined
37
44
  }));
38
45
 
46
+ /**
47
+ * @type {Record<string, number>}
48
+ */
49
+ const quantities = {};
50
+
51
+ if (argv.quantities) {
52
+ for (const quantity of argv.quantities.split(',')) {
53
+ const [table, amount] = quantity.split(':');
54
+
55
+ if (amount === undefined || !isFinite(parseInt(amount))) {
56
+ this.fatal(`Missing quantity for table ${table}`);
57
+ return;
58
+ }
59
+
60
+ quantities[table] = parseInt(amount);
61
+ }
62
+ }
63
+
39
64
  const dataGenerator = new DataGenerator({
40
65
  baseDataPack: argv['base-data-pack'],
41
66
  knex,
@@ -51,7 +76,11 @@ module.exports = class DataGeneratorCommand extends Command {
51
76
  baseUrl: config.getSiteUrl(),
52
77
  clearDatabase: argv['clear-database'],
53
78
  tables,
54
- withDefault: argv['with-default']
79
+ schemaTables,
80
+ withDefault: argv['with-default'],
81
+ printDependencies: argv['print-dependencies'],
82
+ quantities,
83
+ seed: argv.seed || undefined
55
84
  });
56
85
  try {
57
86
  await dataGenerator.importData();
@@ -55,8 +55,7 @@ const privateBlogging = {
55
55
  name: 'ghost-private',
56
56
  maxAge: constants.ONE_MONTH_MS,
57
57
  signed: false,
58
- sameSite: urlUtils.isSSL(config.get('url')) ? 'none' : 'lax',
59
- secure: urlUtils.isSSL(config.get('url'))
58
+ sameSite: 'none'
60
59
  })(req, res, next);
61
60
  },
62
61
 
@@ -22,6 +22,8 @@ module.exports = function excerpt(options) {
22
22
  } else {
23
23
  excerptText = '';
24
24
  }
25
+
26
+ excerptText = _.escape(excerptText);
25
27
 
26
28
  truncateOptions = _.reduce(truncateOptions, (_truncateOptions, value, key) => {
27
29
  if (['words', 'characters'].includes(key)) {
@@ -4,3 +4,4 @@ Disallow: /ghost/
4
4
  Disallow: /p/
5
5
  Disallow: /email/
6
6
  Disallow: /r/
7
+ Disallow: /webmentions/receive/
@@ -38,6 +38,7 @@ const EDITABLE_SETTINGS = [
38
38
  'portal_name',
39
39
  'portal_button',
40
40
  'portal_plans',
41
+ 'portal_default_plan',
41
42
  'portal_button_style',
42
43
  'firstpromoter',
43
44
  'firstpromoter_id',
@@ -1,9 +1,11 @@
1
1
  const _ = require('lodash');
2
2
  const knex = require('knex');
3
3
  const os = require('os');
4
+ const fs = require('fs');
4
5
 
5
6
  const logging = require('@tryghost/logging');
6
7
  const config = require('../../../shared/config');
8
+ const errors = require('@tryghost/errors');
7
9
  let knexInstance;
8
10
 
9
11
  // @TODO:
@@ -45,6 +47,14 @@ function configure(dbConfig) {
45
47
  dbConfig.connection.timezone = 'Z';
46
48
  dbConfig.connection.charset = 'utf8mb4';
47
49
  dbConfig.connection.decimalNumbers = true;
50
+
51
+ if (process.env.REQUIRE_INFILE_STREAM) {
52
+ if (process.env.NODE_ENV === 'development' || process.env.ALLOW_INFILE_STREAM) {
53
+ dbConfig.connection.infileStreamFactory = path => fs.createReadStream(path);
54
+ } else {
55
+ throw new errors.InternalServerError({message: 'MySQL infile streaming is required to run the current process, but is not allowed. Run the script in development mode or set ALLOW_INFILE_STREAM=1.'});
56
+ }
57
+ }
48
58
  }
49
59
 
50
60
  return dbConfig;
@@ -0,0 +1,8 @@
1
+ const {addSetting} = require('../../utils');
2
+
3
+ module.exports = addSetting({
4
+ key: 'portal_default_plan',
5
+ value: 'yearly',
6
+ type: 'string',
7
+ group: 'portal'
8
+ });
@@ -330,6 +330,14 @@
330
330
  "defaultValue": "[\"free\"]",
331
331
  "type": "array"
332
332
  },
333
+ "portal_default_plan": {
334
+ "defaultValue": "yearly",
335
+ "validations": {
336
+ "isEmpty": false,
337
+ "isIn": [["yearly", "monthly"]]
338
+ },
339
+ "type": "string"
340
+ },
333
341
  "portal_products": {
334
342
  "defaultValue": "[]",
335
343
  "type": "array"
@@ -19,7 +19,13 @@ module.exports = function getSiteProperties() {
19
19
 
20
20
  if (config.get('client_sentry') && !config.get('client_sentry').disabled) {
21
21
  siteProperties.sentry_dsn = config.get('client_sentry').dsn;
22
- siteProperties.sentry_env = config.get('env');
22
+
23
+ let environment = config.get('PRO_ENV');
24
+ if (!environment) {
25
+ environment = config.get('env');
26
+ }
27
+
28
+ siteProperties.sentry_env = environment;
23
29
  }
24
30
 
25
31
  return siteProperties;
@@ -0,0 +1,67 @@
1
+ /**
2
+ * @typedef {import('knex').Knex.Client} KnexClient
3
+ */
4
+
5
+ /**
6
+ * @typedef {import('@sentry/types').Integration} SentryIntegration
7
+ */
8
+
9
+ /**
10
+ * Sentry Knex tracing integration
11
+ *
12
+ * @implements {SentryIntegration}
13
+ */
14
+ class SentryKnexTracingIntegration {
15
+ static id = 'Knex';
16
+
17
+ name = SentryKnexTracingIntegration.id;
18
+
19
+ /** @type {KnexClient} */
20
+ #knex;
21
+
22
+ /** @type {Map} */
23
+ #spanCache = new Map();
24
+
25
+ /**
26
+ * @param {KnexClient} knex
27
+ */
28
+ constructor(knex) {
29
+ this.#knex = knex;
30
+ }
31
+
32
+ /**
33
+ * @param {Function} addGlobalEventProcessor
34
+ * @param {Function} getCurrentHub
35
+ */
36
+ setupOnce(addGlobalEventProcessor, getCurrentHub) {
37
+ this.#knex.on('query', (query) => {
38
+ const scope = getCurrentHub().getScope();
39
+ const parentSpan = scope?.getSpan();
40
+
41
+ const span = parentSpan?.startChild({
42
+ op: 'db.query',
43
+ description: query.sql
44
+ });
45
+
46
+ if (span) {
47
+ this.#spanCache.set(query.__knexQueryUid, span);
48
+ }
49
+ });
50
+
51
+ const handleQueryExecuted = (err, query) => {
52
+ const queryId = query.__knexQueryUid;
53
+ const span = this.#spanCache.get(queryId);
54
+
55
+ if (span) {
56
+ span.finish();
57
+
58
+ this.#spanCache.delete(queryId);
59
+ }
60
+ };
61
+
62
+ this.#knex.on('query-response', handleQueryExecuted);
63
+ this.#knex.on('query-error', handleQueryExecuted);
64
+ }
65
+ }
66
+
67
+ module.exports = SentryKnexTracingIntegration;
@@ -182,7 +182,7 @@
182
182
  },
183
183
  "portal": {
184
184
  "url": "https://cdn.jsdelivr.net/ghost/portal@~{version}/umd/portal.min.js",
185
- "version": "2.36"
185
+ "version": "2.37"
186
186
  },
187
187
  "sodoSearch": {
188
188
  "url": "https://cdn.jsdelivr.net/ghost/sodo-search@~{version}/umd/sodo-search.min.js",
@@ -21,7 +21,6 @@ const GA_FEATURES = [
21
21
  'announcementBar',
22
22
  'signupForm',
23
23
  'recommendations',
24
- 'editorEmojiPicker',
25
24
  'listUnsubscribeHeader',
26
25
  'filterEmailDisabled'
27
26
  ];
@@ -45,12 +44,11 @@ const ALPHA_FEATURES = [
45
44
  'tipsAndDonations',
46
45
  'importMemberTier',
47
46
  'lexicalIndicators',
48
- 'editorEmojiPicker',
49
47
  'adminXOffers',
50
48
  'filterEmailDisabled',
51
49
  'adminXDemo',
52
- 'tkReminders',
53
- 'newEmailAddresses'
50
+ 'newEmailAddresses',
51
+ 'portalImprovements'
54
52
  ];
55
53
 
56
54
  module.exports.GA_KEYS = [...GA_FEATURES];
@@ -1,4 +1,6 @@
1
1
  const config = require('./config');
2
+ const logging = require('@tryghost/logging');
3
+ const SentryKnexTracingIntegration = require('./SentryKnexTracingIntegration');
2
4
  const sentryConfig = config.get('sentry');
3
5
  const errors = require('@tryghost/errors');
4
6
 
@@ -58,14 +60,43 @@ const beforeSend = function (event, hint) {
58
60
  if (sentryConfig && !sentryConfig.disabled) {
59
61
  const Sentry = require('@sentry/node');
60
62
  const version = require('@tryghost/version').full;
61
- const environment = config.get('env');
62
- Sentry.init({
63
+
64
+ let environment = config.get('PRO_ENV');
65
+ if (!environment) {
66
+ environment = config.get('env');
67
+ }
68
+
69
+ const sentryInitConfig = {
63
70
  dsn: sentryConfig.dsn,
64
71
  release: 'ghost@' + version,
65
72
  environment: environment,
66
73
  maxValueLength: 1000,
67
- beforeSend: beforeSend
68
- });
74
+ integrations: [],
75
+ beforeSend
76
+ };
77
+
78
+ // Enable tracing if sentry.tracing.enabled is true
79
+ if (sentryConfig.tracing?.enabled === true) {
80
+ sentryInitConfig.integrations.push(new Sentry.Integrations.Http({tracing: true}));
81
+ sentryInitConfig.tracesSampleRate = parseFloat(sentryConfig.tracing.sampleRate) || 0.0;
82
+ // Enable profiling, if configured, only if tracing is also configured
83
+ if (sentryConfig.profiling?.enabled === true) {
84
+ // Import Sentry's profiling integration if available
85
+ let ProfilingIntegration;
86
+ try {
87
+ ({ProfilingIntegration} = require('@sentry/profiling-node'));
88
+ } catch (err) {
89
+ logging.warn('Sentry Profiling Integration not available');
90
+ ProfilingIntegration = null;
91
+ }
92
+
93
+ if (ProfilingIntegration) {
94
+ sentryInitConfig.integrations.push(new ProfilingIntegration());
95
+ sentryInitConfig.profilesSampleRate = parseFloat(sentryConfig.profiling.sampleRate) || 0.0;
96
+ }
97
+ }
98
+ }
99
+ Sentry.init(sentryInitConfig);
69
100
 
70
101
  module.exports = {
71
102
  requestHandler: Sentry.Handlers.requestHandler(),
@@ -82,8 +113,17 @@ if (sentryConfig && !sentryConfig.disabled) {
82
113
  return (error.statusCode === 500);
83
114
  }
84
115
  }),
116
+ tracingHandler: Sentry.Handlers.tracingHandler(),
85
117
  captureException: Sentry.captureException,
86
- beforeSend: beforeSend
118
+ captureMessage: Sentry.captureMessage,
119
+ beforeSend: beforeSend,
120
+ initQueryTracing: (knex) => {
121
+ if (sentryConfig.tracing?.enabled === true) {
122
+ const integration = new SentryKnexTracingIntegration(knex);
123
+
124
+ Sentry.addIntegration(integration);
125
+ }
126
+ }
87
127
  };
88
128
  } else {
89
129
  const expressNoop = function (req, res, next) {
@@ -95,6 +135,8 @@ if (sentryConfig && !sentryConfig.disabled) {
95
135
  module.exports = {
96
136
  requestHandler: expressNoop,
97
137
  errorHandler: expressNoop,
98
- captureException: noop
138
+ tracingHandler: expressNoop,
139
+ captureException: noop,
140
+ initQueryTracing: noop
99
141
  };
100
142
  }
@@ -38,6 +38,7 @@ module.exports = {
38
38
  portal_signup_terms_html: 'portal_signup_terms_html',
39
39
  portal_signup_checkbox_required: 'portal_signup_checkbox_required',
40
40
  portal_plans: 'portal_plans',
41
+ portal_default_plan: 'portal_default_plan',
41
42
  portal_name: 'portal_name',
42
43
  portal_button: 'portal_button',
43
44
  comments_enabled: 'comments_enabled',