ghost 6.62.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.
- package/components/tryghost-adapter-base-jobs-0.0.0.tgz +0 -0
- package/components/tryghost-adapter-base-scheduling-0.2.3.tgz +0 -0
- package/components/tryghost-adapter-base-sso-0.1.3.tgz +0 -0
- package/components/tryghost-admin-api-schema-0.0.0.tgz +0 -0
- package/components/tryghost-checkout-0.0.0.tgz +0 -0
- package/components/tryghost-i18n-0.0.0.tgz +0 -0
- package/components/tryghost-kg-card-factory-5.2.4.tgz +0 -0
- package/components/tryghost-kg-clean-basic-html-4.3.4.tgz +0 -0
- package/components/tryghost-kg-converters-1.2.5.tgz +0 -0
- package/components/tryghost-kg-default-cards-10.3.5.tgz +0 -0
- package/components/tryghost-kg-default-nodes-2.2.1.tgz +0 -0
- package/components/tryghost-kg-default-transforms-1.3.4.tgz +0 -0
- package/components/tryghost-kg-html-to-lexical-1.4.0.tgz +0 -0
- package/components/tryghost-kg-lexical-html-renderer-1.5.0.tgz +0 -0
- package/components/tryghost-kg-markdown-html-renderer-7.2.4.tgz +0 -0
- package/components/tryghost-kg-utils-1.1.4.tgz +0 -0
- package/components/tryghost-limit-service-0.0.0.tgz +0 -0
- package/components/tryghost-metafield-types-0.0.0.tgz +0 -0
- package/content/themes/source/package.json +2 -2
- package/content/themes/source/partials/post-card.hbs +1 -1
- package/core/boot.js +7 -5
- package/core/built/admin/assets/{about-Dyae_UT6.js → about-C1C3s5-g.js} +1 -1
- package/core/built/admin/assets/accordion-CxGsDKwa.js +1 -0
- package/core/built/admin/assets/{account-migration-CESa0mnX.js → account-migration-CbUhW6gk.js} +1 -1
- package/core/built/admin/assets/activitypub/{account-migration-By69CgCp.js → account-migration-KA6Jjf9L.js} +7 -7
- package/core/built/admin/assets/activitypub/activitypub.js +3 -3
- package/core/built/admin/assets/activitypub/{avatar-DLPL3Abs.js → avatar-DVJF5bxP.js} +2 -2
- package/core/built/admin/assets/activitypub/{avatar-flipboard-C9iDY-QV.js → avatar-flipboard-csQaNeYK.js} +2 -2
- package/core/built/admin/assets/activitypub/{bluesky-sharing-BJcPMrDd.js → bluesky-sharing-C7nTDMvw.js} +9 -9
- package/core/built/admin/assets/activitypub/{content-formatters-3rTHg3mp.js → content-formatters-CLcjaBwV.js} +4 -4
- package/core/built/admin/assets/activitypub/{copy-DIAOQoCZ.js → copy-DcOh8kXw.js} +2 -2
- package/core/built/admin/assets/activitypub/{domain-DUR4xSkV.js → domain-fZ-X8i4-.js} +9 -9
- package/core/built/admin/assets/activitypub/{edit-profile-BqtfzxCp.js → edit-profile-BqMLQV88.js} +6 -6
- package/core/built/admin/assets/activitypub/{explore-BxuJd-J4.js → explore-B4yPoP8E.js} +10 -10
- package/core/built/admin/assets/activitypub/{feed-BM1TcksA.js → feed-BRC_mvAe.js} +9 -9
- package/core/built/admin/assets/activitypub/{field-Dn7HHx2-.js → field-COacNgOt.js} +3 -3
- package/core/built/admin/assets/activitypub/{hash-Bm3WxYN4.js → hash-C7u-irQQ.js} +2 -2
- package/core/built/admin/assets/activitypub/{inbox-CCjkuow2.js → inbox-BW-yvUoN.js} +10 -10
- package/core/built/admin/assets/activitypub/{inbox-d8oJRTf4.js → inbox-CbTTdDQ3.js} +2 -2
- package/core/built/admin/assets/activitypub/{label-1AA_s9Fa.js → label-kPMmYI7l.js} +3 -3
- package/core/built/admin/assets/activitypub/layout-BL4_jtuV.js +1 -0
- package/core/built/admin/assets/activitypub/{moderation-CnmxEB8w.js → moderation-CuidJzc0.js} +10 -10
- package/core/built/admin/assets/activitypub/{note-ZKc_Bnba.js → note-CAMRRSqD.js} +7 -7
- package/core/built/admin/assets/activitypub/{notifications-CB2tJZau.js → notifications-BmNlXGgp.js} +9 -9
- package/core/built/admin/assets/activitypub/{onboarding-BsJ9E5qf.js → onboarding-Bqg7fh_L.js} +2 -2
- package/core/built/admin/assets/activitypub/{onboarding-CSUJJIlh.js → onboarding-Dmun9jr_.js} +2 -2
- package/core/built/admin/assets/activitypub/{preferences-0-JZnUkI.js → preferences--oH19wf9.js} +11 -11
- package/core/built/admin/assets/activitypub/{profile-C35cFIhM.js → profile-DH_tQx2D.js} +14 -14
- package/core/built/admin/assets/activitypub/{reply-DYK5vVqb.js → reply-Cap9PxSH.js} +2 -2
- package/core/built/admin/assets/activitypub/{routes-BD4vscyc.js → routes-DdyY9uFF.js} +30 -30
- package/core/built/admin/assets/activitypub/{separator-BbQqTm-p.js → separator-CAxxu8VV.js} +3 -3
- package/core/built/admin/assets/activitypub/{settings-BsMROdqh.js → settings-B6EEcVkW.js} +6 -6
- package/core/built/admin/assets/activitypub/{site-O0RL9YCN.js → site-BYps63oh.js} +2 -2
- package/core/built/admin/assets/activitypub/{step-1-BMSx7c_X.js → step-1-CKjR2KAm.js} +6 -6
- package/core/built/admin/assets/activitypub/{step-2-DtPQzlTH.js → step-2-B6PKfOUQ.js} +6 -6
- package/core/built/admin/assets/activitypub/{step-3-CLlOZTyt.js → step-3-C-qBbcUo.js} +11 -11
- package/core/built/admin/assets/activitypub/{tabs-Dxk-b9M-.js → tabs-DLhZtVde.js} +6 -6
- package/core/built/admin/assets/activitypub/{topic-filter-5yZH6tId.js → topic-filter-DsUOuu0k.js} +3 -3
- package/core/built/admin/assets/activitypub/{use-activity-pub-queries-CV50qe03.js → use-activity-pub-queries-CX9snsLs.js} +3 -3
- package/core/built/admin/assets/activitypub/{use-navigate-with-base-path-Bmk5h4lW.js → use-navigate-with-base-path-DsJTGDSS.js} +988 -959
- package/core/built/admin/assets/activitypub/{use-reply-chain-data-Cbvzgjzd.js → use-reply-chain-data-AJi9zkzm.js} +5 -5
- package/core/built/admin/assets/activitypub/{users-BjcoP_HC.js → users-inweyKL5.js} +186 -160
- package/core/built/admin/assets/activitypub/{x-DbQZOLiI.js → x-DR8AT3-4.js} +2 -2
- package/core/built/admin/assets/{add-integration-modal-BlF6rs_f.js → add-integration-modal-BT_onDJy.js} +1 -1
- package/core/built/admin/assets/{add-newsletter-modal-CglVQqah.js → add-newsletter-modal-Cx1kQpiY.js} +1 -1
- package/core/built/admin/assets/{add-recommendation-modal-wz7BsuaG.js → add-recommendation-modal-B5nvAhvr.js} +1 -1
- package/core/built/admin/assets/{analytics-C4HE1gBg.js → analytics-DjoJWPI7.js} +1 -1
- package/core/built/admin/assets/{announcement-bar-modal-Ci4zz8jO.js → announcement-bar-modal-Dwd0EGFP.js} +1 -1
- package/core/built/admin/assets/{api-keys-3-0vJC3Y.js → api-keys-BGPzLHzA.js} +1 -1
- package/core/built/admin/assets/{api-keys-Ck-Yteiv.js → api-keys-BoeacM-s.js} +1 -1
- package/core/built/admin/assets/{audience-CtbA54Sn.js → audience-ceV3XVHq.js} +1 -1
- package/core/built/admin/assets/automated-emails-BLesE41L.js +1 -0
- package/core/built/admin/assets/{automations-sAcJ1334.js → automations-BN4u3GR8.js} +1 -1
- package/core/built/admin/assets/automations-C-ZTUwW3.js +1 -0
- package/core/built/admin/assets/{bluesky-sharing-BEtJ_gL_.js → bluesky-sharing-vzh-oPXL.js} +1 -1
- package/core/built/admin/assets/{breadcrumb-zUrZrBtW.js → breadcrumb-CaLk2b7D.js} +1 -1
- package/core/built/admin/assets/{button-eNMKQWXr.js → button-Dvcv1QSR.js} +1 -1
- package/core/built/admin/assets/calendar-Bl9RLcZX.js +1 -0
- package/core/built/admin/assets/{chart-helpers-CfBKt0vT.js → chart-helpers-FHywU0pj.js} +1 -1
- package/core/built/admin/assets/{checkbox-CgOn_tKW.js → checkbox-BtayFtjg.js} +1 -1
- package/core/built/admin/assets/chunk.254.035b85ec456ebbd7336b.js +440 -0
- package/core/built/admin/assets/{chunk.524.a697dee88db67fdf6021.js → chunk.524.e6975095fccdf22d90f8.js} +5 -5
- package/core/built/admin/assets/{chunk.582.5ed5d124cfca9c259b9c.js → chunk.582.98b485f9b2802f540897.js} +6 -6
- package/core/built/admin/assets/{chunk.492.f24d855d7e3f3aad261c.js → chunk.901.4ccc639821020230bcca.js} +9949 -7921
- package/core/built/admin/assets/{code-editor-view-K2wI-I5f.js → code-editor-view-C3ZfoF1X.js} +1 -1
- package/core/built/admin/assets/{code-editor-view-BYNoAoNV.js → code-editor-view-CAyRWy1s.js} +1 -1
- package/core/built/admin/assets/{color-picker-Ddw80xX6.js → color-picker-G4kGR7rp.js} +1 -1
- package/core/built/admin/assets/{color-picker-field-D9nUhvA7.js → color-picker-field-DQFVTNnT.js} +1 -1
- package/core/built/admin/assets/{combobox-w9j8PPQT.js → combobox-BnYzgEB4.js} +1 -1
- package/core/built/admin/assets/{command-BfpHORBv.js → command-C_vyTikI.js} +1 -1
- package/core/built/admin/assets/comments-aBrxfnZf.js +1 -0
- package/core/built/admin/assets/{config-DOMQDZGZ.js → config-kSHvwdTG.js} +1 -1
- package/core/built/admin/assets/{confirmation-context-CBM8G0Vj.js → confirmation-context-DwXX_Y5h.js} +1 -1
- package/core/built/admin/assets/{content-api-modal-TXRz3U7S.js → content-api-modal-D2G0nJP6.js} +1 -1
- package/core/built/admin/assets/{context-menu-_QMdd3kp.js → context-menu-DOVB6yaz.js} +1 -1
- package/core/built/admin/assets/{copy-field-6N01S07E.js → copy-field-DCJwh9qf.js} +1 -1
- package/core/built/admin/assets/{create-ghost-browse-value-source-qIBymvvf.js → create-ghost-browse-value-source-5C53jJaX.js} +1 -1
- package/core/built/admin/assets/custom-field-type-option-BAuW0F-E.js +1 -0
- package/core/built/admin/assets/{custom-integration-modal-DmNquxUV.js → custom-integration-modal-AbJGVyKc.js} +1 -1
- package/core/built/admin/assets/{date-range-select-uvz_DtPh.js → date-range-select-BY3K-ukj.js} +1 -1
- package/core/built/admin/assets/design-and-theme-modal-BvEy4_pC.js +2 -0
- package/core/built/admin/assets/{dirty-confirm-dialog-BZ1iytEd.js → dirty-confirm-dialog-DVPuGz3U.js} +1 -1
- package/core/built/admin/assets/{disabled-sources-indicator-DMRrxsiJ.js → disabled-sources-indicator-Cy7Zp4c8.js} +1 -1
- package/core/built/admin/assets/{domain-BNYrt0aD.js → domain-Dl61QGuk.js} +1 -1
- package/core/built/admin/assets/{dropzone-D7nFdAe5.js → dropzone-Dtz5Rmjt.js} +4 -4
- package/core/built/admin/assets/edit-profile-DNJSMDwm.js +1 -0
- package/core/built/admin/assets/editor-DbAen9zf.js +8 -0
- package/core/built/admin/assets/editor-screen-BFWThIai.js +26 -0
- package/core/built/admin/assets/email-sending-status-context-CWDOD1FN.js +1 -0
- package/core/built/admin/assets/email-sending-status-provider-DCPkDICt.js +1 -0
- package/core/built/admin/assets/emails-vFMk4yYl.js +1 -0
- package/core/built/admin/assets/{embed-signup-form-modal-Ds6mPEi5.js → embed-signup-form-modal-DGqsORxS.js} +1 -1
- package/core/built/admin/assets/{explore-UY10Egsp.js → explore-nnRr1Fja.js} +1 -1
- package/core/built/admin/assets/feature-flag-overrides-context-DQjdJFAk.js +1 -0
- package/core/built/admin/assets/{feature-image-placeholder-D1iF_8bc.js → feature-image-placeholder-BrIHmPs8.js} +1 -1
- package/core/built/admin/assets/{feed-81C8mJWR.js → feed-BNUcNu-W.js} +1 -1
- package/core/built/admin/assets/feedback-DJ4Zb9rZ.js +1 -0
- package/core/built/admin/assets/{field-Dihp5p18.js → field-C93_Mg6j.js} +1 -1
- package/core/built/admin/assets/filter-sources-CGJb4C5r.js +1 -0
- package/core/built/admin/assets/{filters-DirqNXjH.js → filters--kKP-EC8.js} +1 -1
- package/core/built/admin/assets/filters-DxA_a4FP.js +1 -0
- package/core/built/admin/assets/{first-promoter-modal-CT6MxYZb.js → first-promoter-modal-BYDtrz2S.js} +1 -1
- package/core/built/admin/assets/focus-koenig-editor-on-bottom-click-BbSnGOtK.js +1 -0
- package/core/built/admin/assets/{ghost-8eabfc1ece81b03cf7b90780d31487e8.css → ghost-8fd5bb799356bbefb254210ba7e1236d.css} +1 -1
- package/core/built/admin/assets/{ghost-c2848508292937415f20f5a830eea59e.js → ghost-b4e8a403baba61905cd7560e30b9732d.js} +43 -27
- package/core/built/admin/assets/{ghost-dark-a7bebe2c561f55369dcf29f4c820f7ff.css → ghost-dark-cac0cb2d5bb78e9bd14d8d1c2768ed45.css} +1 -1
- package/core/built/admin/assets/{gift-link-modal-CQVAye17.js → gift-link-modal-B7u5bD4e.js} +1 -1
- package/core/built/admin/assets/{gift-links-DLDS7ljO.js → gift-links-CfLSnst2.js} +1 -1
- package/core/built/admin/assets/growth-Cd1uO9d2.js +1 -0
- package/core/built/admin/assets/growth-aG32xfdE.js +3 -0
- package/core/built/admin/assets/{history-modal-CFd1Hvx6.js → history-modal-Df8lW8h-.js} +1 -1
- package/core/built/admin/assets/hooks-Cy_-oZ4o.js +2 -0
- package/core/built/admin/assets/{html-field-CJBCLTvv.js → html-field-DA4eU7eq.js} +1 -1
- package/core/built/admin/assets/{images-scfkWZiK.js → images-KXmyO3Ss.js} +1 -1
- package/core/built/admin/assets/{inbox-Mcp4DXZN.js → inbox-gJHG7_xd.js} +6 -6
- package/core/built/admin/assets/index-BHHXtR5C.css +2 -0
- package/core/built/admin/assets/index-CgMCwsxN.js +4 -0
- package/core/built/admin/assets/index.es-CY6-yuw9.js +1 -0
- package/core/built/admin/assets/{input-group-CMhe2DvY.js → input-group-BE8rM2y1.js} +1 -1
- package/core/built/admin/assets/{integrations-Bjbu86Z0.js → integrations-B4kuRBFY.js} +1 -1
- package/core/built/admin/assets/{invite-user-modal-DfheMXs0.js → invite-user-modal-B4CuNcx4.js} +1 -1
- package/core/built/admin/assets/koenig-lexical/koenig-lexical.js +2 -2
- package/core/built/admin/assets/koenig-lexical/koenig-lexical.umd.js +2 -2
- package/core/built/admin/assets/{koenig-lexical-DBSqAuiI.js → koenig-lexical-CGXb0F8o.js} +2 -2
- package/core/built/admin/assets/koenig-loader-BeM5rFPX.js +2 -0
- package/core/built/admin/assets/{kpi-card-DBRMfGOW.js → kpi-card-B21aToe8.js} +1 -1
- package/core/built/admin/assets/{kpi-card-DFafD1qq.js → kpi-card-pz6Wv4Ae.js} +1 -1
- package/core/built/admin/assets/{kpi-helpers-Cv8i8hns.js → kpi-helpers-Dq5jelmP.js} +1 -1
- package/core/built/admin/assets/{kpi-tabs-BJItvLYm.js → kpi-tabs-DEZHpKUt.js} +1 -1
- package/core/built/admin/assets/{label-BnSCvffu.js → label-OLCzze8N.js} +1 -1
- package/core/built/admin/assets/label-picker-BigOvMPV.js +1 -0
- package/core/built/admin/assets/{labels-CH3Kn8RV.js → labels-Dr0SgUQD.js} +1 -1
- package/core/built/admin/assets/layout-DUTL8SH5.js +1 -0
- package/core/built/admin/assets/lib-7QPTI0FS.js +1 -0
- package/core/built/admin/assets/link-helpers-BRAg9SCj.js +1 -0
- package/core/built/admin/assets/links-BDHPTlyj.js +1 -0
- package/core/built/admin/assets/{member-custom-fields-DDQV6QeG.js → member-custom-fields-TRTHCAz9.js} +1 -1
- package/core/built/admin/assets/member-detail-b6dRwc3C.js +1 -0
- package/core/built/admin/assets/members-Czt5lJSc.js +4 -0
- package/core/built/admin/assets/{moderation-AgCIEso4.js → moderation-ZWefD9uH.js} +1 -1
- package/core/built/admin/assets/{multi-select-combobox-BcITkUVr.js → multi-select-combobox-CT13MTo-.js} +1 -1
- package/core/built/admin/assets/navigation-modal-C8FEhBK5.js +1 -0
- package/core/built/admin/assets/newsletter-5VYW4RyJ.js +1 -0
- package/core/built/admin/assets/newsletter-detail-modal-ChjC0ZqH.js +1 -0
- package/core/built/admin/assets/{newsletter-emails-DKzwafuh.js → newsletter-emails-DZH6I-PY.js} +1 -1
- package/core/built/admin/assets/{newsletters-BRBb_uQC.js → newsletters-DOC9KBcX.js} +1 -1
- package/core/built/admin/assets/newsletters-Rq1M3GD-.js +1 -0
- package/core/built/admin/assets/{note-DyGHtS9a.js → note-DIV-Pojr.js} +1 -1
- package/core/built/admin/assets/{notifications-ZgWniKna.js → notifications-s20-H49V.js} +1 -1
- package/core/built/admin/assets/{offers-9J1CSiLy.js → offers--e2nGvkW.js} +1 -1
- package/core/built/admin/assets/{offers-container-modal-B-E8TIWr.js → offers-container-modal-BmG5M5Tv.js} +1 -1
- package/core/built/admin/assets/onboarding-CUuy9unR.js +1 -0
- package/core/built/admin/assets/{onboarding-CzIsre-d.js → onboarding-pXyct0Jm.js} +1 -1
- package/core/built/admin/assets/{onboarding-route-CaavZulg.js → onboarding-route-CK4pcXoR.js} +1 -1
- package/core/built/admin/assets/overview-CaPsciMs.js +1 -0
- package/core/built/admin/assets/overview-a8GfcsKX.js +1 -0
- package/core/built/admin/assets/{page-header-De0VzKBi.js → page-header-DM_KyoFI.js} +1 -1
- package/core/built/admin/assets/{pagemenu-B5KKCpbA.js → pagemenu-vgZVUVKR.js} +1 -1
- package/core/built/admin/assets/pages-CjDY2CBI.js +1 -0
- package/core/built/admin/assets/pages-route-BzKZYdV5.js +1 -0
- package/core/built/admin/assets/{pintura-modal-BZ2J9w3n.js → pintura-modal-DExCF1ii.js} +1 -1
- package/core/built/admin/assets/{portal-frame-B6Hr9wHc.js → portal-frame-Cqanidq4.js} +1 -1
- package/core/built/admin/assets/portal-modal-oinBgA27.js +1 -0
- package/core/built/admin/assets/post-analytics-C5oJ1dWV.js +1 -0
- package/core/built/admin/assets/post-analytics-header-OATo3X_r.js +1 -0
- package/core/built/admin/assets/post-analytics-provider-tOpIVGT5.js +1 -0
- package/core/built/admin/assets/post-helpers-C88JBa4D.js +1 -0
- package/core/built/admin/assets/post-share-modal-DvhC1XgV.js +1 -0
- package/core/built/admin/assets/post-utils-DKF4mfuo.js +1 -0
- package/core/built/admin/assets/posts-list-screen-o4ZjbgS3.js +2 -0
- package/core/built/admin/assets/posts-pCPrhQeR.js +1 -0
- package/core/built/admin/assets/posts-route-9F--xdIb.js +1 -0
- package/core/built/admin/assets/{preferences-C5YJLp74.js → preferences--vNubsqD.js} +2 -2
- package/core/built/admin/assets/{preview-modal-BfeFqi5y.js → preview-modal-YYbzlYdO.js} +1 -1
- package/core/built/admin/assets/profile-BllKV3dR.js +1 -0
- package/core/built/admin/assets/radio-group-DL8GI8rt.js +1 -0
- package/core/built/admin/assets/{referrers-CnhCMWCs.js → referrers-D8oHPmDB.js} +1 -1
- package/core/built/admin/assets/router-provider-BSvTXgZY.js +1 -0
- package/core/built/admin/assets/schemas-BoYdB6YU.js +64 -0
- package/core/built/admin/assets/{select-cb0t_TAJ.js → select-v5YbA3Mw.js} +1 -1
- package/core/built/admin/assets/settings-PEsZupw1.js +4 -0
- package/core/built/admin/assets/{settings-breadcrumbs-DLzbRRSt.js → settings-breadcrumbs-NwPnCTC7.js} +1 -1
- package/core/built/admin/assets/{settings-DZqxR0Da.js → settings-u_s1CRkr.js} +1 -1
- package/core/built/admin/assets/{share-modal-D2-Bz1_I.js → share-modal-SskCmVGL.js} +1 -1
- package/core/built/admin/assets/{slack-modal-DYDTUria.js → slack-modal-XxSJiYgo.js} +1 -1
- package/core/built/admin/assets/{sort-button-VVeQjjbu.js → sort-button-Cx1KtINE.js} +1 -1
- package/core/built/admin/assets/{source-icon-Ck5_5Kgq.js → source-icon-Bdp9Im_5.js} +1 -1
- package/core/built/admin/assets/stats-D9PDLS3x.js +1 -0
- package/core/built/admin/assets/stats-view-W2g6Jsd-.js +1 -0
- package/core/built/admin/assets/{step-1-CsaBjeN4.js → step-1-BQYzvBzr.js} +1 -1
- package/core/built/admin/assets/{step-2-D2vnxOOM.js → step-2-xES32xJV.js} +1 -1
- package/core/built/admin/assets/{step-3-wBoLdGEb.js → step-3-DA_XK5kW.js} +2 -2
- package/core/built/admin/assets/{stripe-button-CDgLz0S0.js → stripe-button-CVsLHelt.js} +1 -1
- package/core/built/admin/assets/{stripe-connect-modal-CSjMJetP.js → stripe-connect-modal-ClmLOMGS.js} +1 -1
- package/core/built/admin/assets/style-Wd9nQubI.css +1 -0
- package/core/built/admin/assets/{table-Do6iQ83Q.js → table-BenqVupI.js} +1 -1
- package/core/built/admin/assets/{tabs-D2yWLMp_.js → tabs-eBBlxPp8.js} +1 -1
- package/core/built/admin/assets/tag-detail-Ce8Se2qd.js +2 -0
- package/core/built/admin/assets/tag-picker-C3UR-uJ-.js +1 -0
- package/core/built/admin/assets/tags-B-kJxCs7.js +1 -0
- package/core/built/admin/assets/{tags-zTFiKRpb.js → tags-ChfdwJyS.js} +1 -1
- package/core/built/admin/assets/{testimonials-modal-CtnZBJKl.js → testimonials-modal-9Q6fT06V.js} +1 -1
- package/core/built/admin/assets/tier-detail-modal-CDyYdqK7.js +1 -0
- package/core/built/admin/assets/tiers-BCpIOGQr.js +1 -0
- package/core/built/admin/assets/{toggle-group-ByUJsxwD.js → toggle-group-CviIkyok.js} +1 -1
- package/core/built/admin/assets/{topic-filter-BgC3g5_v.js → topic-filter-I2jCBGxm.js} +1 -1
- package/core/built/admin/assets/{transistor-modal-Drr0SNfo.js → transistor-modal-p53u3W8y.js} +1 -1
- package/core/built/admin/assets/{trend-badge-6ye93YAW.js → trend-badge-CideVzQd.js} +1 -1
- package/core/built/admin/assets/{unsplash-modal-p6AoQoWp.js → unsplash-modal-DY8UcKcE.js} +1 -1
- package/core/built/admin/assets/{use-analytics-data-CWCMAESo.js → use-analytics-data-DAIGcr2f.js} +1 -1
- package/core/built/admin/assets/{use-check-theme-limit-error-Cw3WQHy8.js → use-check-theme-limit-error-DRUjK4YM.js} +1 -1
- package/core/built/admin/assets/use-filter-params-JkZhIS8L.js +1 -0
- package/core/built/admin/assets/{use-filterable-api-CzXcpUh8.js → use-filterable-api-BVEVMrhZ.js} +1 -1
- package/core/built/admin/assets/{use-growth-stats-DCVG3s9w.js → use-growth-stats-937CUj6j.js} +1 -1
- package/core/built/admin/assets/use-host-limits-D0Dv3tKA.js +1 -0
- package/core/built/admin/assets/{use-limiter-D2WRRx0H.js → use-limiter-CohWfzvK.js} +1 -1
- package/core/built/admin/assets/{use-navigate-with-base-path-BHPA228f.js → use-navigate-with-base-path-BkxcPj5l.js} +1 -1
- package/core/built/admin/assets/use-pintura-config-xgytjU35.js +1 -0
- package/core/built/admin/assets/{use-pintura-editor-BfN1UwzH.js → use-pintura-editor-CaV1mbfO.js} +1 -1
- package/core/built/admin/assets/{use-post-referrers-Czg47m8s.js → use-post-referrers-BCQI7fDg.js} +1 -1
- package/core/built/admin/assets/{use-reply-chain-data-ns0caK8k.js → use-reply-chain-data-CYRhoaxY.js} +1 -1
- package/core/built/admin/assets/{use-router-history-entry-uldn7zJO.js → use-router-history-entry-NOKcd--l.js} +1 -1
- package/core/built/admin/assets/{use-setting-group-DpcuCUDg.js → use-setting-group-bLKMwoBT.js} +1 -1
- package/core/built/admin/assets/{use-settings-navigation-CZjGrhsp.js → use-settings-navigation-B-qrriKD.js} +1 -1
- package/core/built/admin/assets/{use-simple-pagination-DzJWobPR.js → use-simple-pagination-CNPd6Rf6.js} +1 -1
- package/core/built/admin/assets/use-staff-users-pRIMIyiW.js +1 -0
- package/core/built/admin/assets/{use-tinybird-query-CSnGXzZh.js → use-tinybird-query-CmdbCS9X.js} +1 -1
- package/core/built/admin/assets/{use-tinybird-token-DTOKRR7e.js → use-tinybird-token-KLne235s.js} +1 -1
- package/core/built/admin/assets/{use-unsaved-changes-guard-CBzs-KPi.js → use-unsaved-changes-guard-7-ug0JdH.js} +1 -1
- package/core/built/admin/assets/use-upgrade-route-Dm_qqKr0.js +1 -0
- package/core/built/admin/assets/{use-url-input-DFr8lCbS.js → use-url-input-fvp-TpPx.js} +1 -1
- package/core/built/admin/assets/user-detail-modal-D3KlGYv-.js +1 -0
- package/core/built/admin/assets/{users-Cg-OeGzC.js → users-DVNWrqg9.js} +1 -1
- package/core/built/admin/assets/{vendor-5753232c7d6ffb3c44e1eb0a02133953.js → vendor-2dd263291938d407802568d3357ec69e.js} +19 -17
- package/core/built/admin/assets/{virtual-list-BW-padMe.js → virtual-list-CZ3RK2Yf.js} +1 -1
- package/core/built/admin/assets/{web-C1v33ehA.js → web-ClEJsCAj.js} +2 -2
- package/core/built/admin/assets/web-X9rdnrtq.js +1 -0
- package/core/built/admin/assets/{zapier-modal-BBFfI6Ml.js → zapier-modal-DfVhV17j.js} +1 -1
- package/core/built/admin/index.html +19 -18
- package/core/server/adapters/jobs/InMemoryJobsBackend.js +74 -29
- package/core/server/api/endpoints/authentication.js +1 -2
- package/core/server/api/endpoints/authors-public.js +15 -5
- package/core/server/api/endpoints/emails.js +13 -0
- package/core/server/api/endpoints/index.js +8 -0
- package/core/server/api/endpoints/member-metafields-members.js +23 -0
- package/core/server/api/endpoints/member-metafields.js +33 -20
- package/core/server/api/endpoints/members-account.js +42 -0
- package/core/server/api/endpoints/newsletters-public.js +10 -1
- package/core/server/api/endpoints/pages-public.js +15 -5
- package/core/server/api/endpoints/posts-public.js +15 -5
- package/core/server/api/endpoints/tags-public.js +22 -3
- package/core/server/api/endpoints/tiers-checkout-config.js +2 -2
- package/core/server/api/endpoints/tiers-public.js +38 -1
- package/core/server/api/endpoints/users.js +2 -2
- package/core/server/api/endpoints/utils/api-filter-utils.js +170 -3
- package/core/server/api/endpoints/utils/public-cache-keys.js +3 -0
- package/core/server/api/endpoints/utils/serializers/input/authors.js +2 -0
- package/core/server/api/endpoints/utils/serializers/input/members.js +16 -2
- package/core/server/api/endpoints/utils/serializers/input/pages.js +2 -0
- package/core/server/api/endpoints/utils/serializers/input/posts.js +2 -0
- package/core/server/api/endpoints/utils/serializers/input/tags.js +2 -0
- package/core/server/api/endpoints/utils/serializers/output/emails.js +7 -0
- package/core/server/api/endpoints/utils/serializers/output/index.js +4 -0
- package/core/server/api/endpoints/utils/serializers/output/member-metafields.js +3 -3
- package/core/server/api/endpoints/utils/serializers/output/members-account.js +19 -0
- package/core/server/api/endpoints/utils/serializers/output/members-csv-transform.js +1 -1
- package/core/server/api/endpoints/utils/serializers/output/tiers.js +10 -2
- package/core/server/api/endpoints/utils/serializers/output/users.js +0 -10
- package/core/server/data/exporter/table-lists.js +3 -3
- package/core/server/data/migrations/versions/6.53/2026-07-15-20-22-53-add-members-custom-field-values.js +1 -1
- package/core/server/data/migrations/versions/6.57/2026-08-04-18-00-00-store-custom-field-values-as-leaf-rows.js +10 -1
- package/core/server/data/migrations/versions/6.63/2026-09-03-10-07-03-rename-custom-field-tables-to-metafields.js +169 -0
- package/core/server/data/migrations/versions/6.63/2026-09-03-11-03-31-remove-member-custom-field-read-permissions.js +30 -0
- package/core/server/data/schema/fixtures/fixtures.json +0 -11
- package/core/server/data/schema/lib/default-index-name.js +8 -11
- package/core/server/data/schema/schema.js +18 -18
- package/core/server/data/seeders/README.md +48 -0
- package/core/server/data/tinybird/pipes/mv_hits.pipe +86 -50
- package/core/server/lib/db-types/count.js +16 -0
- package/core/server/lib/validate-password.js +81 -120
- package/core/server/models/action.js +4 -4
- package/core/server/models/base/plugins/filtered-collection.js +16 -0
- package/core/server/models/member.js +6 -6
- package/core/server/models/user.js +1 -1
- package/core/server/services/automations/automations-api.js +1 -1
- package/core/server/services/automations/database-automations-repository.js +11 -4
- package/core/server/services/email-service/CONTEXT.md +37 -0
- package/core/server/services/email-service/README.md +42 -0
- package/core/server/services/email-service/batch-sending-service.js +2 -0
- package/core/server/services/email-service/email-controller.js +18 -2
- package/core/server/services/email-service/email-service-wrapper.js +3 -0
- package/core/server/services/email-service/sending-status-schema.js +21 -0
- package/core/server/services/email-service/sending-status-serializers.js +33 -0
- package/core/server/services/email-service/sending-status-service.js +47 -0
- package/core/server/services/email-service/sending-status.js +111 -0
- package/core/server/services/email-suppression-list/email-suppression-list.js +0 -33
- package/core/server/services/email-suppression-list/mailgun-email-suppression-list.js +6 -7
- package/core/server/services/gifts/README.md +2 -2
- package/core/server/services/gifts/constants.js +1 -1
- package/core/server/services/gifts/gift-service.js +19 -57
- package/core/server/services/gifts/index.js +0 -2
- package/core/server/services/jobs-service/index.js +8 -0
- package/core/server/services/jobs-service/jobs-service.js +52 -3
- package/core/server/services/jobs-service/register-job-handlers.js +13 -2
- package/core/server/services/members/account-service.js +98 -0
- package/core/server/services/members/api.js +4 -4
- package/core/server/services/members/import-export/export/exporter.js +20 -20
- package/core/server/services/members/import-export/import/completion-email.js +6 -6
- package/core/server/services/members/import-export/import/importer.js +13 -13
- package/core/server/services/members/import-export/index.js +7 -7
- package/core/server/services/members/members-api/members-api.js +26 -6
- package/core/server/services/members/members-api/repositories/member-repository.js +4 -4
- package/core/server/services/members/members-api/services/member-bread-service.js +45 -39
- package/core/server/services/members/members-ssr.js +18 -0
- package/core/server/services/members/middleware.js +95 -81
- package/core/server/services/members/service.js +70 -42
- package/core/server/services/members/utils.js +9 -0
- package/core/server/services/members-metafields/access.js +28 -0
- package/core/server/services/{members-custom-fields → members-metafields}/actions.js +5 -5
- package/core/server/services/members-metafields/bindings-service.js +147 -0
- package/core/server/services/{members-custom-fields → members-metafields}/codec.js +4 -4
- package/core/server/services/{members-custom-fields → members-metafields}/config.js +1 -1
- package/core/server/services/{members-custom-fields → members-metafields}/definitions-service.js +17 -23
- package/core/server/services/{members-custom-fields → members-metafields}/filter.js +9 -9
- package/core/server/services/{members-custom-fields → members-metafields}/index.js +16 -7
- package/core/server/services/{members-custom-fields → members-metafields}/key.js +1 -1
- package/core/server/services/{members-custom-fields → members-metafields}/models.js +4 -4
- package/core/server/services/members-metafields/namespaces.js +34 -0
- package/core/server/services/{members-custom-fields → members-metafields}/queries.js +1 -1
- package/core/server/services/{members-custom-fields → members-metafields}/schema.js +16 -12
- package/core/server/services/{members-custom-fields → members-metafields}/serializers.js +6 -6
- package/core/server/services/{members-custom-fields → members-metafields}/values-service.js +32 -22
- package/core/server/services/mentions/mention-sending-service.js +26 -9
- package/core/server/services/mentions/send-webmentions-job.js +18 -0
- package/core/server/services/mentions/service.js +1 -31
- package/core/server/services/stripe/services/webhook/checkout-session-event-service.js +2 -2
- package/core/server/services/stripe/stripe-service.js +4 -4
- package/core/server/services/tier-checkout-config/codec.js +2 -2
- package/core/server/services/tier-checkout-config/index.js +2 -1
- package/core/server/services/tier-checkout-config/models.js +2 -2
- package/core/server/services/tier-checkout-config/queries.js +8 -8
- package/core/server/services/tier-checkout-config/serializers.js +57 -0
- package/core/server/services/tier-checkout-config/service.js +1 -1
- package/core/server/services/tiers/service.js +3 -3
- package/core/server/services/url/router-filter.js +8 -10
- package/core/server/services/users.js +1 -19
- package/core/server/web/api/endpoints/admin/routes.js +1 -0
- package/core/server/web/members/account/index.js +2 -0
- package/core/server/web/members/account/routes.js +46 -0
- package/core/server/web/members/app.js +4 -18
- package/core/shared/config/defaults.json +1 -1
- package/core/shared/labs.js +4 -2
- package/package.json +22 -22
- package/pnpm-lock.yaml +513 -571
- package/pnpm-workspace.yaml +12 -12
- package/components/tryghost-custom-field-types-0.0.0.tgz +0 -0
- package/core/built/admin/assets/activitypub/layout-2-0bw6HN.js +0 -1
- package/core/built/admin/assets/automated-emails-D5VVMND9.js +0 -1
- package/core/built/admin/assets/automations-CzKt5fb8.js +0 -1
- package/core/built/admin/assets/chunk.598.7e056fabb47ce7dbd73f.js +0 -366
- package/core/built/admin/assets/comments-BLmCmyCs.js +0 -1
- package/core/built/admin/assets/custom-field-type-option-BddFlJFa.js +0 -1
- package/core/built/admin/assets/design-and-theme-modal-BSmo12Op.js +0 -2
- package/core/built/admin/assets/edit-profile-C5Asm4LA.js +0 -1
- package/core/built/admin/assets/editor-REokrzci.js +0 -8
- package/core/built/admin/assets/filter-sources-BO9xUPj7.js +0 -1
- package/core/built/admin/assets/filters-CRUWecfY.js +0 -1
- package/core/built/admin/assets/growth-BWIu-6xj.js +0 -3
- package/core/built/admin/assets/growth-DU29oxeA.js +0 -1
- package/core/built/admin/assets/hooks-CuEZV2-q.js +0 -2
- package/core/built/admin/assets/index-6MkPdCtr.js +0 -4
- package/core/built/admin/assets/index-Bn7QhcZu.css +0 -2
- package/core/built/admin/assets/index.es-CNnuNH0d.js +0 -1
- package/core/built/admin/assets/koenig-loader-aFQNlJlD.js +0 -2
- package/core/built/admin/assets/label-picker-KVoo91sh.js +0 -1
- package/core/built/admin/assets/layout-Bjv2Ll-5.js +0 -1
- package/core/built/admin/assets/link-helpers-MVDdnFCY.js +0 -1
- package/core/built/admin/assets/member-detail-CdJF6Agw.js +0 -1
- package/core/built/admin/assets/members-DjQbq9Z2.js +0 -4
- package/core/built/admin/assets/navigation-modal-BkT7b1M2.js +0 -1
- package/core/built/admin/assets/newsletter-BMMAuvgq.js +0 -1
- package/core/built/admin/assets/newsletter-detail-modal-0SCJ7Zpm.js +0 -1
- package/core/built/admin/assets/newsletters-DhNigJUh.js +0 -1
- package/core/built/admin/assets/onboarding-qg8Akovm.js +0 -1
- package/core/built/admin/assets/overview-BW8GLeYi.js +0 -1
- package/core/built/admin/assets/overview-BkXZNzaZ.js +0 -1
- package/core/built/admin/assets/pages-jgaFm69d.js +0 -1
- package/core/built/admin/assets/pages-route-CIUAQxtY.js +0 -1
- package/core/built/admin/assets/portal-modal-D4ceei3t.js +0 -1
- package/core/built/admin/assets/post-analytics-header-BYCsT0GP.js +0 -1
- package/core/built/admin/assets/post-analytics-ot7f6pih.js +0 -1
- package/core/built/admin/assets/post-analytics-provider-Bo1gmYaP.js +0 -1
- package/core/built/admin/assets/post-helpers-C5OQMBoi.js +0 -1
- package/core/built/admin/assets/post-share-modal-C-PaYZ_e.js +0 -1
- package/core/built/admin/assets/posts-DuGazgTb.js +0 -1
- package/core/built/admin/assets/posts-list-screen-CBGGgjjj.js +0 -2
- package/core/built/admin/assets/posts-route-D6xmS7Vf.js +0 -1
- package/core/built/admin/assets/profile-B8mx2yAu.js +0 -1
- package/core/built/admin/assets/radio-group-DczlLKOn.js +0 -1
- package/core/built/admin/assets/router-provider-B0gZyiGJ.js +0 -1
- package/core/built/admin/assets/schemas-DppqmpeJ.js +0 -64
- package/core/built/admin/assets/settings-DvfTNdHQ.js +0 -4
- package/core/built/admin/assets/stats-Rjmk5owg.js +0 -1
- package/core/built/admin/assets/stats-view-BGGmkmgv.js +0 -1
- package/core/built/admin/assets/tag-detail-BhXlOsCa.js +0 -2
- package/core/built/admin/assets/tags-ldukRApe.js +0 -1
- package/core/built/admin/assets/tier-detail-modal-BOs8e_G8.js +0 -1
- package/core/built/admin/assets/tiers-Nd_z4BZY.js +0 -1
- package/core/built/admin/assets/use-filter-params-BIni9taJ.js +0 -1
- package/core/built/admin/assets/use-host-limits-DZtR08oa.js +0 -1
- package/core/built/admin/assets/use-pintura-config-h-J0Lvta.js +0 -1
- package/core/built/admin/assets/use-staff-users-Csipb-O0.js +0 -1
- package/core/built/admin/assets/use-upgrade-route-DhRSo7at.js +0 -1
- package/core/built/admin/assets/user-detail-modal-B_iUClI6.js +0 -1
- package/core/built/admin/assets/web-C4BKzn2T.js +0 -1
- package/core/server/services/email-suppression-list/in-memory-email-suppression-list.js +0 -39
- package/core/server/services/members-custom-fields/bindings-service.js +0 -120
- /package/core/built/admin/assets/{chunk.492.f24d855d7e3f3aad261c.js.LICENSE.txt → chunk.901.4ccc639821020230bcca.js.LICENSE.txt} +0 -0
- /package/core/server/services/{members-custom-fields → members-metafields}/storage.js +0 -0
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
const models = require('../../models');
|
|
2
|
+
const {
|
|
3
|
+
rejectNewslettersContentApiRestrictedFieldsTransformer,
|
|
4
|
+
rejectNewslettersContentApiRestrictedOrderFields,
|
|
5
|
+
} = require('./utils/api-filter-utils');
|
|
2
6
|
|
|
3
7
|
/** @type {import('@tryghost/api-framework').Controller} */
|
|
4
8
|
const controller = {
|
|
@@ -11,7 +15,12 @@ const controller = {
|
|
|
11
15
|
options: ['filter', 'fields', 'limit', 'order', 'page'],
|
|
12
16
|
permissions: true,
|
|
13
17
|
query(frame) {
|
|
14
|
-
|
|
18
|
+
const options = {
|
|
19
|
+
...frame.options,
|
|
20
|
+
order: rejectNewslettersContentApiRestrictedOrderFields(frame.options.order),
|
|
21
|
+
mongoTransformer: rejectNewslettersContentApiRestrictedFieldsTransformer,
|
|
22
|
+
};
|
|
23
|
+
return models.Newsletter.findPage(options);
|
|
15
24
|
},
|
|
16
25
|
},
|
|
17
26
|
};
|
|
@@ -1,14 +1,17 @@
|
|
|
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
|
-
const {
|
|
5
|
+
const { rejectPagesContentApiRestrictedFieldsTransformer } = require('./utils/api-filter-utils');
|
|
5
6
|
const { generateGiftKeyData, applyGiftAccess } = require('./utils/gift-link-access');
|
|
6
7
|
const { generateOptionsData, generateAuthData } = require('./utils/public-cache-keys');
|
|
7
8
|
|
|
8
9
|
const ALLOWED_INCLUDES = ['tags', 'authors', 'tiers'];
|
|
10
|
+
const ALLOWED_READ_FIELDS = ['id', 'slug', 'uuid'];
|
|
9
11
|
|
|
10
12
|
const messages = {
|
|
11
13
|
pageNotFound: 'Page not found.',
|
|
14
|
+
missingIdentifier: 'A page id, slug or uuid is required.',
|
|
12
15
|
};
|
|
13
16
|
|
|
14
17
|
/** @type {import('@tryghost/api-framework').Controller} */
|
|
@@ -44,7 +47,7 @@ const controller = {
|
|
|
44
47
|
query(frame) {
|
|
45
48
|
const options = {
|
|
46
49
|
...frame.options,
|
|
47
|
-
mongoTransformer:
|
|
50
|
+
mongoTransformer: rejectPagesContentApiRestrictedFieldsTransformer,
|
|
48
51
|
};
|
|
49
52
|
return models.Post.findPage(options);
|
|
50
53
|
},
|
|
@@ -72,7 +75,7 @@ const controller = {
|
|
|
72
75
|
};
|
|
73
76
|
},
|
|
74
77
|
options: ['include', 'fields', 'formats', 'debug', 'absolute_urls'],
|
|
75
|
-
data:
|
|
78
|
+
data: ALLOWED_READ_FIELDS,
|
|
76
79
|
validation: {
|
|
77
80
|
options: {
|
|
78
81
|
include: {
|
|
@@ -85,11 +88,18 @@ const controller = {
|
|
|
85
88
|
},
|
|
86
89
|
permissions: true,
|
|
87
90
|
async query(frame) {
|
|
91
|
+
// GET bodies bypass the framework's declared data fields. Restrict the
|
|
92
|
+
// actual lookup too, before the model turns it into SQL predicates.
|
|
93
|
+
const data = pick(frame.data, ALLOWED_READ_FIELDS);
|
|
94
|
+
if (!Object.values(data).some(Boolean)) {
|
|
95
|
+
throw new errors.BadRequestError({ message: tpl(messages.missingIdentifier) });
|
|
96
|
+
}
|
|
97
|
+
|
|
88
98
|
const options = {
|
|
89
99
|
...frame.options,
|
|
90
|
-
mongoTransformer:
|
|
100
|
+
mongoTransformer: rejectPagesContentApiRestrictedFieldsTransformer,
|
|
91
101
|
};
|
|
92
|
-
const model = await models.Post.findOne(
|
|
102
|
+
const model = await models.Post.findOne(data, options);
|
|
93
103
|
if (!model) {
|
|
94
104
|
throw new errors.NotFoundError({
|
|
95
105
|
message: tpl(messages.pageNotFound),
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
const models = require('../../models');
|
|
2
2
|
const tpl = require('@tryghost/tpl');
|
|
3
3
|
const errors = require('@tryghost/errors');
|
|
4
|
+
const pick = require('lodash/pick');
|
|
4
5
|
const postsPublicService = require('../../services/posts-public');
|
|
5
6
|
const getPostServiceInstance = require('../../services/posts/posts-service-instance');
|
|
6
7
|
const postsService = getPostServiceInstance();
|
|
7
|
-
const {
|
|
8
|
+
const { rejectPostsContentApiRestrictedFieldsTransformer } = require('./utils/api-filter-utils');
|
|
8
9
|
const { generateGiftKeyData, applyGiftAccess } = require('./utils/gift-link-access');
|
|
9
10
|
const { generateOptionsData, generateAuthData } = require('./utils/public-cache-keys');
|
|
10
11
|
|
|
11
12
|
const ALLOWED_INCLUDES = ['tags', 'authors', 'tiers', 'sentiment'];
|
|
13
|
+
const ALLOWED_READ_FIELDS = ['id', 'slug', 'uuid'];
|
|
12
14
|
|
|
13
15
|
const messages = {
|
|
14
16
|
postNotFound: 'Post not found.',
|
|
17
|
+
missingIdentifier: 'A post id, slug or uuid is required.',
|
|
15
18
|
};
|
|
16
19
|
|
|
17
20
|
/** @type {import('@tryghost/api-framework').Controller} */
|
|
@@ -68,7 +71,7 @@ const controller = {
|
|
|
68
71
|
query(frame) {
|
|
69
72
|
const options = {
|
|
70
73
|
...frame.options,
|
|
71
|
-
mongoTransformer:
|
|
74
|
+
mongoTransformer: rejectPostsContentApiRestrictedFieldsTransformer,
|
|
72
75
|
};
|
|
73
76
|
return postsService.browsePosts(options);
|
|
74
77
|
},
|
|
@@ -93,7 +96,7 @@ const controller = {
|
|
|
93
96
|
};
|
|
94
97
|
},
|
|
95
98
|
options: ['include', 'fields', 'formats', 'debug', 'absolute_urls'],
|
|
96
|
-
data:
|
|
99
|
+
data: ALLOWED_READ_FIELDS,
|
|
97
100
|
validation: {
|
|
98
101
|
options: {
|
|
99
102
|
include: {
|
|
@@ -106,11 +109,18 @@ const controller = {
|
|
|
106
109
|
},
|
|
107
110
|
permissions: true,
|
|
108
111
|
async query(frame) {
|
|
112
|
+
// GET bodies bypass the framework's declared data fields. Restrict the
|
|
113
|
+
// actual lookup too, before the model turns it into SQL predicates.
|
|
114
|
+
const data = pick(frame.data, ALLOWED_READ_FIELDS);
|
|
115
|
+
if (!Object.values(data).some(Boolean)) {
|
|
116
|
+
throw new errors.BadRequestError({ message: tpl(messages.missingIdentifier) });
|
|
117
|
+
}
|
|
118
|
+
|
|
109
119
|
const options = {
|
|
110
120
|
...frame.options,
|
|
111
|
-
mongoTransformer:
|
|
121
|
+
mongoTransformer: rejectPostsContentApiRestrictedFieldsTransformer,
|
|
112
122
|
};
|
|
113
|
-
const model = await models.Post.findOne(
|
|
123
|
+
const model = await models.Post.findOne(data, options);
|
|
114
124
|
if (!model) {
|
|
115
125
|
throw new errors.NotFoundError({
|
|
116
126
|
message: tpl(messages.postNotFound),
|
|
@@ -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
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
|
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,
|
|
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
|
-
|
|
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({
|
|
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
|
|
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,
|
|
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
|
-
|
|
21
|
+
const transformer = mapNQLKeyValues({
|
|
20
22
|
key: {
|
|
21
23
|
from: 'subscribed',
|
|
22
24
|
to: 'newsletters.status',
|
|
@@ -32,6 +34,16 @@ 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
49
|
function liftMetafieldsInclude(frame) {
|
|
@@ -42,7 +54,7 @@ function liftMetafieldsInclude(frame) {
|
|
|
42
54
|
frame.options.withRelated = frame.options.withRelated.filter(
|
|
43
55
|
(relation) => relation !== 'metafields',
|
|
44
56
|
);
|
|
45
|
-
frame.options.
|
|
57
|
+
frame.options.includeMetafields = true;
|
|
46
58
|
}
|
|
47
59
|
|
|
48
60
|
module.exports = {
|
|
@@ -125,11 +137,13 @@ module.exports = {
|
|
|
125
137
|
|
|
126
138
|
bulkEdit(apiConfig, frame) {
|
|
127
139
|
debug('bulkEdit');
|
|
140
|
+
validateBulkFilter(frame);
|
|
128
141
|
mapSubscribedFlagToNewsletterRelation(frame);
|
|
129
142
|
},
|
|
130
143
|
|
|
131
144
|
bulkDestroy(apiConfig, frame) {
|
|
132
145
|
debug('bulkDestroy');
|
|
146
|
+
validateBulkFilter(frame);
|
|
133
147
|
mapSubscribedFlagToNewsletterRelation(frame);
|
|
134
148
|
},
|
|
135
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
|
|