ghost 5.115.0 → 5.116.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (341) hide show
  1. package/components/{tryghost-api-framework-5.115.0.tgz → tryghost-api-framework-5.116.0.tgz} +0 -0
  2. package/components/tryghost-constants-5.116.0.tgz +0 -0
  3. package/components/tryghost-custom-fonts-5.116.0.tgz +0 -0
  4. package/components/{tryghost-custom-theme-settings-service-5.115.0.tgz → tryghost-custom-theme-settings-service-5.116.0.tgz} +0 -0
  5. package/components/tryghost-domain-events-5.116.0.tgz +0 -0
  6. package/components/{tryghost-donations-5.115.0.tgz → tryghost-donations-5.116.0.tgz} +0 -0
  7. package/components/tryghost-email-addresses-5.116.0.tgz +0 -0
  8. package/components/tryghost-email-service-5.116.0.tgz +0 -0
  9. package/components/tryghost-email-suppression-list-5.116.0.tgz +0 -0
  10. package/components/tryghost-html-to-plaintext-5.116.0.tgz +0 -0
  11. package/components/tryghost-i18n-5.116.0.tgz +0 -0
  12. package/components/tryghost-job-manager-5.116.0.tgz +0 -0
  13. package/components/tryghost-link-replacer-5.116.0.tgz +0 -0
  14. package/components/tryghost-magic-link-5.116.0.tgz +0 -0
  15. package/components/tryghost-member-attribution-5.116.0.tgz +0 -0
  16. package/components/tryghost-member-events-5.116.0.tgz +0 -0
  17. package/components/tryghost-members-api-5.116.0.tgz +0 -0
  18. package/components/tryghost-members-csv-5.116.0.tgz +0 -0
  19. package/components/{tryghost-members-offers-5.115.0.tgz → tryghost-members-offers-5.116.0.tgz} +0 -0
  20. package/components/{tryghost-milestones-5.115.0.tgz → tryghost-milestones-5.116.0.tgz} +0 -0
  21. package/components/{tryghost-mw-error-handler-5.115.0.tgz → tryghost-mw-error-handler-5.116.0.tgz} +0 -0
  22. package/components/tryghost-mw-vhost-5.116.0.tgz +0 -0
  23. package/components/{tryghost-post-events-5.115.0.tgz → tryghost-post-events-5.116.0.tgz} +0 -0
  24. package/components/{tryghost-post-revisions-5.115.0.tgz → tryghost-post-revisions-5.116.0.tgz} +0 -0
  25. package/components/tryghost-posts-service-5.116.0.tgz +0 -0
  26. package/components/{tryghost-prometheus-metrics-5.115.0.tgz → tryghost-prometheus-metrics-5.116.0.tgz} +0 -0
  27. package/components/tryghost-security-5.116.0.tgz +0 -0
  28. package/components/{tryghost-tiers-5.115.0.tgz → tryghost-tiers-5.116.0.tgz} +0 -0
  29. package/components/tryghost-webmentions-5.116.0.tgz +0 -0
  30. package/content/themes/casper/LICENSE +1 -1
  31. package/content/themes/casper/README.md +1 -1
  32. package/content/themes/source/LICENSE +1 -1
  33. package/content/themes/source/README.md +1 -1
  34. package/content/themes/source/assets/built/screen.css +1 -1
  35. package/content/themes/source/assets/built/screen.css.map +1 -1
  36. package/content/themes/source/assets/css/screen.css +11 -6
  37. package/content/themes/source/partials/feature-image.hbs +2 -2
  38. package/core/boot.js +3 -43
  39. package/core/built/admin/assets/admin-x-activitypub/admin-x-activitypub.js +30494 -29403
  40. package/core/built/admin/assets/admin-x-demo/admin-x-demo.js +1 -1
  41. package/core/built/admin/assets/admin-x-demo/{index-0040480a.mjs → index-a9601514.mjs} +5 -4
  42. package/core/built/admin/assets/admin-x-demo/{modals-fb35c86c.mjs → modals-c1789d04.mjs} +67 -65
  43. package/core/built/admin/assets/admin-x-settings/{CodeEditorView-806ef39c.mjs → CodeEditorView-e9c9deb8.mjs} +2 -2
  44. package/core/built/admin/assets/admin-x-settings/admin-x-settings.js +2 -2
  45. package/core/built/admin/assets/admin-x-settings/{index-376f847c.mjs → index-84580c3a.mjs} +2 -2
  46. package/core/built/admin/assets/admin-x-settings/{index-8fa19303.mjs → index-f744cab7.mjs} +3147 -3123
  47. package/core/built/admin/assets/admin-x-settings/{modals-36775d71.mjs → modals-d9ca60c5.mjs} +1198 -1192
  48. package/core/built/admin/assets/chunk.524.8371443ef8f60db429d0.js +35 -0
  49. package/core/built/admin/assets/chunk.582.f90151775f2e53dd21d9.js +37 -0
  50. package/core/built/admin/assets/{chunk.874.461cb3cf5b6b36915f8c.js → chunk.713.e9027c0cc3c56110f5da.js} +125 -98
  51. package/core/built/admin/assets/{ghost-938b3d9c29e3564a53a22f8c8f82d351.js → ghost-03b64c086f3c60cabc85fe7a7e2b640a.js} +272 -251
  52. package/core/built/admin/assets/ghost-ba58e9822f7384461e926c7e23f04a75.css +1 -0
  53. package/core/built/admin/assets/ghost-dark-f1f29683b14ffa11615b3bba8b6ab92c.css +1 -0
  54. package/core/built/admin/assets/koenig-lexical/index.css +1 -1
  55. package/core/built/admin/assets/koenig-lexical/koenig-lexical.js +20563 -20891
  56. package/core/built/admin/assets/koenig-lexical/koenig-lexical.umd.js +139 -139
  57. package/core/built/admin/assets/posts/posts.js +5732 -5667
  58. package/core/built/admin/assets/stats/stats.js +75373 -0
  59. package/core/built/admin/assets/{vendor-68a4aa424a179a90f5bbc2b750def576.js → vendor-72026232b36d97babc6320917c16c321.js} +36 -34
  60. package/core/built/admin/index.html +6 -6
  61. package/core/cli/generate-data.js +1 -1
  62. package/core/frontend/helpers/ghost_head.js +8 -1
  63. package/core/frontend/public/ghost-stats.js +55 -2
  64. package/core/frontend/services/assets-minification/AdminAuthAssets.js +2 -1
  65. package/core/frontend/services/assets-minification/CardAssets.js +1 -1
  66. package/core/frontend/services/assets-minification/CommentCountsAssets.js +1 -1
  67. package/core/frontend/services/assets-minification/MemberAttributionAssets.js +1 -1
  68. package/core/frontend/services/assets-minification/Minifier.js +191 -0
  69. package/core/frontend/services/routing/controllers/previews.js +2 -1
  70. package/core/frontend/src/cards/css/cta.css +1 -1
  71. package/core/server/adapters/cache/Redis.js +1 -1
  72. package/core/server/adapters/lib/redis/AdapterCacheRedis.js +287 -0
  73. package/core/server/adapters/lib/redis/redis-store-factory.js +22 -0
  74. package/core/server/api/endpoints/posts.js +9 -3
  75. package/core/server/api/endpoints/previews.js +35 -1
  76. package/core/server/api/endpoints/slugs.js +6 -2
  77. package/core/server/api/endpoints/utils/serializers/output/utils/post-gating.js +6 -9
  78. package/core/server/api/endpoints/utils/validators/input/settings.js +1 -1
  79. package/core/server/data/db/connection.js +2 -0
  80. package/core/server/data/db/index.js +1 -0
  81. package/core/server/data/importer/handlers/ImporterContentFileHandler.js +90 -0
  82. package/core/server/data/importer/import-manager.js +3 -3
  83. package/core/server/data/importer/importers/importer-revue.js +128 -0
  84. package/core/server/data/importer/importers/json-to-html.js +107 -0
  85. package/core/server/data/migrations/utils/tables.js +2 -4
  86. package/core/server/data/seeders/DataGenerator.js +288 -0
  87. package/core/server/data/seeders/importers/BenefitsImporter.js +28 -0
  88. package/core/server/data/seeders/importers/CommentsImporter.js +73 -0
  89. package/core/server/data/seeders/importers/EmailBatchesImporter.js +38 -0
  90. package/core/server/data/seeders/importers/EmailRecipientFailuresImporter.js +67 -0
  91. package/core/server/data/seeders/importers/EmailRecipientsImporter.js +212 -0
  92. package/core/server/data/seeders/importers/EmailsImporter.js +99 -0
  93. package/core/server/data/seeders/importers/LabelsImporter.js +41 -0
  94. package/core/server/data/seeders/importers/MembersClickEventsImporter.js +69 -0
  95. package/core/server/data/seeders/importers/MembersCreatedEventsImporter.js +103 -0
  96. package/core/server/data/seeders/importers/MembersFeedbackImporter.js +45 -0
  97. package/core/server/data/seeders/importers/MembersImporter.js +111 -0
  98. package/core/server/data/seeders/importers/MembersLabelsImporter.js +39 -0
  99. package/core/server/data/seeders/importers/MembersLoginEventsImporter.js +69 -0
  100. package/core/server/data/seeders/importers/MembersNewslettersImporter.js +38 -0
  101. package/core/server/data/seeders/importers/MembersPaidSubscriptionEventsImporter.js +99 -0
  102. package/core/server/data/seeders/importers/MembersProductsImporter.js +42 -0
  103. package/core/server/data/seeders/importers/MembersStatusEventsImporter.js +58 -0
  104. package/core/server/data/seeders/importers/MembersStripeCustomersImporter.js +60 -0
  105. package/core/server/data/seeders/importers/MembersStripeCustomersSubscriptionsImporter.js +259 -0
  106. package/core/server/data/seeders/importers/MembersSubscribeEventsImporter.js +69 -0
  107. package/core/server/data/seeders/importers/MembersSubscriptionCreatedEventsImporter.js +95 -0
  108. package/core/server/data/seeders/importers/NewslettersImporter.js +40 -0
  109. package/core/server/data/seeders/importers/OffersImporter.js +70 -0
  110. package/core/server/data/seeders/importers/PostsAuthorsImporter.js +32 -0
  111. package/core/server/data/seeders/importers/PostsImporter.js +102 -0
  112. package/core/server/data/seeders/importers/PostsProductsImporter.js +35 -0
  113. package/core/server/data/seeders/importers/PostsTagsImporter.js +46 -0
  114. package/core/server/data/seeders/importers/ProductsBenefitsImporter.js +54 -0
  115. package/core/server/data/seeders/importers/ProductsImporter.js +90 -0
  116. package/core/server/data/seeders/importers/RecommendationClickEventsImporter.js +32 -0
  117. package/core/server/data/seeders/importers/RecommendationSubscribeEventsImporter.js +32 -0
  118. package/core/server/data/seeders/importers/RecommendationsImporter.js +34 -0
  119. package/core/server/data/seeders/importers/RedirectsImporter.js +49 -0
  120. package/core/server/data/seeders/importers/RolesUsersImporter.js +42 -0
  121. package/core/server/data/seeders/importers/StripePricesImporter.js +69 -0
  122. package/core/server/data/seeders/importers/StripeProductsImporter.js +34 -0
  123. package/core/server/data/seeders/importers/TableImporter.js +187 -0
  124. package/core/server/data/seeders/importers/TagsImporter.js +41 -0
  125. package/core/server/data/seeders/importers/UsersImporter.js +31 -0
  126. package/core/server/data/seeders/importers/WebMentionsImporter.js +42 -0
  127. package/core/server/data/seeders/importers/index.js +41 -0
  128. package/core/server/data/seeders/utils/JsonImporter.js +39 -0
  129. package/core/server/data/seeders/utils/blog-info.js +3 -0
  130. package/core/server/data/seeders/utils/database-date.js +7 -0
  131. package/core/server/data/seeders/utils/event-generator.js +48 -0
  132. package/core/server/data/seeders/utils/random.js +13 -0
  133. package/core/server/data/seeders/utils/topological-sort.js +33 -0
  134. package/core/server/lib/bootstrap-socket.js +87 -0
  135. package/core/server/lib/package-json/index.js +1 -0
  136. package/core/server/lib/package-json/package-json.js +160 -0
  137. package/core/server/lib/package-json/parse.js +57 -0
  138. package/core/server/models/base/plugins/actions.js +44 -31
  139. package/core/server/models/base/plugins/generate-slug.js +6 -0
  140. package/core/server/notify.js +1 -1
  141. package/core/server/services/activitypub/ActivityPubService.ts +1 -1
  142. package/core/server/services/adapter-manager/AdapterManager.js +161 -0
  143. package/core/server/services/adapter-manager/index.js +1 -1
  144. package/core/server/services/announcement-bar-service/AnnouncementBarSettings.js +54 -0
  145. package/core/server/services/announcement-bar-service/AnnouncementVisibilityValues.js +11 -0
  146. package/core/server/services/announcement-bar-service/index.js +1 -1
  147. package/core/server/services/api-version-compatibility/APIVersionCompatibilityService.js +99 -0
  148. package/core/server/services/api-version-compatibility/VersionNotificationsDataService.js +80 -0
  149. package/core/server/services/api-version-compatibility/extract-api-key.js +57 -0
  150. package/core/server/services/api-version-compatibility/index.js +2 -2
  151. package/core/server/services/api-version-compatibility/mw-api-version-mismatch.js +31 -0
  152. package/core/server/services/audience-feedback/AudienceFeedbackController.js +85 -0
  153. package/core/server/services/audience-feedback/AudienceFeedbackService.js +34 -0
  154. package/core/server/services/audience-feedback/Feedback.js +35 -0
  155. package/core/server/services/audience-feedback/index.js +4 -2
  156. package/core/server/services/auth/session/emails/signin.js +168 -0
  157. package/core/server/services/auth/session/index.js +2 -2
  158. package/core/server/services/auth/session/session-from-token.js +69 -0
  159. package/core/server/services/auth/session/session-service.js +374 -0
  160. package/core/server/services/custom-redirects/index.js +1 -1
  161. package/core/server/services/email-analytics/EmailAnalyticsProviderMailgun.js +62 -0
  162. package/core/server/services/email-analytics/EmailAnalyticsService.js +552 -0
  163. package/core/server/services/email-analytics/EmailAnalyticsServiceWrapper.js +3 -3
  164. package/core/server/services/email-analytics/EventProcessingResult.js +66 -0
  165. package/core/server/services/email-service/EmailServiceWrapper.js +4 -4
  166. package/core/server/services/email-suppression-list/MailgunEmailSuppressionList.js +1 -1
  167. package/core/server/services/email-suppression-list/service.js +1 -1
  168. package/core/server/services/explore-ping/ExplorePingService.js +106 -0
  169. package/core/server/services/explore-ping/index.js +31 -0
  170. package/core/server/services/identity-tokens/IdentityTokenService.js +30 -0
  171. package/core/server/services/identity-tokens/IdentityTokenService.ts +28 -0
  172. package/core/server/services/identity-tokens/IdentityTokenServiceWrapper.js +1 -1
  173. package/core/server/services/invitations/accept.js +5 -2
  174. package/core/server/services/lib/DynamicRedirectManager.js +156 -0
  175. package/core/server/services/lib/EmailContentGenerator.js +54 -0
  176. package/core/server/services/lib/InMemoryRepository.js +62 -0
  177. package/core/server/services/lib/InMemoryRepository.ts +80 -0
  178. package/core/server/services/lib/MailgunClient.js +364 -0
  179. package/core/server/services/link-redirection/LinkRedirect.js +26 -0
  180. package/core/server/services/link-redirection/LinkRedirectRepository.js +7 -7
  181. package/core/server/services/link-redirection/LinkRedirectsService.js +123 -0
  182. package/core/server/services/link-redirection/README.md +151 -0
  183. package/core/server/services/link-redirection/RedirectEvent.js +24 -0
  184. package/core/server/services/link-redirection/index.js +1 -1
  185. package/core/server/services/link-tracking/LinkClickTrackingService.js +1 -1
  186. package/core/server/services/mail/index.js +1 -1
  187. package/core/server/services/mail-events/BookshelfMailEventRepository.js +2 -2
  188. package/core/server/services/mail-events/InMemoryMailEventRepository.js +10 -0
  189. package/core/server/services/mail-events/InMemoryMailEventRepository.ts +8 -0
  190. package/core/server/services/mail-events/MailEvent.js +20 -0
  191. package/core/server/services/mail-events/MailEvent.ts +10 -0
  192. package/core/server/services/mail-events/MailEventRepository.js +2 -0
  193. package/core/server/services/mail-events/MailEventRepository.ts +5 -0
  194. package/core/server/services/mail-events/MailEventService.js +124 -0
  195. package/core/server/services/mail-events/MailEventService.ts +169 -0
  196. package/core/server/services/mail-events/index.js +1 -1
  197. package/core/server/services/mail-events/libraries.d.ts +2 -0
  198. package/core/server/services/members/CaptchaService.js +80 -0
  199. package/core/server/services/members/api.js +1 -1
  200. package/core/server/services/members/importer/MembersCSVImporter.js +464 -0
  201. package/core/server/services/members/importer/MembersCSVImporterStripeUtils.js +194 -0
  202. package/core/server/services/members/importer/email-template.js +182 -0
  203. package/core/server/services/members/importer/index.js +30 -0
  204. package/core/server/services/members/members-ssr.js +333 -0
  205. package/core/server/services/members/service.js +2 -2
  206. package/core/server/services/members-events/LastSeenAtUpdater.js +1 -1
  207. package/core/server/services/offers/service.js +1 -1
  208. package/core/server/services/posts/stats/PostStats.js +13 -0
  209. package/core/server/services/recommendations/RecommendationServiceWrapper.js +8 -8
  210. package/core/server/services/recommendations/service/BookshelfClickEventRepository.js +48 -0
  211. package/core/server/services/recommendations/service/BookshelfClickEventRepository.ts +49 -0
  212. package/core/server/services/recommendations/service/BookshelfRecommendationRepository.js +98 -0
  213. package/core/server/services/recommendations/service/BookshelfRecommendationRepository.ts +117 -0
  214. package/core/server/services/recommendations/service/BookshelfRepository.js +134 -0
  215. package/core/server/services/recommendations/service/BookshelfRepository.ts +196 -0
  216. package/core/server/services/recommendations/service/BookshelfSubscribeEventRepository.js +48 -0
  217. package/core/server/services/recommendations/service/BookshelfSubscribeEventRepository.ts +49 -0
  218. package/core/server/services/recommendations/service/ClickEvent.js +33 -0
  219. package/core/server/services/recommendations/service/ClickEvent.ts +32 -0
  220. package/core/server/services/recommendations/service/InMemoryRecommendationRepository.js +19 -0
  221. package/core/server/services/recommendations/service/InMemoryRecommendationRepository.ts +20 -0
  222. package/core/server/services/recommendations/service/IncomingRecommendationController.js +34 -0
  223. package/core/server/services/recommendations/service/IncomingRecommendationController.ts +51 -0
  224. package/core/server/services/recommendations/service/IncomingRecommendationEmailRenderer.js +25 -0
  225. package/core/server/services/recommendations/service/IncomingRecommendationEmailRenderer.ts +37 -0
  226. package/core/server/services/recommendations/service/IncomingRecommendationService.js +93 -0
  227. package/core/server/services/recommendations/service/IncomingRecommendationService.ts +160 -0
  228. package/core/server/services/recommendations/service/Recommendation.js +140 -0
  229. package/core/server/services/recommendations/service/Recommendation.ts +201 -0
  230. package/core/server/services/recommendations/service/RecommendationController.js +208 -0
  231. package/core/server/services/recommendations/service/RecommendationController.ts +258 -0
  232. package/core/server/services/recommendations/service/RecommendationMetadataService.js +86 -0
  233. package/core/server/services/recommendations/service/RecommendationMetadataService.ts +128 -0
  234. package/core/server/services/recommendations/service/RecommendationRepository.js +2 -0
  235. package/core/server/services/recommendations/service/RecommendationRepository.ts +13 -0
  236. package/core/server/services/recommendations/service/RecommendationService.js +228 -0
  237. package/core/server/services/recommendations/service/RecommendationService.ts +281 -0
  238. package/core/server/services/recommendations/service/SubscribeEvent.js +33 -0
  239. package/core/server/services/recommendations/service/SubscribeEvent.ts +32 -0
  240. package/core/server/services/recommendations/service/UnsafeData.js +183 -0
  241. package/core/server/services/recommendations/service/UnsafeData.ts +217 -0
  242. package/core/server/services/recommendations/service/WellknownService.js +36 -0
  243. package/core/server/services/recommendations/service/WellknownService.ts +47 -0
  244. package/core/server/services/recommendations/service/index.js +31 -0
  245. package/core/server/services/recommendations/service/index.ts +15 -0
  246. package/core/server/services/recommendations/service/libraries.d.ts +5 -0
  247. package/core/server/services/route-settings/SettingsPathManager.js +47 -0
  248. package/core/server/services/route-settings/index.js +1 -1
  249. package/core/server/services/slack-notifications/SlackNotifications.js +211 -0
  250. package/core/server/services/slack-notifications/SlackNotificationsService.js +90 -0
  251. package/core/server/services/slack-notifications/service.js +4 -6
  252. package/core/server/services/stripe/README.md +63 -0
  253. package/core/server/services/stripe/StripeAPI.js +931 -0
  254. package/core/server/services/stripe/StripeMigrations.js +613 -0
  255. package/core/server/services/stripe/StripeService.js +175 -0
  256. package/core/server/services/stripe/WebhookController.js +100 -0
  257. package/core/server/services/stripe/WebhookManager.js +175 -0
  258. package/core/server/services/stripe/events/StripeLiveDisabledEvent.js +23 -0
  259. package/core/server/services/stripe/events/StripeLiveEnabledEvent.js +23 -0
  260. package/core/server/services/stripe/events/index.js +4 -0
  261. package/core/server/services/stripe/service.js +1 -1
  262. package/core/server/services/stripe/services/webhook/CheckoutSessionEventService.js +255 -0
  263. package/core/server/services/stripe/services/webhook/InvoiceEventService.js +70 -0
  264. package/core/server/services/stripe/services/webhook/SubscriptionEventService.js +54 -0
  265. package/core/server/services/themes/loader.js +1 -1
  266. package/core/server/services/themes/to-json.js +1 -1
  267. package/core/server/web/api/endpoints/admin/app.js +1 -21
  268. package/core/server/web/api/endpoints/admin/routes.js +1 -0
  269. package/core/server/web/api/middleware/version-match.js +41 -0
  270. package/core/server/web/shared/middleware/cache-control.js +51 -0
  271. package/core/server/web/shared/middleware/index.js +1 -1
  272. package/core/server/web/well-known.js +1 -1
  273. package/core/shared/labs.js +5 -3
  274. package/core/shared/settings-cache/CacheManager.js +64 -6
  275. package/package.json +98 -146
  276. package/tsconfig.tsbuildinfo +1 -1
  277. package/yarn.lock +1478 -1634
  278. package/components/tryghost-adapter-cache-redis-5.115.0.tgz +0 -0
  279. package/components/tryghost-adapter-manager-5.115.0.tgz +0 -0
  280. package/components/tryghost-announcement-bar-settings-5.115.0.tgz +0 -0
  281. package/components/tryghost-api-version-compatibility-service-5.115.0.tgz +0 -0
  282. package/components/tryghost-audience-feedback-5.115.0.tgz +0 -0
  283. package/components/tryghost-bookshelf-repository-5.115.0.tgz +0 -0
  284. package/components/tryghost-bootstrap-socket-5.115.0.tgz +0 -0
  285. package/components/tryghost-captcha-service-5.115.0.tgz +0 -0
  286. package/components/tryghost-constants-5.115.0.tgz +0 -0
  287. package/components/tryghost-custom-fonts-5.115.0.tgz +0 -0
  288. package/components/tryghost-data-generator-5.115.0.tgz +0 -0
  289. package/components/tryghost-domain-events-5.115.0.tgz +0 -0
  290. package/components/tryghost-email-addresses-5.115.0.tgz +0 -0
  291. package/components/tryghost-email-analytics-provider-mailgun-5.115.0.tgz +0 -0
  292. package/components/tryghost-email-analytics-service-5.115.0.tgz +0 -0
  293. package/components/tryghost-email-content-generator-5.115.0.tgz +0 -0
  294. package/components/tryghost-email-events-5.115.0.tgz +0 -0
  295. package/components/tryghost-email-service-5.115.0.tgz +0 -0
  296. package/components/tryghost-email-suppression-list-5.115.0.tgz +0 -0
  297. package/components/tryghost-express-dynamic-redirects-5.115.0.tgz +0 -0
  298. package/components/tryghost-extract-api-key-5.115.0.tgz +0 -0
  299. package/components/tryghost-ghost-5.115.0.tgz +0 -0
  300. package/components/tryghost-html-to-plaintext-5.115.0.tgz +0 -0
  301. package/components/tryghost-i18n-5.115.0.tgz +0 -0
  302. package/components/tryghost-identity-token-service-5.115.0.tgz +0 -0
  303. package/components/tryghost-importer-handler-content-files-5.115.0.tgz +0 -0
  304. package/components/tryghost-importer-revue-5.115.0.tgz +0 -0
  305. package/components/tryghost-in-memory-repository-5.115.0.tgz +0 -0
  306. package/components/tryghost-job-manager-5.115.0.tgz +0 -0
  307. package/components/tryghost-link-redirects-5.115.0.tgz +0 -0
  308. package/components/tryghost-link-replacer-5.115.0.tgz +0 -0
  309. package/components/tryghost-magic-link-5.115.0.tgz +0 -0
  310. package/components/tryghost-mail-events-5.115.0.tgz +0 -0
  311. package/components/tryghost-mailgun-client-5.115.0.tgz +0 -0
  312. package/components/tryghost-member-attribution-5.115.0.tgz +0 -0
  313. package/components/tryghost-member-events-5.115.0.tgz +0 -0
  314. package/components/tryghost-members-api-5.115.0.tgz +0 -0
  315. package/components/tryghost-members-csv-5.115.0.tgz +0 -0
  316. package/components/tryghost-members-importer-5.115.0.tgz +0 -0
  317. package/components/tryghost-members-payments-5.115.0.tgz +0 -0
  318. package/components/tryghost-members-ssr-5.115.0.tgz +0 -0
  319. package/components/tryghost-members-stripe-service-5.115.0.tgz +0 -0
  320. package/components/tryghost-minifier-5.115.0.tgz +0 -0
  321. package/components/tryghost-mw-api-version-mismatch-5.115.0.tgz +0 -0
  322. package/components/tryghost-mw-cache-control-5.115.0.tgz +0 -0
  323. package/components/tryghost-mw-session-from-token-5.115.0.tgz +0 -0
  324. package/components/tryghost-mw-update-user-last-seen-5.115.0.tgz +0 -0
  325. package/components/tryghost-mw-version-match-5.115.0.tgz +0 -0
  326. package/components/tryghost-mw-vhost-5.115.0.tgz +0 -0
  327. package/components/tryghost-package-json-5.115.0.tgz +0 -0
  328. package/components/tryghost-posts-service-5.115.0.tgz +0 -0
  329. package/components/tryghost-recommendations-5.115.0.tgz +0 -0
  330. package/components/tryghost-referrers-5.115.0.tgz +0 -0
  331. package/components/tryghost-security-5.115.0.tgz +0 -0
  332. package/components/tryghost-session-service-5.115.0.tgz +0 -0
  333. package/components/tryghost-settings-path-manager-5.115.0.tgz +0 -0
  334. package/components/tryghost-slack-notifications-5.115.0.tgz +0 -0
  335. package/components/tryghost-version-notifications-data-service-5.115.0.tgz +0 -0
  336. package/components/tryghost-webmentions-5.115.0.tgz +0 -0
  337. package/core/built/admin/assets/chunk.524.31419fdf6fb3859ecc1e.js +0 -35
  338. package/core/built/admin/assets/chunk.582.08c816d5e4ab766486a7.js +0 -37
  339. package/core/built/admin/assets/ghost-c2a7c4a1b76550c4219adb2ed4124ce0.css +0 -1
  340. package/core/built/admin/assets/ghost-dark-f91e4a479c6d38d94d5d1b14727871dc.css +0 -1
  341. /package/core/built/admin/assets/{chunk.874.461cb3cf5b6b36915f8c.js.LICENSE.txt → chunk.713.e9027c0cc3c56110f5da.js.LICENSE.txt} +0 -0
@@ -1,7 +1,7 @@
1
- const MailgunClient = require('@tryghost/mailgun-client');
2
1
  const models = require('../../models');
3
2
  const configService = require('../../../shared/config');
4
3
  const settingsCache = require('../../../shared/settings-cache');
4
+ const MailgunClient = require('../lib/MailgunClient');
5
5
  const MailgunEmailSuppressionList = require('./MailgunEmailSuppressionList');
6
6
 
7
7
  const mailgunClient = new MailgunClient({
@@ -0,0 +1,106 @@
1
+ module.exports = class ExplorePingService {
2
+ /**
3
+ * @param {object} deps
4
+ * @param {{getPublic: () => import('../../../shared/settings-cache/CacheManager').PublicSettingsCache}} deps.settingsCache
5
+ * @param {object} deps.config
6
+ * @param {object} deps.labs
7
+ * @param {object} deps.logging
8
+ * @param {object} deps.ghostVersion
9
+ * @param {object} deps.request
10
+ * @param {{stats: {
11
+ * getMostRecentlyPublishedPostDate: () => Promise<Date>,
12
+ * getFirstPublishedPostDate: () => Promise<Date>,
13
+ * getTotalPostsPublished: () => Promise<number>
14
+ * }}} deps.posts
15
+ * @param {{stats: {
16
+ * getTotalMembers: () => Promise<number>
17
+ * }}} deps.members
18
+ */
19
+ constructor({settingsCache, config, labs, logging, ghostVersion, request, posts, members}) {
20
+ this.settingsCache = settingsCache;
21
+ this.config = config;
22
+ this.labs = labs;
23
+ this.logging = logging;
24
+ this.ghostVersion = ghostVersion;
25
+ this.request = request;
26
+ this.posts = posts;
27
+ this.members = members;
28
+ }
29
+
30
+ async constructPayload() {
31
+ /* eslint-disable camelcase */
32
+ const {title, description, icon, locale, accent_color, twitter, facebook} = this.settingsCache.getPublic();
33
+
34
+ // Get post statistics
35
+ const [totalPosts, lastPublishedAt, firstPublishedAt] = await Promise.all([
36
+ this.posts.stats.getTotalPostsPublished(),
37
+ this.posts.stats.getMostRecentlyPublishedPostDate(),
38
+ this.posts.stats.getFirstPublishedPostDate()
39
+ ]);
40
+
41
+ // Get member statistics with error handling
42
+ let totalMembers = null;
43
+ try {
44
+ totalMembers = await this.members.stats.getTotalMembers();
45
+ } catch (err) {
46
+ this.logging.warn('Failed to fetch member statistics', {
47
+ error: err.message,
48
+ context: 'explore-ping-service'
49
+ });
50
+ // Continue without member statistics
51
+ }
52
+
53
+ return {
54
+ ghost: this.ghostVersion.full,
55
+ url: this.config.get('url'),
56
+ title,
57
+ description,
58
+ icon,
59
+ locale,
60
+ accent_color,
61
+ twitter,
62
+ facebook,
63
+ posts_first: firstPublishedAt ? firstPublishedAt.toISOString() : null,
64
+ posts_last: lastPublishedAt ? lastPublishedAt.toISOString() : null,
65
+ posts_total: totalPosts,
66
+ members_total: totalMembers
67
+ };
68
+ /* eslint-enable camelcase */
69
+ }
70
+
71
+ async makeRequest(exploreUrl, payload) {
72
+ const json = JSON.stringify(payload);
73
+ this.logging.info('Pinging Explore with Payload', exploreUrl, json);
74
+
75
+ try {
76
+ const response = await this.request(exploreUrl, {
77
+ method: 'POST',
78
+ body: json,
79
+ headers: {
80
+ 'Content-Type': 'application/json'
81
+ }
82
+ });
83
+
84
+ this.logging.info('Explore Response', response.statusCode, response.statusMessage);
85
+
86
+ return response;
87
+ } catch (err) {
88
+ this.logging.warn('Explore Error', err.message);
89
+ }
90
+ }
91
+
92
+ async ping() {
93
+ if (!this.labs.isSet('explore')) {
94
+ return;
95
+ }
96
+
97
+ const exploreUrl = this.config.get('explore:url');
98
+ if (!exploreUrl) {
99
+ this.logging.warn('Explore URL not set');
100
+ return;
101
+ }
102
+
103
+ const payload = await this.constructPayload();
104
+ await this.makeRequest(exploreUrl, payload);
105
+ }
106
+ };
@@ -0,0 +1,31 @@
1
+ const ExplorePingService = require('./ExplorePingService');
2
+ const config = require('../../../shared/config');
3
+ const labs = require('../../../shared/labs');
4
+ const logging = require('@tryghost/logging');
5
+ const ghostVersion = require('@tryghost/version');
6
+ const request = require('@tryghost/request');
7
+ const settingsCache = require('../../../shared/settings-cache');
8
+ const posts = require('../posts/posts-service');
9
+ const members = require('../members');
10
+
11
+ // Export the creation function for testing
12
+ module.exports.createService = function createService() {
13
+ return new ExplorePingService({
14
+ settingsCache,
15
+ config,
16
+ labs,
17
+ logging,
18
+ ghostVersion,
19
+ request,
20
+ posts: posts(),
21
+ members
22
+ });
23
+ };
24
+
25
+ module.exports.init = async function init() {
26
+ const explorePingService = module.exports.createService();
27
+
28
+ // The final intention is to have this run on a schedule
29
+ // For the initial version, we'll just ping when the server starts
30
+ await explorePingService.ping();
31
+ };
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IdentityTokenService = void 0;
4
+ const jsonwebtoken_1 = require("jsonwebtoken");
5
+ class IdentityTokenService {
6
+ privateKey;
7
+ issuer;
8
+ keyId;
9
+ constructor(privateKey, issuer, keyId) {
10
+ this.privateKey = privateKey;
11
+ this.issuer = issuer;
12
+ this.keyId = keyId;
13
+ }
14
+ async getTokenForUser(email, role) {
15
+ const claims = {
16
+ sub: email
17
+ };
18
+ if (typeof role === 'string') {
19
+ claims.role = role;
20
+ }
21
+ const token = (0, jsonwebtoken_1.sign)(claims, this.privateKey, {
22
+ issuer: this.issuer,
23
+ expiresIn: '5m',
24
+ algorithm: 'RS256',
25
+ keyid: this.keyId
26
+ });
27
+ return token;
28
+ }
29
+ }
30
+ exports.IdentityTokenService = IdentityTokenService;
@@ -0,0 +1,28 @@
1
+ import {sign} from 'jsonwebtoken';
2
+
3
+ export class IdentityTokenService {
4
+ constructor(
5
+ private privateKey: string,
6
+ private issuer: string,
7
+ private keyId: string
8
+ ) {}
9
+
10
+ async getTokenForUser(email: string, role?: string) {
11
+ const claims: Record<string, string> = {
12
+ sub: email
13
+ };
14
+
15
+ if (typeof role === 'string') {
16
+ claims.role = role;
17
+ }
18
+
19
+ const token = sign(claims, this.privateKey, {
20
+ issuer: this.issuer,
21
+ expiresIn: '5m',
22
+ algorithm: 'RS256',
23
+ keyid: this.keyId
24
+ });
25
+
26
+ return token;
27
+ }
28
+ }
@@ -1,4 +1,4 @@
1
- const {IdentityTokenService} = require('@tryghost/identity-token-service');
1
+ const {IdentityTokenService} = require('./IdentityTokenService');
2
2
 
3
3
  module.exports = class IdentityTokenServiceWrapper {
4
4
  /** @type IdentityTokenService */
@@ -2,13 +2,16 @@ const errors = require('@tryghost/errors');
2
2
  const tpl = require('@tryghost/tpl');
3
3
  const models = require('../../models');
4
4
  const security = require('@tryghost/security');
5
- const messages = {inviteNotFound: 'Invite not found.',
5
+
6
+ const messages = {
7
+ inviteNotFound: 'Invite not found.',
6
8
  inviteExpired: 'Invite is expired.',
7
9
  inviteEmailAlreadyExist: {
8
10
  message: 'Could not create an account, email is already in use.',
9
11
  context: 'Attempting to create an account with existing email address.',
10
12
  help: 'Use different email address to register your account.'
11
- }};
13
+ }
14
+ };
12
15
 
13
16
  async function accept(invitation) {
14
17
  const data = invitation.invitation[0];
@@ -0,0 +1,156 @@
1
+ const express = require('express');
2
+ const {parse: parseURL, format: formatURL} = require('url');
3
+ const {parse: parseQuerystring, stringify: formatQuerystring} = require('querystring');
4
+
5
+ class DynamicRedirectManager {
6
+ /**
7
+ * @param {object} config
8
+ * @param {number} config.permanentMaxAge
9
+ * @param {function} config.getSubdirectoryURL
10
+ */
11
+ constructor({permanentMaxAge, getSubdirectoryURL}) {
12
+ /** @private */
13
+ this.permanentMaxAge = permanentMaxAge;
14
+
15
+ this.getSubdirectoryURL = getSubdirectoryURL;
16
+
17
+ /** @private */
18
+ this.router = express.Router();
19
+ /** @private @type {Object.<string, {fromRegex: RegExp, to: string, options: {permanent: boolean}}>} */
20
+ this.redirects = {};
21
+
22
+ this.handleRequest = this.handleRequest.bind(this);
23
+ }
24
+
25
+ /**
26
+ * @private
27
+ * @param {string} string
28
+ * @returns {RegExp}
29
+ */
30
+ buildRegex(string) {
31
+ let flags = '';
32
+
33
+ if (string.startsWith('/') && string.endsWith('/i')) {
34
+ string = string.slice(1, -2);
35
+ flags += 'i';
36
+ }
37
+
38
+ if (string.endsWith('/')) {
39
+ string = string.slice(0, -1);
40
+ }
41
+
42
+ if (!string.endsWith('$')) {
43
+ string += '/?$';
44
+ }
45
+
46
+ return new RegExp(string, flags);
47
+ }
48
+
49
+ /**
50
+ * @private
51
+ * @param {string} redirectId
52
+ * @returns {void}
53
+ */
54
+ setupRedirect(redirectId) {
55
+ const {fromRegex, to, options: {permanent}} = this.redirects[redirectId];
56
+
57
+ this.router.get(fromRegex, (req, res) => {
58
+ const maxAge = permanent ? this.permanentMaxAge : 0;
59
+ const toURL = parseURL(to);
60
+ const toURLParams = parseQuerystring(toURL.query);
61
+ const currentURL = parseURL(req.url);
62
+ const currentURLParams = parseQuerystring(currentURL.query);
63
+ const params = Object.assign({}, currentURLParams, toURLParams);
64
+ const search = formatQuerystring(params);
65
+
66
+ toURL.pathname = currentURL.pathname.replace(fromRegex, toURL.pathname);
67
+ toURL.search = search !== '' ? `?${search}` : null;
68
+
69
+ /**
70
+ * Only if the url is internal should we prepend the Ghost subdirectory
71
+ * @see https://github.com/TryGhost/Ghost/issues/10776
72
+ */
73
+ if (!toURL.hostname) {
74
+ toURL.pathname = this.getSubdirectoryURL(toURL.pathname);
75
+ }
76
+
77
+ res.set({
78
+ 'Cache-Control': `public, max-age=${maxAge}`
79
+ });
80
+
81
+ res.redirect(permanent ? 301 : 302, formatURL(toURL));
82
+ });
83
+ }
84
+
85
+ /**
86
+ * @param {string} from
87
+ * @param {string} to
88
+ * @param {object} [options]
89
+ * @param {boolean} [options.permanent]
90
+ *
91
+ * @returns {string} The redirect ID
92
+ */
93
+ addRedirect(from, to, options = {}) {
94
+ try {
95
+ // encode "from" only if it's not a regex
96
+ try {
97
+ new RegExp(from);
98
+ } catch (e) {
99
+ from = encodeURI(from);
100
+ }
101
+
102
+ const fromRegex = this.buildRegex(from);
103
+ const redirectId = from;
104
+
105
+ this.redirects[redirectId] = {
106
+ fromRegex,
107
+ to,
108
+ options
109
+ };
110
+
111
+ this.setupRedirect(redirectId);
112
+
113
+ return redirectId;
114
+ } catch (error) {
115
+ if (error.message.match(/Invalid regular expression/gi)) {
116
+ return null;
117
+ }
118
+
119
+ throw error;
120
+ }
121
+ }
122
+
123
+ /**
124
+ * @param {string} redirectId
125
+ * @returns {void}
126
+ */
127
+ removeRedirect(redirectId) {
128
+ delete this.redirects[redirectId];
129
+
130
+ this.router = express.Router();
131
+ Object.keys(this.redirects).forEach(id => this.setupRedirect(id));
132
+
133
+ return;
134
+ }
135
+
136
+ /**
137
+ * @returns {void}
138
+ */
139
+ removeAllRedirects() {
140
+ this.redirects = {};
141
+ this.router = express.Router();
142
+ }
143
+
144
+ /**
145
+ * @param {express.Request} req
146
+ * @param {express.Response} res
147
+ * @param {express.NextFunction} next
148
+ *
149
+ * @returns {void}
150
+ */
151
+ handleRequest(req, res, next) {
152
+ this.router(req, res, next);
153
+ }
154
+ }
155
+
156
+ module.exports = DynamicRedirectManager;
@@ -0,0 +1,54 @@
1
+ const _ = require('lodash').runInContext();
2
+ const fs = require('fs-extra');
3
+ const path = require('path');
4
+
5
+ _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
6
+
7
+ class EmailContentGenerator {
8
+ /**
9
+ *
10
+ * @param {Object} options
11
+ * @param {function} options.getSiteUrl
12
+ * @param {function} options.getSiteTitle
13
+ * @param {string} options.templatesDir - path to the directory containing email templates
14
+ */
15
+ constructor({getSiteUrl, getSiteTitle, templatesDir}) {
16
+ this.getSiteUrl = getSiteUrl;
17
+ this.getSiteTitle = getSiteTitle;
18
+ this.templatesDir = templatesDir;
19
+ }
20
+
21
+ /**
22
+ *
23
+ * @param {Object} options
24
+ * @param {string} options.template - HTML template name to use for generation
25
+ * @param {Object} [options.data] - variable data to use during HTML template compilation
26
+ * @returns {Promise<{html: String, text: String}>} resolves with an object containing html and text properties
27
+ */
28
+ async getContent(options) {
29
+ const defaults = {
30
+ siteUrl: this.getSiteUrl(),
31
+ siteTitle: this.getSiteTitle()
32
+ };
33
+
34
+ const data = _.defaults(defaults, options.data);
35
+
36
+ // read the proper email body template
37
+ const content = await fs.readFile(path.join(this.templatesDir, options.template + '.html'), 'utf8');
38
+
39
+ // insert user-specific data into the email
40
+ const compiled = _.template(content);
41
+ const htmlContent = compiled(data);
42
+
43
+ // lazyload the lib, and generate a plain-text version of the same email
44
+ const htmlToText = require('html-to-text');
45
+ const textContent = htmlToText.fromString(htmlContent);
46
+
47
+ return {
48
+ html: htmlContent,
49
+ text: textContent
50
+ };
51
+ }
52
+ }
53
+
54
+ module.exports = EmailContentGenerator;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.InMemoryRepository = void 0;
7
+ const nql_1 = __importDefault(require("@tryghost/nql"));
8
+ class InMemoryRepository {
9
+ store = [];
10
+ ids = new Map();
11
+ async save(entity) {
12
+ if (entity.deleted) {
13
+ this.store = this.store.filter(item => item.id !== entity.id);
14
+ this.ids.delete(entity.id);
15
+ return;
16
+ }
17
+ if (this.ids.has(entity.id)) {
18
+ this.store = this.store.map((item) => {
19
+ if (item.id === entity.id) {
20
+ return entity;
21
+ }
22
+ return item;
23
+ });
24
+ }
25
+ else {
26
+ this.store.push(entity);
27
+ this.ids.set(entity.id, true);
28
+ }
29
+ }
30
+ async getById(id) {
31
+ return this.store.find(item => item.id === id) || null;
32
+ }
33
+ async getAll(options = {}) {
34
+ const filter = (0, nql_1.default)(options.filter);
35
+ const results = this.store.slice().filter(item => filter.queryJSON(this.toPrimitive(item)));
36
+ if (options.order) {
37
+ for (const order of options.order) {
38
+ results.sort((a, b) => {
39
+ if (order.direction === 'asc') {
40
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
41
+ return a[order.field] > b[order.field] ? 1 : -1;
42
+ }
43
+ else {
44
+ return a[order.field] < b[order.field] ? 1 : -1;
45
+ }
46
+ });
47
+ }
48
+ }
49
+ return results;
50
+ }
51
+ async getPage(options = { page: 1, limit: 15 }) {
52
+ const results = await this.getAll(options);
53
+ const start = (options.page - 1) * options.limit;
54
+ const end = start + options.limit;
55
+ return results.slice(start, end);
56
+ }
57
+ async getCount(options) {
58
+ const results = await this.getAll(options);
59
+ return results.length;
60
+ }
61
+ }
62
+ exports.InMemoryRepository = InMemoryRepository;
@@ -0,0 +1,80 @@
1
+ import nql from '@tryghost/nql';
2
+
3
+ type Entity<T> = {
4
+ id: T;
5
+ deleted: boolean;
6
+ }
7
+
8
+ type Order<T> = {
9
+ field: keyof T;
10
+ direction: 'asc' | 'desc';
11
+ }
12
+
13
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
+ type OrderOption<T extends Entity<any>> = Order<T>[];
15
+
16
+ export abstract class InMemoryRepository<IDType, T extends Entity<IDType>> {
17
+ protected store: T[] = [];
18
+ private ids: Map<IDType, true> = new Map();
19
+
20
+ protected abstract toPrimitive(entity: T): object;
21
+
22
+ public async save(entity: T): Promise<void> {
23
+ if (entity.deleted) {
24
+ this.store = this.store.filter(item => item.id !== entity.id);
25
+ this.ids.delete(entity.id);
26
+ return;
27
+ }
28
+
29
+ if (this.ids.has(entity.id)) {
30
+ this.store = this.store.map((item) => {
31
+ if (item.id === entity.id) {
32
+ return entity;
33
+ }
34
+ return item;
35
+ });
36
+ } else {
37
+ this.store.push(entity);
38
+ this.ids.set(entity.id, true);
39
+ }
40
+ }
41
+
42
+ public async getById(id: string): Promise<T | null> {
43
+ return this.store.find(item => item.id === id) || null;
44
+ }
45
+
46
+ public async getAll(options: { filter?: string; order?: OrderOption<T> } = {}): Promise<T[]> {
47
+ const filter = nql(options.filter);
48
+
49
+ const results = this.store.slice().filter(item => filter.queryJSON(this.toPrimitive(item)));
50
+
51
+ if (options.order) {
52
+ for (const order of options.order) {
53
+ results.sort((a, b) => {
54
+ if (order.direction === 'asc') {
55
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
56
+ return a[order.field] as any > (b[order.field] as any) ? 1 : -1;
57
+ } else {
58
+ return a[order.field] < b[order.field] ? 1 : -1;
59
+ }
60
+ });
61
+ }
62
+ }
63
+
64
+ return results;
65
+ }
66
+
67
+ public async getPage(options: { filter?: string; page: number; limit: number; order?: Order<T>[] } = {page: 1, limit: 15}): Promise<T[]> {
68
+ const results = await this.getAll(options);
69
+
70
+ const start = (options.page - 1) * options.limit;
71
+ const end = start + options.limit;
72
+
73
+ return results.slice(start, end);
74
+ }
75
+
76
+ public async getCount(options: { filter?: string }): Promise<number> {
77
+ const results = await this.getAll(options);
78
+ return results.length;
79
+ }
80
+ }