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.
- package/components/ghost-storage-base-3.0.0.tgz +0 -0
- package/components/tryghost-adapter-base-cache-0.2.0.tgz +0 -0
- package/components/tryghost-adapter-base-jobs-0.0.0.tgz +0 -0
- package/components/tryghost-adapter-base-redirects-0.0.0.tgz +0 -0
- package/components/tryghost-adapter-base-route-settings-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/components/tryghost-nql-string-0.0.0.tgz +0 -0
- package/components/tryghost-parse-email-address-0.0.0.tgz +0 -0
- package/content/settings/README.md +1 -1
- package/content/themes/casper/.gitignore +28 -0
- package/content/themes/casper/assets/built/casper.js +1 -1
- package/content/themes/casper/assets/built/screen.css +1 -1
- package/content/themes/casper/assets/css/screen.css +2 -1
- package/content/themes/casper/assets/js/lightbox.js +63 -46
- package/content/themes/casper/package.json +6 -6
- package/content/themes/casper/page.hbs +1 -0
- package/content/themes/casper/post.hbs +1 -0
- package/content/themes/source/.gitignore +28 -0
- package/content/themes/source/assets/built/screen.css +1 -1
- package/content/themes/source/assets/built/source.js +1 -1
- package/content/themes/source/assets/css/screen.css +2 -1
- package/content/themes/source/assets/js/lightbox.js +62 -45
- package/content/themes/source/assets/js/main.js +2 -2
- package/content/themes/source/package.json +4 -4
- package/content/themes/source/partials/feature-image.hbs +1 -0
- package/content/themes/source/partials/post-card.hbs +1 -1
- package/core/boot.js +61 -27
- package/core/built/admin/assets/Combination-B0l4MKVh.js +41 -0
- package/core/built/admin/assets/InterVariable-DiVDrmQJ.woff2 +0 -0
- package/core/built/admin/assets/InterVariable-Italic-FCBEiFp6.woff2 +0 -0
- package/core/built/admin/assets/{about-Bve7IJS2.js → about-C1C3s5-g.js} +1 -1
- package/core/built/admin/assets/accordion-CxGsDKwa.js +1 -0
- package/core/built/admin/assets/account-migration-CbUhW6gk.js +1 -0
- package/core/built/admin/assets/activitypub/{account-migration-C-aej4x_.js → account-migration-KA6Jjf9L.js} +16 -16
- package/core/built/admin/assets/activitypub/activitypub.js +9 -9
- 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-BXkA5mqV.js → bluesky-sharing-C7nTDMvw.js} +37 -37
- package/core/built/admin/assets/activitypub/{content-formatters-CHcyMFk4.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-B3ihkPde.js → domain-fZ-X8i4-.js} +121 -121
- package/core/built/admin/assets/activitypub/{edit-profile-DsZM3rTX.js → edit-profile-BqMLQV88.js} +40 -40
- package/core/built/admin/assets/activitypub/{explore-BodNrZgR.js → explore-B4yPoP8E.js} +27 -27
- package/core/built/admin/assets/activitypub/{feed-PwH1iJ84.js → feed-BRC_mvAe.js} +51 -51
- package/core/built/admin/assets/activitypub/{field-D06-kmOJ.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-BW-yvUoN.js +1284 -0
- package/core/built/admin/assets/activitypub/{inbox-d8oJRTf4.js → inbox-CbTTdDQ3.js} +2 -2
- package/core/built/admin/assets/activitypub/label-kPMmYI7l.js +16 -0
- package/core/built/admin/assets/activitypub/layout-BL4_jtuV.js +1 -0
- package/core/built/admin/assets/activitypub/{moderation-D1Yapsod.js → moderation-CuidJzc0.js} +91 -91
- package/core/built/admin/assets/activitypub/{note-C5zjqq5C.js → note-CAMRRSqD.js} +24 -24
- package/core/built/admin/assets/activitypub/{notifications-B9p8eCHD.js → notifications-BmNlXGgp.js} +51 -51
- package/core/built/admin/assets/activitypub/{onboarding-CNelD_uF.js → onboarding-Bqg7fh_L.js} +2 -2
- package/core/built/admin/assets/activitypub/{onboarding-mat5Hrl0.js → onboarding-Dmun9jr_.js} +2 -2
- package/core/built/admin/assets/activitypub/{preferences-BCqUdC3v.js → preferences--oH19wf9.js} +1519 -1519
- package/core/built/admin/assets/activitypub/{profile-BRCWoFem.js → profile-DH_tQx2D.js} +185 -185
- package/core/built/admin/assets/activitypub/{reply-DYK5vVqb.js → reply-Cap9PxSH.js} +2 -2
- package/core/built/admin/assets/activitypub/{routes-BSXT992i.js → routes-DdyY9uFF.js} +744 -735
- package/core/built/admin/assets/activitypub/{separator-BbQqTm-p.js → separator-CAxxu8VV.js} +3 -3
- package/core/built/admin/assets/activitypub/settings-B6EEcVkW.js +315 -0
- package/core/built/admin/assets/activitypub/{site-DHoMupSB.js → site-BYps63oh.js} +2 -2
- package/core/built/admin/assets/activitypub/{step-1-B-YfsVeO.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-D6BFMXL_.js → step-3-C-qBbcUo.js} +11 -11
- package/core/built/admin/assets/activitypub/{tabs-GpNecvfB.js → tabs-DLhZtVde.js} +306 -306
- package/core/built/admin/assets/activitypub/{topic-filter-BPDeQQys.js → topic-filter-DsUOuu0k.js} +3 -3
- package/core/built/admin/assets/activitypub/{use-activity-pub-queries-BoVOxXkV.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-wVBX7swM.js → use-reply-chain-data-AJi9zkzm.js} +30 -30
- package/core/built/admin/assets/activitypub/{users-CoX6FT_K.js → users-inweyKL5.js} +192 -164
- package/core/built/admin/assets/activitypub/{x-DbQZOLiI.js → x-DR8AT3-4.js} +2 -2
- package/core/built/admin/assets/add-integration-modal-BT_onDJy.js +1 -0
- package/core/built/admin/assets/add-newsletter-modal-Cx1kQpiY.js +1 -0
- package/core/built/admin/assets/add-recommendation-modal-B5nvAhvr.js +1 -0
- package/core/built/admin/assets/analytics-DjoJWPI7.js +1 -0
- package/core/built/admin/assets/{announcement-bar-modal-DM3cYOpo.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-BLm2NDBh.js → api-keys-BoeacM-s.js} +1 -1
- package/core/built/admin/assets/{audience-9mwU5TW6.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-vzh-oPXL.js +1 -0
- package/core/built/admin/assets/{breadcrumb-DLiqCyFc.js → breadcrumb-CaLk2b7D.js} +1 -1
- package/core/built/admin/assets/{button-B2jcu6bk.js → button-Dvcv1QSR.js} +1 -1
- package/core/built/admin/assets/calendar-Bl9RLcZX.js +1 -0
- package/core/built/admin/assets/{chart-helpers-Fo3bUL3K.js → chart-helpers-FHywU0pj.js} +1 -1
- package/core/built/admin/assets/{checkbox-BfKktMph.js → checkbox-BtayFtjg.js} +1 -1
- package/core/built/admin/assets/chunk.254.035b85ec456ebbd7336b.js +440 -0
- package/core/built/admin/assets/{chunk.524.60ca4692d91c6022042f.js → chunk.524.e6975095fccdf22d90f8.js} +5 -5
- package/core/built/admin/assets/{chunk.582.525c7617c2d9e94c940a.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-DCQJxsfU.js → code-editor-view-C3ZfoF1X.js} +1 -1
- package/core/built/admin/assets/{code-editor-view-CYVu4EW6.js → code-editor-view-CAyRWy1s.js} +1 -1
- package/core/built/admin/assets/color-picker-G4kGR7rp.js +3 -0
- package/core/built/admin/assets/color-picker-field-DQFVTNnT.js +1 -0
- package/core/built/admin/assets/combobox-BnYzgEB4.js +1 -0
- package/core/built/admin/assets/command-C_vyTikI.js +1 -0
- 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-DwXX_Y5h.js +1 -0
- package/core/built/admin/assets/{content-api-modal-CyQEC3fr.js → content-api-modal-D2G0nJP6.js} +1 -1
- package/core/built/admin/assets/context-menu-DOVB6yaz.js +1 -0
- package/core/built/admin/assets/{copy-field-B3M1s78L.js → copy-field-DCJwh9qf.js} +1 -1
- package/core/built/admin/assets/create-ghost-browse-value-source-5C53jJaX.js +1 -0
- package/core/built/admin/assets/custom-field-type-option-BAuW0F-E.js +1 -0
- package/core/built/admin/assets/custom-integration-modal-AbJGVyKc.js +1 -0
- package/core/built/admin/assets/{date-range-select-DD2RKkgB.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-DVPuGz3U.js +1 -0
- package/core/built/admin/assets/{disabled-sources-indicator-Cvy47bE2.js → disabled-sources-indicator-Cy7Zp4c8.js} +1 -1
- package/core/built/admin/assets/dist-Dcsslyo72.js +1 -0
- package/core/built/admin/assets/domain-Dl61QGuk.js +1 -0
- package/core/built/admin/assets/dropzone-Dtz5Rmjt.js +5 -0
- 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-DeBMLxlL.js → embed-signup-form-modal-DGqsORxS.js} +1 -1
- package/core/built/admin/assets/en-B1jX3WMs.js +1 -0
- package/core/built/admin/assets/explore-nnRr1Fja.js +1 -0
- package/core/built/admin/assets/feature-flag-overrides-context-DQjdJFAk.js +1 -0
- package/core/built/admin/assets/feature-image-placeholder-BrIHmPs8.js +1 -0
- package/core/built/admin/assets/feed-BNUcNu-W.js +1 -0
- package/core/built/admin/assets/feedback-DJ4Zb9rZ.js +1 -0
- package/core/built/admin/assets/{field-Cj8lmDOo.js → field-C93_Mg6j.js} +1 -1
- package/core/built/admin/assets/filter-bar-Da1qxybu.js +1 -0
- package/core/built/admin/assets/filter-sources-CGJb4C5r.js +1 -0
- package/core/built/admin/assets/filters--kKP-EC8.js +1 -0
- package/core/built/admin/assets/filters-DxA_a4FP.js +1 -0
- package/core/built/admin/assets/first-promoter-modal-BYDtrz2S.js +1 -0
- package/core/built/admin/assets/focus-koenig-editor-on-bottom-click-BbSnGOtK.js +1 -0
- package/core/built/admin/assets/{ghost-c8807202a07c20030acb719ee0114815.css → ghost-8fd5bb799356bbefb254210ba7e1236d.css} +1 -1
- package/core/built/admin/assets/{ghost-3894eedcc6968f658578c0abfe942aab.js → ghost-b4e8a403baba61905cd7560e30b9732d.js} +63 -44
- package/core/built/admin/assets/{ghost-dark-fbf1e384aaef3ae315e540f0eb7373a7.css → ghost-dark-cac0cb2d5bb78e9bd14d8d1c2768ed45.css} +1 -1
- package/core/built/admin/assets/gift-link-modal-B7u5bD4e.js +1 -0
- package/core/built/admin/assets/{gift-links-DLDS7ljO.js → gift-links-CfLSnst2.js} +1 -1
- package/core/built/admin/assets/{growth-D6mhcx3q.js → growth-Cd1uO9d2.js} +1 -1
- package/core/built/admin/assets/growth-aG32xfdE.js +3 -0
- package/core/built/admin/assets/history-modal-Df8lW8h-.js +1 -0
- package/core/built/admin/assets/hooks-Cy_-oZ4o.js +2 -0
- package/core/built/admin/assets/{html-field-C8qVGGC1.js → html-field-DA4eU7eq.js} +1 -1
- package/core/built/admin/assets/{images-h8VZEQ9k.js → images-KXmyO3Ss.js} +1 -1
- package/core/built/admin/assets/{inbox-BYd1M06Q.js → inbox-gJHG7_xd.js} +14 -14
- 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-D8sCXRF5.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-B4CuNcx4.js +1 -0
- package/core/built/admin/assets/koenig-lexical/koenig-lexical.js +14 -14
- package/core/built/admin/assets/koenig-lexical/koenig-lexical.umd.js +3 -3
- package/core/built/admin/assets/koenig-lexical/style.css +1 -1
- package/core/built/admin/assets/{koenig-lexical-_-IsVI7E.js → koenig-lexical-CGXb0F8o.js} +3 -3
- package/core/built/admin/assets/koenig-loader-BeM5rFPX.js +2 -0
- package/core/built/admin/assets/{kpi-card-DZQk_0W8.js → kpi-card-B21aToe8.js} +1 -1
- package/core/built/admin/assets/{kpi-card-DW_2y3ug.js → kpi-card-pz6Wv4Ae.js} +1 -1
- package/core/built/admin/assets/{kpi-helpers-PueTKuA6.js → kpi-helpers-Dq5jelmP.js} +1 -1
- package/core/built/admin/assets/{kpi-tabs-CojDs-Qz.js → kpi-tabs-DEZHpKUt.js} +1 -1
- package/core/built/admin/assets/{label-DjbT91GM.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-TRTHCAz9.js +1 -0
- 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-ZWefD9uH.js +1 -0
- package/core/built/admin/assets/{multi-select-combobox-B6LiRzDO.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-CFeLlt4z.js → newsletter-emails-DZH6I-PY.js} +1 -1
- package/core/built/admin/assets/newsletters-DOC9KBcX.js +1 -0
- package/core/built/admin/assets/newsletters-Rq1M3GD-.js +1 -0
- package/core/built/admin/assets/note-DIV-Pojr.js +1 -0
- package/core/built/admin/assets/notifications-s20-H49V.js +1 -0
- package/core/built/admin/assets/nql-BLpCn7qX.js +21 -0
- package/core/built/admin/assets/{offers-9J1CSiLy.js → offers--e2nGvkW.js} +1 -1
- package/core/built/admin/assets/offers-container-modal-BmG5M5Tv.js +1 -0
- package/core/built/admin/assets/onboarding-CUuy9unR.js +1 -0
- package/core/built/admin/assets/{onboarding-B4YhlZ0i.js → onboarding-pXyct0Jm.js} +1 -1
- package/core/built/admin/assets/{onboarding-route-Dmc4IPm3.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-BR_nbIPp.js → page-header-DM_KyoFI.js} +1 -1
- package/core/built/admin/assets/pagemenu-vgZVUVKR.js +1 -0
- 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/papaparse.min-cQwnxGCG.js +10 -0
- package/core/built/admin/assets/{pintura-modal-BR9hEvS8.js → pintura-modal-DExCF1ii.js} +1 -1
- package/core/built/admin/assets/portal-frame-Cqanidq4.js +1 -0
- 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--vNubsqD.js +5 -0
- package/core/built/admin/assets/{preview-modal-C-BL-F9k.js → preview-modal-YYbzlYdO.js} +1 -1
- package/core/built/admin/assets/profile-BllKV3dR.js +1 -0
- package/core/built/admin/assets/{radio-group-Bgz60i81.js → radio-group-DL8GI8rt.js} +1 -1
- 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-v5YbA3Mw.js +1 -0
- package/core/built/admin/assets/settings-PEsZupw1.js +4 -0
- package/core/built/admin/assets/{settings-breadcrumbs-CyP_9zTo.js → settings-breadcrumbs-NwPnCTC7.js} +1 -1
- package/core/built/admin/assets/settings-u_s1CRkr.js +1 -0
- package/core/built/admin/assets/share-modal-SskCmVGL.js +1 -0
- package/core/built/admin/assets/slack-modal-XxSJiYgo.js +1 -0
- package/core/built/admin/assets/{sort-button-Cc-Z96sA.js → sort-button-Cx1KtINE.js} +1 -1
- package/core/built/admin/assets/{source-icon-v6PUnmyM.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-DSRp2vBj.js → step-1-BQYzvBzr.js} +1 -1
- package/core/built/admin/assets/{step-2-COqv2g0u.js → step-2-xES32xJV.js} +1 -1
- package/core/built/admin/assets/{step-3-6W1NMVQc.js → step-3-DA_XK5kW.js} +2 -2
- package/core/built/admin/assets/{stripe-button-D2K42Uty.js → stripe-button-CVsLHelt.js} +1 -1
- package/core/built/admin/assets/stripe-connect-modal-ClmLOMGS.js +1 -0
- package/core/built/admin/assets/style-Wd9nQubI.css +1 -0
- package/core/built/admin/assets/{table-B2pIKjVh.js → table-BenqVupI.js} +1 -1
- package/core/built/admin/assets/{tabs-SaW_UT-Q.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-9Q6fT06V.js +1 -0
- 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-EM9WpESu.js → toggle-group-CviIkyok.js} +1 -1
- package/core/built/admin/assets/{topic-filter-DY4gNHn2.js → topic-filter-I2jCBGxm.js} +1 -1
- package/core/built/admin/assets/{transistor-modal-CpyPG-MH.js → transistor-modal-p53u3W8y.js} +1 -1
- package/core/built/admin/assets/{trend-badge-ByMkuAuH.js → trend-badge-CideVzQd.js} +1 -1
- package/core/built/admin/assets/{unsplash-modal-Cv2Q6GtY.js → unsplash-modal-DY8UcKcE.js} +1 -1
- package/core/built/admin/assets/{use-analytics-data-CHvjMYuT.js → use-analytics-data-DAIGcr2f.js} +1 -1
- package/core/built/admin/assets/use-check-theme-limit-error-B8bjF-gO.css +1 -0
- package/core/built/admin/assets/{use-check-theme-limit-error-Qv4SVXqw.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-937CUj6j.js +1 -0
- package/core/built/admin/assets/use-host-limits-D0Dv3tKA.js +1 -0
- package/core/built/admin/assets/{use-limiter-cwJvsNBo.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-BDBXWUYq.js → use-pintura-editor-CaV1mbfO.js} +1 -1
- package/core/built/admin/assets/{use-post-referrers-DbY-mzci.js → use-post-referrers-BCQI7fDg.js} +1 -1
- package/core/built/admin/assets/use-reply-chain-data-CYRhoaxY.js +1 -0
- package/core/built/admin/assets/{use-router-history-entry-Bg6BhBQQ.js → use-router-history-entry-NOKcd--l.js} +1 -1
- package/core/built/admin/assets/{use-setting-group-VM7FQwMY.js → use-setting-group-bLKMwoBT.js} +1 -1
- package/core/built/admin/assets/use-settings-navigation-B-qrriKD.js +1 -0
- package/core/built/admin/assets/{use-simple-pagination-Dum6Irbs.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-CmdbCS9X.js +1 -0
- package/core/built/admin/assets/use-tinybird-token-KLne235s.js +1 -0
- package/core/built/admin/assets/{use-unsaved-changes-guard-BAy0RANR.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-Df5QzNa7.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-DVNWrqg9.js +1 -0
- package/core/built/admin/assets/{vendor-5753232c7d6ffb3c44e1eb0a02133953.js → vendor-2dd263291938d407802568d3357ec69e.js} +19 -17
- package/core/built/admin/assets/{virtual-list-DEx8WgiO.js → virtual-list-CZ3RK2Yf.js} +1 -1
- package/core/built/admin/assets/web-ClEJsCAj.js +2 -0
- package/core/built/admin/assets/web-X9rdnrtq.js +1 -0
- package/core/built/admin/assets/{zapier-modal-Cw3BTBUu.js → zapier-modal-DfVhV17j.js} +1 -1
- package/core/built/admin/index.html +23 -27
- package/core/frontend/apps/private-blogging/lib/views/private.hbs +44 -43
- package/core/frontend/helpers/cancel_link.js +2 -2
- package/core/frontend/helpers/pagination.js +2 -2
- package/core/frontend/helpers/social_accounts.js +2 -2
- package/core/frontend/public/ghost.css +1 -1
- package/core/frontend/public/ghost.min.css +1 -1
- package/core/frontend/services/sitemap/user-map-generator.js +9 -2
- 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 +10 -2
- package/core/server/api/endpoints/mail.js +1 -1
- package/core/server/api/endpoints/member-metafields-members.js +23 -0
- package/core/server/api/endpoints/member-metafields.js +102 -0
- package/core/server/api/endpoints/members-account.js +42 -0
- package/core/server/api/endpoints/members.js +4 -4
- 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/posts.js +3 -3
- 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 +20 -9
- 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 +6 -2
- package/core/server/api/endpoints/utils/serializers/output/member-metafields.js +18 -0
- 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/members.js +2 -4
- 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/api/endpoints/utils/validators/input/invitations.js +0 -5
- package/core/server/api/endpoints/utils/validators/input/pages.js +1 -1
- package/core/server/api/endpoints/utils/validators/input/posts.js +1 -1
- package/core/server/data/exporter/table-lists.js +3 -3
- package/core/server/data/importer/importers/data/data-importer.js +3 -3
- package/core/server/data/migrations/utils/migrations.js +1 -1
- 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/image/image-size.js +24 -0
- package/core/server/lib/package-json/parse.js +2 -2
- 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 +10 -21
- package/core/server/models/post.js +2 -2
- package/core/server/models/relations/authors.js +2 -16
- package/core/server/models/user.js +10 -3
- package/core/server/services/auth/passwordreset.js +13 -0
- 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/comments/comments-controller.js +30 -9
- package/core/server/services/comments/comments-service.js +55 -5
- package/core/server/services/content-import/csv/formula.js +12 -0
- package/core/server/services/content-import/csv/index.js +6 -1
- package/core/server/services/content-import/csv/parse.js +27 -6
- package/core/server/services/content-import/csv/serialize.js +13 -0
- package/core/server/services/content-import/import/completion-email.js +164 -0
- package/core/server/services/content-import/import/errors-file.js +36 -0
- package/core/server/services/content-import/import/importer.js +160 -53
- package/core/server/services/content-import/import/local-media-url.js +63 -0
- package/core/server/services/content-import/import/media.js +254 -0
- package/core/server/services/content-import/import/post-data.js +0 -1
- package/core/server/services/content-import/import/post-link.js +11 -0
- package/core/server/services/content-import/import/post-repository.js +25 -3
- package/core/server/services/content-import/import/reader.js +9 -2
- package/core/server/services/content-import/import/report.js +34 -0
- package/core/server/services/content-import/import/row.js +0 -2
- package/core/server/services/content-import/import/schema.js +1 -0
- package/core/server/services/content-import/import/staged-file.js +29 -0
- package/core/server/services/content-import/import/store.js +25 -2
- package/core/server/services/content-import/index.js +52 -6
- package/core/server/services/content-import/jobs/content-csv-import-job.js +20 -0
- package/core/server/services/custom-redirects/redirect-config-parser.js +2 -2
- package/core/server/services/custom-redirects/redirects-service.js +1 -1
- package/core/server/services/custom-redirects/validation.js +1 -1
- package/core/server/services/email-address/email-address-parser.js +30 -38
- package/core/server/services/email-address/email-address-service.js +37 -4
- package/core/server/services/email-analytics/index.js +2 -7
- 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 -4
- package/core/server/services/email-service/email-controller.js +18 -2
- package/core/server/services/email-service/email-renderer.js +14 -4
- package/core/server/services/email-service/email-service-wrapper.js +3 -9
- package/core/server/services/email-service/mailgun-email-provider.js +20 -9
- 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/email-templates/gift-delivery.hbs +3 -3
- package/core/server/services/gifts/gift-email-service.js +0 -1
- package/core/server/services/gifts/gift-service.js +19 -57
- package/core/server/services/gifts/index.js +3 -5
- package/core/server/services/gifts/jobs/index.js +4 -4
- package/core/server/services/indexnow-ping/indexnow-ping-service.js +2 -2
- package/core/server/services/invitations/accept.js +4 -2
- package/core/server/services/jobs/job-service.js +0 -9
- 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 +32 -11
- package/core/server/services/mail/ghost-mailer.js +4 -4
- package/core/server/services/member-welcome-emails/service.js +7 -7
- package/core/server/services/members/account-service.js +98 -0
- package/core/server/services/members/api.js +4 -3
- package/core/server/services/members/import-export/csv/parse.js +0 -7
- package/core/server/services/members/import-export/export/exporter.js +20 -20
- package/core/server/services/members/import-export/import/completion-email.js +8 -11
- package/core/server/services/members/import-export/import/importer.js +13 -13
- package/core/server/services/members/import-export/import/row.js +0 -3
- package/core/server/services/members/import-export/index.js +10 -17
- package/core/server/services/members/jobs/clean-expired-comped-job.js +7 -0
- package/core/server/services/members/jobs/clean-expired-comped-task.js +145 -0
- package/core/server/services/members/jobs/index.js +48 -24
- package/core/server/services/members/members-api/controllers/member-controller.js +11 -0
- package/core/server/services/members/members-api/controllers/router-controller.js +3 -6
- package/core/server/services/members/members-api/members-api.js +26 -8
- package/core/server/services/members/members-api/repositories/event-repository.js +0 -4
- 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 +62 -84
- package/core/server/services/members/members-api/services/payments-service.js +1 -1
- 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 +71 -47
- 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-metafields/codec.js +14 -0
- 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 +68 -22
- package/core/server/services/members-metafields/filter.js +181 -0
- package/core/server/services/{members-custom-fields → members-metafields}/index.js +16 -7
- package/core/server/services/{members-custom-fields → members-metafields}/key.js +2 -1
- package/core/server/services/{members-custom-fields → members-metafields}/models.js +5 -5
- 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-metafields/serializers.js +22 -0
- package/core/server/services/{members-custom-fields → members-metafields}/values-service.js +80 -48
- package/core/server/services/mentions/mention-controller.js +23 -21
- package/core/server/services/mentions/mention-sending-service.js +26 -9
- package/core/server/services/mentions/process-webmention-job.js +16 -0
- package/core/server/services/mentions/send-webmentions-job.js +18 -0
- package/core/server/services/mentions/service.js +7 -33
- package/core/server/services/route-settings/validation-errors.js +1 -1
- package/core/server/services/route-settings/yaml-parser.js +1 -1
- package/core/server/services/settings/settings-service.js +1 -8
- package/core/server/services/settings-helpers/settings-helpers.js +4 -6
- package/core/server/services/slack-ping/slack-ping-service.js +1 -1
- package/core/server/services/staff/staff-service-emails.js +2 -2
- package/core/server/services/stripe/config.js +14 -8
- package/core/server/services/stripe/service.js +10 -1
- package/core/server/services/stripe/services/checkout/completed-session.js +2 -2
- package/core/server/services/stripe/services/checkout/session-options.js +18 -15
- package/core/server/services/stripe/services/webhook/checkout-session-event-service.js +28 -7
- package/core/server/services/stripe/stripe-api.js +2 -0
- package/core/server/services/stripe/stripe-service.js +24 -14
- package/core/server/services/stripe/webhook-controller.js +10 -0
- package/core/server/services/tier-checkout-config/codec.js +11 -7
- package/core/server/services/tier-checkout-config/index.js +2 -1
- package/core/server/services/tier-checkout-config/models.js +11 -5
- package/core/server/services/tier-checkout-config/queries.js +12 -12
- package/core/server/services/tier-checkout-config/serializers.js +73 -10
- package/core/server/services/tier-checkout-config/service.js +14 -13
- package/core/server/services/tiers/service.js +3 -3
- package/core/server/services/update-check/index.js +13 -13
- package/core/server/services/update-check/jobs/update-check-job.js +7 -0
- package/core/server/services/update-check/update-check-service.js +2 -2
- package/core/server/services/url/router-filter.js +8 -10
- package/core/server/services/users.js +1 -19
- package/core/server/web/admin/controller.js +1 -1
- package/core/server/web/api/endpoints/admin/routes.js +20 -16
- 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/config/env/config.testing-mysql.json +1 -1
- package/core/shared/labs.js +7 -2
- package/package.json +42 -41
- package/pnpm-lock.yaml +1159 -582
- package/pnpm-workspace.yaml +18 -15
- package/components/tryghost-custom-field-types-0.0.0.tgz +0 -0
- package/components/tryghost-kg-default-nodes-2.2.0.tgz +0 -0
- package/core/built/admin/assets/Combination-5fYEzgbs.js +0 -41
- package/core/built/admin/assets/account-migration-DRhAehfw.js +0 -1
- package/core/built/admin/assets/activitypub/inbox-BluD2ucT.js +0 -1284
- package/core/built/admin/assets/activitypub/label-FHSh6ZAw.js +0 -16
- package/core/built/admin/assets/activitypub/layout-Cq4NG0Xr.js +0 -1
- package/core/built/admin/assets/activitypub/settings-DQDkr06X.js +0 -315
- package/core/built/admin/assets/add-integration-modal-BC0jExDZ.js +0 -1
- package/core/built/admin/assets/add-newsletter-modal-DchTkA7l.js +0 -1
- package/core/built/admin/assets/add-recommendation-modal-DMvaJZKp.js +0 -1
- package/core/built/admin/assets/alert-dialog-QhXzdHfc.js +0 -1
- package/core/built/admin/assets/analytics-No1DDY3A.js +0 -1
- package/core/built/admin/assets/automated-emails-te1D5kq-.js +0 -1
- package/core/built/admin/assets/automations-DpUNUdcZ.js +0 -1
- package/core/built/admin/assets/bluesky-sharing-Cjrv_f62.js +0 -1
- package/core/built/admin/assets/chunk.896.435fe0637944d4a69810.js +0 -366
- package/core/built/admin/assets/color-picker-BTY_NdEm.js +0 -3
- package/core/built/admin/assets/color-picker-field-CPlkzOH0.js +0 -1
- package/core/built/admin/assets/combobox-DrMtv_4P.js +0 -1
- package/core/built/admin/assets/command-ZdgYJpoI.js +0 -1
- package/core/built/admin/assets/comments-kidj60-h.js +0 -1
- package/core/built/admin/assets/confirmation-context-BhbmQQEl.js +0 -1
- package/core/built/admin/assets/custom-field-type-option-CsGIZk1J.js +0 -10
- package/core/built/admin/assets/custom-integration-modal-BY37O_9X.js +0 -1
- package/core/built/admin/assets/design-and-theme-modal-DUSKM4uC.js +0 -22
- package/core/built/admin/assets/dialog-B44iRwlc.js +0 -1
- package/core/built/admin/assets/dirty-confirm-dialog-BxgQgQ6H.js +0 -1
- package/core/built/admin/assets/dist-Cy8tfrp_.js +0 -1
- package/core/built/admin/assets/domain-Ca6KhoQt.js +0 -1
- package/core/built/admin/assets/dropzone-Bb-5zQTk.js +0 -5
- package/core/built/admin/assets/edit-profile-BdupLlus.js +0 -1
- package/core/built/admin/assets/editor-BP883Lpn.js +0 -8
- package/core/built/admin/assets/explore-FB-CimXw.js +0 -1
- package/core/built/admin/assets/feed-C1GxsmI2.js +0 -1
- package/core/built/admin/assets/filter-sources-D5n5bFA2.js +0 -1
- package/core/built/admin/assets/filters-DJEzkMUK.js +0 -1
- package/core/built/admin/assets/filters-MZXvdH5D.js +0 -1
- package/core/built/admin/assets/first-promoter-modal-CGTGLCr5.js +0 -1
- package/core/built/admin/assets/gift-link-modal-B6v0tnRN.js +0 -1
- package/core/built/admin/assets/growth-BGAJD1rs.js +0 -3
- package/core/built/admin/assets/history-modal-iKwUY3XR.js +0 -1
- package/core/built/admin/assets/hooks-CuEZV2-q.js +0 -2
- package/core/built/admin/assets/index-DjQe-e5s.js +0 -4
- package/core/built/admin/assets/index-Dqf2x-ry.css +0 -1
- package/core/built/admin/assets/index.es-VihPwfeH.js +0 -1
- package/core/built/admin/assets/input--W-rCTrX.js +0 -1
- package/core/built/admin/assets/invite-user-modal-MdImLCaJ.js +0 -1
- package/core/built/admin/assets/koenig-loader-DYZpm6El.js +0 -2
- package/core/built/admin/assets/label-picker-cB51xl1r.js +0 -1
- package/core/built/admin/assets/layout-c_B_1hax.js +0 -1
- package/core/built/admin/assets/link-helpers-MVDdnFCY.js +0 -1
- package/core/built/admin/assets/loading-indicator-BpFWTVgh.js +0 -1
- package/core/built/admin/assets/member-custom-fields-qs0dIkxM.js +0 -1
- package/core/built/admin/assets/member-detail-B6uec2a6.js +0 -1
- package/core/built/admin/assets/members-BQF3CqhI.js +0 -2
- package/core/built/admin/assets/moderation-DY4wF1Q3.js +0 -1
- package/core/built/admin/assets/navigation-modal-DX-gNF3X.js +0 -1
- package/core/built/admin/assets/newsletter-CyQA7m3m.js +0 -1
- package/core/built/admin/assets/newsletter-detail-modal-BDrptuxn.js +0 -1
- package/core/built/admin/assets/newsletters-DXuNmC42.js +0 -1
- package/core/built/admin/assets/newsletters-DhNigJUh.js +0 -1
- package/core/built/admin/assets/note-Cgo2LCJ6.js +0 -1
- package/core/built/admin/assets/notifications-BC50AMku.js +0 -1
- package/core/built/admin/assets/offers-container-modal-DWycIMzT.js +0 -1
- package/core/built/admin/assets/onboarding-DGQuV7Ew.js +0 -1
- package/core/built/admin/assets/overview-CVbFtn-k.js +0 -1
- package/core/built/admin/assets/overview-YKj7SZaK.js +0 -1
- package/core/built/admin/assets/pages-B6vr9F_D.js +0 -1
- package/core/built/admin/assets/popover-CCy0h5rq.js +0 -1
- package/core/built/admin/assets/portal-frame-dc4XKr0e.js +0 -1
- package/core/built/admin/assets/portal-modal-BvvdF_B9.js +0 -1
- package/core/built/admin/assets/post-analytics-DX470WRG.js +0 -1
- package/core/built/admin/assets/post-analytics-header-CXpJmdDv.js +0 -1
- package/core/built/admin/assets/post-analytics-provider-CLfKGWZy.js +0 -1
- package/core/built/admin/assets/post-helpers-C5OQMBoi.js +0 -1
- package/core/built/admin/assets/post-share-modal-Cl0NXRJr.js +0 -1
- package/core/built/admin/assets/posts-KY3aUhVV.js +0 -1
- package/core/built/admin/assets/preferences-DO0UUWFp.js +0 -5
- package/core/built/admin/assets/profile-CxT-0l4d.js +0 -1
- package/core/built/admin/assets/router-provider-B0gZyiGJ.js +0 -1
- package/core/built/admin/assets/schemas-4UPic-oD.js +0 -64
- package/core/built/admin/assets/select-DuDUFdPq.js +0 -1
- package/core/built/admin/assets/settings-BjCii7BM.js +0 -1
- package/core/built/admin/assets/settings-b8kNzZSQ.js +0 -4
- package/core/built/admin/assets/share-modal-BV70mr9k.js +0 -1
- package/core/built/admin/assets/shim-ClF_m5ux.js +0 -1
- package/core/built/admin/assets/slack-modal-Be2_KK-z.js +0 -1
- package/core/built/admin/assets/stats-C4reGh9O.js +0 -1
- package/core/built/admin/assets/stats-view-DP9pQ62k.js +0 -1
- package/core/built/admin/assets/stripe-connect-modal-Z-UT_BGc.js +0 -1
- package/core/built/admin/assets/tag-detail-Dc0nTOtU.js +0 -2
- package/core/built/admin/assets/tags-BLaXBwnb.js +0 -1
- package/core/built/admin/assets/testimonials-modal-sFwRnNLh.js +0 -1
- package/core/built/admin/assets/tier-detail-modal-BCFpWwUS.js +0 -1
- package/core/built/admin/assets/tiers-Nd_z4BZY.js +0 -1
- package/core/built/admin/assets/use-filter-params-CAvfDvf1.js +0 -1
- package/core/built/admin/assets/use-growth-stats-D6mZXGhK.js +0 -1
- package/core/built/admin/assets/use-host-limits-DZtR08oa.js +0 -1
- package/core/built/admin/assets/use-pintura-config-CzTfnufz.js +0 -1
- package/core/built/admin/assets/use-reply-chain-data-BeQwz8oF.js +0 -1
- package/core/built/admin/assets/use-settings-navigation-BbrSUVcf.js +0 -1
- package/core/built/admin/assets/use-staff-users-cZg4ugOF.js +0 -1
- package/core/built/admin/assets/use-tinybird-query-B1IMyAcv.js +0 -39
- package/core/built/admin/assets/use-tinybird-token-Bow0Zwn8.js +0 -1
- package/core/built/admin/assets/use-upgrade-route-DhRSo7at.js +0 -1
- package/core/built/admin/assets/user-detail-modal-yipSoQfv.js +0 -1
- package/core/built/admin/assets/users-5msE1WMs.js +0 -1
- package/core/built/admin/assets/web-CKcXAu86.js +0 -1
- package/core/built/admin/assets/web-DR4TqM3E.js +0 -2
- package/core/server/api/endpoints/member-custom-fields.js +0 -90
- package/core/server/api/endpoints/utils/serializers/output/member-custom-fields.js +0 -20
- package/core/server/services/email-suppression-list/in-memory-email-suppression-list.js +0 -39
- package/core/server/services/jobs/worker-model-event-bridge.js +0 -149
- package/core/server/services/members/jobs/clean-expired-comped.js +0 -132
- package/core/server/services/members-custom-fields/bindings-service.js +0 -119
- package/core/server/services/members-custom-fields/codec.js +0 -15
- package/core/server/services/members-custom-fields/filter.js +0 -199
- package/core/server/services/members-custom-fields/serializers.js +0 -24
- package/core/server/services/stripe/services/checkout/allowed-countries.js +0 -267
- package/core/server/services/stripe/services/checkout/field-ports.js +0 -34
- package/core/server/services/tier-checkout-config/destinations.js +0 -17
- package/core/server/services/update-check/run-update-check.js +0 -63
- /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,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.toCheckoutConfigResponse = exports.CheckoutConfigInput = void 0;
|
|
4
|
+
exports.requirementsByTier = requirementsByTier;
|
|
4
5
|
const zod_1 = require("zod");
|
|
5
|
-
const
|
|
6
|
-
const allowed_countries_1 = require("../stripe/services/checkout/allowed-countries");
|
|
6
|
+
const checkout_1 = require("@tryghost/checkout");
|
|
7
7
|
const models_1 = require("./models");
|
|
8
8
|
// Every country Stripe will take, sent at once, was measured as accepted — so the only
|
|
9
9
|
// ceiling is the list itself, and a request naming more than there are countries is naming
|
|
10
|
-
// something twice.
|
|
11
|
-
const MAX_ALLOWED_COUNTRIES =
|
|
10
|
+
// something twice. A request that means all of them omits the list instead.
|
|
11
|
+
const MAX_ALLOWED_COUNTRIES = checkout_1.STRIPE_ALLOWED_COUNTRIES.length;
|
|
12
12
|
const QuestionInput = zod_1.z.object({
|
|
13
13
|
key: zod_1.z.string().min(1, { error: 'Every checkout question needs a custom field key.' }),
|
|
14
14
|
label: zod_1.z.string().trim().min(1).nullish(),
|
|
@@ -21,7 +21,7 @@ const CountryCode = zod_1.z
|
|
|
21
21
|
.trim()
|
|
22
22
|
.regex(/^[A-Za-z]{2}$/, { error: 'Enter a 2-letter country code, like US.' })
|
|
23
23
|
.toUpperCase()
|
|
24
|
-
.refine(
|
|
24
|
+
.refine(checkout_1.isStripeAllowedCountry, {
|
|
25
25
|
error: 'Stripe will not ship to that country, so a checkout cannot offer it.',
|
|
26
26
|
});
|
|
27
27
|
/**
|
|
@@ -37,8 +37,8 @@ const Destination = zod_1.z.strictObject({ custom_field_key: CustomFieldKey }, {
|
|
|
37
37
|
exports.CheckoutConfigInput = zod_1.z.strictObject({
|
|
38
38
|
custom_fields: zod_1.z
|
|
39
39
|
.array(QuestionInput)
|
|
40
|
-
.max(
|
|
41
|
-
error: `A checkout can ask at most ${
|
|
40
|
+
.max(checkout_1.MAX_CHECKOUT_CUSTOM_FIELDS, {
|
|
41
|
+
error: `A checkout can ask at most ${checkout_1.MAX_CHECKOUT_CUSTOM_FIELDS} questions.`,
|
|
42
42
|
})
|
|
43
43
|
.refine((questions) => new Set(questions.map((question) => question.key)).size === questions.length, { error: 'This checkout already asks for that field.' })
|
|
44
44
|
.optional(),
|
|
@@ -47,10 +47,14 @@ exports.CheckoutConfigInput = zod_1.z.strictObject({
|
|
|
47
47
|
zod_1.z.strictObject({ collect: zod_1.z.literal(false) }),
|
|
48
48
|
zod_1.z.strictObject({
|
|
49
49
|
collect: zod_1.z.literal(true),
|
|
50
|
+
// Absent means everywhere the processor ships. Empty is refused rather than
|
|
51
|
+
// read as everywhere: a publisher who cleared the list said something, and it
|
|
52
|
+
// was not "deliver worldwide".
|
|
50
53
|
allowed_countries: zod_1.z
|
|
51
54
|
.array(CountryCode, { error: 'Choose at least one country you deliver to.' })
|
|
52
55
|
.min(1, { error: 'Choose at least one country you deliver to.' })
|
|
53
|
-
.max(MAX_ALLOWED_COUNTRIES)
|
|
56
|
+
.max(MAX_ALLOWED_COUNTRIES)
|
|
57
|
+
.optional(),
|
|
54
58
|
name: Destination,
|
|
55
59
|
address: Destination,
|
|
56
60
|
}),
|
|
@@ -75,7 +79,8 @@ const CollectionResource = zod_1.z.object({
|
|
|
75
79
|
});
|
|
76
80
|
const ShippingResource = zod_1.z.object({
|
|
77
81
|
collect: zod_1.z.literal(true),
|
|
78
|
-
|
|
82
|
+
/** Absent means everywhere, the same way it does on the way in. */
|
|
83
|
+
allowed_countries: zod_1.z.array(zod_1.z.string()).optional(),
|
|
79
84
|
name: zod_1.z.object({ custom_field_key: zod_1.z.string() }),
|
|
80
85
|
address: zod_1.z.object({ custom_field_key: zod_1.z.string() }),
|
|
81
86
|
});
|
|
@@ -102,7 +107,9 @@ exports.toCheckoutConfigResponse = zod_1.z
|
|
|
102
107
|
? {
|
|
103
108
|
shipping: {
|
|
104
109
|
collect: true,
|
|
105
|
-
|
|
110
|
+
...(config.shipping.allowedCountries
|
|
111
|
+
? { allowed_countries: config.shipping.allowedCountries }
|
|
112
|
+
: {}),
|
|
106
113
|
name: { custom_field_key: config.shipping.nameCustomFieldKey },
|
|
107
114
|
address: { custom_field_key: config.shipping.addressCustomFieldKey },
|
|
108
115
|
},
|
|
@@ -120,3 +127,59 @@ exports.toCheckoutConfigResponse = zod_1.z
|
|
|
120
127
|
})),
|
|
121
128
|
}))
|
|
122
129
|
.pipe(CheckoutConfigResponse);
|
|
130
|
+
/**
|
|
131
|
+
* What a tier asks a member for, as the tier payload carries it.
|
|
132
|
+
*
|
|
133
|
+
* The same rows as the publisher's resource above, minus everything about where a value
|
|
134
|
+
* lands. A member supplies a delivery address rather than a value for a named field, and
|
|
135
|
+
* which field holds it is the publisher's business; naming it here would invite a client
|
|
136
|
+
* to write there directly. The tax number goes too, because the processor keeps one
|
|
137
|
+
* against the customer it invoices and Ghost never stores it. So do the checkout
|
|
138
|
+
* questions, which a tier change does not draw.
|
|
139
|
+
*
|
|
140
|
+
* Not named for the collection, deliberately: a collection in this domain is a collected
|
|
141
|
+
* thing together with the field it lands in, and that second half is exactly the part
|
|
142
|
+
* this drops.
|
|
143
|
+
*/
|
|
144
|
+
const TierRequirements = zod_1.z.object({
|
|
145
|
+
/**
|
|
146
|
+
* A block appears only when the tier asks for that thing, and says so as well, the same
|
|
147
|
+
* way the publisher's resource does. Presence and the flag agree, so a client may read
|
|
148
|
+
* whichever it finds clearer.
|
|
149
|
+
*
|
|
150
|
+
* Neither says whether a thing may be skipped, because nothing here may be: everything
|
|
151
|
+
* a tier requires is required. Collection a member could decline is the change that
|
|
152
|
+
* would need a field of its own rather than a new reading of these two.
|
|
153
|
+
*/
|
|
154
|
+
shipping: zod_1.z
|
|
155
|
+
.object({
|
|
156
|
+
collect: zod_1.z.literal(true),
|
|
157
|
+
/** Absent means everywhere the processor ships, the same as for a publisher. */
|
|
158
|
+
allowed_countries: zod_1.z.array(zod_1.z.string()).optional(),
|
|
159
|
+
})
|
|
160
|
+
.optional(),
|
|
161
|
+
phone: zod_1.z.object({ collect: zod_1.z.literal(true) }).optional(),
|
|
162
|
+
});
|
|
163
|
+
/**
|
|
164
|
+
* Keyed by tier, because the payload this joins onto is a list of tiers and a lookup is
|
|
165
|
+
* the only thing it needs. Tiers a publisher has never set up are absent, and a tier that
|
|
166
|
+
* collects only a tax number resolves to nothing asked.
|
|
167
|
+
*/
|
|
168
|
+
function requirementsByTier(configs) {
|
|
169
|
+
return new Map(configs.map((config) => [
|
|
170
|
+
config.tierId,
|
|
171
|
+
TierRequirements.parse({
|
|
172
|
+
...(config.shipping
|
|
173
|
+
? {
|
|
174
|
+
shipping: {
|
|
175
|
+
collect: true,
|
|
176
|
+
...(config.shipping.allowedCountries
|
|
177
|
+
? { allowed_countries: config.shipping.allowedCountries }
|
|
178
|
+
: {}),
|
|
179
|
+
},
|
|
180
|
+
}
|
|
181
|
+
: {}),
|
|
182
|
+
...(config.phone ? { phone: { collect: true } } : {}),
|
|
183
|
+
}),
|
|
184
|
+
]));
|
|
185
|
+
}
|
|
@@ -7,12 +7,11 @@ exports.TierCheckoutConfigService = void 0;
|
|
|
7
7
|
const bson_objectid_1 = __importDefault(require("bson-objectid"));
|
|
8
8
|
const errors_1 = __importDefault(require("@tryghost/errors"));
|
|
9
9
|
const zod_1 = require("zod");
|
|
10
|
-
const schema_1 = require("../members-
|
|
11
|
-
const
|
|
10
|
+
const schema_1 = require("../members-metafields/schema");
|
|
11
|
+
const checkout_1 = require("@tryghost/checkout");
|
|
12
12
|
const codec_1 = require("./codec");
|
|
13
13
|
const queries_1 = require("./queries");
|
|
14
14
|
const models_1 = require("./models");
|
|
15
|
-
const destinations_1 = require("./destinations");
|
|
16
15
|
const serializers_1 = require("./serializers");
|
|
17
16
|
/**
|
|
18
17
|
* A request states its settings in named sections: one for shipping, one for phone. Each
|
|
@@ -26,8 +25,8 @@ const serializers_1 = require("./serializers");
|
|
|
26
25
|
* save that the publisher believes they have turned off.
|
|
27
26
|
*/
|
|
28
27
|
const BLOCK_PORTS = {
|
|
29
|
-
shipping: [
|
|
30
|
-
phone: [
|
|
28
|
+
shipping: [checkout_1.STRIPE_PORT.shippingName, checkout_1.STRIPE_PORT.shippingAddress],
|
|
29
|
+
phone: [checkout_1.STRIPE_PORT.phone],
|
|
31
30
|
};
|
|
32
31
|
class TierCheckoutConfigService {
|
|
33
32
|
knex;
|
|
@@ -115,10 +114,10 @@ class TierCheckoutConfigService {
|
|
|
115
114
|
async planCollection(stated) {
|
|
116
115
|
const wanted = [];
|
|
117
116
|
if (stated.shipping?.collect) {
|
|
118
|
-
wanted.push({ port:
|
|
117
|
+
wanted.push({ port: checkout_1.STRIPE_PORT.shippingName, key: stated.shipping.name.custom_field_key }, { port: checkout_1.STRIPE_PORT.shippingAddress, key: stated.shipping.address.custom_field_key });
|
|
119
118
|
}
|
|
120
119
|
if (stated.phone?.collect) {
|
|
121
|
-
wanted.push({ port:
|
|
120
|
+
wanted.push({ port: checkout_1.STRIPE_PORT.phone, key: stated.phone.custom_field_key });
|
|
122
121
|
}
|
|
123
122
|
const bound = new Set(wanted.map(({ port }) => port));
|
|
124
123
|
const clear = [];
|
|
@@ -129,7 +128,7 @@ class TierCheckoutConfigService {
|
|
|
129
128
|
}
|
|
130
129
|
const create = new Map();
|
|
131
130
|
for (const { port, key } of wanted) {
|
|
132
|
-
const wants =
|
|
131
|
+
const wants = checkout_1.PORT_FIELD[port];
|
|
133
132
|
const existing = await this.fields.findByKey(key);
|
|
134
133
|
if (existing) {
|
|
135
134
|
assertCollectableInto(port, existing, wants.type);
|
|
@@ -240,7 +239,9 @@ function assertCollectableInto(port, field, valueType) {
|
|
|
240
239
|
}
|
|
241
240
|
async function writeOptions(trx, productId, stated, now) {
|
|
242
241
|
const all = zod_1.z.encode(codec_1.optionsCodec, {
|
|
243
|
-
shippingAllowedCountries: stated.shipping?.collect
|
|
242
|
+
shippingAllowedCountries: stated.shipping?.collect
|
|
243
|
+
? (stated.shipping.allowed_countries ?? null)
|
|
244
|
+
: null,
|
|
244
245
|
taxNumber: stated.tax_number?.collect ?? false,
|
|
245
246
|
});
|
|
246
247
|
// Only the columns this request spoke about are written, so two requests changing
|
|
@@ -262,7 +263,7 @@ async function writeOptions(trx, productId, stated, now) {
|
|
|
262
263
|
.merge({ ...columns, updated_at: now });
|
|
263
264
|
}
|
|
264
265
|
async function assertQuestionsAskable(db, questions) {
|
|
265
|
-
const collides = questions.find((question) => (0,
|
|
266
|
+
const collides = questions.find((question) => (0, checkout_1.isStripePort)(question.key));
|
|
266
267
|
if (collides) {
|
|
267
268
|
throw new errors_1.default.ValidationError({
|
|
268
269
|
message: `A field keyed ${collides.key} cannot be asked at checkout, because that is what this checkout calls something it collects for itself.`,
|
|
@@ -286,16 +287,16 @@ async function assertQuestionsAskable(db, questions) {
|
|
|
286
287
|
property: 'checkout.custom_fields',
|
|
287
288
|
});
|
|
288
289
|
}
|
|
289
|
-
if (!(0,
|
|
290
|
+
if (!(0, checkout_1.isCheckoutEligible)(field.type)) {
|
|
290
291
|
throw new errors_1.default.ValidationError({
|
|
291
292
|
message: `A ${field.type} field cannot be asked for at checkout.`,
|
|
292
293
|
property: 'checkout.custom_fields',
|
|
293
294
|
});
|
|
294
295
|
}
|
|
295
296
|
const prompt = question.label ?? field.name;
|
|
296
|
-
if (prompt.length >
|
|
297
|
+
if (prompt.length > checkout_1.MAX_CHECKOUT_LABEL_LENGTH) {
|
|
297
298
|
throw new errors_1.default.ValidationError({
|
|
298
|
-
message: `A checkout question can be at most ${
|
|
299
|
+
message: `A checkout question can be at most ${checkout_1.MAX_CHECKOUT_LABEL_LENGTH} characters. Give this one a shorter label.`,
|
|
299
300
|
property: 'checkout.custom_fields',
|
|
300
301
|
});
|
|
301
302
|
}
|
|
@@ -32,14 +32,14 @@ class TiersServiceWrapper {
|
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
// What a tier's checkout asks, kept beside the tier rather than inside it: these
|
|
35
|
-
// rows are read live on every request, because deleting a
|
|
35
|
+
// rows are read live on every request, because deleting a metafield cascades a
|
|
36
36
|
// question away without the repository above ever seeing it, and a cached copy
|
|
37
37
|
// would go on naming a field the site no longer has.
|
|
38
38
|
//
|
|
39
|
-
// Boot builds the
|
|
39
|
+
// Boot builds the metafields services before this one, so both collaborators
|
|
40
40
|
// are ready by the time this runs.
|
|
41
41
|
const { TierCheckoutConfigService } = require('../tier-checkout-config');
|
|
42
|
-
const { bindings, definitions } = require('../members-
|
|
42
|
+
const { bindings, definitions } = require('../members-metafields');
|
|
43
43
|
this.checkout = new TierCheckoutConfigService({
|
|
44
44
|
knex: models.Base.knex,
|
|
45
45
|
// A binding is where a collected value lands, and the same rows are what a completed
|
|
@@ -2,7 +2,7 @@ const api = require('../../api').endpoints;
|
|
|
2
2
|
const config = require('../../../shared/config');
|
|
3
3
|
const logging = require('@tryghost/logging');
|
|
4
4
|
const urlUtils = require('../../../shared/url-utils').default;
|
|
5
|
-
const
|
|
5
|
+
const UpdateCheckJob = require('./jobs/update-check-job').default;
|
|
6
6
|
|
|
7
7
|
const request = require('@tryghost/request');
|
|
8
8
|
const ghostVersion = require('@tryghost/version');
|
|
@@ -66,7 +66,7 @@ module.exports = async ({
|
|
|
66
66
|
await updateChecker.check();
|
|
67
67
|
};
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
const scheduleRecurringJob = async (jobsService) => {
|
|
70
70
|
// use a random seconds/minutes/hours value to avoid spikes to the update service API
|
|
71
71
|
const s = Math.floor(Math.random() * 60); // 0-59
|
|
72
72
|
const m = Math.floor(Math.random() * 60); // 0-59
|
|
@@ -74,17 +74,17 @@ module.exports.scheduleRecurringJobs = () => {
|
|
|
74
74
|
|
|
75
75
|
const at = `${s} ${m} ${h} * * *`;
|
|
76
76
|
logging.info(`[Background Job] update-check scheduled at ${at}`);
|
|
77
|
-
jobsService.
|
|
78
|
-
at, // Every day
|
|
79
|
-
job: require('path').resolve(__dirname, 'run-update-check.js'),
|
|
80
|
-
name: 'update-check',
|
|
81
|
-
});
|
|
77
|
+
await jobsService.scheduleRecurring(new UpdateCheckJob(), { cron: at });
|
|
82
78
|
};
|
|
83
79
|
|
|
84
|
-
|
|
85
|
-
logging.info('[Background Job] update-check
|
|
86
|
-
jobsService.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
80
|
+
const scheduleBootJob = async (jobsService) => {
|
|
81
|
+
logging.info('[Background Job] update-check boot run queued');
|
|
82
|
+
await jobsService.dispatch(new UpdateCheckJob());
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
module.exports.scheduleJobs = async (jobsService) => {
|
|
86
|
+
await scheduleRecurringJob(jobsService);
|
|
87
|
+
if (config.get('updateCheck:forceUpdate')) {
|
|
88
|
+
await scheduleBootJob(jobsService);
|
|
89
|
+
}
|
|
90
90
|
};
|
|
@@ -99,7 +99,7 @@ class UpdateCheckService {
|
|
|
99
99
|
);
|
|
100
100
|
|
|
101
101
|
err.context = tpl(messages.checkingForUpdatesFailedError);
|
|
102
|
-
err.help = tpl(messages.checkingForUpdatesFailedHelp, { url: 'https://ghost.org/
|
|
102
|
+
err.help = tpl(messages.checkingForUpdatesFailedHelp, { url: 'https://docs.ghost.org/' });
|
|
103
103
|
|
|
104
104
|
this.logging.error(
|
|
105
105
|
{
|
|
@@ -120,7 +120,7 @@ class UpdateCheckService {
|
|
|
120
120
|
* Only the Ghost version is sent so the service can return the relevant
|
|
121
121
|
* release and security notifications. No site data is collected.
|
|
122
122
|
*
|
|
123
|
-
* @see https://ghost.org/
|
|
123
|
+
* @see https://docs.ghost.org/concepts/config/#privacy
|
|
124
124
|
* @returns {Promise}
|
|
125
125
|
*/
|
|
126
126
|
async updateCheckRequest() {
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.EXPANSIONS = void 0;
|
|
4
7
|
exports.routerTypeOf = routerTypeOf;
|
|
5
8
|
exports.buildFilter = buildFilter;
|
|
6
9
|
exports.filterMatches = filterMatches;
|
|
7
|
-
const
|
|
8
|
-
const
|
|
10
|
+
const nql_1 = __importDefault(require("@tryghost/nql"));
|
|
11
|
+
const logging_1 = __importDefault(require("@tryghost/logging"));
|
|
9
12
|
// NQL evaluation for routes.yaml collection filters, kept in one place so the
|
|
10
13
|
// forward lookup, ownership check and reverse lookup all decide membership the
|
|
11
14
|
// same way.
|
|
@@ -17,7 +20,7 @@ exports.EXPANSIONS = [
|
|
|
17
20
|
{ key: 'primary_tag', replacement: 'primary_tag.slug' },
|
|
18
21
|
{ key: 'primary_author', replacement: 'primary_author.slug' },
|
|
19
22
|
];
|
|
20
|
-
const PAGE_TRANSFORMER =
|
|
23
|
+
const PAGE_TRANSFORMER = nql_1.default.utils.mapKeyValues({
|
|
21
24
|
key: { from: 'page', to: 'type' },
|
|
22
25
|
values: [
|
|
23
26
|
{ from: false, to: 'post' },
|
|
@@ -45,7 +48,7 @@ function buildFilter(filter) {
|
|
|
45
48
|
if (!filter) {
|
|
46
49
|
return null;
|
|
47
50
|
}
|
|
48
|
-
return
|
|
51
|
+
return (0, nql_1.default)(filter, { expansions: exports.EXPANSIONS, transformer: PAGE_TRANSFORMER });
|
|
49
52
|
}
|
|
50
53
|
// A null filter always matches; anything that throws is a non-match, not an
|
|
51
54
|
// error.
|
|
@@ -65,12 +68,7 @@ function filterMatches(compiledFilter, record) {
|
|
|
65
68
|
}
|
|
66
69
|
catch (err) {
|
|
67
70
|
const message = err instanceof Error ? err.message : String(err);
|
|
68
|
-
|
|
71
|
+
logging_1.default.warn('NQL match failed', message);
|
|
69
72
|
return false;
|
|
70
73
|
}
|
|
71
74
|
}
|
|
72
|
-
module.exports = { EXPANSIONS: exports.EXPANSIONS, routerTypeOf, buildFilter, filterMatches };
|
|
73
|
-
module.exports.EXPANSIONS = exports.EXPANSIONS;
|
|
74
|
-
module.exports.routerTypeOf = routerTypeOf;
|
|
75
|
-
module.exports.buildFilter = buildFilter;
|
|
76
|
-
module.exports.filterMatches = filterMatches;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
const path = require('path');
|
|
3
2
|
const ObjectId = require('bson-objectid').default;
|
|
4
3
|
|
|
5
4
|
/**
|
|
@@ -7,11 +6,6 @@ const ObjectId = require('bson-objectid').default;
|
|
|
7
6
|
*/
|
|
8
7
|
const DomainEvents = require('@tryghost/domain-events/lib/DomainEvents');
|
|
9
8
|
|
|
10
|
-
/**
|
|
11
|
-
* @typedef {Object} IdbBackup
|
|
12
|
-
* @prop {() => Promise<string>} backup
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
9
|
/**
|
|
16
10
|
* @typedef {Object} IModels
|
|
17
11
|
* @prop {Object} Base
|
|
@@ -40,14 +34,12 @@ const DomainEvents = require('@tryghost/domain-events/lib/DomainEvents');
|
|
|
40
34
|
class Users {
|
|
41
35
|
/**
|
|
42
36
|
* @param {Object} dependencies
|
|
43
|
-
* @param {IdbBackup} dependencies.dbBackup
|
|
44
37
|
* @param {IModels} dependencies.models
|
|
45
38
|
* @param {IAuth} dependencies.auth
|
|
46
39
|
* @param {Object} dependencies.apiMail
|
|
47
40
|
* @param {Object} dependencies.apiSettings
|
|
48
41
|
*/
|
|
49
|
-
constructor({
|
|
50
|
-
this.dbBackup = dbBackup;
|
|
42
|
+
constructor({ models, auth, apiMail, apiSettings }) {
|
|
51
43
|
this.models = models;
|
|
52
44
|
this.auth = auth;
|
|
53
45
|
this.apiMail = apiMail;
|
|
@@ -183,14 +175,6 @@ class Users {
|
|
|
183
175
|
* @returns
|
|
184
176
|
*/
|
|
185
177
|
async destroyUser(frameOptions) {
|
|
186
|
-
let filename = null;
|
|
187
|
-
const backupPath = await this.dbBackup.backup();
|
|
188
|
-
|
|
189
|
-
if (backupPath) {
|
|
190
|
-
const parsedFileName = path.parse(backupPath);
|
|
191
|
-
filename = `${parsedFileName.name}${parsedFileName.ext}`;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
178
|
return this.models.Base.transaction(async (t) => {
|
|
195
179
|
frameOptions.transacting = t;
|
|
196
180
|
|
|
@@ -234,8 +218,6 @@ class Users {
|
|
|
234
218
|
}
|
|
235
219
|
|
|
236
220
|
await this.models.User.destroy(Object.assign({ status: 'all' }, frameOptions));
|
|
237
|
-
|
|
238
|
-
return filename;
|
|
239
221
|
});
|
|
240
222
|
}
|
|
241
223
|
}
|
|
@@ -46,7 +46,7 @@ module.exports = function adminController(req, res) {
|
|
|
46
46
|
throw new errors.IncorrectUsageError({
|
|
47
47
|
message: tpl(messages.templateError.message, { templatePath }),
|
|
48
48
|
context: tpl(messages.templateError.context),
|
|
49
|
-
help: tpl(messages.templateError.help, { link: 'https://ghost.org/
|
|
49
|
+
help: tpl(messages.templateError.help, { link: 'https://docs.ghost.org/install/source/' }),
|
|
50
50
|
err,
|
|
51
51
|
});
|
|
52
52
|
}
|
|
@@ -161,7 +161,7 @@ module.exports = function apiRoutes() {
|
|
|
161
161
|
router.put(
|
|
162
162
|
'/tiers/:id/checkout_config',
|
|
163
163
|
mw.authAdminApi,
|
|
164
|
-
labs.enabledMiddleware('
|
|
164
|
+
labs.enabledMiddleware('stripeCheckoutCollection'),
|
|
165
165
|
http(api.tiersCheckoutConfig.edit),
|
|
166
166
|
);
|
|
167
167
|
|
|
@@ -195,36 +195,39 @@ module.exports = function apiRoutes() {
|
|
|
195
195
|
|
|
196
196
|
router.get('/members/stripe_connect', mw.authAdminApi, http(api.membersStripeConnect.auth));
|
|
197
197
|
|
|
198
|
-
//
|
|
199
|
-
//
|
|
200
|
-
//
|
|
201
|
-
//
|
|
202
|
-
router.get('/members/
|
|
198
|
+
// Reading definitions is deliberately not behind the feature flag: Admin asks every site
|
|
199
|
+
// for them, and a site without the flag simply has none, so the answer is an empty list
|
|
200
|
+
// rather than a 404. Creating and changing them is flagged. Registered before /members/:id
|
|
201
|
+
// so the literal path is not captured as an id.
|
|
202
|
+
router.get('/members/metafields/:namespace', mw.authAdminApi, http(api.membersMetafields.browse));
|
|
203
203
|
router.post(
|
|
204
|
-
'/members/
|
|
204
|
+
'/members/metafields/:namespace',
|
|
205
205
|
mw.authAdminApi,
|
|
206
206
|
labs.enabledMiddleware('membersCustomFields'),
|
|
207
|
-
http(api.
|
|
207
|
+
http(api.membersMetafields.add),
|
|
208
208
|
);
|
|
209
|
-
// A PUT on the collection sets the publisher's order for the whole list.
|
|
210
209
|
router.put(
|
|
211
|
-
'/members/
|
|
210
|
+
'/members/metafields/:namespace',
|
|
212
211
|
mw.authAdminApi,
|
|
213
212
|
labs.enabledMiddleware('membersCustomFields'),
|
|
214
|
-
http(api.
|
|
213
|
+
http(api.membersMetafields.reorder),
|
|
214
|
+
);
|
|
215
|
+
router.get(
|
|
216
|
+
'/members/metafields/:namespace/:key',
|
|
217
|
+
mw.authAdminApi,
|
|
218
|
+
http(api.membersMetafields.read),
|
|
215
219
|
);
|
|
216
|
-
router.get('/members/custom_fields/:key', mw.authAdminApi, http(api.membersCustomFields.read));
|
|
217
220
|
router.put(
|
|
218
|
-
'/members/
|
|
221
|
+
'/members/metafields/:namespace/:key',
|
|
219
222
|
mw.authAdminApi,
|
|
220
223
|
labs.enabledMiddleware('membersCustomFields'),
|
|
221
|
-
http(api.
|
|
224
|
+
http(api.membersMetafields.edit),
|
|
222
225
|
);
|
|
223
226
|
router.delete(
|
|
224
|
-
'/members/
|
|
227
|
+
'/members/metafields/:namespace/:key',
|
|
225
228
|
mw.authAdminApi,
|
|
226
229
|
labs.enabledMiddleware('membersCustomFields'),
|
|
227
|
-
http(api.
|
|
230
|
+
http(api.membersMetafields.destroy),
|
|
228
231
|
);
|
|
229
232
|
|
|
230
233
|
router.get('/members/:id', mw.authAdminApi, http(api.members.read));
|
|
@@ -518,6 +521,7 @@ module.exports = function apiRoutes() {
|
|
|
518
521
|
// ## Emails
|
|
519
522
|
router.get('/emails', mw.authAdminApi, http(api.emails.browse));
|
|
520
523
|
router.get('/emails/:id', mw.authAdminApi, http(api.emails.read));
|
|
524
|
+
router.get('/emails/:id/status', mw.authAdminApi, http(api.emails.sendingStatus));
|
|
521
525
|
router.put('/emails/:id/retry', mw.authAdminApi, http(api.emails.retry));
|
|
522
526
|
router.get('/emails/:id/batches', mw.authAdminApi, http(api.emails.browseBatches));
|
|
523
527
|
router.get('/emails/:id/recipient-failures', mw.authAdminApi, http(api.emails.browseFailures));
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const express = require('../../../../shared/express');
|
|
3
|
+
const bodyParser = require('body-parser');
|
|
4
|
+
const config = require('../../../../shared/config');
|
|
5
|
+
const { http } = require('@tryghost/api-framework');
|
|
6
|
+
const api = require('../../../api').endpoints;
|
|
7
|
+
const middleware = require('../../../services/members/middleware');
|
|
8
|
+
/**
|
|
9
|
+
* A member's own account, over HTTP.
|
|
10
|
+
*
|
|
11
|
+
* Everything reached by a signed-in member acting on their own record lives here,
|
|
12
|
+
* so how these routes authenticate is a property of the module rather than a line
|
|
13
|
+
* each one repeats. Establishing who is asking happens once; each route then says
|
|
14
|
+
* what it wants done when there is nobody.
|
|
15
|
+
*
|
|
16
|
+
* Endpoints reached by someone who is not signed in stay outside this: the
|
|
17
|
+
* unsubscribe links identify a member by a signed link, and changing an email
|
|
18
|
+
* address by a token in the body, because in both cases the person following them
|
|
19
|
+
* has no session.
|
|
20
|
+
*/
|
|
21
|
+
module.exports = function accountRoutes() {
|
|
22
|
+
const router = express.Router('member-account');
|
|
23
|
+
router.use(middleware.loadMemberIdentity);
|
|
24
|
+
// Reading who you are. Answering with nothing when there is no member is the
|
|
25
|
+
// right answer rather than a failure: a themed page asks this on every view.
|
|
26
|
+
if (config.get('cacheMembersContent:enabled')) {
|
|
27
|
+
router.get('/',
|
|
28
|
+
// Not for this route's benefit. This configuration stamps a cookie saying
|
|
29
|
+
// what the reader is entitled to, so a cache can vary on it, and that needs
|
|
30
|
+
// the member's subscriptions rather than only their identity. It rides here
|
|
31
|
+
// because Portal asks this endpoint on every page load.
|
|
32
|
+
middleware.loadMemberSession, middleware.accessInfoSession, middleware.emptyWhenAnonymous, http(api.membersAccount.read));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
router.get('/', middleware.emptyWhenAnonymous, http(api.membersAccount.read));
|
|
36
|
+
}
|
|
37
|
+
router.put('/', bodyParser.json({ limit: '50mb' }), middleware.rejectWhenAnonymous, http(api.membersAccount.update));
|
|
38
|
+
// The fields a publisher has defined, which a member's client renders inputs
|
|
39
|
+
// from. Under the account because a member reads them to fill in their own, and
|
|
40
|
+
// refused to an unknown caller because what a publisher collects is their
|
|
41
|
+
// configuration rather than something the site announces.
|
|
42
|
+
router.get('/metafields/:namespace', middleware.rejectWhenAnonymous, http(api.memberMetafieldsMembers.browse));
|
|
43
|
+
// Letting Ghost email this member again after it stopped.
|
|
44
|
+
router.delete('/suppression', middleware.rejectWhenAnonymous, http(api.membersAccount.destroySuppression));
|
|
45
|
+
return router;
|
|
46
|
+
};
|
|
@@ -8,10 +8,10 @@ const audienceFeedbackService = require('../../services/audience-feedback');
|
|
|
8
8
|
const middleware = membersService.middleware;
|
|
9
9
|
const shared = require('../shared');
|
|
10
10
|
const errorHandler = require('@tryghost/mw-error-handler');
|
|
11
|
-
const config = require('../../../shared/config');
|
|
12
11
|
const { http } = require('@tryghost/api-framework');
|
|
13
12
|
const api = require('../../api').endpoints;
|
|
14
13
|
|
|
14
|
+
const accountRoutes = require('./account');
|
|
15
15
|
const commentRouter = require('../comments');
|
|
16
16
|
const announcementRouter = require('../announcement');
|
|
17
17
|
const corsMiddleware = require('./middleware/cors');
|
|
@@ -57,21 +57,9 @@ module.exports = function setupMembersApp() {
|
|
|
57
57
|
middleware.updateMemberNewsletters,
|
|
58
58
|
);
|
|
59
59
|
|
|
60
|
-
//
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (shouldCacheMembersContent) {
|
|
64
|
-
membersApp.get(
|
|
65
|
-
'/api/member',
|
|
66
|
-
middleware.loadMemberSession,
|
|
67
|
-
middleware.accessInfoSession,
|
|
68
|
-
middleware.getMemberData,
|
|
69
|
-
);
|
|
70
|
-
} else {
|
|
71
|
-
membersApp.get('/api/member', middleware.getMemberData);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
membersApp.put('/api/member', bodyParser.json({ limit: '50mb' }), middleware.updateMemberData);
|
|
60
|
+
// A member's own account. Its routes and how they authenticate live together.
|
|
61
|
+
membersApp.use('/api/member', accountRoutes());
|
|
62
|
+
|
|
75
63
|
membersApp.post('/api/member/email', bodyParser.json({ limit: '50mb' }), (req, res, next) =>
|
|
76
64
|
membersService.api.middleware.updateEmailAddress(req, res, next),
|
|
77
65
|
);
|
|
@@ -86,8 +74,6 @@ module.exports = function setupMembersApp() {
|
|
|
86
74
|
);
|
|
87
75
|
|
|
88
76
|
// Remove email from suppression list
|
|
89
|
-
membersApp.delete('/api/member/suppression', middleware.deleteSuppression);
|
|
90
|
-
|
|
91
77
|
// Manage session
|
|
92
78
|
membersApp.get('/api/session', middleware.getIdentityToken);
|
|
93
79
|
membersApp.delete('/api/session', bodyParser.json({ limit: '5mb' }), middleware.deleteSession);
|
package/core/shared/labs.js
CHANGED
|
@@ -27,7 +27,7 @@ const messages = {
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
// flags in this list always return `true`, allows quick global enable prior to full flag removal
|
|
30
|
-
const GA_FEATURES = ['automationAnalytics', '
|
|
30
|
+
const GA_FEATURES = ['automationAnalytics', 'tagDetailsReact'];
|
|
31
31
|
|
|
32
32
|
// These features are considered publicly available and can be enabled/disabled by users
|
|
33
33
|
const PUBLIC_BETA_FEATURES = [
|
|
@@ -42,20 +42,25 @@ const PUBLIC_BETA_FEATURES = [
|
|
|
42
42
|
const PRIVATE_FEATURES = [
|
|
43
43
|
'automations',
|
|
44
44
|
'automationRunAnalytics',
|
|
45
|
+
'automationsTinybirdSync',
|
|
45
46
|
'stripeAutomaticTax',
|
|
46
47
|
'importMemberTier',
|
|
47
48
|
'csvContentImporter',
|
|
48
49
|
'adminUIRefresh',
|
|
49
50
|
'tagsX',
|
|
50
51
|
'emailUniqueid',
|
|
52
|
+
'improveSendingUI',
|
|
51
53
|
'themeTranslation',
|
|
52
54
|
'pictureImageFormats',
|
|
53
55
|
'getHelperDeduplication',
|
|
54
56
|
'membersCustomFields',
|
|
57
|
+
'stripeCheckoutCollection',
|
|
58
|
+
'membersImportRedesign',
|
|
55
59
|
'paywallImprovements',
|
|
56
|
-
'tagDetailsReact',
|
|
57
60
|
'selfServeArchives',
|
|
58
61
|
'machinePayments',
|
|
62
|
+
'postsListReact',
|
|
63
|
+
'editorReact',
|
|
59
64
|
];
|
|
60
65
|
|
|
61
66
|
module.exports.GA_KEYS = [...GA_FEATURES];
|