ghost 6.61.0 → 6.63.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 (619) 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-i18n-0.0.0.tgz +0 -0
  11. package/components/tryghost-kg-card-factory-5.2.4.tgz +0 -0
  12. package/components/tryghost-kg-clean-basic-html-4.3.4.tgz +0 -0
  13. package/components/tryghost-kg-converters-1.2.5.tgz +0 -0
  14. package/components/tryghost-kg-default-cards-10.3.5.tgz +0 -0
  15. package/components/tryghost-kg-default-nodes-2.2.1.tgz +0 -0
  16. package/components/tryghost-kg-default-transforms-1.3.4.tgz +0 -0
  17. package/components/tryghost-kg-html-to-lexical-1.4.0.tgz +0 -0
  18. package/components/tryghost-kg-lexical-html-renderer-1.5.0.tgz +0 -0
  19. package/components/tryghost-kg-markdown-html-renderer-7.2.4.tgz +0 -0
  20. package/components/tryghost-kg-utils-1.1.4.tgz +0 -0
  21. package/components/tryghost-limit-service-0.0.0.tgz +0 -0
  22. package/components/tryghost-metafield-types-0.0.0.tgz +0 -0
  23. package/components/tryghost-nql-string-0.0.0.tgz +0 -0
  24. package/components/tryghost-parse-email-address-0.0.0.tgz +0 -0
  25. package/content/settings/README.md +1 -1
  26. package/content/themes/casper/.gitignore +28 -0
  27. package/content/themes/casper/assets/built/casper.js +1 -1
  28. package/content/themes/casper/assets/built/screen.css +1 -1
  29. package/content/themes/casper/assets/css/screen.css +2 -1
  30. package/content/themes/casper/assets/js/lightbox.js +63 -46
  31. package/content/themes/casper/package.json +6 -6
  32. package/content/themes/casper/page.hbs +1 -0
  33. package/content/themes/casper/post.hbs +1 -0
  34. package/content/themes/source/.gitignore +28 -0
  35. package/content/themes/source/assets/built/screen.css +1 -1
  36. package/content/themes/source/assets/built/source.js +1 -1
  37. package/content/themes/source/assets/css/screen.css +2 -1
  38. package/content/themes/source/assets/js/lightbox.js +62 -45
  39. package/content/themes/source/assets/js/main.js +2 -2
  40. package/content/themes/source/package.json +4 -4
  41. package/content/themes/source/partials/feature-image.hbs +1 -0
  42. package/content/themes/source/partials/post-card.hbs +1 -1
  43. package/core/boot.js +61 -27
  44. package/core/built/admin/assets/Combination-B0l4MKVh.js +41 -0
  45. package/core/built/admin/assets/InterVariable-DiVDrmQJ.woff2 +0 -0
  46. package/core/built/admin/assets/InterVariable-Italic-FCBEiFp6.woff2 +0 -0
  47. package/core/built/admin/assets/{about-Bve7IJS2.js → about-C1C3s5-g.js} +1 -1
  48. package/core/built/admin/assets/accordion-CxGsDKwa.js +1 -0
  49. package/core/built/admin/assets/account-migration-CbUhW6gk.js +1 -0
  50. package/core/built/admin/assets/activitypub/{account-migration-C-aej4x_.js → account-migration-KA6Jjf9L.js} +16 -16
  51. package/core/built/admin/assets/activitypub/activitypub.js +9 -9
  52. package/core/built/admin/assets/activitypub/{avatar-DLPL3Abs.js → avatar-DVJF5bxP.js} +2 -2
  53. package/core/built/admin/assets/activitypub/{avatar-flipboard-C9iDY-QV.js → avatar-flipboard-csQaNeYK.js} +2 -2
  54. package/core/built/admin/assets/activitypub/{bluesky-sharing-BXkA5mqV.js → bluesky-sharing-C7nTDMvw.js} +37 -37
  55. package/core/built/admin/assets/activitypub/{content-formatters-CHcyMFk4.js → content-formatters-CLcjaBwV.js} +4 -4
  56. package/core/built/admin/assets/activitypub/{copy-DIAOQoCZ.js → copy-DcOh8kXw.js} +2 -2
  57. package/core/built/admin/assets/activitypub/{domain-B3ihkPde.js → domain-fZ-X8i4-.js} +121 -121
  58. package/core/built/admin/assets/activitypub/{edit-profile-DsZM3rTX.js → edit-profile-BqMLQV88.js} +40 -40
  59. package/core/built/admin/assets/activitypub/{explore-BodNrZgR.js → explore-B4yPoP8E.js} +27 -27
  60. package/core/built/admin/assets/activitypub/{feed-PwH1iJ84.js → feed-BRC_mvAe.js} +51 -51
  61. package/core/built/admin/assets/activitypub/{field-D06-kmOJ.js → field-COacNgOt.js} +3 -3
  62. package/core/built/admin/assets/activitypub/{hash-Bm3WxYN4.js → hash-C7u-irQQ.js} +2 -2
  63. package/core/built/admin/assets/activitypub/inbox-BW-yvUoN.js +1284 -0
  64. package/core/built/admin/assets/activitypub/{inbox-d8oJRTf4.js → inbox-CbTTdDQ3.js} +2 -2
  65. package/core/built/admin/assets/activitypub/label-kPMmYI7l.js +16 -0
  66. package/core/built/admin/assets/activitypub/layout-BL4_jtuV.js +1 -0
  67. package/core/built/admin/assets/activitypub/{moderation-D1Yapsod.js → moderation-CuidJzc0.js} +91 -91
  68. package/core/built/admin/assets/activitypub/{note-C5zjqq5C.js → note-CAMRRSqD.js} +24 -24
  69. package/core/built/admin/assets/activitypub/{notifications-B9p8eCHD.js → notifications-BmNlXGgp.js} +51 -51
  70. package/core/built/admin/assets/activitypub/{onboarding-CNelD_uF.js → onboarding-Bqg7fh_L.js} +2 -2
  71. package/core/built/admin/assets/activitypub/{onboarding-mat5Hrl0.js → onboarding-Dmun9jr_.js} +2 -2
  72. package/core/built/admin/assets/activitypub/{preferences-BCqUdC3v.js → preferences--oH19wf9.js} +1519 -1519
  73. package/core/built/admin/assets/activitypub/{profile-BRCWoFem.js → profile-DH_tQx2D.js} +185 -185
  74. package/core/built/admin/assets/activitypub/{reply-DYK5vVqb.js → reply-Cap9PxSH.js} +2 -2
  75. package/core/built/admin/assets/activitypub/{routes-BSXT992i.js → routes-DdyY9uFF.js} +744 -735
  76. package/core/built/admin/assets/activitypub/{separator-BbQqTm-p.js → separator-CAxxu8VV.js} +3 -3
  77. package/core/built/admin/assets/activitypub/settings-B6EEcVkW.js +315 -0
  78. package/core/built/admin/assets/activitypub/{site-DHoMupSB.js → site-BYps63oh.js} +2 -2
  79. package/core/built/admin/assets/activitypub/{step-1-B-YfsVeO.js → step-1-CKjR2KAm.js} +6 -6
  80. package/core/built/admin/assets/activitypub/{step-2-DtPQzlTH.js → step-2-B6PKfOUQ.js} +6 -6
  81. package/core/built/admin/assets/activitypub/{step-3-D6BFMXL_.js → step-3-C-qBbcUo.js} +11 -11
  82. package/core/built/admin/assets/activitypub/{tabs-GpNecvfB.js → tabs-DLhZtVde.js} +306 -306
  83. package/core/built/admin/assets/activitypub/{topic-filter-BPDeQQys.js → topic-filter-DsUOuu0k.js} +3 -3
  84. package/core/built/admin/assets/activitypub/{use-activity-pub-queries-BoVOxXkV.js → use-activity-pub-queries-CX9snsLs.js} +3 -3
  85. package/core/built/admin/assets/activitypub/{use-navigate-with-base-path-Bmk5h4lW.js → use-navigate-with-base-path-DsJTGDSS.js} +988 -959
  86. package/core/built/admin/assets/activitypub/{use-reply-chain-data-wVBX7swM.js → use-reply-chain-data-AJi9zkzm.js} +30 -30
  87. package/core/built/admin/assets/activitypub/{users-CoX6FT_K.js → users-inweyKL5.js} +192 -164
  88. package/core/built/admin/assets/activitypub/{x-DbQZOLiI.js → x-DR8AT3-4.js} +2 -2
  89. package/core/built/admin/assets/add-integration-modal-BT_onDJy.js +1 -0
  90. package/core/built/admin/assets/add-newsletter-modal-Cx1kQpiY.js +1 -0
  91. package/core/built/admin/assets/add-recommendation-modal-B5nvAhvr.js +1 -0
  92. package/core/built/admin/assets/analytics-DjoJWPI7.js +1 -0
  93. package/core/built/admin/assets/{announcement-bar-modal-DM3cYOpo.js → announcement-bar-modal-Dwd0EGFP.js} +1 -1
  94. package/core/built/admin/assets/{api-keys-3-0vJC3Y.js → api-keys-BGPzLHzA.js} +1 -1
  95. package/core/built/admin/assets/{api-keys-BLm2NDBh.js → api-keys-BoeacM-s.js} +1 -1
  96. package/core/built/admin/assets/{audience-9mwU5TW6.js → audience-ceV3XVHq.js} +1 -1
  97. package/core/built/admin/assets/automated-emails-BLesE41L.js +1 -0
  98. package/core/built/admin/assets/{automations-sAcJ1334.js → automations-BN4u3GR8.js} +1 -1
  99. package/core/built/admin/assets/automations-C-ZTUwW3.js +1 -0
  100. package/core/built/admin/assets/bluesky-sharing-vzh-oPXL.js +1 -0
  101. package/core/built/admin/assets/{breadcrumb-DLiqCyFc.js → breadcrumb-CaLk2b7D.js} +1 -1
  102. package/core/built/admin/assets/{button-B2jcu6bk.js → button-Dvcv1QSR.js} +1 -1
  103. package/core/built/admin/assets/calendar-Bl9RLcZX.js +1 -0
  104. package/core/built/admin/assets/{chart-helpers-Fo3bUL3K.js → chart-helpers-FHywU0pj.js} +1 -1
  105. package/core/built/admin/assets/{checkbox-BfKktMph.js → checkbox-BtayFtjg.js} +1 -1
  106. package/core/built/admin/assets/chunk.254.035b85ec456ebbd7336b.js +440 -0
  107. package/core/built/admin/assets/{chunk.524.60ca4692d91c6022042f.js → chunk.524.e6975095fccdf22d90f8.js} +5 -5
  108. package/core/built/admin/assets/{chunk.582.525c7617c2d9e94c940a.js → chunk.582.98b485f9b2802f540897.js} +6 -6
  109. package/core/built/admin/assets/{chunk.492.f24d855d7e3f3aad261c.js → chunk.901.4ccc639821020230bcca.js} +9949 -7921
  110. package/core/built/admin/assets/{code-editor-view-DCQJxsfU.js → code-editor-view-C3ZfoF1X.js} +1 -1
  111. package/core/built/admin/assets/{code-editor-view-CYVu4EW6.js → code-editor-view-CAyRWy1s.js} +1 -1
  112. package/core/built/admin/assets/color-picker-G4kGR7rp.js +3 -0
  113. package/core/built/admin/assets/color-picker-field-DQFVTNnT.js +1 -0
  114. package/core/built/admin/assets/combobox-BnYzgEB4.js +1 -0
  115. package/core/built/admin/assets/command-C_vyTikI.js +1 -0
  116. package/core/built/admin/assets/comments-aBrxfnZf.js +1 -0
  117. package/core/built/admin/assets/{config-DOMQDZGZ.js → config-kSHvwdTG.js} +1 -1
  118. package/core/built/admin/assets/confirmation-context-DwXX_Y5h.js +1 -0
  119. package/core/built/admin/assets/{content-api-modal-CyQEC3fr.js → content-api-modal-D2G0nJP6.js} +1 -1
  120. package/core/built/admin/assets/context-menu-DOVB6yaz.js +1 -0
  121. package/core/built/admin/assets/{copy-field-B3M1s78L.js → copy-field-DCJwh9qf.js} +1 -1
  122. package/core/built/admin/assets/create-ghost-browse-value-source-5C53jJaX.js +1 -0
  123. package/core/built/admin/assets/custom-field-type-option-BAuW0F-E.js +1 -0
  124. package/core/built/admin/assets/custom-integration-modal-AbJGVyKc.js +1 -0
  125. package/core/built/admin/assets/{date-range-select-DD2RKkgB.js → date-range-select-BY3K-ukj.js} +1 -1
  126. package/core/built/admin/assets/design-and-theme-modal-BvEy4_pC.js +2 -0
  127. package/core/built/admin/assets/dirty-confirm-dialog-DVPuGz3U.js +1 -0
  128. package/core/built/admin/assets/{disabled-sources-indicator-Cvy47bE2.js → disabled-sources-indicator-Cy7Zp4c8.js} +1 -1
  129. package/core/built/admin/assets/dist-Dcsslyo72.js +1 -0
  130. package/core/built/admin/assets/domain-Dl61QGuk.js +1 -0
  131. package/core/built/admin/assets/dropzone-Dtz5Rmjt.js +5 -0
  132. package/core/built/admin/assets/edit-profile-DNJSMDwm.js +1 -0
  133. package/core/built/admin/assets/editor-DbAen9zf.js +8 -0
  134. package/core/built/admin/assets/editor-screen-BFWThIai.js +26 -0
  135. package/core/built/admin/assets/email-sending-status-context-CWDOD1FN.js +1 -0
  136. package/core/built/admin/assets/email-sending-status-provider-DCPkDICt.js +1 -0
  137. package/core/built/admin/assets/emails-vFMk4yYl.js +1 -0
  138. package/core/built/admin/assets/{embed-signup-form-modal-DeBMLxlL.js → embed-signup-form-modal-DGqsORxS.js} +1 -1
  139. package/core/built/admin/assets/en-B1jX3WMs.js +1 -0
  140. package/core/built/admin/assets/explore-nnRr1Fja.js +1 -0
  141. package/core/built/admin/assets/feature-flag-overrides-context-DQjdJFAk.js +1 -0
  142. package/core/built/admin/assets/feature-image-placeholder-BrIHmPs8.js +1 -0
  143. package/core/built/admin/assets/feed-BNUcNu-W.js +1 -0
  144. package/core/built/admin/assets/feedback-DJ4Zb9rZ.js +1 -0
  145. package/core/built/admin/assets/{field-Cj8lmDOo.js → field-C93_Mg6j.js} +1 -1
  146. package/core/built/admin/assets/filter-bar-Da1qxybu.js +1 -0
  147. package/core/built/admin/assets/filter-sources-CGJb4C5r.js +1 -0
  148. package/core/built/admin/assets/filters--kKP-EC8.js +1 -0
  149. package/core/built/admin/assets/filters-DxA_a4FP.js +1 -0
  150. package/core/built/admin/assets/first-promoter-modal-BYDtrz2S.js +1 -0
  151. package/core/built/admin/assets/focus-koenig-editor-on-bottom-click-BbSnGOtK.js +1 -0
  152. package/core/built/admin/assets/{ghost-c8807202a07c20030acb719ee0114815.css → ghost-8fd5bb799356bbefb254210ba7e1236d.css} +1 -1
  153. package/core/built/admin/assets/{ghost-3894eedcc6968f658578c0abfe942aab.js → ghost-b4e8a403baba61905cd7560e30b9732d.js} +63 -44
  154. package/core/built/admin/assets/{ghost-dark-fbf1e384aaef3ae315e540f0eb7373a7.css → ghost-dark-cac0cb2d5bb78e9bd14d8d1c2768ed45.css} +1 -1
  155. package/core/built/admin/assets/gift-link-modal-B7u5bD4e.js +1 -0
  156. package/core/built/admin/assets/{gift-links-DLDS7ljO.js → gift-links-CfLSnst2.js} +1 -1
  157. package/core/built/admin/assets/{growth-D6mhcx3q.js → growth-Cd1uO9d2.js} +1 -1
  158. package/core/built/admin/assets/growth-aG32xfdE.js +3 -0
  159. package/core/built/admin/assets/history-modal-Df8lW8h-.js +1 -0
  160. package/core/built/admin/assets/hooks-Cy_-oZ4o.js +2 -0
  161. package/core/built/admin/assets/{html-field-C8qVGGC1.js → html-field-DA4eU7eq.js} +1 -1
  162. package/core/built/admin/assets/{images-h8VZEQ9k.js → images-KXmyO3Ss.js} +1 -1
  163. package/core/built/admin/assets/{inbox-BYd1M06Q.js → inbox-gJHG7_xd.js} +14 -14
  164. package/core/built/admin/assets/index-BHHXtR5C.css +2 -0
  165. package/core/built/admin/assets/index-CgMCwsxN.js +4 -0
  166. package/core/built/admin/assets/index.es-CY6-yuw9.js +1 -0
  167. package/core/built/admin/assets/{input-group-D8sCXRF5.js → input-group-BE8rM2y1.js} +1 -1
  168. package/core/built/admin/assets/{integrations-Bjbu86Z0.js → integrations-B4kuRBFY.js} +1 -1
  169. package/core/built/admin/assets/invite-user-modal-B4CuNcx4.js +1 -0
  170. package/core/built/admin/assets/koenig-lexical/koenig-lexical.js +14 -14
  171. package/core/built/admin/assets/koenig-lexical/koenig-lexical.umd.js +3 -3
  172. package/core/built/admin/assets/koenig-lexical/style.css +1 -1
  173. package/core/built/admin/assets/{koenig-lexical-_-IsVI7E.js → koenig-lexical-CGXb0F8o.js} +3 -3
  174. package/core/built/admin/assets/koenig-loader-BeM5rFPX.js +2 -0
  175. package/core/built/admin/assets/{kpi-card-DZQk_0W8.js → kpi-card-B21aToe8.js} +1 -1
  176. package/core/built/admin/assets/{kpi-card-DW_2y3ug.js → kpi-card-pz6Wv4Ae.js} +1 -1
  177. package/core/built/admin/assets/{kpi-helpers-PueTKuA6.js → kpi-helpers-Dq5jelmP.js} +1 -1
  178. package/core/built/admin/assets/{kpi-tabs-CojDs-Qz.js → kpi-tabs-DEZHpKUt.js} +1 -1
  179. package/core/built/admin/assets/{label-DjbT91GM.js → label-OLCzze8N.js} +1 -1
  180. package/core/built/admin/assets/label-picker-BigOvMPV.js +1 -0
  181. package/core/built/admin/assets/{labels-CH3Kn8RV.js → labels-Dr0SgUQD.js} +1 -1
  182. package/core/built/admin/assets/layout-DUTL8SH5.js +1 -0
  183. package/core/built/admin/assets/lib-7QPTI0FS.js +1 -0
  184. package/core/built/admin/assets/link-helpers-BRAg9SCj.js +1 -0
  185. package/core/built/admin/assets/links-BDHPTlyj.js +1 -0
  186. package/core/built/admin/assets/member-custom-fields-TRTHCAz9.js +1 -0
  187. package/core/built/admin/assets/member-detail-b6dRwc3C.js +1 -0
  188. package/core/built/admin/assets/members-Czt5lJSc.js +4 -0
  189. package/core/built/admin/assets/moderation-ZWefD9uH.js +1 -0
  190. package/core/built/admin/assets/{multi-select-combobox-B6LiRzDO.js → multi-select-combobox-CT13MTo-.js} +1 -1
  191. package/core/built/admin/assets/navigation-modal-C8FEhBK5.js +1 -0
  192. package/core/built/admin/assets/newsletter-5VYW4RyJ.js +1 -0
  193. package/core/built/admin/assets/newsletter-detail-modal-ChjC0ZqH.js +1 -0
  194. package/core/built/admin/assets/{newsletter-emails-CFeLlt4z.js → newsletter-emails-DZH6I-PY.js} +1 -1
  195. package/core/built/admin/assets/newsletters-DOC9KBcX.js +1 -0
  196. package/core/built/admin/assets/newsletters-Rq1M3GD-.js +1 -0
  197. package/core/built/admin/assets/note-DIV-Pojr.js +1 -0
  198. package/core/built/admin/assets/notifications-s20-H49V.js +1 -0
  199. package/core/built/admin/assets/nql-BLpCn7qX.js +21 -0
  200. package/core/built/admin/assets/{offers-9J1CSiLy.js → offers--e2nGvkW.js} +1 -1
  201. package/core/built/admin/assets/offers-container-modal-BmG5M5Tv.js +1 -0
  202. package/core/built/admin/assets/onboarding-CUuy9unR.js +1 -0
  203. package/core/built/admin/assets/{onboarding-B4YhlZ0i.js → onboarding-pXyct0Jm.js} +1 -1
  204. package/core/built/admin/assets/{onboarding-route-Dmc4IPm3.js → onboarding-route-CK4pcXoR.js} +1 -1
  205. package/core/built/admin/assets/overview-CaPsciMs.js +1 -0
  206. package/core/built/admin/assets/overview-a8GfcsKX.js +1 -0
  207. package/core/built/admin/assets/{page-header-BR_nbIPp.js → page-header-DM_KyoFI.js} +1 -1
  208. package/core/built/admin/assets/pagemenu-vgZVUVKR.js +1 -0
  209. package/core/built/admin/assets/pages-CjDY2CBI.js +1 -0
  210. package/core/built/admin/assets/pages-route-BzKZYdV5.js +1 -0
  211. package/core/built/admin/assets/papaparse.min-cQwnxGCG.js +10 -0
  212. package/core/built/admin/assets/{pintura-modal-BR9hEvS8.js → pintura-modal-DExCF1ii.js} +1 -1
  213. package/core/built/admin/assets/portal-frame-Cqanidq4.js +1 -0
  214. package/core/built/admin/assets/portal-modal-oinBgA27.js +1 -0
  215. package/core/built/admin/assets/post-analytics-C5oJ1dWV.js +1 -0
  216. package/core/built/admin/assets/post-analytics-header-OATo3X_r.js +1 -0
  217. package/core/built/admin/assets/post-analytics-provider-tOpIVGT5.js +1 -0
  218. package/core/built/admin/assets/post-helpers-C88JBa4D.js +1 -0
  219. package/core/built/admin/assets/post-share-modal-DvhC1XgV.js +1 -0
  220. package/core/built/admin/assets/post-utils-DKF4mfuo.js +1 -0
  221. package/core/built/admin/assets/posts-list-screen-o4ZjbgS3.js +2 -0
  222. package/core/built/admin/assets/posts-pCPrhQeR.js +1 -0
  223. package/core/built/admin/assets/posts-route-9F--xdIb.js +1 -0
  224. package/core/built/admin/assets/preferences--vNubsqD.js +5 -0
  225. package/core/built/admin/assets/{preview-modal-C-BL-F9k.js → preview-modal-YYbzlYdO.js} +1 -1
  226. package/core/built/admin/assets/profile-BllKV3dR.js +1 -0
  227. package/core/built/admin/assets/{radio-group-Bgz60i81.js → radio-group-DL8GI8rt.js} +1 -1
  228. package/core/built/admin/assets/{referrers-CnhCMWCs.js → referrers-D8oHPmDB.js} +1 -1
  229. package/core/built/admin/assets/router-provider-BSvTXgZY.js +1 -0
  230. package/core/built/admin/assets/schemas-BoYdB6YU.js +64 -0
  231. package/core/built/admin/assets/select-v5YbA3Mw.js +1 -0
  232. package/core/built/admin/assets/settings-PEsZupw1.js +4 -0
  233. package/core/built/admin/assets/{settings-breadcrumbs-CyP_9zTo.js → settings-breadcrumbs-NwPnCTC7.js} +1 -1
  234. package/core/built/admin/assets/settings-u_s1CRkr.js +1 -0
  235. package/core/built/admin/assets/share-modal-SskCmVGL.js +1 -0
  236. package/core/built/admin/assets/slack-modal-XxSJiYgo.js +1 -0
  237. package/core/built/admin/assets/{sort-button-Cc-Z96sA.js → sort-button-Cx1KtINE.js} +1 -1
  238. package/core/built/admin/assets/{source-icon-v6PUnmyM.js → source-icon-Bdp9Im_5.js} +1 -1
  239. package/core/built/admin/assets/stats-D9PDLS3x.js +1 -0
  240. package/core/built/admin/assets/stats-view-W2g6Jsd-.js +1 -0
  241. package/core/built/admin/assets/{step-1-DSRp2vBj.js → step-1-BQYzvBzr.js} +1 -1
  242. package/core/built/admin/assets/{step-2-COqv2g0u.js → step-2-xES32xJV.js} +1 -1
  243. package/core/built/admin/assets/{step-3-6W1NMVQc.js → step-3-DA_XK5kW.js} +2 -2
  244. package/core/built/admin/assets/{stripe-button-D2K42Uty.js → stripe-button-CVsLHelt.js} +1 -1
  245. package/core/built/admin/assets/stripe-connect-modal-ClmLOMGS.js +1 -0
  246. package/core/built/admin/assets/style-Wd9nQubI.css +1 -0
  247. package/core/built/admin/assets/{table-B2pIKjVh.js → table-BenqVupI.js} +1 -1
  248. package/core/built/admin/assets/{tabs-SaW_UT-Q.js → tabs-eBBlxPp8.js} +1 -1
  249. package/core/built/admin/assets/tag-detail-Ce8Se2qd.js +2 -0
  250. package/core/built/admin/assets/tag-picker-C3UR-uJ-.js +1 -0
  251. package/core/built/admin/assets/tags-B-kJxCs7.js +1 -0
  252. package/core/built/admin/assets/{tags-zTFiKRpb.js → tags-ChfdwJyS.js} +1 -1
  253. package/core/built/admin/assets/testimonials-modal-9Q6fT06V.js +1 -0
  254. package/core/built/admin/assets/tier-detail-modal-CDyYdqK7.js +1 -0
  255. package/core/built/admin/assets/tiers-BCpIOGQr.js +1 -0
  256. package/core/built/admin/assets/{toggle-group-EM9WpESu.js → toggle-group-CviIkyok.js} +1 -1
  257. package/core/built/admin/assets/{topic-filter-DY4gNHn2.js → topic-filter-I2jCBGxm.js} +1 -1
  258. package/core/built/admin/assets/{transistor-modal-CpyPG-MH.js → transistor-modal-p53u3W8y.js} +1 -1
  259. package/core/built/admin/assets/{trend-badge-ByMkuAuH.js → trend-badge-CideVzQd.js} +1 -1
  260. package/core/built/admin/assets/{unsplash-modal-Cv2Q6GtY.js → unsplash-modal-DY8UcKcE.js} +1 -1
  261. package/core/built/admin/assets/{use-analytics-data-CHvjMYuT.js → use-analytics-data-DAIGcr2f.js} +1 -1
  262. package/core/built/admin/assets/use-check-theme-limit-error-B8bjF-gO.css +1 -0
  263. package/core/built/admin/assets/{use-check-theme-limit-error-Qv4SVXqw.js → use-check-theme-limit-error-DRUjK4YM.js} +1 -1
  264. package/core/built/admin/assets/use-filter-params-JkZhIS8L.js +1 -0
  265. package/core/built/admin/assets/{use-filterable-api-CzXcpUh8.js → use-filterable-api-BVEVMrhZ.js} +1 -1
  266. package/core/built/admin/assets/use-growth-stats-937CUj6j.js +1 -0
  267. package/core/built/admin/assets/use-host-limits-D0Dv3tKA.js +1 -0
  268. package/core/built/admin/assets/{use-limiter-cwJvsNBo.js → use-limiter-CohWfzvK.js} +1 -1
  269. package/core/built/admin/assets/{use-navigate-with-base-path-BHPA228f.js → use-navigate-with-base-path-BkxcPj5l.js} +1 -1
  270. package/core/built/admin/assets/use-pintura-config-xgytjU35.js +1 -0
  271. package/core/built/admin/assets/{use-pintura-editor-BDBXWUYq.js → use-pintura-editor-CaV1mbfO.js} +1 -1
  272. package/core/built/admin/assets/{use-post-referrers-DbY-mzci.js → use-post-referrers-BCQI7fDg.js} +1 -1
  273. package/core/built/admin/assets/use-reply-chain-data-CYRhoaxY.js +1 -0
  274. package/core/built/admin/assets/{use-router-history-entry-Bg6BhBQQ.js → use-router-history-entry-NOKcd--l.js} +1 -1
  275. package/core/built/admin/assets/{use-setting-group-VM7FQwMY.js → use-setting-group-bLKMwoBT.js} +1 -1
  276. package/core/built/admin/assets/use-settings-navigation-B-qrriKD.js +1 -0
  277. package/core/built/admin/assets/{use-simple-pagination-Dum6Irbs.js → use-simple-pagination-CNPd6Rf6.js} +1 -1
  278. package/core/built/admin/assets/use-staff-users-pRIMIyiW.js +1 -0
  279. package/core/built/admin/assets/use-tinybird-query-CmdbCS9X.js +1 -0
  280. package/core/built/admin/assets/use-tinybird-token-KLne235s.js +1 -0
  281. package/core/built/admin/assets/{use-unsaved-changes-guard-BAy0RANR.js → use-unsaved-changes-guard-7-ug0JdH.js} +1 -1
  282. package/core/built/admin/assets/use-upgrade-route-Dm_qqKr0.js +1 -0
  283. package/core/built/admin/assets/{use-url-input-Df5QzNa7.js → use-url-input-fvp-TpPx.js} +1 -1
  284. package/core/built/admin/assets/user-detail-modal-D3KlGYv-.js +1 -0
  285. package/core/built/admin/assets/users-DVNWrqg9.js +1 -0
  286. package/core/built/admin/assets/{vendor-5753232c7d6ffb3c44e1eb0a02133953.js → vendor-2dd263291938d407802568d3357ec69e.js} +19 -17
  287. package/core/built/admin/assets/{virtual-list-DEx8WgiO.js → virtual-list-CZ3RK2Yf.js} +1 -1
  288. package/core/built/admin/assets/web-ClEJsCAj.js +2 -0
  289. package/core/built/admin/assets/web-X9rdnrtq.js +1 -0
  290. package/core/built/admin/assets/{zapier-modal-Cw3BTBUu.js → zapier-modal-DfVhV17j.js} +1 -1
  291. package/core/built/admin/index.html +23 -27
  292. package/core/frontend/apps/private-blogging/lib/views/private.hbs +44 -43
  293. package/core/frontend/helpers/cancel_link.js +2 -2
  294. package/core/frontend/helpers/pagination.js +2 -2
  295. package/core/frontend/helpers/social_accounts.js +2 -2
  296. package/core/frontend/public/ghost.css +1 -1
  297. package/core/frontend/public/ghost.min.css +1 -1
  298. package/core/frontend/services/sitemap/user-map-generator.js +9 -2
  299. package/core/server/adapters/jobs/InMemoryJobsBackend.js +74 -29
  300. package/core/server/api/endpoints/authentication.js +1 -2
  301. package/core/server/api/endpoints/authors-public.js +15 -5
  302. package/core/server/api/endpoints/emails.js +13 -0
  303. package/core/server/api/endpoints/index.js +10 -2
  304. package/core/server/api/endpoints/mail.js +1 -1
  305. package/core/server/api/endpoints/member-metafields-members.js +23 -0
  306. package/core/server/api/endpoints/member-metafields.js +102 -0
  307. package/core/server/api/endpoints/members-account.js +42 -0
  308. package/core/server/api/endpoints/members.js +4 -4
  309. package/core/server/api/endpoints/newsletters-public.js +10 -1
  310. package/core/server/api/endpoints/pages-public.js +15 -5
  311. package/core/server/api/endpoints/posts-public.js +15 -5
  312. package/core/server/api/endpoints/posts.js +3 -3
  313. package/core/server/api/endpoints/tags-public.js +22 -3
  314. package/core/server/api/endpoints/tiers-checkout-config.js +2 -2
  315. package/core/server/api/endpoints/tiers-public.js +38 -1
  316. package/core/server/api/endpoints/users.js +2 -2
  317. package/core/server/api/endpoints/utils/api-filter-utils.js +170 -3
  318. package/core/server/api/endpoints/utils/public-cache-keys.js +3 -0
  319. package/core/server/api/endpoints/utils/serializers/input/authors.js +2 -0
  320. package/core/server/api/endpoints/utils/serializers/input/members.js +20 -9
  321. package/core/server/api/endpoints/utils/serializers/input/pages.js +2 -0
  322. package/core/server/api/endpoints/utils/serializers/input/posts.js +2 -0
  323. package/core/server/api/endpoints/utils/serializers/input/tags.js +2 -0
  324. package/core/server/api/endpoints/utils/serializers/output/emails.js +7 -0
  325. package/core/server/api/endpoints/utils/serializers/output/index.js +6 -2
  326. package/core/server/api/endpoints/utils/serializers/output/member-metafields.js +18 -0
  327. package/core/server/api/endpoints/utils/serializers/output/members-account.js +19 -0
  328. package/core/server/api/endpoints/utils/serializers/output/members-csv-transform.js +1 -1
  329. package/core/server/api/endpoints/utils/serializers/output/members.js +2 -4
  330. package/core/server/api/endpoints/utils/serializers/output/tiers.js +10 -2
  331. package/core/server/api/endpoints/utils/serializers/output/users.js +0 -10
  332. package/core/server/api/endpoints/utils/validators/input/invitations.js +0 -5
  333. package/core/server/api/endpoints/utils/validators/input/pages.js +1 -1
  334. package/core/server/api/endpoints/utils/validators/input/posts.js +1 -1
  335. package/core/server/data/exporter/table-lists.js +3 -3
  336. package/core/server/data/importer/importers/data/data-importer.js +3 -3
  337. package/core/server/data/migrations/utils/migrations.js +1 -1
  338. package/core/server/data/migrations/versions/6.53/2026-07-15-20-22-53-add-members-custom-field-values.js +1 -1
  339. package/core/server/data/migrations/versions/6.57/2026-08-04-18-00-00-store-custom-field-values-as-leaf-rows.js +10 -1
  340. package/core/server/data/migrations/versions/6.63/2026-09-03-10-07-03-rename-custom-field-tables-to-metafields.js +169 -0
  341. package/core/server/data/migrations/versions/6.63/2026-09-03-11-03-31-remove-member-custom-field-read-permissions.js +30 -0
  342. package/core/server/data/schema/fixtures/fixtures.json +0 -11
  343. package/core/server/data/schema/lib/default-index-name.js +8 -11
  344. package/core/server/data/schema/schema.js +18 -18
  345. package/core/server/data/seeders/README.md +48 -0
  346. package/core/server/data/tinybird/pipes/mv_hits.pipe +86 -50
  347. package/core/server/lib/db-types/count.js +16 -0
  348. package/core/server/lib/image/image-size.js +24 -0
  349. package/core/server/lib/package-json/parse.js +2 -2
  350. package/core/server/lib/validate-password.js +81 -120
  351. package/core/server/models/action.js +4 -4
  352. package/core/server/models/base/plugins/filtered-collection.js +16 -0
  353. package/core/server/models/member.js +10 -21
  354. package/core/server/models/post.js +2 -2
  355. package/core/server/models/relations/authors.js +2 -16
  356. package/core/server/models/user.js +10 -3
  357. package/core/server/services/auth/passwordreset.js +13 -0
  358. package/core/server/services/automations/automations-api.js +1 -1
  359. package/core/server/services/automations/database-automations-repository.js +11 -4
  360. package/core/server/services/comments/comments-controller.js +30 -9
  361. package/core/server/services/comments/comments-service.js +55 -5
  362. package/core/server/services/content-import/csv/formula.js +12 -0
  363. package/core/server/services/content-import/csv/index.js +6 -1
  364. package/core/server/services/content-import/csv/parse.js +27 -6
  365. package/core/server/services/content-import/csv/serialize.js +13 -0
  366. package/core/server/services/content-import/import/completion-email.js +164 -0
  367. package/core/server/services/content-import/import/errors-file.js +36 -0
  368. package/core/server/services/content-import/import/importer.js +160 -53
  369. package/core/server/services/content-import/import/local-media-url.js +63 -0
  370. package/core/server/services/content-import/import/media.js +254 -0
  371. package/core/server/services/content-import/import/post-data.js +0 -1
  372. package/core/server/services/content-import/import/post-link.js +11 -0
  373. package/core/server/services/content-import/import/post-repository.js +25 -3
  374. package/core/server/services/content-import/import/reader.js +9 -2
  375. package/core/server/services/content-import/import/report.js +34 -0
  376. package/core/server/services/content-import/import/row.js +0 -2
  377. package/core/server/services/content-import/import/schema.js +1 -0
  378. package/core/server/services/content-import/import/staged-file.js +29 -0
  379. package/core/server/services/content-import/import/store.js +25 -2
  380. package/core/server/services/content-import/index.js +52 -6
  381. package/core/server/services/content-import/jobs/content-csv-import-job.js +20 -0
  382. package/core/server/services/custom-redirects/redirect-config-parser.js +2 -2
  383. package/core/server/services/custom-redirects/redirects-service.js +1 -1
  384. package/core/server/services/custom-redirects/validation.js +1 -1
  385. package/core/server/services/email-address/email-address-parser.js +30 -38
  386. package/core/server/services/email-address/email-address-service.js +37 -4
  387. package/core/server/services/email-analytics/index.js +2 -7
  388. package/core/server/services/email-service/CONTEXT.md +37 -0
  389. package/core/server/services/email-service/README.md +42 -0
  390. package/core/server/services/email-service/batch-sending-service.js +2 -4
  391. package/core/server/services/email-service/email-controller.js +18 -2
  392. package/core/server/services/email-service/email-renderer.js +14 -4
  393. package/core/server/services/email-service/email-service-wrapper.js +3 -9
  394. package/core/server/services/email-service/mailgun-email-provider.js +20 -9
  395. package/core/server/services/email-service/sending-status-schema.js +21 -0
  396. package/core/server/services/email-service/sending-status-serializers.js +33 -0
  397. package/core/server/services/email-service/sending-status-service.js +47 -0
  398. package/core/server/services/email-service/sending-status.js +111 -0
  399. package/core/server/services/email-suppression-list/email-suppression-list.js +0 -33
  400. package/core/server/services/email-suppression-list/mailgun-email-suppression-list.js +6 -7
  401. package/core/server/services/gifts/README.md +2 -2
  402. package/core/server/services/gifts/constants.js +1 -1
  403. package/core/server/services/gifts/email-templates/gift-delivery.hbs +3 -3
  404. package/core/server/services/gifts/gift-email-service.js +0 -1
  405. package/core/server/services/gifts/gift-service.js +19 -57
  406. package/core/server/services/gifts/index.js +3 -5
  407. package/core/server/services/gifts/jobs/index.js +4 -4
  408. package/core/server/services/indexnow-ping/indexnow-ping-service.js +2 -2
  409. package/core/server/services/invitations/accept.js +4 -2
  410. package/core/server/services/jobs/job-service.js +0 -9
  411. package/core/server/services/jobs-service/index.js +8 -0
  412. package/core/server/services/jobs-service/jobs-service.js +52 -3
  413. package/core/server/services/jobs-service/register-job-handlers.js +32 -11
  414. package/core/server/services/mail/ghost-mailer.js +4 -4
  415. package/core/server/services/member-welcome-emails/service.js +7 -7
  416. package/core/server/services/members/account-service.js +98 -0
  417. package/core/server/services/members/api.js +4 -3
  418. package/core/server/services/members/import-export/csv/parse.js +0 -7
  419. package/core/server/services/members/import-export/export/exporter.js +20 -20
  420. package/core/server/services/members/import-export/import/completion-email.js +8 -11
  421. package/core/server/services/members/import-export/import/importer.js +13 -13
  422. package/core/server/services/members/import-export/import/row.js +0 -3
  423. package/core/server/services/members/import-export/index.js +10 -17
  424. package/core/server/services/members/jobs/clean-expired-comped-job.js +7 -0
  425. package/core/server/services/members/jobs/clean-expired-comped-task.js +145 -0
  426. package/core/server/services/members/jobs/index.js +48 -24
  427. package/core/server/services/members/members-api/controllers/member-controller.js +11 -0
  428. package/core/server/services/members/members-api/controllers/router-controller.js +3 -6
  429. package/core/server/services/members/members-api/members-api.js +26 -8
  430. package/core/server/services/members/members-api/repositories/event-repository.js +0 -4
  431. package/core/server/services/members/members-api/repositories/member-repository.js +4 -4
  432. package/core/server/services/members/members-api/services/member-bread-service.js +62 -84
  433. package/core/server/services/members/members-api/services/payments-service.js +1 -1
  434. package/core/server/services/members/members-ssr.js +18 -0
  435. package/core/server/services/members/middleware.js +95 -81
  436. package/core/server/services/members/service.js +71 -47
  437. package/core/server/services/members/utils.js +9 -0
  438. package/core/server/services/members-metafields/access.js +28 -0
  439. package/core/server/services/{members-custom-fields → members-metafields}/actions.js +5 -5
  440. package/core/server/services/members-metafields/bindings-service.js +147 -0
  441. package/core/server/services/members-metafields/codec.js +14 -0
  442. package/core/server/services/{members-custom-fields → members-metafields}/config.js +1 -1
  443. package/core/server/services/{members-custom-fields → members-metafields}/definitions-service.js +68 -22
  444. package/core/server/services/members-metafields/filter.js +181 -0
  445. package/core/server/services/{members-custom-fields → members-metafields}/index.js +16 -7
  446. package/core/server/services/{members-custom-fields → members-metafields}/key.js +2 -1
  447. package/core/server/services/{members-custom-fields → members-metafields}/models.js +5 -5
  448. package/core/server/services/members-metafields/namespaces.js +34 -0
  449. package/core/server/services/{members-custom-fields → members-metafields}/queries.js +1 -1
  450. package/core/server/services/{members-custom-fields → members-metafields}/schema.js +16 -12
  451. package/core/server/services/members-metafields/serializers.js +22 -0
  452. package/core/server/services/{members-custom-fields → members-metafields}/values-service.js +80 -48
  453. package/core/server/services/mentions/mention-controller.js +23 -21
  454. package/core/server/services/mentions/mention-sending-service.js +26 -9
  455. package/core/server/services/mentions/process-webmention-job.js +16 -0
  456. package/core/server/services/mentions/send-webmentions-job.js +18 -0
  457. package/core/server/services/mentions/service.js +7 -33
  458. package/core/server/services/route-settings/validation-errors.js +1 -1
  459. package/core/server/services/route-settings/yaml-parser.js +1 -1
  460. package/core/server/services/settings/settings-service.js +1 -8
  461. package/core/server/services/settings-helpers/settings-helpers.js +4 -6
  462. package/core/server/services/slack-ping/slack-ping-service.js +1 -1
  463. package/core/server/services/staff/staff-service-emails.js +2 -2
  464. package/core/server/services/stripe/config.js +14 -8
  465. package/core/server/services/stripe/service.js +10 -1
  466. package/core/server/services/stripe/services/checkout/completed-session.js +2 -2
  467. package/core/server/services/stripe/services/checkout/session-options.js +18 -15
  468. package/core/server/services/stripe/services/webhook/checkout-session-event-service.js +28 -7
  469. package/core/server/services/stripe/stripe-api.js +2 -0
  470. package/core/server/services/stripe/stripe-service.js +24 -14
  471. package/core/server/services/stripe/webhook-controller.js +10 -0
  472. package/core/server/services/tier-checkout-config/codec.js +11 -7
  473. package/core/server/services/tier-checkout-config/index.js +2 -1
  474. package/core/server/services/tier-checkout-config/models.js +11 -5
  475. package/core/server/services/tier-checkout-config/queries.js +12 -12
  476. package/core/server/services/tier-checkout-config/serializers.js +73 -10
  477. package/core/server/services/tier-checkout-config/service.js +14 -13
  478. package/core/server/services/tiers/service.js +3 -3
  479. package/core/server/services/update-check/index.js +13 -13
  480. package/core/server/services/update-check/jobs/update-check-job.js +7 -0
  481. package/core/server/services/update-check/update-check-service.js +2 -2
  482. package/core/server/services/url/router-filter.js +8 -10
  483. package/core/server/services/users.js +1 -19
  484. package/core/server/web/admin/controller.js +1 -1
  485. package/core/server/web/api/endpoints/admin/routes.js +20 -16
  486. package/core/server/web/members/account/index.js +2 -0
  487. package/core/server/web/members/account/routes.js +46 -0
  488. package/core/server/web/members/app.js +4 -18
  489. package/core/shared/config/defaults.json +1 -1
  490. package/core/shared/config/env/config.testing-mysql.json +1 -1
  491. package/core/shared/labs.js +7 -2
  492. package/package.json +42 -41
  493. package/pnpm-lock.yaml +1159 -582
  494. package/pnpm-workspace.yaml +18 -15
  495. package/components/tryghost-custom-field-types-0.0.0.tgz +0 -0
  496. package/components/tryghost-kg-default-nodes-2.2.0.tgz +0 -0
  497. package/core/built/admin/assets/Combination-5fYEzgbs.js +0 -41
  498. package/core/built/admin/assets/account-migration-DRhAehfw.js +0 -1
  499. package/core/built/admin/assets/activitypub/inbox-BluD2ucT.js +0 -1284
  500. package/core/built/admin/assets/activitypub/label-FHSh6ZAw.js +0 -16
  501. package/core/built/admin/assets/activitypub/layout-Cq4NG0Xr.js +0 -1
  502. package/core/built/admin/assets/activitypub/settings-DQDkr06X.js +0 -315
  503. package/core/built/admin/assets/add-integration-modal-BC0jExDZ.js +0 -1
  504. package/core/built/admin/assets/add-newsletter-modal-DchTkA7l.js +0 -1
  505. package/core/built/admin/assets/add-recommendation-modal-DMvaJZKp.js +0 -1
  506. package/core/built/admin/assets/alert-dialog-QhXzdHfc.js +0 -1
  507. package/core/built/admin/assets/analytics-No1DDY3A.js +0 -1
  508. package/core/built/admin/assets/automated-emails-te1D5kq-.js +0 -1
  509. package/core/built/admin/assets/automations-DpUNUdcZ.js +0 -1
  510. package/core/built/admin/assets/bluesky-sharing-Cjrv_f62.js +0 -1
  511. package/core/built/admin/assets/chunk.896.435fe0637944d4a69810.js +0 -366
  512. package/core/built/admin/assets/color-picker-BTY_NdEm.js +0 -3
  513. package/core/built/admin/assets/color-picker-field-CPlkzOH0.js +0 -1
  514. package/core/built/admin/assets/combobox-DrMtv_4P.js +0 -1
  515. package/core/built/admin/assets/command-ZdgYJpoI.js +0 -1
  516. package/core/built/admin/assets/comments-kidj60-h.js +0 -1
  517. package/core/built/admin/assets/confirmation-context-BhbmQQEl.js +0 -1
  518. package/core/built/admin/assets/custom-field-type-option-CsGIZk1J.js +0 -10
  519. package/core/built/admin/assets/custom-integration-modal-BY37O_9X.js +0 -1
  520. package/core/built/admin/assets/design-and-theme-modal-DUSKM4uC.js +0 -22
  521. package/core/built/admin/assets/dialog-B44iRwlc.js +0 -1
  522. package/core/built/admin/assets/dirty-confirm-dialog-BxgQgQ6H.js +0 -1
  523. package/core/built/admin/assets/dist-Cy8tfrp_.js +0 -1
  524. package/core/built/admin/assets/domain-Ca6KhoQt.js +0 -1
  525. package/core/built/admin/assets/dropzone-Bb-5zQTk.js +0 -5
  526. package/core/built/admin/assets/edit-profile-BdupLlus.js +0 -1
  527. package/core/built/admin/assets/editor-BP883Lpn.js +0 -8
  528. package/core/built/admin/assets/explore-FB-CimXw.js +0 -1
  529. package/core/built/admin/assets/feed-C1GxsmI2.js +0 -1
  530. package/core/built/admin/assets/filter-sources-D5n5bFA2.js +0 -1
  531. package/core/built/admin/assets/filters-DJEzkMUK.js +0 -1
  532. package/core/built/admin/assets/filters-MZXvdH5D.js +0 -1
  533. package/core/built/admin/assets/first-promoter-modal-CGTGLCr5.js +0 -1
  534. package/core/built/admin/assets/gift-link-modal-B6v0tnRN.js +0 -1
  535. package/core/built/admin/assets/growth-BGAJD1rs.js +0 -3
  536. package/core/built/admin/assets/history-modal-iKwUY3XR.js +0 -1
  537. package/core/built/admin/assets/hooks-CuEZV2-q.js +0 -2
  538. package/core/built/admin/assets/index-DjQe-e5s.js +0 -4
  539. package/core/built/admin/assets/index-Dqf2x-ry.css +0 -1
  540. package/core/built/admin/assets/index.es-VihPwfeH.js +0 -1
  541. package/core/built/admin/assets/input--W-rCTrX.js +0 -1
  542. package/core/built/admin/assets/invite-user-modal-MdImLCaJ.js +0 -1
  543. package/core/built/admin/assets/koenig-loader-DYZpm6El.js +0 -2
  544. package/core/built/admin/assets/label-picker-cB51xl1r.js +0 -1
  545. package/core/built/admin/assets/layout-c_B_1hax.js +0 -1
  546. package/core/built/admin/assets/link-helpers-MVDdnFCY.js +0 -1
  547. package/core/built/admin/assets/loading-indicator-BpFWTVgh.js +0 -1
  548. package/core/built/admin/assets/member-custom-fields-qs0dIkxM.js +0 -1
  549. package/core/built/admin/assets/member-detail-B6uec2a6.js +0 -1
  550. package/core/built/admin/assets/members-BQF3CqhI.js +0 -2
  551. package/core/built/admin/assets/moderation-DY4wF1Q3.js +0 -1
  552. package/core/built/admin/assets/navigation-modal-DX-gNF3X.js +0 -1
  553. package/core/built/admin/assets/newsletter-CyQA7m3m.js +0 -1
  554. package/core/built/admin/assets/newsletter-detail-modal-BDrptuxn.js +0 -1
  555. package/core/built/admin/assets/newsletters-DXuNmC42.js +0 -1
  556. package/core/built/admin/assets/newsletters-DhNigJUh.js +0 -1
  557. package/core/built/admin/assets/note-Cgo2LCJ6.js +0 -1
  558. package/core/built/admin/assets/notifications-BC50AMku.js +0 -1
  559. package/core/built/admin/assets/offers-container-modal-DWycIMzT.js +0 -1
  560. package/core/built/admin/assets/onboarding-DGQuV7Ew.js +0 -1
  561. package/core/built/admin/assets/overview-CVbFtn-k.js +0 -1
  562. package/core/built/admin/assets/overview-YKj7SZaK.js +0 -1
  563. package/core/built/admin/assets/pages-B6vr9F_D.js +0 -1
  564. package/core/built/admin/assets/popover-CCy0h5rq.js +0 -1
  565. package/core/built/admin/assets/portal-frame-dc4XKr0e.js +0 -1
  566. package/core/built/admin/assets/portal-modal-BvvdF_B9.js +0 -1
  567. package/core/built/admin/assets/post-analytics-DX470WRG.js +0 -1
  568. package/core/built/admin/assets/post-analytics-header-CXpJmdDv.js +0 -1
  569. package/core/built/admin/assets/post-analytics-provider-CLfKGWZy.js +0 -1
  570. package/core/built/admin/assets/post-helpers-C5OQMBoi.js +0 -1
  571. package/core/built/admin/assets/post-share-modal-Cl0NXRJr.js +0 -1
  572. package/core/built/admin/assets/posts-KY3aUhVV.js +0 -1
  573. package/core/built/admin/assets/preferences-DO0UUWFp.js +0 -5
  574. package/core/built/admin/assets/profile-CxT-0l4d.js +0 -1
  575. package/core/built/admin/assets/router-provider-B0gZyiGJ.js +0 -1
  576. package/core/built/admin/assets/schemas-4UPic-oD.js +0 -64
  577. package/core/built/admin/assets/select-DuDUFdPq.js +0 -1
  578. package/core/built/admin/assets/settings-BjCii7BM.js +0 -1
  579. package/core/built/admin/assets/settings-b8kNzZSQ.js +0 -4
  580. package/core/built/admin/assets/share-modal-BV70mr9k.js +0 -1
  581. package/core/built/admin/assets/shim-ClF_m5ux.js +0 -1
  582. package/core/built/admin/assets/slack-modal-Be2_KK-z.js +0 -1
  583. package/core/built/admin/assets/stats-C4reGh9O.js +0 -1
  584. package/core/built/admin/assets/stats-view-DP9pQ62k.js +0 -1
  585. package/core/built/admin/assets/stripe-connect-modal-Z-UT_BGc.js +0 -1
  586. package/core/built/admin/assets/tag-detail-Dc0nTOtU.js +0 -2
  587. package/core/built/admin/assets/tags-BLaXBwnb.js +0 -1
  588. package/core/built/admin/assets/testimonials-modal-sFwRnNLh.js +0 -1
  589. package/core/built/admin/assets/tier-detail-modal-BCFpWwUS.js +0 -1
  590. package/core/built/admin/assets/tiers-Nd_z4BZY.js +0 -1
  591. package/core/built/admin/assets/use-filter-params-CAvfDvf1.js +0 -1
  592. package/core/built/admin/assets/use-growth-stats-D6mZXGhK.js +0 -1
  593. package/core/built/admin/assets/use-host-limits-DZtR08oa.js +0 -1
  594. package/core/built/admin/assets/use-pintura-config-CzTfnufz.js +0 -1
  595. package/core/built/admin/assets/use-reply-chain-data-BeQwz8oF.js +0 -1
  596. package/core/built/admin/assets/use-settings-navigation-BbrSUVcf.js +0 -1
  597. package/core/built/admin/assets/use-staff-users-cZg4ugOF.js +0 -1
  598. package/core/built/admin/assets/use-tinybird-query-B1IMyAcv.js +0 -39
  599. package/core/built/admin/assets/use-tinybird-token-Bow0Zwn8.js +0 -1
  600. package/core/built/admin/assets/use-upgrade-route-DhRSo7at.js +0 -1
  601. package/core/built/admin/assets/user-detail-modal-yipSoQfv.js +0 -1
  602. package/core/built/admin/assets/users-5msE1WMs.js +0 -1
  603. package/core/built/admin/assets/web-CKcXAu86.js +0 -1
  604. package/core/built/admin/assets/web-DR4TqM3E.js +0 -2
  605. package/core/server/api/endpoints/member-custom-fields.js +0 -90
  606. package/core/server/api/endpoints/utils/serializers/output/member-custom-fields.js +0 -20
  607. package/core/server/services/email-suppression-list/in-memory-email-suppression-list.js +0 -39
  608. package/core/server/services/jobs/worker-model-event-bridge.js +0 -149
  609. package/core/server/services/members/jobs/clean-expired-comped.js +0 -132
  610. package/core/server/services/members-custom-fields/bindings-service.js +0 -119
  611. package/core/server/services/members-custom-fields/codec.js +0 -15
  612. package/core/server/services/members-custom-fields/filter.js +0 -199
  613. package/core/server/services/members-custom-fields/serializers.js +0 -24
  614. package/core/server/services/stripe/services/checkout/allowed-countries.js +0 -267
  615. package/core/server/services/stripe/services/checkout/field-ports.js +0 -34
  616. package/core/server/services/tier-checkout-config/destinations.js +0 -17
  617. package/core/server/services/update-check/run-update-check.js +0 -63
  618. /package/core/built/admin/assets/{chunk.492.f24d855d7e3f3aad261c.js.LICENSE.txt → chunk.901.4ccc639821020230bcca.js.LICENSE.txt} +0 -0
  619. /package/core/server/services/{members-custom-fields → members-metafields}/storage.js +0 -0
@@ -1,12 +1,16 @@
1
1
  const tpl = require('@tryghost/tpl');
2
2
  const errors = require('@tryghost/errors');
3
+ const pick = require('lodash/pick');
3
4
  const models = require('../../models');
4
5
  const tagsPublicService = require('../../services/tags-public');
6
+ const { rejectTagsContentApiRestrictedFieldsTransformer } = require('./utils/api-filter-utils');
5
7
 
6
8
  const ALLOWED_INCLUDES = ['count.posts'];
9
+ const ALLOWED_READ_FIELDS = ['id', 'slug', 'visibility'];
7
10
 
8
11
  const messages = {
9
12
  tagNotFound: 'Tag not found.',
13
+ missingIdentifier: 'A tag id or slug is required.',
10
14
  };
11
15
 
12
16
  /** @type {import('@tryghost/api-framework').Controller} */
@@ -28,7 +32,11 @@ const controller = {
28
32
  },
29
33
  permissions: true,
30
34
  query(frame) {
31
- return models.TagPublic.findPage(frame.options);
35
+ const options = {
36
+ ...frame.options,
37
+ mongoTransformer: rejectTagsContentApiRestrictedFieldsTransformer,
38
+ };
39
+ return models.TagPublic.findPage(options);
32
40
  },
33
41
  },
34
42
 
@@ -37,7 +45,7 @@ const controller = {
37
45
  cacheInvalidate: false,
38
46
  },
39
47
  options: ['include', 'filter', 'fields', 'debug'],
40
- data: ['id', 'slug', 'visibility'],
48
+ data: ALLOWED_READ_FIELDS,
41
49
  validation: {
42
50
  options: {
43
51
  include: {
@@ -47,7 +55,18 @@ const controller = {
47
55
  },
48
56
  permissions: true,
49
57
  async query(frame) {
50
- const model = await models.TagPublic.findOne(frame.data, frame.options);
58
+ // GET bodies bypass the framework's declared data fields. Preserve the
59
+ // public visibility constraint, but require an actual tag identifier.
60
+ const data = pick(frame.data, ALLOWED_READ_FIELDS);
61
+ if (![data.id, data.slug].some(Boolean)) {
62
+ throw new errors.BadRequestError({ message: tpl(messages.missingIdentifier) });
63
+ }
64
+
65
+ const options = {
66
+ ...frame.options,
67
+ mongoTransformer: rejectTagsContentApiRestrictedFieldsTransformer,
68
+ };
69
+ const model = await models.TagPublic.findOne(data, options);
51
70
  if (!model) {
52
71
  throw new errors.NotFoundError({
53
72
  message: tpl(messages.tagNotFound),
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const members_custom_fields_1 = require("../../services/members-custom-fields");
3
+ const members_metafields_1 = require("../../services/members-metafields");
4
4
  const tier_checkout_config_1 = require("../../services/tier-checkout-config");
5
5
  const tiersService = require('../../services/tiers');
6
6
  /**
@@ -50,7 +50,7 @@ const controller = {
50
50
  validation: { options: { id: { required: true } } },
51
51
  permissions: { docName: 'products', method: 'edit' },
52
52
  async query(frame) {
53
- await tiersService.checkout.edit((0, members_custom_fields_1.actingContext)(frame.options.context), frame.options.id, frame.data.tiers_checkout_config?.[0] ?? {});
53
+ await tiersService.checkout.edit((0, members_metafields_1.actingContext)(frame.options.context), frame.options.id, frame.data.tiers_checkout_config?.[0] ?? {});
54
54
  return [await forTier(frame.options.id)];
55
55
  },
56
56
  },
@@ -1,4 +1,38 @@
1
+ const logging = require('@tryghost/logging');
2
+ const labs = require('../../../shared/labs');
1
3
  const tiersService = require('../../services/tiers');
4
+ const { requirementsByTier } = require('../../services/tier-checkout-config');
5
+
6
+ /**
7
+ * What each tier asks a member for, or nothing when the site does not do that.
8
+ *
9
+ * Looked up per request rather than kept with the tier, because a tier is loaded into
10
+ * memory once at boot and these rows change underneath it: deleting a custom field
11
+ * cascades a tier's binding away without that repository ever hearing about it, so a copy
12
+ * taken at boot would go on promising to ask for a field the site no longer has.
13
+ *
14
+ * One lookup per response, and only for this payload. Staff read these settings through a
15
+ * resource of their own that carries them in full, and the payloads carrying tiers in
16
+ * bulk each build their own reduced projection of a tier, so none of them pays for this.
17
+ *
18
+ * A failure costs the requirements and nothing else. A tier a reader cannot see the price
19
+ * of is worse than one whose delivery question they meet a moment later.
20
+ */
21
+ async function requirements() {
22
+ if (!labs.isSet('stripeCheckoutCollection')) {
23
+ return undefined;
24
+ }
25
+
26
+ try {
27
+ return requirementsByTier(await tiersService.checkout.browse());
28
+ } catch (err) {
29
+ logging.error(
30
+ { event: { name: 'tiers.requirements.read_failed' }, err },
31
+ 'Failed to read what tiers ask a member for',
32
+ );
33
+ return undefined;
34
+ }
35
+ }
2
36
 
3
37
  /** @type {import('@tryghost/api-framework').Controller} */
4
38
  const controller = {
@@ -13,7 +47,10 @@ const controller = {
13
47
  async query(frame) {
14
48
  const page = await tiersService.api.browse(frame.options);
15
49
 
16
- return page;
50
+ // Carried on the page rather than fetched while serializing, so the serializer
51
+ // renders what it was handed. The admin controller looks none up, which is what
52
+ // keeps them off the admin payload — no serializer needs to ask who is calling.
53
+ return { ...page, requirements: await requirements() };
17
54
  },
18
55
  },
19
56
  };
@@ -2,13 +2,12 @@ const tpl = require('@tryghost/tpl');
2
2
  const errors = require('@tryghost/errors');
3
3
  const models = require('../../models');
4
4
  const permissionsService = require('../../services/permissions');
5
- const dbBackup = require('../../data/db/backup');
6
5
  const auth = require('../../services/auth');
7
6
  const apiMail = require('./index').mail;
8
7
  const apiSettings = require('./index').settings;
9
8
  const { rejectAdminApiRestrictedFieldsTransformer } = require('./utils/api-filter-utils');
10
9
  const UsersService = require('../../services/users');
11
- const userService = new UsersService({ dbBackup, models, auth, apiMail, apiSettings });
10
+ const userService = new UsersService({ models, auth, apiMail, apiSettings });
12
11
  const ALLOWED_INCLUDES = ['count.posts', 'permissions', 'roles', 'roles.permissions'];
13
12
  const UNSAFE_ATTRS = ['status', 'roles'];
14
13
 
@@ -191,6 +190,7 @@ const controller = {
191
190
  },
192
191
 
193
192
  destroy: {
193
+ statusCode: 204,
194
194
  headers: {
195
195
  cacheInvalidate: true,
196
196
  },
@@ -3,21 +3,173 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.validateAdminApiBulkFilterTransformer = exports.rejectAdminApiRestrictedFieldsTransformer = exports.rejectContentApiRestrictedFieldsTransformer = void 0;
6
+ exports.validateAdminApiBulkFilterTransformer = exports.rejectAdminApiRestrictedFieldsTransformer = exports.rejectNewslettersContentApiRestrictedFieldsTransformer = exports.rejectPagesContentApiRestrictedFieldsTransformer = exports.rejectPostsContentApiRestrictedFieldsTransformer = exports.rejectTagsContentApiRestrictedFieldsTransformer = exports.rejectAuthorsContentApiRestrictedFieldsTransformer = exports.rejectContentApiRestrictedFieldsTransformer = void 0;
7
+ exports.rejectAuthorsRestrictedOrderFields = rejectAuthorsRestrictedOrderFields;
8
+ exports.rejectTagsRestrictedOrderFields = rejectTagsRestrictedOrderFields;
9
+ exports.rejectPostsContentApiRestrictedOrderFields = rejectPostsContentApiRestrictedOrderFields;
10
+ exports.rejectPagesContentApiRestrictedOrderFields = rejectPagesContentApiRestrictedOrderFields;
11
+ exports.rejectNewslettersContentApiRestrictedOrderFields = rejectNewslettersContentApiRestrictedOrderFields;
7
12
  const errors_1 = __importDefault(require("@tryghost/errors"));
8
13
  const mongo_utils_1 = require("@tryghost/mongo-utils");
9
- const CONTENT_API_RESTRICTED_FIELDS = new Set(['password', 'email']);
14
+ const schema = require('../../../data/schema').tables;
15
+ // Never filterable or orderable through the Content API, on any resource or relation.
16
+ const CONTENT_API_RESTRICTED_FIELDS = new Set([
17
+ 'password',
18
+ 'email',
19
+ 'email_only',
20
+ 'html',
21
+ 'lexical',
22
+ 'locale',
23
+ 'mobiledoc',
24
+ 'newsletter_id',
25
+ 'plaintext',
26
+ 'email_recipient_filter',
27
+ 'published_by',
28
+ ]);
29
+ const CONTENT_API_RESTRICTED_RELATIONS = new Set(['mobiledoc_revisions', 'post_revisions']);
30
+ const CONTENT_API_PAGE_RESTRICTED_FIELDS = new Set(['email_subject']);
31
+ const CONTENT_API_POST_RESTRICTED_FIELDS = new Set(['show_title_and_feature_image']);
32
+ const CONTENT_API_NEWSLETTER_FIELDS = new Set([
33
+ 'id',
34
+ 'uuid',
35
+ 'name',
36
+ 'description',
37
+ 'slug',
38
+ 'sender_email',
39
+ 'subscribe_on_signup',
40
+ 'visibility',
41
+ 'sort_order',
42
+ 'created_at',
43
+ 'updated_at',
44
+ ]);
45
+ // User fields and relations the Content API does not expose: blocked as bare fields on authors and via author relations elsewhere.
46
+ // Not blocked as bare fields on other resources, where visibility/status are legitimate filters.
47
+ const CONTENT_API_USER_RESTRICTED_FIELDS = new Set([
48
+ 'status',
49
+ 'last_seen',
50
+ 'created_at',
51
+ 'updated_at',
52
+ 'roles',
53
+ 'roles_users',
54
+ 'visibility',
55
+ 'locale',
56
+ 'accessibility',
57
+ 'paid_subscription_started_notification',
58
+ 'paid_subscription_canceled_notification',
59
+ 'tour',
60
+ 'comment_notifications',
61
+ 'recommendation_notifications',
62
+ 'gift_subscription_notifications',
63
+ 'mention_notifications',
64
+ 'donation_notifications',
65
+ 'milestone_notifications',
66
+ 'free_member_signup_notification',
67
+ ]);
68
+ const CONTENT_API_AUTHOR_RELATIONS = new Set(['author', 'authors', 'primary_author']);
69
+ const CONTENT_API_TAG_RESTRICTED_FIELDS = new Set([
70
+ 'created_at',
71
+ 'updated_at',
72
+ 'parent_id',
73
+ 'parent',
74
+ ]);
75
+ const CONTENT_API_TAG_RELATIONS = new Set(['tag', 'tags', 'primary_tag']);
10
76
  const ADMIN_API_RESTRICTED_FIELDS = new Set(['password']);
77
+ function getOrderAttributes(tableName) {
78
+ return Object.keys(schema[tableName])
79
+ .map((field) => `${tableName}.${field}`)
80
+ .filter((field) => !field.includes('@@'));
81
+ }
82
+ const CONTENT_API_AUTHOR_ORDER_ATTRIBUTES = getOrderAttributes('users');
83
+ const CONTENT_API_TAG_ORDER_ATTRIBUTES = getOrderAttributes('tags');
84
+ const CONTENT_API_NEWSLETTER_ORDER_ATTRIBUTES = getOrderAttributes('newsletters');
85
+ const CONTENT_API_POST_ORDER_ATTRIBUTES = [
86
+ ...getOrderAttributes('posts'),
87
+ ...getOrderAttributes('posts_meta').filter((field) => !['posts_meta.id', 'posts_meta.post_id'].includes(field)),
88
+ ];
11
89
  function hasRestrictedSegment(key, fields) {
12
90
  return key
13
91
  .toLowerCase()
14
92
  .split('.')
15
93
  .some((segment) => fields.has(segment));
16
94
  }
95
+ function hasRestrictedUserSegment(key) {
96
+ const segments = key.toLowerCase().split('.');
97
+ return segments.some((segment, index) => index > 0 &&
98
+ CONTENT_API_AUTHOR_RELATIONS.has(segments[index - 1]) &&
99
+ CONTENT_API_USER_RESTRICTED_FIELDS.has(segment));
100
+ }
101
+ function hasRestrictedTagSegment(key) {
102
+ const segments = key.toLowerCase().split('.');
103
+ return segments.some((segment, index) => index > 0 &&
104
+ CONTENT_API_TAG_RELATIONS.has(segments[index - 1]) &&
105
+ CONTENT_API_TAG_RESTRICTED_FIELDS.has(segment));
106
+ }
107
+ function isContentApiRestrictedKey(key) {
108
+ return (hasRestrictedSegment(key, CONTENT_API_RESTRICTED_FIELDS) ||
109
+ hasRestrictedSegment(key, CONTENT_API_RESTRICTED_RELATIONS) ||
110
+ hasRestrictedUserSegment(key) ||
111
+ hasRestrictedTagSegment(key));
112
+ }
113
+ function isAuthorsContentApiRestrictedKey(key) {
114
+ return (isContentApiRestrictedKey(key) || hasRestrictedSegment(key, CONTENT_API_USER_RESTRICTED_FIELDS));
115
+ }
116
+ function isTagsContentApiRestrictedKey(key) {
117
+ return (isContentApiRestrictedKey(key) || hasRestrictedSegment(key, CONTENT_API_TAG_RESTRICTED_FIELDS));
118
+ }
119
+ function isPostsContentApiRestrictedKey(key) {
120
+ return (isContentApiRestrictedKey(key) || hasRestrictedSegment(key, CONTENT_API_POST_RESTRICTED_FIELDS));
121
+ }
122
+ function isPagesContentApiRestrictedKey(key) {
123
+ return (isContentApiRestrictedKey(key) || hasRestrictedSegment(key, CONTENT_API_PAGE_RESTRICTED_FIELDS));
124
+ }
125
+ function isNewslettersContentApiRestrictedKey(key) {
126
+ const normalizedKey = key.toLowerCase();
127
+ const fieldKey = normalizedKey.startsWith('newsletters.')
128
+ ? normalizedKey.slice('newsletters.'.length)
129
+ : normalizedKey;
130
+ return !CONTENT_API_NEWSLETTER_FIELDS.has(fieldKey);
131
+ }
132
+ function rejectRestrictedOrderFields(order, orderAttributes, isRestricted) {
133
+ if (!order) {
134
+ return order;
135
+ }
136
+ const allowedClauses = (Array.isArray(order) ? order : [order])
137
+ .flatMap((value) => value.split(','))
138
+ .map((clause) => clause.trim())
139
+ .filter(Boolean)
140
+ .filter((clause) => {
141
+ const [field] = clause.split(/\s+/);
142
+ const normalizedField = field.toLowerCase();
143
+ const resolvedField = orderAttributes.find((orderAttribute) => orderAttribute.endsWith(normalizedField)) ||
144
+ normalizedField;
145
+ return !isRestricted(resolvedField);
146
+ });
147
+ return allowedClauses.length ? allowedClauses.join(',') : undefined;
148
+ }
17
149
  const rejectContentApiRestrictedFieldsTransformer = (input) => {
18
- return (0, mongo_utils_1.rejectStatements)(input, (key) => hasRestrictedSegment(key, CONTENT_API_RESTRICTED_FIELDS));
150
+ return (0, mongo_utils_1.rejectStatements)(input, isContentApiRestrictedKey);
19
151
  };
20
152
  exports.rejectContentApiRestrictedFieldsTransformer = rejectContentApiRestrictedFieldsTransformer;
153
+ const rejectAuthorsContentApiRestrictedFieldsTransformer = (input) => {
154
+ return (0, mongo_utils_1.rejectStatements)(input, isAuthorsContentApiRestrictedKey);
155
+ };
156
+ exports.rejectAuthorsContentApiRestrictedFieldsTransformer = rejectAuthorsContentApiRestrictedFieldsTransformer;
157
+ const rejectTagsContentApiRestrictedFieldsTransformer = (input) => {
158
+ return (0, mongo_utils_1.rejectStatements)(input, isTagsContentApiRestrictedKey);
159
+ };
160
+ exports.rejectTagsContentApiRestrictedFieldsTransformer = rejectTagsContentApiRestrictedFieldsTransformer;
161
+ const rejectPostsContentApiRestrictedFieldsTransformer = (input) => {
162
+ return (0, mongo_utils_1.rejectStatements)(input, isPostsContentApiRestrictedKey);
163
+ };
164
+ exports.rejectPostsContentApiRestrictedFieldsTransformer = rejectPostsContentApiRestrictedFieldsTransformer;
165
+ const rejectPagesContentApiRestrictedFieldsTransformer = (input) => {
166
+ return (0, mongo_utils_1.rejectStatements)(input, isPagesContentApiRestrictedKey);
167
+ };
168
+ exports.rejectPagesContentApiRestrictedFieldsTransformer = rejectPagesContentApiRestrictedFieldsTransformer;
169
+ const rejectNewslettersContentApiRestrictedFieldsTransformer = (input) => {
170
+ return (0, mongo_utils_1.rejectStatements)(input, isNewslettersContentApiRestrictedKey);
171
+ };
172
+ exports.rejectNewslettersContentApiRestrictedFieldsTransformer = rejectNewslettersContentApiRestrictedFieldsTransformer;
21
173
  const rejectAdminApiRestrictedFieldsTransformer = (input) => {
22
174
  return (0, mongo_utils_1.rejectStatements)(input, (key) => hasRestrictedSegment(key, ADMIN_API_RESTRICTED_FIELDS));
23
175
  };
@@ -32,3 +184,18 @@ const validateAdminApiBulkFilterTransformer = (input) => {
32
184
  return input;
33
185
  };
34
186
  exports.validateAdminApiBulkFilterTransformer = validateAdminApiBulkFilterTransformer;
187
+ function rejectAuthorsRestrictedOrderFields(order) {
188
+ return rejectRestrictedOrderFields(order, CONTENT_API_AUTHOR_ORDER_ATTRIBUTES, isAuthorsContentApiRestrictedKey);
189
+ }
190
+ function rejectTagsRestrictedOrderFields(order) {
191
+ return rejectRestrictedOrderFields(order, CONTENT_API_TAG_ORDER_ATTRIBUTES, isTagsContentApiRestrictedKey);
192
+ }
193
+ function rejectPostsContentApiRestrictedOrderFields(order) {
194
+ return rejectRestrictedOrderFields(order, CONTENT_API_POST_ORDER_ATTRIBUTES, isPostsContentApiRestrictedKey);
195
+ }
196
+ function rejectPagesContentApiRestrictedOrderFields(order) {
197
+ return rejectRestrictedOrderFields(order, CONTENT_API_POST_ORDER_ATTRIBUTES, isPagesContentApiRestrictedKey);
198
+ }
199
+ function rejectNewslettersContentApiRestrictedOrderFields(order) {
200
+ return rejectRestrictedOrderFields(order, CONTENT_API_NEWSLETTER_ORDER_ATTRIBUTES, isNewslettersContentApiRestrictedKey);
201
+ }
@@ -27,6 +27,9 @@ function generateAuthData(frame) {
27
27
  const member = frame.options?.context?.member;
28
28
  if (member) {
29
29
  return {
30
+ // Transistor embeds contain the individual member UUID. Use null for
31
+ // UUID-less shims so they also avoid old entitlement-only cache entries.
32
+ uuid: member.uuid ?? null,
30
33
  free: member.status === 'free',
31
34
  tiers: member.products?.map((product) => product.slug).sort(),
32
35
  };
@@ -2,6 +2,7 @@ const debug = require('@tryghost/debug')('api:endpoints:utils:serializers:input:
2
2
  const url = require('./utils/url');
3
3
  const slugFilterOrder = require('./utils/slug-filter-order');
4
4
  const utils = require('../../index');
5
+ const { rejectAuthorsRestrictedOrderFields } = require('../../api-filter-utils');
5
6
 
6
7
  function setDefaultOrder(frame) {
7
8
  if (!frame.options.order && frame.options.filter) {
@@ -20,6 +21,7 @@ module.exports = {
20
21
  url.forceUrlColumns(frame, 'authors');
21
22
 
22
23
  if (utils.isContentAPI(frame)) {
24
+ frame.options.order = rejectAuthorsRestrictedOrderFields(frame.options.order);
23
25
  setDefaultOrder(frame);
24
26
  }
25
27
  },
@@ -1,6 +1,8 @@
1
1
  const _ = require('lodash');
2
2
  const debug = require('@tryghost/debug')('api:endpoints:utils:serializers:input:members');
3
3
  const mapNQLKeyValues = require('@tryghost/nql').utils.mapKeyValues;
4
+ const { chainTransformers } = require('@tryghost/mongo-utils');
5
+ const { validateAdminApiBulkFilterTransformer } = require('../../api-filter-utils');
4
6
 
5
7
  function defaultRelations(frame) {
6
8
  if (frame.options.withRelated) {
@@ -16,7 +18,7 @@ function defaultRelations(frame) {
16
18
 
17
19
  // @TODO: move this into the member repository in members-api
18
20
  function mapSubscribedFlagToNewsletterRelation(frame) {
19
- frame.options.mongoTransformer = mapNQLKeyValues({
21
+ const transformer = mapNQLKeyValues({
20
22
  key: {
21
23
  from: 'subscribed',
22
24
  to: 'newsletters.status',
@@ -32,20 +34,27 @@ function mapSubscribedFlagToNewsletterRelation(frame) {
32
34
  },
33
35
  ],
34
36
  });
37
+
38
+ frame.options.mongoTransformer = frame.options.mongoTransformer
39
+ ? chainTransformers(frame.options.mongoTransformer, transformer)
40
+ : transformer;
41
+ }
42
+
43
+ function validateBulkFilter(frame) {
44
+ frame.options.mongoTransformer = frame.options.mongoTransformer
45
+ ? chainTransformers(validateAdminApiBulkFilterTransformer, frame.options.mongoTransformer)
46
+ : validateAdminApiBulkFilterTransformer;
35
47
  }
36
48
 
37
- // Values are not a member relation — they're stored per field type and read by
38
- // the custom fields service — so `include=custom_fields` must not reach the model
39
- // layer as something to eager-load. Lift it out and leave a flag browse can act on.
40
- function liftCustomFieldsInclude(frame) {
41
- if (!frame.options.withRelated.includes('custom_fields')) {
49
+ function liftMetafieldsInclude(frame) {
50
+ if (!frame.options.withRelated.includes('metafields')) {
42
51
  return;
43
52
  }
44
53
 
45
54
  frame.options.withRelated = frame.options.withRelated.filter(
46
- (relation) => relation !== 'custom_fields',
55
+ (relation) => relation !== 'metafields',
47
56
  );
48
- frame.options.includeCustomFields = true;
57
+ frame.options.includeMetafields = true;
49
58
  }
50
59
 
51
60
  module.exports = {
@@ -54,7 +63,7 @@ module.exports = {
54
63
  return;
55
64
  }
56
65
 
57
- liftCustomFieldsInclude(frame);
66
+ liftMetafieldsInclude(frame);
58
67
 
59
68
  frame.options.withRelated = frame.options.withRelated.map((relation) => {
60
69
  if (relation === 'tiers') {
@@ -128,11 +137,13 @@ module.exports = {
128
137
 
129
138
  bulkEdit(apiConfig, frame) {
130
139
  debug('bulkEdit');
140
+ validateBulkFilter(frame);
131
141
  mapSubscribedFlagToNewsletterRelation(frame);
132
142
  },
133
143
 
134
144
  bulkDestroy(apiConfig, frame) {
135
145
  debug('bulkDestroy');
146
+ validateBulkFilter(frame);
136
147
  mapSubscribedFlagToNewsletterRelation(frame);
137
148
  },
138
149
  };
@@ -9,6 +9,7 @@ const postsMetaSchema = require('../../../../../data/schema').tables.posts_meta;
9
9
  const postsSchema = require('../../../../../data/schema').tables.posts;
10
10
  const clean = require('./utils/clean');
11
11
  const lexical = require('../../../../../lib/lexical');
12
+ const { rejectPagesContentApiRestrictedOrderFields } = require('../../api-filter-utils');
12
13
 
13
14
  const messages = {
14
15
  failedHtmlToLexical: 'Failed to convert HTML to Lexical',
@@ -137,6 +138,7 @@ module.exports = {
137
138
  removeSourceFormats(frame); // remove from the format field
138
139
  selectAllAllowedColumns(frame); // remove from any specified column or selectRaw options
139
140
 
141
+ frame.options.order = rejectPagesContentApiRestrictedOrderFields(frame.options.order);
140
142
  setDefaultOrder(frame);
141
143
  forceVisibilityColumn(frame);
142
144
  url.forceUrlRelations(frame, 'pages');
@@ -9,6 +9,7 @@ const postsMetaSchema = require('../../../../../data/schema').tables.posts_meta;
9
9
  const postsSchema = require('../../../../../data/schema').tables.posts;
10
10
  const clean = require('./utils/clean');
11
11
  const lexical = require('../../../../../lib/lexical');
12
+ const { rejectPostsContentApiRestrictedOrderFields } = require('../../api-filter-utils');
12
13
 
13
14
  const messages = {
14
15
  failedHtmlToLexical: 'Failed to convert HTML to Lexical',
@@ -172,6 +173,7 @@ module.exports = {
172
173
  removeSourceFormats(frame); // remove from the format field
173
174
  selectAllAllowedColumns(frame); // remove from any specified column or selectRaw options
174
175
 
176
+ frame.options.order = rejectPostsContentApiRestrictedOrderFields(frame.options.order);
175
177
  setDefaultOrder(frame);
176
178
  forceVisibilityColumn(frame);
177
179
  mapWithRelated(frame);
@@ -2,6 +2,7 @@ const debug = require('@tryghost/debug')('api:endpoints:utils:serializers:input:
2
2
  const url = require('./utils/url');
3
3
  const slugFilterOrder = require('./utils/slug-filter-order');
4
4
  const utils = require('../../index');
5
+ const { rejectTagsRestrictedOrderFields } = require('../../api-filter-utils');
5
6
 
6
7
  function setDefaultOrder(frame) {
7
8
  let defaultOrder = 'name asc';
@@ -22,6 +23,7 @@ module.exports = {
22
23
  url.forceUrlColumns(frame, 'tags');
23
24
 
24
25
  if (utils.isContentAPI(frame)) {
26
+ frame.options.order = rejectTagsRestrictedOrderFields(frame.options.order);
25
27
  setDefaultOrder(frame);
26
28
  }
27
29
  },
@@ -1,7 +1,14 @@
1
1
  const batchMapper = require('./mappers/email-batches');
2
2
  const failureMapper = require('./mappers/email-failures');
3
+ const {
4
+ toEmailStatusesResponse,
5
+ } = require('../../../../../services/email-service/sending-status-serializers');
3
6
 
4
7
  module.exports = {
8
+ sendingStatus(response, apiConfig, frame) {
9
+ frame.response = toEmailStatusesResponse.parse(response);
10
+ },
11
+
5
12
  browseBatches(response, apiConfig, frame) {
6
13
  frame.response = {};
7
14
 
@@ -20,6 +20,10 @@ module.exports = {
20
20
  return require('./member-commenting');
21
21
  },
22
22
 
23
+ get members_account() {
24
+ return require('./members-account');
25
+ },
26
+
23
27
  get authentication() {
24
28
  return require('./authentication');
25
29
  },
@@ -76,8 +80,8 @@ module.exports = {
76
80
  return require('./members');
77
81
  },
78
82
 
79
- get members_custom_fields() {
80
- return require('./member-custom-fields');
83
+ get members_metafields() {
84
+ return require('./member-metafields');
81
85
  },
82
86
 
83
87
  get tiers() {
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const serializers_1 = require("../../../../../services/members-metafields/serializers");
4
+ const serializeOne = (field, _apiConfig, frame) => {
5
+ frame.response = serializers_1.toMetafieldsResponse.parse([field]);
6
+ };
7
+ const serializeMany = (fields, _apiConfig, frame) => {
8
+ frame.response = serializers_1.toMetafieldsResponse.parse(fields);
9
+ };
10
+ // The API framework loads this file with `require()`, so it exports CommonJS-style;
11
+ // `export default` would not be picked up.
12
+ module.exports = {
13
+ browse: serializeMany,
14
+ read: serializeOne,
15
+ add: serializeMany,
16
+ reorder: serializeMany,
17
+ edit: serializeOne,
18
+ };
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ const { formattedMemberResponse } = require('../../../../../services/members/utils');
3
+ /**
4
+ * A member's own record, as this API has always written one down.
5
+ *
6
+ * The projection itself is unchanged and still lives beside the other member
7
+ * formatting; what changes is that it is now reached the way every other
8
+ * serializer is, by this endpoint's `docName`, rather than being called by hand
9
+ * from a request handler.
10
+ */
11
+ const serialize = (member, _apiConfig, frame) => {
12
+ frame.response = formattedMemberResponse(member);
13
+ };
14
+ // The API framework loads this file with `require()`, so it exports CommonJS-style;
15
+ // `export default` would not be picked up.
16
+ module.exports = {
17
+ read: serialize,
18
+ update: serialize,
19
+ };
@@ -14,7 +14,7 @@ const { toExportCsvRow } = require('../../../../../services/members/import-expor
14
14
  * @returns {Transform} Transform stream that converts objects to CSV
15
15
  */
16
16
  function createCSVTransform() {
17
- // Locked in from the first row rather than declared up front: custom fields
17
+ // Locked in from the first row rather than declared up front: metafields
18
18
  // add a column per site, so the column set isn't known until a row arrives.
19
19
  // Every row carries the same keys, so the first is representative.
20
20
  let fields = null;
@@ -131,10 +131,8 @@ function serializeMember(member, options) {
131
131
  serialized.tiers = json.products;
132
132
  }
133
133
 
134
- // Present on a read whenever the flag is on; absent otherwise, and absent on
135
- // browse. An empty object is a member with no values set.
136
- if (json.custom_fields) {
137
- serialized.custom_fields = json.custom_fields;
134
+ if (json.metafields) {
135
+ serialized.metafields = json.metafields;
138
136
  }
139
137
 
140
138
  serialized.current_subscription = json.current_subscription || null;
@@ -20,7 +20,7 @@ module.exports = {
20
20
  function paginatedTiers(page, _apiConfig, frame) {
21
21
  return {
22
22
  tiers: page.data.map((model) => {
23
- return serializeTier(model, frame.options);
23
+ return serializeTier(model, frame.options, page.requirements);
24
24
  }),
25
25
  meta: page.meta,
26
26
  };
@@ -45,7 +45,7 @@ function singleTier(model, _apiConfig, frame) {
45
45
  *
46
46
  * @returns {SerializedTier}
47
47
  */
48
- function serializeTier(tier, options) {
48
+ function serializeTier(tier, options, requirements = null) {
49
49
  const json = tier.toJSON(options);
50
50
 
51
51
  const serialized = {
@@ -70,6 +70,14 @@ function serializeTier(tier, options) {
70
70
  serialized.benefits = null;
71
71
  }
72
72
 
73
+ // Only the payload that was asked for these carries them, so a response that did not
74
+ // look them up says nothing rather than saying every tier asks for nothing. Where they
75
+ // were looked up, every tier carries the key and an empty one means it asks for
76
+ // nothing.
77
+ if (requirements) {
78
+ serialized.requirements = requirements.get(json.id) ?? {};
79
+ }
80
+
73
81
  if (serialized.type === 'free') {
74
82
  delete serialized.currency;
75
83
  delete serialized.monthly_price;
@@ -6,16 +6,6 @@ const messages = {
6
6
  };
7
7
 
8
8
  module.exports = {
9
- destroy(filename, apiConfig, frame) {
10
- debug('destroy');
11
-
12
- frame.response = {
13
- meta: {
14
- filename: filename,
15
- },
16
- };
17
- },
18
-
19
9
  changePassword(models, apiConfig, frame) {
20
10
  debug('changePassword');
21
11