ghost 5.88.3 → 5.89.1

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 (184) hide show
  1. package/components/tryghost-adapter-cache-memory-ttl-5.89.1.tgz +0 -0
  2. package/components/tryghost-adapter-cache-redis-5.89.1.tgz +0 -0
  3. package/components/tryghost-adapter-manager-5.89.1.tgz +0 -0
  4. package/components/tryghost-announcement-bar-settings-5.89.1.tgz +0 -0
  5. package/components/tryghost-api-framework-5.89.1.tgz +0 -0
  6. package/components/tryghost-api-version-compatibility-service-5.89.1.tgz +0 -0
  7. package/components/tryghost-audience-feedback-5.89.1.tgz +0 -0
  8. package/components/tryghost-bookshelf-repository-5.89.1.tgz +0 -0
  9. package/components/tryghost-bootstrap-socket-5.89.1.tgz +0 -0
  10. package/components/tryghost-collections-5.89.1.tgz +0 -0
  11. package/components/tryghost-constants-5.89.1.tgz +0 -0
  12. package/components/tryghost-custom-theme-settings-service-5.89.1.tgz +0 -0
  13. package/components/{tryghost-data-generator-5.88.3.tgz → tryghost-data-generator-5.89.1.tgz} +0 -0
  14. package/components/tryghost-domain-events-5.89.1.tgz +0 -0
  15. package/components/tryghost-donations-5.89.1.tgz +0 -0
  16. package/components/tryghost-dynamic-routing-events-5.89.1.tgz +0 -0
  17. package/components/{tryghost-email-addresses-5.88.3.tgz → tryghost-email-addresses-5.89.1.tgz} +0 -0
  18. package/components/tryghost-email-analytics-provider-mailgun-5.89.1.tgz +0 -0
  19. package/components/tryghost-email-analytics-service-5.89.1.tgz +0 -0
  20. package/components/tryghost-email-content-generator-5.89.1.tgz +0 -0
  21. package/components/tryghost-email-events-5.89.1.tgz +0 -0
  22. package/components/{tryghost-email-service-5.88.3.tgz → tryghost-email-service-5.89.1.tgz} +0 -0
  23. package/components/tryghost-email-suppression-list-5.89.1.tgz +0 -0
  24. package/components/tryghost-express-dynamic-redirects-5.89.1.tgz +0 -0
  25. package/components/tryghost-external-media-inliner-5.89.1.tgz +0 -0
  26. package/components/tryghost-extract-api-key-5.89.1.tgz +0 -0
  27. package/components/tryghost-ghost-5.89.1.tgz +0 -0
  28. package/components/tryghost-html-to-plaintext-5.89.1.tgz +0 -0
  29. package/components/tryghost-i18n-5.89.1.tgz +0 -0
  30. package/components/tryghost-importer-handler-content-files-5.89.1.tgz +0 -0
  31. package/components/tryghost-importer-revue-5.89.1.tgz +0 -0
  32. package/components/tryghost-in-memory-repository-5.89.1.tgz +0 -0
  33. package/components/tryghost-job-manager-5.89.1.tgz +0 -0
  34. package/components/tryghost-link-redirects-5.89.1.tgz +0 -0
  35. package/components/tryghost-link-replacer-5.89.1.tgz +0 -0
  36. package/components/tryghost-link-tracking-5.89.1.tgz +0 -0
  37. package/components/tryghost-magic-link-5.89.1.tgz +0 -0
  38. package/components/tryghost-mail-events-5.89.1.tgz +0 -0
  39. package/components/tryghost-mailgun-client-5.89.1.tgz +0 -0
  40. package/components/tryghost-member-attribution-5.89.1.tgz +0 -0
  41. package/components/tryghost-member-events-5.89.1.tgz +0 -0
  42. package/components/tryghost-members-api-5.89.1.tgz +0 -0
  43. package/components/tryghost-members-csv-5.89.1.tgz +0 -0
  44. package/components/tryghost-members-events-service-5.89.1.tgz +0 -0
  45. package/components/{tryghost-members-importer-5.88.3.tgz → tryghost-members-importer-5.89.1.tgz} +0 -0
  46. package/components/tryghost-members-offers-5.89.1.tgz +0 -0
  47. package/components/tryghost-members-payments-5.89.1.tgz +0 -0
  48. package/components/tryghost-members-ssr-5.89.1.tgz +0 -0
  49. package/components/tryghost-members-stripe-service-5.89.1.tgz +0 -0
  50. package/components/tryghost-mentions-email-report-5.89.1.tgz +0 -0
  51. package/components/tryghost-milestones-5.89.1.tgz +0 -0
  52. package/components/tryghost-minifier-5.89.1.tgz +0 -0
  53. package/components/tryghost-model-to-domain-event-interceptor-5.89.1.tgz +0 -0
  54. package/components/tryghost-mw-api-version-mismatch-5.89.1.tgz +0 -0
  55. package/components/tryghost-mw-cache-control-5.89.1.tgz +0 -0
  56. package/components/tryghost-mw-error-handler-5.89.1.tgz +0 -0
  57. package/components/tryghost-mw-session-from-token-5.89.1.tgz +0 -0
  58. package/components/tryghost-mw-update-user-last-seen-5.89.1.tgz +0 -0
  59. package/components/tryghost-mw-version-match-5.89.1.tgz +0 -0
  60. package/components/tryghost-mw-vhost-5.89.1.tgz +0 -0
  61. package/components/tryghost-nql-filter-expansions-5.89.1.tgz +0 -0
  62. package/components/tryghost-oembed-service-5.89.1.tgz +0 -0
  63. package/components/tryghost-package-json-5.89.1.tgz +0 -0
  64. package/components/tryghost-post-events-5.89.1.tgz +0 -0
  65. package/components/{tryghost-post-revisions-5.88.3.tgz → tryghost-post-revisions-5.89.1.tgz} +0 -0
  66. package/components/tryghost-posts-service-5.89.1.tgz +0 -0
  67. package/components/tryghost-recommendations-5.89.1.tgz +0 -0
  68. package/components/tryghost-referrers-5.89.1.tgz +0 -0
  69. package/components/tryghost-security-5.89.1.tgz +0 -0
  70. package/components/tryghost-session-service-5.89.1.tgz +0 -0
  71. package/components/tryghost-settings-path-manager-5.89.1.tgz +0 -0
  72. package/components/tryghost-slack-notifications-5.89.1.tgz +0 -0
  73. package/components/tryghost-staff-service-5.89.1.tgz +0 -0
  74. package/components/tryghost-stats-service-5.89.1.tgz +0 -0
  75. package/components/tryghost-tiers-5.89.1.tgz +0 -0
  76. package/components/tryghost-update-check-service-5.89.1.tgz +0 -0
  77. package/components/tryghost-verification-trigger-5.89.1.tgz +0 -0
  78. package/components/tryghost-version-notifications-data-service-5.89.1.tgz +0 -0
  79. package/components/tryghost-webmentions-5.89.1.tgz +0 -0
  80. package/core/built/admin/assets/admin-x-activitypub/admin-x-activitypub.js +2 -2
  81. package/core/built/admin/assets/admin-x-activitypub/{index-d7494526.mjs → index-980aeac1.mjs} +3107 -3030
  82. package/core/built/admin/assets/admin-x-activitypub/{modals-8098b85c.mjs → modals-e013f67b.mjs} +182 -191
  83. package/core/built/admin/assets/admin-x-demo/admin-x-demo.js +2 -2
  84. package/core/built/admin/assets/admin-x-demo/{index-5e68f89b.mjs → index-71687654.mjs} +801 -796
  85. package/core/built/admin/assets/admin-x-demo/{modals-f789a6c4.mjs → modals-4b59bbd8.mjs} +2 -2
  86. package/core/built/admin/assets/admin-x-settings/{CodeEditorView-3601b44e.mjs → CodeEditorView-8dcd0ded.mjs} +2 -2
  87. package/core/built/admin/assets/admin-x-settings/admin-x-settings.js +2 -2
  88. package/core/built/admin/assets/admin-x-settings/{index-e7c4aa3c.mjs → index-01e25660.mjs} +2527 -2522
  89. package/core/built/admin/assets/admin-x-settings/{index-0b24e982.mjs → index-541636a3.mjs} +2365 -2272
  90. package/core/built/admin/assets/admin-x-settings/{modals-f8ab7cf2.mjs → modals-172c4d1c.mjs} +732 -726
  91. package/core/built/admin/assets/{chunk.42.0879e40a4de3db25b177.js → chunk.42.a0b3ca84230d788d0e11.js} +209 -196
  92. package/core/built/admin/assets/{chunk.524.4004209e970256976de7.js → chunk.524.e09e59707739cbab5488.js} +5 -5
  93. package/core/built/admin/assets/{chunk.582.eab996a9d6616a80727a.js → chunk.582.8aa2a0331d317e552bbe.js} +6 -6
  94. package/core/built/admin/assets/codemirror/{codemirror-98996fc475bb3df2b1b82dd701d32bc0.js → codemirror-91774021e5e17ea08db5cd2ed9f3e664.js} +5 -5
  95. package/core/built/admin/assets/{ghost-cb98187b163a0d8b42d752ab890e039a.css → ghost-87438e5801b7bb0f2e3497a68572a529.css} +1 -1
  96. package/core/built/admin/assets/{ghost-a9fa385e2a92cc3686349b2dea0249d2.js → ghost-b5e602d62644bd997ce54c647953f437.js} +154 -142
  97. package/core/built/admin/assets/{ghost-dark-0d78b0a11f5c2604992de20c1bfe396f.css → ghost-dark-f0b3a9ea961171ad4f736edbab905a0c.css} +1 -1
  98. package/core/built/admin/assets/{vendor-051d43ec47258b77ffd2fcc21a6d8c50.js → vendor-35f20b2f9b6201dcd4a00c8acac98aa6.js} +9 -9
  99. package/core/built/admin/index.html +6 -6
  100. package/core/frontend/meta/blog-logo.js +1 -1
  101. package/core/frontend/services/rss/renderer.js +1 -1
  102. package/core/server/data/migrations/versions/5.89/2024-07-30-19-51-06-backfill-offer-redemptions.js +64 -0
  103. package/core/server/lib/image/BlogIcon.js +13 -5
  104. package/core/server/services/members/middleware.js +1 -1
  105. package/core/server/services/slack.js +3 -3
  106. package/core/server/services/staff/index.js +2 -0
  107. package/core/shared/config/env/config.development.json +12 -0
  108. package/package.json +168 -168
  109. package/yarn.lock +963 -1076
  110. package/components/tryghost-adapter-cache-memory-ttl-5.88.3.tgz +0 -0
  111. package/components/tryghost-adapter-cache-redis-5.88.3.tgz +0 -0
  112. package/components/tryghost-adapter-manager-5.88.3.tgz +0 -0
  113. package/components/tryghost-announcement-bar-settings-5.88.3.tgz +0 -0
  114. package/components/tryghost-api-framework-5.88.3.tgz +0 -0
  115. package/components/tryghost-api-version-compatibility-service-5.88.3.tgz +0 -0
  116. package/components/tryghost-audience-feedback-5.88.3.tgz +0 -0
  117. package/components/tryghost-bookshelf-repository-5.88.3.tgz +0 -0
  118. package/components/tryghost-bootstrap-socket-5.88.3.tgz +0 -0
  119. package/components/tryghost-collections-5.88.3.tgz +0 -0
  120. package/components/tryghost-constants-5.88.3.tgz +0 -0
  121. package/components/tryghost-custom-theme-settings-service-5.88.3.tgz +0 -0
  122. package/components/tryghost-domain-events-5.88.3.tgz +0 -0
  123. package/components/tryghost-donations-5.88.3.tgz +0 -0
  124. package/components/tryghost-dynamic-routing-events-5.88.3.tgz +0 -0
  125. package/components/tryghost-email-analytics-provider-mailgun-5.88.3.tgz +0 -0
  126. package/components/tryghost-email-analytics-service-5.88.3.tgz +0 -0
  127. package/components/tryghost-email-content-generator-5.88.3.tgz +0 -0
  128. package/components/tryghost-email-events-5.88.3.tgz +0 -0
  129. package/components/tryghost-email-suppression-list-5.88.3.tgz +0 -0
  130. package/components/tryghost-express-dynamic-redirects-5.88.3.tgz +0 -0
  131. package/components/tryghost-external-media-inliner-5.88.3.tgz +0 -0
  132. package/components/tryghost-extract-api-key-5.88.3.tgz +0 -0
  133. package/components/tryghost-ghost-5.88.3.tgz +0 -0
  134. package/components/tryghost-html-to-plaintext-5.88.3.tgz +0 -0
  135. package/components/tryghost-i18n-5.88.3.tgz +0 -0
  136. package/components/tryghost-importer-handler-content-files-5.88.3.tgz +0 -0
  137. package/components/tryghost-importer-revue-5.88.3.tgz +0 -0
  138. package/components/tryghost-in-memory-repository-5.88.3.tgz +0 -0
  139. package/components/tryghost-job-manager-5.88.3.tgz +0 -0
  140. package/components/tryghost-link-redirects-5.88.3.tgz +0 -0
  141. package/components/tryghost-link-replacer-5.88.3.tgz +0 -0
  142. package/components/tryghost-link-tracking-5.88.3.tgz +0 -0
  143. package/components/tryghost-magic-link-5.88.3.tgz +0 -0
  144. package/components/tryghost-mail-events-5.88.3.tgz +0 -0
  145. package/components/tryghost-mailgun-client-5.88.3.tgz +0 -0
  146. package/components/tryghost-member-attribution-5.88.3.tgz +0 -0
  147. package/components/tryghost-member-events-5.88.3.tgz +0 -0
  148. package/components/tryghost-members-api-5.88.3.tgz +0 -0
  149. package/components/tryghost-members-csv-5.88.3.tgz +0 -0
  150. package/components/tryghost-members-events-service-5.88.3.tgz +0 -0
  151. package/components/tryghost-members-offers-5.88.3.tgz +0 -0
  152. package/components/tryghost-members-payments-5.88.3.tgz +0 -0
  153. package/components/tryghost-members-ssr-5.88.3.tgz +0 -0
  154. package/components/tryghost-members-stripe-service-5.88.3.tgz +0 -0
  155. package/components/tryghost-mentions-email-report-5.88.3.tgz +0 -0
  156. package/components/tryghost-milestones-5.88.3.tgz +0 -0
  157. package/components/tryghost-minifier-5.88.3.tgz +0 -0
  158. package/components/tryghost-model-to-domain-event-interceptor-5.88.3.tgz +0 -0
  159. package/components/tryghost-mw-api-version-mismatch-5.88.3.tgz +0 -0
  160. package/components/tryghost-mw-cache-control-5.88.3.tgz +0 -0
  161. package/components/tryghost-mw-error-handler-5.88.3.tgz +0 -0
  162. package/components/tryghost-mw-session-from-token-5.88.3.tgz +0 -0
  163. package/components/tryghost-mw-update-user-last-seen-5.88.3.tgz +0 -0
  164. package/components/tryghost-mw-version-match-5.88.3.tgz +0 -0
  165. package/components/tryghost-mw-vhost-5.88.3.tgz +0 -0
  166. package/components/tryghost-nql-filter-expansions-5.88.3.tgz +0 -0
  167. package/components/tryghost-oembed-service-5.88.3.tgz +0 -0
  168. package/components/tryghost-package-json-5.88.3.tgz +0 -0
  169. package/components/tryghost-post-events-5.88.3.tgz +0 -0
  170. package/components/tryghost-posts-service-5.88.3.tgz +0 -0
  171. package/components/tryghost-recommendations-5.88.3.tgz +0 -0
  172. package/components/tryghost-referrers-5.88.3.tgz +0 -0
  173. package/components/tryghost-security-5.88.3.tgz +0 -0
  174. package/components/tryghost-session-service-5.88.3.tgz +0 -0
  175. package/components/tryghost-settings-path-manager-5.88.3.tgz +0 -0
  176. package/components/tryghost-slack-notifications-5.88.3.tgz +0 -0
  177. package/components/tryghost-staff-service-5.88.3.tgz +0 -0
  178. package/components/tryghost-stats-service-5.88.3.tgz +0 -0
  179. package/components/tryghost-tiers-5.88.3.tgz +0 -0
  180. package/components/tryghost-update-check-service-5.88.3.tgz +0 -0
  181. package/components/tryghost-verification-trigger-5.88.3.tgz +0 -0
  182. package/components/tryghost-version-notifications-data-service-5.88.3.tgz +0 -0
  183. package/components/tryghost-webmentions-5.88.3.tgz +0 -0
  184. /package/core/built/admin/assets/{chunk.42.0879e40a4de3db25b177.js.LICENSE.txt → chunk.42.a0b3ca84230d788d0e11.js.LICENSE.txt} +0 -0
@@ -712,7 +712,7 @@ return{named:new Proxy(c,a),positional:new Proxy([],l)}}:(e,t)=>{var{named:r,pos
712
712
  Object.defineProperty(o,n.CUSTOM_TAG_FOR,{configurable:!1,enumerable:!1,value:e=>G(r,e)}),Object.keys(r).forEach((e=>{Object.defineProperty(o,e,{enumerable:!0,configurable:!0,get:()=>(0,u.valueForRef)(r[e])})}))
713
713
  var s=[]
714
714
  return Object.defineProperty(s,n.CUSTOM_TAG_FOR,{configurable:!1,enumerable:!1,value:e=>Y(i,e)}),i.forEach(((e,t)=>{Object.defineProperty(s,t,{enumerable:!0,configurable:!0,get:()=>(0,u.valueForRef)(e)})})),{named:o,positional:s}}
715
- function X(e){return(0,d.getValue)(e.argsCache)}class Z{constructor(e,t=(()=>c.EMPTY_ARGS)){var r=(0,d.createCache)((()=>t(e)))
715
+ function X(e){return(0,d.getValue)(e.argsCache)}class Z{constructor(e,t=()=>c.EMPTY_ARGS){var r=(0,d.createCache)((()=>t(e)))
716
716
  this.argsCache=r}get named(){return X(this).named||c.EMPTY_NAMED}get positional(){return X(this).positional||c.EMPTY_POSITIONAL}}var ee=(0,s.symbol)("RECOMPUTE_TAG"),te=new b._WeakSet
717
717
  function re(e){return te.has(e)}var ne=e.Helper=o.FrameworkObject.extend({init(){this._super(...arguments),this[ee]=(0,d.createTag)()},recompute(){(0,g.join)((()=>(0,d.dirtyTag)(this[ee])))}})
718
718
  ne.isHelperFactory=!0
@@ -3085,7 +3085,7 @@ if(void 0!==r&&d(r,n))N(r)
3085
3085
  else{R()
3086
3086
  try{e[F]=t()}finally{r=j(),e[z]=r,e[B]=c(r),N(r)}}return e[F]},e.isConst=function(e){H(e,"isConst")
3087
3087
  var t=e[z]
3088
- return function(e,t){0}(),v(t)},e.isConstTag=v,e.isTracking=function(){return null!==S},e.logTrackingStack=void 0,e.resetTracking=function(){for(;A.length>0;)A.pop()
3088
+ return function(){0}(),v(t)},e.isConstTag=v,e.isTracking=function(){return null!==S},e.logTrackingStack=void 0,e.resetTracking=function(){for(;A.length>0;)A.pop()
3089
3089
  S=null,!1},e.setTrackingTransactionEnv=e.runInTrackingTransaction=void 0,e.tagFor=T,e.tagMetaFor=P,e.track=function(e,t){var r
3090
3090
  R(t)
3091
3091
  try{e()}finally{r=j()}return r},e.trackedData=function(e,t){var r=new WeakMap,n="function"==typeof t
@@ -6090,14 +6090,14 @@ Object.keys(r).forEach((n=>{r[n].type&&e.call(t,n,r[n])}))}}function et(e,t,r,n,
6090
6090
  if(void 0===l)throw new Error("adapter.findMany returned undefined, this was very likely a mistake")
6091
6091
  return(l=U(l,t,u)).then((e=>{var n=$(t.serializerFor(r),t,a,e,null,"findMany")
6092
6092
  return t._push(n)}),null,`DS: Extract payload of ${r}`)}function tt(e,t,r,n){var i,o,s=(i=t.data,o=(t,i)=>{var{id:o,type:s}=t
6093
- return function(e,t,r,n,i){var{id:o,type:s}=e
6093
+ return function(e,t,r,n){var{id:i,type:o}=e
6094
6094
  e.relationships||(e.relationships={})
6095
- var{relationships:a}=e,l=function(e,t,r,n){return function({_storeWrapper:e},t,r,n){var{name:i}=r,{modelName:o}=t,s=e.inverseForRelationship(o,i)
6095
+ var{relationships:s}=e,a=function(e,t,r,n){return function({_storeWrapper:e},t,r,n){var{name:i}=r,{modelName:o}=t,s=e.inverseForRelationship(o,i)
6096
6096
  if(s){var{meta:{kind:a}}=e.relationshipsDefinitionFor(n)[s]
6097
- return{inverseKey:s,kind:a}}}(e,t,r,n)}(r,t,n,s)
6098
- if(l){var{inverseKey:u,kind:c}=l,d=a[u]&&a[u].data
6099
- "hasMany"===c&&void 0===d||(a[u]=a[u]||{},a[u].data=function(e,t,{id:r,modelName:n}){var i,o={id:r,type:n}
6100
- return"hasMany"===t?(i=e||[]).push(o):(i=e||{},Ember.assign(i,o)),i}(d,c,t))}}(t,r,e,n),{id:o,type:s}},Array.isArray(i)?i.map(o):o(i)),a={id:r.id,type:r.modelName,relationships:{[n.key]:{meta:t.meta,links:t.links,data:s}}}
6097
+ return{inverseKey:s,kind:a}}}(e,t,r,n)}(r,t,n,o)
6098
+ if(a){var{inverseKey:l,kind:u}=a,c=s[l]&&s[l].data
6099
+ "hasMany"===u&&void 0===c||(s[l]=s[l]||{},s[l].data=function(e,t,{id:r,modelName:n}){var i,o={id:r,type:n}
6100
+ return"hasMany"===t?(i=e||[]).push(o):(i=e||{},Ember.assign(i,o)),i}(c,u,t))}}(t,r,e,n),{id:o,type:s}},Array.isArray(i)?i.map(o):o(i)),a={id:r.id,type:r.modelName,relationships:{[n.key]:{meta:t.meta,links:t.links,data:s}}}
6101
6101
  return Array.isArray(t.included)||(t.included=[]),t.included.push(a),t}function rt(e,t,r,n){var i=t.modelFor(r),o=t.peekAll(r),s=o._createSnapshot(n),a=Ember.RSVP.Promise.resolve().then((()=>e.findAll(t,i,null,s)))
6102
6102
  return(a=U(a,t,"DS: Handle Adapter#findAll of "+i)).then((e=>{var n=$(t.serializerFor(r),t,i,e,null,"findAll")
6103
6103
  return t._push(n),t._didUpdateAll(r),o}),null,"DS: Extract payload of findAll ${modelName}")}var nt,it=a("DEBUG-ts-brand")
@@ -9514,4 +9514,4 @@ e.default=class{constructor(e){if(this._data=new t.default,e)for(let t=0;t<e.len
9514
9514
  return this}get(e){let t=this._data[e]
9515
9515
  return t===r.UNDEFINED_KEY?void 0:t}set(e,t){return this._data[e]=t,this}delete(e){return this._data[e]=r.UNDEFINED_KEY,!0}}}))
9516
9516
 
9517
- //# sourceMappingURL=vendor-1a4f8a4af6641461dc52cf7021eddd2f.map
9517
+ //# sourceMappingURL=vendor-bb6b765916d677a72aa5ce778360bb62.map
@@ -8,7 +8,7 @@
8
8
  <title>Ghost Admin</title>
9
9
 
10
10
 
11
- <meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%22%2C%22cdnUrl%22%3A%22%22%2C%22editorUrl%22%3A%22%22%2C%22rootURL%22%3A%22%22%2C%22locationType%22%3A%22trailing-hash%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%2C%22Array%22%3Atrue%2C%22String%22%3Atrue%2C%22Function%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_JQUERY_INTEGRATION%22%3Atrue%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%225.88%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22%40sentry%2Fember%22%3A%7B%22disablePerformance%22%3Atrue%2C%22sentry%22%3A%7B%7D%7D%2C%22ember-cli-mirage%22%3A%7B%22usingProxy%22%3Afalse%2C%22useDefaultPassthroughs%22%3Atrue%7D%2C%22exportApplicationGlobal%22%3Afalse%2C%22ember-load%22%3A%7B%22loadingIndicatorClass%22%3A%22ember-load-indicator%22%7D%2C%22editorFilename%22%3A%22koenig-lexical.umd.js%22%2C%22editorHash%22%3A%22eac6431ceb%22%2C%22adminXDemoFilename%22%3A%22admin-x-demo.js%22%2C%22adminXDemoHash%22%3A%22714b89ba9e%22%2C%22adminXSettingsFilename%22%3A%22admin-x-settings.js%22%2C%22adminXSettingsHash%22%3A%22452dba3a8c%22%2C%22adminXActivitypubFilename%22%3A%22admin-x-activitypub.js%22%2C%22adminXActivitypubHash%22%3A%22f3467942d6%22%7D" />
11
+ <meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%22%2C%22cdnUrl%22%3A%22%22%2C%22editorUrl%22%3A%22%22%2C%22rootURL%22%3A%22%22%2C%22locationType%22%3A%22trailing-hash%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%2C%22Array%22%3Atrue%2C%22String%22%3Atrue%2C%22Function%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_JQUERY_INTEGRATION%22%3Atrue%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%225.89%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22%40sentry%2Fember%22%3A%7B%22disablePerformance%22%3Atrue%2C%22sentry%22%3A%7B%7D%7D%2C%22ember-cli-mirage%22%3A%7B%22usingProxy%22%3Afalse%2C%22useDefaultPassthroughs%22%3Atrue%7D%2C%22exportApplicationGlobal%22%3Afalse%2C%22ember-load%22%3A%7B%22loadingIndicatorClass%22%3A%22ember-load-indicator%22%7D%2C%22editorFilename%22%3A%22koenig-lexical.umd.js%22%2C%22editorHash%22%3A%22eac6431ceb%22%2C%22adminXDemoFilename%22%3A%22admin-x-demo.js%22%2C%22adminXDemoHash%22%3A%22a9802a6502%22%2C%22adminXSettingsFilename%22%3A%22admin-x-settings.js%22%2C%22adminXSettingsHash%22%3A%220ba469b121%22%2C%22adminXActivitypubFilename%22%3A%22admin-x-activitypub.js%22%2C%22adminXActivitypubHash%22%3A%222f4784ce5f%22%7D" />
12
12
 
13
13
  <meta name="HandheldFriendly" content="True" />
14
14
  <meta name="MobileOptimized" content="320" />
@@ -37,7 +37,7 @@
37
37
  </style>
38
38
 
39
39
  <link integrity="" rel="stylesheet" href="assets/vendor-0ede59da8efb5e28fa929557f7ff7154.css">
40
- <link integrity="" rel="stylesheet" href="assets/ghost-cb98187b163a0d8b42d752ab890e039a.css" title="light">
40
+ <link integrity="" rel="stylesheet" href="assets/ghost-87438e5801b7bb0f2e3497a68572a529.css" title="light">
41
41
 
42
42
 
43
43
  </head>
@@ -56,9 +56,9 @@
56
56
 
57
57
  <div id="ember-basic-dropdown-wormhole"></div>
58
58
 
59
- <script src="assets/vendor-051d43ec47258b77ffd2fcc21a6d8c50.js"></script>
60
- <script src="assets/chunk.42.0879e40a4de3db25b177.js"></script>
61
- <script src="assets/chunk.524.4004209e970256976de7.js"></script>
62
- <script src="assets/ghost-a9fa385e2a92cc3686349b2dea0249d2.js"></script>
59
+ <script src="assets/vendor-35f20b2f9b6201dcd4a00c8acac98aa6.js"></script>
60
+ <script src="assets/chunk.42.a0b3ca84230d788d0e11.js"></script>
61
+ <script src="assets/chunk.524.e09e59707739cbab5488.js"></script>
62
+ <script src="assets/ghost-b5e602d62644bd997ce54c647953f437.js"></script>
63
63
  </body>
64
64
  </html>
@@ -11,7 +11,7 @@ function getBlogLogo() {
11
11
  // CASE: no publication logo is updated. We can try to use either an uploaded publication icon
12
12
  // or use the default one to make
13
13
  // Google happy with it. See https://github.com/TryGhost/Ghost/issues/7558
14
- logo.url = blogIcon.getIconUrl(true);
14
+ logo.url = blogIcon.getIconUrl({absolute: true});
15
15
  }
16
16
 
17
17
  return logo;
@@ -9,7 +9,7 @@ module.exports.render = function render(res, baseUrl, data) {
9
9
  return rssCache
10
10
  .getXML(baseUrl, rssData)
11
11
  .then(function then(feedXml) {
12
- res.set('Content-Type', 'text/xml; charset=UTF-8');
12
+ res.set('Content-Type', 'application/rss+xml; charset=UTF-8');
13
13
  res.send(feedXml);
14
14
  });
15
15
  };
@@ -0,0 +1,64 @@
1
+ // For information on writing migrations, see https://www.notion.so/ghost/Database-migrations-eb5b78c435d741d2b34a582d57c24253
2
+
3
+ const logging = require('@tryghost/logging');
4
+ const DatabaseInfo = require('@tryghost/database-info');
5
+ const {default: ObjectID} = require('bson-objectid');
6
+
7
+ // For DML - data changes
8
+ const {createTransactionalMigration} = require('../../utils');
9
+
10
+ module.exports = createTransactionalMigration(
11
+ async function up(knex) {
12
+ // Backfill missing offer redemptions
13
+ try {
14
+ // Select all subscriptions that have an `offer_id` but don't have a matching row in the `offer_redemptions` table
15
+ logging.info('Selecting subscriptions with missing offer redemptions');
16
+ const result = await knex.raw(`
17
+ SELECT
18
+ mscs.id AS subscription_id,
19
+ mscs.offer_id,
20
+ mscs.start_date AS created_at,
21
+ m.id AS member_id
22
+ FROM
23
+ members_stripe_customers_subscriptions mscs
24
+ LEFT JOIN
25
+ offer_redemptions r ON r.subscription_id = mscs.id
26
+ INNER JOIN
27
+ members_stripe_customers msc ON mscs.customer_id = msc.customer_id
28
+ INNER JOIN
29
+ members m ON msc.member_id = m.id
30
+ WHERE
31
+ mscs.offer_id IS NOT NULL and r.id IS NULL;
32
+ `);
33
+
34
+ // knex.raw() returns a different result depending on the database. We need to handle either case
35
+ let rows = [];
36
+ if (DatabaseInfo.isSQLite(knex)) {
37
+ rows = result;
38
+ } else {
39
+ rows = result[0];
40
+ }
41
+
42
+ // Do the backfil
43
+ if (rows && rows.length > 0) {
44
+ logging.info(`Backfilling ${rows.length} offer redemptions`);
45
+ // Generate IDs for each row
46
+ const offerRedemptions = rows.map((row) => {
47
+ return {
48
+ id: (new ObjectID()).toHexString(),
49
+ ...row
50
+ };
51
+ });
52
+ // Batch insert rows into the offer_redemptions table
53
+ await knex.batchInsert('offer_redemptions', offerRedemptions, 1000);
54
+ } else {
55
+ logging.info('No offer redemptions to backfill');
56
+ }
57
+ } catch (error) {
58
+ logging.error(`Error backfilling offer redemptions: ${error.message}`);
59
+ }
60
+ },
61
+ async function down() {
62
+ // We don't want to un-backfill data, so do nothing here.
63
+ }
64
+ );
@@ -98,13 +98,17 @@ class BlogIcon {
98
98
  }
99
99
 
100
100
  /**
101
- * Return URL for Blog icon: [subdirectory or not]favicon.[ico, jpeg, or png]
102
- * Always returns {string} getIconUrl
103
- * @returns {string} [subdirectory or not]favicon.[ico, jpeg, or png]
101
+ * Return URL for blog icon, if available: [subdirectory or not]favicon.[ico, jpeg, or png]
102
+ * Otherwise, fallbacks to the default Ghost favicon.ico file, if requested
103
+ * Otherwise, returns null
104
+ * @param {Object} [options]
105
+ * @param {boolean} [options.absolute] - if true, return absolute URL. Default: false
106
+ * @param {boolean} [options.fallbackToDefault] - if true, fallbacks to Ghost's default favicon.ico when no blog icon is found. Default: true
107
+ * @returns {string|null} [subdirectory or not]favicon.[ico, jpeg, or png] or null
104
108
  * @description Checks if we have a custom uploaded icon and the extension of it. If no custom uploaded icon
105
109
  * exists, we're returning the default `favicon.ico`
106
110
  */
107
- getIconUrl(absolute) {
111
+ getIconUrl({absolute = false, fallbackToDefault = true} = {}) {
108
112
  const blogIcon = this.settingsCache.get('icon');
109
113
 
110
114
  if (blogIcon) {
@@ -124,9 +128,13 @@ class BlogIcon {
124
128
 
125
129
  const sizedIcon = blogIcon.replace(/\/content\/images\//, '/content/images/size/w256h256/');
126
130
  return this.urlUtils.urlFor({relativeUrl: sizedIcon}, absolute ? true : undefined);
127
- } else {
131
+ }
132
+
133
+ if (fallbackToDefault) {
128
134
  return this.urlUtils.urlFor({relativeUrl: '/favicon.ico'}, absolute ? true : undefined);
129
135
  }
136
+
137
+ return null;
130
138
  }
131
139
 
132
140
  /**
@@ -110,7 +110,7 @@ const authMemberByUuid = async function authMemberByUuid(req, res, next) {
110
110
  }
111
111
 
112
112
  throw new errors.UnauthorizedError({
113
- messsage: tpl(messages.missingUuid)
113
+ message: tpl(messages.missingUuid)
114
114
  });
115
115
  }
116
116
 
@@ -110,7 +110,7 @@ function ping(post) {
110
110
  // if it is a post or a test message to check webhook working.
111
111
  text: `Notification from *${blogTitle}* :ghost:`,
112
112
  unfurl_links: true,
113
- icon_url: blogIcon.getIconUrl(true),
113
+ icon_url: blogIcon.getIconUrl({absolute: true}),
114
114
  username: slackSettings.username,
115
115
  // We don't want to send attachment if it is a test notification.
116
116
  attachments: [
@@ -141,7 +141,7 @@ function ping(post) {
141
141
  }
142
142
  ],
143
143
  footer: blogTitle,
144
- footer_icon: blogIcon.getIconUrl(true),
144
+ footer_icon: blogIcon.getIconUrl({absolute: true}),
145
145
  ts: moment().unix()
146
146
  }
147
147
  ]
@@ -150,7 +150,7 @@ function ping(post) {
150
150
  slackData = {
151
151
  text: message,
152
152
  unfurl_links: true,
153
- icon_url: blogIcon.getIconUrl(true),
153
+ icon_url: blogIcon.getIconUrl({absolute: true}),
154
154
  username: slackSettings.username
155
155
  };
156
156
  }
@@ -17,6 +17,7 @@ class StaffServiceWrapper {
17
17
  const mailer = new GhostMailer();
18
18
  const settingsCache = require('../../../shared/settings-cache');
19
19
  const urlUtils = require('../../../shared/url-utils');
20
+ const {blogIcon} = require('../../../server/lib/image');
20
21
  const settingsHelpers = require('../settings-helpers');
21
22
 
22
23
  this.api = new StaffService({
@@ -26,6 +27,7 @@ class StaffServiceWrapper {
26
27
  settingsHelpers,
27
28
  settingsCache,
28
29
  urlUtils,
30
+ blogIcon,
29
31
  DomainEvents,
30
32
  memberAttributionService: memberAttribution.service,
31
33
  labs
@@ -1,5 +1,17 @@
1
1
  {
2
2
  "url": "http://localhost:2368",
3
+ "mail": {
4
+ "from": "test@example.com",
5
+ "transport": "SMTP",
6
+ "options": {
7
+ "host": "127.0.0.1",
8
+ "port": 1025,
9
+ "auth": {
10
+ "user": "user",
11
+ "pass": "unsecure"
12
+ }
13
+ }
14
+ },
3
15
  "database": {
4
16
  "client": "sqlite3",
5
17
  "connection": {