ghost 4.48.0 → 5.0.2

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 (663) 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-a40c7b301c702bd84c2fae19366ab5d7.css +1 -0
  24. package/core/built/assets/{ghost.min-10ba0de3ecb93d63d62bb43ac11c740f.js → ghost.min-b37a2752b0abda202c14c948b8bc3587.js} +1138 -1212
  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 +1 -13
  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 +18 -3
  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/table-lists.js +0 -3
  133. package/core/server/data/importer/importers/data/base.js +16 -7
  134. package/core/server/data/importer/importers/data/data-importer.js +38 -1
  135. package/core/server/data/importer/importers/data/newsletters.js +45 -0
  136. package/core/server/data/importer/importers/data/posts.js +40 -12
  137. package/core/server/data/importer/importers/data/products.js +68 -0
  138. package/core/server/data/importer/importers/data/settings.js +10 -10
  139. package/core/server/data/importer/importers/data/stripe-prices.js +59 -0
  140. package/core/server/data/importer/importers/data/stripe-products.js +61 -0
  141. package/core/server/data/migrations/utils/constants.js +3 -0
  142. package/core/server/data/migrations/utils/index.js +10 -0
  143. package/core/server/data/migrations/utils/migrations.js +156 -0
  144. package/core/server/data/migrations/utils/permissions.js +291 -0
  145. package/core/server/data/migrations/utils/schema.js +158 -0
  146. package/core/server/data/migrations/utils/settings.js +59 -0
  147. package/core/server/data/migrations/utils/tables.js +94 -0
  148. package/core/server/data/migrations/versions/1.25/01-final-v1.js +2 -0
  149. package/core/server/data/migrations/versions/1.25/02-noop.js +6 -0
  150. package/core/server/data/migrations/versions/2.37/01-final-v2.js +2 -0
  151. package/core/server/data/migrations/versions/3.41/01-final-v3.js +2 -0
  152. package/core/server/data/migrations/versions/4.0/22-solve-orphaned-webhooks.js +3 -9
  153. package/core/server/data/migrations/versions/4.0/23-regenerate-posts-html.js +2 -11
  154. package/core/server/data/migrations/versions/4.11/02-add-email-verification-required-setting.js +1 -1
  155. package/core/server/data/migrations/versions/4.12/02-fix-member-statuses.js +1 -1
  156. package/core/server/data/migrations/versions/4.14/02-fix-free-members-status-events.js +1 -1
  157. package/core/server/data/migrations/versions/4.22/01-add-is-launch-complete-setting.js +1 -1
  158. package/core/server/data/migrations/versions/4.22/02-update-launch-complete-setting-from-user-data.js +1 -1
  159. package/core/server/data/migrations/versions/4.35/2022-02-02-10-38-add-default-content-visibility-tiers-setting.js +1 -1
  160. package/core/server/data/migrations/versions/4.45/2022-04-21-02-55-add-notifications-key-entry-to-settings-table.js +1 -1
  161. package/core/server/data/migrations/versions/4.6/01-remove-comped-status.js +1 -1
  162. package/core/server/data/migrations/versions/4.7/03-add-labs-setting.js +1 -1
  163. package/core/server/data/migrations/versions/4.9/05-fix-missed-mobiledoc-url-transforms.js +1 -1
  164. package/core/server/data/migrations/versions/4.9/06-add-comped-status.js +1 -1
  165. package/core/server/data/migrations/versions/4.9/07-update-comped-members-status-events.js +1 -1
  166. package/core/server/data/migrations/versions/5.0/2022-03-14-12-33-delete-duplicate-offer-redemptions.js +36 -0
  167. package/core/server/data/migrations/versions/5.0/2022-03-28-15-25-backfill-mrr-adjustments-for-offers.js +108 -0
  168. package/core/server/data/migrations/versions/5.0/2022-04-25-10-32-backfill-mrr-for-discounted-subscriptions.js +44 -0
  169. package/core/server/data/migrations/versions/5.0/2022-04-26-15-44-backfill-mrr-events-for-canceled-subscriptions.js +73 -0
  170. package/core/server/data/migrations/versions/5.0/2022-04-27-11-26-backfill-mrr-for-canceled-subscriptions.js +31 -0
  171. package/core/server/data/migrations/versions/5.0/2022-04-28-03-26-remove-author-id-column-from-posts-table.js +7 -0
  172. package/core/server/data/migrations/versions/5.0/2022-05-03-09-39-drop-nullable-subscribe-event-newsletter-id.js +4 -0
  173. package/core/server/data/migrations/versions/5.0/2022-05-04-15-24-map-existing-emails-to-default-newsletter.js +44 -0
  174. package/core/server/data/migrations/versions/5.0/2022-05-05-13-13-migrate-legacy-recipient-filters.js +30 -0
  175. package/core/server/data/migrations/versions/5.0/2022-05-05-13-29-add-newsletters-admin-integration-permission-roles.js +20 -0
  176. package/core/server/data/migrations/versions/5.0/2022-05-05-15-17-drop-oauth-table.js +3 -0
  177. package/core/server/data/migrations/versions/5.0/2022-05-06-08-16-cleanup-client-subscriber-permissions.js +68 -0
  178. package/core/server/data/migrations/versions/5.0/2022-05-06-13-22-add-frontend-integration.js +68 -0
  179. package/core/server/data/migrations/versions/5.0/2022-05-09-10-00-drop-members-subscribed-column.js +18 -0
  180. package/core/server/data/migrations/versions/5.0/2022-05-09-14-17-cleanup-invalid-users-status.js +17 -0
  181. package/core/server/data/migrations/versions/5.0/2022-05-10-08-33-drop-members-analytics-table.js +3 -0
  182. package/core/server/data/migrations/versions/5.0/2022-05-10-14-57-cleanup-invalid-posts-status.js +17 -0
  183. package/core/server/data/migrations/versions/5.0/2022-05-11-12-08-drop-webhooks-status-column.js +18 -0
  184. package/core/server/data/migrations/versions/5.0/2022-05-11-13-12-rename-settings.js +51 -0
  185. package/core/server/data/migrations/versions/5.0/2022-05-11-16-36-remove-unused-settings.js +54 -0
  186. package/core/server/data/migrations/versions/5.0/2022-05-12-10-29-add-newsletter-permissions-for-editors-and-authors.js +20 -0
  187. package/core/server/data/migrations/versions/5.0/2022-05-12-13-51-add-label-permissions-for-authors.js +12 -0
  188. package/core/server/data/migrations/versions/5.0/2022-05-13-11-38-drop-none-email-recipient-filter.js +28 -0
  189. package/core/server/data/migrations/versions/5.0/2022-05-21-00-00-regenerate-posts-html.js +70 -0
  190. package/core/server/data/schema/commands.js +35 -3
  191. package/core/server/data/schema/default-settings/default-settings.json +2 -159
  192. package/core/server/data/schema/fixtures/fixture-manager.js +11 -2
  193. package/core/server/data/schema/fixtures/fixtures.json +16 -7
  194. package/core/server/data/schema/schema.js +26 -38
  195. package/core/server/data/schema/validator.js +2 -0
  196. package/core/server/ghost-server.js +34 -64
  197. package/core/server/lib/image/gravatar.js +25 -9
  198. package/core/server/models/api-key.js +3 -26
  199. package/core/server/models/base/plugins/bulk-operations.js +14 -6
  200. package/core/server/models/integration.js +17 -0
  201. package/core/server/models/member.js +8 -4
  202. package/core/server/models/newsletter.js +27 -0
  203. package/core/server/models/post.js +30 -32
  204. package/core/server/models/relations/authors.js +74 -100
  205. package/core/server/models/settings.js +6 -2
  206. package/core/server/models/webhook.js +2 -1
  207. package/core/server/run-update-check.js +1 -1
  208. package/core/server/services/api-version-compatibility/index.js +24 -18
  209. package/core/server/services/api-version-compatibility/legacy-api-path-match.js +23 -0
  210. package/core/server/services/api-version-compatibility/mw-version-rewrites.js +36 -0
  211. package/core/server/services/auth/api-key/admin.js +8 -7
  212. package/core/server/services/auth/passwordreset.js +3 -3
  213. package/core/server/services/auth/session/express-session.js +1 -1
  214. package/core/server/services/auth/session/index.js +1 -1
  215. package/core/server/services/auth/setup.js +8 -8
  216. package/core/server/services/bulk-email/bulk-email-processor.js +5 -1
  217. package/core/server/services/email-analytics/lib/event-processor.js +25 -14
  218. package/core/server/services/frontend-data-service/frontend-data-service.js +27 -0
  219. package/core/server/services/frontend-data-service/index.js +6 -0
  220. package/core/server/services/mail/index.js +14 -1
  221. package/core/server/services/mega/email-preview.js +14 -15
  222. package/core/server/services/mega/mega.js +37 -52
  223. package/core/server/services/mega/post-email-serializer.js +18 -28
  224. package/core/server/services/members/api.js +0 -3
  225. package/core/server/services/members/config.js +0 -49
  226. package/core/server/services/members/exporter/query.js +7 -7
  227. package/core/server/services/members/middleware.js +3 -135
  228. package/core/server/services/members/service.js +0 -27
  229. package/core/server/services/members/settings.js +3 -9
  230. package/core/server/services/newsletters/service.js +78 -10
  231. package/core/server/services/posts/post-scheduling-service.js +5 -17
  232. package/core/server/services/posts/posts-service.js +15 -62
  233. package/core/server/services/public-config/site.js +0 -6
  234. package/core/server/services/route-settings/index.js +0 -3
  235. package/core/server/services/route-settings/settings-loader.js +10 -34
  236. package/core/server/services/route-settings/validate.js +1 -7
  237. package/core/server/services/settings/index.js +1 -77
  238. package/core/server/services/settings/settings-service.js +184 -0
  239. package/core/server/services/themes/validate.js +1 -1
  240. package/core/server/services/url/Resources.js +1 -3
  241. package/core/server/services/url/UrlGenerator.js +1 -1
  242. package/core/server/services/url/UrlService.js +6 -20
  243. package/core/server/services/url/{configs/v2.js → config.js} +0 -0
  244. package/core/server/services/users.js +2 -2
  245. package/core/server/services/webhooks/listen.js +5 -2
  246. package/core/server/services/webhooks/serialize.js +6 -7
  247. package/core/server/services/webhooks/trigger.js +62 -47
  248. package/core/server/update-check.js +1 -1
  249. package/core/server/web/admin/app.js +1 -1
  250. package/core/server/web/admin/views/default-prod.html +4 -4
  251. package/core/server/web/admin/views/default.html +4 -4
  252. package/core/server/web/api/app.js +3 -15
  253. package/core/server/web/api/canary/admin/app.js +1 -1
  254. package/core/server/web/api/canary/admin/middleware.js +3 -1
  255. package/core/server/web/api/canary/admin/routes.js +7 -23
  256. package/core/server/web/api/canary/content/app.js +2 -3
  257. package/core/server/web/api/canary/content/routes.js +5 -4
  258. package/core/server/web/members/app.js +5 -4
  259. package/core/server/web/parent/backend.js +0 -1
  260. package/core/server/web/parent/frontend.js +5 -6
  261. package/core/server/web/parent/middleware/ghost-locals.js +0 -3
  262. package/core/server/web/well-known.js +14 -1
  263. package/core/shared/config/defaults.json +5 -2
  264. package/core/shared/config/overrides.json +1 -27
  265. package/core/shared/html-to-plaintext.js +78 -10
  266. package/core/shared/labs.js +4 -8
  267. package/core/shared/settings-cache/cache.js +38 -4
  268. package/core/shared/settings-cache/public.js +13 -7
  269. package/core/shared/url-utils.js +0 -2
  270. package/ghost.js +6 -0
  271. package/package.json +66 -64
  272. package/yarn.lock +765 -1300
  273. package/core/built/assets/ghost-dark-c94ae212747200ca4bafc37cfb0714d8.css +0 -1
  274. package/core/built/assets/ghost.min-4084931bc22e794fe3722139050a80b3.css +0 -1
  275. package/core/frontend/helpers/author.js +0 -41
  276. package/core/frontend/helpers/products.js +0 -65
  277. package/core/frontend/services/rendering/secure.js +0 -19
  278. package/core/frontend/services/routing/config/canary.js +0 -61
  279. package/core/frontend/services/routing/config/v2.js +0 -54
  280. package/core/frontend/services/routing/config/v3.js +0 -54
  281. package/core/frontend/services/theme-engine/engines/create.js +0 -45
  282. package/core/frontend/services/theme-engine/engines/index.js +0 -5
  283. package/core/frontend/services/theme-engine/middleware/update-local-template-data.js +0 -9
  284. package/core/server/api/canary/products-public.js +0 -34
  285. package/core/server/api/canary/products.js +0 -116
  286. package/core/server/api/canary/utils/serializers/input/products.js +0 -28
  287. package/core/server/api/canary/utils/serializers/output/email-previews.js +0 -7
  288. package/core/server/api/canary/utils/serializers/output/products.js +0 -213
  289. package/core/server/api/v2/actions.js +0 -38
  290. package/core/server/api/v2/authentication.js +0 -191
  291. package/core/server/api/v2/authors-public.js +0 -69
  292. package/core/server/api/v2/config.js +0 -12
  293. package/core/server/api/v2/db.js +0 -120
  294. package/core/server/api/v2/images.js +0 -20
  295. package/core/server/api/v2/index.js +0 -147
  296. package/core/server/api/v2/integrations.js +0 -144
  297. package/core/server/api/v2/invites.js +0 -126
  298. package/core/server/api/v2/mail.js +0 -66
  299. package/core/server/api/v2/notifications.js +0 -96
  300. package/core/server/api/v2/oembed.js +0 -186
  301. package/core/server/api/v2/pages-public.js +0 -78
  302. package/core/server/api/v2/pages.js +0 -197
  303. package/core/server/api/v2/posts-public.js +0 -78
  304. package/core/server/api/v2/posts.js +0 -192
  305. package/core/server/api/v2/preview.js +0 -46
  306. package/core/server/api/v2/redirects.js +0 -28
  307. package/core/server/api/v2/roles.js +0 -19
  308. package/core/server/api/v2/schedules.js +0 -77
  309. package/core/server/api/v2/session.js +0 -70
  310. package/core/server/api/v2/settings-public.js +0 -17
  311. package/core/server/api/v2/settings.js +0 -195
  312. package/core/server/api/v2/site.js +0 -14
  313. package/core/server/api/v2/slack.js +0 -12
  314. package/core/server/api/v2/slugs.js +0 -51
  315. package/core/server/api/v2/tags-public.js +0 -71
  316. package/core/server/api/v2/tags.js +0 -159
  317. package/core/server/api/v2/themes.js +0 -133
  318. package/core/server/api/v2/users.js +0 -179
  319. package/core/server/api/v2/utils/index.js +0 -34
  320. package/core/server/api/v2/utils/permissions.js +0 -112
  321. package/core/server/api/v2/utils/serializers/index.js +0 -9
  322. package/core/server/api/v2/utils/serializers/input/db.js +0 -20
  323. package/core/server/api/v2/utils/serializers/input/index.js +0 -33
  324. package/core/server/api/v2/utils/serializers/input/integrations.js +0 -33
  325. package/core/server/api/v2/utils/serializers/input/pages.js +0 -203
  326. package/core/server/api/v2/utils/serializers/input/posts.js +0 -218
  327. package/core/server/api/v2/utils/serializers/input/settings.js +0 -152
  328. package/core/server/api/v2/utils/serializers/input/tags.js +0 -35
  329. package/core/server/api/v2/utils/serializers/input/users.js +0 -26
  330. package/core/server/api/v2/utils/serializers/input/utils/url.js +0 -71
  331. package/core/server/api/v2/utils/serializers/input/webhooks.js +0 -12
  332. package/core/server/api/v2/utils/serializers/output/actions.js +0 -13
  333. package/core/server/api/v2/utils/serializers/output/all.js +0 -25
  334. package/core/server/api/v2/utils/serializers/output/authentication.js +0 -68
  335. package/core/server/api/v2/utils/serializers/output/authors.js +0 -21
  336. package/core/server/api/v2/utils/serializers/output/config.js +0 -21
  337. package/core/server/api/v2/utils/serializers/output/db.js +0 -40
  338. package/core/server/api/v2/utils/serializers/output/images.js +0 -19
  339. package/core/server/api/v2/utils/serializers/output/index.js +0 -107
  340. package/core/server/api/v2/utils/serializers/output/integrations.js +0 -35
  341. package/core/server/api/v2/utils/serializers/output/invites.js +0 -24
  342. package/core/server/api/v2/utils/serializers/output/mail.js +0 -19
  343. package/core/server/api/v2/utils/serializers/output/notifications.js +0 -29
  344. package/core/server/api/v2/utils/serializers/output/oembed.js +0 -8
  345. package/core/server/api/v2/utils/serializers/output/pages.js +0 -26
  346. package/core/server/api/v2/utils/serializers/output/posts.js +0 -26
  347. package/core/server/api/v2/utils/serializers/output/preview.js +0 -9
  348. package/core/server/api/v2/utils/serializers/output/redirects.js +0 -5
  349. package/core/server/api/v2/utils/serializers/output/roles.js +0 -29
  350. package/core/server/api/v2/utils/serializers/output/schedules.js +0 -5
  351. package/core/server/api/v2/utils/serializers/output/settings.js +0 -61
  352. package/core/server/api/v2/utils/serializers/output/site.js +0 -16
  353. package/core/server/api/v2/utils/serializers/output/slugs.js +0 -11
  354. package/core/server/api/v2/utils/serializers/output/tags.js +0 -25
  355. package/core/server/api/v2/utils/serializers/output/themes.js +0 -25
  356. package/core/server/api/v2/utils/serializers/output/users.js +0 -45
  357. package/core/server/api/v2/utils/serializers/output/utils/clean.js +0 -174
  358. package/core/server/api/v2/utils/serializers/output/utils/date.js +0 -21
  359. package/core/server/api/v2/utils/serializers/output/utils/extra-attrs.js +0 -161
  360. package/core/server/api/v2/utils/serializers/output/utils/mapper.js +0 -136
  361. package/core/server/api/v2/utils/serializers/output/utils/post-gating.js +0 -29
  362. package/core/server/api/v2/utils/serializers/output/utils/settings-type-group-mapper.js +0 -24
  363. package/core/server/api/v2/utils/serializers/output/utils/url.js +0 -67
  364. package/core/server/api/v2/utils/serializers/output/webhooks.js +0 -15
  365. package/core/server/api/v2/utils/validators/index.js +0 -9
  366. package/core/server/api/v2/utils/validators/input/images.js +0 -85
  367. package/core/server/api/v2/utils/validators/input/index.js +0 -45
  368. package/core/server/api/v2/utils/validators/input/invitations.js +0 -49
  369. package/core/server/api/v2/utils/validators/input/invites.js +0 -21
  370. package/core/server/api/v2/utils/validators/input/oembed.js +0 -17
  371. package/core/server/api/v2/utils/validators/input/pages.js +0 -46
  372. package/core/server/api/v2/utils/validators/input/passwordreset.js +0 -36
  373. package/core/server/api/v2/utils/validators/input/posts.js +0 -46
  374. package/core/server/api/v2/utils/validators/input/settings.js +0 -79
  375. package/core/server/api/v2/utils/validators/input/setup.js +0 -17
  376. package/core/server/api/v2/utils/validators/input/tags.js +0 -6
  377. package/core/server/api/v2/utils/validators/input/users.js +0 -21
  378. package/core/server/api/v2/utils/validators/output/index.js +0 -1
  379. package/core/server/api/v2/utils/validators/utils/json-schema.js +0 -17
  380. package/core/server/api/v2/webhooks.js +0 -163
  381. package/core/server/api/v3/authentication.js +0 -192
  382. package/core/server/api/v3/authors-public.js +0 -69
  383. package/core/server/api/v3/config.js +0 -12
  384. package/core/server/api/v3/db.js +0 -131
  385. package/core/server/api/v3/email-preview.js +0 -74
  386. package/core/server/api/v3/email.js +0 -65
  387. package/core/server/api/v3/identities.js +0 -36
  388. package/core/server/api/v3/images.js +0 -20
  389. package/core/server/api/v3/index.js +0 -179
  390. package/core/server/api/v3/integrations.js +0 -150
  391. package/core/server/api/v3/invites.js +0 -125
  392. package/core/server/api/v3/labels.js +0 -162
  393. package/core/server/api/v3/mail.js +0 -66
  394. package/core/server/api/v3/memberSigninUrls.js +0 -33
  395. package/core/server/api/v3/members.js +0 -412
  396. package/core/server/api/v3/membersStripeConnect.js +0 -29
  397. package/core/server/api/v3/notifications.js +0 -96
  398. package/core/server/api/v3/oembed.js +0 -23
  399. package/core/server/api/v3/pages-public.js +0 -77
  400. package/core/server/api/v3/pages.js +0 -199
  401. package/core/server/api/v3/posts-public.js +0 -76
  402. package/core/server/api/v3/posts.js +0 -200
  403. package/core/server/api/v3/preview.js +0 -44
  404. package/core/server/api/v3/redirects.js +0 -47
  405. package/core/server/api/v3/roles.js +0 -19
  406. package/core/server/api/v3/schedules.js +0 -77
  407. package/core/server/api/v3/session.js +0 -70
  408. package/core/server/api/v3/settings-public.js +0 -17
  409. package/core/server/api/v3/settings.js +0 -224
  410. package/core/server/api/v3/site.js +0 -14
  411. package/core/server/api/v3/slack.js +0 -12
  412. package/core/server/api/v3/slugs.js +0 -48
  413. package/core/server/api/v3/snippets.js +0 -115
  414. package/core/server/api/v3/tags-public.js +0 -71
  415. package/core/server/api/v3/tags.js +0 -159
  416. package/core/server/api/v3/themes.js +0 -131
  417. package/core/server/api/v3/users.js +0 -242
  418. package/core/server/api/v3/utils/index.js +0 -34
  419. package/core/server/api/v3/utils/permissions.js +0 -116
  420. package/core/server/api/v3/utils/serializers/index.js +0 -9
  421. package/core/server/api/v3/utils/serializers/input/authors.js +0 -31
  422. package/core/server/api/v3/utils/serializers/input/db.js +0 -20
  423. package/core/server/api/v3/utils/serializers/input/index.js +0 -41
  424. package/core/server/api/v3/utils/serializers/input/integrations.js +0 -33
  425. package/core/server/api/v3/utils/serializers/input/members.js +0 -62
  426. package/core/server/api/v3/utils/serializers/input/pages.js +0 -208
  427. package/core/server/api/v3/utils/serializers/input/posts.js +0 -242
  428. package/core/server/api/v3/utils/serializers/input/settings.js +0 -168
  429. package/core/server/api/v3/utils/serializers/input/tags.js +0 -42
  430. package/core/server/api/v3/utils/serializers/input/users.js +0 -26
  431. package/core/server/api/v3/utils/serializers/input/utils/slug-filter-order.js +0 -18
  432. package/core/server/api/v3/utils/serializers/input/utils/url.js +0 -71
  433. package/core/server/api/v3/utils/serializers/input/webhooks.js +0 -12
  434. package/core/server/api/v3/utils/serializers/output/actions.js +0 -13
  435. package/core/server/api/v3/utils/serializers/output/all.js +0 -25
  436. package/core/server/api/v3/utils/serializers/output/authentication.js +0 -69
  437. package/core/server/api/v3/utils/serializers/output/authors.js +0 -21
  438. package/core/server/api/v3/utils/serializers/output/config.js +0 -25
  439. package/core/server/api/v3/utils/serializers/output/db.js +0 -40
  440. package/core/server/api/v3/utils/serializers/output/email-preview.js +0 -7
  441. package/core/server/api/v3/utils/serializers/output/emails.js +0 -13
  442. package/core/server/api/v3/utils/serializers/output/identities.js +0 -7
  443. package/core/server/api/v3/utils/serializers/output/images.js +0 -19
  444. package/core/server/api/v3/utils/serializers/output/index.js +0 -135
  445. package/core/server/api/v3/utils/serializers/output/integrations.js +0 -35
  446. package/core/server/api/v3/utils/serializers/output/invites.js +0 -24
  447. package/core/server/api/v3/utils/serializers/output/labels.js +0 -25
  448. package/core/server/api/v3/utils/serializers/output/mail.js +0 -19
  449. package/core/server/api/v3/utils/serializers/output/member-signin_urls.js +0 -7
  450. package/core/server/api/v3/utils/serializers/output/members.js +0 -228
  451. package/core/server/api/v3/utils/serializers/output/notifications.js +0 -29
  452. package/core/server/api/v3/utils/serializers/output/oembed.js +0 -8
  453. package/core/server/api/v3/utils/serializers/output/pages.js +0 -26
  454. package/core/server/api/v3/utils/serializers/output/posts.js +0 -26
  455. package/core/server/api/v3/utils/serializers/output/preview.js +0 -10
  456. package/core/server/api/v3/utils/serializers/output/redirects.js +0 -5
  457. package/core/server/api/v3/utils/serializers/output/roles.js +0 -29
  458. package/core/server/api/v3/utils/serializers/output/schedules.js +0 -5
  459. package/core/server/api/v3/utils/serializers/output/settings.js +0 -65
  460. package/core/server/api/v3/utils/serializers/output/site.js +0 -19
  461. package/core/server/api/v3/utils/serializers/output/slugs.js +0 -11
  462. package/core/server/api/v3/utils/serializers/output/snippets.js +0 -97
  463. package/core/server/api/v3/utils/serializers/output/tags.js +0 -25
  464. package/core/server/api/v3/utils/serializers/output/themes.js +0 -25
  465. package/core/server/api/v3/utils/serializers/output/users.js +0 -74
  466. package/core/server/api/v3/utils/serializers/output/utils/clean.js +0 -166
  467. package/core/server/api/v3/utils/serializers/output/utils/date.js +0 -21
  468. package/core/server/api/v3/utils/serializers/output/utils/extra-attrs.js +0 -174
  469. package/core/server/api/v3/utils/serializers/output/utils/mapper.js +0 -197
  470. package/core/server/api/v3/utils/serializers/output/utils/post-gating.js +0 -39
  471. package/core/server/api/v3/utils/serializers/output/utils/settings-type-group-mapper.js +0 -24
  472. package/core/server/api/v3/utils/serializers/output/utils/url.js +0 -67
  473. package/core/server/api/v3/utils/serializers/output/webhooks.js +0 -15
  474. package/core/server/api/v3/utils/validators/index.js +0 -9
  475. package/core/server/api/v3/utils/validators/input/images.js +0 -85
  476. package/core/server/api/v3/utils/validators/input/index.js +0 -61
  477. package/core/server/api/v3/utils/validators/input/invitations.js +0 -49
  478. package/core/server/api/v3/utils/validators/input/invites.js +0 -21
  479. package/core/server/api/v3/utils/validators/input/labels.js +0 -6
  480. package/core/server/api/v3/utils/validators/input/members.js +0 -6
  481. package/core/server/api/v3/utils/validators/input/oembed.js +0 -17
  482. package/core/server/api/v3/utils/validators/input/pages.js +0 -46
  483. package/core/server/api/v3/utils/validators/input/passwordreset.js +0 -36
  484. package/core/server/api/v3/utils/validators/input/posts.js +0 -46
  485. package/core/server/api/v3/utils/validators/input/settings.js +0 -89
  486. package/core/server/api/v3/utils/validators/input/setup.js +0 -17
  487. package/core/server/api/v3/utils/validators/input/snippets.js +0 -6
  488. package/core/server/api/v3/utils/validators/input/tags.js +0 -6
  489. package/core/server/api/v3/utils/validators/input/users.js +0 -22
  490. package/core/server/api/v3/utils/validators/input/webhooks.js +0 -27
  491. package/core/server/api/v3/utils/validators/output/index.js +0 -1
  492. package/core/server/api/v3/utils/validators/utils/json-schema.js +0 -17
  493. package/core/server/api/v3/webhooks.js +0 -130
  494. package/core/server/data/migrations/utils.js +0 -571
  495. package/core/server/data/migrations/versions/1.13/1-custom-template-post.js +0 -7
  496. package/core/server/data/migrations/versions/1.13/2-theme-permissions.js +0 -58
  497. package/core/server/data/migrations/versions/1.18/1-add-webhooks-table.js +0 -2
  498. package/core/server/data/migrations/versions/1.19/1-webhook-permissions.js +0 -31
  499. package/core/server/data/migrations/versions/1.20/1-remove-settings-keys.js +0 -65
  500. package/core/server/data/migrations/versions/1.21/1-add-contributor-role.js +0 -58
  501. package/core/server/data/migrations/versions/1.22/1-multiple-authors-DDL.js +0 -2
  502. package/core/server/data/migrations/versions/1.22/1-multiple-authors-DML.js +0 -63
  503. package/core/server/data/migrations/versions/1.25/1-update-koenig-beta-html.js +0 -70
  504. package/core/server/data/migrations/versions/1.25/2-demo-post.js +0 -55
  505. package/core/server/data/migrations/versions/1.3/1-post-excerpt.js +0 -7
  506. package/core/server/data/migrations/versions/1.4/1-codeinjection-post.js +0 -14
  507. package/core/server/data/migrations/versions/1.5/1-og-twitter-post.js +0 -34
  508. package/core/server/data/migrations/versions/1.7/1-add-backup-client.js +0 -10
  509. package/core/server/data/migrations/versions/1.9/1-add-permissions-redirect.js +0 -23
  510. package/core/server/data/migrations/versions/2.0/1-rename-amp-column.js +0 -44
  511. package/core/server/data/migrations/versions/2.0/2-update-posts.js +0 -7
  512. package/core/server/data/migrations/versions/2.0/3-remove-koenig-labs.js +0 -42
  513. package/core/server/data/migrations/versions/2.0/4-permalink-setting.js +0 -85
  514. package/core/server/data/migrations/versions/2.0/5-remove-demo-post.js +0 -85
  515. package/core/server/data/migrations/versions/2.0/6-replace-fixture-posts.js +0 -10
  516. package/core/server/data/migrations/versions/2.13/1-remove-empty-strings.js +0 -5
  517. package/core/server/data/migrations/versions/2.14/1-add-actions-table.js +0 -2
  518. package/core/server/data/migrations/versions/2.14/2-add-actions-permissions.js +0 -12
  519. package/core/server/data/migrations/versions/2.15/1-add-type-column-to-integrations.js +0 -8
  520. package/core/server/data/migrations/versions/2.15/2-insert-zapier-integration.js +0 -69
  521. package/core/server/data/migrations/versions/2.16/1-add-members-perrmissions.js +0 -1
  522. package/core/server/data/migrations/versions/2.17/1-normalize-settings.js +0 -74
  523. package/core/server/data/migrations/versions/2.17/2-posts-add-canonical-url.js +0 -7
  524. package/core/server/data/migrations/versions/2.18/1-restore-settings-from-backup.js +0 -134
  525. package/core/server/data/migrations/versions/2.2/1-add-sessions-table.js +0 -2
  526. package/core/server/data/migrations/versions/2.2/2-add-integrations-and-api-key-tables.js +0 -6
  527. package/core/server/data/migrations/versions/2.2/3-insert-admin-integration-role.js +0 -83
  528. package/core/server/data/migrations/versions/2.2/4-insert-integration-and-api-key-permissions.js +0 -77
  529. package/core/server/data/migrations/versions/2.2/5-add-mobiledoc-revisions-table.js +0 -2
  530. package/core/server/data/migrations/versions/2.21/1-update-editor-permissions.js +0 -28
  531. package/core/server/data/migrations/versions/2.22/1-add-member-permissions-to-roles.js +0 -47
  532. package/core/server/data/migrations/versions/2.27/1-insert-ghost-db-backup-role.js +0 -83
  533. package/core/server/data/migrations/versions/2.27/2-insert-db-backup-integration.js +0 -69
  534. package/core/server/data/migrations/versions/2.27/3-add-subdirectory-to-relative-canonical-urls.js +0 -100
  535. package/core/server/data/migrations/versions/2.28/1-add-db-backup-content-permission.js +0 -9
  536. package/core/server/data/migrations/versions/2.28/2-add-db-backup-content-permission-to-roles.js +0 -15
  537. package/core/server/data/migrations/versions/2.28/3-insert-ghost-scheduler-role.js +0 -84
  538. package/core/server/data/migrations/versions/2.28/4-insert-scheduler-integration.js +0 -69
  539. package/core/server/data/migrations/versions/2.28/5-add-scheduler-permission-to-roles.js +0 -23
  540. package/core/server/data/migrations/versions/2.28/6-add-type-column.js +0 -6
  541. package/core/server/data/migrations/versions/2.28/7-populate-type-column.js +0 -6
  542. package/core/server/data/migrations/versions/2.28/8-remove-page-column.js +0 -6
  543. package/core/server/data/migrations/versions/2.29/1-add-post-page-column.js +0 -20
  544. package/core/server/data/migrations/versions/2.29/2-populate-post-page-column.js +0 -98
  545. package/core/server/data/migrations/versions/2.29/3-remove-page-type-column.js +0 -15
  546. package/core/server/data/migrations/versions/2.3/1-add-webhook-columns.js +0 -45
  547. package/core/server/data/migrations/versions/2.3/2-add-webhook-edit-permission.js +0 -9
  548. package/core/server/data/migrations/versions/2.31/1-remove-name-and-password-from-members-table.js +0 -15
  549. package/core/server/data/migrations/versions/2.32/01-add-members-stripe-customers-table.js +0 -4
  550. package/core/server/data/migrations/versions/2.32/02-add-name-to-members-table.js +0 -7
  551. package/core/server/data/migrations/versions/2.33/01-correct-members-stripe-customers-table.js +0 -37
  552. package/core/server/data/migrations/versions/2.34/01-add-stripe-customers-subscriptions-table.js +0 -2
  553. package/core/server/data/migrations/versions/2.34/02-add-email-to-members-stripe-customers-table.js +0 -7
  554. package/core/server/data/migrations/versions/2.34/03-add-name-to-members-stripe-customers-table.js +0 -7
  555. package/core/server/data/migrations/versions/2.35/01-add-note-to-members-table.js +0 -7
  556. package/core/server/data/migrations/versions/2.37/01-add-self-signup-and-from address-to-members-settings.js +0 -67
  557. package/core/server/data/migrations/versions/2.6/1-add-webhook-permission-roles.js +0 -31
  558. package/core/server/data/migrations/versions/2.8/1-add-members-table.js +0 -2
  559. package/core/server/data/migrations/versions/3.0/01-remove-user-ghost-auth-columns.js +0 -14
  560. package/core/server/data/migrations/versions/3.0/02-drop-token-auth-tables.js +0 -31
  561. package/core/server/data/migrations/versions/3.0/03-drop-client-auth-tables.js +0 -35
  562. package/core/server/data/migrations/versions/3.0/04-add-posts-meta-table.js +0 -2
  563. package/core/server/data/migrations/versions/3.0/05-populate-posts-meta-table.js +0 -83
  564. package/core/server/data/migrations/versions/3.0/06-remove-posts-meta-columns.js +0 -44
  565. package/core/server/data/migrations/versions/3.0/07-add-posts-type-column.js +0 -8
  566. package/core/server/data/migrations/versions/3.0/08-populate-posts-type-column.js +0 -94
  567. package/core/server/data/migrations/versions/3.0/09-remove-posts-page-column.js +0 -7
  568. package/core/server/data/migrations/versions/3.0/10-remove-empty-strings.js +0 -81
  569. package/core/server/data/migrations/versions/3.0/11-update-posts-html.js +0 -7
  570. package/core/server/data/migrations/versions/3.0/12-populate-members-table-from-subscribers.js +0 -54
  571. package/core/server/data/migrations/versions/3.0/13-drop-subscribers-table.js +0 -34
  572. package/core/server/data/migrations/versions/3.0/14-remove-subscribers-flag.js +0 -24
  573. package/core/server/data/migrations/versions/3.1/01-add-send-email-when-published-to-posts.js +0 -7
  574. package/core/server/data/migrations/versions/3.1/02-add-email-subject-to-posts-meta.js +0 -7
  575. package/core/server/data/migrations/versions/3.1/03-add-email-preview-permissions.js +0 -18
  576. package/core/server/data/migrations/versions/3.1/04-add-subscribed-flag-to-members.js +0 -7
  577. package/core/server/data/migrations/versions/3.1/05-add-emails-table.js +0 -2
  578. package/core/server/data/migrations/versions/3.1/06-add-email-permissions.js +0 -15
  579. package/core/server/data/migrations/versions/3.1/07-add-uuid-field-to-members.js +0 -8
  580. package/core/server/data/migrations/versions/3.1/08-add-uuid-values-to-members.js +0 -23
  581. package/core/server/data/migrations/versions/3.1/09-add-further-email-permissions.js +0 -25
  582. package/core/server/data/migrations/versions/3.1/10-add-email-error-data-column.js +0 -8
  583. package/core/server/data/migrations/versions/3.11/01-remove-broken-complimentary-plan-from-members-settings.js +0 -68
  584. package/core/server/data/migrations/versions/3.12/01-add-identity-permission.js +0 -7
  585. package/core/server/data/migrations/versions/3.12/02-remove-legacy-is-paid-flag-from-settings.js +0 -93
  586. package/core/server/data/migrations/versions/3.18/01-add-email-preview-permissions-to-roles.js +0 -39
  587. package/core/server/data/migrations/versions/3.18/02-add-members_stripe_connect-auth-permissions.js +0 -7
  588. package/core/server/data/migrations/versions/3.19/01-update-member-from-email-address.js +0 -91
  589. package/core/server/data/migrations/versions/3.2/01-add-cancel-at-period-end-to-subscriptions.js +0 -7
  590. package/core/server/data/migrations/versions/3.22/01-removed-legacy-values-from-settings-table.js +0 -65
  591. package/core/server/data/migrations/versions/3.22/02-settings-key-renames.js +0 -90
  592. package/core/server/data/migrations/versions/3.22/03-add-group-and-flags-to-settings.js +0 -15
  593. package/core/server/data/migrations/versions/3.22/04-populate-settings-groups-and-flags.js +0 -194
  594. package/core/server/data/migrations/versions/3.22/05-migrate-members-subscription-settings.js +0 -182
  595. package/core/server/data/migrations/versions/3.22/06-migrate-stripe-connect-settings.js +0 -132
  596. package/core/server/data/migrations/versions/3.22/07-update-type-for-settings.js +0 -137
  597. package/core/server/data/migrations/versions/3.23/01-migrate-bulk-email-settings.js +0 -65
  598. package/core/server/data/migrations/versions/3.23/02-remove-bulk-email-settings.js +0 -48
  599. package/core/server/data/migrations/versions/3.23/03-update-portal-button-setting.js +0 -24
  600. package/core/server/data/migrations/versions/3.23/04-add-meta-columns-to-tags-table.js +0 -54
  601. package/core/server/data/migrations/versions/3.24/01-populate-group-for-new-portal-settings.js +0 -38
  602. package/core/server/data/migrations/versions/3.25/01-add-members-stripe-webhook-settings.js +0 -22
  603. package/core/server/data/migrations/versions/3.26/01-add-amp-gtag-id-setting.js +0 -20
  604. package/core/server/data/migrations/versions/3.29/01-remove-duplicate-subscriptions.js +0 -53
  605. package/core/server/data/migrations/versions/3.29/02-remove-duplicate-customers.js +0 -53
  606. package/core/server/data/migrations/versions/3.29/03-remove-orphaned-customers.js +0 -35
  607. package/core/server/data/migrations/versions/3.29/04-remove-orphaned-subscriptions.js +0 -35
  608. package/core/server/data/migrations/versions/3.29/05-add-member-constraints.js +0 -177
  609. package/core/server/data/migrations/versions/3.30/01-add-member-signin-url-permission-roles.js +0 -8
  610. package/core/server/data/migrations/versions/3.32/01-add-member-support-address-setting.js +0 -27
  611. package/core/server/data/migrations/versions/3.32/02-add-member-reply-address-setting.js +0 -20
  612. package/core/server/data/migrations/versions/3.32/03-add-routes-hash-setting.js +0 -20
  613. package/core/server/data/migrations/versions/3.33/01-add-email-recipients-tables.js +0 -8
  614. package/core/server/data/migrations/versions/3.34/01-add-tokens-table.js +0 -2
  615. package/core/server/data/migrations/versions/3.35/01-add-address-columns-to-emails-table.js +0 -14
  616. package/core/server/data/migrations/versions/3.36/01-add-snippets-table.js +0 -2
  617. package/core/server/data/migrations/versions/3.36/02-add-snippets-permissions.js +0 -56
  618. package/core/server/data/migrations/versions/3.37/01-update-portal-button-setting.js +0 -30
  619. package/core/server/data/migrations/versions/3.38/01-add-email-recipient-filter-column.js +0 -8
  620. package/core/server/data/migrations/versions/3.38/02-populate-email-recipient-filter-column.js +0 -34
  621. package/core/server/data/migrations/versions/3.38/03-add-recipient-filter-column.js +0 -8
  622. package/core/server/data/migrations/versions/3.38/04-populate-recipient-filter-column.js +0 -49
  623. package/core/server/data/migrations/versions/3.38/05-add-emails-track-opens-column.js +0 -7
  624. package/core/server/data/migrations/versions/3.38/06-add-newsletter-settings.js +0 -16
  625. package/core/server/data/migrations/versions/3.38/07-migrate-newsletter-settings-from-config.js +0 -48
  626. package/core/server/data/migrations/versions/3.38/08-repopulate-send-email-when-published-down-migration.js +0 -25
  627. package/core/server/data/migrations/versions/3.38/09-remove-send-email-when-published-column.js +0 -7
  628. package/core/server/data/migrations/versions/3.39/01-add-members-signup-redirect-settings.js +0 -16
  629. package/core/server/data/migrations/versions/3.39/02-add-user-id-to-api-keys-table.js +0 -7
  630. package/core/server/data/migrations/versions/3.39/03-add-email-track-opens-setting.js +0 -16
  631. package/core/server/data/migrations/versions/3.39/04-add-cancellation-reason-column.js +0 -7
  632. package/core/server/data/migrations/versions/3.39/05-remove-unused-columns-on-emails.js +0 -14
  633. package/core/server/data/migrations/versions/3.39/06-add-email-recipient-index.js +0 -58
  634. package/core/server/data/migrations/versions/3.39/07-add-email-recipients-event-timestamps.js +0 -19
  635. package/core/server/data/migrations/versions/3.39/08-add-email-stats-columns.js +0 -22
  636. package/core/server/data/migrations/versions/3.40/01-add-members-email-open-rate-column.js +0 -8
  637. package/core/server/data/migrations/versions/3.40/02-add members-email-aggregation-columns.js +0 -16
  638. package/core/server/data/migrations/versions/3.40/03-populate-members-email-counts.js +0 -15
  639. package/core/server/data/migrations/versions/3.41/01-add-firstpromoter-settings.js +0 -16
  640. package/core/server/data/migrations/versions/3.6/1-add-labels-table.js +0 -2
  641. package/core/server/data/migrations/versions/3.6/2-add-members-labels-table.js +0 -2
  642. package/core/server/data/migrations/versions/3.6/3-add-labels-permissions.js +0 -47
  643. package/core/server/data/migrations/versions/3.7/01-fix-incorrect-member-labels-foreign-keys.js +0 -46
  644. package/core/server/data/migrations/versions/3.8/01-add-geolocation-to-members.js +0 -7
  645. package/core/server/data/migrations/versions/3.9/01-add-member-sigin-url-permissions.js +0 -7
  646. package/core/server/services/mail/utils.js +0 -34
  647. package/core/server/services/url/configs/canary.js +0 -143
  648. package/core/server/services/url/configs/v3.js +0 -141
  649. package/core/server/services/url/configs/v4.js +0 -143
  650. package/core/server/web/api/v2/admin/app.js +0 -43
  651. package/core/server/web/api/v2/admin/middleware.js +0 -85
  652. package/core/server/web/api/v2/admin/routes.js +0 -200
  653. package/core/server/web/api/v2/content/app.js +0 -38
  654. package/core/server/web/api/v2/content/middleware.js +0 -23
  655. package/core/server/web/api/v2/content/routes.js +0 -37
  656. package/core/server/web/api/v3/admin/app.js +0 -43
  657. package/core/server/web/api/v3/admin/middleware.js +0 -89
  658. package/core/server/web/api/v3/admin/routes.js +0 -267
  659. package/core/server/web/api/v3/content/app.js +0 -38
  660. package/core/server/web/api/v3/content/middleware.js +0 -23
  661. package/core/server/web/api/v3/content/routes.js +0 -37
  662. package/core/server/web/oauth/app.js +0 -153
  663. package/core/server/web/oauth/index.js +0 -1
@@ -3,10 +3,11 @@ const template = require('./template');
3
3
  const settingsCache = require('../../../shared/settings-cache');
4
4
  const urlUtils = require('../../../shared/url-utils');
5
5
  const moment = require('moment-timezone');
6
- const api = require('../../api');
6
+ const api = require('../../api').endpoints;
7
+ const apiShared = require('../../api').shared;
7
8
  const {URL} = require('url');
8
9
  const mobiledocLib = require('../../lib/mobiledoc');
9
- const htmlToText = require('html-to-text');
10
+ const htmlToPlaintext = require('../../../shared/html-to-plaintext');
10
11
  const {isUnsplashImage, isLocalContentImage} = require('@tryghost/kg-default-cards/lib/utils');
11
12
  const {textColorForBackgroundColor, darkenToContrastThreshold} = require('@tryghost/color-utils');
12
13
  const logging = require('@tryghost/logging');
@@ -48,29 +49,16 @@ const getSite = () => {
48
49
  });
49
50
  };
50
51
 
51
- const htmlToPlaintext = (html) => {
52
- // same options as used in Post model for generating plaintext but without `wordwrap: 80`
53
- // to avoid replacement strings being split across lines and for mail clients to handle
54
- // word wrapping based on user preferences
55
- return htmlToText.fromString(html, {
56
- wordwrap: false,
57
- ignoreImage: true,
58
- hideLinkHrefIfSameAsText: true,
59
- preserveNewlines: true,
60
- returnDomByDefault: true,
61
- uppercaseHeadings: false
62
- });
63
- };
64
-
65
52
  /**
66
53
  * createUnsubscribeUrl
67
54
  *
68
- * Takes a member uuid and returns the url that should be used to unsubscribe
55
+ * Takes a member and newsletter uuid. Returns the url that should be used to unsubscribe
69
56
  * In case of no member uuid, generates the preview unsubscribe url - `?preview=1`
70
57
  *
71
- * @param {string} uuid
58
+ * @param {string} uuid post uuid
59
+ * @param {string} newsletterUuid newsletter uuid
72
60
  */
73
- const createUnsubscribeUrl = (uuid) => {
61
+ const createUnsubscribeUrl = (uuid, newsletterUuid) => {
74
62
  const siteUrl = urlUtils.getSiteUrl();
75
63
  const unsubscribeUrl = new URL(siteUrl);
76
64
  unsubscribeUrl.pathname = `${unsubscribeUrl.pathname}/unsubscribe/`.replace('//', '/');
@@ -79,21 +67,23 @@ const createUnsubscribeUrl = (uuid) => {
79
67
  } else {
80
68
  unsubscribeUrl.searchParams.set('preview', '1');
81
69
  }
70
+ if (newsletterUuid) {
71
+ unsubscribeUrl.searchParams.set('newsletter', newsletterUuid);
72
+ }
82
73
 
83
74
  return unsubscribeUrl.href;
84
75
  };
85
76
 
86
- // NOTE: serialization is needed to make sure we are using current API and do post transformations
87
- // such as image URL transformation from relative to absolute
88
- const serializePostModel = async (model, apiVersion = 'v4') => {
77
+ // NOTE: serialization is needed to make sure we do post transformations such as image URL transformation from relative to absolute
78
+ const serializePostModel = async (model) => {
89
79
  // fetch mobiledoc rather than html and plaintext so we can render email-specific contents
90
80
  const frame = {options: {context: {user: true}, formats: 'mobiledoc'}};
91
81
  const docName = 'posts';
92
82
 
93
- await api.shared
83
+ await apiShared
94
84
  .serializers
95
85
  .handle
96
- .output(model, {docName: docName, method: 'read'}, api[apiVersion].serializers.output, frame);
86
+ .output(model, {docName: docName, method: 'read'}, api.serializers.output, frame);
97
87
 
98
88
  return frame.response[docName][0];
99
89
  };
@@ -222,8 +212,8 @@ const getTemplateSettings = async (newsletter) => {
222
212
  return templateSettings;
223
213
  };
224
214
 
225
- const serialize = async (postModel, newsletter, options = {isBrowserPreview: false, apiVersion: 'v4'}) => {
226
- const post = await serializePostModel(postModel, options.apiVersion);
215
+ const serialize = async (postModel, newsletter, options = {isBrowserPreview: false}) => {
216
+ const post = await serializePostModel(postModel);
227
217
 
228
218
  const timezone = settingsCache.get('timezone');
229
219
  const momentDate = post.published_at ? moment(post.published_at) : moment();
@@ -258,7 +248,7 @@ const serialize = async (postModel, newsletter, options = {isBrowserPreview: fal
258
248
  `).remove();
259
249
  post.html = _cheerio('body').html();
260
250
 
261
- post.plaintext = htmlToPlaintext(post.html);
251
+ post.plaintext = htmlToPlaintext.email(post.html);
262
252
 
263
253
  // Outlook will render feature images at full-size breaking the layout.
264
254
  // Content images fix this by rendering max 600px images - do the same for feature image here
@@ -331,7 +321,7 @@ function renderEmailForSegment(email, memberSegment) {
331
321
  });
332
322
 
333
323
  result.html = formatHtmlForEmail($.html());
334
- result.plaintext = htmlToPlaintext(result.html);
324
+ result.plaintext = htmlToPlaintext.email(result.html);
335
325
 
336
326
  return result;
337
327
  }
@@ -170,9 +170,6 @@ function createApiInstance(config) {
170
170
  }
171
171
  }
172
172
  },
173
- paymentConfig: {
174
- stripe: config.getStripePaymentConfig()
175
- },
176
173
  models: {
177
174
  EmailRecipient: models.EmailRecipient,
178
175
  StripeCustomer: models.MemberStripeCustomer,
@@ -53,36 +53,6 @@ class MembersConfigProvider {
53
53
  return this.getEmailSupportAddress() || this.getEmailFromAddress();
54
54
  }
55
55
 
56
- getPublicPlans() {
57
- const defaultPriceData = {
58
- monthly: 0,
59
- yearly: 0,
60
- currency: 'USD'
61
- };
62
-
63
- try {
64
- const plans = this._settingsCache.get('stripe_plans') || [];
65
-
66
- const priceData = plans.reduce((prices, plan) => {
67
- const numberAmount = 0 + plan.amount;
68
- const dollarAmount = numberAmount ? Math.round(numberAmount / 100) : 0;
69
- return Object.assign(prices, {
70
- [plan.name.toLowerCase()]: dollarAmount
71
- });
72
- }, {});
73
-
74
- priceData.currency = plans[0].currency || 'USD';
75
-
76
- if (Number.isInteger(priceData.monthly) && Number.isInteger(priceData.yearly)) {
77
- return priceData;
78
- }
79
-
80
- return defaultPriceData;
81
- } catch (err) {
82
- return defaultPriceData;
83
- }
84
- }
85
-
86
56
  /**
87
57
  * @param {'direct' | 'connect'} type - The "type" of keys to fetch from settings
88
58
  * @returns {{publicKey: string, secretKey: string} | null}
@@ -128,25 +98,6 @@ class MembersConfigProvider {
128
98
  return this.getActiveStripeKeys() !== null;
129
99
  }
130
100
 
131
- getStripePaymentConfig() {
132
- if (!this.isStripeConnected()) {
133
- return null;
134
- }
135
-
136
- const stripeApiKeys = this.getActiveStripeKeys();
137
-
138
- if (!stripeApiKeys) {
139
- return null;
140
- }
141
-
142
- return {
143
- product: {
144
- name: this._settingsCache.get('stripe_product_name')
145
- },
146
- plans: this._settingsCache.get('stripe_plans') || []
147
- };
148
- }
149
-
150
101
  getAuthSecret() {
151
102
  const hexSecret = this._settingsCache.get('members_email_auth_secret');
152
103
  if (!hexSecret) {
@@ -22,7 +22,7 @@ module.exports = async function (options) {
22
22
  // Include mongoTransformer to apply subscribed:{true|false} => newsletter relation mapping
23
23
  Object.assign(filterOptions, _.pick(options, ['filter', 'search', 'mongoTransformer']));
24
24
  }
25
-
25
+
26
26
  const memberRows = await models.Member.getFilteredCollectionQuery(filterOptions)
27
27
  .select('members.id')
28
28
  .distinct();
@@ -42,7 +42,7 @@ module.exports = async function (options) {
42
42
  END) as subscribed
43
43
  `))
44
44
  .select(knex.raw(`
45
- (SELECT GROUP_CONCAT(product_id) FROM members_products f WHERE f.member_id = members.id) as products
45
+ (SELECT GROUP_CONCAT(product_id) FROM members_products f WHERE f.member_id = members.id) as tiers
46
46
  `))
47
47
  .select(knex.raw(`
48
48
  (SELECT GROUP_CONCAT(label_id) FROM members_labels f WHERE f.member_id = members.id) as labels
@@ -57,14 +57,14 @@ module.exports = async function (options) {
57
57
 
58
58
  const rows = await query;
59
59
  for (const row of rows) {
60
- const productIds = row.products ? row.products.split(',') : [];
61
- const products = productIds.map((id) => {
62
- const product = allProducts.find(p => p.id === id);
60
+ const tierIds = row.tiers ? row.tiers.split(',') : [];
61
+ const tiers = tierIds.map((id) => {
62
+ const tier = allProducts.find(p => p.id === id);
63
63
  return {
64
- name: product.get('name')
64
+ name: tier.get('name')
65
65
  };
66
66
  });
67
- row.products = products;
67
+ row.tiers = tiers;
68
68
 
69
69
  const labelIds = row.labels ? row.labels.split(',') : [];
70
70
  const labels = labelIds.map((id) => {
@@ -2,14 +2,8 @@ const _ = require('lodash');
2
2
  const logging = require('@tryghost/logging');
3
3
  const membersService = require('./service');
4
4
  const models = require('../../models');
5
- const offersService = require('../offers/service');
6
5
  const urlUtils = require('../../../shared/url-utils');
7
- const ghostVersion = require('@tryghost/version');
8
- const settingsCache = require('../../../shared/settings-cache');
9
6
  const {formattedMemberResponse} = require('./utils');
10
- const labsService = require('../../../shared/labs');
11
- const config = require('../../../shared/config');
12
- const newslettersService = require('../newsletters');
13
7
 
14
8
  // @TODO: This piece of middleware actually belongs to the frontend, not to the member app
15
9
  // Need to figure a way to separate these things (e.g. frontend actually talks to members API)
@@ -61,14 +55,6 @@ const getMemberData = async function (req, res) {
61
55
  }
62
56
  };
63
57
 
64
- const getOfferData = async function (req, res) {
65
- const offerId = req.params.id;
66
- const offer = await offersService.api.getOffer({id: offerId});
67
- return res.json({
68
- offers: [offer]
69
- });
70
- };
71
-
72
58
  const getMemberNewsletters = async function (req, res) {
73
59
  try {
74
60
  const memberUuid = req.query.uuid;
@@ -149,114 +135,6 @@ const updateMemberData = async function (req, res) {
149
135
  }
150
136
  };
151
137
 
152
- const getPortalProductPrices = async function () {
153
- const page = await membersService.api.productRepository.list({
154
- withRelated: ['monthlyPrice', 'yearlyPrice', 'benefits']
155
- });
156
-
157
- const products = page.data.map((productModel) => {
158
- const product = productModel.toJSON();
159
- const productPrices = [];
160
- if (product.monthlyPrice) {
161
- productPrices.push(product.monthlyPrice);
162
- }
163
- if (product.yearlyPrice) {
164
- productPrices.push(product.yearlyPrice);
165
- }
166
- return {
167
- id: product.id,
168
- name: product.name,
169
- description: product.description || '',
170
- monthlyPrice: product.monthlyPrice,
171
- yearlyPrice: product.yearlyPrice,
172
- benefits: product.benefits,
173
- active: product.active,
174
- type: product.type,
175
- visibility: product.visibility,
176
- prices: productPrices
177
- };
178
- }).filter((product) => {
179
- return !!product.active;
180
- });
181
- const defaultProduct = products.find((product) => {
182
- return product.type === 'paid';
183
- });
184
- const defaultPrices = defaultProduct ? defaultProduct.prices : [];
185
- let portalProducts = defaultProduct ? [defaultProduct] : [];
186
- if (labsService.isSet('multipleProducts')) {
187
- portalProducts = products;
188
- }
189
-
190
- return {
191
- prices: defaultPrices,
192
- products: portalProducts
193
- };
194
- };
195
-
196
- const getSiteNewsletters = async function () {
197
- try {
198
- return await newslettersService.browse({filter: 'status:active', limit: 'all'});
199
- } catch (err) {
200
- logging.warn('Failed to fetch site newsletters');
201
- logging.warn(err.message);
202
- return [];
203
- }
204
- };
205
-
206
- const getMemberSiteData = async function (req, res) {
207
- const isStripeConfigured = membersService.config.isStripeConnected();
208
- const domain = urlUtils.urlFor('home', true).match(new RegExp('^https?://([^/:?#]+)(?:[/:?#]|$)', 'i'));
209
- const firstpromoterId = settingsCache.get('firstpromoter') ? settingsCache.get('firstpromoter_id') : '';
210
- const blogDomain = domain && domain[1];
211
- let supportAddress = settingsCache.get('members_support_address') || 'noreply';
212
- if (!supportAddress.includes('@')) {
213
- supportAddress = `${supportAddress}@${blogDomain}`;
214
- }
215
- const {products = [], prices = []} = await getPortalProductPrices() || {};
216
- const portalVersion = config.get('portal:version');
217
- const newsletters = await getSiteNewsletters();
218
- const response = {
219
- title: settingsCache.get('title'),
220
- description: settingsCache.get('description'),
221
- logo: settingsCache.get('logo'),
222
- icon: settingsCache.get('icon'),
223
- accent_color: settingsCache.get('accent_color'),
224
- url: urlUtils.urlFor('home', true),
225
- version: ghostVersion.safe,
226
- portal_version: portalVersion,
227
- free_price_name: settingsCache.get('members_free_price_name'),
228
- free_price_description: settingsCache.get('members_free_price_description'),
229
- allow_self_signup: membersService.config.getAllowSelfSignup(),
230
- members_signup_access: settingsCache.get('members_signup_access'),
231
- is_stripe_configured: isStripeConfigured,
232
- portal_button: settingsCache.get('portal_button'),
233
- portal_name: settingsCache.get('portal_name'),
234
- portal_plans: settingsCache.get('portal_plans'),
235
- portal_button_icon: settingsCache.get('portal_button_icon'),
236
- portal_button_signup_text: settingsCache.get('portal_button_signup_text'),
237
- portal_button_style: settingsCache.get('portal_button_style'),
238
- firstpromoter_id: firstpromoterId,
239
- members_support_address: supportAddress,
240
- prices,
241
- products
242
- };
243
-
244
- if (labsService.isSet('multipleNewsletters')) {
245
- response.newsletters = newsletters;
246
- }
247
-
248
- if (labsService.isSet('multipleProducts')) {
249
- response.portal_products = settingsCache.get('portal_products');
250
- }
251
- if (config.get('portal_sentry') && !config.get('portal_sentry').disabled) {
252
- response.portal_sentry = {
253
- dsn: config.get('portal_sentry').dsn,
254
- env: config.get('env')
255
- };
256
- }
257
- res.json({site: response});
258
- };
259
-
260
138
  const createSessionFromMagicLink = async function (req, res, next) {
261
139
  if (!req.url.includes('token=')) {
262
140
  return next();
@@ -287,18 +165,10 @@ const createSessionFromMagicLink = async function (req, res, next) {
287
165
  })
288
166
  .find(sub => ['active', 'trialing'].includes(sub.status));
289
167
  if (mostRecentActiveSubscription) {
290
- if (labsService.isSet('tierWelcomePages')) {
291
- customRedirect = mostRecentActiveSubscription.tier.welcome_page_url;
292
- } else {
293
- customRedirect = settingsCache.get('members_paid_signup_redirect') || '';
294
- }
168
+ customRedirect = mostRecentActiveSubscription.tier.welcome_page_url;
295
169
  } else {
296
- if (labsService.isSet('tierWelcomePages')) {
297
- const freeTier = await models.Product.findOne({type: 'free'});
298
- customRedirect = freeTier && freeTier.get('welcome_page_url') || '';
299
- } else {
300
- customRedirect = settingsCache.get('members_free_signup_redirect') || '';
301
- }
170
+ const freeTier = await models.Product.findOne({type: 'free'});
171
+ customRedirect = freeTier && freeTier.get('welcome_page_url') || '';
302
172
  }
303
173
 
304
174
  if (customRedirect && customRedirect !== '/') {
@@ -331,9 +201,7 @@ module.exports = {
331
201
  getIdentityToken,
332
202
  getMemberNewsletters,
333
203
  getMemberData,
334
- getOfferData,
335
204
  updateMemberData,
336
205
  updateMemberNewsletters,
337
- getMemberSiteData,
338
206
  deleteSession
339
207
  };
@@ -18,7 +18,6 @@ const jobsService = require('../jobs');
18
18
  const VerificationTrigger = require('@tryghost/verification-trigger');
19
19
  const DomainEvents = require('@tryghost/domain-events');
20
20
  const {LastSeenAtUpdater} = require('@tryghost/members-events-service');
21
- const events = require('../../lib/common/events');
22
21
  const DatabaseInfo = require('@tryghost/database-info');
23
22
 
24
23
  const messages = {
@@ -74,32 +73,6 @@ module.exports = {
74
73
  const createMembersApiInstance = require('./api');
75
74
  const env = config.get('env');
76
75
 
77
- events.on('settings.edited', async function (settingModel) {
78
- if (labsService.isSet('multipleProducts')) {
79
- return;
80
- }
81
-
82
- const key = settingModel.get('key');
83
- const value = settingModel.get('value');
84
-
85
- if (key === 'members_free_signup_redirect') {
86
- try {
87
- await models.Product.forge().query().update('welcome_page_url', value).where('type', 'free');
88
- } catch (err) {
89
- logging.error(err);
90
- }
91
- return;
92
- }
93
- if (key === 'members_paid_signup_redirect') {
94
- try {
95
- await models.Product.forge().query().update('welcome_page_url', value).where('type', 'paid');
96
- } catch (err) {
97
- logging.error(err);
98
- }
99
- return;
100
- }
101
- });
102
-
103
76
  // @TODO Move to stripe service
104
77
  if (env !== 'production') {
105
78
  if (stripeService.api.configured && stripeService.api.mode === 'live') {
@@ -52,7 +52,7 @@ function createSettingsInstance(config) {
52
52
  return updateEmailTemplate({url, email, siteTitle});
53
53
  },
54
54
  getSigninURL(token, type) {
55
- const signinURL = new URL(getApiUrl({version: 'v4', type: 'admin'}));
55
+ const signinURL = new URL(urlUtils.urlFor('api', {type: 'admin'}, true));
56
56
  signinURL.pathname = path.join(signinURL.pathname, '/settings/members/email/');
57
57
  signinURL.searchParams.set('token', token);
58
58
  signinURL.searchParams.set('action', type);
@@ -60,10 +60,6 @@ function createSettingsInstance(config) {
60
60
  }
61
61
  };
62
62
 
63
- const getApiUrl = ({version, type}) => {
64
- return urlUtils.urlFor('api', {version: version, versionType: type}, true);
65
- };
66
-
67
63
  const magicLinkService = new MagicLink({
68
64
  transporter,
69
65
  tokenProvider: new SingleUseTokenProvider(models.SingleUseToken, MAGIC_LINK_TOKEN_VALIDITY),
@@ -73,7 +69,7 @@ function createSettingsInstance(config) {
73
69
  getSubject
74
70
  });
75
71
 
76
- const sendEmailAddressUpdateMagicLink = ({email, type = 'fromAddressUpdate'}) => {
72
+ const sendEmailAddressUpdateMagicLink = ({email, type = 'supportAddressUpdate'}) => {
77
73
  const [,toDomain] = email.split('@');
78
74
  let fromEmail = `noreply@${toDomain}`;
79
75
  if (fromEmail === email) {
@@ -103,9 +99,7 @@ function createSettingsInstance(config) {
103
99
 
104
100
  const getAdminRedirectLink = ({type}) => {
105
101
  const adminUrl = urlUtils.urlFor('admin', true);
106
- if (type === 'fromAddressUpdate') {
107
- return urlUtils.urlJoin(adminUrl, `#/settings/members-email/?${type}=success`);
108
- } else if (type === 'supportAddressUpdate') {
102
+ if (type === 'supportAddressUpdate') {
109
103
  return urlUtils.urlJoin(adminUrl, `#/settings/members/?${type}=success`);
110
104
  } else {
111
105
  return urlUtils.urlJoin(adminUrl, `#/site/`);
@@ -3,6 +3,13 @@ const MagicLink = require('@tryghost/magic-link');
3
3
  const logging = require('@tryghost/logging');
4
4
  const verifyEmailTemplate = require('./emails/verify-email');
5
5
  const debug = require('@tryghost/debug')('services:newsletters');
6
+ const tpl = require('@tryghost/tpl');
7
+ const errors = require('@tryghost/errors');
8
+
9
+ const messages = {
10
+ nameAlreadyExists: 'A newsletter with the same name already exists',
11
+ newsletterNotFound: 'Newsletter not found.'
12
+ };
6
13
 
7
14
  class NewslettersService {
8
15
  /**
@@ -73,6 +80,23 @@ class NewslettersService {
73
80
  });
74
81
  }
75
82
 
83
+ /**
84
+ * @public
85
+ * @param {Object} options data (id, uuid, slug...)
86
+ * @param {Object} [options] options
87
+ * @returns {Promise<object>} JSONified Newsletter models
88
+ */
89
+ async read(data, options = {}) {
90
+ const newsletter = await this.NewsletterModel.findOne(data, options);
91
+
92
+ if (!newsletter) {
93
+ throw new errors.NotFoundError({
94
+ message: tpl(messages.newsletterNotFound)
95
+ });
96
+ }
97
+ return newsletter;
98
+ }
99
+
76
100
  /**
77
101
  * @public
78
102
  * @param {Object} [options] options
@@ -83,11 +107,13 @@ class NewslettersService {
83
107
 
84
108
  return newsletters.toJSON();
85
109
  }
110
+
86
111
  /**
87
112
  * @public
88
113
  * @param {object} attrs model properties
89
114
  * @param {Object} [options] options
90
- * @param {Object} [options] options.transacting
115
+ * @param {boolean} [options.opt_in_existing] Opt in existing members
116
+ * @param {Object} [options.transacting]
91
117
  * @returns {Promise<{object}>} Newsetter Model with verification metadata
92
118
  */
93
119
  async add(attrs, options = {}) {
@@ -99,7 +125,9 @@ class NewslettersService {
99
125
  });
100
126
  }
101
127
 
102
- await this.limitService.errorIfWouldGoOverLimit('newsletters');
128
+ if (!attrs.status || attrs.status === 'active') {
129
+ await this.limitService.errorIfWouldGoOverLimit('newsletters', options.transacting ? {transacting: options.transacting} : {});
130
+ }
103
131
 
104
132
  // remove any email properties that are not allowed to be set without verification
105
133
  const {cleanedAttrs, emailsToVerify} = await this.prepAttrsForEmailVerification(attrs);
@@ -108,8 +136,23 @@ class NewslettersService {
108
136
  const sortOrder = await this.NewsletterModel.getNextAvailableSortOrder(options);
109
137
  cleanedAttrs.sort_order = sortOrder;
110
138
 
111
- // add the model now because we need the ID for sending verification emails
112
- const newsletter = await this.NewsletterModel.add(cleanedAttrs, options);
139
+ let newsletter;
140
+ try {
141
+ // add the model now because we need the ID for sending verification emails
142
+ newsletter = await this.NewsletterModel.add(cleanedAttrs, options);
143
+ } catch (error) {
144
+ if (error.code && error.message.toLowerCase().indexOf('unique') !== -1) {
145
+ throw new errors.ValidationError({
146
+ message: tpl(messages.nameAlreadyExists),
147
+ property: 'name'
148
+ });
149
+ }
150
+
151
+ throw error;
152
+ }
153
+
154
+ // Load relations correctly
155
+ newsletter = await this.NewsletterModel.findOne({id: newsletter.id}, {...options, require: true});
113
156
 
114
157
  // subscribe existing members if opt_in_existing=true
115
158
  if (options.opt_in_existing) {
@@ -135,18 +178,43 @@ class NewslettersService {
135
178
  /**
136
179
  * @public
137
180
  * @param {object} attrs model properties
138
- * @param {Object} [options] options
181
+ * @param {Object} options options
182
+ * @param {string} options.id Newsletter id to edit
183
+ * @param {Object} [options.transacting]
139
184
  * @returns {Promise<{object}>} Newsetter Model with verification metadata
140
185
  */
141
- async edit(attrs, options = {}) {
186
+ async edit(attrs, options) {
187
+ const sharedOptions = _.pick(options, 'transacting');
188
+
142
189
  // fetch newsletter first so we can compare changed emails
143
- const originalNewsletter = await this.NewsletterModel.findOne(options, {require: true});
190
+ const originalNewsletter = await this.NewsletterModel.findOne({id: options.id}, {...sharedOptions, require: true});
144
191
 
145
192
  const {cleanedAttrs, emailsToVerify} = await this.prepAttrsForEmailVerification(attrs, originalNewsletter);
146
193
 
147
- const updatedNewsletter = await this.NewsletterModel.edit(cleanedAttrs, options);
194
+ if (originalNewsletter.get('status') !== 'active' && cleanedAttrs.status === 'active') {
195
+ await this.limitService.errorIfWouldGoOverLimit('newsletters', sharedOptions);
196
+ }
197
+
198
+ let updatedNewsletter;
199
+
200
+ try {
201
+ updatedNewsletter = await this.NewsletterModel.edit(cleanedAttrs, options);
202
+ } catch (error) {
203
+ if (error.code && error.message.toLowerCase().indexOf('unique') !== -1) {
204
+ throw new errors.ValidationError({
205
+ message: tpl(messages.nameAlreadyExists),
206
+ property: 'name'
207
+ });
208
+ }
209
+
210
+ throw error;
211
+ }
148
212
 
149
- return this.respondWithEmailVerification(updatedNewsletter, emailsToVerify);
213
+ // Load relations correctly in the response
214
+ updatedNewsletter = await this.NewsletterModel.findOne({id: updatedNewsletter.id}, {...options, require: true});
215
+
216
+ await this.respondWithEmailVerification(updatedNewsletter, emailsToVerify);
217
+ return updatedNewsletter;
150
218
  }
151
219
 
152
220
  /**
@@ -249,7 +317,7 @@ class NewslettersService {
249
317
 
250
318
  /**
251
319
  * @typedef {object} ILimitService
252
- * @prop {(name: string) => Promise<void>} errorIfWouldGoOverLimit
320
+ * @prop {(name: string, options?: {transacting?: Object}) => Promise<void>} errorIfWouldGoOverLimit
253
321
  **/
254
322
 
255
323
  module.exports = NewslettersService;
@@ -3,7 +3,7 @@ const errors = require('@tryghost/errors');
3
3
  const moment = require('moment');
4
4
  const config = require('../../../shared/config');
5
5
  const urlUtils = require('../../../shared/url-utils');
6
- const api = require('../../api');
6
+ const api = require('../../api').endpoints;
7
7
 
8
8
  const messages = {
9
9
  jobNotFound: 'Job not found.',
@@ -11,15 +11,6 @@ const messages = {
11
11
  };
12
12
 
13
13
  class PostSchedulingService {
14
- /**
15
- *
16
- * @param {Object} options
17
- * @param {String} options.apiVersion - api version
18
- */
19
- constructor({apiVersion}) {
20
- this.api = api[apiVersion];
21
- }
22
-
23
14
  /**
24
15
  * Publishes scheduled resource (a post or a page at the moment of writing)
25
16
  *
@@ -32,7 +23,7 @@ class PostSchedulingService {
32
23
  async publish(resourceType, id, force, options) {
33
24
  const publishAPostBySchedulerToleranceInMinutes = config.get('times').publishAPostBySchedulerToleranceInMinutes;
34
25
 
35
- const result = await this.api[resourceType].read({id}, options);
26
+ const result = await api[resourceType].read({id}, options);
36
27
  const preScheduledResource = result[resourceType][0];
37
28
 
38
29
  const publishedAtMoment = moment(preScheduledResource.published_at);
@@ -51,7 +42,7 @@ class PostSchedulingService {
51
42
  updated_at: moment(preScheduledResource.updated_at).toISOString(true)
52
43
  }];
53
44
 
54
- const editResult = await this.api[resourceType].edit(
45
+ const editResult = await api[resourceType].edit(
55
46
  editedResource,
56
47
  _.pick(options, ['context', 'id', 'transacting', 'forUpdate'])
57
48
  );
@@ -88,13 +79,10 @@ class PostSchedulingService {
88
79
  }
89
80
 
90
81
  /**
91
- * @param {string} apiVersion - API version to use within the service
92
82
  * @returns {PostSchedulingService} instance of the PostsService
93
83
  */
94
- const getPostSchedulingServiceInstance = (apiVersion) => {
95
- return new PostSchedulingService({
96
- apiVersion: apiVersion
97
- });
84
+ const getPostSchedulingServiceInstance = () => {
85
+ return new PostSchedulingService();
98
86
  };
99
87
 
100
88
  module.exports = getPostSchedulingServiceInstance;