ghost 6.61.0 → 6.62.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 (472) hide show
  1. package/components/ghost-storage-base-3.0.0.tgz +0 -0
  2. package/components/tryghost-adapter-base-cache-0.2.0.tgz +0 -0
  3. package/components/tryghost-adapter-base-jobs-0.0.0.tgz +0 -0
  4. package/components/tryghost-adapter-base-redirects-0.0.0.tgz +0 -0
  5. package/components/tryghost-adapter-base-route-settings-0.0.0.tgz +0 -0
  6. package/components/tryghost-adapter-base-scheduling-0.2.3.tgz +0 -0
  7. package/components/tryghost-adapter-base-sso-0.1.3.tgz +0 -0
  8. package/components/tryghost-admin-api-schema-0.0.0.tgz +0 -0
  9. package/components/tryghost-checkout-0.0.0.tgz +0 -0
  10. package/components/tryghost-custom-field-types-0.0.0.tgz +0 -0
  11. package/components/tryghost-i18n-0.0.0.tgz +0 -0
  12. package/components/tryghost-kg-card-factory-5.2.4.tgz +0 -0
  13. package/components/tryghost-kg-clean-basic-html-4.3.4.tgz +0 -0
  14. package/components/tryghost-kg-converters-1.2.5.tgz +0 -0
  15. package/components/tryghost-kg-default-cards-10.3.5.tgz +0 -0
  16. package/components/tryghost-kg-default-nodes-2.2.1.tgz +0 -0
  17. package/components/tryghost-kg-default-transforms-1.3.4.tgz +0 -0
  18. package/components/tryghost-kg-html-to-lexical-1.4.0.tgz +0 -0
  19. package/components/tryghost-kg-lexical-html-renderer-1.5.0.tgz +0 -0
  20. package/components/tryghost-kg-markdown-html-renderer-7.2.4.tgz +0 -0
  21. package/components/tryghost-kg-utils-1.1.4.tgz +0 -0
  22. package/components/tryghost-nql-string-0.0.0.tgz +0 -0
  23. package/components/tryghost-parse-email-address-0.0.0.tgz +0 -0
  24. package/content/settings/README.md +1 -1
  25. package/content/themes/casper/.gitignore +28 -0
  26. package/content/themes/casper/assets/built/casper.js +1 -1
  27. package/content/themes/casper/assets/built/screen.css +1 -1
  28. package/content/themes/casper/assets/css/screen.css +2 -1
  29. package/content/themes/casper/assets/js/lightbox.js +63 -46
  30. package/content/themes/casper/package.json +6 -6
  31. package/content/themes/casper/page.hbs +1 -0
  32. package/content/themes/casper/post.hbs +1 -0
  33. package/content/themes/source/.gitignore +28 -0
  34. package/content/themes/source/assets/built/screen.css +1 -1
  35. package/content/themes/source/assets/built/source.js +1 -1
  36. package/content/themes/source/assets/css/screen.css +2 -1
  37. package/content/themes/source/assets/js/lightbox.js +62 -45
  38. package/content/themes/source/assets/js/main.js +2 -2
  39. package/content/themes/source/package.json +4 -4
  40. package/content/themes/source/partials/feature-image.hbs +1 -0
  41. package/core/boot.js +54 -22
  42. package/core/built/admin/assets/Combination-B0l4MKVh.js +41 -0
  43. package/core/built/admin/assets/InterVariable-DiVDrmQJ.woff2 +0 -0
  44. package/core/built/admin/assets/InterVariable-Italic-FCBEiFp6.woff2 +0 -0
  45. package/core/built/admin/assets/{about-Bve7IJS2.js → about-Dyae_UT6.js} +1 -1
  46. package/core/built/admin/assets/account-migration-CESa0mnX.js +1 -0
  47. package/core/built/admin/assets/activitypub/{account-migration-C-aej4x_.js → account-migration-By69CgCp.js} +16 -16
  48. package/core/built/admin/assets/activitypub/activitypub.js +9 -9
  49. package/core/built/admin/assets/activitypub/{bluesky-sharing-BXkA5mqV.js → bluesky-sharing-BJcPMrDd.js} +36 -36
  50. package/core/built/admin/assets/activitypub/{content-formatters-CHcyMFk4.js → content-formatters-3rTHg3mp.js} +3 -3
  51. package/core/built/admin/assets/activitypub/{domain-B3ihkPde.js → domain-DUR4xSkV.js} +121 -121
  52. package/core/built/admin/assets/activitypub/{edit-profile-DsZM3rTX.js → edit-profile-BqtfzxCp.js} +40 -40
  53. package/core/built/admin/assets/activitypub/{explore-BodNrZgR.js → explore-BxuJd-J4.js} +26 -26
  54. package/core/built/admin/assets/activitypub/{feed-PwH1iJ84.js → feed-BM1TcksA.js} +48 -48
  55. package/core/built/admin/assets/activitypub/{field-D06-kmOJ.js → field-Dn7HHx2-.js} +2 -2
  56. package/core/built/admin/assets/activitypub/inbox-CCjkuow2.js +1284 -0
  57. package/core/built/admin/assets/activitypub/label-1AA_s9Fa.js +16 -0
  58. package/core/built/admin/assets/activitypub/layout-2-0bw6HN.js +1 -0
  59. package/core/built/admin/assets/activitypub/{moderation-D1Yapsod.js → moderation-CnmxEB8w.js} +91 -91
  60. package/core/built/admin/assets/activitypub/{note-C5zjqq5C.js → note-ZKc_Bnba.js} +23 -23
  61. package/core/built/admin/assets/activitypub/{notifications-B9p8eCHD.js → notifications-CB2tJZau.js} +48 -48
  62. package/core/built/admin/assets/activitypub/{onboarding-CNelD_uF.js → onboarding-BsJ9E5qf.js} +2 -2
  63. package/core/built/admin/assets/activitypub/{onboarding-mat5Hrl0.js → onboarding-CSUJJIlh.js} +2 -2
  64. package/core/built/admin/assets/activitypub/{preferences-BCqUdC3v.js → preferences-0-JZnUkI.js} +1519 -1519
  65. package/core/built/admin/assets/activitypub/{profile-BRCWoFem.js → profile-C35cFIhM.js} +183 -183
  66. package/core/built/admin/assets/activitypub/{routes-BSXT992i.js → routes-BD4vscyc.js} +740 -731
  67. package/core/built/admin/assets/activitypub/settings-BsMROdqh.js +315 -0
  68. package/core/built/admin/assets/activitypub/{site-DHoMupSB.js → site-O0RL9YCN.js} +2 -2
  69. package/core/built/admin/assets/activitypub/{step-1-B-YfsVeO.js → step-1-BMSx7c_X.js} +4 -4
  70. package/core/built/admin/assets/activitypub/{step-3-D6BFMXL_.js → step-3-CLlOZTyt.js} +3 -3
  71. package/core/built/admin/assets/activitypub/{tabs-GpNecvfB.js → tabs-Dxk-b9M-.js} +306 -306
  72. package/core/built/admin/assets/activitypub/{topic-filter-BPDeQQys.js → topic-filter-5yZH6tId.js} +2 -2
  73. package/core/built/admin/assets/activitypub/{use-activity-pub-queries-BoVOxXkV.js → use-activity-pub-queries-CV50qe03.js} +2 -2
  74. package/core/built/admin/assets/activitypub/{use-reply-chain-data-wVBX7swM.js → use-reply-chain-data-Cbvzgjzd.js} +30 -30
  75. package/core/built/admin/assets/activitypub/{users-CoX6FT_K.js → users-BjcoP_HC.js} +7 -5
  76. package/core/built/admin/assets/add-integration-modal-BlF6rs_f.js +1 -0
  77. package/core/built/admin/assets/add-newsletter-modal-CglVQqah.js +1 -0
  78. package/core/built/admin/assets/add-recommendation-modal-wz7BsuaG.js +1 -0
  79. package/core/built/admin/assets/analytics-C4HE1gBg.js +1 -0
  80. package/core/built/admin/assets/{announcement-bar-modal-DM3cYOpo.js → announcement-bar-modal-Ci4zz8jO.js} +1 -1
  81. package/core/built/admin/assets/{api-keys-BLm2NDBh.js → api-keys-Ck-Yteiv.js} +1 -1
  82. package/core/built/admin/assets/{audience-9mwU5TW6.js → audience-CtbA54Sn.js} +1 -1
  83. package/core/built/admin/assets/{automated-emails-te1D5kq-.js → automated-emails-D5VVMND9.js} +1 -1
  84. package/core/built/admin/assets/automations-CzKt5fb8.js +1 -0
  85. package/core/built/admin/assets/bluesky-sharing-BEtJ_gL_.js +1 -0
  86. package/core/built/admin/assets/{breadcrumb-DLiqCyFc.js → breadcrumb-zUrZrBtW.js} +1 -1
  87. package/core/built/admin/assets/{button-B2jcu6bk.js → button-eNMKQWXr.js} +1 -1
  88. package/core/built/admin/assets/{chart-helpers-Fo3bUL3K.js → chart-helpers-CfBKt0vT.js} +1 -1
  89. package/core/built/admin/assets/{checkbox-BfKktMph.js → checkbox-CgOn_tKW.js} +1 -1
  90. package/core/built/admin/assets/{chunk.524.60ca4692d91c6022042f.js → chunk.524.a697dee88db67fdf6021.js} +4 -4
  91. package/core/built/admin/assets/{chunk.582.525c7617c2d9e94c940a.js → chunk.582.5ed5d124cfca9c259b9c.js} +6 -6
  92. package/core/built/admin/assets/{chunk.896.435fe0637944d4a69810.js → chunk.598.7e056fabb47ce7dbd73f.js} +14 -14
  93. package/core/built/admin/assets/{code-editor-view-CYVu4EW6.js → code-editor-view-BYNoAoNV.js} +1 -1
  94. package/core/built/admin/assets/{code-editor-view-DCQJxsfU.js → code-editor-view-K2wI-I5f.js} +1 -1
  95. package/core/built/admin/assets/color-picker-Ddw80xX6.js +3 -0
  96. package/core/built/admin/assets/color-picker-field-D9nUhvA7.js +1 -0
  97. package/core/built/admin/assets/combobox-w9j8PPQT.js +1 -0
  98. package/core/built/admin/assets/command-BfpHORBv.js +1 -0
  99. package/core/built/admin/assets/comments-BLmCmyCs.js +1 -0
  100. package/core/built/admin/assets/confirmation-context-CBM8G0Vj.js +1 -0
  101. package/core/built/admin/assets/{content-api-modal-CyQEC3fr.js → content-api-modal-TXRz3U7S.js} +1 -1
  102. package/core/built/admin/assets/context-menu-_QMdd3kp.js +1 -0
  103. package/core/built/admin/assets/{copy-field-B3M1s78L.js → copy-field-6N01S07E.js} +1 -1
  104. package/core/built/admin/assets/create-ghost-browse-value-source-qIBymvvf.js +1 -0
  105. package/core/built/admin/assets/custom-field-type-option-BddFlJFa.js +1 -0
  106. package/core/built/admin/assets/custom-integration-modal-DmNquxUV.js +1 -0
  107. package/core/built/admin/assets/{date-range-select-DD2RKkgB.js → date-range-select-uvz_DtPh.js} +1 -1
  108. package/core/built/admin/assets/design-and-theme-modal-BSmo12Op.js +2 -0
  109. package/core/built/admin/assets/dirty-confirm-dialog-BZ1iytEd.js +1 -0
  110. package/core/built/admin/assets/{disabled-sources-indicator-Cvy47bE2.js → disabled-sources-indicator-DMRrxsiJ.js} +1 -1
  111. package/core/built/admin/assets/dist-Dcsslyo72.js +1 -0
  112. package/core/built/admin/assets/domain-BNYrt0aD.js +1 -0
  113. package/core/built/admin/assets/dropzone-D7nFdAe5.js +5 -0
  114. package/core/built/admin/assets/edit-profile-C5Asm4LA.js +1 -0
  115. package/core/built/admin/assets/editor-REokrzci.js +8 -0
  116. package/core/built/admin/assets/{embed-signup-form-modal-DeBMLxlL.js → embed-signup-form-modal-Ds6mPEi5.js} +1 -1
  117. package/core/built/admin/assets/en-B1jX3WMs.js +1 -0
  118. package/core/built/admin/assets/explore-UY10Egsp.js +1 -0
  119. package/core/built/admin/assets/feature-image-placeholder-D1iF_8bc.js +1 -0
  120. package/core/built/admin/assets/feed-81C8mJWR.js +1 -0
  121. package/core/built/admin/assets/{field-Cj8lmDOo.js → field-Dihp5p18.js} +1 -1
  122. package/core/built/admin/assets/filter-bar-Da1qxybu.js +1 -0
  123. package/core/built/admin/assets/filter-sources-BO9xUPj7.js +1 -0
  124. package/core/built/admin/assets/filters-CRUWecfY.js +1 -0
  125. package/core/built/admin/assets/filters-DirqNXjH.js +1 -0
  126. package/core/built/admin/assets/first-promoter-modal-CT6MxYZb.js +1 -0
  127. package/core/built/admin/assets/{ghost-c8807202a07c20030acb719ee0114815.css → ghost-8eabfc1ece81b03cf7b90780d31487e8.css} +1 -1
  128. package/core/built/admin/assets/{ghost-3894eedcc6968f658578c0abfe942aab.js → ghost-c2848508292937415f20f5a830eea59e.js} +31 -28
  129. package/core/built/admin/assets/{ghost-dark-fbf1e384aaef3ae315e540f0eb7373a7.css → ghost-dark-a7bebe2c561f55369dcf29f4c820f7ff.css} +1 -1
  130. package/core/built/admin/assets/gift-link-modal-CQVAye17.js +1 -0
  131. package/core/built/admin/assets/growth-BWIu-6xj.js +3 -0
  132. package/core/built/admin/assets/growth-DU29oxeA.js +1 -0
  133. package/core/built/admin/assets/history-modal-CFd1Hvx6.js +1 -0
  134. package/core/built/admin/assets/{html-field-C8qVGGC1.js → html-field-CJBCLTvv.js} +1 -1
  135. package/core/built/admin/assets/{images-h8VZEQ9k.js → images-scfkWZiK.js} +1 -1
  136. package/core/built/admin/assets/{inbox-BYd1M06Q.js → inbox-Mcp4DXZN.js} +14 -14
  137. package/core/built/admin/assets/index-6MkPdCtr.js +4 -0
  138. package/core/built/admin/assets/index-Bn7QhcZu.css +2 -0
  139. package/core/built/admin/assets/index.es-CNnuNH0d.js +1 -0
  140. package/core/built/admin/assets/{input-group-D8sCXRF5.js → input-group-CMhe2DvY.js} +1 -1
  141. package/core/built/admin/assets/invite-user-modal-DfheMXs0.js +1 -0
  142. package/core/built/admin/assets/koenig-lexical/koenig-lexical.js +14 -14
  143. package/core/built/admin/assets/koenig-lexical/koenig-lexical.umd.js +3 -3
  144. package/core/built/admin/assets/koenig-lexical/style.css +1 -1
  145. package/core/built/admin/assets/{koenig-lexical-_-IsVI7E.js → koenig-lexical-DBSqAuiI.js} +3 -3
  146. package/core/built/admin/assets/koenig-loader-aFQNlJlD.js +2 -0
  147. package/core/built/admin/assets/{kpi-card-DZQk_0W8.js → kpi-card-DBRMfGOW.js} +1 -1
  148. package/core/built/admin/assets/{kpi-card-DW_2y3ug.js → kpi-card-DFafD1qq.js} +1 -1
  149. package/core/built/admin/assets/{kpi-helpers-PueTKuA6.js → kpi-helpers-Cv8i8hns.js} +1 -1
  150. package/core/built/admin/assets/{kpi-tabs-CojDs-Qz.js → kpi-tabs-BJItvLYm.js} +1 -1
  151. package/core/built/admin/assets/{label-DjbT91GM.js → label-BnSCvffu.js} +1 -1
  152. package/core/built/admin/assets/label-picker-KVoo91sh.js +1 -0
  153. package/core/built/admin/assets/layout-Bjv2Ll-5.js +1 -0
  154. package/core/built/admin/assets/member-custom-fields-DDQV6QeG.js +1 -0
  155. package/core/built/admin/assets/member-detail-CdJF6Agw.js +1 -0
  156. package/core/built/admin/assets/members-DjQbq9Z2.js +4 -0
  157. package/core/built/admin/assets/moderation-AgCIEso4.js +1 -0
  158. package/core/built/admin/assets/{multi-select-combobox-B6LiRzDO.js → multi-select-combobox-BcITkUVr.js} +1 -1
  159. package/core/built/admin/assets/navigation-modal-BkT7b1M2.js +1 -0
  160. package/core/built/admin/assets/newsletter-BMMAuvgq.js +1 -0
  161. package/core/built/admin/assets/newsletter-detail-modal-0SCJ7Zpm.js +1 -0
  162. package/core/built/admin/assets/{newsletter-emails-CFeLlt4z.js → newsletter-emails-DKzwafuh.js} +1 -1
  163. package/core/built/admin/assets/newsletters-BRBb_uQC.js +1 -0
  164. package/core/built/admin/assets/note-DyGHtS9a.js +1 -0
  165. package/core/built/admin/assets/notifications-ZgWniKna.js +1 -0
  166. package/core/built/admin/assets/nql-BLpCn7qX.js +21 -0
  167. package/core/built/admin/assets/offers-container-modal-B-E8TIWr.js +1 -0
  168. package/core/built/admin/assets/{onboarding-B4YhlZ0i.js → onboarding-CzIsre-d.js} +1 -1
  169. package/core/built/admin/assets/onboarding-qg8Akovm.js +1 -0
  170. package/core/built/admin/assets/{onboarding-route-Dmc4IPm3.js → onboarding-route-CaavZulg.js} +1 -1
  171. package/core/built/admin/assets/overview-BW8GLeYi.js +1 -0
  172. package/core/built/admin/assets/overview-BkXZNzaZ.js +1 -0
  173. package/core/built/admin/assets/{page-header-BR_nbIPp.js → page-header-De0VzKBi.js} +1 -1
  174. package/core/built/admin/assets/pagemenu-B5KKCpbA.js +1 -0
  175. package/core/built/admin/assets/pages-jgaFm69d.js +1 -0
  176. package/core/built/admin/assets/pages-route-CIUAQxtY.js +1 -0
  177. package/core/built/admin/assets/papaparse.min-cQwnxGCG.js +10 -0
  178. package/core/built/admin/assets/{pintura-modal-BR9hEvS8.js → pintura-modal-BZ2J9w3n.js} +1 -1
  179. package/core/built/admin/assets/portal-frame-B6Hr9wHc.js +1 -0
  180. package/core/built/admin/assets/portal-modal-D4ceei3t.js +1 -0
  181. package/core/built/admin/assets/post-analytics-header-BYCsT0GP.js +1 -0
  182. package/core/built/admin/assets/post-analytics-ot7f6pih.js +1 -0
  183. package/core/built/admin/assets/{post-analytics-provider-CLfKGWZy.js → post-analytics-provider-Bo1gmYaP.js} +1 -1
  184. package/core/built/admin/assets/{post-share-modal-Cl0NXRJr.js → post-share-modal-C-PaYZ_e.js} +1 -1
  185. package/core/built/admin/assets/posts-DuGazgTb.js +1 -0
  186. package/core/built/admin/assets/posts-list-screen-CBGGgjjj.js +2 -0
  187. package/core/built/admin/assets/posts-route-D6xmS7Vf.js +1 -0
  188. package/core/built/admin/assets/preferences-C5YJLp74.js +5 -0
  189. package/core/built/admin/assets/{preview-modal-C-BL-F9k.js → preview-modal-BfeFqi5y.js} +1 -1
  190. package/core/built/admin/assets/profile-B8mx2yAu.js +1 -0
  191. package/core/built/admin/assets/radio-group-DczlLKOn.js +1 -0
  192. package/core/built/admin/assets/{schemas-4UPic-oD.js → schemas-DppqmpeJ.js} +1 -1
  193. package/core/built/admin/assets/select-cb0t_TAJ.js +1 -0
  194. package/core/built/admin/assets/settings-DZqxR0Da.js +1 -0
  195. package/core/built/admin/assets/settings-DvfTNdHQ.js +4 -0
  196. package/core/built/admin/assets/{settings-breadcrumbs-CyP_9zTo.js → settings-breadcrumbs-DLzbRRSt.js} +1 -1
  197. package/core/built/admin/assets/share-modal-D2-Bz1_I.js +1 -0
  198. package/core/built/admin/assets/slack-modal-DYDTUria.js +1 -0
  199. package/core/built/admin/assets/{sort-button-Cc-Z96sA.js → sort-button-VVeQjjbu.js} +1 -1
  200. package/core/built/admin/assets/{source-icon-v6PUnmyM.js → source-icon-Ck5_5Kgq.js} +1 -1
  201. package/core/built/admin/assets/stats-Rjmk5owg.js +1 -0
  202. package/core/built/admin/assets/stats-view-BGGmkmgv.js +1 -0
  203. package/core/built/admin/assets/{step-1-DSRp2vBj.js → step-1-CsaBjeN4.js} +1 -1
  204. package/core/built/admin/assets/{step-2-COqv2g0u.js → step-2-D2vnxOOM.js} +1 -1
  205. package/core/built/admin/assets/{step-3-6W1NMVQc.js → step-3-wBoLdGEb.js} +2 -2
  206. package/core/built/admin/assets/{stripe-button-D2K42Uty.js → stripe-button-CDgLz0S0.js} +1 -1
  207. package/core/built/admin/assets/stripe-connect-modal-CSjMJetP.js +1 -0
  208. package/core/built/admin/assets/{table-B2pIKjVh.js → table-Do6iQ83Q.js} +1 -1
  209. package/core/built/admin/assets/{tabs-SaW_UT-Q.js → tabs-D2yWLMp_.js} +1 -1
  210. package/core/built/admin/assets/tag-detail-BhXlOsCa.js +2 -0
  211. package/core/built/admin/assets/tags-ldukRApe.js +1 -0
  212. package/core/built/admin/assets/testimonials-modal-CtnZBJKl.js +1 -0
  213. package/core/built/admin/assets/tier-detail-modal-BOs8e_G8.js +1 -0
  214. package/core/built/admin/assets/{toggle-group-EM9WpESu.js → toggle-group-ByUJsxwD.js} +1 -1
  215. package/core/built/admin/assets/{topic-filter-DY4gNHn2.js → topic-filter-BgC3g5_v.js} +1 -1
  216. package/core/built/admin/assets/{transistor-modal-CpyPG-MH.js → transistor-modal-Drr0SNfo.js} +1 -1
  217. package/core/built/admin/assets/{trend-badge-ByMkuAuH.js → trend-badge-6ye93YAW.js} +1 -1
  218. package/core/built/admin/assets/{unsplash-modal-Cv2Q6GtY.js → unsplash-modal-p6AoQoWp.js} +1 -1
  219. package/core/built/admin/assets/{use-analytics-data-CHvjMYuT.js → use-analytics-data-CWCMAESo.js} +1 -1
  220. package/core/built/admin/assets/use-check-theme-limit-error-B8bjF-gO.css +1 -0
  221. package/core/built/admin/assets/{use-check-theme-limit-error-Qv4SVXqw.js → use-check-theme-limit-error-Cw3WQHy8.js} +1 -1
  222. package/core/built/admin/assets/use-filter-params-BIni9taJ.js +1 -0
  223. package/core/built/admin/assets/use-growth-stats-DCVG3s9w.js +1 -0
  224. package/core/built/admin/assets/{use-limiter-cwJvsNBo.js → use-limiter-D2WRRx0H.js} +1 -1
  225. package/core/built/admin/assets/{use-pintura-config-CzTfnufz.js → use-pintura-config-h-J0Lvta.js} +1 -1
  226. package/core/built/admin/assets/{use-pintura-editor-BDBXWUYq.js → use-pintura-editor-BfN1UwzH.js} +1 -1
  227. package/core/built/admin/assets/use-post-referrers-Czg47m8s.js +1 -0
  228. package/core/built/admin/assets/use-reply-chain-data-ns0caK8k.js +1 -0
  229. package/core/built/admin/assets/{use-router-history-entry-Bg6BhBQQ.js → use-router-history-entry-uldn7zJO.js} +1 -1
  230. package/core/built/admin/assets/{use-setting-group-VM7FQwMY.js → use-setting-group-DpcuCUDg.js} +1 -1
  231. package/core/built/admin/assets/use-settings-navigation-CZjGrhsp.js +1 -0
  232. package/core/built/admin/assets/{use-simple-pagination-Dum6Irbs.js → use-simple-pagination-DzJWobPR.js} +1 -1
  233. package/core/built/admin/assets/{use-staff-users-cZg4ugOF.js → use-staff-users-Csipb-O0.js} +1 -1
  234. package/core/built/admin/assets/use-tinybird-query-CSnGXzZh.js +1 -0
  235. package/core/built/admin/assets/use-tinybird-token-DTOKRR7e.js +1 -0
  236. package/core/built/admin/assets/{use-unsaved-changes-guard-BAy0RANR.js → use-unsaved-changes-guard-CBzs-KPi.js} +1 -1
  237. package/core/built/admin/assets/{use-url-input-Df5QzNa7.js → use-url-input-DFr8lCbS.js} +1 -1
  238. package/core/built/admin/assets/user-detail-modal-B_iUClI6.js +1 -0
  239. package/core/built/admin/assets/users-Cg-OeGzC.js +1 -0
  240. package/core/built/admin/assets/{virtual-list-DEx8WgiO.js → virtual-list-BW-padMe.js} +1 -1
  241. package/core/built/admin/assets/web-C1v33ehA.js +2 -0
  242. package/core/built/admin/assets/web-C4BKzn2T.js +1 -0
  243. package/core/built/admin/assets/{zapier-modal-Cw3BTBUu.js → zapier-modal-BBFfI6Ml.js} +1 -1
  244. package/core/built/admin/index.html +17 -22
  245. package/core/frontend/apps/private-blogging/lib/views/private.hbs +44 -43
  246. package/core/frontend/helpers/cancel_link.js +2 -2
  247. package/core/frontend/helpers/pagination.js +2 -2
  248. package/core/frontend/helpers/social_accounts.js +2 -2
  249. package/core/frontend/public/ghost.css +1 -1
  250. package/core/frontend/public/ghost.min.css +1 -1
  251. package/core/frontend/services/sitemap/user-map-generator.js +9 -2
  252. package/core/server/api/endpoints/index.js +2 -2
  253. package/core/server/api/endpoints/mail.js +1 -1
  254. package/core/server/api/endpoints/{member-custom-fields.js → member-metafields.js} +27 -28
  255. package/core/server/api/endpoints/members.js +4 -4
  256. package/core/server/api/endpoints/posts.js +3 -3
  257. package/core/server/api/endpoints/utils/serializers/input/members.js +4 -7
  258. package/core/server/api/endpoints/utils/serializers/output/index.js +2 -2
  259. package/core/server/api/endpoints/utils/serializers/output/{member-custom-fields.js → member-metafields.js} +2 -4
  260. package/core/server/api/endpoints/utils/serializers/output/members.js +2 -4
  261. package/core/server/api/endpoints/utils/validators/input/invitations.js +0 -5
  262. package/core/server/api/endpoints/utils/validators/input/pages.js +1 -1
  263. package/core/server/api/endpoints/utils/validators/input/posts.js +1 -1
  264. package/core/server/data/importer/importers/data/data-importer.js +3 -3
  265. package/core/server/data/migrations/utils/migrations.js +1 -1
  266. package/core/server/lib/image/image-size.js +24 -0
  267. package/core/server/lib/package-json/parse.js +2 -2
  268. package/core/server/models/member.js +6 -17
  269. package/core/server/models/post.js +2 -2
  270. package/core/server/models/relations/authors.js +2 -16
  271. package/core/server/models/user.js +9 -2
  272. package/core/server/services/auth/passwordreset.js +13 -0
  273. package/core/server/services/comments/comments-controller.js +30 -9
  274. package/core/server/services/comments/comments-service.js +55 -5
  275. package/core/server/services/content-import/csv/formula.js +12 -0
  276. package/core/server/services/content-import/csv/index.js +6 -1
  277. package/core/server/services/content-import/csv/parse.js +27 -6
  278. package/core/server/services/content-import/csv/serialize.js +13 -0
  279. package/core/server/services/content-import/import/completion-email.js +164 -0
  280. package/core/server/services/content-import/import/errors-file.js +36 -0
  281. package/core/server/services/content-import/import/importer.js +160 -53
  282. package/core/server/services/content-import/import/local-media-url.js +63 -0
  283. package/core/server/services/content-import/import/media.js +254 -0
  284. package/core/server/services/content-import/import/post-data.js +0 -1
  285. package/core/server/services/content-import/import/post-link.js +11 -0
  286. package/core/server/services/content-import/import/post-repository.js +25 -3
  287. package/core/server/services/content-import/import/reader.js +9 -2
  288. package/core/server/services/content-import/import/report.js +34 -0
  289. package/core/server/services/content-import/import/row.js +0 -2
  290. package/core/server/services/content-import/import/schema.js +1 -0
  291. package/core/server/services/content-import/import/staged-file.js +29 -0
  292. package/core/server/services/content-import/import/store.js +25 -2
  293. package/core/server/services/content-import/index.js +52 -6
  294. package/core/server/services/content-import/jobs/content-csv-import-job.js +20 -0
  295. package/core/server/services/custom-redirects/redirect-config-parser.js +2 -2
  296. package/core/server/services/custom-redirects/redirects-service.js +1 -1
  297. package/core/server/services/custom-redirects/validation.js +1 -1
  298. package/core/server/services/email-address/email-address-parser.js +30 -38
  299. package/core/server/services/email-address/email-address-service.js +37 -4
  300. package/core/server/services/email-analytics/index.js +2 -7
  301. package/core/server/services/email-service/batch-sending-service.js +0 -4
  302. package/core/server/services/email-service/email-renderer.js +14 -4
  303. package/core/server/services/email-service/email-service-wrapper.js +0 -9
  304. package/core/server/services/email-service/mailgun-email-provider.js +20 -9
  305. package/core/server/services/gifts/email-templates/gift-delivery.hbs +3 -3
  306. package/core/server/services/gifts/gift-email-service.js +0 -1
  307. package/core/server/services/gifts/index.js +3 -3
  308. package/core/server/services/gifts/jobs/index.js +4 -4
  309. package/core/server/services/indexnow-ping/indexnow-ping-service.js +2 -2
  310. package/core/server/services/invitations/accept.js +4 -2
  311. package/core/server/services/jobs/job-service.js +0 -9
  312. package/core/server/services/jobs-service/register-job-handlers.js +21 -11
  313. package/core/server/services/mail/ghost-mailer.js +4 -4
  314. package/core/server/services/member-welcome-emails/service.js +7 -7
  315. package/core/server/services/members/api.js +1 -0
  316. package/core/server/services/members/import-export/csv/parse.js +0 -7
  317. package/core/server/services/members/import-export/import/completion-email.js +2 -5
  318. package/core/server/services/members/import-export/import/row.js +0 -3
  319. package/core/server/services/members/import-export/index.js +4 -11
  320. package/core/server/services/members/jobs/clean-expired-comped-job.js +7 -0
  321. package/core/server/services/members/jobs/clean-expired-comped-task.js +145 -0
  322. package/core/server/services/members/jobs/index.js +48 -24
  323. package/core/server/services/members/members-api/controllers/member-controller.js +11 -0
  324. package/core/server/services/members/members-api/controllers/router-controller.js +3 -6
  325. package/core/server/services/members/members-api/members-api.js +4 -6
  326. package/core/server/services/members/members-api/repositories/event-repository.js +0 -4
  327. package/core/server/services/members/members-api/services/member-bread-service.js +34 -62
  328. package/core/server/services/members/members-api/services/payments-service.js +1 -1
  329. package/core/server/services/members/service.js +1 -5
  330. package/core/server/services/members-custom-fields/bindings-service.js +2 -1
  331. package/core/server/services/members-custom-fields/codec.js +3 -4
  332. package/core/server/services/members-custom-fields/definitions-service.js +62 -10
  333. package/core/server/services/members-custom-fields/filter.js +75 -93
  334. package/core/server/services/members-custom-fields/key.js +2 -1
  335. package/core/server/services/members-custom-fields/models.js +1 -1
  336. package/core/server/services/members-custom-fields/serializers.js +3 -5
  337. package/core/server/services/members-custom-fields/values-service.js +50 -28
  338. package/core/server/services/mentions/mention-controller.js +23 -21
  339. package/core/server/services/mentions/process-webmention-job.js +16 -0
  340. package/core/server/services/mentions/service.js +8 -4
  341. package/core/server/services/route-settings/validation-errors.js +1 -1
  342. package/core/server/services/route-settings/yaml-parser.js +1 -1
  343. package/core/server/services/settings/settings-service.js +1 -8
  344. package/core/server/services/settings-helpers/settings-helpers.js +4 -6
  345. package/core/server/services/slack-ping/slack-ping-service.js +1 -1
  346. package/core/server/services/staff/staff-service-emails.js +2 -2
  347. package/core/server/services/stripe/config.js +14 -8
  348. package/core/server/services/stripe/service.js +10 -1
  349. package/core/server/services/stripe/services/checkout/completed-session.js +2 -2
  350. package/core/server/services/stripe/services/checkout/session-options.js +18 -15
  351. package/core/server/services/stripe/services/webhook/checkout-session-event-service.js +26 -5
  352. package/core/server/services/stripe/stripe-api.js +2 -0
  353. package/core/server/services/stripe/stripe-service.js +20 -10
  354. package/core/server/services/stripe/webhook-controller.js +10 -0
  355. package/core/server/services/tier-checkout-config/codec.js +9 -5
  356. package/core/server/services/tier-checkout-config/models.js +9 -3
  357. package/core/server/services/tier-checkout-config/queries.js +4 -4
  358. package/core/server/services/tier-checkout-config/serializers.js +16 -10
  359. package/core/server/services/tier-checkout-config/service.js +13 -12
  360. package/core/server/services/update-check/index.js +13 -13
  361. package/core/server/services/update-check/jobs/update-check-job.js +7 -0
  362. package/core/server/services/update-check/update-check-service.js +2 -2
  363. package/core/server/web/admin/controller.js +1 -1
  364. package/core/server/web/api/endpoints/admin/routes.js +19 -16
  365. package/core/shared/config/env/config.testing-mysql.json +1 -1
  366. package/core/shared/labs.js +5 -2
  367. package/package.json +24 -23
  368. package/pnpm-lock.yaml +704 -69
  369. package/pnpm-workspace.yaml +8 -5
  370. package/components/tryghost-kg-default-nodes-2.2.0.tgz +0 -0
  371. package/core/built/admin/assets/Combination-5fYEzgbs.js +0 -41
  372. package/core/built/admin/assets/account-migration-DRhAehfw.js +0 -1
  373. package/core/built/admin/assets/activitypub/inbox-BluD2ucT.js +0 -1284
  374. package/core/built/admin/assets/activitypub/label-FHSh6ZAw.js +0 -16
  375. package/core/built/admin/assets/activitypub/layout-Cq4NG0Xr.js +0 -1
  376. package/core/built/admin/assets/activitypub/settings-DQDkr06X.js +0 -315
  377. package/core/built/admin/assets/add-integration-modal-BC0jExDZ.js +0 -1
  378. package/core/built/admin/assets/add-newsletter-modal-DchTkA7l.js +0 -1
  379. package/core/built/admin/assets/add-recommendation-modal-DMvaJZKp.js +0 -1
  380. package/core/built/admin/assets/alert-dialog-QhXzdHfc.js +0 -1
  381. package/core/built/admin/assets/analytics-No1DDY3A.js +0 -1
  382. package/core/built/admin/assets/automations-DpUNUdcZ.js +0 -1
  383. package/core/built/admin/assets/bluesky-sharing-Cjrv_f62.js +0 -1
  384. package/core/built/admin/assets/color-picker-BTY_NdEm.js +0 -3
  385. package/core/built/admin/assets/color-picker-field-CPlkzOH0.js +0 -1
  386. package/core/built/admin/assets/combobox-DrMtv_4P.js +0 -1
  387. package/core/built/admin/assets/command-ZdgYJpoI.js +0 -1
  388. package/core/built/admin/assets/comments-kidj60-h.js +0 -1
  389. package/core/built/admin/assets/confirmation-context-BhbmQQEl.js +0 -1
  390. package/core/built/admin/assets/custom-field-type-option-CsGIZk1J.js +0 -10
  391. package/core/built/admin/assets/custom-integration-modal-BY37O_9X.js +0 -1
  392. package/core/built/admin/assets/design-and-theme-modal-DUSKM4uC.js +0 -22
  393. package/core/built/admin/assets/dialog-B44iRwlc.js +0 -1
  394. package/core/built/admin/assets/dirty-confirm-dialog-BxgQgQ6H.js +0 -1
  395. package/core/built/admin/assets/dist-Cy8tfrp_.js +0 -1
  396. package/core/built/admin/assets/domain-Ca6KhoQt.js +0 -1
  397. package/core/built/admin/assets/dropzone-Bb-5zQTk.js +0 -5
  398. package/core/built/admin/assets/edit-profile-BdupLlus.js +0 -1
  399. package/core/built/admin/assets/editor-BP883Lpn.js +0 -8
  400. package/core/built/admin/assets/explore-FB-CimXw.js +0 -1
  401. package/core/built/admin/assets/feed-C1GxsmI2.js +0 -1
  402. package/core/built/admin/assets/filter-sources-D5n5bFA2.js +0 -1
  403. package/core/built/admin/assets/filters-DJEzkMUK.js +0 -1
  404. package/core/built/admin/assets/filters-MZXvdH5D.js +0 -1
  405. package/core/built/admin/assets/first-promoter-modal-CGTGLCr5.js +0 -1
  406. package/core/built/admin/assets/gift-link-modal-B6v0tnRN.js +0 -1
  407. package/core/built/admin/assets/growth-BGAJD1rs.js +0 -3
  408. package/core/built/admin/assets/growth-D6mhcx3q.js +0 -1
  409. package/core/built/admin/assets/history-modal-iKwUY3XR.js +0 -1
  410. package/core/built/admin/assets/index-DjQe-e5s.js +0 -4
  411. package/core/built/admin/assets/index-Dqf2x-ry.css +0 -1
  412. package/core/built/admin/assets/index.es-VihPwfeH.js +0 -1
  413. package/core/built/admin/assets/input--W-rCTrX.js +0 -1
  414. package/core/built/admin/assets/invite-user-modal-MdImLCaJ.js +0 -1
  415. package/core/built/admin/assets/koenig-loader-DYZpm6El.js +0 -2
  416. package/core/built/admin/assets/label-picker-cB51xl1r.js +0 -1
  417. package/core/built/admin/assets/layout-c_B_1hax.js +0 -1
  418. package/core/built/admin/assets/loading-indicator-BpFWTVgh.js +0 -1
  419. package/core/built/admin/assets/member-custom-fields-qs0dIkxM.js +0 -1
  420. package/core/built/admin/assets/member-detail-B6uec2a6.js +0 -1
  421. package/core/built/admin/assets/members-BQF3CqhI.js +0 -2
  422. package/core/built/admin/assets/moderation-DY4wF1Q3.js +0 -1
  423. package/core/built/admin/assets/navigation-modal-DX-gNF3X.js +0 -1
  424. package/core/built/admin/assets/newsletter-CyQA7m3m.js +0 -1
  425. package/core/built/admin/assets/newsletter-detail-modal-BDrptuxn.js +0 -1
  426. package/core/built/admin/assets/newsletters-DXuNmC42.js +0 -1
  427. package/core/built/admin/assets/note-Cgo2LCJ6.js +0 -1
  428. package/core/built/admin/assets/notifications-BC50AMku.js +0 -1
  429. package/core/built/admin/assets/offers-container-modal-DWycIMzT.js +0 -1
  430. package/core/built/admin/assets/onboarding-DGQuV7Ew.js +0 -1
  431. package/core/built/admin/assets/overview-CVbFtn-k.js +0 -1
  432. package/core/built/admin/assets/overview-YKj7SZaK.js +0 -1
  433. package/core/built/admin/assets/pages-B6vr9F_D.js +0 -1
  434. package/core/built/admin/assets/popover-CCy0h5rq.js +0 -1
  435. package/core/built/admin/assets/portal-frame-dc4XKr0e.js +0 -1
  436. package/core/built/admin/assets/portal-modal-BvvdF_B9.js +0 -1
  437. package/core/built/admin/assets/post-analytics-DX470WRG.js +0 -1
  438. package/core/built/admin/assets/post-analytics-header-CXpJmdDv.js +0 -1
  439. package/core/built/admin/assets/posts-KY3aUhVV.js +0 -1
  440. package/core/built/admin/assets/preferences-DO0UUWFp.js +0 -5
  441. package/core/built/admin/assets/profile-CxT-0l4d.js +0 -1
  442. package/core/built/admin/assets/radio-group-Bgz60i81.js +0 -1
  443. package/core/built/admin/assets/select-DuDUFdPq.js +0 -1
  444. package/core/built/admin/assets/settings-BjCii7BM.js +0 -1
  445. package/core/built/admin/assets/settings-b8kNzZSQ.js +0 -4
  446. package/core/built/admin/assets/share-modal-BV70mr9k.js +0 -1
  447. package/core/built/admin/assets/shim-ClF_m5ux.js +0 -1
  448. package/core/built/admin/assets/slack-modal-Be2_KK-z.js +0 -1
  449. package/core/built/admin/assets/stats-C4reGh9O.js +0 -1
  450. package/core/built/admin/assets/stats-view-DP9pQ62k.js +0 -1
  451. package/core/built/admin/assets/stripe-connect-modal-Z-UT_BGc.js +0 -1
  452. package/core/built/admin/assets/tag-detail-Dc0nTOtU.js +0 -2
  453. package/core/built/admin/assets/tags-BLaXBwnb.js +0 -1
  454. package/core/built/admin/assets/testimonials-modal-sFwRnNLh.js +0 -1
  455. package/core/built/admin/assets/tier-detail-modal-BCFpWwUS.js +0 -1
  456. package/core/built/admin/assets/use-filter-params-CAvfDvf1.js +0 -1
  457. package/core/built/admin/assets/use-growth-stats-D6mZXGhK.js +0 -1
  458. package/core/built/admin/assets/use-post-referrers-DbY-mzci.js +0 -1
  459. package/core/built/admin/assets/use-reply-chain-data-BeQwz8oF.js +0 -1
  460. package/core/built/admin/assets/use-settings-navigation-BbrSUVcf.js +0 -1
  461. package/core/built/admin/assets/use-tinybird-query-B1IMyAcv.js +0 -39
  462. package/core/built/admin/assets/use-tinybird-token-Bow0Zwn8.js +0 -1
  463. package/core/built/admin/assets/user-detail-modal-yipSoQfv.js +0 -1
  464. package/core/built/admin/assets/users-5msE1WMs.js +0 -1
  465. package/core/built/admin/assets/web-CKcXAu86.js +0 -1
  466. package/core/built/admin/assets/web-DR4TqM3E.js +0 -2
  467. package/core/server/services/jobs/worker-model-event-bridge.js +0 -149
  468. package/core/server/services/members/jobs/clean-expired-comped.js +0 -132
  469. package/core/server/services/stripe/services/checkout/allowed-countries.js +0 -267
  470. package/core/server/services/stripe/services/checkout/field-ports.js +0 -34
  471. package/core/server/services/tier-checkout-config/destinations.js +0 -17
  472. package/core/server/services/update-check/run-update-check.js +0 -63
@@ -13,7 +13,7 @@ function isUnsplashImage(url) {
13
13
  }
14
14
  const { DateTime } = require('luxon');
15
15
  const htmlToPlaintext = require('@tryghost/html-to-plaintext');
16
- const EmailAddressParser = require('../email-address/email-address-parser');
16
+ const emailAddressParser = require('../email-address/email-address-parser');
17
17
  const { getEmailDesign } = require('../email-rendering/email-design');
18
18
  const { registerHelpers } = require('./helpers/register-helpers');
19
19
  const crypto = require('crypto');
@@ -229,6 +229,8 @@ function cheerioLoad(html) {
229
229
  * @prop {string} id
230
230
  * @prop {RegExp} token
231
231
  * @prop {(member: MemberLike) => string} getValue
232
+ * @prop {boolean} [trusted] - Value is server-generated, so it is inserted into the
233
+ * html body as-is instead of being HTML-escaped. Defaults to false (escaped).
232
234
  */
233
235
 
234
236
  /**
@@ -337,7 +339,7 @@ class EmailRenderer {
337
339
  }
338
340
 
339
341
  #getRawFromAddress(post, newsletter) {
340
- // Pass the raw name through; EmailAddressParser.stringify() is the single
342
+ // Pass the raw name through; emailAddressParser.stringify() is the single
341
343
  // point that escapes it for the RFC5322 quoted-string From header. Escaping
342
344
  // here too would double-escape (e.g. a title containing a double quote).
343
345
  let senderName = this.#settingsCache.get('title') || '';
@@ -394,7 +396,7 @@ class EmailRenderer {
394
396
  { useFallbackAddress },
395
397
  );
396
398
 
397
- return EmailAddressParser.stringify(addresses.from);
399
+ return emailAddressParser.stringify(addresses.from);
398
400
  }
399
401
 
400
402
  /**
@@ -423,7 +425,7 @@ class EmailRenderer {
423
425
  );
424
426
 
425
427
  if (addresses.replyTo) {
426
- return EmailAddressParser.stringify(addresses.replyTo);
428
+ return emailAddressParser.stringify(addresses.replyTo);
427
429
  }
428
430
  return null;
429
431
  }
@@ -920,18 +922,21 @@ class EmailRenderer {
920
922
  getValue: (member) => {
921
923
  return this.createUnsubscribeUrl(member.uuid, { newsletterUuid });
922
924
  },
925
+ trusted: true, // Server-generated URL, must not be HTML-escaped
923
926
  },
924
927
  {
925
928
  id: 'manage_account_url',
926
929
  getValue: () => {
927
930
  return this.createManageAccountUrl();
928
931
  },
932
+ trusted: true, // Server-generated URL, must not be HTML-escaped
929
933
  },
930
934
  {
931
935
  id: 'uuid',
932
936
  getValue: (member) => {
933
937
  return member.uuid;
934
938
  },
939
+ trusted: true, // Server-generated identifier
935
940
  },
936
941
  {
937
942
  id: 'key',
@@ -941,6 +946,7 @@ class EmailRenderer {
941
946
  .update(member.uuid)
942
947
  .digest('hex');
943
948
  },
949
+ trusted: true, // Server-generated hmac
944
950
  },
945
951
  {
946
952
  id: 'first_name',
@@ -1000,6 +1006,7 @@ class EmailRenderer {
1000
1006
  return this.createUnsubscribeUrl(member.uuid, { newsletterUuid });
1001
1007
  },
1002
1008
  required: true, // Used in email headers
1009
+ trusted: true, // Server-generated URL, must not be HTML-escaped
1003
1010
  },
1004
1011
  // Unique ID used for ad images to bypass ESP image proxies
1005
1012
  {
@@ -1007,6 +1014,7 @@ class EmailRenderer {
1007
1014
  getValue: () => {
1008
1015
  return crypto.randomUUID();
1009
1016
  },
1017
+ trusted: true, // Server-generated identifier
1010
1018
  },
1011
1019
  ];
1012
1020
 
@@ -1043,6 +1051,7 @@ class EmailRenderer {
1043
1051
  getValue: fallback
1044
1052
  ? (member) => definition.getValue(member) || fallback
1045
1053
  : definition.getValue,
1054
+ trusted: definition.trusted === true,
1046
1055
  });
1047
1056
  }
1048
1057
  }
@@ -1056,6 +1065,7 @@ class EmailRenderer {
1056
1065
  originalId: definition.id,
1057
1066
  token: new RegExp(`%%\\{${definition.id}\\}%%`, 'g'),
1058
1067
  getValue: definition.getValue,
1068
+ trusted: definition.trusted === true,
1059
1069
  });
1060
1070
  }
1061
1071
  }
@@ -1,5 +1,4 @@
1
1
  const debug = require('@tryghost/debug')('i18n');
2
- const logging = require('@tryghost/logging');
3
2
  const url = require('../../api/endpoints/utils/serializers/output/utils/url');
4
3
  const events = require('../../lib/common/events');
5
4
 
@@ -55,12 +54,6 @@ class EmailServiceWrapper {
55
54
  const emailAnalyticsJobs = require('../email-analytics/jobs');
56
55
  const { cachedImageSizeFromUrl } = require('../../lib/image');
57
56
 
58
- // capture errors from mailgun client and log them in sentry
59
- const errorHandler = (error) => {
60
- logging.info(`Capturing error for mailgun email provider service`);
61
- sentry.captureException(error);
62
- };
63
-
64
57
  // Mailgun client instance for email provider
65
58
  const mailgunClient = new MailgunClient({
66
59
  config: configService,
@@ -78,7 +71,6 @@ class EmailServiceWrapper {
78
71
  const mailgunEmailProvider = new MailgunEmailProvider({
79
72
  mailgunClient,
80
73
  config: configService,
81
- errorHandler,
82
74
  });
83
75
 
84
76
  const emailRenderer = new EmailRenderer({
@@ -134,7 +126,6 @@ class EmailServiceWrapper {
134
126
  db,
135
127
  sentry,
136
128
  getRequiredUrlRelations,
137
- debugStorageFilePath: configService.getContentPath('data'),
138
129
  });
139
130
 
140
131
  if (ghostServer) {
@@ -1,6 +1,7 @@
1
1
  const logging = require('@tryghost/logging');
2
2
  const errors = require('@tryghost/errors');
3
3
  const debug = require('@tryghost/debug')('email-service:mailgun-provider-service');
4
+ const { escapeExpression } = require('handlebars');
4
5
 
5
6
  /**
6
7
  * @typedef {object} Config
@@ -35,35 +36,41 @@ const debug = require('@tryghost/debug')('email-service:mailgun-provider-service
35
36
  class MailgunEmailProvider {
36
37
  #mailgunClient;
37
38
  #config;
38
- #errorHandler;
39
39
 
40
40
  /**
41
41
  * @param {object} dependencies
42
42
  * @param {import('../lib/mailgun-client')} dependencies.mailgunClient - mailgun client to send emails
43
43
  * @param {Config} dependencies.config
44
- * @param {Function} [dependencies.errorHandler] - custom error handler for logging exceptions
45
44
  */
46
- constructor({ mailgunClient, config, errorHandler }) {
45
+ constructor({ mailgunClient, config }) {
47
46
  this.#mailgunClient = mailgunClient;
48
47
  this.#config = config;
49
- this.#errorHandler = errorHandler;
50
48
  }
51
49
 
52
- #createRecipientData(replacements) {
50
+ #createRecipientData(replacements, htmlEscapedIds) {
53
51
  let recipientData = {};
54
52
 
55
53
  recipientData = replacements.reduce((acc, replacement) => {
56
54
  const { id, value } = replacement;
57
55
  acc[id] = value;
56
+ // Mailgun's recipient-variables substitution is a simple string replace with
57
+ // no HTML awareness, and the same value is used for both the html and plaintext
58
+ // bodies. Member-controlled values get an extra, escaped variant that only the
59
+ // html body points at. Trusted server-generated values (urls, uuids, hmacs) are
60
+ // skipped so their URLs don't end up entity-encoded inside hrefs.
61
+ if (htmlEscapedIds.has(id)) {
62
+ acc[`${id}_html`] = typeof value === 'string' ? escapeExpression(value) : value;
63
+ }
58
64
  return acc;
59
65
  }, {});
60
66
 
61
67
  return recipientData;
62
68
  }
63
69
 
64
- #updateRecipientVariables(data, replacementDefinitions) {
70
+ #updateRecipientVariables(data, replacementDefinitions, isHtml) {
65
71
  for (const def of replacementDefinitions) {
66
- data = data.replace(def.token, `%recipient.${def.id}%`);
72
+ const useHtmlVariant = isHtml && !def.trusted;
73
+ data = data.replace(def.token, `%recipient.${def.id}${useHtmlVariant ? '_html' : ''}%`);
67
74
  }
68
75
  return data;
69
76
  }
@@ -128,8 +135,11 @@ class MailgunEmailProvider {
128
135
  }
129
136
 
130
137
  // create recipient data for Mailgun using replacement definitions
138
+ const htmlEscapedIds = new Set(
139
+ replacementDefinitions.filter((def) => !def.trusted).map((def) => def.id),
140
+ );
131
141
  const recipientData = recipients.reduce((acc, recipient) => {
132
- acc[recipient.email] = this.#createRecipientData(recipient.replacements);
142
+ acc[recipient.email] = this.#createRecipientData(recipient.replacements, htmlEscapedIds);
133
143
  return acc;
134
144
  }, {});
135
145
 
@@ -139,6 +149,7 @@ class MailgunEmailProvider {
139
149
  messageData[key] = this.#updateRecipientVariables(
140
150
  messageData[key],
141
151
  replacementDefinitions,
152
+ key === 'html',
142
153
  );
143
154
  }
144
155
  });
@@ -165,7 +176,7 @@ class MailgunEmailProvider {
165
176
  message: this.#createMailgunErrorMessage(error),
166
177
  errorDetails: JSON.stringify({ error, messageData }),
167
178
  context: `Mailgun Error ${error.status}: ${error.details}`,
168
- help: `https://ghost.org/docs/newsletters/#bulk-email-configuration`,
179
+ help: `https://docs.ghost.org/newsletters/#bulk-email-configuration`,
169
180
  code: 'BULK_EMAIL_SEND_FAILED',
170
181
  });
171
182
  } else {
@@ -31,9 +31,9 @@
31
31
  <tr>
32
32
  <td align="left" style="padding-bottom: 22px; text-align: left;">
33
33
  {{#if siteIconUrl}}
34
- <a href="{{siteUrl}}"><img src="{{siteIconUrl}}" alt="{{siteTitle}}" border="0" width="48" height="48" style="border-radius: 4px;"></a>
34
+ <img src="{{siteIconUrl}}" alt="{{siteTitle}}" border="0" width="48" height="48" style="border-radius: 4px;">
35
35
  {{else}}
36
- <a href="{{siteUrl}}" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 17px; font-weight: 700; color: {{accentColor}}; text-decoration: none;">{{siteTitle}}</a>
36
+ <span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 17px; font-weight: 700; color: {{accentColor}};">{{siteTitle}}</span>
37
37
  {{/if}}
38
38
  </td>
39
39
  </tr>
@@ -92,7 +92,7 @@
92
92
  </tr>
93
93
  <tr>
94
94
  <td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top; padding-top: 40px;">
95
- <p class="small" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; line-height: 16px; font-size: 11px; color: #738A94; font-weight: normal; margin: 0;">{{t 'This message was sent from {siteDomain} to {email} on behalf of {buyerName} ({buyerEmail}).' siteDomain=(linkTag siteUrl siteDomain class="small" style="text-decoration: underline; color: #738A94; font-size: 11px;") email=(linkTag (mailto toEmail) toEmail class="small" style="text-decoration: underline; color: #738A94; font-size: 11px;") buyerName=buyerName buyerEmail=(linkTag (mailto buyerEmail) buyerEmail class="small" style="text-decoration: underline; color: #738A94; font-size: 11px;")}}</p>
95
+ <p class="small" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; line-height: 16px; font-size: 11px; color: #738A94; font-weight: normal; margin: 0;">{{t 'This message was sent from {siteDomain} to {email} on behalf of {buyerName} ({buyerEmail}).' siteDomain=siteDomain email=toEmail buyerName=buyerName buyerEmail=buyerEmail}}</p>
96
96
  </td>
97
97
  </tr>
98
98
  </table>
@@ -182,7 +182,6 @@ class GiftEmailService {
182
182
  const giftLink = `${siteUrl.replace(/\/$/, '')}/gift/${token}`;
183
183
  const { html, text } = await this.renderer.renderDelivery({
184
184
  siteTitle,
185
- siteUrl,
186
185
  siteIconUrl: this.blogIcon.getIconUrl({ absolute: true, fallbackToDefault: false }),
187
186
  siteDomain,
188
187
  accentColor: this.accentColor,
@@ -14,7 +14,7 @@ const send_gift_delivery_event_1 = require("./events/send-gift-delivery-event");
14
14
  // Persistent scheduling adapters keep their queue across restarts and opt out
15
15
  // of boot-time rebuilds (same contract post scheduling honours in boot.js).
16
16
  let rescheduleDeliveriesOnBoot = true;
17
- async function init(options) {
17
+ function init(options) {
18
18
  if (exports.service) {
19
19
  return;
20
20
  }
@@ -37,7 +37,7 @@ async function init(options) {
37
37
  const labsService = require('../../../shared/labs');
38
38
  const urlUtils = require('../../../shared/url-utils').default;
39
39
  const settingsHelpers = require('../settings-helpers');
40
- const EmailAddressParser = require('../email-address/email-address-parser');
40
+ const emailAddressParser = require('../email-address/email-address-parser');
41
41
  const { blogIcon } = require('../../../server/lib/image');
42
42
  const { t } = require('../i18n');
43
43
  const repository = new gift_bookshelf_repository_1.GiftBookshelfRepository({
@@ -57,7 +57,7 @@ async function init(options) {
57
57
  bulkMailer: new MailgunClient({ config, settings: settingsCache }),
58
58
  settingsCache,
59
59
  urlUtils,
60
- getFromAddress: () => EmailAddressParser.stringify(settingsHelpers.getDefaultEmail()),
60
+ getFromAddress: () => emailAddressParser.stringify(settingsHelpers.getDefaultEmail()),
61
61
  getReplyToAddress: () => settingsHelpers.getMembersSupportAddress(),
62
62
  blogIcon,
63
63
  t,
@@ -1,6 +1,6 @@
1
1
  const path = require('path');
2
2
  const logging = require('@tryghost/logging');
3
- const jobsService = require('../../jobs');
3
+ const jobManager = require('../../jobs');
4
4
  const CleanGiftsJob = require('./clean-gifts-job').default;
5
5
 
6
6
  let hasScheduled = {
@@ -31,7 +31,7 @@ function scheduleJob(key, name, jobFile) {
31
31
  const at = randomOffPeakDailyCron();
32
32
 
33
33
  logging.info(`[Background Job] ${name} scheduled at ${at}`);
34
- jobsService.addJob({
34
+ jobManager.addJob({
35
35
  at,
36
36
  job: path.resolve(__dirname, jobFile),
37
37
  name,
@@ -43,14 +43,14 @@ function scheduleJob(key, name, jobFile) {
43
43
  }
44
44
 
45
45
  module.exports = {
46
- async scheduleGiftCleanupJob(classBasedJobs) {
46
+ async scheduleGiftCleanupJob(jobsService) {
47
47
  if (alreadyScheduledOrTest('cleanup')) {
48
48
  return;
49
49
  }
50
50
 
51
51
  const cron = randomOffPeakDailyCron();
52
52
  logging.info(`[Background Job] clean-gifts scheduled at ${cron}`);
53
- await classBasedJobs.scheduleRecurring(new CleanGiftsJob(), { cron });
53
+ await jobsService.scheduleRecurring(new CleanGiftsJob(), { cron });
54
54
 
55
55
  hasScheduled.cleanup = true;
56
56
  },
@@ -160,7 +160,7 @@ class IndexNowPingService {
160
160
  err,
161
161
  message: err.message,
162
162
  context: (0, tpl_1.default)(constants_1.messages.requestFailedError, { service: 'IndexNow' }),
163
- help: (0, tpl_1.default)(constants_1.messages.requestFailedHelp, { url: 'https://ghost.org/docs/' }),
163
+ help: (0, tpl_1.default)(constants_1.messages.requestFailedHelp, { url: 'https://docs.ghost.org/' }),
164
164
  }),
165
165
  };
166
166
  }
@@ -181,7 +181,7 @@ class IndexNowPingService {
181
181
  err,
182
182
  message: err.message,
183
183
  context: (0, tpl_1.default)(constants_1.messages.requestFailedError, { service: 'IndexNow' }),
184
- help: (0, tpl_1.default)(constants_1.messages.requestFailedHelp, { url: 'https://ghost.org/docs/' }),
184
+ help: (0, tpl_1.default)(constants_1.messages.requestFailedHelp, { url: 'https://docs.ghost.org/' }),
185
185
  }),
186
186
  };
187
187
  }
@@ -30,7 +30,9 @@ async function accept(invitation) {
30
30
  throw new errors.NotFoundError({ message: tpl(messages.inviteExpired) });
31
31
  }
32
32
 
33
- let user = await models.User.findOne({ email: data.email }, options);
33
+ const email = invite.get('email');
34
+
35
+ let user = await models.User.findOne({ email }, options);
34
36
  if (user) {
35
37
  throw new errors.ValidationError({
36
38
  message: tpl(messages.inviteEmailAlreadyExist.message),
@@ -45,7 +47,7 @@ async function accept(invitation) {
45
47
 
46
48
  await models.User.add(
47
49
  {
48
- email: data.email,
50
+ email,
49
51
  name: data.name,
50
52
  password: data.password,
51
53
  roles: [roleId],
@@ -9,22 +9,13 @@ const models = require('../../models');
9
9
  const sentry = require('../../../shared/sentry');
10
10
  const domainEvents = require('@tryghost/domain-events');
11
11
  const config = require('../../../shared/config');
12
- const WorkerModelEventBridge = require('./worker-model-event-bridge');
13
12
  const errorHandler = (error, workerMeta) => {
14
13
  logging.error(error, `[Background Job] ${workerMeta.name} failed`);
15
14
  sentry.captureException(error);
16
15
  };
17
16
  const events = require('../../lib/common/events');
18
- const workerModelEventBridge = new WorkerModelEventBridge({ models, events, logging, sentry });
19
17
 
20
18
  const workerMessageHandler = ({ name, message }) => {
21
- if (workerModelEventBridge.isModelEventMessage(message)) {
22
- // Carries its own `eventName` rather than job-manager's reserved `event` key,
23
- // so it routes through the bridge instead of being dispatched as a raw domain event.
24
- workerModelEventBridge.handle(message, { jobName: name });
25
- return;
26
- }
27
-
28
19
  if (typeof message === 'string' && !['done', 'cancelled'].includes(message)) {
29
20
  logging.info(`[Background Job] ${name}: ${message}`);
30
21
  }
@@ -37,25 +37,35 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.default = registerJobHandlers;
40
- const errors_1 = __importDefault(require("@tryghost/errors"));
41
40
  const clean_tokens_job_1 = __importDefault(require("../members/jobs/clean-tokens-job"));
42
- const clean_tokens_task_1 = __importDefault(require("../members/jobs/clean-tokens-task"));
43
- const gifts = __importStar(require("../gifts"));
41
+ const clean_expired_comped_job_1 = __importDefault(require("../members/jobs/clean-expired-comped-job"));
44
42
  const clean_gifts_job_1 = __importDefault(require("../gifts/jobs/clean-gifts-job"));
45
43
  const external_media_inliner_job_1 = __importDefault(require("../media-inliner/external-media-inliner-job"));
46
- function registerJobHandlers({ jobsService, db, logging, mediaInliner, }) {
44
+ const content_csv_import_job_1 = __importDefault(require("../content-import/jobs/content-csv-import-job"));
45
+ const contentImport = __importStar(require("../content-import"));
46
+ const update_check_job_1 = __importDefault(require("../update-check/jobs/update-check-job"));
47
+ const process_webmention_job_1 = __importDefault(require("../mentions/process-webmention-job"));
48
+ const updateCheck = require('../update-check');
49
+ function registerJobHandlers({ jobsService, memberJobs, giftService, mediaInliner, mentionsController, }) {
47
50
  jobsService.handle(clean_tokens_job_1.default, async () => {
48
- await (0, clean_tokens_task_1.default)({ db, logging });
51
+ await memberJobs.cleanTokens();
52
+ });
53
+ jobsService.handle(clean_expired_comped_job_1.default, async () => {
54
+ await memberJobs.cleanExpiredComped();
49
55
  });
50
56
  jobsService.handle(clean_gifts_job_1.default, async () => {
51
- if (!gifts.service) {
52
- throw new errors_1.default.IncorrectUsageError({
53
- message: 'clean-gifts ran before the gifts service was initialised',
54
- });
55
- }
56
- await gifts.service.cleanup();
57
+ await giftService.cleanup();
57
58
  });
58
59
  jobsService.handle(external_media_inliner_job_1.default, async (job) => {
59
60
  await mediaInliner.inline(job.domains);
60
61
  });
62
+ jobsService.handle(content_csv_import_job_1.default, async (job) => {
63
+ await contentImport.handleJob(job);
64
+ });
65
+ jobsService.handle(update_check_job_1.default, async () => {
66
+ await updateCheck({ rethrowErrors: true });
67
+ });
68
+ jobsService.handle(process_webmention_job_1.default, async (job) => {
69
+ await mentionsController.processWebmention(job);
70
+ });
61
71
  }
@@ -17,7 +17,7 @@ const messages = {
17
17
  reason: ' Reason: {reason}.',
18
18
  messageSent: 'Message sent. Double check inbox and spam folder!',
19
19
  };
20
- const EmailAddressParser = require('../email-address/email-address-parser');
20
+ const emailAddressParser = require('../email-address/email-address-parser');
21
21
  const DEFAULT_TAGS = ['ghost-email', 'transactional-email'];
22
22
  const MAX_MAILGUN_TAGS = 10;
23
23
 
@@ -54,8 +54,8 @@ function getFromAddress(requestedFromAddress, requestedReplyToAddress) {
54
54
  }
55
55
 
56
56
  return {
57
- from: EmailAddressParser.stringify(addresses.from),
58
- replyTo: addresses.replyTo ? EmailAddressParser.stringify(addresses.replyTo) : null,
57
+ from: emailAddressParser.stringify(addresses.from),
58
+ replyTo: addresses.replyTo ? emailAddressParser.stringify(addresses.replyTo) : null,
59
59
  };
60
60
  }
61
61
 
@@ -100,7 +100,7 @@ function createMessage(message) {
100
100
  */
101
101
  function createMailError({ message, err, ignoreDefaultMessage } = { message: '' }) {
102
102
  const helpMessage = tpl(messages.checkEmailConfigInstructions, {
103
- url: 'https://ghost.org/docs/config/#mail',
103
+ url: 'https://docs.ghost.org/config/#mail',
104
104
  });
105
105
  const defaultErrorMessage = tpl(messages.failedSendingEmailError);
106
106
 
@@ -7,7 +7,7 @@ const MagicLink = require('../lib/magic-link/magic-link');
7
7
  const sentry = require('../../../shared/sentry');
8
8
  const emailAddressService = require('../email-address');
9
9
  const settingsHelpers = require('../settings-helpers');
10
- const EmailAddressParser = require('../email-address/email-address-parser');
10
+ const emailAddressParser = require('../email-address/email-address-parser');
11
11
  const mail = require('../mail');
12
12
  const MailgunClient = require('../lib/mailgun-client');
13
13
  const config = require('../../../shared/config');
@@ -152,7 +152,7 @@ class MemberWelcomeEmailService {
152
152
  },
153
153
  });
154
154
 
155
- const from = EmailAddressParser.stringify(fromAddresses.from);
155
+ const from = emailAddressParser.stringify(fromAddresses.from);
156
156
  const replyToSetting = newsletter.get('sender_reply_to');
157
157
  let replyTo = null;
158
158
 
@@ -173,7 +173,7 @@ class MemberWelcomeEmailService {
173
173
  });
174
174
 
175
175
  if (addresses.replyTo) {
176
- replyTo = EmailAddressParser.stringify(addresses.replyTo);
176
+ replyTo = emailAddressParser.stringify(addresses.replyTo);
177
177
  }
178
178
  }
179
179
 
@@ -199,10 +199,10 @@ class MemberWelcomeEmailService {
199
199
  async #getEffectiveSenderOptions(automatedSender = {}) {
200
200
  const defaultOptions = await this.#getSenderOptions();
201
201
  const defaultFrom =
202
- EmailAddressParser.parse(defaultOptions.from || '') ||
202
+ emailAddressParser.parse(defaultOptions.from || '') ||
203
203
  emailAddressService.service.defaultFromEmail;
204
204
  const defaultReplyTo = defaultOptions.replyTo
205
- ? EmailAddressParser.parse(defaultOptions.replyTo)
205
+ ? emailAddressParser.parse(defaultOptions.replyTo)
206
206
  : undefined;
207
207
 
208
208
  const senderName = trimValue(automatedSender.senderName) || defaultFrom?.name || undefined;
@@ -218,10 +218,10 @@ class MemberWelcomeEmailService {
218
218
  });
219
219
 
220
220
  return {
221
- from: EmailAddressParser.stringify(addresses.from),
221
+ from: emailAddressParser.stringify(addresses.from),
222
222
  ...(addresses.replyTo
223
223
  ? {
224
- replyTo: EmailAddressParser.stringify(addresses.replyTo),
224
+ replyTo: emailAddressParser.stringify(addresses.replyTo),
225
225
  }
226
226
  : {}),
227
227
  };
@@ -274,6 +274,7 @@ function createApiInstance(config) {
274
274
  // two together in boot order. Custom fields is initialised in initCore, the
275
275
  // members API is built in initServices, so this is always the live instance.
276
276
  customFieldValues: customFieldsService.values,
277
+ customFieldDefinitions: customFieldsService.definitions,
277
278
  });
278
279
 
279
280
  return membersApiInstance;
@@ -43,19 +43,12 @@ function parse(path, headerMapping) {
43
43
  // hasOwn, not `in`: a prototype-named header would otherwise match an
44
44
  // inherited method on the mapping and take a function as its mapped name.
45
45
  if (headerMapping && Object.hasOwn(headerMapping, header)) {
46
- // An empty target is the caller naming a column to leave out, which
47
- // it has to name: an unnamed column carries through below, and for a
48
- // custom_fields.* column carrying through means being imported. So
49
- // omitting a column from the mapping is the opposite of excluding it.
50
46
  if (!headerMapping[header]) {
51
47
  continue;
52
48
  }
53
49
  row[headerMapping[header]] = value;
54
50
  }
55
51
  else if (isSafeColumnName(header)) {
56
- // Carry any unmapped column through untouched, so the import is not
57
- // constrained to a known vocabulary: a custom_fields.* column
58
- // survives parsing even though nothing consumes it yet.
59
52
  row[header] = value;
60
53
  }
61
54
  }
@@ -55,8 +55,6 @@ function humaniseError(row) {
55
55
  function stringifyLabels(labels) {
56
56
  return labels.map((label) => (typeof label === 'string' ? label : label.name)).join(',');
57
57
  }
58
- // The custom_fields.* cells a submitted row carried, echoed untouched so a manager can
59
- // fix a failed row and re-upload the values they mapped.
60
58
  function customFieldCells(row) {
61
59
  return Object.fromEntries(Object.entries(row).filter(([column]) => (0, csv_2.isCustomFieldColumn)(column)));
62
60
  }
@@ -82,9 +80,8 @@ function toErrorReportRow(row) {
82
80
  }
83
81
  // The error report attached to the completion email: the failed rows as CSV, called only
84
82
  // when there are rows to list. It shares the serialiser with the export but not the
85
- // shaping -- the export writes db members, this echoes submitted rows. Member columns come from the shaper's keys (so the type
86
- // stays the single source); the custom_fields.* columns across the rows are threaded in
87
- // before the last error column, and each row's custom cells merged on.
83
+ // shaping -- the export writes db members, this echoes submitted rows. Member columns
84
+ // come from the shaper's keys, so the type stays the single source.
88
85
  function buildErrorReport(errors) {
89
86
  const memberColumns = Object.keys(toErrorReportRow(errors[0])).filter((column) => column !== 'error');
90
87
  const customColumns = [...new Set(errors.flatMap((row) => Object.keys(customFieldCells(row))))];
@@ -16,9 +16,6 @@ const optionalCell = zod_1.z
16
16
  // not defaulted), so a CSV lacking these columns leaves the member's state untouched.
17
17
  const isSubscribed = (cell) => cell.toLowerCase() !== 'false';
18
18
  const isComplimentary = (cell) => cell.toLowerCase() === 'true';
19
- // The member import vocabulary as a schema: the single source of truth that coerces the
20
- // raw string Row into typed member fields. Unknown columns (custom_fields.*, and anything
21
- // else a source carries) pass through via .loose() so nothing is lost before the kernel.
22
19
  exports.memberImportRowSchema = zod_1.z
23
20
  .object({
24
21
  id: optionalCell,
@@ -12,7 +12,6 @@ const exporter_1 = __importDefault(require("./export/exporter"));
12
12
  const MembersCSVImporterStripeUtils = require('./import/stripe-utils');
13
13
  const db = require('../../../data/db');
14
14
  const models = require('../../../models');
15
- const labs = require('../../../../shared/labs');
16
15
  const logging = require('@tryghost/logging');
17
16
  const sentry = require('../../../../shared/sentry');
18
17
  // Build the members CSV importer. This is the composition root: today's models and
@@ -57,11 +56,8 @@ function makeImporter(deps) {
57
56
  transacting: options.transacting,
58
57
  }),
59
58
  };
60
- // Gated by the same labs flag as the export, so the two halves round-trip or stay
61
- // silent together: off, activeFields resolves empty and every custom_fields.* column
62
- // is dropped.
63
59
  const customFields = {
64
- activeFields: async () => labs.isSet('membersCustomFields') ? deps.customFields.definitions.browse() : [],
60
+ activeFields: async () => deps.customFields.definitions.browse(),
65
61
  planWrite: (values) => deps.customFields.values.planWrite(values),
66
62
  // Every value the import writes came out of the file, whichever column carried it.
67
63
  // An import has no id to give until runs are tracked, so it names its kind only.
@@ -105,9 +101,7 @@ function makeImporter(deps) {
105
101
  }
106
102
  // Build the members CSV exporter. The same composition root from the other direction:
107
103
  // knex and the members id lookup are wired here, and the custom fields definitions and
108
- // values services are injected (boot builds them before this one). The labs flag alone
109
- // decides whether custom field columns appear, so nothing flag-shaped leaks into the
110
- // exporter itself.
104
+ // values services are injected (boot builds them before this one).
111
105
  function makeExporter({ definitions, values, }) {
112
106
  const exporter = new exporter_1.default({
113
107
  knex: db.knex,
@@ -126,9 +120,8 @@ function makeExporter({ definitions, values, }) {
126
120
  },
127
121
  customFields: {
128
122
  // Boot builds the definitions and values services before this one, so they
129
- // are always present -- no not-initialised state to guard. The flag decides
130
- // whether their columns are included at all.
131
- activeDefinitions: async () => labs.isSet('membersCustomFields') ? definitions.browse() : [],
123
+ // are always present -- no not-initialised state to guard.
124
+ activeDefinitions: async () => definitions.browse(),
132
125
  valuesForMembers: (memberIds) => values.getValuesForMembers(memberIds),
133
126
  },
134
127
  });
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const job_1 = require("../../jobs-service/job");
4
+ class CleanExpiredCompedJob extends job_1.Job {
5
+ static type = 'clean-expired-comped';
6
+ }
7
+ exports.default = CleanExpiredCompedJob;