ghost 4.48.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (660) 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-08acba9994ea4f9478dfdca2a97b36f1.css +1 -0
  23. package/core/built/assets/{ghost.min-10ba0de3ecb93d63d62bb43ac11c740f.js → ghost.min-75bec566fbea362ed98811fe6d5b6e24.js} +1115 -1185
  24. package/core/built/assets/ghost.min-855c93486d789aa09dbe97f272672bf9.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-14ad7269e0529dd20f61d2989e69fa1e.js} +95 -90
  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 +102 -103
  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/format-response.js +9 -2
  57. package/core/frontend/services/rendering/index.js +0 -4
  58. package/core/frontend/services/rendering/render-entry.js +1 -1
  59. package/core/frontend/services/rendering/templates.js +15 -5
  60. package/core/frontend/services/routing/CollectionRouter.js +2 -2
  61. package/core/frontend/services/routing/EmailRouter.js +2 -2
  62. package/core/frontend/services/routing/ParentRouter.js +1 -1
  63. package/core/frontend/services/routing/PreviewRouter.js +3 -3
  64. package/core/frontend/services/routing/{config/v4.js → config.js} +3 -5
  65. package/core/frontend/services/routing/controllers/channel.js +0 -10
  66. package/core/frontend/services/routing/controllers/collection.js +0 -9
  67. package/core/frontend/services/routing/controllers/email-post.js +2 -7
  68. package/core/frontend/services/routing/controllers/entry.js +1 -3
  69. package/core/frontend/services/routing/controllers/index.js +2 -2
  70. package/core/frontend/services/routing/controllers/{preview.js → previews.js} +3 -8
  71. package/core/frontend/services/routing/controllers/static.js +1 -6
  72. package/core/frontend/services/routing/router-manager.js +38 -20
  73. package/core/frontend/services/rss/generate-feed.js +7 -9
  74. package/core/frontend/services/theme-engine/active.js +0 -8
  75. package/core/frontend/services/theme-engine/config/defaults.json +1 -3
  76. package/core/frontend/services/theme-engine/middleware/index.js +0 -1
  77. package/core/frontend/services/theme-engine/middleware/update-global-template-options.js +0 -69
  78. package/core/frontend/services/theme-engine/middleware/update-local-template-options.js +3 -6
  79. package/core/frontend/web/middleware/static-theme.js +14 -6
  80. package/core/frontend/web/routes.js +9 -9
  81. package/core/frontend/web/site.js +15 -18
  82. package/core/server/adapters/scheduling/post-scheduling/index.js +1 -1
  83. package/core/server/api/README.md +2 -6
  84. package/core/server/api/canary/authentication.js +4 -3
  85. package/core/server/api/canary/{email-preview.js → email-previews.js} +9 -8
  86. package/core/server/api/canary/index.js +14 -18
  87. package/core/server/api/canary/members.js +1 -13
  88. package/core/server/api/{v3/actions.js → canary/newsletters-public.js} +6 -6
  89. package/core/server/api/canary/newsletters.js +1 -13
  90. package/core/server/api/canary/notifications.js +17 -22
  91. package/core/server/api/canary/offers-public.js +28 -0
  92. package/core/server/api/canary/pages.js +1 -1
  93. package/core/server/api/canary/posts.js +4 -8
  94. package/core/server/api/canary/{preview.js → previews.js} +1 -1
  95. package/core/server/api/canary/schedules.js +1 -1
  96. package/core/server/api/canary/session.js +1 -1
  97. package/core/server/api/canary/settings-public.js +3 -1
  98. package/core/server/api/canary/settings.js +28 -16
  99. package/core/server/api/canary/utils/index.js +2 -4
  100. package/core/server/api/canary/utils/serializers/input/index.js +0 -4
  101. package/core/server/api/canary/utils/serializers/input/members.js +46 -17
  102. package/core/server/api/canary/utils/serializers/input/pages.js +0 -17
  103. package/core/server/api/canary/utils/serializers/input/posts.js +1 -28
  104. package/core/server/api/canary/utils/serializers/input/settings.js +61 -142
  105. package/core/server/api/canary/utils/serializers/input/tiers.js +39 -4
  106. package/core/server/api/canary/utils/serializers/output/authentication.js +2 -6
  107. package/core/server/api/canary/utils/serializers/output/index.js +2 -10
  108. package/core/server/api/canary/utils/serializers/output/mappers/index.js +1 -0
  109. package/core/server/api/canary/utils/serializers/output/mappers/newsletters.js +24 -0
  110. package/core/server/api/canary/utils/serializers/output/mappers/pages.js +1 -1
  111. package/core/server/api/canary/utils/serializers/output/mappers/posts.js +9 -7
  112. package/core/server/api/canary/utils/serializers/output/mappers/settings.js +5 -31
  113. package/core/server/api/canary/utils/serializers/output/members.js +18 -3
  114. package/core/server/api/canary/utils/serializers/output/offers.js +9 -1
  115. package/core/server/api/canary/utils/serializers/output/{preview.js → previews.js} +2 -2
  116. package/core/server/api/canary/utils/serializers/output/settings.js +6 -14
  117. package/core/server/api/canary/utils/serializers/output/site.js +0 -1
  118. package/core/server/api/canary/utils/serializers/output/tiers.js +21 -62
  119. package/core/server/api/canary/utils/serializers/output/utils/clean.js +5 -10
  120. package/core/server/api/canary/utils/serializers/output/utils/extra-attrs.js +0 -126
  121. package/core/server/api/canary/utils/serializers/output/utils/post-gating.js +1 -1
  122. package/core/server/api/canary/utils/serializers/output/utils/url.js +0 -5
  123. package/core/server/api/canary/utils/validators/input/index.js +2 -2
  124. package/core/server/api/canary/utils/validators/input/{passwordreset.js → password_reset.js} +2 -2
  125. package/core/server/api/canary/utils/validators/input/settings.js +2 -23
  126. package/core/server/api/canary/utils/validators/utils/json-schema.js +1 -2
  127. package/core/server/api/index.js +1 -7
  128. package/core/server/api/shared/serializers/input/utils/settings-key-group-mapper.js +2 -2
  129. package/core/server/api/shared/serializers/input/utils/settings-key-type-mapper.js +2 -4
  130. package/core/server/data/db/connection.js +0 -13
  131. package/core/server/data/exporter/table-lists.js +0 -3
  132. package/core/server/data/importer/importers/data/base.js +16 -7
  133. package/core/server/data/importer/importers/data/data-importer.js +38 -1
  134. package/core/server/data/importer/importers/data/newsletters.js +45 -0
  135. package/core/server/data/importer/importers/data/posts.js +40 -12
  136. package/core/server/data/importer/importers/data/products.js +68 -0
  137. package/core/server/data/importer/importers/data/settings.js +10 -10
  138. package/core/server/data/importer/importers/data/stripe-prices.js +59 -0
  139. package/core/server/data/importer/importers/data/stripe-products.js +61 -0
  140. package/core/server/data/migrations/utils/constants.js +3 -0
  141. package/core/server/data/migrations/utils/index.js +10 -0
  142. package/core/server/data/migrations/utils/migrations.js +156 -0
  143. package/core/server/data/migrations/utils/permissions.js +291 -0
  144. package/core/server/data/migrations/utils/schema.js +158 -0
  145. package/core/server/data/migrations/utils/settings.js +59 -0
  146. package/core/server/data/migrations/utils/tables.js +94 -0
  147. package/core/server/data/migrations/versions/1.25/01-final-v1.js +2 -0
  148. package/core/server/data/migrations/versions/1.25/02-noop.js +6 -0
  149. package/core/server/data/migrations/versions/2.37/01-final-v2.js +2 -0
  150. package/core/server/data/migrations/versions/3.41/01-final-v3.js +2 -0
  151. package/core/server/data/migrations/versions/4.0/22-solve-orphaned-webhooks.js +3 -9
  152. package/core/server/data/migrations/versions/4.0/23-regenerate-posts-html.js +2 -11
  153. package/core/server/data/migrations/versions/4.11/02-add-email-verification-required-setting.js +1 -1
  154. package/core/server/data/migrations/versions/4.12/02-fix-member-statuses.js +1 -1
  155. package/core/server/data/migrations/versions/4.14/02-fix-free-members-status-events.js +1 -1
  156. package/core/server/data/migrations/versions/4.22/01-add-is-launch-complete-setting.js +1 -1
  157. package/core/server/data/migrations/versions/4.22/02-update-launch-complete-setting-from-user-data.js +1 -1
  158. package/core/server/data/migrations/versions/4.35/2022-02-02-10-38-add-default-content-visibility-tiers-setting.js +1 -1
  159. package/core/server/data/migrations/versions/4.45/2022-04-21-02-55-add-notifications-key-entry-to-settings-table.js +1 -1
  160. package/core/server/data/migrations/versions/4.6/01-remove-comped-status.js +1 -1
  161. package/core/server/data/migrations/versions/4.7/03-add-labs-setting.js +1 -1
  162. package/core/server/data/migrations/versions/4.9/05-fix-missed-mobiledoc-url-transforms.js +1 -1
  163. package/core/server/data/migrations/versions/4.9/06-add-comped-status.js +1 -1
  164. package/core/server/data/migrations/versions/4.9/07-update-comped-members-status-events.js +1 -1
  165. package/core/server/data/migrations/versions/5.0/2022-03-14-12-33-delete-duplicate-offer-redemptions.js +36 -0
  166. package/core/server/data/migrations/versions/5.0/2022-03-28-15-25-backfill-mrr-adjustments-for-offers.js +108 -0
  167. package/core/server/data/migrations/versions/5.0/2022-04-25-10-32-backfill-mrr-for-discounted-subscriptions.js +44 -0
  168. package/core/server/data/migrations/versions/5.0/2022-04-26-15-44-backfill-mrr-events-for-canceled-subscriptions.js +73 -0
  169. package/core/server/data/migrations/versions/5.0/2022-04-27-11-26-backfill-mrr-for-canceled-subscriptions.js +31 -0
  170. package/core/server/data/migrations/versions/5.0/2022-04-28-03-26-remove-author-id-column-from-posts-table.js +7 -0
  171. package/core/server/data/migrations/versions/5.0/2022-05-03-09-39-drop-nullable-subscribe-event-newsletter-id.js +4 -0
  172. package/core/server/data/migrations/versions/5.0/2022-05-04-15-24-map-existing-emails-to-default-newsletter.js +44 -0
  173. package/core/server/data/migrations/versions/5.0/2022-05-05-13-13-migrate-legacy-recipient-filters.js +30 -0
  174. package/core/server/data/migrations/versions/5.0/2022-05-05-13-29-add-newsletters-admin-integration-permission-roles.js +20 -0
  175. package/core/server/data/migrations/versions/5.0/2022-05-05-15-17-drop-oauth-table.js +3 -0
  176. package/core/server/data/migrations/versions/5.0/2022-05-06-08-16-cleanup-client-subscriber-permissions.js +68 -0
  177. package/core/server/data/migrations/versions/5.0/2022-05-06-13-22-add-frontend-integration.js +68 -0
  178. package/core/server/data/migrations/versions/5.0/2022-05-09-10-00-drop-members-subscribed-column.js +18 -0
  179. package/core/server/data/migrations/versions/5.0/2022-05-09-14-17-cleanup-invalid-users-status.js +17 -0
  180. package/core/server/data/migrations/versions/5.0/2022-05-10-08-33-drop-members-analytics-table.js +3 -0
  181. package/core/server/data/migrations/versions/5.0/2022-05-10-14-57-cleanup-invalid-posts-status.js +17 -0
  182. package/core/server/data/migrations/versions/5.0/2022-05-11-12-08-drop-webhooks-status-column.js +18 -0
  183. package/core/server/data/migrations/versions/5.0/2022-05-11-13-12-rename-settings.js +51 -0
  184. package/core/server/data/migrations/versions/5.0/2022-05-11-16-36-remove-unused-settings.js +54 -0
  185. package/core/server/data/migrations/versions/5.0/2022-05-12-10-29-add-newsletter-permissions-for-editors-and-authors.js +20 -0
  186. package/core/server/data/migrations/versions/5.0/2022-05-12-13-51-add-label-permissions-for-authors.js +12 -0
  187. package/core/server/data/migrations/versions/5.0/2022-05-13-11-38-drop-none-email-recipient-filter.js +28 -0
  188. package/core/server/data/migrations/versions/5.0/2022-05-21-00-00-regenerate-posts-html.js +70 -0
  189. package/core/server/data/schema/commands.js +35 -3
  190. package/core/server/data/schema/default-settings/default-settings.json +2 -159
  191. package/core/server/data/schema/fixtures/fixture-manager.js +11 -2
  192. package/core/server/data/schema/fixtures/fixtures.json +16 -7
  193. package/core/server/data/schema/schema.js +26 -38
  194. package/core/server/data/schema/validator.js +2 -0
  195. package/core/server/ghost-server.js +34 -64
  196. package/core/server/lib/image/gravatar.js +25 -9
  197. package/core/server/models/api-key.js +3 -26
  198. package/core/server/models/base/plugins/bulk-operations.js +14 -6
  199. package/core/server/models/integration.js +17 -0
  200. package/core/server/models/member.js +8 -4
  201. package/core/server/models/newsletter.js +27 -0
  202. package/core/server/models/post.js +30 -32
  203. package/core/server/models/relations/authors.js +74 -100
  204. package/core/server/models/settings.js +6 -2
  205. package/core/server/models/webhook.js +2 -1
  206. package/core/server/run-update-check.js +1 -1
  207. package/core/server/services/api-version-compatibility/index.js +24 -18
  208. package/core/server/services/api-version-compatibility/legacy-api-path-match.js +23 -0
  209. package/core/server/services/api-version-compatibility/mw-version-rewrites.js +36 -0
  210. package/core/server/services/auth/api-key/admin.js +8 -7
  211. package/core/server/services/auth/passwordreset.js +3 -3
  212. package/core/server/services/auth/session/express-session.js +1 -1
  213. package/core/server/services/auth/session/index.js +1 -1
  214. package/core/server/services/auth/setup.js +8 -8
  215. package/core/server/services/bulk-email/bulk-email-processor.js +5 -1
  216. package/core/server/services/frontend-data-service/frontend-data-service.js +27 -0
  217. package/core/server/services/frontend-data-service/index.js +6 -0
  218. package/core/server/services/mail/index.js +14 -1
  219. package/core/server/services/mega/email-preview.js +14 -15
  220. package/core/server/services/mega/mega.js +37 -52
  221. package/core/server/services/mega/post-email-serializer.js +18 -28
  222. package/core/server/services/members/api.js +0 -3
  223. package/core/server/services/members/config.js +0 -49
  224. package/core/server/services/members/exporter/query.js +7 -7
  225. package/core/server/services/members/middleware.js +3 -135
  226. package/core/server/services/members/service.js +0 -27
  227. package/core/server/services/members/settings.js +3 -9
  228. package/core/server/services/newsletters/service.js +78 -10
  229. package/core/server/services/posts/post-scheduling-service.js +5 -17
  230. package/core/server/services/posts/posts-service.js +15 -62
  231. package/core/server/services/public-config/site.js +0 -6
  232. package/core/server/services/route-settings/index.js +0 -3
  233. package/core/server/services/route-settings/settings-loader.js +10 -34
  234. package/core/server/services/route-settings/validate.js +1 -7
  235. package/core/server/services/settings/index.js +1 -77
  236. package/core/server/services/settings/settings-service.js +184 -0
  237. package/core/server/services/themes/validate.js +1 -1
  238. package/core/server/services/url/Resources.js +1 -3
  239. package/core/server/services/url/UrlGenerator.js +1 -1
  240. package/core/server/services/url/UrlService.js +6 -20
  241. package/core/server/services/url/{configs/v2.js → config.js} +0 -0
  242. package/core/server/services/users.js +2 -2
  243. package/core/server/services/webhooks/listen.js +5 -2
  244. package/core/server/services/webhooks/serialize.js +6 -7
  245. package/core/server/services/webhooks/trigger.js +62 -47
  246. package/core/server/update-check.js +1 -1
  247. package/core/server/web/admin/app.js +1 -1
  248. package/core/server/web/admin/views/default-prod.html +4 -4
  249. package/core/server/web/admin/views/default.html +4 -4
  250. package/core/server/web/api/app.js +3 -15
  251. package/core/server/web/api/canary/admin/app.js +1 -1
  252. package/core/server/web/api/canary/admin/middleware.js +3 -1
  253. package/core/server/web/api/canary/admin/routes.js +7 -23
  254. package/core/server/web/api/canary/content/app.js +2 -3
  255. package/core/server/web/api/canary/content/routes.js +5 -4
  256. package/core/server/web/members/app.js +5 -4
  257. package/core/server/web/parent/backend.js +0 -1
  258. package/core/server/web/parent/frontend.js +5 -6
  259. package/core/server/web/parent/middleware/ghost-locals.js +0 -3
  260. package/core/shared/config/defaults.json +5 -2
  261. package/core/shared/config/overrides.json +1 -27
  262. package/core/shared/html-to-plaintext.js +74 -10
  263. package/core/shared/labs.js +4 -8
  264. package/core/shared/settings-cache/cache.js +38 -4
  265. package/core/shared/settings-cache/public.js +13 -7
  266. package/core/shared/url-utils.js +0 -2
  267. package/ghost.js +6 -0
  268. package/package.json +66 -64
  269. package/yarn.lock +751 -1295
  270. package/core/built/assets/ghost-dark-c94ae212747200ca4bafc37cfb0714d8.css +0 -1
  271. package/core/built/assets/ghost.min-4084931bc22e794fe3722139050a80b3.css +0 -1
  272. package/core/frontend/helpers/author.js +0 -41
  273. package/core/frontend/helpers/products.js +0 -65
  274. package/core/frontend/services/rendering/secure.js +0 -19
  275. package/core/frontend/services/routing/config/canary.js +0 -61
  276. package/core/frontend/services/routing/config/v2.js +0 -54
  277. package/core/frontend/services/routing/config/v3.js +0 -54
  278. package/core/frontend/services/theme-engine/engines/create.js +0 -45
  279. package/core/frontend/services/theme-engine/engines/index.js +0 -5
  280. package/core/frontend/services/theme-engine/middleware/update-local-template-data.js +0 -9
  281. package/core/server/api/canary/products-public.js +0 -34
  282. package/core/server/api/canary/products.js +0 -116
  283. package/core/server/api/canary/utils/serializers/input/products.js +0 -28
  284. package/core/server/api/canary/utils/serializers/output/email-previews.js +0 -7
  285. package/core/server/api/canary/utils/serializers/output/products.js +0 -213
  286. package/core/server/api/v2/actions.js +0 -38
  287. package/core/server/api/v2/authentication.js +0 -191
  288. package/core/server/api/v2/authors-public.js +0 -69
  289. package/core/server/api/v2/config.js +0 -12
  290. package/core/server/api/v2/db.js +0 -120
  291. package/core/server/api/v2/images.js +0 -20
  292. package/core/server/api/v2/index.js +0 -147
  293. package/core/server/api/v2/integrations.js +0 -144
  294. package/core/server/api/v2/invites.js +0 -126
  295. package/core/server/api/v2/mail.js +0 -66
  296. package/core/server/api/v2/notifications.js +0 -96
  297. package/core/server/api/v2/oembed.js +0 -186
  298. package/core/server/api/v2/pages-public.js +0 -78
  299. package/core/server/api/v2/pages.js +0 -197
  300. package/core/server/api/v2/posts-public.js +0 -78
  301. package/core/server/api/v2/posts.js +0 -192
  302. package/core/server/api/v2/preview.js +0 -46
  303. package/core/server/api/v2/redirects.js +0 -28
  304. package/core/server/api/v2/roles.js +0 -19
  305. package/core/server/api/v2/schedules.js +0 -77
  306. package/core/server/api/v2/session.js +0 -70
  307. package/core/server/api/v2/settings-public.js +0 -17
  308. package/core/server/api/v2/settings.js +0 -195
  309. package/core/server/api/v2/site.js +0 -14
  310. package/core/server/api/v2/slack.js +0 -12
  311. package/core/server/api/v2/slugs.js +0 -51
  312. package/core/server/api/v2/tags-public.js +0 -71
  313. package/core/server/api/v2/tags.js +0 -159
  314. package/core/server/api/v2/themes.js +0 -133
  315. package/core/server/api/v2/users.js +0 -179
  316. package/core/server/api/v2/utils/index.js +0 -34
  317. package/core/server/api/v2/utils/permissions.js +0 -112
  318. package/core/server/api/v2/utils/serializers/index.js +0 -9
  319. package/core/server/api/v2/utils/serializers/input/db.js +0 -20
  320. package/core/server/api/v2/utils/serializers/input/index.js +0 -33
  321. package/core/server/api/v2/utils/serializers/input/integrations.js +0 -33
  322. package/core/server/api/v2/utils/serializers/input/pages.js +0 -203
  323. package/core/server/api/v2/utils/serializers/input/posts.js +0 -218
  324. package/core/server/api/v2/utils/serializers/input/settings.js +0 -152
  325. package/core/server/api/v2/utils/serializers/input/tags.js +0 -35
  326. package/core/server/api/v2/utils/serializers/input/users.js +0 -26
  327. package/core/server/api/v2/utils/serializers/input/utils/url.js +0 -71
  328. package/core/server/api/v2/utils/serializers/input/webhooks.js +0 -12
  329. package/core/server/api/v2/utils/serializers/output/actions.js +0 -13
  330. package/core/server/api/v2/utils/serializers/output/all.js +0 -25
  331. package/core/server/api/v2/utils/serializers/output/authentication.js +0 -68
  332. package/core/server/api/v2/utils/serializers/output/authors.js +0 -21
  333. package/core/server/api/v2/utils/serializers/output/config.js +0 -21
  334. package/core/server/api/v2/utils/serializers/output/db.js +0 -40
  335. package/core/server/api/v2/utils/serializers/output/images.js +0 -19
  336. package/core/server/api/v2/utils/serializers/output/index.js +0 -107
  337. package/core/server/api/v2/utils/serializers/output/integrations.js +0 -35
  338. package/core/server/api/v2/utils/serializers/output/invites.js +0 -24
  339. package/core/server/api/v2/utils/serializers/output/mail.js +0 -19
  340. package/core/server/api/v2/utils/serializers/output/notifications.js +0 -29
  341. package/core/server/api/v2/utils/serializers/output/oembed.js +0 -8
  342. package/core/server/api/v2/utils/serializers/output/pages.js +0 -26
  343. package/core/server/api/v2/utils/serializers/output/posts.js +0 -26
  344. package/core/server/api/v2/utils/serializers/output/preview.js +0 -9
  345. package/core/server/api/v2/utils/serializers/output/redirects.js +0 -5
  346. package/core/server/api/v2/utils/serializers/output/roles.js +0 -29
  347. package/core/server/api/v2/utils/serializers/output/schedules.js +0 -5
  348. package/core/server/api/v2/utils/serializers/output/settings.js +0 -61
  349. package/core/server/api/v2/utils/serializers/output/site.js +0 -16
  350. package/core/server/api/v2/utils/serializers/output/slugs.js +0 -11
  351. package/core/server/api/v2/utils/serializers/output/tags.js +0 -25
  352. package/core/server/api/v2/utils/serializers/output/themes.js +0 -25
  353. package/core/server/api/v2/utils/serializers/output/users.js +0 -45
  354. package/core/server/api/v2/utils/serializers/output/utils/clean.js +0 -174
  355. package/core/server/api/v2/utils/serializers/output/utils/date.js +0 -21
  356. package/core/server/api/v2/utils/serializers/output/utils/extra-attrs.js +0 -161
  357. package/core/server/api/v2/utils/serializers/output/utils/mapper.js +0 -136
  358. package/core/server/api/v2/utils/serializers/output/utils/post-gating.js +0 -29
  359. package/core/server/api/v2/utils/serializers/output/utils/settings-type-group-mapper.js +0 -24
  360. package/core/server/api/v2/utils/serializers/output/utils/url.js +0 -67
  361. package/core/server/api/v2/utils/serializers/output/webhooks.js +0 -15
  362. package/core/server/api/v2/utils/validators/index.js +0 -9
  363. package/core/server/api/v2/utils/validators/input/images.js +0 -85
  364. package/core/server/api/v2/utils/validators/input/index.js +0 -45
  365. package/core/server/api/v2/utils/validators/input/invitations.js +0 -49
  366. package/core/server/api/v2/utils/validators/input/invites.js +0 -21
  367. package/core/server/api/v2/utils/validators/input/oembed.js +0 -17
  368. package/core/server/api/v2/utils/validators/input/pages.js +0 -46
  369. package/core/server/api/v2/utils/validators/input/passwordreset.js +0 -36
  370. package/core/server/api/v2/utils/validators/input/posts.js +0 -46
  371. package/core/server/api/v2/utils/validators/input/settings.js +0 -79
  372. package/core/server/api/v2/utils/validators/input/setup.js +0 -17
  373. package/core/server/api/v2/utils/validators/input/tags.js +0 -6
  374. package/core/server/api/v2/utils/validators/input/users.js +0 -21
  375. package/core/server/api/v2/utils/validators/output/index.js +0 -1
  376. package/core/server/api/v2/utils/validators/utils/json-schema.js +0 -17
  377. package/core/server/api/v2/webhooks.js +0 -163
  378. package/core/server/api/v3/authentication.js +0 -192
  379. package/core/server/api/v3/authors-public.js +0 -69
  380. package/core/server/api/v3/config.js +0 -12
  381. package/core/server/api/v3/db.js +0 -131
  382. package/core/server/api/v3/email-preview.js +0 -74
  383. package/core/server/api/v3/email.js +0 -65
  384. package/core/server/api/v3/identities.js +0 -36
  385. package/core/server/api/v3/images.js +0 -20
  386. package/core/server/api/v3/index.js +0 -179
  387. package/core/server/api/v3/integrations.js +0 -150
  388. package/core/server/api/v3/invites.js +0 -125
  389. package/core/server/api/v3/labels.js +0 -162
  390. package/core/server/api/v3/mail.js +0 -66
  391. package/core/server/api/v3/memberSigninUrls.js +0 -33
  392. package/core/server/api/v3/members.js +0 -412
  393. package/core/server/api/v3/membersStripeConnect.js +0 -29
  394. package/core/server/api/v3/notifications.js +0 -96
  395. package/core/server/api/v3/oembed.js +0 -23
  396. package/core/server/api/v3/pages-public.js +0 -77
  397. package/core/server/api/v3/pages.js +0 -199
  398. package/core/server/api/v3/posts-public.js +0 -76
  399. package/core/server/api/v3/posts.js +0 -200
  400. package/core/server/api/v3/preview.js +0 -44
  401. package/core/server/api/v3/redirects.js +0 -47
  402. package/core/server/api/v3/roles.js +0 -19
  403. package/core/server/api/v3/schedules.js +0 -77
  404. package/core/server/api/v3/session.js +0 -70
  405. package/core/server/api/v3/settings-public.js +0 -17
  406. package/core/server/api/v3/settings.js +0 -224
  407. package/core/server/api/v3/site.js +0 -14
  408. package/core/server/api/v3/slack.js +0 -12
  409. package/core/server/api/v3/slugs.js +0 -48
  410. package/core/server/api/v3/snippets.js +0 -115
  411. package/core/server/api/v3/tags-public.js +0 -71
  412. package/core/server/api/v3/tags.js +0 -159
  413. package/core/server/api/v3/themes.js +0 -131
  414. package/core/server/api/v3/users.js +0 -242
  415. package/core/server/api/v3/utils/index.js +0 -34
  416. package/core/server/api/v3/utils/permissions.js +0 -116
  417. package/core/server/api/v3/utils/serializers/index.js +0 -9
  418. package/core/server/api/v3/utils/serializers/input/authors.js +0 -31
  419. package/core/server/api/v3/utils/serializers/input/db.js +0 -20
  420. package/core/server/api/v3/utils/serializers/input/index.js +0 -41
  421. package/core/server/api/v3/utils/serializers/input/integrations.js +0 -33
  422. package/core/server/api/v3/utils/serializers/input/members.js +0 -62
  423. package/core/server/api/v3/utils/serializers/input/pages.js +0 -208
  424. package/core/server/api/v3/utils/serializers/input/posts.js +0 -242
  425. package/core/server/api/v3/utils/serializers/input/settings.js +0 -168
  426. package/core/server/api/v3/utils/serializers/input/tags.js +0 -42
  427. package/core/server/api/v3/utils/serializers/input/users.js +0 -26
  428. package/core/server/api/v3/utils/serializers/input/utils/slug-filter-order.js +0 -18
  429. package/core/server/api/v3/utils/serializers/input/utils/url.js +0 -71
  430. package/core/server/api/v3/utils/serializers/input/webhooks.js +0 -12
  431. package/core/server/api/v3/utils/serializers/output/actions.js +0 -13
  432. package/core/server/api/v3/utils/serializers/output/all.js +0 -25
  433. package/core/server/api/v3/utils/serializers/output/authentication.js +0 -69
  434. package/core/server/api/v3/utils/serializers/output/authors.js +0 -21
  435. package/core/server/api/v3/utils/serializers/output/config.js +0 -25
  436. package/core/server/api/v3/utils/serializers/output/db.js +0 -40
  437. package/core/server/api/v3/utils/serializers/output/email-preview.js +0 -7
  438. package/core/server/api/v3/utils/serializers/output/emails.js +0 -13
  439. package/core/server/api/v3/utils/serializers/output/identities.js +0 -7
  440. package/core/server/api/v3/utils/serializers/output/images.js +0 -19
  441. package/core/server/api/v3/utils/serializers/output/index.js +0 -135
  442. package/core/server/api/v3/utils/serializers/output/integrations.js +0 -35
  443. package/core/server/api/v3/utils/serializers/output/invites.js +0 -24
  444. package/core/server/api/v3/utils/serializers/output/labels.js +0 -25
  445. package/core/server/api/v3/utils/serializers/output/mail.js +0 -19
  446. package/core/server/api/v3/utils/serializers/output/member-signin_urls.js +0 -7
  447. package/core/server/api/v3/utils/serializers/output/members.js +0 -228
  448. package/core/server/api/v3/utils/serializers/output/notifications.js +0 -29
  449. package/core/server/api/v3/utils/serializers/output/oembed.js +0 -8
  450. package/core/server/api/v3/utils/serializers/output/pages.js +0 -26
  451. package/core/server/api/v3/utils/serializers/output/posts.js +0 -26
  452. package/core/server/api/v3/utils/serializers/output/preview.js +0 -10
  453. package/core/server/api/v3/utils/serializers/output/redirects.js +0 -5
  454. package/core/server/api/v3/utils/serializers/output/roles.js +0 -29
  455. package/core/server/api/v3/utils/serializers/output/schedules.js +0 -5
  456. package/core/server/api/v3/utils/serializers/output/settings.js +0 -65
  457. package/core/server/api/v3/utils/serializers/output/site.js +0 -19
  458. package/core/server/api/v3/utils/serializers/output/slugs.js +0 -11
  459. package/core/server/api/v3/utils/serializers/output/snippets.js +0 -97
  460. package/core/server/api/v3/utils/serializers/output/tags.js +0 -25
  461. package/core/server/api/v3/utils/serializers/output/themes.js +0 -25
  462. package/core/server/api/v3/utils/serializers/output/users.js +0 -74
  463. package/core/server/api/v3/utils/serializers/output/utils/clean.js +0 -166
  464. package/core/server/api/v3/utils/serializers/output/utils/date.js +0 -21
  465. package/core/server/api/v3/utils/serializers/output/utils/extra-attrs.js +0 -174
  466. package/core/server/api/v3/utils/serializers/output/utils/mapper.js +0 -197
  467. package/core/server/api/v3/utils/serializers/output/utils/post-gating.js +0 -39
  468. package/core/server/api/v3/utils/serializers/output/utils/settings-type-group-mapper.js +0 -24
  469. package/core/server/api/v3/utils/serializers/output/utils/url.js +0 -67
  470. package/core/server/api/v3/utils/serializers/output/webhooks.js +0 -15
  471. package/core/server/api/v3/utils/validators/index.js +0 -9
  472. package/core/server/api/v3/utils/validators/input/images.js +0 -85
  473. package/core/server/api/v3/utils/validators/input/index.js +0 -61
  474. package/core/server/api/v3/utils/validators/input/invitations.js +0 -49
  475. package/core/server/api/v3/utils/validators/input/invites.js +0 -21
  476. package/core/server/api/v3/utils/validators/input/labels.js +0 -6
  477. package/core/server/api/v3/utils/validators/input/members.js +0 -6
  478. package/core/server/api/v3/utils/validators/input/oembed.js +0 -17
  479. package/core/server/api/v3/utils/validators/input/pages.js +0 -46
  480. package/core/server/api/v3/utils/validators/input/passwordreset.js +0 -36
  481. package/core/server/api/v3/utils/validators/input/posts.js +0 -46
  482. package/core/server/api/v3/utils/validators/input/settings.js +0 -89
  483. package/core/server/api/v3/utils/validators/input/setup.js +0 -17
  484. package/core/server/api/v3/utils/validators/input/snippets.js +0 -6
  485. package/core/server/api/v3/utils/validators/input/tags.js +0 -6
  486. package/core/server/api/v3/utils/validators/input/users.js +0 -22
  487. package/core/server/api/v3/utils/validators/input/webhooks.js +0 -27
  488. package/core/server/api/v3/utils/validators/output/index.js +0 -1
  489. package/core/server/api/v3/utils/validators/utils/json-schema.js +0 -17
  490. package/core/server/api/v3/webhooks.js +0 -130
  491. package/core/server/data/migrations/utils.js +0 -571
  492. package/core/server/data/migrations/versions/1.13/1-custom-template-post.js +0 -7
  493. package/core/server/data/migrations/versions/1.13/2-theme-permissions.js +0 -58
  494. package/core/server/data/migrations/versions/1.18/1-add-webhooks-table.js +0 -2
  495. package/core/server/data/migrations/versions/1.19/1-webhook-permissions.js +0 -31
  496. package/core/server/data/migrations/versions/1.20/1-remove-settings-keys.js +0 -65
  497. package/core/server/data/migrations/versions/1.21/1-add-contributor-role.js +0 -58
  498. package/core/server/data/migrations/versions/1.22/1-multiple-authors-DDL.js +0 -2
  499. package/core/server/data/migrations/versions/1.22/1-multiple-authors-DML.js +0 -63
  500. package/core/server/data/migrations/versions/1.25/1-update-koenig-beta-html.js +0 -70
  501. package/core/server/data/migrations/versions/1.25/2-demo-post.js +0 -55
  502. package/core/server/data/migrations/versions/1.3/1-post-excerpt.js +0 -7
  503. package/core/server/data/migrations/versions/1.4/1-codeinjection-post.js +0 -14
  504. package/core/server/data/migrations/versions/1.5/1-og-twitter-post.js +0 -34
  505. package/core/server/data/migrations/versions/1.7/1-add-backup-client.js +0 -10
  506. package/core/server/data/migrations/versions/1.9/1-add-permissions-redirect.js +0 -23
  507. package/core/server/data/migrations/versions/2.0/1-rename-amp-column.js +0 -44
  508. package/core/server/data/migrations/versions/2.0/2-update-posts.js +0 -7
  509. package/core/server/data/migrations/versions/2.0/3-remove-koenig-labs.js +0 -42
  510. package/core/server/data/migrations/versions/2.0/4-permalink-setting.js +0 -85
  511. package/core/server/data/migrations/versions/2.0/5-remove-demo-post.js +0 -85
  512. package/core/server/data/migrations/versions/2.0/6-replace-fixture-posts.js +0 -10
  513. package/core/server/data/migrations/versions/2.13/1-remove-empty-strings.js +0 -5
  514. package/core/server/data/migrations/versions/2.14/1-add-actions-table.js +0 -2
  515. package/core/server/data/migrations/versions/2.14/2-add-actions-permissions.js +0 -12
  516. package/core/server/data/migrations/versions/2.15/1-add-type-column-to-integrations.js +0 -8
  517. package/core/server/data/migrations/versions/2.15/2-insert-zapier-integration.js +0 -69
  518. package/core/server/data/migrations/versions/2.16/1-add-members-perrmissions.js +0 -1
  519. package/core/server/data/migrations/versions/2.17/1-normalize-settings.js +0 -74
  520. package/core/server/data/migrations/versions/2.17/2-posts-add-canonical-url.js +0 -7
  521. package/core/server/data/migrations/versions/2.18/1-restore-settings-from-backup.js +0 -134
  522. package/core/server/data/migrations/versions/2.2/1-add-sessions-table.js +0 -2
  523. package/core/server/data/migrations/versions/2.2/2-add-integrations-and-api-key-tables.js +0 -6
  524. package/core/server/data/migrations/versions/2.2/3-insert-admin-integration-role.js +0 -83
  525. package/core/server/data/migrations/versions/2.2/4-insert-integration-and-api-key-permissions.js +0 -77
  526. package/core/server/data/migrations/versions/2.2/5-add-mobiledoc-revisions-table.js +0 -2
  527. package/core/server/data/migrations/versions/2.21/1-update-editor-permissions.js +0 -28
  528. package/core/server/data/migrations/versions/2.22/1-add-member-permissions-to-roles.js +0 -47
  529. package/core/server/data/migrations/versions/2.27/1-insert-ghost-db-backup-role.js +0 -83
  530. package/core/server/data/migrations/versions/2.27/2-insert-db-backup-integration.js +0 -69
  531. package/core/server/data/migrations/versions/2.27/3-add-subdirectory-to-relative-canonical-urls.js +0 -100
  532. package/core/server/data/migrations/versions/2.28/1-add-db-backup-content-permission.js +0 -9
  533. package/core/server/data/migrations/versions/2.28/2-add-db-backup-content-permission-to-roles.js +0 -15
  534. package/core/server/data/migrations/versions/2.28/3-insert-ghost-scheduler-role.js +0 -84
  535. package/core/server/data/migrations/versions/2.28/4-insert-scheduler-integration.js +0 -69
  536. package/core/server/data/migrations/versions/2.28/5-add-scheduler-permission-to-roles.js +0 -23
  537. package/core/server/data/migrations/versions/2.28/6-add-type-column.js +0 -6
  538. package/core/server/data/migrations/versions/2.28/7-populate-type-column.js +0 -6
  539. package/core/server/data/migrations/versions/2.28/8-remove-page-column.js +0 -6
  540. package/core/server/data/migrations/versions/2.29/1-add-post-page-column.js +0 -20
  541. package/core/server/data/migrations/versions/2.29/2-populate-post-page-column.js +0 -98
  542. package/core/server/data/migrations/versions/2.29/3-remove-page-type-column.js +0 -15
  543. package/core/server/data/migrations/versions/2.3/1-add-webhook-columns.js +0 -45
  544. package/core/server/data/migrations/versions/2.3/2-add-webhook-edit-permission.js +0 -9
  545. package/core/server/data/migrations/versions/2.31/1-remove-name-and-password-from-members-table.js +0 -15
  546. package/core/server/data/migrations/versions/2.32/01-add-members-stripe-customers-table.js +0 -4
  547. package/core/server/data/migrations/versions/2.32/02-add-name-to-members-table.js +0 -7
  548. package/core/server/data/migrations/versions/2.33/01-correct-members-stripe-customers-table.js +0 -37
  549. package/core/server/data/migrations/versions/2.34/01-add-stripe-customers-subscriptions-table.js +0 -2
  550. package/core/server/data/migrations/versions/2.34/02-add-email-to-members-stripe-customers-table.js +0 -7
  551. package/core/server/data/migrations/versions/2.34/03-add-name-to-members-stripe-customers-table.js +0 -7
  552. package/core/server/data/migrations/versions/2.35/01-add-note-to-members-table.js +0 -7
  553. package/core/server/data/migrations/versions/2.37/01-add-self-signup-and-from address-to-members-settings.js +0 -67
  554. package/core/server/data/migrations/versions/2.6/1-add-webhook-permission-roles.js +0 -31
  555. package/core/server/data/migrations/versions/2.8/1-add-members-table.js +0 -2
  556. package/core/server/data/migrations/versions/3.0/01-remove-user-ghost-auth-columns.js +0 -14
  557. package/core/server/data/migrations/versions/3.0/02-drop-token-auth-tables.js +0 -31
  558. package/core/server/data/migrations/versions/3.0/03-drop-client-auth-tables.js +0 -35
  559. package/core/server/data/migrations/versions/3.0/04-add-posts-meta-table.js +0 -2
  560. package/core/server/data/migrations/versions/3.0/05-populate-posts-meta-table.js +0 -83
  561. package/core/server/data/migrations/versions/3.0/06-remove-posts-meta-columns.js +0 -44
  562. package/core/server/data/migrations/versions/3.0/07-add-posts-type-column.js +0 -8
  563. package/core/server/data/migrations/versions/3.0/08-populate-posts-type-column.js +0 -94
  564. package/core/server/data/migrations/versions/3.0/09-remove-posts-page-column.js +0 -7
  565. package/core/server/data/migrations/versions/3.0/10-remove-empty-strings.js +0 -81
  566. package/core/server/data/migrations/versions/3.0/11-update-posts-html.js +0 -7
  567. package/core/server/data/migrations/versions/3.0/12-populate-members-table-from-subscribers.js +0 -54
  568. package/core/server/data/migrations/versions/3.0/13-drop-subscribers-table.js +0 -34
  569. package/core/server/data/migrations/versions/3.0/14-remove-subscribers-flag.js +0 -24
  570. package/core/server/data/migrations/versions/3.1/01-add-send-email-when-published-to-posts.js +0 -7
  571. package/core/server/data/migrations/versions/3.1/02-add-email-subject-to-posts-meta.js +0 -7
  572. package/core/server/data/migrations/versions/3.1/03-add-email-preview-permissions.js +0 -18
  573. package/core/server/data/migrations/versions/3.1/04-add-subscribed-flag-to-members.js +0 -7
  574. package/core/server/data/migrations/versions/3.1/05-add-emails-table.js +0 -2
  575. package/core/server/data/migrations/versions/3.1/06-add-email-permissions.js +0 -15
  576. package/core/server/data/migrations/versions/3.1/07-add-uuid-field-to-members.js +0 -8
  577. package/core/server/data/migrations/versions/3.1/08-add-uuid-values-to-members.js +0 -23
  578. package/core/server/data/migrations/versions/3.1/09-add-further-email-permissions.js +0 -25
  579. package/core/server/data/migrations/versions/3.1/10-add-email-error-data-column.js +0 -8
  580. package/core/server/data/migrations/versions/3.11/01-remove-broken-complimentary-plan-from-members-settings.js +0 -68
  581. package/core/server/data/migrations/versions/3.12/01-add-identity-permission.js +0 -7
  582. package/core/server/data/migrations/versions/3.12/02-remove-legacy-is-paid-flag-from-settings.js +0 -93
  583. package/core/server/data/migrations/versions/3.18/01-add-email-preview-permissions-to-roles.js +0 -39
  584. package/core/server/data/migrations/versions/3.18/02-add-members_stripe_connect-auth-permissions.js +0 -7
  585. package/core/server/data/migrations/versions/3.19/01-update-member-from-email-address.js +0 -91
  586. package/core/server/data/migrations/versions/3.2/01-add-cancel-at-period-end-to-subscriptions.js +0 -7
  587. package/core/server/data/migrations/versions/3.22/01-removed-legacy-values-from-settings-table.js +0 -65
  588. package/core/server/data/migrations/versions/3.22/02-settings-key-renames.js +0 -90
  589. package/core/server/data/migrations/versions/3.22/03-add-group-and-flags-to-settings.js +0 -15
  590. package/core/server/data/migrations/versions/3.22/04-populate-settings-groups-and-flags.js +0 -194
  591. package/core/server/data/migrations/versions/3.22/05-migrate-members-subscription-settings.js +0 -182
  592. package/core/server/data/migrations/versions/3.22/06-migrate-stripe-connect-settings.js +0 -132
  593. package/core/server/data/migrations/versions/3.22/07-update-type-for-settings.js +0 -137
  594. package/core/server/data/migrations/versions/3.23/01-migrate-bulk-email-settings.js +0 -65
  595. package/core/server/data/migrations/versions/3.23/02-remove-bulk-email-settings.js +0 -48
  596. package/core/server/data/migrations/versions/3.23/03-update-portal-button-setting.js +0 -24
  597. package/core/server/data/migrations/versions/3.23/04-add-meta-columns-to-tags-table.js +0 -54
  598. package/core/server/data/migrations/versions/3.24/01-populate-group-for-new-portal-settings.js +0 -38
  599. package/core/server/data/migrations/versions/3.25/01-add-members-stripe-webhook-settings.js +0 -22
  600. package/core/server/data/migrations/versions/3.26/01-add-amp-gtag-id-setting.js +0 -20
  601. package/core/server/data/migrations/versions/3.29/01-remove-duplicate-subscriptions.js +0 -53
  602. package/core/server/data/migrations/versions/3.29/02-remove-duplicate-customers.js +0 -53
  603. package/core/server/data/migrations/versions/3.29/03-remove-orphaned-customers.js +0 -35
  604. package/core/server/data/migrations/versions/3.29/04-remove-orphaned-subscriptions.js +0 -35
  605. package/core/server/data/migrations/versions/3.29/05-add-member-constraints.js +0 -177
  606. package/core/server/data/migrations/versions/3.30/01-add-member-signin-url-permission-roles.js +0 -8
  607. package/core/server/data/migrations/versions/3.32/01-add-member-support-address-setting.js +0 -27
  608. package/core/server/data/migrations/versions/3.32/02-add-member-reply-address-setting.js +0 -20
  609. package/core/server/data/migrations/versions/3.32/03-add-routes-hash-setting.js +0 -20
  610. package/core/server/data/migrations/versions/3.33/01-add-email-recipients-tables.js +0 -8
  611. package/core/server/data/migrations/versions/3.34/01-add-tokens-table.js +0 -2
  612. package/core/server/data/migrations/versions/3.35/01-add-address-columns-to-emails-table.js +0 -14
  613. package/core/server/data/migrations/versions/3.36/01-add-snippets-table.js +0 -2
  614. package/core/server/data/migrations/versions/3.36/02-add-snippets-permissions.js +0 -56
  615. package/core/server/data/migrations/versions/3.37/01-update-portal-button-setting.js +0 -30
  616. package/core/server/data/migrations/versions/3.38/01-add-email-recipient-filter-column.js +0 -8
  617. package/core/server/data/migrations/versions/3.38/02-populate-email-recipient-filter-column.js +0 -34
  618. package/core/server/data/migrations/versions/3.38/03-add-recipient-filter-column.js +0 -8
  619. package/core/server/data/migrations/versions/3.38/04-populate-recipient-filter-column.js +0 -49
  620. package/core/server/data/migrations/versions/3.38/05-add-emails-track-opens-column.js +0 -7
  621. package/core/server/data/migrations/versions/3.38/06-add-newsletter-settings.js +0 -16
  622. package/core/server/data/migrations/versions/3.38/07-migrate-newsletter-settings-from-config.js +0 -48
  623. package/core/server/data/migrations/versions/3.38/08-repopulate-send-email-when-published-down-migration.js +0 -25
  624. package/core/server/data/migrations/versions/3.38/09-remove-send-email-when-published-column.js +0 -7
  625. package/core/server/data/migrations/versions/3.39/01-add-members-signup-redirect-settings.js +0 -16
  626. package/core/server/data/migrations/versions/3.39/02-add-user-id-to-api-keys-table.js +0 -7
  627. package/core/server/data/migrations/versions/3.39/03-add-email-track-opens-setting.js +0 -16
  628. package/core/server/data/migrations/versions/3.39/04-add-cancellation-reason-column.js +0 -7
  629. package/core/server/data/migrations/versions/3.39/05-remove-unused-columns-on-emails.js +0 -14
  630. package/core/server/data/migrations/versions/3.39/06-add-email-recipient-index.js +0 -58
  631. package/core/server/data/migrations/versions/3.39/07-add-email-recipients-event-timestamps.js +0 -19
  632. package/core/server/data/migrations/versions/3.39/08-add-email-stats-columns.js +0 -22
  633. package/core/server/data/migrations/versions/3.40/01-add-members-email-open-rate-column.js +0 -8
  634. package/core/server/data/migrations/versions/3.40/02-add members-email-aggregation-columns.js +0 -16
  635. package/core/server/data/migrations/versions/3.40/03-populate-members-email-counts.js +0 -15
  636. package/core/server/data/migrations/versions/3.41/01-add-firstpromoter-settings.js +0 -16
  637. package/core/server/data/migrations/versions/3.6/1-add-labels-table.js +0 -2
  638. package/core/server/data/migrations/versions/3.6/2-add-members-labels-table.js +0 -2
  639. package/core/server/data/migrations/versions/3.6/3-add-labels-permissions.js +0 -47
  640. package/core/server/data/migrations/versions/3.7/01-fix-incorrect-member-labels-foreign-keys.js +0 -46
  641. package/core/server/data/migrations/versions/3.8/01-add-geolocation-to-members.js +0 -7
  642. package/core/server/data/migrations/versions/3.9/01-add-member-sigin-url-permissions.js +0 -7
  643. package/core/server/services/mail/utils.js +0 -34
  644. package/core/server/services/url/configs/canary.js +0 -143
  645. package/core/server/services/url/configs/v3.js +0 -141
  646. package/core/server/services/url/configs/v4.js +0 -143
  647. package/core/server/web/api/v2/admin/app.js +0 -43
  648. package/core/server/web/api/v2/admin/middleware.js +0 -85
  649. package/core/server/web/api/v2/admin/routes.js +0 -200
  650. package/core/server/web/api/v2/content/app.js +0 -38
  651. package/core/server/web/api/v2/content/middleware.js +0 -23
  652. package/core/server/web/api/v2/content/routes.js +0 -37
  653. package/core/server/web/api/v3/admin/app.js +0 -43
  654. package/core/server/web/api/v3/admin/middleware.js +0 -89
  655. package/core/server/web/api/v3/admin/routes.js +0 -267
  656. package/core/server/web/api/v3/content/app.js +0 -38
  657. package/core/server/web/api/v3/content/middleware.js +0 -23
  658. package/core/server/web/api/v3/content/routes.js +0 -37
  659. package/core/server/web/oauth/app.js +0 -153
  660. package/core/server/web/oauth/index.js +0 -1
@@ -16,12 +16,16 @@ const mobiledocLib = require('../lib/mobiledoc');
16
16
  const relations = require('./relations');
17
17
  const urlUtils = require('../../shared/url-utils');
18
18
  const {Tag} = require('./tag');
19
+ const {Newsletter} = require('./newsletter');
20
+ const {BadRequestError} = require('@tryghost/errors');
19
21
 
20
22
  const messages = {
21
23
  isAlreadyPublished: 'Your post is already published, please reload your page.',
22
24
  valueCannotBeBlank: 'Value in {key} cannot be blank.',
23
25
  expectedPublishedAtInFuture: 'Date must be at least {cannotScheduleAPostBeforeInMinutes} minutes in the future.',
24
- untitled: '(Untitled)'
26
+ untitled: '(Untitled)',
27
+ notEnoughPermission: 'You do not have permission to perform this action',
28
+ invalidNewsletter: 'The newsletter parameter doesn\'t match any active newsletter.'
25
29
  };
26
30
 
27
31
  const MOBILEDOC_REVISIONS_COUNT = 10;
@@ -78,7 +82,7 @@ Post = ghostBookshelf.Model.extend({
78
82
  type: 'post',
79
83
  tiers,
80
84
  visibility: visibility,
81
- email_recipient_filter: 'none'
85
+ email_recipient_filter: 'all'
82
86
  };
83
87
  },
84
88
 
@@ -135,14 +139,6 @@ Post = ghostBookshelf.Model.extend({
135
139
  }
136
140
  });
137
141
 
138
- // update legacy email_recipient_filter values to proper NQL
139
- if (attrs.email_recipient_filter === 'free') {
140
- attrs.email_recipient_filter = 'status:free';
141
- }
142
- if (attrs.email_recipient_filter === 'paid') {
143
- attrs.email_recipient_filter = 'status:-free';
144
- }
145
-
146
142
  return attrs;
147
143
  },
148
144
 
@@ -186,14 +182,6 @@ Post = ghostBookshelf.Model.extend({
186
182
  }
187
183
  });
188
184
 
189
- // update legacy email_recipient_filter values to proper NQL
190
- if (attrs.email_recipient_filter === 'free') {
191
- attrs.email_recipient_filter = 'status:free';
192
- }
193
- if (attrs.email_recipient_filter === 'paid') {
194
- attrs.email_recipient_filter = 'status:-free';
195
- }
196
-
197
185
  // transform visibility NQL queries to special-case values where necessary
198
186
  // ensures checks against special-case values such as `{{#has visibility="paid"}}` continue working
199
187
  if (attrs.visibility && !['public', 'members', 'paid', 'tiers'].includes(attrs.visibility)) {
@@ -638,7 +626,7 @@ Post = ghostBookshelf.Model.extend({
638
626
  if (this.get('html') === null) {
639
627
  plaintext = null;
640
628
  } else {
641
- plaintext = htmlToPlaintext(this.get('html'));
629
+ plaintext = htmlToPlaintext.excerpt(this.get('html'));
642
630
  }
643
631
 
644
632
  // CASE: html is e.g. <p></p>
@@ -674,20 +662,30 @@ Post = ghostBookshelf.Model.extend({
674
662
  }
675
663
  }
676
664
 
677
- // newsletter_id is read-only and should only be set using a query param when publishing/scheduling
678
- if (options.newsletter_id
665
+ // newsletter_id is read-only and should only be set using the newsletter param when publishing/scheduling
666
+ if (options.newsletter
679
667
  && !this.get('newsletter_id')
680
668
  && this.hasChanged('status')
681
669
  && (newStatus === 'published' || newStatus === 'scheduled')) {
682
- this.set('newsletter_id', options.newsletter_id);
683
- }
670
+ // Map the passed slug to the id + validate the passed newsletter
671
+ ops.push(async () => {
672
+ const newsletter = await Newsletter.findOne({slug: options.newsletter}, {transacting: options.transacting, filter: 'status:active'});
673
+ if (!newsletter) {
674
+ throw new BadRequestError({
675
+ message: messages.invalidNewsletter
676
+ });
677
+ }
678
+ this.set('newsletter_id', newsletter.id);
679
+ });
684
680
 
685
- // email_recipient_filter is read-only and should only be set using a query param when publishing/scheduling
686
- if (options.email_recipient_filter
687
- && (options.email_recipient_filter !== 'none')
688
- && this.hasChanged('status')
689
- && (newStatus === 'published' || newStatus === 'scheduled')) {
690
- this.set('email_recipient_filter', options.email_recipient_filter);
681
+ // If the `email_segment` isn't passed at the same time, reset it to be 100% sure that they can only be used together
682
+ this.set('email_recipient_filter', 'all');
683
+
684
+ // email_segment is read-only and should only be set using a query param when publishing/scheduling
685
+ // we can't set it if we don't pass newsletter
686
+ if (options.email_segment) {
687
+ this.set('email_recipient_filter', options.email_segment);
688
+ }
691
689
  }
692
690
 
693
691
  // ensure draft posts have the email_recipient_filter reset unless an email has already been sent
@@ -695,7 +693,7 @@ Post = ghostBookshelf.Model.extend({
695
693
  ops.push(function ensureSendEmailWhenPublishedIsUnchanged() {
696
694
  return self.related('email').fetch({transacting: options.transacting}).then((email) => {
697
695
  if (!email) {
698
- self.set('email_recipient_filter', 'none');
696
+ self.set('email_recipient_filter', 'all');
699
697
  self.set('newsletter_id', null);
700
698
  }
701
699
  });
@@ -862,7 +860,7 @@ Post = ghostBookshelf.Model.extend({
862
860
  * This is protected by the fn `permittedOptions`.
863
861
  */
864
862
  defaultColumnsToFetch: function defaultColumnsToFetch() {
865
- return ['id', 'published_at', 'slug', 'author_id'];
863
+ return ['id', 'published_at', 'slug'];
866
864
  },
867
865
  /**
868
866
  * If the `formats` option is not used, we return `html` be default.
@@ -1029,7 +1027,7 @@ Post = ghostBookshelf.Model.extend({
1029
1027
  findPage: ['status'],
1030
1028
  findAll: ['columns', 'filter'],
1031
1029
  destroy: ['destroyAll', 'destroyBy'],
1032
- edit: ['filter', 'email_recipient_filter', 'force_rerender', 'newsletter_id']
1030
+ edit: ['filter', 'email_segment', 'force_rerender', 'newsletter']
1033
1031
  };
1034
1032
 
1035
1033
  // The post model additionally supports having a formats option
@@ -17,13 +17,7 @@ const messages = {
17
17
  * We fetch the `authors` relations when you either request `withRelated=['authors']` or `withRelated=['author`].
18
18
  * The old `author` relation was removed, but we still have to support this case.
19
19
  *
20
- * # CASE 2
21
- * We fetch when editing a post.
22
- * Imagine you change `author_id` and you have 3 existing `posts_authors`.
23
- * We now need to set `author_id` as primary author `post.authors[0]`.
24
- * Furthermore, we now longer have a `author` relationship.
25
- *
26
- * # CASE 3:
20
+ * # CASE 2:
27
21
  * If you request `include=author`, we have to fill this object with `post.authors[0]`.
28
22
  * Otherwise we can't return `post.author = User`.
29
23
  *
@@ -85,19 +79,10 @@ module.exports.extendModel = function extendModel(Post, Posts, ghostBookshelf) {
85
79
  return proto.onFetchingCollection.call(this, collection, attrs, options);
86
80
  },
87
81
 
88
- // NOTE: sending `post.author = {}` was always ignored [unsupported]
89
82
  onCreating: function onCreating(model, attrs, options) {
90
- if (!model.get('author_id')) {
91
- if (model.get('authors')) {
92
- model.set('author_id', model.get('authors')[0].id);
93
- } else {
94
- model.set('author_id', this.contextUser(options));
95
- }
96
- }
97
-
98
83
  if (!model.get('authors')) {
99
84
  model.set('authors', [{
100
- id: model.get('author_id')
85
+ id: this.contextUser(options)
101
86
  }]);
102
87
  }
103
88
 
@@ -141,44 +126,6 @@ module.exports.extendModel = function extendModel(Post, Posts, ghostBookshelf) {
141
126
  }
142
127
 
143
128
  ops.push(() => {
144
- // CASE: `post.author_id` has changed
145
- if (model.hasChanged('author_id')) {
146
- // CASE: you don't send `post.authors`
147
- // SOLUTION: we have to update the primary author
148
- if (!model.get('authors')) {
149
- let existingAuthors = model.related('authors').toJSON();
150
-
151
- // CASE: override primary author
152
- existingAuthors[0] = {
153
- id: model.get('author_id')
154
- };
155
-
156
- model.set('authors', existingAuthors);
157
- } else {
158
- // CASE: you send `post.authors` next to `post.author_id`
159
- if (model.get('authors')[0].id !== model.get('author_id')) {
160
- model.set('author_id', model.get('authors')[0].id);
161
- }
162
- }
163
- }
164
-
165
- // CASE: if you change `post.author_id`, we have to update the primary author
166
- // CASE: if the `author_id` has change and you pass `posts.authors`, we already check above that
167
- // the primary author id must be equal
168
- if (model.hasChanged('author_id') && !model.get('authors')) {
169
- let existingAuthors = model.related('authors').toJSON();
170
-
171
- // CASE: override primary author
172
- existingAuthors[0] = {
173
- id: model.get('author_id')
174
- };
175
-
176
- model.set('authors', existingAuthors);
177
- } else if (model.get('authors') && model.get('authors').length) {
178
- // ensure we update the primary author id
179
- model.set('author_id', model.get('authors')[0].id);
180
- }
181
-
182
129
  return proto.onSaving.call(this, model, attrs, options);
183
130
  });
184
131
 
@@ -207,14 +154,6 @@ module.exports.extendModel = function extendModel(Post, Posts, ghostBookshelf) {
207
154
  }
208
155
 
209
156
  attrs.author = attrs.authors[0];
210
- delete attrs.author_id;
211
- } else {
212
- // CASE: we return `post.author=id` with or without requested columns.
213
- // @NOTE: this serialization should be moved into api layer, it's not being moved as it's deprecated
214
- if (!options.columns || (options.columns && options.columns.indexOf('author') !== -1)) {
215
- attrs.author = attrs.author_id;
216
- delete attrs.author_id;
217
- }
218
157
  }
219
158
 
220
159
  // CASE: `posts.authors` was not requested, but fetched in specific cases (see top)
@@ -294,12 +233,14 @@ module.exports.extendModel = function extendModel(Post, Posts, ghostBookshelf) {
294
233
  }
295
234
  }, {
296
235
  /**
297
- * ### destroyByAuthor
298
- * @param {[type]} options has context and id. Context is the user doing the destroy, id is the user to destroy
236
+ * ### reassignByAuthor
237
+ * @param {Object} unfilteredOptions has context and id. Context is the user doing the destroy, id is the user to destroy
238
+ * @param {string} unfilteredOptions.id
239
+ * @param {Object} unfilteredOptions.context
240
+ * @param {Object} unfilteredOptions.transacting
299
241
  */
300
- destroyByAuthor: function destroyByAuthor(unfilteredOptions) {
301
- let options = this.filterOptions(unfilteredOptions, 'destroyByAuthor', {extraAllowedProperties: ['id']});
302
- let postCollection = Posts.forge();
242
+ reassignByAuthor: async function reassignByAuthor(unfilteredOptions) {
243
+ let options = this.filterOptions(unfilteredOptions, 'reassignByAuthor', {extraAllowedProperties: ['id']});
303
244
  let authorId = options.id;
304
245
 
305
246
  if (!authorId) {
@@ -308,34 +249,76 @@ module.exports.extendModel = function extendModel(Post, Posts, ghostBookshelf) {
308
249
  }));
309
250
  }
310
251
 
311
- // CASE: if you are the primary author of a post, the whole post and it's relations get's deleted.
312
- // `posts_authors` are automatically removed (bookshelf-relations)
313
- // CASE: if you are the secondary author of a post, you are just deleted as author.
314
- // must happen manually
315
- const destroyPost = (() => {
316
- return postCollection
317
- .query('where', 'author_id', '=', authorId)
318
- .fetch(options)
319
- .call('invokeThen', 'destroy', options)
320
- .then(function (response) {
321
- return (options.transacting || ghostBookshelf.knex)('posts_authors')
322
- .where('author_id', authorId)
323
- .del()
324
- .then(() => response);
325
- })
326
- .catch((err) => {
327
- throw new errors.InternalServerError({err: err});
328
- });
252
+ const reassignPost = (async () => {
253
+ let trx = options.transacting;
254
+ let knex = ghostBookshelf.knex;
255
+
256
+ try {
257
+ // There's only one possible owner per Ghost instance
258
+ const ownerUser = await knex('roles')
259
+ .transacting(trx)
260
+ .join('roles_users', 'roles.id', '=', 'roles_users.role_id')
261
+ .where('roles.name', 'Owner')
262
+ .select('roles_users.user_id');
263
+ const ownerId = ownerUser[0].user_id;
264
+
265
+ const authorsPosts = await knex('posts_authors')
266
+ .transacting(trx)
267
+ .where('author_id', authorId)
268
+ .select('post_id', 'sort_order');
269
+
270
+ const ownersPosts = await knex('posts_authors')
271
+ .transacting(trx)
272
+ .where('author_id', ownerId)
273
+ .select('post_id');
274
+
275
+ const authorsPrimaryPosts = authorsPosts.filter(ap => ap.sort_order === 0);
276
+ const primaryPostsWithOwnerCoauthor = _.intersectionBy(authorsPrimaryPosts, ownersPosts, 'post_id');
277
+ const primaryPostsWithOwnerCoauthorIds = primaryPostsWithOwnerCoauthor.map(post => post.post_id);
278
+
279
+ // remove author and bump owner's sort_order to 0 to make them a primary author
280
+ // remove author from posts
281
+ await knex('posts_authors')
282
+ .transacting(trx)
283
+ .whereIn('post_id', primaryPostsWithOwnerCoauthorIds)
284
+ .where('author_id', authorId)
285
+ .del();
286
+
287
+ // make the owner a primary author
288
+ await knex('posts_authors')
289
+ .transacting(trx)
290
+ .whereIn('post_id', primaryPostsWithOwnerCoauthorIds)
291
+ .where('author_id', ownerId)
292
+ .update('sort_order', 0);
293
+
294
+ const primaryPostsWithoutOwnerCoauthor = _.differenceBy(authorsPrimaryPosts, primaryPostsWithOwnerCoauthor, 'post_id');
295
+ const postsWithoutOwnerCoauthorIds = primaryPostsWithoutOwnerCoauthor.map(post => post.post_id);
296
+
297
+ // swap out current author with the owner
298
+ await knex('posts_authors')
299
+ .transacting(trx)
300
+ .whereIn('post_id', postsWithoutOwnerCoauthorIds)
301
+ .where('author_id', authorId)
302
+ .update('author_id', ownerId);
303
+
304
+ // remove author as secondary author from any other posts
305
+ await knex('posts_authors')
306
+ .transacting(trx)
307
+ .where('author_id', authorId)
308
+ .del();
309
+ } catch (err) {
310
+ throw new errors.InternalServerError({err: err});
311
+ }
329
312
  });
330
313
 
331
314
  if (!options.transacting) {
332
315
  return ghostBookshelf.transaction((transacting) => {
333
316
  options.transacting = transacting;
334
- return destroyPost();
317
+ return reassignPost();
335
318
  });
336
319
  }
337
320
 
338
- return destroyPost();
321
+ return reassignPost();
339
322
  },
340
323
 
341
324
  permissible: function permissible(postModelOrId, action, context, unsafeAttrs, loadedPermissions, hasUserPermission, hasApiKeyPermission) {
@@ -375,10 +358,6 @@ module.exports.extendModel = function extendModel(Post, Posts, ghostBookshelf) {
375
358
  isAdd = (action === 'add');
376
359
  isDestroy = (action === 'destroy');
377
360
 
378
- function isChanging(attr) {
379
- return unsafeAttrs[attr] && unsafeAttrs[attr] !== postModel.get(attr);
380
- }
381
-
382
361
  function isChangingAuthors() {
383
362
  if (!unsafeAttrs.authors) {
384
363
  return false;
@@ -394,14 +373,10 @@ module.exports.extendModel = function extendModel(Post, Posts, ghostBookshelf) {
394
373
  function isOwner() {
395
374
  let isCorrectOwner = true;
396
375
 
397
- if (!unsafeAttrs.author_id && !unsafeAttrs.authors) {
376
+ if (!unsafeAttrs.authors) {
398
377
  return false;
399
378
  }
400
379
 
401
- if (unsafeAttrs.author_id) {
402
- isCorrectOwner = unsafeAttrs.author_id && unsafeAttrs.author_id === context.user;
403
- }
404
-
405
380
  if (unsafeAttrs.authors) {
406
381
  isCorrectOwner = isCorrectOwner && unsafeAttrs.authors.length && unsafeAttrs.authors[0].id === context.user;
407
382
  }
@@ -418,13 +393,13 @@ module.exports.extendModel = function extendModel(Post, Posts, ghostBookshelf) {
418
393
  }
419
394
 
420
395
  if (isContributor && isEdit) {
421
- hasUserPermission = !isChanging('author_id') && !isChangingAuthors() && isCoAuthor();
396
+ hasUserPermission = !isChangingAuthors() && isCoAuthor();
422
397
  } else if (isContributor && isAdd) {
423
398
  hasUserPermission = isOwner();
424
399
  } else if (isContributor && isDestroy) {
425
400
  hasUserPermission = isPrimaryAuthor();
426
401
  } else if (isAuthor && isEdit) {
427
- hasUserPermission = isCoAuthor() && !isChanging('author_id') && !isChangingAuthors();
402
+ hasUserPermission = isCoAuthor() && !isChangingAuthors();
428
403
  } else if (isAuthor && isAdd) {
429
404
  hasUserPermission = isOwner();
430
405
  } else if (postModel) {
@@ -444,7 +419,6 @@ module.exports.extendModel = function extendModel(Post, Posts, ghostBookshelf) {
444
419
  // @TODO: we need a concept for making a diff between incoming authors and existing authors
445
420
  // @TODO: for now we simply re-use the new concept of `excludedAttrs`
446
421
  // We only check the primary author of `authors`, any other change will be ignored.
447
- // By this we can deprecate `author_id` more easily.
448
422
  if (isContributor || isAuthor) {
449
423
  return {
450
424
  excludedAttrs: ['authors'].concat(excludedAttrs)
@@ -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