ghost 5.73.2 → 5.74.1

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 (177) hide show
  1. package/components/tryghost-adapter-cache-memory-ttl-5.74.1.tgz +0 -0
  2. package/components/tryghost-adapter-cache-redis-5.74.1.tgz +0 -0
  3. package/components/{tryghost-adapter-manager-5.73.2.tgz → tryghost-adapter-manager-5.74.1.tgz} +0 -0
  4. package/components/{tryghost-announcement-bar-settings-5.73.2.tgz → tryghost-announcement-bar-settings-5.74.1.tgz} +0 -0
  5. package/components/{tryghost-api-framework-5.73.2.tgz → tryghost-api-framework-5.74.1.tgz} +0 -0
  6. package/components/tryghost-api-version-compatibility-service-5.74.1.tgz +0 -0
  7. package/components/{tryghost-audience-feedback-5.73.2.tgz → tryghost-audience-feedback-5.74.1.tgz} +0 -0
  8. package/components/tryghost-bookshelf-repository-5.74.1.tgz +0 -0
  9. package/components/{tryghost-bootstrap-socket-5.73.2.tgz → tryghost-bootstrap-socket-5.74.1.tgz} +0 -0
  10. package/components/tryghost-collections-5.74.1.tgz +0 -0
  11. package/components/{tryghost-constants-5.73.2.tgz → tryghost-constants-5.74.1.tgz} +0 -0
  12. package/components/tryghost-custom-theme-settings-service-5.74.1.tgz +0 -0
  13. package/components/tryghost-data-generator-5.74.1.tgz +0 -0
  14. package/components/tryghost-domain-events-5.74.1.tgz +0 -0
  15. package/components/tryghost-donations-5.74.1.tgz +0 -0
  16. package/components/tryghost-dynamic-routing-events-5.74.1.tgz +0 -0
  17. package/components/tryghost-email-analytics-provider-mailgun-5.74.1.tgz +0 -0
  18. package/components/tryghost-email-analytics-service-5.74.1.tgz +0 -0
  19. package/components/tryghost-email-content-generator-5.74.1.tgz +0 -0
  20. package/components/{tryghost-email-events-5.73.2.tgz → tryghost-email-events-5.74.1.tgz} +0 -0
  21. package/components/tryghost-email-service-5.74.1.tgz +0 -0
  22. package/components/tryghost-email-suppression-list-5.74.1.tgz +0 -0
  23. package/components/tryghost-event-aware-cache-wrapper-5.74.1.tgz +0 -0
  24. package/components/tryghost-express-dynamic-redirects-5.74.1.tgz +0 -0
  25. package/components/tryghost-external-media-inliner-5.74.1.tgz +0 -0
  26. package/components/tryghost-extract-api-key-5.74.1.tgz +0 -0
  27. package/components/tryghost-html-to-plaintext-5.74.1.tgz +0 -0
  28. package/components/tryghost-i18n-5.74.1.tgz +0 -0
  29. package/components/tryghost-importer-handler-content-files-5.74.1.tgz +0 -0
  30. package/components/{tryghost-importer-revue-5.73.2.tgz → tryghost-importer-revue-5.74.1.tgz} +0 -0
  31. package/components/tryghost-in-memory-repository-5.74.1.tgz +0 -0
  32. package/components/{tryghost-job-manager-5.73.2.tgz → tryghost-job-manager-5.74.1.tgz} +0 -0
  33. package/components/tryghost-link-redirects-5.74.1.tgz +0 -0
  34. package/components/tryghost-link-replacer-5.74.1.tgz +0 -0
  35. package/components/tryghost-link-tracking-5.74.1.tgz +0 -0
  36. package/components/{tryghost-magic-link-5.73.2.tgz → tryghost-magic-link-5.74.1.tgz} +0 -0
  37. package/components/{tryghost-mail-events-5.73.2.tgz → tryghost-mail-events-5.74.1.tgz} +0 -0
  38. package/components/tryghost-mailgun-client-5.74.1.tgz +0 -0
  39. package/components/{tryghost-member-attribution-5.73.2.tgz → tryghost-member-attribution-5.74.1.tgz} +0 -0
  40. package/components/tryghost-member-events-5.74.1.tgz +0 -0
  41. package/components/tryghost-members-api-5.74.1.tgz +0 -0
  42. package/components/{tryghost-members-csv-5.73.2.tgz → tryghost-members-csv-5.74.1.tgz} +0 -0
  43. package/components/tryghost-members-events-service-5.74.1.tgz +0 -0
  44. package/components/{tryghost-members-importer-5.73.2.tgz → tryghost-members-importer-5.74.1.tgz} +0 -0
  45. package/components/tryghost-members-offers-5.74.1.tgz +0 -0
  46. package/components/tryghost-members-payments-5.74.1.tgz +0 -0
  47. package/components/tryghost-members-ssr-5.74.1.tgz +0 -0
  48. package/components/{tryghost-members-stripe-service-5.73.2.tgz → tryghost-members-stripe-service-5.74.1.tgz} +0 -0
  49. package/components/tryghost-mentions-email-report-5.74.1.tgz +0 -0
  50. package/components/tryghost-milestones-5.74.1.tgz +0 -0
  51. package/components/{tryghost-minifier-5.73.2.tgz → tryghost-minifier-5.74.1.tgz} +0 -0
  52. package/components/{tryghost-model-to-domain-event-interceptor-5.73.2.tgz → tryghost-model-to-domain-event-interceptor-5.74.1.tgz} +0 -0
  53. package/components/tryghost-mw-api-version-mismatch-5.74.1.tgz +0 -0
  54. package/components/tryghost-mw-cache-control-5.74.1.tgz +0 -0
  55. package/components/tryghost-mw-error-handler-5.74.1.tgz +0 -0
  56. package/components/{tryghost-mw-session-from-token-5.73.2.tgz → tryghost-mw-session-from-token-5.74.1.tgz} +0 -0
  57. package/components/tryghost-mw-update-user-last-seen-5.74.1.tgz +0 -0
  58. package/components/tryghost-mw-version-match-5.74.1.tgz +0 -0
  59. package/components/tryghost-mw-vhost-5.74.1.tgz +0 -0
  60. package/components/tryghost-nql-filter-expansions-5.74.1.tgz +0 -0
  61. package/components/tryghost-oembed-service-5.74.1.tgz +0 -0
  62. package/components/{tryghost-package-json-5.73.2.tgz → tryghost-package-json-5.74.1.tgz} +0 -0
  63. package/components/{tryghost-post-events-5.73.2.tgz → tryghost-post-events-5.74.1.tgz} +0 -0
  64. package/components/tryghost-post-revisions-5.74.1.tgz +0 -0
  65. package/components/tryghost-posts-service-5.74.1.tgz +0 -0
  66. package/components/tryghost-recommendations-5.74.1.tgz +0 -0
  67. package/components/tryghost-referrers-5.74.1.tgz +0 -0
  68. package/components/{tryghost-security-5.73.2.tgz → tryghost-security-5.74.1.tgz} +0 -0
  69. package/components/tryghost-session-service-5.74.1.tgz +0 -0
  70. package/components/tryghost-settings-path-manager-5.74.1.tgz +0 -0
  71. package/components/tryghost-slack-notifications-5.74.1.tgz +0 -0
  72. package/components/{tryghost-staff-service-5.73.2.tgz → tryghost-staff-service-5.74.1.tgz} +0 -0
  73. package/components/tryghost-stats-service-5.74.1.tgz +0 -0
  74. package/components/tryghost-tiers-5.74.1.tgz +0 -0
  75. package/components/tryghost-update-check-service-5.74.1.tgz +0 -0
  76. package/components/{tryghost-verification-trigger-5.73.2.tgz → tryghost-verification-trigger-5.74.1.tgz} +0 -0
  77. package/components/tryghost-version-notifications-data-service-5.74.1.tgz +0 -0
  78. package/components/tryghost-webmentions-5.74.1.tgz +0 -0
  79. package/content/themes/source/assets/built/screen.css +1 -1
  80. package/content/themes/source/assets/built/screen.css.map +1 -1
  81. package/content/themes/source/assets/built/source.js +1 -1
  82. package/content/themes/source/assets/built/source.js.map +1 -1
  83. package/content/themes/source/assets/css/screen.css +2 -2
  84. package/content/themes/source/assets/js/dropdown.js +7 -0
  85. package/content/themes/source/package.json +1 -1
  86. package/core/boot.js +5 -0
  87. package/core/built/admin/assets/admin-x-settings/{CodeEditorView-7eba6adb.mjs → CodeEditorView-c01e294c.mjs} +83 -83
  88. package/core/built/admin/assets/admin-x-settings/admin-x-settings.js +2 -2
  89. package/core/built/admin/assets/admin-x-settings/{index-8ca58c71.mjs → index-6594c4bf.mjs} +9294 -9094
  90. package/core/built/admin/assets/admin-x-settings/{index-e732a865.mjs → index-9f6ad8b1.mjs} +182 -182
  91. package/core/built/admin/assets/admin-x-settings/{modals-c85ad0c1.mjs → modals-37a4690d.mjs} +9832 -9404
  92. package/core/built/admin/assets/{chunk.143.69dbfb81579afebba388.js → chunk.143.821225c203086be63d54.js} +5 -5
  93. package/core/built/admin/assets/{chunk.178.5a3a63ad3ac3c3190d9f.js → chunk.178.4dbabde59a049f23a86c.js} +4 -4
  94. package/core/built/admin/assets/{chunk.761.88d6f15954870c0c9f60.js → chunk.761.5cfbe0d0f8ec7aefe7bc.js} +234 -201
  95. package/core/built/admin/assets/{ghost-f849fe36e5d0bab807c159e331a2c5a9.js → ghost-ad9952b86c1d886c49a92339adf702e3.js} +153 -141
  96. package/core/built/admin/assets/koenig-lexical/index.css +1 -1
  97. package/core/built/admin/assets/koenig-lexical/koenig-lexical.js +21808 -21618
  98. package/core/built/admin/assets/koenig-lexical/koenig-lexical.umd.js +152 -152
  99. package/core/built/admin/index.html +4 -4
  100. package/core/frontend/services/routing/controllers/previews.js +5 -0
  101. package/core/frontend/src/cards/css/toggle.css +2 -0
  102. package/core/server/api/endpoints/members.js +25 -0
  103. package/core/server/api/endpoints/utils/serializers/output/mappers/activity-feed-events.js +7 -1
  104. package/core/server/data/migrations/versions/5.74/2023-11-14-11-15-00-add-transient-id-column-nullable.js +9 -0
  105. package/core/server/data/migrations/versions/5.74/2023-11-14-11-16-00-fill-transient-id-column.js +17 -0
  106. package/core/server/data/migrations/versions/5.74/2023-11-14-11-17-00-drop-nullable-transient-id-column.js +4 -0
  107. package/core/server/data/schema/schema.js +1 -0
  108. package/core/server/lib/lexical.js +0 -4
  109. package/core/server/models/comment.js +2 -2
  110. package/core/server/models/member.js +1 -0
  111. package/core/server/models/post.js +2 -2
  112. package/core/server/services/email-analytics/EmailAnalyticsServiceWrapper.js +5 -2
  113. package/core/server/services/email-suppression-list/MailgunEmailSuppressionList.js +9 -0
  114. package/core/server/services/offers/OfferBookshelfRepository.js +2 -2
  115. package/core/server/services/webhooks/listen.js +1 -1
  116. package/core/server/web/api/endpoints/admin/routes.js +1 -0
  117. package/core/server/web/api/endpoints/content/routes.js +1 -2
  118. package/core/server/web/members/app.js +1 -1
  119. package/core/shared/labs.js +4 -2
  120. package/package.json +160 -158
  121. package/yarn.lock +320 -357
  122. package/components/tryghost-adapter-cache-memory-ttl-5.73.2.tgz +0 -0
  123. package/components/tryghost-adapter-cache-redis-5.73.2.tgz +0 -0
  124. package/components/tryghost-api-version-compatibility-service-5.73.2.tgz +0 -0
  125. package/components/tryghost-bookshelf-repository-5.73.2.tgz +0 -0
  126. package/components/tryghost-collections-5.73.2.tgz +0 -0
  127. package/components/tryghost-custom-theme-settings-service-5.73.2.tgz +0 -0
  128. package/components/tryghost-data-generator-5.73.2.tgz +0 -0
  129. package/components/tryghost-domain-events-5.73.2.tgz +0 -0
  130. package/components/tryghost-donations-5.73.2.tgz +0 -0
  131. package/components/tryghost-dynamic-routing-events-5.73.2.tgz +0 -0
  132. package/components/tryghost-email-analytics-provider-mailgun-5.73.2.tgz +0 -0
  133. package/components/tryghost-email-analytics-service-5.73.2.tgz +0 -0
  134. package/components/tryghost-email-content-generator-5.73.2.tgz +0 -0
  135. package/components/tryghost-email-service-5.73.2.tgz +0 -0
  136. package/components/tryghost-email-suppression-list-5.73.2.tgz +0 -0
  137. package/components/tryghost-event-aware-cache-wrapper-5.73.2.tgz +0 -0
  138. package/components/tryghost-express-dynamic-redirects-5.73.2.tgz +0 -0
  139. package/components/tryghost-external-media-inliner-5.73.2.tgz +0 -0
  140. package/components/tryghost-extract-api-key-5.73.2.tgz +0 -0
  141. package/components/tryghost-html-to-plaintext-5.73.2.tgz +0 -0
  142. package/components/tryghost-i18n-5.73.2.tgz +0 -0
  143. package/components/tryghost-importer-handler-content-files-5.73.2.tgz +0 -0
  144. package/components/tryghost-in-memory-repository-5.73.2.tgz +0 -0
  145. package/components/tryghost-link-redirects-5.73.2.tgz +0 -0
  146. package/components/tryghost-link-replacer-5.73.2.tgz +0 -0
  147. package/components/tryghost-link-tracking-5.73.2.tgz +0 -0
  148. package/components/tryghost-mailgun-client-5.73.2.tgz +0 -0
  149. package/components/tryghost-member-events-5.73.2.tgz +0 -0
  150. package/components/tryghost-members-api-5.73.2.tgz +0 -0
  151. package/components/tryghost-members-events-service-5.73.2.tgz +0 -0
  152. package/components/tryghost-members-offers-5.73.2.tgz +0 -0
  153. package/components/tryghost-members-payments-5.73.2.tgz +0 -0
  154. package/components/tryghost-members-ssr-5.73.2.tgz +0 -0
  155. package/components/tryghost-mentions-email-report-5.73.2.tgz +0 -0
  156. package/components/tryghost-milestones-5.73.2.tgz +0 -0
  157. package/components/tryghost-mw-api-version-mismatch-5.73.2.tgz +0 -0
  158. package/components/tryghost-mw-cache-control-5.73.2.tgz +0 -0
  159. package/components/tryghost-mw-error-handler-5.73.2.tgz +0 -0
  160. package/components/tryghost-mw-update-user-last-seen-5.73.2.tgz +0 -0
  161. package/components/tryghost-mw-version-match-5.73.2.tgz +0 -0
  162. package/components/tryghost-mw-vhost-5.73.2.tgz +0 -0
  163. package/components/tryghost-nql-filter-expansions-5.73.2.tgz +0 -0
  164. package/components/tryghost-oembed-service-5.73.2.tgz +0 -0
  165. package/components/tryghost-post-revisions-5.73.2.tgz +0 -0
  166. package/components/tryghost-posts-service-5.73.2.tgz +0 -0
  167. package/components/tryghost-recommendations-5.73.2.tgz +0 -0
  168. package/components/tryghost-referrers-5.73.2.tgz +0 -0
  169. package/components/tryghost-session-service-5.73.2.tgz +0 -0
  170. package/components/tryghost-settings-path-manager-5.73.2.tgz +0 -0
  171. package/components/tryghost-slack-notifications-5.73.2.tgz +0 -0
  172. package/components/tryghost-stats-service-5.73.2.tgz +0 -0
  173. package/components/tryghost-tiers-5.73.2.tgz +0 -0
  174. package/components/tryghost-update-check-service-5.73.2.tgz +0 -0
  175. package/components/tryghost-version-notifications-data-service-5.73.2.tgz +0 -0
  176. package/components/tryghost-webmentions-5.73.2.tgz +0 -0
  177. /package/core/built/admin/assets/{chunk.761.88d6f15954870c0c9f60.js.LICENSE.txt → chunk.761.5cfbe0d0f8ec7aefe7bc.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.73%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%22ce83cc9517%22%2C%22adminXSettingsFilename%22%3A%22admin-x-settings.js%22%2C%22adminXSettingsHash%22%3A%2291be3d3866%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.74%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%228d3cae634e%22%2C%22adminXSettingsFilename%22%3A%22admin-x-settings.js%22%2C%22adminXSettingsHash%22%3A%22344c297ea0%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-f6856af9fcd8ab6533f2a4339ececbc8.js"></script>
60
- <script src="assets/chunk.761.88d6f15954870c0c9f60.js"></script>
61
- <script src="assets/chunk.143.69dbfb81579afebba388.js"></script>
62
- <script src="assets/ghost-f849fe36e5d0bab807c159e331a2c5a9.js"></script>
60
+ <script src="assets/chunk.761.5cfbe0d0f8ec7aefe7bc.js"></script>
61
+ <script src="assets/chunk.143.821225c203086be63d54.js"></script>
62
+ <script src="assets/ghost-ad9952b86c1d886c49a92339adf702e3.js"></script>
63
63
  </body>
64
64
  </html>
@@ -53,6 +53,11 @@ module.exports = function previewController(req, res, next) {
53
53
  return urlUtils.redirect301(res, routerManager.getUrlByResourceId(post.id, {withSubdirectory: true}));
54
54
  }
55
55
 
56
+ // published content should only resolve to /:slug or /email/:uuid - /p/:uuid is for drafts only in lieu of an actual preview api
57
+ if (post.status !== 'published' && post.email_only === true) {
58
+ return urlUtils.redirect301(res, urlUtils.urlJoin('/email', post.uuid, '/'));
59
+ }
60
+
56
61
  post.access = !!post.html;
57
62
 
58
63
  return renderer.renderEntry(req, res)(post);
@@ -70,8 +70,10 @@
70
70
  justify-content: center;
71
71
  align-items: center;
72
72
  margin-left: 1em;
73
+ padding: 0;
73
74
  background: none;
74
75
  border: 0;
76
+ cursor: pointer;
75
77
  }
76
78
 
77
79
  .kg-toggle-heading svg {
@@ -143,6 +143,31 @@ module.exports = {
143
143
  }
144
144
  },
145
145
 
146
+ logout: {
147
+ statusCode: 204,
148
+ headers: {
149
+ cacheInvalidate: false
150
+ },
151
+ options: [
152
+ 'id'
153
+ ],
154
+ validation: {
155
+ options: {
156
+ id: {
157
+ required: true
158
+ }
159
+ }
160
+ },
161
+ permissions: {
162
+ method: 'edit'
163
+ },
164
+ async query(frame) {
165
+ const member = await membersService.api.memberBREADService.logout(frame.options);
166
+
167
+ return member;
168
+ }
169
+ },
170
+
146
171
  editSubscription: {
147
172
  statusCode: 200,
148
173
  headers: {
@@ -107,7 +107,7 @@ const feedbackEventMapper = (json, frame) => {
107
107
  } else {
108
108
  response.post = null;
109
109
  }
110
-
110
+
111
111
  if (data.member) {
112
112
  response.member = _.pick(data.member, memberFields);
113
113
  } else {
@@ -159,6 +159,12 @@ const activityFeedMapper = (event, frame) => {
159
159
  if (event.data?.subscriptionCreatedEvent) {
160
160
  delete event.data.subscriptionCreatedEvent;
161
161
  }
162
+
163
+ if (event.data.member) {
164
+ event.data.member = _.pick(event.data.member, memberFields);
165
+ } else {
166
+ event.data.member = null;
167
+ }
162
168
  return event;
163
169
  };
164
170
 
@@ -0,0 +1,9 @@
1
+ const {createAddColumnMigration} = require('../../utils');
2
+
3
+ // First make a nullable column
4
+ module.exports = createAddColumnMigration('members', 'transient_id', {
5
+ type: 'string',
6
+ maxlength: 191,
7
+ nullable: true,
8
+ unique: true
9
+ });
@@ -0,0 +1,17 @@
1
+ const logging = require('@tryghost/logging');
2
+
3
+ const {createTransactionalMigration} = require('../../utils');
4
+
5
+ module.exports = createTransactionalMigration(
6
+ async function up(knex) {
7
+ logging.info('Setting transient_id column to email');
8
+
9
+ const updatedRows = await knex('members')
10
+ .update('transient_id', knex.raw('email'));
11
+
12
+ logging.info(`Updated ${updatedRows} members with transient_id = email`);
13
+ },
14
+ async function down() {
15
+ // Not required
16
+ }
17
+ );
@@ -0,0 +1,4 @@
1
+ const {createDropNullableMigration} = require('../../utils');
2
+
3
+ // We need to disable foreign key checks because if MySQL is missing the STRICT_TRANS_TABLES mode, we cannot revert the migration
4
+ module.exports = createDropNullableMigration('members', 'transient_id', {disableForeignKeyChecks: true});
@@ -417,6 +417,7 @@ module.exports = {
417
417
  members: {
418
418
  id: {type: 'string', maxlength: 24, nullable: false, primary: true},
419
419
  uuid: {type: 'string', maxlength: 36, nullable: true, unique: true, validations: {isUUID: true}},
420
+ transient_id: {type: 'string', maxlength: 191, nullable: false, unique: true},
420
421
  email: {type: 'string', maxlength: 191, nullable: false, unique: true, validations: {isEmail: true}},
421
422
  status: {
422
423
  type: 'string', maxlength: 50, nullable: false, defaultTo: 'free', validations: {
@@ -99,10 +99,6 @@ module.exports = {
99
99
  && imageTransform.shouldResizeFileExtension(ext)
100
100
  && typeof storage.getStorage('images').saveRaw === 'function';
101
101
  },
102
- createDocument() {
103
- const {JSDOM} = require('jsdom');
104
- return (new JSDOM()).window.document;
105
- },
106
102
  getCollectionPosts
107
103
  }, userOptions);
108
104
 
@@ -78,7 +78,7 @@ const Comment = ghostBookshelf.Model.extend({
78
78
  // Enforce _blank and safe URLs
79
79
  transformTags: {
80
80
  a: sanitizeHtml.simpleTransform('a', {
81
- target: '_blank',
81
+ target: '_blank',
82
82
  rel: 'ugc noopener noreferrer nofollow'
83
83
  })
84
84
  }
@@ -106,7 +106,7 @@ const Comment = ghostBookshelf.Model.extend({
106
106
  if (options.parentId === null) {
107
107
  return 'parent_id:null';
108
108
  }
109
- return 'parent_id:' + options.parentId;
109
+ return 'parent_id:\'' + options.parentId + '\'';
110
110
  }
111
111
 
112
112
  return null;
@@ -11,6 +11,7 @@ const Member = ghostBookshelf.Model.extend({
11
11
  return {
12
12
  status: 'free',
13
13
  uuid: uuid.v4(),
14
+ transient_id: uuid.v4(),
14
15
  email_count: 0,
15
16
  email_opened_count: 0,
16
17
  enable_comment_notifications: true
@@ -904,7 +904,7 @@ Post = ghostBookshelf.Model.extend({
904
904
  ops.push(function updateRevisions() {
905
905
  return ghostBookshelf.model('MobiledocRevision')
906
906
  .findAll(Object.assign({
907
- filter: `post_id:${model.id}`,
907
+ filter: `post_id:'${model.id}'`,
908
908
  columns: ['id']
909
909
  }, _.pick(options, 'transacting')))
910
910
  .then((revisions) => {
@@ -958,7 +958,7 @@ Post = ghostBookshelf.Model.extend({
958
958
  ops.push(async function updateRevisions() {
959
959
  const revisionModels = await ghostBookshelf.model('PostRevision')
960
960
  .findAll(Object.assign({
961
- filter: `post_id:${model.id}`,
961
+ filter: `post_id:'${model.id}'`,
962
962
  columns: ['id', 'lexical', 'created_at', 'author_id', 'title', 'reason', 'post_status', 'created_at_ts', 'feature_image']
963
963
  }, _.pick(options, 'transacting')));
964
964
 
@@ -9,7 +9,7 @@ class EmailAnalyticsServiceWrapper {
9
9
  const {EmailAnalyticsService} = require('@tryghost/email-analytics-service');
10
10
  const {EmailEventStorage, EmailEventProcessor} = require('@tryghost/email-service');
11
11
  const MailgunProvider = require('@tryghost/email-analytics-provider-mailgun');
12
- const {EmailRecipientFailure, EmailSpamComplaintEvent} = require('../../models');
12
+ const {EmailRecipientFailure, EmailSpamComplaintEvent, Email} = require('../../models');
13
13
  const StartEmailAnalyticsJobEvent = require('./events/StartEmailAnalyticsJobEvent');
14
14
 
15
15
  const domainEvents = require('@tryghost/domain-events');
@@ -19,14 +19,17 @@ class EmailAnalyticsServiceWrapper {
19
19
  const queries = require('./lib/queries');
20
20
  const membersService = require('../members');
21
21
  const membersRepository = membersService.api.members;
22
+ const emailSuppressionList = require('../email-suppression-list');
22
23
 
23
24
  this.eventStorage = new EmailEventStorage({
24
25
  db,
25
26
  membersRepository,
26
27
  models: {
28
+ Email,
27
29
  EmailRecipientFailure,
28
30
  EmailSpamComplaintEvent
29
- }
31
+ },
32
+ emailSuppressionList
30
33
  });
31
34
 
32
35
  // Since this is running in a worker thread, we cant dispatch directly
@@ -47,6 +47,15 @@ class MailgunEmailSuppressionList extends AbstractEmailSuppressionList {
47
47
  return true;
48
48
  }
49
49
 
50
+ async removeUnsubscribe(email) {
51
+ try {
52
+ await this.apiClient.removeUnsubscribe(email);
53
+ } catch (err) {
54
+ logging.error(err);
55
+ return false;
56
+ }
57
+ }
58
+
50
59
  async getSuppressionData(email) {
51
60
  try {
52
61
  const model = await this.Suppression.findOne({
@@ -97,7 +97,6 @@ class OfferBookshelfRepository {
97
97
  */
98
98
  async mapToOffer(model, options) {
99
99
  const json = model.toJSON();
100
-
101
100
  const count = await this.OfferRedemptionModel.where({offer_id: json.id}).count('id', {
102
101
  transacting: options.transacting
103
102
  });
@@ -119,7 +118,8 @@ class OfferBookshelfRepository {
119
118
  tier: {
120
119
  id: json.product.id,
121
120
  name: json.product.name
122
- }
121
+ },
122
+ created_at: json.created_at
123
123
  }, null);
124
124
  } catch (err) {
125
125
  logger.error(err);
@@ -52,7 +52,7 @@ const listen = async () => {
52
52
  const overLimit = await limitService.checkWouldGoOverLimit('customIntegrations');
53
53
 
54
54
  if (overLimit) {
55
- logging.info(`Skipped subscribing webhooks to events. The "customIntegrations" plan limit is enabled."`);
55
+ logging.info(`Skipped subscribing webhooks to events. The "customIntegrations" plan limit is enabled.`);
56
56
  return;
57
57
  }
58
58
  }
@@ -144,6 +144,7 @@ module.exports = function apiRoutes() {
144
144
  router.get('/members/:id', mw.authAdminApi, http(api.members.read));
145
145
  router.put('/members/:id', mw.authAdminApi, http(api.members.edit));
146
146
  router.del('/members/:id', mw.authAdminApi, http(api.members.destroy));
147
+ router.del('/members/:id/sessions', mw.authAdminApi, http(api.members.logout));
147
148
 
148
149
  router.post('/members/:id/subscriptions/', mw.authAdminApi, http(api.members.createSubscription));
149
150
  router.put('/members/:id/subscriptions/:subscription_id', mw.authAdminApi, http(api.members.editSubscription));
@@ -4,7 +4,6 @@ const api = require('../../../../api').endpoints;
4
4
  const {http} = require('@tryghost/api-framework');
5
5
  const mw = require('./middleware');
6
6
  const config = require('../../../../../shared/config');
7
- const membersService = require('../../../../../server/services/members');
8
7
 
9
8
  module.exports = function apiRoutes() {
10
9
  const router = express.Router('content api');
@@ -32,7 +31,7 @@ module.exports = function apiRoutes() {
32
31
  router.get('/tags/slug/:slug', mw.authenticatePublic, http(api.tagsPublic.read));
33
32
 
34
33
  // ## Settings
35
- router.get('/settings', mw.authenticatePublic, membersService.middleware.loadMemberSession, http(api.publicSettings.browse));
34
+ router.get('/settings', mw.authenticatePublic, http(api.publicSettings.browse));
36
35
 
37
36
  // ## Members
38
37
  router.get('/newsletters', mw.authenticatePublic, http(api.newslettersPublic.browse));
@@ -51,7 +51,7 @@ module.exports = function setupMembersApp() {
51
51
 
52
52
  // Manage session
53
53
  membersApp.get('/api/session', middleware.getIdentityToken);
54
- membersApp.delete('/api/session', middleware.deleteSession);
54
+ membersApp.delete('/api/session', bodyParser.json({limit: '5mb'}), middleware.deleteSession);
55
55
 
56
56
  // NOTE: this is wrapped in a function to ensure we always go via the getter
57
57
  membersApp.post(
@@ -21,7 +21,9 @@ const GA_FEATURES = [
21
21
  'announcementBar',
22
22
  'signupForm',
23
23
  'recommendations',
24
- 'editorEmojiPicker'
24
+ 'editorEmojiPicker',
25
+ 'listUnsubscribeHeader',
26
+ 'filterEmailDisabled'
25
27
  ];
26
28
 
27
29
  // NOTE: this allowlist is meant to be used to filter out any unexpected
@@ -43,7 +45,7 @@ const ALPHA_FEATURES = [
43
45
  'tipsAndDonations',
44
46
  'importMemberTier',
45
47
  'lexicalIndicators',
46
- 'listUnsubscribeHeader',
48
+ 'editorEmojiPicker',
47
49
  'adminXOffers'
48
50
  ];
49
51