ghost 5.101.2 → 5.101.4

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 (163) hide show
  1. package/components/tryghost-activitypub-5.101.4.tgz +0 -0
  2. package/components/{tryghost-adapter-cache-memory-ttl-5.101.2.tgz → tryghost-adapter-cache-memory-ttl-5.101.4.tgz} +0 -0
  3. package/components/{tryghost-adapter-cache-redis-5.101.2.tgz → tryghost-adapter-cache-redis-5.101.4.tgz} +0 -0
  4. package/components/tryghost-adapter-manager-5.101.4.tgz +0 -0
  5. package/components/{tryghost-announcement-bar-settings-5.101.2.tgz → tryghost-announcement-bar-settings-5.101.4.tgz} +0 -0
  6. package/components/{tryghost-api-framework-5.101.2.tgz → tryghost-api-framework-5.101.4.tgz} +0 -0
  7. package/components/tryghost-api-version-compatibility-service-5.101.4.tgz +0 -0
  8. package/components/tryghost-audience-feedback-5.101.4.tgz +0 -0
  9. package/components/{tryghost-bookshelf-repository-5.101.2.tgz → tryghost-bookshelf-repository-5.101.4.tgz} +0 -0
  10. package/components/{tryghost-bootstrap-socket-5.101.2.tgz → tryghost-bootstrap-socket-5.101.4.tgz} +0 -0
  11. package/components/tryghost-collections-5.101.4.tgz +0 -0
  12. package/components/{tryghost-constants-5.101.2.tgz → tryghost-constants-5.101.4.tgz} +0 -0
  13. package/components/tryghost-custom-fonts-5.101.4.tgz +0 -0
  14. package/components/tryghost-custom-theme-settings-service-5.101.4.tgz +0 -0
  15. package/components/{tryghost-data-generator-5.101.2.tgz → tryghost-data-generator-5.101.4.tgz} +0 -0
  16. package/components/tryghost-domain-events-5.101.4.tgz +0 -0
  17. package/components/tryghost-donations-5.101.4.tgz +0 -0
  18. package/components/tryghost-dynamic-routing-events-5.101.4.tgz +0 -0
  19. package/components/tryghost-email-addresses-5.101.4.tgz +0 -0
  20. package/components/tryghost-email-analytics-provider-mailgun-5.101.4.tgz +0 -0
  21. package/components/tryghost-email-analytics-service-5.101.4.tgz +0 -0
  22. package/components/{tryghost-email-content-generator-5.101.2.tgz → tryghost-email-content-generator-5.101.4.tgz} +0 -0
  23. package/components/{tryghost-email-events-5.101.2.tgz → tryghost-email-events-5.101.4.tgz} +0 -0
  24. package/components/tryghost-email-service-5.101.4.tgz +0 -0
  25. package/components/tryghost-email-suppression-list-5.101.4.tgz +0 -0
  26. package/components/{tryghost-express-dynamic-redirects-5.101.2.tgz → tryghost-express-dynamic-redirects-5.101.4.tgz} +0 -0
  27. package/components/tryghost-external-media-inliner-5.101.4.tgz +0 -0
  28. package/components/tryghost-extract-api-key-5.101.4.tgz +0 -0
  29. package/components/tryghost-ghost-5.101.4.tgz +0 -0
  30. package/components/{tryghost-html-to-plaintext-5.101.2.tgz → tryghost-html-to-plaintext-5.101.4.tgz} +0 -0
  31. package/components/tryghost-i18n-5.101.4.tgz +0 -0
  32. package/components/{tryghost-identity-token-service-5.101.2.tgz → tryghost-identity-token-service-5.101.4.tgz} +0 -0
  33. package/components/tryghost-importer-handler-content-files-5.101.4.tgz +0 -0
  34. package/components/tryghost-importer-revue-5.101.4.tgz +0 -0
  35. package/components/tryghost-in-memory-repository-5.101.4.tgz +0 -0
  36. package/components/{tryghost-job-manager-5.101.2.tgz → tryghost-job-manager-5.101.4.tgz} +0 -0
  37. package/components/tryghost-link-redirects-5.101.4.tgz +0 -0
  38. package/components/tryghost-link-replacer-5.101.4.tgz +0 -0
  39. package/components/{tryghost-link-tracking-5.101.2.tgz → tryghost-link-tracking-5.101.4.tgz} +0 -0
  40. package/components/{tryghost-magic-link-5.101.2.tgz → tryghost-magic-link-5.101.4.tgz} +0 -0
  41. package/components/tryghost-mail-events-5.101.4.tgz +0 -0
  42. package/components/{tryghost-mailgun-client-5.101.2.tgz → tryghost-mailgun-client-5.101.4.tgz} +0 -0
  43. package/components/{tryghost-member-attribution-5.101.2.tgz → tryghost-member-attribution-5.101.4.tgz} +0 -0
  44. package/components/{tryghost-member-events-5.101.2.tgz → tryghost-member-events-5.101.4.tgz} +0 -0
  45. package/components/{tryghost-members-api-5.101.2.tgz → tryghost-members-api-5.101.4.tgz} +0 -0
  46. package/components/{tryghost-members-csv-5.101.2.tgz → tryghost-members-csv-5.101.4.tgz} +0 -0
  47. package/components/{tryghost-members-events-service-5.101.2.tgz → tryghost-members-events-service-5.101.4.tgz} +0 -0
  48. package/components/{tryghost-members-importer-5.101.2.tgz → tryghost-members-importer-5.101.4.tgz} +0 -0
  49. package/components/{tryghost-members-offers-5.101.2.tgz → tryghost-members-offers-5.101.4.tgz} +0 -0
  50. package/components/tryghost-members-payments-5.101.4.tgz +0 -0
  51. package/components/{tryghost-members-ssr-5.101.2.tgz → tryghost-members-ssr-5.101.4.tgz} +0 -0
  52. package/components/{tryghost-members-stripe-service-5.101.2.tgz → tryghost-members-stripe-service-5.101.4.tgz} +0 -0
  53. package/components/{tryghost-mentions-email-report-5.101.2.tgz → tryghost-mentions-email-report-5.101.4.tgz} +0 -0
  54. package/components/{tryghost-milestones-5.101.2.tgz → tryghost-milestones-5.101.4.tgz} +0 -0
  55. package/components/tryghost-minifier-5.101.4.tgz +0 -0
  56. package/components/tryghost-model-to-domain-event-interceptor-5.101.4.tgz +0 -0
  57. package/components/tryghost-mw-api-version-mismatch-5.101.4.tgz +0 -0
  58. package/components/{tryghost-mw-cache-control-5.101.2.tgz → tryghost-mw-cache-control-5.101.4.tgz} +0 -0
  59. package/components/tryghost-mw-error-handler-5.101.4.tgz +0 -0
  60. package/components/{tryghost-mw-session-from-token-5.101.2.tgz → tryghost-mw-session-from-token-5.101.4.tgz} +0 -0
  61. package/components/{tryghost-mw-update-user-last-seen-5.101.2.tgz → tryghost-mw-update-user-last-seen-5.101.4.tgz} +0 -0
  62. package/components/{tryghost-mw-version-match-5.101.2.tgz → tryghost-mw-version-match-5.101.4.tgz} +0 -0
  63. package/components/tryghost-mw-vhost-5.101.4.tgz +0 -0
  64. package/components/tryghost-nql-filter-expansions-5.101.4.tgz +0 -0
  65. package/components/{tryghost-oembed-service-5.101.2.tgz → tryghost-oembed-service-5.101.4.tgz} +0 -0
  66. package/components/{tryghost-package-json-5.101.2.tgz → tryghost-package-json-5.101.4.tgz} +0 -0
  67. package/components/{tryghost-post-events-5.101.2.tgz → tryghost-post-events-5.101.4.tgz} +0 -0
  68. package/components/tryghost-post-revisions-5.101.4.tgz +0 -0
  69. package/components/tryghost-posts-service-5.101.4.tgz +0 -0
  70. package/components/tryghost-prometheus-metrics-5.101.4.tgz +0 -0
  71. package/components/tryghost-recommendations-5.101.4.tgz +0 -0
  72. package/components/{tryghost-referrers-5.101.2.tgz → tryghost-referrers-5.101.4.tgz} +0 -0
  73. package/components/{tryghost-security-5.101.2.tgz → tryghost-security-5.101.4.tgz} +0 -0
  74. package/components/{tryghost-session-service-5.101.2.tgz → tryghost-session-service-5.101.4.tgz} +0 -0
  75. package/components/{tryghost-settings-path-manager-5.101.2.tgz → tryghost-settings-path-manager-5.101.4.tgz} +0 -0
  76. package/components/{tryghost-slack-notifications-5.101.2.tgz → tryghost-slack-notifications-5.101.4.tgz} +0 -0
  77. package/components/tryghost-staff-service-5.101.4.tgz +0 -0
  78. package/components/tryghost-stats-service-5.101.4.tgz +0 -0
  79. package/components/{tryghost-tiers-5.101.2.tgz → tryghost-tiers-5.101.4.tgz} +0 -0
  80. package/components/{tryghost-update-check-service-5.101.2.tgz → tryghost-update-check-service-5.101.4.tgz} +0 -0
  81. package/components/tryghost-verification-trigger-5.101.4.tgz +0 -0
  82. package/components/tryghost-version-notifications-data-service-5.101.4.tgz +0 -0
  83. package/components/{tryghost-webmentions-5.101.2.tgz → tryghost-webmentions-5.101.4.tgz} +0 -0
  84. package/core/built/admin/assets/admin-x-activitypub/admin-x-activitypub.js +4419 -4649
  85. package/core/built/admin/assets/admin-x-settings/{CodeEditorView-5232526b.mjs → CodeEditorView-fa4375e5.mjs} +2 -2
  86. package/core/built/admin/assets/admin-x-settings/admin-x-settings.js +1 -1
  87. package/core/built/admin/assets/admin-x-settings/{index-a5977522.mjs → index-7983f12e.mjs} +571 -561
  88. package/core/built/admin/assets/admin-x-settings/{index-dc5a8d0e.mjs → index-9d96af7c.mjs} +2 -2
  89. package/core/built/admin/assets/admin-x-settings/{modals-c9e2dce0.mjs → modals-25991a5c.mjs} +1617 -1617
  90. package/core/built/admin/assets/{chunk.524.76341ddca302335ab934.js → chunk.524.859e8cb40c11bac0d76d.js} +5 -5
  91. package/core/built/admin/assets/{chunk.582.5fec9324b1fb4565b285.js → chunk.582.223364000d6cf50a79eb.js} +6 -6
  92. package/core/built/admin/assets/{chunk.874.5eb920d19e75683234c2.js → chunk.874.d89f27fe288df0daf539.js} +3 -3
  93. package/core/built/admin/assets/{ghost-53495065f10948cc84a1893b07f22402.js → ghost-a18a45be9cbdd3a4025e2eeb23043120.js} +15 -12
  94. package/core/built/admin/assets/koenig-lexical/index.css +1 -1
  95. package/core/built/admin/assets/koenig-lexical/koenig-lexical.js +7484 -7476
  96. package/core/built/admin/assets/koenig-lexical/koenig-lexical.umd.js +120 -120
  97. package/core/built/admin/index.html +4 -4
  98. package/core/frontend/src/admin-auth/message-handler.js +15 -1
  99. package/core/server/api/endpoints/comment-replies.js +36 -0
  100. package/core/server/api/endpoints/comments.js +0 -1
  101. package/core/server/api/endpoints/index.js +4 -0
  102. package/core/server/api/endpoints/utils/serializers/output/mappers/comments.js +10 -2
  103. package/core/server/models/comment.js +29 -9
  104. package/core/server/services/comments/CommentsController.js +9 -0
  105. package/core/server/services/comments/email-templates/new-comment-reply.hbs +1 -1
  106. package/core/server/services/comments/email-templates/new-comment.hbs +1 -1
  107. package/core/server/services/comments/email-templates/report.hbs +1 -1
  108. package/core/server/services/email-analytics/EmailAnalyticsServiceWrapper.js +4 -2
  109. package/core/server/services/members/emails/signin.js +1 -1
  110. package/core/server/services/members/emails/signup-paid.js +1 -1
  111. package/core/server/services/members/emails/signup.js +1 -1
  112. package/core/server/services/members/emails/subscribe.js +1 -1
  113. package/core/server/services/members/emails/update-email.js +1 -1
  114. package/core/server/services/newsletters/emails/verify-email.js +1 -1
  115. package/core/server/services/settings/emails/verify-email.js +1 -1
  116. package/core/server/services/webhooks/WebhookTrigger.js +26 -2
  117. package/core/server/services/webhooks/listen.js +1 -13
  118. package/core/server/web/api/endpoints/admin/routes.js +1 -0
  119. package/core/shared/config/defaults.json +1 -1
  120. package/core/shared/labs.js +3 -3
  121. package/package.json +155 -155
  122. package/yarn.lock +14 -14
  123. package/components/tryghost-activitypub-5.101.2.tgz +0 -0
  124. package/components/tryghost-adapter-manager-5.101.2.tgz +0 -0
  125. package/components/tryghost-api-version-compatibility-service-5.101.2.tgz +0 -0
  126. package/components/tryghost-audience-feedback-5.101.2.tgz +0 -0
  127. package/components/tryghost-collections-5.101.2.tgz +0 -0
  128. package/components/tryghost-custom-fonts-5.101.2.tgz +0 -0
  129. package/components/tryghost-custom-theme-settings-service-5.101.2.tgz +0 -0
  130. package/components/tryghost-domain-events-5.101.2.tgz +0 -0
  131. package/components/tryghost-donations-5.101.2.tgz +0 -0
  132. package/components/tryghost-dynamic-routing-events-5.101.2.tgz +0 -0
  133. package/components/tryghost-email-addresses-5.101.2.tgz +0 -0
  134. package/components/tryghost-email-analytics-provider-mailgun-5.101.2.tgz +0 -0
  135. package/components/tryghost-email-analytics-service-5.101.2.tgz +0 -0
  136. package/components/tryghost-email-service-5.101.2.tgz +0 -0
  137. package/components/tryghost-email-suppression-list-5.101.2.tgz +0 -0
  138. package/components/tryghost-external-media-inliner-5.101.2.tgz +0 -0
  139. package/components/tryghost-extract-api-key-5.101.2.tgz +0 -0
  140. package/components/tryghost-ghost-5.101.2.tgz +0 -0
  141. package/components/tryghost-i18n-5.101.2.tgz +0 -0
  142. package/components/tryghost-importer-handler-content-files-5.101.2.tgz +0 -0
  143. package/components/tryghost-importer-revue-5.101.2.tgz +0 -0
  144. package/components/tryghost-in-memory-repository-5.101.2.tgz +0 -0
  145. package/components/tryghost-link-redirects-5.101.2.tgz +0 -0
  146. package/components/tryghost-link-replacer-5.101.2.tgz +0 -0
  147. package/components/tryghost-mail-events-5.101.2.tgz +0 -0
  148. package/components/tryghost-members-payments-5.101.2.tgz +0 -0
  149. package/components/tryghost-minifier-5.101.2.tgz +0 -0
  150. package/components/tryghost-model-to-domain-event-interceptor-5.101.2.tgz +0 -0
  151. package/components/tryghost-mw-api-version-mismatch-5.101.2.tgz +0 -0
  152. package/components/tryghost-mw-error-handler-5.101.2.tgz +0 -0
  153. package/components/tryghost-mw-vhost-5.101.2.tgz +0 -0
  154. package/components/tryghost-nql-filter-expansions-5.101.2.tgz +0 -0
  155. package/components/tryghost-post-revisions-5.101.2.tgz +0 -0
  156. package/components/tryghost-posts-service-5.101.2.tgz +0 -0
  157. package/components/tryghost-prometheus-metrics-5.101.2.tgz +0 -0
  158. package/components/tryghost-recommendations-5.101.2.tgz +0 -0
  159. package/components/tryghost-staff-service-5.101.2.tgz +0 -0
  160. package/components/tryghost-stats-service-5.101.2.tgz +0 -0
  161. package/components/tryghost-verification-trigger-5.101.2.tgz +0 -0
  162. package/components/tryghost-version-notifications-data-service-5.101.2.tgz +0 -0
  163. /package/core/built/admin/assets/{chunk.874.5eb920d19e75683234c2.js.LICENSE.txt → chunk.874.d89f27fe288df0daf539.js.LICENSE.txt} +0 -0
@@ -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.101%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%2213eb180462%22%2C%22adminXDemoFilename%22%3A%22admin-x-demo.js%22%2C%22adminXDemoHash%22%3A%22eb8ede230e%22%2C%22adminXSettingsFilename%22%3A%22admin-x-settings.js%22%2C%22adminXSettingsHash%22%3A%22ce304a6e0f%22%2C%22adminXActivitypubFilename%22%3A%22admin-x-activitypub.js%22%2C%22adminXActivitypubHash%22%3A%2251263df223%22%2C%22adminXActivitypubCustomUrl%22%3A%22https%3A%2F%2Fcdn.jsdelivr.net%2Fghost%2Fadmin-x-activitypub%400%2Fdist%2Fadmin-x-activitypub.js%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.101%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%221b5f2bde3f%22%2C%22adminXDemoFilename%22%3A%22admin-x-demo.js%22%2C%22adminXDemoHash%22%3A%22eb8ede230e%22%2C%22adminXSettingsFilename%22%3A%22admin-x-settings.js%22%2C%22adminXSettingsHash%22%3A%229e23b0ff9c%22%2C%22adminXActivitypubFilename%22%3A%22admin-x-activitypub.js%22%2C%22adminXActivitypubHash%22%3A%221a00d98cc8%22%2C%22adminXActivitypubCustomUrl%22%3A%22https%3A%2F%2Fcdn.jsdelivr.net%2Fghost%2Fadmin-x-activitypub%400%2Fdist%2Fadmin-x-activitypub.js%22%7D" />
12
12
 
13
13
  <meta name="HandheldFriendly" content="True" />
14
14
  <meta name="MobileOptimized" content="320" />
@@ -57,8 +57,8 @@
57
57
  <div id="ember-basic-dropdown-wormhole"></div>
58
58
 
59
59
  <script src="assets/vendor-88cd9f5cf5eba65221e2d2a636531eaa.js"></script>
60
- <script src="assets/chunk.874.5eb920d19e75683234c2.js"></script>
61
- <script src="assets/chunk.524.76341ddca302335ab934.js"></script>
62
- <script src="assets/ghost-53495065f10948cc84a1893b07f22402.js"></script>
60
+ <script src="assets/chunk.874.d89f27fe288df0daf539.js"></script>
61
+ <script src="assets/chunk.524.859e8cb40c11bac0d76d.js"></script>
62
+ <script src="assets/ghost-a18a45be9cbdd3a4025e2eeb23043120.js"></script>
63
63
  </body>
64
64
  </html>
@@ -25,8 +25,22 @@ window.addEventListener('message', async function (event) {
25
25
 
26
26
  if (data.action === 'browseComments') {
27
27
  try {
28
+ const {postId, params} = data;
28
29
  const res = await fetch(
29
- adminUrl + '/comments/?limit=50&order=created_at%20desc'
30
+ adminUrl + `/comments/post/${postId}/?${new URLSearchParams(params).toString()}`
31
+ );
32
+ const json = await res.json();
33
+ respond(null, json);
34
+ } catch (err) {
35
+ respond(err, null);
36
+ }
37
+ }
38
+
39
+ if (data.action === 'getReplies') {
40
+ try {
41
+ const {commentId, params} = data;
42
+ const res = await fetch(
43
+ adminUrl + `/comments/${commentId}/replies/?${new URLSearchParams(params).toString()}`
30
44
  );
31
45
  const json = await res.json();
32
46
  respond(null, json);
@@ -0,0 +1,36 @@
1
+ // This is a new endpoint for the admin API to return replies to a comment with pagination
2
+
3
+ const commentsService = require('../../services/comments');
4
+
5
+ /** @type {import('@tryghost/api-framework').Controller} */
6
+ const controller = {
7
+ docName: 'comments',
8
+ browse: {
9
+ headers: {
10
+ cacheInvalidate: false
11
+ },
12
+ options: [
13
+ 'include',
14
+ 'page',
15
+ 'limit',
16
+ 'fields',
17
+ 'filter',
18
+ 'order',
19
+ 'debug',
20
+ 'id'
21
+ ],
22
+ validation: {
23
+ options: {
24
+ id: {
25
+ required: true
26
+ }
27
+ }
28
+ },
29
+ permissions: true,
30
+ query(frame) {
31
+ return commentsService.controller.adminReplies(frame);
32
+ }
33
+ }
34
+ };
35
+
36
+ module.exports = controller;
@@ -1,6 +1,5 @@
1
1
  const models = require('../../models');
2
2
  const commentsService = require('../../services/comments');
3
-
4
3
  function handleCacheHeaders(model, frame) {
5
4
  if (model) {
6
5
  const postId = model.get('post_id');
@@ -197,6 +197,10 @@ module.exports = {
197
197
  return apiFramework.pipeline(require('./comments'), localUtils);
198
198
  },
199
199
 
200
+ get commentReplies() {
201
+ return apiFramework.pipeline(require('./comment-replies'), localUtils);
202
+ },
203
+
200
204
  get links() {
201
205
  return apiFramework.pipeline(require('./links'), localUtils);
202
206
  },
@@ -2,6 +2,7 @@ const _ = require('lodash');
2
2
  const utils = require('../../..');
3
3
  const url = require('../utils/url');
4
4
  const htmlToPlaintext = require('@tryghost/html-to-plaintext');
5
+ const labs = require('../../../../../../../shared/labs');
5
6
 
6
7
  const commentFields = [
7
8
  'id',
@@ -45,8 +46,15 @@ const countFields = [
45
46
  const commentMapper = (model, frame) => {
46
47
  const jsonModel = model.toJSON ? model.toJSON(frame.options) : model;
47
48
 
48
- if (jsonModel.inReplyTo && jsonModel.inReplyTo.status === 'published') {
49
- jsonModel.in_reply_to_snippet = htmlToPlaintext.commentSnippet(jsonModel.inReplyTo.html);
49
+ if (labs.isSet('commentImprovements')) {
50
+ if (jsonModel.inReplyTo && jsonModel.inReplyTo.status === 'published') {
51
+ jsonModel.in_reply_to_snippet = htmlToPlaintext.commentSnippet(jsonModel.inReplyTo.html);
52
+ } else {
53
+ jsonModel.in_reply_to_id = null;
54
+ jsonModel.in_reply_to_snippet = null;
55
+ }
56
+ } else {
57
+ delete jsonModel.in_reply_to_id;
50
58
  }
51
59
 
52
60
  const response = _.pick(jsonModel, commentFields);
@@ -61,6 +61,7 @@ const Comment = ghostBookshelf.Model.extend({
61
61
  // Note: this limit is not working
62
62
  .query('limit', 3);
63
63
  },
64
+
64
65
  customQuery(qb) {
65
66
  qb.where(function () {
66
67
  this.whereNotIn('comments.status', ['hidden', 'deleted'])
@@ -258,6 +259,7 @@ const Comment = ghostBookshelf.Model.extend({
258
259
  const relationsToLoadIndividually = [
259
260
  'replies',
260
261
  'replies.member',
262
+ 'replies.inReplyTo',
261
263
  'replies.count.likes',
262
264
  'replies.count.liked'
263
265
  ].filter(relation => withRelated.includes(relation));
@@ -270,13 +272,32 @@ const Comment = ghostBookshelf.Model.extend({
270
272
 
271
273
  countRelations() {
272
274
  return {
273
- replies(modelOrCollection) {
274
- modelOrCollection.query('columns', 'comments.*', (qb) => {
275
- qb.count('replies.id')
276
- .from('comments AS replies')
277
- .whereRaw('replies.parent_id = comments.id')
278
- .as('count__replies');
279
- });
275
+ replies(modelOrCollection, options) {
276
+ if (labs.isSet('commentImprovements') && !options.isAdmin) {
277
+ modelOrCollection.query('columns', 'comments.*', (qb) => {
278
+ qb.count('replies.id')
279
+ .from('comments AS replies')
280
+ .whereRaw('replies.parent_id = comments.id')
281
+ .whereNotIn('replies.status', ['hidden', 'deleted'])
282
+ .as('count__replies');
283
+ });
284
+ } else {
285
+ modelOrCollection.query('columns', 'comments.*', (qb) => {
286
+ qb.count('replies.id')
287
+ .from('comments AS replies')
288
+ .whereRaw('replies.parent_id = comments.id')
289
+ .as('count__replies');
290
+ });
291
+ }
292
+ if (options.isAdmin && labs.isSet('commentImprovements')) {
293
+ modelOrCollection.query('columns', 'comments.*', (qb) => {
294
+ qb.count('replies.id')
295
+ .from('comments AS replies')
296
+ .whereRaw('replies.parent_id = comments.id')
297
+ .whereNotIn('replies.status', ['deleted'])
298
+ .as('count__replies');
299
+ });
300
+ }
280
301
  },
281
302
  likes(modelOrCollection) {
282
303
  modelOrCollection.query('columns', 'comments.*', (qb) => {
@@ -311,8 +332,7 @@ const Comment = ghostBookshelf.Model.extend({
311
332
  */
312
333
  permittedOptions: function permittedOptions(methodName) {
313
334
  let options = ghostBookshelf.Model.permittedOptions.call(this, methodName);
314
-
315
- // The comment model additionally supports having a parentId option
335
+ // The comment model additionally supports having a parentId and isAdmin option
316
336
  options.push('parentId');
317
337
  options.push('isAdmin');
318
338
 
@@ -82,6 +82,15 @@ module.exports = class CommentsController {
82
82
  return this.service.getReplies(frame.options.id, _.omit(frame.options, 'id'));
83
83
  }
84
84
 
85
+ /**
86
+ * @param {Frame} frame
87
+ */
88
+ async adminReplies(frame) {
89
+ frame.options.isAdmin = true;
90
+ frame.options.order = 'created_at asc'; // we always want to load replies from oldest to newest
91
+ return this.service.getReplies(frame.options.id, _.omit(frame.options, 'id'));
92
+ }
93
+
85
94
  /**
86
95
  * @param {Frame} frame
87
96
  */
@@ -166,7 +166,7 @@
166
166
  </tbody>
167
167
  </table>
168
168
  <hr/>
169
- <p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 5px;">You can also copy & paste this URL into your browser:</p>
169
+ <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 5px;">You can also copy & paste this URL into your browser:</p>
170
170
  <p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; line-height: 25px; margin-top:0; color: #3A464C;">{{postUrl}}#ghost-comments</p>
171
171
  </td>
172
172
  </tr>
@@ -166,7 +166,7 @@
166
166
  </tbody>
167
167
  </table>
168
168
  <hr/>
169
- <p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 5px;">You can also copy & paste this URL into your browser:</p>
169
+ <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 5px;">You can also copy & paste this URL into your browser:</p>
170
170
  <p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; line-height: 25px; margin-top:0; color: #3A464C;">{{postUrl}}#ghost-comments</p>
171
171
  </td>
172
172
  </tr>
@@ -161,7 +161,7 @@
161
161
  </tbody>
162
162
  </table>
163
163
  <hr/>
164
- <p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 5px;">You can also copy & paste this URL into your browser:</p>
164
+ <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 5px;">You can also copy & paste this URL into your browser:</p>
165
165
  <p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; line-height: 25px; margin-top:0; color: #3A464C;">{{postUrl}}#ghost-comments</p>
166
166
  </td>
167
167
  </tr>
@@ -32,7 +32,8 @@ class EmailAnalyticsServiceWrapper {
32
32
  EmailRecipientFailure,
33
33
  EmailSpamComplaintEvent
34
34
  },
35
- emailSuppressionList
35
+ emailSuppressionList,
36
+ prometheusClient
36
37
  });
37
38
 
38
39
  // Since this is running in a worker thread, we cant dispatch directly
@@ -40,7 +41,8 @@ class EmailAnalyticsServiceWrapper {
40
41
  const eventProcessor = new EmailEventProcessor({
41
42
  domainEvents,
42
43
  db,
43
- eventStorage: this.eventStorage
44
+ eventStorage: this.eventStorage,
45
+ prometheusClient
44
46
  });
45
47
 
46
48
  this.service = new EmailAnalyticsService({
@@ -136,7 +136,7 @@ module.exports = ({t, siteTitle, email, url, accentColor = '#15212A', siteDomain
136
136
  <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; color: #3A464C; font-weight: normal; line-height: 24px; margin: 0; margin-bottom: 11px;">${t('For your security, the link will expire in 24 hours time.')}</p>
137
137
  <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; color: #3A464C; font-weight: normal; line-height: 24px; margin: 0; margin-bottom: 30px;">${t('See you soon!')}</p>
138
138
  <hr/>
139
- <p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; margin: 0; line-height: 24px;">${t('You can also copy & paste this URL into your browser:')}</p>
139
+ <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; margin: 0; line-height: 24px;">${t('You can also copy & paste this URL into your browser:')}</p>
140
140
  <p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; line-height: 22px; margin-top:0; color: #3A464C;">${url}</p>
141
141
  </td>
142
142
  </tr>
@@ -136,7 +136,7 @@ module.exports = ({t, siteTitle, email, url, accentColor = '#15212A', siteDomain
136
136
  <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; color: #3A464C; font-weight: normal; line-height: 24px; margin: 0; margin-bottom: 11px;">${t('For your security, the link will expire in 24 hours time.')}</p>
137
137
  <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; color: #3A464C; font-weight: normal; line-height: 24px; margin: 0; margin-bottom: 30px;">${t('See you soon!')}</p>
138
138
  <hr/>
139
- <p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; line-height: 24px; margin: 0;">${t('You can also copy & paste this URL into your browser:')}</p>
139
+ <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; line-height: 24px; margin: 0;">${t('You can also copy & paste this URL into your browser:')}</p>
140
140
  <p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; line-height: 22px; margin-top: 0; color: #3A464C;">${url}</p>
141
141
  </td>
142
142
  </tr>
@@ -136,7 +136,7 @@ module.exports = ({t, siteTitle, email, url, accentColor = '#15212A', siteDomain
136
136
  <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; color: #3A464C; font-weight: normal; line-height: 24px; margin: 0; margin-bottom: 11px;">${t('For your security, the link will expire in 24 hours time.')}</p>
137
137
  <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; color: #3A464C; font-weight: normal; line-height: 24px; margin: 0; margin-bottom: 30px;">${t('See you soon!')}</p>
138
138
  <hr/>
139
- <p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; line-height: 24px; margin: 0;">${t('You can also copy & paste this URL into your browser:')}</p>
139
+ <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; line-height: 24px; margin: 0;">${t('You can also copy & paste this URL into your browser:')}</p>
140
140
  <p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; line-height: 22px; margin-top: 0; color: #3A464C;">${url}</p>
141
141
  </td>
142
142
  </tr>
@@ -136,7 +136,7 @@ module.exports = ({t, siteTitle, email, url, accentColor = '#15212A', siteDomain
136
136
  <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; color: #3A464C; font-weight: normal; margin: 0; line-height: 24px; margin-bottom: 11px;">${t('For your security, the link will expire in 24 hours time.')}</p>
137
137
  <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; color: #3A464C; font-weight: normal; margin: 0; line-height: 24px; margin-bottom: 30px;">${t('All the best!')}</p>
138
138
  <hr/>
139
- <p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; margin: 0; line-height: 24px;">${t('You can also copy & paste this URL into your browser:')}</p>
139
+ <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; margin: 0; line-height: 24px;">${t('You can also copy & paste this URL into your browser:')}</p>
140
140
  <p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; line-height: 22px; margin-top: 0; color: #3A464C;">${url}</p>
141
141
  </td>
142
142
  </tr>
@@ -127,7 +127,7 @@ module.exports = ({t, email, url}) => `
127
127
  </table>
128
128
  <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; color: #3A464C; font-weight: normal; margin: 0; line-height: 24px; margin-bottom: 25px;">${t('For your security, the link will expire in 24 hours time.')}</p>
129
129
  <hr/>
130
- <p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; margin: 0; line-height: 24px;">${t('You can also copy & paste this URL into your browser:')}</p>
130
+ <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; margin: 0; line-height: 24px;">${t('You can also copy & paste this URL into your browser:')}</p>
131
131
  <p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; line-height: 22px; margin-top: 0; color: #738A94;">${url}</p>
132
132
  </td>
133
133
  </tr>
@@ -135,7 +135,7 @@ module.exports = ({email, url}) => `
135
135
  </table>
136
136
  <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; color: #3A464C; font-weight: normal; line-height: 24px; margin: 0; margin-bottom: 11px;">For your security, the link will expire in 24 hours time.</p>
137
137
  <hr/>
138
- <p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; line-height: 24px; margin: 0;">You can also copy & paste this URL into your browser:</p>
138
+ <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; line-height: 24px; margin: 0;">You can also copy & paste this URL into your browser:</p>
139
139
  <p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; line-height: 22px; margin-top: 0; color: #3A464C;">${url}</p>
140
140
  </td>
141
141
  </tr>
@@ -127,7 +127,7 @@ module.exports = ({email, url}) => `
127
127
  </table>
128
128
  <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 25px;">For your security, the link will expire in 24 hours time.</p>
129
129
  <hr/>
130
- <p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 5px;">You can also copy & paste this URL into your browser:</p>
130
+ <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 5px;">You can also copy & paste this URL into your browser:</p>
131
131
  <p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; line-height: 21px; margin-top: 0; color: #738A94;">${url}</p>
132
132
  </td>
133
133
  </tr>
@@ -9,16 +9,40 @@ class WebhookTrigger {
9
9
  * @param {Object} options
10
10
  * @param {Object} options.models - Ghost models
11
11
  * @param {Function} options.payload - Function to generate payload
12
+ * @param {import('../../services/limits')} options.limitService - Function to generate payload
12
13
  * @param {Object} [options.request] - HTTP request handling library
13
14
  */
14
- constructor({models, payload, request}){
15
+ constructor({models, payload, request, limitService}){
15
16
  this.models = models;
16
17
  this.payload = payload;
17
18
 
18
19
  this.request = request ?? require('@tryghost/request');
20
+ this.limitService = limitService;
19
21
  }
20
22
 
21
- getAll(event) {
23
+ async getAll(event) {
24
+ if (this.limitService.isLimited('customIntegrations')) {
25
+ // NOTE: using "checkWouldGoOverLimit" instead of "checkIsOverLimit" here because flag limits don't have
26
+ // a concept of measuring if the limit has been surpassed
27
+ const overLimit = await this.limitService.checkWouldGoOverLimit('customIntegrations');
28
+
29
+ if (overLimit) {
30
+ logging.info(`Skipping all non-internal webhooks for event ${event}. The "customIntegrations" plan limit is enabled.`);
31
+ const result = await this.models
32
+ .Webhook
33
+ .findAllByEvent(event, {
34
+ context: {internal: true},
35
+ withRelated: ['integration']
36
+ });
37
+
38
+ return {
39
+ models: result?.models?.filter((model) => {
40
+ return model.related('integration')?.get('type') === 'internal';
41
+ }) || []
42
+ };
43
+ }
44
+ }
45
+
22
46
  return this.models
23
47
  .Webhook
24
48
  .findAllByEvent(event, {context: {internal: true}});
@@ -1,6 +1,5 @@
1
1
  const _ = require('lodash');
2
2
  const limitService = require('../../services/limits');
3
- const logging = require('@tryghost/logging');
4
3
  const WebhookTrigger = require('./WebhookTrigger');
5
4
  const models = require('../../models');
6
5
  const payload = require('./payload');
@@ -46,18 +45,7 @@ const WEBHOOKS = [
46
45
  ];
47
46
 
48
47
  const listen = async () => {
49
- if (limitService.isLimited('customIntegrations')) {
50
- // NOTE: using "checkWouldGoOverLimit" instead of "checkIsOverLimit" here because flag limits don't have
51
- // a concept of measuring if the limit has been surpassed
52
- const overLimit = await limitService.checkWouldGoOverLimit('customIntegrations');
53
-
54
- if (overLimit) {
55
- logging.info(`Skipped subscribing webhooks to events. The "customIntegrations" plan limit is enabled.`);
56
- return;
57
- }
58
- }
59
-
60
- const webhookTrigger = new WebhookTrigger({models, payload});
48
+ const webhookTrigger = new WebhookTrigger({models, payload, limitService});
61
49
  _.each(WEBHOOKS, (event) => {
62
50
  // @NOTE: The early exit makes sure the listeners are only registered once.
63
51
  // During testing the "events" instance is kept around with all the
@@ -51,6 +51,7 @@ module.exports = function apiRoutes() {
51
51
 
52
52
  router.get('/mentions', mw.authAdminApi, http(api.mentions.browse));
53
53
 
54
+ router.get('/comments/:id/replies', mw.authAdminApi, http(api.commentReplies.browse));
54
55
  router.get('/comments/post/:post_id', mw.authAdminApi, http(api.comments.browse));
55
56
  router.put('/comments/:id', mw.authAdminApi, http(api.comments.edit));
56
57
 
@@ -210,7 +210,7 @@
210
210
  },
211
211
  "comments": {
212
212
  "url": "https://cdn.jsdelivr.net/ghost/comments-ui@~{version}/umd/comments-ui.min.js",
213
- "version": "0.21"
213
+ "version": "0.22"
214
214
  },
215
215
  "signupForm": {
216
216
  "url": "https://cdn.jsdelivr.net/ghost/signup-form@~{version}/umd/signup-form.min.js",
@@ -31,7 +31,8 @@ const BETA_FEATURES = [
31
31
  'stripeAutomaticTax',
32
32
  'webmentions',
33
33
  'editorExcerpt',
34
- 'ActivityPub'
34
+ 'ActivityPub',
35
+ 'customFonts'
35
36
  ];
36
37
 
37
38
  const ALPHA_FEATURES = [
@@ -46,8 +47,7 @@ const ALPHA_FEATURES = [
46
47
  'adminXDemo',
47
48
  'contentVisibility',
48
49
  'commentImprovements',
49
- 'staff2fa',
50
- 'customFonts'
50
+ 'staff2fa'
51
51
  ];
52
52
 
53
53
  module.exports.GA_KEYS = [...GA_FEATURES];