ghost 4.47.4 → 5.0.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 (664) hide show
  1. package/Gruntfile.js +24 -24
  2. package/README.md +3 -2
  3. package/content/themes/casper/assets/built/global.css +1 -1
  4. package/content/themes/casper/assets/built/global.css.map +1 -1
  5. package/content/themes/casper/assets/built/screen.css +1 -1
  6. package/content/themes/casper/assets/built/screen.css.map +1 -1
  7. package/content/themes/casper/assets/css/global.css +2 -2
  8. package/content/themes/casper/assets/css/screen.css +412 -664
  9. package/content/themes/casper/author.hbs +48 -35
  10. package/content/themes/casper/default.hbs +5 -23
  11. package/content/themes/casper/error-404.hbs +1 -1
  12. package/content/themes/casper/index.hbs +29 -22
  13. package/content/themes/casper/package.json +25 -37
  14. package/content/themes/casper/page.hbs +12 -12
  15. package/content/themes/casper/partials/icons/facebook.hbs +1 -1
  16. package/content/themes/casper/partials/icons/twitter.hbs +1 -1
  17. package/content/themes/casper/partials/post-card.hbs +26 -40
  18. package/content/themes/casper/post.hbs +54 -50
  19. package/content/themes/casper/tag.hbs +42 -47
  20. package/core/boot.js +18 -15
  21. package/core/bridge.js +24 -25
  22. package/core/built/assets/ghost-dark-b6e3268bcae976a8675b0d9ae54540f2.css +1 -0
  23. package/core/built/assets/{ghost.min-a2a47979b0b61d15a3914042a7b1cd20.js → ghost.min-2cc3688ea6600a54e0cd83107a8577e8.js} +1138 -1212
  24. package/core/built/assets/ghost.min-a40c7b301c702bd84c2fae19366ab5d7.css +1 -0
  25. package/core/built/assets/icons/analytics.svg +14 -0
  26. package/core/built/assets/icons/calendar.svg +4 -1
  27. package/core/built/assets/icons/email-at.svg +1 -1
  28. package/core/built/assets/icons/email-name.svg +1 -1
  29. package/core/built/assets/icons/info.svg +1 -1
  30. package/core/built/assets/icons/twitter-logo.svg +3 -0
  31. package/core/built/assets/{vendor.min-97fd438f4772c5ec6bb30ad779b8530e.js → vendor.min-2bca41946dea27dc292428db605d466d.js} +99 -93
  32. package/core/cli/README.md +88 -0
  33. package/core/cli/command.js +129 -0
  34. package/core/cli/repl.js +32 -0
  35. package/core/cli/timetravel.js +87 -0
  36. package/core/frontend/apps/amp/lib/helpers/amp_content.js +10 -12
  37. package/core/frontend/apps/amp/lib/router.js +2 -3
  38. package/core/frontend/helpers/body_class.js +2 -2
  39. package/core/frontend/helpers/excerpt.js +0 -2
  40. package/core/frontend/helpers/get.js +23 -24
  41. package/core/frontend/helpers/ghost_head.js +104 -108
  42. package/core/frontend/helpers/navigation.js +0 -2
  43. package/core/frontend/helpers/prev_post.js +20 -26
  44. package/core/frontend/helpers/price.js +2 -2
  45. package/core/frontend/meta/author-url.js +2 -2
  46. package/core/frontend/meta/description.js +3 -3
  47. package/core/frontend/meta/excerpt.js +1 -2
  48. package/core/frontend/meta/generate-excerpt.js +2 -11
  49. package/core/frontend/meta/paginated-url.js +1 -1
  50. package/core/frontend/meta/rss-url.js +0 -1
  51. package/core/frontend/meta/url.js +4 -4
  52. package/core/frontend/services/data/entry-lookup.js +1 -1
  53. package/core/frontend/services/data/fetch-data.js +1 -1
  54. package/core/frontend/services/helpers/handlebars.js +11 -12
  55. package/core/frontend/services/proxy.js +11 -1
  56. package/core/frontend/services/rendering/context.js +1 -5
  57. package/core/frontend/services/rendering/format-response.js +9 -2
  58. package/core/frontend/services/rendering/index.js +0 -4
  59. package/core/frontend/services/rendering/render-entry.js +1 -1
  60. package/core/frontend/services/rendering/templates.js +15 -5
  61. package/core/frontend/services/routing/CollectionRouter.js +2 -2
  62. package/core/frontend/services/routing/EmailRouter.js +2 -2
  63. package/core/frontend/services/routing/ParentRouter.js +1 -1
  64. package/core/frontend/services/routing/PreviewRouter.js +3 -3
  65. package/core/frontend/services/routing/{config/v4.js → config.js} +3 -5
  66. package/core/frontend/services/routing/controllers/channel.js +0 -10
  67. package/core/frontend/services/routing/controllers/collection.js +0 -9
  68. package/core/frontend/services/routing/controllers/email-post.js +2 -7
  69. package/core/frontend/services/routing/controllers/entry.js +1 -3
  70. package/core/frontend/services/routing/controllers/index.js +2 -2
  71. package/core/frontend/services/routing/controllers/{preview.js → previews.js} +3 -8
  72. package/core/frontend/services/routing/controllers/static.js +1 -6
  73. package/core/frontend/services/routing/router-manager.js +38 -20
  74. package/core/frontend/services/rss/generate-feed.js +7 -9
  75. package/core/frontend/services/theme-engine/active.js +0 -8
  76. package/core/frontend/services/theme-engine/config/defaults.json +1 -3
  77. package/core/frontend/services/theme-engine/middleware/index.js +0 -1
  78. package/core/frontend/services/theme-engine/middleware/update-global-template-options.js +0 -69
  79. package/core/frontend/services/theme-engine/middleware/update-local-template-options.js +3 -6
  80. package/core/frontend/web/middleware/static-theme.js +14 -6
  81. package/core/frontend/web/routes.js +9 -9
  82. package/core/frontend/web/site.js +15 -18
  83. package/core/server/adapters/scheduling/post-scheduling/index.js +1 -1
  84. package/core/server/api/README.md +2 -6
  85. package/core/server/api/canary/authentication.js +4 -3
  86. package/core/server/api/canary/{email-preview.js → email-previews.js} +9 -8
  87. package/core/server/api/canary/index.js +14 -18
  88. package/core/server/api/canary/members.js +4 -24
  89. package/core/server/api/{v3/actions.js → canary/newsletters-public.js} +6 -6
  90. package/core/server/api/canary/newsletters.js +1 -13
  91. package/core/server/api/canary/notifications.js +17 -22
  92. package/core/server/api/canary/offers-public.js +28 -0
  93. package/core/server/api/canary/pages.js +1 -1
  94. package/core/server/api/canary/posts.js +4 -8
  95. package/core/server/api/canary/{preview.js → previews.js} +1 -1
  96. package/core/server/api/canary/schedules.js +1 -1
  97. package/core/server/api/canary/session.js +1 -1
  98. package/core/server/api/canary/settings-public.js +3 -1
  99. package/core/server/api/canary/settings.js +30 -16
  100. package/core/server/api/canary/utils/index.js +2 -4
  101. package/core/server/api/canary/utils/serializers/input/index.js +0 -4
  102. package/core/server/api/canary/utils/serializers/input/members.js +46 -17
  103. package/core/server/api/canary/utils/serializers/input/pages.js +0 -17
  104. package/core/server/api/canary/utils/serializers/input/posts.js +1 -28
  105. package/core/server/api/canary/utils/serializers/input/settings.js +61 -142
  106. package/core/server/api/canary/utils/serializers/input/tiers.js +56 -12
  107. package/core/server/api/canary/utils/serializers/output/authentication.js +2 -6
  108. package/core/server/api/canary/utils/serializers/output/index.js +2 -10
  109. package/core/server/api/canary/utils/serializers/output/mappers/index.js +1 -0
  110. package/core/server/api/canary/utils/serializers/output/mappers/newsletters.js +24 -0
  111. package/core/server/api/canary/utils/serializers/output/mappers/pages.js +1 -1
  112. package/core/server/api/canary/utils/serializers/output/mappers/posts.js +9 -7
  113. package/core/server/api/canary/utils/serializers/output/mappers/settings.js +5 -31
  114. package/core/server/api/canary/utils/serializers/output/members.js +21 -11
  115. package/core/server/api/canary/utils/serializers/output/offers.js +9 -1
  116. package/core/server/api/canary/utils/serializers/output/{preview.js → previews.js} +2 -2
  117. package/core/server/api/canary/utils/serializers/output/settings.js +6 -14
  118. package/core/server/api/canary/utils/serializers/output/site.js +0 -1
  119. package/core/server/api/canary/utils/serializers/output/tiers.js +35 -75
  120. package/core/server/api/canary/utils/serializers/output/utils/clean.js +5 -10
  121. package/core/server/api/canary/utils/serializers/output/utils/extra-attrs.js +0 -126
  122. package/core/server/api/canary/utils/serializers/output/utils/post-gating.js +1 -1
  123. package/core/server/api/canary/utils/serializers/output/utils/url.js +0 -5
  124. package/core/server/api/canary/utils/validators/input/index.js +2 -2
  125. package/core/server/api/canary/utils/validators/input/{passwordreset.js → password_reset.js} +2 -2
  126. package/core/server/api/canary/utils/validators/input/settings.js +2 -23
  127. package/core/server/api/canary/utils/validators/utils/json-schema.js +1 -2
  128. package/core/server/api/index.js +1 -7
  129. package/core/server/api/shared/serializers/input/utils/settings-key-group-mapper.js +2 -2
  130. package/core/server/api/shared/serializers/input/utils/settings-key-type-mapper.js +2 -4
  131. package/core/server/data/db/connection.js +0 -13
  132. package/core/server/data/exporter/index.js +4 -1
  133. package/core/server/data/exporter/table-lists.js +13 -15
  134. package/core/server/data/importer/importers/data/base.js +16 -7
  135. package/core/server/data/importer/importers/data/data-importer.js +38 -1
  136. package/core/server/data/importer/importers/data/newsletters.js +45 -0
  137. package/core/server/data/importer/importers/data/posts.js +40 -12
  138. package/core/server/data/importer/importers/data/products.js +68 -0
  139. package/core/server/data/importer/importers/data/settings.js +10 -10
  140. package/core/server/data/importer/importers/data/stripe-prices.js +59 -0
  141. package/core/server/data/importer/importers/data/stripe-products.js +61 -0
  142. package/core/server/data/migrations/utils/constants.js +3 -0
  143. package/core/server/data/migrations/utils/index.js +10 -0
  144. package/core/server/data/migrations/utils/migrations.js +156 -0
  145. package/core/server/data/migrations/utils/permissions.js +291 -0
  146. package/core/server/data/migrations/utils/schema.js +158 -0
  147. package/core/server/data/migrations/utils/settings.js +59 -0
  148. package/core/server/data/migrations/utils/tables.js +94 -0
  149. package/core/server/data/migrations/versions/1.25/01-final-v1.js +2 -0
  150. package/core/server/data/migrations/versions/1.25/02-noop.js +6 -0
  151. package/core/server/data/migrations/versions/2.37/01-final-v2.js +2 -0
  152. package/core/server/data/migrations/versions/3.41/01-final-v3.js +2 -0
  153. package/core/server/data/migrations/versions/4.0/22-solve-orphaned-webhooks.js +3 -9
  154. package/core/server/data/migrations/versions/4.0/23-regenerate-posts-html.js +2 -11
  155. package/core/server/data/migrations/versions/4.11/02-add-email-verification-required-setting.js +1 -1
  156. package/core/server/data/migrations/versions/4.12/02-fix-member-statuses.js +1 -1
  157. package/core/server/data/migrations/versions/4.14/02-fix-free-members-status-events.js +1 -1
  158. package/core/server/data/migrations/versions/4.22/01-add-is-launch-complete-setting.js +1 -1
  159. package/core/server/data/migrations/versions/4.22/02-update-launch-complete-setting-from-user-data.js +1 -1
  160. package/core/server/data/migrations/versions/4.35/2022-02-02-10-38-add-default-content-visibility-tiers-setting.js +1 -1
  161. package/core/server/data/migrations/versions/4.45/2022-04-21-02-55-add-notifications-key-entry-to-settings-table.js +1 -1
  162. package/core/server/data/migrations/versions/4.6/01-remove-comped-status.js +1 -1
  163. package/core/server/data/migrations/versions/4.7/03-add-labs-setting.js +1 -1
  164. package/core/server/data/migrations/versions/4.9/05-fix-missed-mobiledoc-url-transforms.js +1 -1
  165. package/core/server/data/migrations/versions/4.9/06-add-comped-status.js +1 -1
  166. package/core/server/data/migrations/versions/4.9/07-update-comped-members-status-events.js +1 -1
  167. package/core/server/data/migrations/versions/5.0/2022-03-14-12-33-delete-duplicate-offer-redemptions.js +36 -0
  168. package/core/server/data/migrations/versions/5.0/2022-03-28-15-25-backfill-mrr-adjustments-for-offers.js +108 -0
  169. package/core/server/data/migrations/versions/5.0/2022-04-25-10-32-backfill-mrr-for-discounted-subscriptions.js +44 -0
  170. package/core/server/data/migrations/versions/5.0/2022-04-26-15-44-backfill-mrr-events-for-canceled-subscriptions.js +73 -0
  171. package/core/server/data/migrations/versions/5.0/2022-04-27-11-26-backfill-mrr-for-canceled-subscriptions.js +31 -0
  172. package/core/server/data/migrations/versions/5.0/2022-04-28-03-26-remove-author-id-column-from-posts-table.js +7 -0
  173. package/core/server/data/migrations/versions/5.0/2022-05-03-09-39-drop-nullable-subscribe-event-newsletter-id.js +4 -0
  174. package/core/server/data/migrations/versions/5.0/2022-05-04-15-24-map-existing-emails-to-default-newsletter.js +44 -0
  175. package/core/server/data/migrations/versions/5.0/2022-05-05-13-13-migrate-legacy-recipient-filters.js +30 -0
  176. package/core/server/data/migrations/versions/5.0/2022-05-05-13-29-add-newsletters-admin-integration-permission-roles.js +20 -0
  177. package/core/server/data/migrations/versions/5.0/2022-05-05-15-17-drop-oauth-table.js +3 -0
  178. package/core/server/data/migrations/versions/5.0/2022-05-06-08-16-cleanup-client-subscriber-permissions.js +68 -0
  179. package/core/server/data/migrations/versions/5.0/2022-05-06-13-22-add-frontend-integration.js +68 -0
  180. package/core/server/data/migrations/versions/5.0/2022-05-09-10-00-drop-members-subscribed-column.js +18 -0
  181. package/core/server/data/migrations/versions/5.0/2022-05-09-14-17-cleanup-invalid-users-status.js +17 -0
  182. package/core/server/data/migrations/versions/5.0/2022-05-10-08-33-drop-members-analytics-table.js +3 -0
  183. package/core/server/data/migrations/versions/5.0/2022-05-10-14-57-cleanup-invalid-posts-status.js +17 -0
  184. package/core/server/data/migrations/versions/5.0/2022-05-11-12-08-drop-webhooks-status-column.js +18 -0
  185. package/core/server/data/migrations/versions/5.0/2022-05-11-13-12-rename-settings.js +51 -0
  186. package/core/server/data/migrations/versions/5.0/2022-05-11-16-36-remove-unused-settings.js +54 -0
  187. package/core/server/data/migrations/versions/5.0/2022-05-12-10-29-add-newsletter-permissions-for-editors-and-authors.js +20 -0
  188. package/core/server/data/migrations/versions/5.0/2022-05-12-13-51-add-label-permissions-for-authors.js +12 -0
  189. package/core/server/data/migrations/versions/5.0/2022-05-13-11-38-drop-none-email-recipient-filter.js +28 -0
  190. package/core/server/data/migrations/versions/5.0/2022-05-21-00-00-regenerate-posts-html.js +70 -0
  191. package/core/server/data/schema/commands.js +35 -3
  192. package/core/server/data/schema/default-settings/default-settings.json +2 -159
  193. package/core/server/data/schema/fixtures/fixture-manager.js +11 -2
  194. package/core/server/data/schema/fixtures/fixtures.json +16 -7
  195. package/core/server/data/schema/schema.js +26 -38
  196. package/core/server/data/schema/validator.js +2 -0
  197. package/core/server/ghost-server.js +34 -64
  198. package/core/server/lib/image/gravatar.js +25 -9
  199. package/core/server/models/api-key.js +3 -26
  200. package/core/server/models/base/plugins/bulk-operations.js +14 -6
  201. package/core/server/models/integration.js +17 -0
  202. package/core/server/models/member.js +8 -4
  203. package/core/server/models/newsletter.js +27 -0
  204. package/core/server/models/post.js +30 -32
  205. package/core/server/models/relations/authors.js +74 -100
  206. package/core/server/models/settings.js +6 -2
  207. package/core/server/models/webhook.js +2 -1
  208. package/core/server/run-update-check.js +1 -1
  209. package/core/server/services/api-version-compatibility/index.js +24 -18
  210. package/core/server/services/api-version-compatibility/legacy-api-path-match.js +23 -0
  211. package/core/server/services/api-version-compatibility/mw-version-rewrites.js +36 -0
  212. package/core/server/services/auth/api-key/admin.js +8 -7
  213. package/core/server/services/auth/passwordreset.js +3 -3
  214. package/core/server/services/auth/session/express-session.js +1 -1
  215. package/core/server/services/auth/session/index.js +1 -1
  216. package/core/server/services/auth/setup.js +8 -8
  217. package/core/server/services/bulk-email/bulk-email-processor.js +5 -1
  218. package/core/server/services/email-analytics/lib/event-processor.js +25 -14
  219. package/core/server/services/frontend-data-service/frontend-data-service.js +27 -0
  220. package/core/server/services/frontend-data-service/index.js +6 -0
  221. package/core/server/services/mail/index.js +14 -1
  222. package/core/server/services/mega/email-preview.js +14 -15
  223. package/core/server/services/mega/mega.js +37 -52
  224. package/core/server/services/mega/post-email-serializer.js +18 -28
  225. package/core/server/services/members/api.js +0 -3
  226. package/core/server/services/members/config.js +0 -49
  227. package/core/server/services/members/exporter/query.js +88 -0
  228. package/core/server/services/members/middleware.js +3 -135
  229. package/core/server/services/members/service.js +2 -29
  230. package/core/server/services/members/settings.js +3 -9
  231. package/core/server/services/newsletters/service.js +78 -10
  232. package/core/server/services/posts/post-scheduling-service.js +5 -17
  233. package/core/server/services/posts/posts-service.js +15 -62
  234. package/core/server/services/public-config/site.js +0 -6
  235. package/core/server/services/route-settings/index.js +0 -3
  236. package/core/server/services/route-settings/settings-loader.js +10 -34
  237. package/core/server/services/route-settings/validate.js +1 -7
  238. package/core/server/services/settings/index.js +1 -77
  239. package/core/server/services/settings/settings-service.js +184 -0
  240. package/core/server/services/themes/validate.js +1 -1
  241. package/core/server/services/url/Resources.js +1 -3
  242. package/core/server/services/url/UrlGenerator.js +1 -1
  243. package/core/server/services/url/UrlService.js +6 -20
  244. package/core/server/services/url/{configs/v2.js → config.js} +0 -0
  245. package/core/server/services/users.js +2 -2
  246. package/core/server/services/webhooks/listen.js +5 -2
  247. package/core/server/services/webhooks/serialize.js +6 -7
  248. package/core/server/services/webhooks/trigger.js +62 -47
  249. package/core/server/update-check.js +1 -1
  250. package/core/server/web/admin/app.js +1 -1
  251. package/core/server/web/admin/views/default-prod.html +4 -4
  252. package/core/server/web/admin/views/default.html +4 -4
  253. package/core/server/web/api/app.js +3 -15
  254. package/core/server/web/api/canary/admin/app.js +1 -1
  255. package/core/server/web/api/canary/admin/middleware.js +3 -1
  256. package/core/server/web/api/canary/admin/routes.js +7 -23
  257. package/core/server/web/api/canary/content/app.js +2 -3
  258. package/core/server/web/api/canary/content/routes.js +5 -4
  259. package/core/server/web/members/app.js +5 -4
  260. package/core/server/web/parent/backend.js +0 -1
  261. package/core/server/web/parent/frontend.js +5 -6
  262. package/core/server/web/parent/middleware/ghost-locals.js +0 -3
  263. package/core/server/web/well-known.js +14 -1
  264. package/core/shared/config/defaults.json +5 -2
  265. package/core/shared/config/overrides.json +1 -27
  266. package/core/shared/html-to-plaintext.js +78 -10
  267. package/core/shared/labs.js +4 -8
  268. package/core/shared/settings-cache/cache.js +38 -4
  269. package/core/shared/settings-cache/public.js +13 -7
  270. package/core/shared/url-utils.js +0 -2
  271. package/ghost.js +6 -0
  272. package/package.json +66 -64
  273. package/yarn.lock +765 -1300
  274. package/core/built/assets/ghost-dark-c94ae212747200ca4bafc37cfb0714d8.css +0 -1
  275. package/core/built/assets/ghost.min-4084931bc22e794fe3722139050a80b3.css +0 -1
  276. package/core/frontend/helpers/author.js +0 -41
  277. package/core/frontend/helpers/products.js +0 -65
  278. package/core/frontend/services/rendering/secure.js +0 -19
  279. package/core/frontend/services/routing/config/canary.js +0 -61
  280. package/core/frontend/services/routing/config/v2.js +0 -54
  281. package/core/frontend/services/routing/config/v3.js +0 -54
  282. package/core/frontend/services/theme-engine/engines/create.js +0 -45
  283. package/core/frontend/services/theme-engine/engines/index.js +0 -5
  284. package/core/frontend/services/theme-engine/middleware/update-local-template-data.js +0 -9
  285. package/core/server/api/canary/products-public.js +0 -34
  286. package/core/server/api/canary/products.js +0 -116
  287. package/core/server/api/canary/utils/serializers/input/products.js +0 -28
  288. package/core/server/api/canary/utils/serializers/output/email-previews.js +0 -7
  289. package/core/server/api/canary/utils/serializers/output/products.js +0 -213
  290. package/core/server/api/v2/actions.js +0 -38
  291. package/core/server/api/v2/authentication.js +0 -191
  292. package/core/server/api/v2/authors-public.js +0 -69
  293. package/core/server/api/v2/config.js +0 -12
  294. package/core/server/api/v2/db.js +0 -120
  295. package/core/server/api/v2/images.js +0 -20
  296. package/core/server/api/v2/index.js +0 -147
  297. package/core/server/api/v2/integrations.js +0 -144
  298. package/core/server/api/v2/invites.js +0 -126
  299. package/core/server/api/v2/mail.js +0 -66
  300. package/core/server/api/v2/notifications.js +0 -96
  301. package/core/server/api/v2/oembed.js +0 -186
  302. package/core/server/api/v2/pages-public.js +0 -78
  303. package/core/server/api/v2/pages.js +0 -197
  304. package/core/server/api/v2/posts-public.js +0 -78
  305. package/core/server/api/v2/posts.js +0 -192
  306. package/core/server/api/v2/preview.js +0 -46
  307. package/core/server/api/v2/redirects.js +0 -28
  308. package/core/server/api/v2/roles.js +0 -19
  309. package/core/server/api/v2/schedules.js +0 -77
  310. package/core/server/api/v2/session.js +0 -70
  311. package/core/server/api/v2/settings-public.js +0 -17
  312. package/core/server/api/v2/settings.js +0 -195
  313. package/core/server/api/v2/site.js +0 -14
  314. package/core/server/api/v2/slack.js +0 -12
  315. package/core/server/api/v2/slugs.js +0 -51
  316. package/core/server/api/v2/tags-public.js +0 -71
  317. package/core/server/api/v2/tags.js +0 -159
  318. package/core/server/api/v2/themes.js +0 -133
  319. package/core/server/api/v2/users.js +0 -179
  320. package/core/server/api/v2/utils/index.js +0 -34
  321. package/core/server/api/v2/utils/permissions.js +0 -112
  322. package/core/server/api/v2/utils/serializers/index.js +0 -9
  323. package/core/server/api/v2/utils/serializers/input/db.js +0 -20
  324. package/core/server/api/v2/utils/serializers/input/index.js +0 -33
  325. package/core/server/api/v2/utils/serializers/input/integrations.js +0 -33
  326. package/core/server/api/v2/utils/serializers/input/pages.js +0 -203
  327. package/core/server/api/v2/utils/serializers/input/posts.js +0 -218
  328. package/core/server/api/v2/utils/serializers/input/settings.js +0 -152
  329. package/core/server/api/v2/utils/serializers/input/tags.js +0 -35
  330. package/core/server/api/v2/utils/serializers/input/users.js +0 -26
  331. package/core/server/api/v2/utils/serializers/input/utils/url.js +0 -71
  332. package/core/server/api/v2/utils/serializers/input/webhooks.js +0 -12
  333. package/core/server/api/v2/utils/serializers/output/actions.js +0 -13
  334. package/core/server/api/v2/utils/serializers/output/all.js +0 -25
  335. package/core/server/api/v2/utils/serializers/output/authentication.js +0 -68
  336. package/core/server/api/v2/utils/serializers/output/authors.js +0 -21
  337. package/core/server/api/v2/utils/serializers/output/config.js +0 -21
  338. package/core/server/api/v2/utils/serializers/output/db.js +0 -40
  339. package/core/server/api/v2/utils/serializers/output/images.js +0 -19
  340. package/core/server/api/v2/utils/serializers/output/index.js +0 -107
  341. package/core/server/api/v2/utils/serializers/output/integrations.js +0 -35
  342. package/core/server/api/v2/utils/serializers/output/invites.js +0 -24
  343. package/core/server/api/v2/utils/serializers/output/mail.js +0 -19
  344. package/core/server/api/v2/utils/serializers/output/notifications.js +0 -29
  345. package/core/server/api/v2/utils/serializers/output/oembed.js +0 -8
  346. package/core/server/api/v2/utils/serializers/output/pages.js +0 -26
  347. package/core/server/api/v2/utils/serializers/output/posts.js +0 -26
  348. package/core/server/api/v2/utils/serializers/output/preview.js +0 -9
  349. package/core/server/api/v2/utils/serializers/output/redirects.js +0 -5
  350. package/core/server/api/v2/utils/serializers/output/roles.js +0 -29
  351. package/core/server/api/v2/utils/serializers/output/schedules.js +0 -5
  352. package/core/server/api/v2/utils/serializers/output/settings.js +0 -61
  353. package/core/server/api/v2/utils/serializers/output/site.js +0 -16
  354. package/core/server/api/v2/utils/serializers/output/slugs.js +0 -11
  355. package/core/server/api/v2/utils/serializers/output/tags.js +0 -25
  356. package/core/server/api/v2/utils/serializers/output/themes.js +0 -25
  357. package/core/server/api/v2/utils/serializers/output/users.js +0 -45
  358. package/core/server/api/v2/utils/serializers/output/utils/clean.js +0 -174
  359. package/core/server/api/v2/utils/serializers/output/utils/date.js +0 -21
  360. package/core/server/api/v2/utils/serializers/output/utils/extra-attrs.js +0 -161
  361. package/core/server/api/v2/utils/serializers/output/utils/mapper.js +0 -136
  362. package/core/server/api/v2/utils/serializers/output/utils/post-gating.js +0 -29
  363. package/core/server/api/v2/utils/serializers/output/utils/settings-type-group-mapper.js +0 -24
  364. package/core/server/api/v2/utils/serializers/output/utils/url.js +0 -67
  365. package/core/server/api/v2/utils/serializers/output/webhooks.js +0 -15
  366. package/core/server/api/v2/utils/validators/index.js +0 -9
  367. package/core/server/api/v2/utils/validators/input/images.js +0 -85
  368. package/core/server/api/v2/utils/validators/input/index.js +0 -45
  369. package/core/server/api/v2/utils/validators/input/invitations.js +0 -49
  370. package/core/server/api/v2/utils/validators/input/invites.js +0 -21
  371. package/core/server/api/v2/utils/validators/input/oembed.js +0 -17
  372. package/core/server/api/v2/utils/validators/input/pages.js +0 -46
  373. package/core/server/api/v2/utils/validators/input/passwordreset.js +0 -36
  374. package/core/server/api/v2/utils/validators/input/posts.js +0 -46
  375. package/core/server/api/v2/utils/validators/input/settings.js +0 -79
  376. package/core/server/api/v2/utils/validators/input/setup.js +0 -17
  377. package/core/server/api/v2/utils/validators/input/tags.js +0 -6
  378. package/core/server/api/v2/utils/validators/input/users.js +0 -21
  379. package/core/server/api/v2/utils/validators/output/index.js +0 -1
  380. package/core/server/api/v2/utils/validators/utils/json-schema.js +0 -17
  381. package/core/server/api/v2/webhooks.js +0 -163
  382. package/core/server/api/v3/authentication.js +0 -192
  383. package/core/server/api/v3/authors-public.js +0 -69
  384. package/core/server/api/v3/config.js +0 -12
  385. package/core/server/api/v3/db.js +0 -131
  386. package/core/server/api/v3/email-preview.js +0 -74
  387. package/core/server/api/v3/email.js +0 -65
  388. package/core/server/api/v3/identities.js +0 -36
  389. package/core/server/api/v3/images.js +0 -20
  390. package/core/server/api/v3/index.js +0 -179
  391. package/core/server/api/v3/integrations.js +0 -150
  392. package/core/server/api/v3/invites.js +0 -125
  393. package/core/server/api/v3/labels.js +0 -162
  394. package/core/server/api/v3/mail.js +0 -66
  395. package/core/server/api/v3/memberSigninUrls.js +0 -33
  396. package/core/server/api/v3/members.js +0 -412
  397. package/core/server/api/v3/membersStripeConnect.js +0 -29
  398. package/core/server/api/v3/notifications.js +0 -96
  399. package/core/server/api/v3/oembed.js +0 -23
  400. package/core/server/api/v3/pages-public.js +0 -77
  401. package/core/server/api/v3/pages.js +0 -199
  402. package/core/server/api/v3/posts-public.js +0 -76
  403. package/core/server/api/v3/posts.js +0 -200
  404. package/core/server/api/v3/preview.js +0 -44
  405. package/core/server/api/v3/redirects.js +0 -47
  406. package/core/server/api/v3/roles.js +0 -19
  407. package/core/server/api/v3/schedules.js +0 -77
  408. package/core/server/api/v3/session.js +0 -70
  409. package/core/server/api/v3/settings-public.js +0 -17
  410. package/core/server/api/v3/settings.js +0 -224
  411. package/core/server/api/v3/site.js +0 -14
  412. package/core/server/api/v3/slack.js +0 -12
  413. package/core/server/api/v3/slugs.js +0 -48
  414. package/core/server/api/v3/snippets.js +0 -115
  415. package/core/server/api/v3/tags-public.js +0 -71
  416. package/core/server/api/v3/tags.js +0 -159
  417. package/core/server/api/v3/themes.js +0 -131
  418. package/core/server/api/v3/users.js +0 -242
  419. package/core/server/api/v3/utils/index.js +0 -34
  420. package/core/server/api/v3/utils/permissions.js +0 -116
  421. package/core/server/api/v3/utils/serializers/index.js +0 -9
  422. package/core/server/api/v3/utils/serializers/input/authors.js +0 -31
  423. package/core/server/api/v3/utils/serializers/input/db.js +0 -20
  424. package/core/server/api/v3/utils/serializers/input/index.js +0 -41
  425. package/core/server/api/v3/utils/serializers/input/integrations.js +0 -33
  426. package/core/server/api/v3/utils/serializers/input/members.js +0 -62
  427. package/core/server/api/v3/utils/serializers/input/pages.js +0 -208
  428. package/core/server/api/v3/utils/serializers/input/posts.js +0 -242
  429. package/core/server/api/v3/utils/serializers/input/settings.js +0 -168
  430. package/core/server/api/v3/utils/serializers/input/tags.js +0 -42
  431. package/core/server/api/v3/utils/serializers/input/users.js +0 -26
  432. package/core/server/api/v3/utils/serializers/input/utils/slug-filter-order.js +0 -18
  433. package/core/server/api/v3/utils/serializers/input/utils/url.js +0 -71
  434. package/core/server/api/v3/utils/serializers/input/webhooks.js +0 -12
  435. package/core/server/api/v3/utils/serializers/output/actions.js +0 -13
  436. package/core/server/api/v3/utils/serializers/output/all.js +0 -25
  437. package/core/server/api/v3/utils/serializers/output/authentication.js +0 -69
  438. package/core/server/api/v3/utils/serializers/output/authors.js +0 -21
  439. package/core/server/api/v3/utils/serializers/output/config.js +0 -25
  440. package/core/server/api/v3/utils/serializers/output/db.js +0 -40
  441. package/core/server/api/v3/utils/serializers/output/email-preview.js +0 -7
  442. package/core/server/api/v3/utils/serializers/output/emails.js +0 -13
  443. package/core/server/api/v3/utils/serializers/output/identities.js +0 -7
  444. package/core/server/api/v3/utils/serializers/output/images.js +0 -19
  445. package/core/server/api/v3/utils/serializers/output/index.js +0 -135
  446. package/core/server/api/v3/utils/serializers/output/integrations.js +0 -35
  447. package/core/server/api/v3/utils/serializers/output/invites.js +0 -24
  448. package/core/server/api/v3/utils/serializers/output/labels.js +0 -25
  449. package/core/server/api/v3/utils/serializers/output/mail.js +0 -19
  450. package/core/server/api/v3/utils/serializers/output/member-signin_urls.js +0 -7
  451. package/core/server/api/v3/utils/serializers/output/members.js +0 -228
  452. package/core/server/api/v3/utils/serializers/output/notifications.js +0 -29
  453. package/core/server/api/v3/utils/serializers/output/oembed.js +0 -8
  454. package/core/server/api/v3/utils/serializers/output/pages.js +0 -26
  455. package/core/server/api/v3/utils/serializers/output/posts.js +0 -26
  456. package/core/server/api/v3/utils/serializers/output/preview.js +0 -10
  457. package/core/server/api/v3/utils/serializers/output/redirects.js +0 -5
  458. package/core/server/api/v3/utils/serializers/output/roles.js +0 -29
  459. package/core/server/api/v3/utils/serializers/output/schedules.js +0 -5
  460. package/core/server/api/v3/utils/serializers/output/settings.js +0 -65
  461. package/core/server/api/v3/utils/serializers/output/site.js +0 -19
  462. package/core/server/api/v3/utils/serializers/output/slugs.js +0 -11
  463. package/core/server/api/v3/utils/serializers/output/snippets.js +0 -97
  464. package/core/server/api/v3/utils/serializers/output/tags.js +0 -25
  465. package/core/server/api/v3/utils/serializers/output/themes.js +0 -25
  466. package/core/server/api/v3/utils/serializers/output/users.js +0 -74
  467. package/core/server/api/v3/utils/serializers/output/utils/clean.js +0 -166
  468. package/core/server/api/v3/utils/serializers/output/utils/date.js +0 -21
  469. package/core/server/api/v3/utils/serializers/output/utils/extra-attrs.js +0 -174
  470. package/core/server/api/v3/utils/serializers/output/utils/mapper.js +0 -197
  471. package/core/server/api/v3/utils/serializers/output/utils/post-gating.js +0 -39
  472. package/core/server/api/v3/utils/serializers/output/utils/settings-type-group-mapper.js +0 -24
  473. package/core/server/api/v3/utils/serializers/output/utils/url.js +0 -67
  474. package/core/server/api/v3/utils/serializers/output/webhooks.js +0 -15
  475. package/core/server/api/v3/utils/validators/index.js +0 -9
  476. package/core/server/api/v3/utils/validators/input/images.js +0 -85
  477. package/core/server/api/v3/utils/validators/input/index.js +0 -61
  478. package/core/server/api/v3/utils/validators/input/invitations.js +0 -49
  479. package/core/server/api/v3/utils/validators/input/invites.js +0 -21
  480. package/core/server/api/v3/utils/validators/input/labels.js +0 -6
  481. package/core/server/api/v3/utils/validators/input/members.js +0 -6
  482. package/core/server/api/v3/utils/validators/input/oembed.js +0 -17
  483. package/core/server/api/v3/utils/validators/input/pages.js +0 -46
  484. package/core/server/api/v3/utils/validators/input/passwordreset.js +0 -36
  485. package/core/server/api/v3/utils/validators/input/posts.js +0 -46
  486. package/core/server/api/v3/utils/validators/input/settings.js +0 -89
  487. package/core/server/api/v3/utils/validators/input/setup.js +0 -17
  488. package/core/server/api/v3/utils/validators/input/snippets.js +0 -6
  489. package/core/server/api/v3/utils/validators/input/tags.js +0 -6
  490. package/core/server/api/v3/utils/validators/input/users.js +0 -22
  491. package/core/server/api/v3/utils/validators/input/webhooks.js +0 -27
  492. package/core/server/api/v3/utils/validators/output/index.js +0 -1
  493. package/core/server/api/v3/utils/validators/utils/json-schema.js +0 -17
  494. package/core/server/api/v3/webhooks.js +0 -130
  495. package/core/server/data/migrations/utils.js +0 -571
  496. package/core/server/data/migrations/versions/1.13/1-custom-template-post.js +0 -7
  497. package/core/server/data/migrations/versions/1.13/2-theme-permissions.js +0 -58
  498. package/core/server/data/migrations/versions/1.18/1-add-webhooks-table.js +0 -2
  499. package/core/server/data/migrations/versions/1.19/1-webhook-permissions.js +0 -31
  500. package/core/server/data/migrations/versions/1.20/1-remove-settings-keys.js +0 -65
  501. package/core/server/data/migrations/versions/1.21/1-add-contributor-role.js +0 -58
  502. package/core/server/data/migrations/versions/1.22/1-multiple-authors-DDL.js +0 -2
  503. package/core/server/data/migrations/versions/1.22/1-multiple-authors-DML.js +0 -63
  504. package/core/server/data/migrations/versions/1.25/1-update-koenig-beta-html.js +0 -70
  505. package/core/server/data/migrations/versions/1.25/2-demo-post.js +0 -55
  506. package/core/server/data/migrations/versions/1.3/1-post-excerpt.js +0 -7
  507. package/core/server/data/migrations/versions/1.4/1-codeinjection-post.js +0 -14
  508. package/core/server/data/migrations/versions/1.5/1-og-twitter-post.js +0 -34
  509. package/core/server/data/migrations/versions/1.7/1-add-backup-client.js +0 -10
  510. package/core/server/data/migrations/versions/1.9/1-add-permissions-redirect.js +0 -23
  511. package/core/server/data/migrations/versions/2.0/1-rename-amp-column.js +0 -44
  512. package/core/server/data/migrations/versions/2.0/2-update-posts.js +0 -7
  513. package/core/server/data/migrations/versions/2.0/3-remove-koenig-labs.js +0 -42
  514. package/core/server/data/migrations/versions/2.0/4-permalink-setting.js +0 -85
  515. package/core/server/data/migrations/versions/2.0/5-remove-demo-post.js +0 -85
  516. package/core/server/data/migrations/versions/2.0/6-replace-fixture-posts.js +0 -10
  517. package/core/server/data/migrations/versions/2.13/1-remove-empty-strings.js +0 -5
  518. package/core/server/data/migrations/versions/2.14/1-add-actions-table.js +0 -2
  519. package/core/server/data/migrations/versions/2.14/2-add-actions-permissions.js +0 -12
  520. package/core/server/data/migrations/versions/2.15/1-add-type-column-to-integrations.js +0 -8
  521. package/core/server/data/migrations/versions/2.15/2-insert-zapier-integration.js +0 -69
  522. package/core/server/data/migrations/versions/2.16/1-add-members-perrmissions.js +0 -1
  523. package/core/server/data/migrations/versions/2.17/1-normalize-settings.js +0 -74
  524. package/core/server/data/migrations/versions/2.17/2-posts-add-canonical-url.js +0 -7
  525. package/core/server/data/migrations/versions/2.18/1-restore-settings-from-backup.js +0 -134
  526. package/core/server/data/migrations/versions/2.2/1-add-sessions-table.js +0 -2
  527. package/core/server/data/migrations/versions/2.2/2-add-integrations-and-api-key-tables.js +0 -6
  528. package/core/server/data/migrations/versions/2.2/3-insert-admin-integration-role.js +0 -83
  529. package/core/server/data/migrations/versions/2.2/4-insert-integration-and-api-key-permissions.js +0 -77
  530. package/core/server/data/migrations/versions/2.2/5-add-mobiledoc-revisions-table.js +0 -2
  531. package/core/server/data/migrations/versions/2.21/1-update-editor-permissions.js +0 -28
  532. package/core/server/data/migrations/versions/2.22/1-add-member-permissions-to-roles.js +0 -47
  533. package/core/server/data/migrations/versions/2.27/1-insert-ghost-db-backup-role.js +0 -83
  534. package/core/server/data/migrations/versions/2.27/2-insert-db-backup-integration.js +0 -69
  535. package/core/server/data/migrations/versions/2.27/3-add-subdirectory-to-relative-canonical-urls.js +0 -100
  536. package/core/server/data/migrations/versions/2.28/1-add-db-backup-content-permission.js +0 -9
  537. package/core/server/data/migrations/versions/2.28/2-add-db-backup-content-permission-to-roles.js +0 -15
  538. package/core/server/data/migrations/versions/2.28/3-insert-ghost-scheduler-role.js +0 -84
  539. package/core/server/data/migrations/versions/2.28/4-insert-scheduler-integration.js +0 -69
  540. package/core/server/data/migrations/versions/2.28/5-add-scheduler-permission-to-roles.js +0 -23
  541. package/core/server/data/migrations/versions/2.28/6-add-type-column.js +0 -6
  542. package/core/server/data/migrations/versions/2.28/7-populate-type-column.js +0 -6
  543. package/core/server/data/migrations/versions/2.28/8-remove-page-column.js +0 -6
  544. package/core/server/data/migrations/versions/2.29/1-add-post-page-column.js +0 -20
  545. package/core/server/data/migrations/versions/2.29/2-populate-post-page-column.js +0 -98
  546. package/core/server/data/migrations/versions/2.29/3-remove-page-type-column.js +0 -15
  547. package/core/server/data/migrations/versions/2.3/1-add-webhook-columns.js +0 -45
  548. package/core/server/data/migrations/versions/2.3/2-add-webhook-edit-permission.js +0 -9
  549. package/core/server/data/migrations/versions/2.31/1-remove-name-and-password-from-members-table.js +0 -15
  550. package/core/server/data/migrations/versions/2.32/01-add-members-stripe-customers-table.js +0 -4
  551. package/core/server/data/migrations/versions/2.32/02-add-name-to-members-table.js +0 -7
  552. package/core/server/data/migrations/versions/2.33/01-correct-members-stripe-customers-table.js +0 -37
  553. package/core/server/data/migrations/versions/2.34/01-add-stripe-customers-subscriptions-table.js +0 -2
  554. package/core/server/data/migrations/versions/2.34/02-add-email-to-members-stripe-customers-table.js +0 -7
  555. package/core/server/data/migrations/versions/2.34/03-add-name-to-members-stripe-customers-table.js +0 -7
  556. package/core/server/data/migrations/versions/2.35/01-add-note-to-members-table.js +0 -7
  557. package/core/server/data/migrations/versions/2.37/01-add-self-signup-and-from address-to-members-settings.js +0 -67
  558. package/core/server/data/migrations/versions/2.6/1-add-webhook-permission-roles.js +0 -31
  559. package/core/server/data/migrations/versions/2.8/1-add-members-table.js +0 -2
  560. package/core/server/data/migrations/versions/3.0/01-remove-user-ghost-auth-columns.js +0 -14
  561. package/core/server/data/migrations/versions/3.0/02-drop-token-auth-tables.js +0 -31
  562. package/core/server/data/migrations/versions/3.0/03-drop-client-auth-tables.js +0 -35
  563. package/core/server/data/migrations/versions/3.0/04-add-posts-meta-table.js +0 -2
  564. package/core/server/data/migrations/versions/3.0/05-populate-posts-meta-table.js +0 -83
  565. package/core/server/data/migrations/versions/3.0/06-remove-posts-meta-columns.js +0 -44
  566. package/core/server/data/migrations/versions/3.0/07-add-posts-type-column.js +0 -8
  567. package/core/server/data/migrations/versions/3.0/08-populate-posts-type-column.js +0 -94
  568. package/core/server/data/migrations/versions/3.0/09-remove-posts-page-column.js +0 -7
  569. package/core/server/data/migrations/versions/3.0/10-remove-empty-strings.js +0 -81
  570. package/core/server/data/migrations/versions/3.0/11-update-posts-html.js +0 -7
  571. package/core/server/data/migrations/versions/3.0/12-populate-members-table-from-subscribers.js +0 -54
  572. package/core/server/data/migrations/versions/3.0/13-drop-subscribers-table.js +0 -34
  573. package/core/server/data/migrations/versions/3.0/14-remove-subscribers-flag.js +0 -24
  574. package/core/server/data/migrations/versions/3.1/01-add-send-email-when-published-to-posts.js +0 -7
  575. package/core/server/data/migrations/versions/3.1/02-add-email-subject-to-posts-meta.js +0 -7
  576. package/core/server/data/migrations/versions/3.1/03-add-email-preview-permissions.js +0 -18
  577. package/core/server/data/migrations/versions/3.1/04-add-subscribed-flag-to-members.js +0 -7
  578. package/core/server/data/migrations/versions/3.1/05-add-emails-table.js +0 -2
  579. package/core/server/data/migrations/versions/3.1/06-add-email-permissions.js +0 -15
  580. package/core/server/data/migrations/versions/3.1/07-add-uuid-field-to-members.js +0 -8
  581. package/core/server/data/migrations/versions/3.1/08-add-uuid-values-to-members.js +0 -23
  582. package/core/server/data/migrations/versions/3.1/09-add-further-email-permissions.js +0 -25
  583. package/core/server/data/migrations/versions/3.1/10-add-email-error-data-column.js +0 -8
  584. package/core/server/data/migrations/versions/3.11/01-remove-broken-complimentary-plan-from-members-settings.js +0 -68
  585. package/core/server/data/migrations/versions/3.12/01-add-identity-permission.js +0 -7
  586. package/core/server/data/migrations/versions/3.12/02-remove-legacy-is-paid-flag-from-settings.js +0 -93
  587. package/core/server/data/migrations/versions/3.18/01-add-email-preview-permissions-to-roles.js +0 -39
  588. package/core/server/data/migrations/versions/3.18/02-add-members_stripe_connect-auth-permissions.js +0 -7
  589. package/core/server/data/migrations/versions/3.19/01-update-member-from-email-address.js +0 -91
  590. package/core/server/data/migrations/versions/3.2/01-add-cancel-at-period-end-to-subscriptions.js +0 -7
  591. package/core/server/data/migrations/versions/3.22/01-removed-legacy-values-from-settings-table.js +0 -65
  592. package/core/server/data/migrations/versions/3.22/02-settings-key-renames.js +0 -90
  593. package/core/server/data/migrations/versions/3.22/03-add-group-and-flags-to-settings.js +0 -15
  594. package/core/server/data/migrations/versions/3.22/04-populate-settings-groups-and-flags.js +0 -194
  595. package/core/server/data/migrations/versions/3.22/05-migrate-members-subscription-settings.js +0 -182
  596. package/core/server/data/migrations/versions/3.22/06-migrate-stripe-connect-settings.js +0 -132
  597. package/core/server/data/migrations/versions/3.22/07-update-type-for-settings.js +0 -137
  598. package/core/server/data/migrations/versions/3.23/01-migrate-bulk-email-settings.js +0 -65
  599. package/core/server/data/migrations/versions/3.23/02-remove-bulk-email-settings.js +0 -48
  600. package/core/server/data/migrations/versions/3.23/03-update-portal-button-setting.js +0 -24
  601. package/core/server/data/migrations/versions/3.23/04-add-meta-columns-to-tags-table.js +0 -54
  602. package/core/server/data/migrations/versions/3.24/01-populate-group-for-new-portal-settings.js +0 -38
  603. package/core/server/data/migrations/versions/3.25/01-add-members-stripe-webhook-settings.js +0 -22
  604. package/core/server/data/migrations/versions/3.26/01-add-amp-gtag-id-setting.js +0 -20
  605. package/core/server/data/migrations/versions/3.29/01-remove-duplicate-subscriptions.js +0 -53
  606. package/core/server/data/migrations/versions/3.29/02-remove-duplicate-customers.js +0 -53
  607. package/core/server/data/migrations/versions/3.29/03-remove-orphaned-customers.js +0 -35
  608. package/core/server/data/migrations/versions/3.29/04-remove-orphaned-subscriptions.js +0 -35
  609. package/core/server/data/migrations/versions/3.29/05-add-member-constraints.js +0 -177
  610. package/core/server/data/migrations/versions/3.30/01-add-member-signin-url-permission-roles.js +0 -8
  611. package/core/server/data/migrations/versions/3.32/01-add-member-support-address-setting.js +0 -27
  612. package/core/server/data/migrations/versions/3.32/02-add-member-reply-address-setting.js +0 -20
  613. package/core/server/data/migrations/versions/3.32/03-add-routes-hash-setting.js +0 -20
  614. package/core/server/data/migrations/versions/3.33/01-add-email-recipients-tables.js +0 -8
  615. package/core/server/data/migrations/versions/3.34/01-add-tokens-table.js +0 -2
  616. package/core/server/data/migrations/versions/3.35/01-add-address-columns-to-emails-table.js +0 -14
  617. package/core/server/data/migrations/versions/3.36/01-add-snippets-table.js +0 -2
  618. package/core/server/data/migrations/versions/3.36/02-add-snippets-permissions.js +0 -56
  619. package/core/server/data/migrations/versions/3.37/01-update-portal-button-setting.js +0 -30
  620. package/core/server/data/migrations/versions/3.38/01-add-email-recipient-filter-column.js +0 -8
  621. package/core/server/data/migrations/versions/3.38/02-populate-email-recipient-filter-column.js +0 -34
  622. package/core/server/data/migrations/versions/3.38/03-add-recipient-filter-column.js +0 -8
  623. package/core/server/data/migrations/versions/3.38/04-populate-recipient-filter-column.js +0 -49
  624. package/core/server/data/migrations/versions/3.38/05-add-emails-track-opens-column.js +0 -7
  625. package/core/server/data/migrations/versions/3.38/06-add-newsletter-settings.js +0 -16
  626. package/core/server/data/migrations/versions/3.38/07-migrate-newsletter-settings-from-config.js +0 -48
  627. package/core/server/data/migrations/versions/3.38/08-repopulate-send-email-when-published-down-migration.js +0 -25
  628. package/core/server/data/migrations/versions/3.38/09-remove-send-email-when-published-column.js +0 -7
  629. package/core/server/data/migrations/versions/3.39/01-add-members-signup-redirect-settings.js +0 -16
  630. package/core/server/data/migrations/versions/3.39/02-add-user-id-to-api-keys-table.js +0 -7
  631. package/core/server/data/migrations/versions/3.39/03-add-email-track-opens-setting.js +0 -16
  632. package/core/server/data/migrations/versions/3.39/04-add-cancellation-reason-column.js +0 -7
  633. package/core/server/data/migrations/versions/3.39/05-remove-unused-columns-on-emails.js +0 -14
  634. package/core/server/data/migrations/versions/3.39/06-add-email-recipient-index.js +0 -58
  635. package/core/server/data/migrations/versions/3.39/07-add-email-recipients-event-timestamps.js +0 -19
  636. package/core/server/data/migrations/versions/3.39/08-add-email-stats-columns.js +0 -22
  637. package/core/server/data/migrations/versions/3.40/01-add-members-email-open-rate-column.js +0 -8
  638. package/core/server/data/migrations/versions/3.40/02-add members-email-aggregation-columns.js +0 -16
  639. package/core/server/data/migrations/versions/3.40/03-populate-members-email-counts.js +0 -15
  640. package/core/server/data/migrations/versions/3.41/01-add-firstpromoter-settings.js +0 -16
  641. package/core/server/data/migrations/versions/3.6/1-add-labels-table.js +0 -2
  642. package/core/server/data/migrations/versions/3.6/2-add-members-labels-table.js +0 -2
  643. package/core/server/data/migrations/versions/3.6/3-add-labels-permissions.js +0 -47
  644. package/core/server/data/migrations/versions/3.7/01-fix-incorrect-member-labels-foreign-keys.js +0 -46
  645. package/core/server/data/migrations/versions/3.8/01-add-geolocation-to-members.js +0 -7
  646. package/core/server/data/migrations/versions/3.9/01-add-member-sigin-url-permissions.js +0 -7
  647. package/core/server/services/mail/utils.js +0 -34
  648. package/core/server/services/url/configs/canary.js +0 -143
  649. package/core/server/services/url/configs/v3.js +0 -141
  650. package/core/server/services/url/configs/v4.js +0 -143
  651. package/core/server/web/api/v2/admin/app.js +0 -43
  652. package/core/server/web/api/v2/admin/middleware.js +0 -85
  653. package/core/server/web/api/v2/admin/routes.js +0 -200
  654. package/core/server/web/api/v2/content/app.js +0 -38
  655. package/core/server/web/api/v2/content/middleware.js +0 -23
  656. package/core/server/web/api/v2/content/routes.js +0 -37
  657. package/core/server/web/api/v3/admin/app.js +0 -43
  658. package/core/server/web/api/v3/admin/middleware.js +0 -89
  659. package/core/server/web/api/v3/admin/routes.js +0 -267
  660. package/core/server/web/api/v3/content/app.js +0 -38
  661. package/core/server/web/api/v3/content/middleware.js +0 -23
  662. package/core/server/web/api/v3/content/routes.js +0 -37
  663. package/core/server/web/oauth/app.js +0 -153
  664. package/core/server/web/oauth/index.js +0 -1
@@ -53,8 +53,7 @@ function parseDefaultSettings() {
53
53
  const dynamicDefault = {
54
54
  db_hash: () => uuid.v4(),
55
55
  public_hash: () => crypto.randomBytes(15).toString('hex'),
56
- // @TODO: session_secret would ideally be named "admin_session_secret"
57
- session_secret: () => crypto.randomBytes(32).toString('hex'),
56
+ admin_session_secret: () => crypto.randomBytes(32).toString('hex'),
58
57
  theme_session_secret: () => crypto.randomBytes(32).toString('hex'),
59
58
  members_public_key: () => getMembersKey('public'),
60
59
  members_private_key: () => getMembersKey('private'),
@@ -217,6 +216,11 @@ Settings = ghostBookshelf.Model.extend({
217
216
  return Promise.reject(new errors.ValidationError({message: tpl(messages.valueCannotBeBlank)}));
218
217
  }
219
218
 
219
+ // Ensure that object keys are stringified
220
+ if (_.isObject(item.value)) {
221
+ item.value = JSON.stringify(item.value);
222
+ }
223
+
220
224
  item = self.filterData(item);
221
225
 
222
226
  return Settings.forge({key: item.key}).fetch(options).then(function then(setting) {
@@ -1,5 +1,6 @@
1
1
  const Promise = require('bluebird');
2
2
  const ghostBookshelf = require('./base');
3
+ const ghostVersion = require('@tryghost/version');
3
4
  let Webhook;
4
5
  let Webhooks;
5
6
 
@@ -8,7 +9,7 @@ Webhook = ghostBookshelf.Model.extend({
8
9
 
9
10
  defaults() {
10
11
  return {
11
- api_version: 'v4',
12
+ api_version: `v${ghostVersion.safe}`,
12
13
  status: 'available'
13
14
  };
14
15
  },
@@ -38,7 +38,7 @@ if (parentPort) {
38
38
  const permissions = require('./services/permissions');
39
39
  await permissions.init();
40
40
 
41
- const settings = require('./services/settings');
41
+ const settings = require('./services/settings/settings-service');
42
42
  await settings.init();
43
43
  // Finished INIT
44
44
 
@@ -1,38 +1,41 @@
1
1
  const APIVersionCompatibilityService = require('@tryghost/api-version-compatibility-service');
2
- const VersionNotificationsDataService = require('@tryghost/version-notifications-data-service');
3
2
  const versionMismatchHandler = require('@tryghost/mw-api-version-mismatch');
4
- // const {GhostMailer} = require('../mail');
5
- const settingsService = require('../../services/settings');
6
- const models = require('../../models');
7
- const logging = require('@tryghost/logging');
8
3
  const ghostVersion = require('@tryghost/version');
4
+ const {GhostMailer} = require('../mail');
5
+ const settingsService = require('../settings/settings-service');
6
+ const models = require('../../models');
7
+ const urlUtils = require('../../../shared/url-utils');
8
+ const settingsCache = require('../../../shared/settings-cache');
9
9
 
10
10
  let serviceInstance;
11
11
 
12
12
  const init = () => {
13
- //const ghostMailer = new GhostMailer();
14
- const versionNotificationsDataService = new VersionNotificationsDataService({
15
- UserModel: models.User,
16
- settingsService: settingsService.getSettingsBREADServiceInstance()
17
- });
13
+ const ghostMailer = new GhostMailer();
18
14
 
19
15
  serviceInstance = new APIVersionCompatibilityService({
16
+ UserModel: models.User,
17
+ ApiKeyModel: models.ApiKey,
18
+ settingsService: settingsService.getSettingsBREADServiceInstance(),
20
19
  sendEmail: (options) => {
21
20
  // NOTE: not using bind here because mockMailer is having trouble mocking bound methods
22
- //return ghostMailer.send(options);
23
- // For now log a warning, rather than sending an email
24
- logging.warn(options.html);
21
+ return ghostMailer.send(options);
25
22
  },
26
- fetchEmailsToNotify: versionNotificationsDataService.getNotificationEmails.bind(versionNotificationsDataService),
27
- fetchHandled: versionNotificationsDataService.fetchNotification.bind(versionNotificationsDataService),
28
- saveHandled: versionNotificationsDataService.saveNotification.bind(versionNotificationsDataService)
23
+ getSiteUrl: () => urlUtils.urlFor('home', true),
24
+ getSiteTitle: () => settingsCache.get('title')
29
25
  });
30
26
  };
31
27
 
32
- module.exports.errorHandler = (req, res, next) => {
33
- return versionMismatchHandler(serviceInstance)(req, res, next);
28
+ module.exports.errorHandler = (err, req, res, next) => {
29
+ return versionMismatchHandler(serviceInstance)(err, req, res, next);
34
30
  };
35
31
 
32
+ /**
33
+ * If Accept-Version is set on the request set Content-Version on the response
34
+ *
35
+ * @param {import('express').Request} req
36
+ * @param {import('express').Response} res
37
+ * @param {import('express').NextFunction} next
38
+ */
36
39
  module.exports.contentVersion = (req, res, next) => {
37
40
  if (req.header('accept-version')) {
38
41
  res.header('Content-Version', `v${ghostVersion.safe}`);
@@ -40,4 +43,7 @@ module.exports.contentVersion = (req, res, next) => {
40
43
  next();
41
44
  };
42
45
 
46
+ module.exports.versionRewrites = require('./mw-version-rewrites');
47
+ module.exports.legacyApiPathMatch = require('./legacy-api-path-match');
48
+
43
49
  module.exports.init = init;
@@ -0,0 +1,23 @@
1
+ const pathMatch = require('path-match')();
2
+
3
+ module.exports = (url) => {
4
+ let basePath = 'ghost/api';
5
+ let apiRouteMatcher = '/:version(v2|v3|v4|canary)?/:api(admin|content)/*';
6
+ let urlToMatch = url;
7
+
8
+ if (url.includes(basePath)) {
9
+ urlToMatch = url.split(basePath)[1];
10
+ }
11
+
12
+ if (!urlToMatch.endsWith('/')) {
13
+ urlToMatch += '/';
14
+ }
15
+
16
+ let {version, api} = pathMatch(apiRouteMatcher)(urlToMatch);
17
+
18
+ if (version === [null]) {
19
+ version = null;
20
+ }
21
+
22
+ return {version, api};
23
+ };
@@ -0,0 +1,36 @@
1
+ const legacyApiPathMatch = require('./legacy-api-path-match');
2
+ const urlUtils = require('../../../shared/url-utils');
3
+
4
+ /**
5
+ * If there is a version in the URL, and this is a valid API URL containing admin/content
6
+ * Rewrite the URL and add the accept-version & deprecation headers
7
+ * @param {import('express').Request} req
8
+ * @param {import('express').Response} res
9
+ * @param {import('express').NextFunction} next
10
+ */
11
+ module.exports = (req, res, next) => {
12
+ let {version} = legacyApiPathMatch(req.url);
13
+
14
+ // If we don't match a valid version, carry on
15
+ if (!version) {
16
+ return next();
17
+ }
18
+
19
+ const versionlessUrl = req.url.replace(`${version}/`, '');
20
+
21
+ // Always send the explicit, numeric version in headers
22
+ if (version === 'canary') {
23
+ version = 'v4';
24
+ }
25
+
26
+ // Rewrite the url
27
+ req.url = versionlessUrl;
28
+
29
+ // Add the accept-version header so our internal systems will act as if it was set on the request
30
+ req.headers['accept-version'] = req.headers['accept-version'] || `${version}.0`;
31
+
32
+ res.header('Deprecation', `version="${version}"`);
33
+ res.header('Link', `<${urlUtils.urlJoin(urlUtils.urlFor('admin', true), 'api', versionlessUrl)}>; rel="latest-version"`);
34
+
35
+ next();
36
+ };
@@ -3,7 +3,7 @@ const url = require('url');
3
3
  const models = require('../../../models');
4
4
  const errors = require('@tryghost/errors');
5
5
  const limitService = require('../../../services/limits');
6
- const config = require('../../../../shared/config');
6
+ const {legacyApiPathMatch} = require('../../../services/api-version-compatibility');
7
7
  const tpl = require('@tryghost/tpl');
8
8
  const _ = require('lodash');
9
9
 
@@ -139,19 +139,20 @@ const authenticateWithToken = async (req, res, next, {token, JWT_OPTIONS}) => {
139
139
  // https://github.com/auth0/node-jsonwebtoken/issues/208#issuecomment-231861138
140
140
  const secret = Buffer.from(apiKey.get('secret'), 'hex');
141
141
 
142
- const {pathname} = url.parse(req.originalUrl);
143
- const [hasMatch, version, api] = pathname.match(/ghost\/api\/([^/]+)\/([^/]+)\/(.+)*/); // eslint-disable-line no-unused-vars
142
+ // Using req.originalUrl means we get the right url even if version-rewrites have happened
143
+ const {version, api} = legacyApiPathMatch(req.originalUrl);
144
144
 
145
145
  // ensure the token was meant for this api
146
146
  let options;
147
- if (!config.get('api:versions:all').includes(version)) {
148
- // CASE: non-versioned api request
147
+
148
+ if (version) {
149
+ // CASE: legacy versioned api request
149
150
  options = Object.assign({
150
- audience: new RegExp(`\/?${version}\/?$`) // eslint-disable-line no-useless-escape
151
+ audience: new RegExp(`/?${version}/${api}/?$`)
151
152
  }, JWT_OPTIONS);
152
153
  } else {
153
154
  options = Object.assign({
154
- audience: new RegExp(`\/?${version}\/${api}\/?$`) // eslint-disable-line no-useless-escape
155
+ audience: new RegExp(`/?${api}/?$`)
155
156
  }, JWT_OPTIONS);
156
157
  }
157
158
 
@@ -61,10 +61,10 @@ function generateToken(email, settingsAPI, transaction) {
61
61
  }
62
62
 
63
63
  function extractTokenParts(options) {
64
- options.data.passwordreset[0].token = security.url.decodeBase64(options.data.passwordreset[0].token);
64
+ options.data.password_reset[0].token = security.url.decodeBase64(options.data.password_reset[0].token);
65
65
 
66
66
  const tokenParts = security.tokens.resetToken.extract({
67
- token: options.data.passwordreset[0].token
67
+ token: options.data.password_reset[0].token
68
68
  });
69
69
 
70
70
  if (!tokenParts) {
@@ -93,7 +93,7 @@ function protectBruteForce({options, tokenParts}) {
93
93
  function doReset(options, tokenParts, settingsAPI) {
94
94
  let dbHash;
95
95
 
96
- const data = options.data.passwordreset[0];
96
+ const data = options.data.password_reset[0];
97
97
  const resetToken = data.token;
98
98
  const oldPassword = data.oldPassword;
99
99
  const newPassword = data.newPassword;
@@ -15,7 +15,7 @@ function getExpressSessionMiddleware() {
15
15
  if (!unoExpressSessionMiddleware) {
16
16
  unoExpressSessionMiddleware = session({
17
17
  store: sessionStore,
18
- secret: settingsCache.get('session_secret'),
18
+ secret: settingsCache.get('admin_session_secret'),
19
19
  resave: false,
20
20
  saveUninitialized: false,
21
21
  name: 'ghost-admin-api-session',
@@ -32,7 +32,7 @@ const sessionService = createSessionService({
32
32
  getOriginOfRequest,
33
33
  getSession: expressSession.getSession,
34
34
  findUserById({id}) {
35
- return models.User.findOne({id});
35
+ return models.User.findOne({id, status: 'active'});
36
36
  }
37
37
  });
38
38
 
@@ -108,8 +108,8 @@ async function doSettings(data, settingsAPI) {
108
108
  }
109
109
 
110
110
  // Update names for default product and newsletter to site title
111
- async function doProductAndNewsletter(data, api) {
112
- const {products: productsAPI, newsletters: newslettersAPI} = api;
111
+ async function doTiersAndNewsletter(data, api) {
112
+ const {tiers: tiersAPI, newsletters: newslettersAPI} = api;
113
113
  const context = {context: {user: data.user.id}};
114
114
  const user = data.user;
115
115
  const blogTitle = data.userData.blogTitle;
@@ -118,16 +118,16 @@ async function doProductAndNewsletter(data, api) {
118
118
  return user;
119
119
  }
120
120
  try {
121
- const productPage = await productsAPI.browse({limit: 'all'});
121
+ const tierPage = await tiersAPI.browse({limit: 'all'});
122
122
  const newsletterPage = await newslettersAPI.browse({limit: 'all'});
123
123
 
124
- const defaultProduct = productPage.products.find(p => p.slug === 'default-product');
124
+ const defaultTier = tierPage.tiers.find(p => p.slug === 'default-product');
125
125
  const defaultNewsletter = newsletterPage.newsletters.find(p => p.slug === 'default-newsletter');
126
126
 
127
- if (defaultProduct) {
128
- await productsAPI.edit({products: [{
127
+ if (defaultTier) {
128
+ await tiersAPI.edit({tiers: [{
129
129
  name: blogTitle.trim()
130
- }]}, {context: context.context, id: defaultProduct.id});
130
+ }]}, {context: context.context, id: defaultTier.id});
131
131
  }
132
132
 
133
133
  if (defaultNewsletter) {
@@ -231,7 +231,7 @@ module.exports = {
231
231
  assertSetupCompleted: assertSetupCompleted,
232
232
  setupUser: setupUser,
233
233
  doSettings: doSettings,
234
- doProductAndNewsletter: doProductAndNewsletter,
234
+ doProductAndNewsletter: doTiersAndNewsletter,
235
235
  installTheme: installTheme,
236
236
  doFixtures: doFixtures,
237
237
  sendWelcomeEmail: sendWelcomeEmail
@@ -167,6 +167,9 @@ module.exports = {
167
167
  await emailBatchModel.save({status: 'submitting'}, knexOptions);
168
168
 
169
169
  try {
170
+ // Load newsletter data on email
171
+ await emailBatchModel.relations.email.related('newsletter').fetch(Object.assign({}, {require: false}, knexOptions));
172
+
170
173
  // send the email
171
174
  const sendResponse = await this.send(emailBatchModel.relations.email.toJSON(), recipientRows, memberSegment);
172
175
 
@@ -217,11 +220,12 @@ module.exports = {
217
220
 
218
221
  // collate static and dynamic data for each recipient ready for provider
219
222
  const recipientData = {};
223
+ const newsletterUuid = emailData.newsletter ? emailData.newsletter.uuid : null;
220
224
  recipients.forEach((recipient) => {
221
225
  // static data for every recipient
222
226
  const data = {
223
227
  unique_id: recipient.member_uuid,
224
- unsubscribe_url: postEmailSerializer.createUnsubscribeUrl(recipient.member_uuid)
228
+ unsubscribe_url: postEmailSerializer.createUnsubscribeUrl(recipient.member_uuid, newsletterUuid)
225
229
  };
226
230
 
227
231
  // computed properties on recipients - TODO: better way of handling these
@@ -1,4 +1,5 @@
1
1
  const {EventProcessor} = require('@tryghost/email-analytics-service');
2
+ const {default: ObjectID} = require('bson-objectid');
2
3
  const moment = require('moment-timezone');
3
4
 
4
5
  class GhostEventProcessor extends EventProcessor {
@@ -130,33 +131,43 @@ class GhostEventProcessor extends EventProcessor {
130
131
  }
131
132
 
132
133
  async handleUnsubscribed(event) {
134
+ return this._unsubscribeFromNewsletters(event);
135
+ }
136
+
137
+ async handleComplained(event) {
138
+ return this._unsubscribeFromNewsletters(event);
139
+ }
140
+
141
+ async _unsubscribeFromNewsletters(event) {
133
142
  const memberId = await this.getMemberId(event);
134
143
 
135
144
  if (!memberId) {
136
145
  return false;
137
146
  }
138
147
 
139
- const updateResult = await this.db.knex('members')
140
- .where('id', '=', memberId)
141
- .update({
142
- subscribed: false,
143
- updated_at: moment.utc().toDate()
144
- });
148
+ const subscribedNewsletterIds = await this.db.knex('members_newsletters')
149
+ .where('member_id', '=', memberId)
150
+ .pluck('newsletter_id');
145
151
 
146
- return updateResult > 0;
147
- }
148
-
149
- async handleComplained(event) {
150
- const memberId = await this.getMemberId(event);
152
+ await this.db.knex('members_newsletters')
153
+ .where('member_id', '=', memberId)
154
+ .del();
151
155
 
152
- if (!memberId) {
153
- return false;
156
+ const nowUTC = moment.utc().toDate();
157
+ for (const newsletterId of subscribedNewsletterIds) {
158
+ await this.db.knex('members_subscribe_events').insert({
159
+ id: ObjectID().toHexString(),
160
+ member_id: memberId,
161
+ newsletter_id: newsletterId,
162
+ subscribed: false,
163
+ created_at: nowUTC,
164
+ source: 'member'
165
+ });
154
166
  }
155
167
 
156
168
  const updateResult = await this.db.knex('members')
157
169
  .where('id', '=', memberId)
158
170
  .update({
159
- subscribed: false,
160
171
  updated_at: moment.utc().toDate()
161
172
  });
162
173
 
@@ -0,0 +1,27 @@
1
+ const errors = require('@tryghost/errors');
2
+ const logging = require('@tryghost/logging');
3
+
4
+ class FrontendDataService {
5
+ constructor({IntegrationModel}) {
6
+ this.IntegrationModel = IntegrationModel;
7
+ this.frontendKey = null;
8
+ }
9
+
10
+ async getFrontendKey() {
11
+ if (this.frontendKey) {
12
+ return this.frontendKey;
13
+ }
14
+
15
+ try {
16
+ const key = await this.IntegrationModel.getInternalFrontendKey();
17
+ this.frontendKey = key.toJSON().api_keys[0].secret;
18
+ } catch (error) {
19
+ this.frontendKey = null;
20
+ logging.error(new errors.InternalServerError({message: 'Unable to find the internal frontend key', err: error}));
21
+ }
22
+
23
+ return this.frontendKey;
24
+ }
25
+ }
26
+
27
+ module.exports = FrontendDataService;
@@ -0,0 +1,6 @@
1
+ const models = require('../../models');
2
+ const FrontendDataService = require('./frontend-data-service');
3
+
4
+ module.exports.init = () => {
5
+ return new FrontendDataService({IntegrationModel: models.Integration});
6
+ };
@@ -1,2 +1,15 @@
1
+ const path = require('path');
2
+ const urlUtils = require('../../../shared/url-utils');
3
+ const settingsCache = require('../../../shared/settings-cache');
4
+ const EmailContentGenerator = require('@tryghost/email-content-generator');
5
+
6
+ const emailContentGenerator = new EmailContentGenerator({
7
+ getSiteUrl: () => urlUtils.urlFor('home', true),
8
+ getSiteTitle: () => settingsCache.get('title'),
9
+ templatesDir: path.resolve(__dirname, '..', 'mail', 'templates')
10
+ });
11
+
1
12
  exports.GhostMailer = require('./GhostMailer');
2
- exports.utils = require('./utils');
13
+ exports.utils = {
14
+ generateContent: emailContentGenerator.getContent.bind(emailContentGenerator)
15
+ };
@@ -2,26 +2,25 @@ const postEmailSerializer = require('./post-email-serializer');
2
2
  const models = require('../../models');
3
3
 
4
4
  class EmailPreview {
5
- /**
6
- * @constructor
7
- * @param {Object} options
8
- * @param {String} options.apiVersion
9
- */
10
- constructor({apiVersion}) {
11
- this.apiVersion = apiVersion;
12
- }
13
-
14
5
  /**
15
6
  * @param {Object} post - Post model object instance
16
- * @param {String} memberSegment - member segment filter
7
+ * @param {Object} options
8
+ * @param {String} options.newsletter - newsletter slug
9
+ * @param {String} options.memberSegment - member segment filter
17
10
  * @returns {Promise<Object>}
18
11
  */
19
- async generateEmailContent(post, memberSegment) {
20
- const newsletter = await models.Newsletter.getDefaultNewsletter();
12
+ async generateEmailContent(post, {newsletter, memberSegment} = {}) {
13
+ let newsletterModel = post.relations.newsletter ?? await post.related('newsletter').fetch();
14
+ if (!newsletterModel) {
15
+ if (newsletter) {
16
+ newsletterModel = await models.Newsletter.findOne({slug: newsletter});
17
+ } else {
18
+ newsletterModel = await models.Newsletter.getDefaultNewsletter();
19
+ }
20
+ }
21
21
 
22
- let emailContent = await postEmailSerializer.serialize(post, newsletter, {
23
- isBrowserPreview: true,
24
- apiVersion: this.apiVersion
22
+ let emailContent = await postEmailSerializer.serialize(post, newsletterModel, {
23
+ isBrowserPreview: true
25
24
  });
26
25
 
27
26
  if (memberSegment) {
@@ -17,7 +17,6 @@ const models = require('../../models');
17
17
  const postEmailSerializer = require('./post-email-serializer');
18
18
  const labs = require('../../../shared/labs');
19
19
  const {getSegmentsFromHtml} = require('./segment-parser');
20
- const labsService = require('../../../shared/labs');
21
20
 
22
21
  // Used to listen to email.added and email.edited model events originally, I think to offload this - ideally would just use jobs now if possible
23
22
  const events = require('../../lib/common/events');
@@ -28,6 +27,7 @@ const messages = {
28
27
  noneFilterError: 'Cannot send email to "none" {property}',
29
28
  emailSendingDisabled: `Email sending is temporarily disabled because your account is currently in review. You should have an email about this from us already, but you can also reach us any time at support@ghost.org`,
30
29
  sendEmailRequestFailed: 'The email service was unable to send an email batch.',
30
+ archivedNewsletterError: 'Cannot send email to archived newsletters',
31
31
  newsletterVisibilityError: 'Unexpected visibility value "{value}". Use one of the valid: "members", "paid".'
32
32
  };
33
33
 
@@ -51,11 +51,11 @@ const getReplyToAddress = (fromAddress, replyAddressOption) => {
51
51
  *
52
52
  * @param {Object} postModel - post model instance
53
53
  * @param {Object} options
54
- * @param {ValidAPIVersion} options.apiVersion - api version to be used when serializing email data
55
54
  */
56
55
  const getEmailData = async (postModel, options) => {
57
- let newsletter = postModel.relations.newsletter ? postModel.relations.newsletter : (await postModel.related('newsletter').fetch());
56
+ let newsletter = postModel.relations.newsletter ?? await postModel.related('newsletter').fetch();
58
57
  if (!newsletter) {
58
+ // The postModel doesn't have a newsletter in test emails
59
59
  newsletter = await models.Newsletter.getDefaultNewsletter();
60
60
  }
61
61
  const {subject, html, plaintext} = await postEmailSerializer.serialize(postModel, newsletter, options);
@@ -83,11 +83,10 @@ const getEmailData = async (postModel, options) => {
83
83
  *
84
84
  * @param {Object} postModel - post model instance
85
85
  * @param {[string]} toEmails - member email addresses to send email to
86
- * @param {ValidAPIVersion} apiVersion - api version to be used when serializing email data
87
86
  * @param {ValidMemberSegment} [memberSegment]
88
87
  */
89
- const sendTestEmail = async (postModel, toEmails, apiVersion, memberSegment) => {
90
- let emailData = await getEmailData(postModel, {apiVersion});
88
+ const sendTestEmail = async (postModel, toEmails, memberSegment) => {
89
+ let emailData = await getEmailData(postModel);
91
90
  emailData.subject = `[Test] ${emailData.subject}`;
92
91
 
93
92
  if (memberSegment) {
@@ -134,28 +133,14 @@ const sendTestEmail = async (postModel, toEmails, apiVersion, memberSegment) =>
134
133
  *
135
134
  * Accepts a filter string, errors on unexpected legacy filter syntax and enforces subscribed:true
136
135
  *
136
+ * @param {Object} newsletter
137
137
  * @param {string} emailRecipientFilter NQL filter for members
138
- * @param {object} options
138
+ * @param {string} errorProperty
139
139
  */
140
- const transformEmailRecipientFilter = (emailRecipientFilter, {errorProperty = 'email_recipient_filter'} = {}, newsletter = null) => {
141
- let filter = [];
142
-
143
- if (!newsletter) {
144
- filter.push(`subscribed:true`);
145
- } else {
146
- filter.push(`newsletters.id:${newsletter.id}`);
147
- }
140
+ const transformEmailRecipientFilter = (newsletter, emailRecipientFilter, errorProperty) => {
141
+ const filter = [`newsletters.id:${newsletter.id}`];
148
142
 
149
143
  switch (emailRecipientFilter) {
150
- // `paid` and `free` were swapped out for NQL filters in 4.5.0, we shouldn't see them here now
151
- case 'paid':
152
- case 'free':
153
- throw new errors.InternalServerError({
154
- message: tpl(messages.unexpectedFilterError, {
155
- property: errorProperty,
156
- value: emailRecipientFilter
157
- })
158
- });
159
144
  case 'all':
160
145
  break;
161
146
  case 'none':
@@ -169,22 +154,20 @@ const transformEmailRecipientFilter = (emailRecipientFilter, {errorProperty = 'e
169
154
  break;
170
155
  }
171
156
 
172
- if (newsletter) {
173
- const visibility = newsletter.get('visibility');
174
- switch (visibility) {
175
- case 'members':
176
- // No need to add a member status filter as the email is available to all members
177
- break;
178
- case 'paid':
179
- filter.push(`status:-free`);
180
- break;
181
- default:
182
- throw new errors.InternalServerError({
183
- message: tpl(messages.newsletterVisibilityError, {
184
- value: visibility
185
- })
186
- });
187
- }
157
+ const visibility = newsletter.get('visibility');
158
+ switch (visibility) {
159
+ case 'members':
160
+ // No need to add a member status filter as the email is available to all members
161
+ break;
162
+ case 'paid':
163
+ filter.push(`status:-free`);
164
+ break;
165
+ default:
166
+ throw new errors.InternalServerError({
167
+ message: tpl(messages.newsletterVisibilityError, {
168
+ value: visibility
169
+ })
170
+ });
188
171
  }
189
172
 
190
173
  return filter.join('+');
@@ -198,8 +181,6 @@ const transformEmailRecipientFilter = (emailRecipientFilter, {errorProperty = 'e
198
181
  *
199
182
  * @param {object} postModel Post Model Object
200
183
  * @param {object} options
201
- * @param {ValidAPIVersion} options.apiVersion - api version to be used when serializing email data
202
- * @param {string} options.newsletter_id - the newsletter_id to send the email to
203
184
  */
204
185
 
205
186
  const addEmail = async (postModel, options) => {
@@ -216,10 +197,19 @@ const addEmail = async (postModel, options) => {
216
197
  const knexOptions = _.pick(options, ['transacting', 'forUpdate']);
217
198
  const filterOptions = {...knexOptions, limit: 1};
218
199
 
219
- const newsletter = postModel.relations.newsletter ? postModel.relations.newsletter : (await postModel.related('newsletter').fetch({require: true, ..._.pick(options, ['transacting'])}));
200
+ // TODO: this is a hack for https://github.com/TryGhost/Team/issues/1626
201
+ const newsletter = postModel.relations.newsletter ?? await postModel.related('newsletter').fetch({require: true, ..._.pick(options, ['transacting'])});
202
+
203
+ if (newsletter.get('status') !== 'active') {
204
+ // A post might have been scheduled to an archived newsletter.
205
+ // Don't send it (people can't unsubscribe any longer).
206
+ throw new errors.EmailError({
207
+ message: tpl(messages.archivedNewsletterError)
208
+ });
209
+ }
220
210
 
221
211
  const emailRecipientFilter = postModel.get('email_recipient_filter');
222
- filterOptions.filter = transformEmailRecipientFilter(emailRecipientFilter, {errorProperty: 'email_recipient_filter'}, newsletter);
212
+ filterOptions.filter = transformEmailRecipientFilter(newsletter, emailRecipientFilter, 'email_segment');
223
213
 
224
214
  const startRetrieve = Date.now();
225
215
  debug('addEmail: retrieving members count');
@@ -426,11 +416,8 @@ async function getEmailMemberRows({emailModel, memberSegment, options}) {
426
416
  const knexOptions = _.pick(options, ['transacting', 'forUpdate']);
427
417
  const filterOptions = Object.assign({}, knexOptions);
428
418
 
429
- let newsletter = null;
430
- if (labsService.isSet('multipleNewsletters')) {
431
- newsletter = emailModel.relations.newsletter ? emailModel.relations.newsletter : (await emailModel.related('newsletter').fetch(Object.assign({}, {require: false}, _.pick(options, ['transacting']))));
432
- }
433
- const recipientFilter = transformEmailRecipientFilter(emailModel.get('recipient_filter'), {errorProperty: 'recipient_filter'}, newsletter);
419
+ const newsletter = emailModel.relations.newsletter ?? await emailModel.related('newsletter').fetch(Object.assign({}, {require: true}, _.pick(options, ['transacting'])));
420
+ const recipientFilter = transformEmailRecipientFilter(newsletter, emailModel.get('recipient_filter'), 'recipient_filter');
434
421
  filterOptions.filter = recipientFilter;
435
422
 
436
423
  if (memberSegment) {
@@ -609,11 +596,9 @@ module.exports = {
609
596
  _partitionMembersBySegment: partitionMembersBySegment,
610
597
  _getEmailMemberRows: getEmailMemberRows,
611
598
  _getFromAddress: getFromAddress,
612
- _getReplyToAddress: getReplyToAddress,
613
- _sendEmailJob: sendEmailJob
599
+ _getReplyToAddress: getReplyToAddress
614
600
  };
615
601
 
616
602
  /**
617
- * @typedef {'v2' | 'v3' | 'v4' | 'canary' } ValidAPIVersion
618
603
  * @typedef {'status:free' | 'status:-free'} ValidMemberSegment
619
604
  */