ghost 5.38.0 → 5.40.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 (183) hide show
  1. package/components/{tryghost-adapter-cache-memory-ttl-5.38.0.tgz → tryghost-adapter-cache-memory-ttl-5.40.0.tgz} +0 -0
  2. package/components/tryghost-adapter-cache-redis-5.40.0.tgz +0 -0
  3. package/components/tryghost-adapter-manager-5.40.0.tgz +0 -0
  4. package/components/{tryghost-api-framework-5.38.0.tgz → tryghost-api-framework-5.40.0.tgz} +0 -0
  5. package/components/tryghost-api-version-compatibility-service-5.40.0.tgz +0 -0
  6. package/components/tryghost-audience-feedback-5.40.0.tgz +0 -0
  7. package/components/tryghost-bootstrap-socket-5.40.0.tgz +0 -0
  8. package/components/tryghost-constants-5.40.0.tgz +0 -0
  9. package/components/{tryghost-custom-theme-settings-service-5.38.0.tgz → tryghost-custom-theme-settings-service-5.40.0.tgz} +0 -0
  10. package/components/tryghost-data-generator-5.40.0.tgz +0 -0
  11. package/components/{tryghost-domain-events-5.38.0.tgz → tryghost-domain-events-5.40.0.tgz} +0 -0
  12. package/components/tryghost-dynamic-routing-events-5.40.0.tgz +0 -0
  13. package/components/tryghost-email-analytics-provider-mailgun-5.40.0.tgz +0 -0
  14. package/components/tryghost-email-analytics-service-5.40.0.tgz +0 -0
  15. package/components/tryghost-email-content-generator-5.40.0.tgz +0 -0
  16. package/components/tryghost-email-events-5.40.0.tgz +0 -0
  17. package/components/tryghost-email-service-5.40.0.tgz +0 -0
  18. package/components/{tryghost-email-suppression-list-5.38.0.tgz → tryghost-email-suppression-list-5.40.0.tgz} +0 -0
  19. package/components/tryghost-event-aware-cache-wrapper-5.40.0.tgz +0 -0
  20. package/components/{tryghost-express-dynamic-redirects-5.38.0.tgz → tryghost-express-dynamic-redirects-5.40.0.tgz} +0 -0
  21. package/components/tryghost-external-media-inliner-5.40.0.tgz +0 -0
  22. package/components/tryghost-extract-api-key-5.40.0.tgz +0 -0
  23. package/components/tryghost-html-to-plaintext-5.40.0.tgz +0 -0
  24. package/components/tryghost-i18n-5.40.0.tgz +0 -0
  25. package/components/tryghost-importer-handler-content-files-5.40.0.tgz +0 -0
  26. package/components/tryghost-importer-revue-5.40.0.tgz +0 -0
  27. package/components/tryghost-job-manager-5.40.0.tgz +0 -0
  28. package/components/tryghost-link-redirects-5.40.0.tgz +0 -0
  29. package/components/tryghost-link-replacer-5.40.0.tgz +0 -0
  30. package/components/{tryghost-link-tracking-5.38.0.tgz → tryghost-link-tracking-5.40.0.tgz} +0 -0
  31. package/components/tryghost-magic-link-5.40.0.tgz +0 -0
  32. package/components/tryghost-mailgun-client-5.40.0.tgz +0 -0
  33. package/components/tryghost-member-attribution-5.40.0.tgz +0 -0
  34. package/components/tryghost-member-events-5.40.0.tgz +0 -0
  35. package/components/tryghost-members-api-5.40.0.tgz +0 -0
  36. package/components/tryghost-members-csv-5.40.0.tgz +0 -0
  37. package/components/{tryghost-members-events-service-5.38.0.tgz → tryghost-members-events-service-5.40.0.tgz} +0 -0
  38. package/components/tryghost-members-importer-5.40.0.tgz +0 -0
  39. package/components/tryghost-members-offers-5.40.0.tgz +0 -0
  40. package/components/tryghost-members-payments-5.40.0.tgz +0 -0
  41. package/components/tryghost-members-ssr-5.40.0.tgz +0 -0
  42. package/components/tryghost-members-stripe-service-5.40.0.tgz +0 -0
  43. package/components/tryghost-mentions-email-report-5.40.0.tgz +0 -0
  44. package/components/tryghost-milestones-5.40.0.tgz +0 -0
  45. package/components/{tryghost-minifier-5.38.0.tgz → tryghost-minifier-5.40.0.tgz} +0 -0
  46. package/components/tryghost-mw-api-version-mismatch-5.40.0.tgz +0 -0
  47. package/components/{tryghost-mw-cache-control-5.38.0.tgz → tryghost-mw-cache-control-5.40.0.tgz} +0 -0
  48. package/components/tryghost-mw-error-handler-5.40.0.tgz +0 -0
  49. package/components/tryghost-mw-session-from-token-5.40.0.tgz +0 -0
  50. package/components/tryghost-mw-update-user-last-seen-5.40.0.tgz +0 -0
  51. package/components/{tryghost-mw-version-match-5.38.0.tgz → tryghost-mw-version-match-5.40.0.tgz} +0 -0
  52. package/components/tryghost-mw-vhost-5.40.0.tgz +0 -0
  53. package/components/tryghost-oembed-service-5.40.0.tgz +0 -0
  54. package/components/tryghost-package-json-5.40.0.tgz +0 -0
  55. package/components/tryghost-posts-service-5.40.0.tgz +0 -0
  56. package/components/tryghost-referrers-5.40.0.tgz +0 -0
  57. package/components/tryghost-security-5.40.0.tgz +0 -0
  58. package/components/tryghost-session-service-5.40.0.tgz +0 -0
  59. package/components/tryghost-settings-path-manager-5.40.0.tgz +0 -0
  60. package/components/tryghost-slack-notifications-5.40.0.tgz +0 -0
  61. package/components/tryghost-staff-service-5.40.0.tgz +0 -0
  62. package/components/tryghost-stats-service-5.40.0.tgz +0 -0
  63. package/components/tryghost-tiers-5.40.0.tgz +0 -0
  64. package/components/{tryghost-update-check-service-5.38.0.tgz → tryghost-update-check-service-5.40.0.tgz} +0 -0
  65. package/components/tryghost-verification-trigger-5.40.0.tgz +0 -0
  66. package/components/tryghost-version-notifications-data-service-5.40.0.tgz +0 -0
  67. package/components/tryghost-webmentions-5.40.0.tgz +0 -0
  68. package/core/boot.js +7 -0
  69. package/core/built/admin/assets/{chunk.143.c6802c882a911797ce4f.js → chunk.143.9e105aa0a9236484523a.js} +8 -8
  70. package/core/built/admin/assets/{chunk.178.09faefd4027fcba4113d.js → chunk.178.9b53f20952b9ae4763a2.js} +4 -4
  71. package/core/built/admin/assets/{chunk.220.9ca2950240aba3fced21.js → chunk.462.b66cfed1f66c8d2678b2.js} +9407 -9041
  72. package/core/built/admin/assets/chunk.808.2e76eb12fa4d7be8cb23.js +5 -0
  73. package/core/built/admin/assets/{ghost-35103ff053c43f1dfa7f35821c3c2412.js → ghost-467b96c17c6bc0d06fa88e85074fbecf.js} +299 -275
  74. package/core/built/admin/assets/ghost-68ea49029c6d45b4aa090f4e218917aa.css +1 -0
  75. package/core/built/admin/assets/ghost-dark-c9b38252afc29364507e8c92e4ba9933.css +1 -0
  76. package/core/built/admin/assets/img/latest-posts-1-ea1e669b275f2c7dfa23abd4be8d7ad5.png +0 -0
  77. package/core/built/admin/assets/img/latest-posts-2-e6b0809353ac31642839a6f3bab0d4e8.png +0 -0
  78. package/core/built/admin/assets/img/latest-posts-3-ac8c2e95dd9adecb9029a7b037ed7f15.png +0 -0
  79. package/core/built/admin/assets/{vendor-b982e3bf1020bff77b2a3c44d5f59e55.js → vendor-d08b4de6f990b9cd7b5a92d61952a5bb.js} +54 -49
  80. package/core/built/admin/index.html +6 -6
  81. package/core/frontend/meta/schema.js +4 -16
  82. package/core/server/api/endpoints/db.js +10 -2
  83. package/core/server/api/endpoints/members.js +8 -1
  84. package/core/server/api/endpoints/posts.js +30 -1
  85. package/core/server/api/endpoints/utils/serializers/output/mappers/emails.js +2 -1
  86. package/core/server/api/endpoints/utils/serializers/output/posts.js +5 -0
  87. package/core/server/data/importer/import-manager.js +3 -8
  88. package/core/server/data/migrations/versions/5.39/2023-03-13-09-29-add-newsletter-show-post-title-section.js +7 -0
  89. package/core/server/data/migrations/versions/5.39/2023-03-13-13-11-add-newsletter-show-comment-cta.js +7 -0
  90. package/core/server/data/migrations/versions/5.39/2023-03-13-14-30-add-newsletter-show-subscription-details.js +7 -0
  91. package/core/server/data/migrations/versions/5.39/2023-03-14-12-26-add-last-mentions-email-report-timestamp-setting.js +8 -0
  92. package/core/server/data/migrations/versions/5.40/2023-03-13-14-05-add-newsletter-show-latest-posts.js +7 -0
  93. package/core/server/data/migrations/versions/5.40/2023-03-21-18-42-add-self-serve-integration-role.js +31 -0
  94. package/core/server/data/migrations/versions/5.40/2023-03-21-18-43-add-self-serve-migration-and-permissions.js +25 -0
  95. package/core/server/data/migrations/versions/5.40/2023-03-21-18-52-add-self-serve-integration.js +37 -0
  96. package/core/server/data/migrations/versions/5.40/2023-03-21-19-02-add-self-serve-integration-api-key.js +72 -0
  97. package/core/server/data/schema/default-settings/default-settings.json +4 -0
  98. package/core/server/data/schema/fixtures/fixtures.json +21 -0
  99. package/core/server/data/schema/schema.js +4 -0
  100. package/core/server/lib/request-external.js +8 -4
  101. package/core/server/models/base/plugins/relations.js +22 -0
  102. package/core/server/models/base/plugins/sanitize.js +1 -1
  103. package/core/server/models/newsletter.js +4 -0
  104. package/core/server/services/email-service/wrapper.js +4 -1
  105. package/core/server/services/i18n.js +14 -0
  106. package/core/server/services/member-attribution/index.js +2 -1
  107. package/core/server/services/members/api.js +43 -42
  108. package/core/server/services/members/emails/signin.js +9 -9
  109. package/core/server/services/mentions/BookshelfMentionRepository.js +11 -0
  110. package/core/server/services/mentions/service.js +4 -0
  111. package/core/server/services/mentions-email-report/StartMentionEmailReportJob.js +16 -0
  112. package/core/server/services/mentions-email-report/index.js +1 -0
  113. package/core/server/services/mentions-email-report/job.js +11 -0
  114. package/core/server/services/mentions-email-report/service.js +162 -0
  115. package/core/server/services/milestones/BookshelfMilestoneRepository.js +18 -6
  116. package/core/server/services/milestones/service.js +17 -15
  117. package/core/server/services/posts/posts-service.js +22 -119
  118. package/core/server/services/public-config/config.js +1 -1
  119. package/core/server/services/slack-notifications/service.js +1 -2
  120. package/core/server/services/webhooks/trigger.js +2 -2
  121. package/core/server/web/api/endpoints/admin/routes.js +2 -1
  122. package/core/shared/config/defaults.json +3 -4
  123. package/core/shared/config/overrides.json +3 -1
  124. package/core/shared/labs.js +3 -4
  125. package/package.json +149 -142
  126. package/yarn.lock +3544 -1240
  127. package/components/tryghost-adapter-cache-redis-5.38.0.tgz +0 -0
  128. package/components/tryghost-adapter-manager-5.38.0.tgz +0 -0
  129. package/components/tryghost-api-version-compatibility-service-5.38.0.tgz +0 -0
  130. package/components/tryghost-audience-feedback-5.38.0.tgz +0 -0
  131. package/components/tryghost-bootstrap-socket-5.38.0.tgz +0 -0
  132. package/components/tryghost-constants-5.38.0.tgz +0 -0
  133. package/components/tryghost-data-generator-5.38.0.tgz +0 -0
  134. package/components/tryghost-dynamic-routing-events-5.38.0.tgz +0 -0
  135. package/components/tryghost-email-analytics-provider-mailgun-5.38.0.tgz +0 -0
  136. package/components/tryghost-email-analytics-service-5.38.0.tgz +0 -0
  137. package/components/tryghost-email-content-generator-5.38.0.tgz +0 -0
  138. package/components/tryghost-email-events-5.38.0.tgz +0 -0
  139. package/components/tryghost-email-service-5.38.0.tgz +0 -0
  140. package/components/tryghost-event-aware-cache-wrapper-5.38.0.tgz +0 -0
  141. package/components/tryghost-external-media-inliner-5.38.0.tgz +0 -0
  142. package/components/tryghost-extract-api-key-5.38.0.tgz +0 -0
  143. package/components/tryghost-html-to-plaintext-5.38.0.tgz +0 -0
  144. package/components/tryghost-i18n-5.38.0.tgz +0 -0
  145. package/components/tryghost-importer-handler-content-files-5.38.0.tgz +0 -0
  146. package/components/tryghost-importer-revue-5.38.0.tgz +0 -0
  147. package/components/tryghost-job-manager-5.38.0.tgz +0 -0
  148. package/components/tryghost-link-redirects-5.38.0.tgz +0 -0
  149. package/components/tryghost-link-replacer-5.38.0.tgz +0 -0
  150. package/components/tryghost-magic-link-5.38.0.tgz +0 -0
  151. package/components/tryghost-mailgun-client-5.38.0.tgz +0 -0
  152. package/components/tryghost-member-attribution-5.38.0.tgz +0 -0
  153. package/components/tryghost-member-events-5.38.0.tgz +0 -0
  154. package/components/tryghost-members-api-5.38.0.tgz +0 -0
  155. package/components/tryghost-members-csv-5.38.0.tgz +0 -0
  156. package/components/tryghost-members-importer-5.38.0.tgz +0 -0
  157. package/components/tryghost-members-offers-5.38.0.tgz +0 -0
  158. package/components/tryghost-members-payments-5.38.0.tgz +0 -0
  159. package/components/tryghost-members-ssr-5.38.0.tgz +0 -0
  160. package/components/tryghost-members-stripe-service-5.38.0.tgz +0 -0
  161. package/components/tryghost-milestones-5.38.0.tgz +0 -0
  162. package/components/tryghost-mw-api-version-mismatch-5.38.0.tgz +0 -0
  163. package/components/tryghost-mw-error-handler-5.38.0.tgz +0 -0
  164. package/components/tryghost-mw-session-from-token-5.38.0.tgz +0 -0
  165. package/components/tryghost-mw-update-user-last-seen-5.38.0.tgz +0 -0
  166. package/components/tryghost-mw-vhost-5.38.0.tgz +0 -0
  167. package/components/tryghost-oembed-service-5.38.0.tgz +0 -0
  168. package/components/tryghost-package-json-5.38.0.tgz +0 -0
  169. package/components/tryghost-referrers-5.38.0.tgz +0 -0
  170. package/components/tryghost-security-5.38.0.tgz +0 -0
  171. package/components/tryghost-session-service-5.38.0.tgz +0 -0
  172. package/components/tryghost-settings-path-manager-5.38.0.tgz +0 -0
  173. package/components/tryghost-slack-notifications-5.38.0.tgz +0 -0
  174. package/components/tryghost-staff-service-5.38.0.tgz +0 -0
  175. package/components/tryghost-stats-service-5.38.0.tgz +0 -0
  176. package/components/tryghost-tiers-5.38.0.tgz +0 -0
  177. package/components/tryghost-verification-trigger-5.38.0.tgz +0 -0
  178. package/components/tryghost-version-notifications-data-service-5.38.0.tgz +0 -0
  179. package/components/tryghost-webmentions-5.38.0.tgz +0 -0
  180. package/core/built/admin/assets/chunk.79.acb7dd01e1c785f4920c.js +0 -287
  181. package/core/built/admin/assets/ghost-a9307c9cfe26a4bc621e02cd3bae421a.css +0 -1
  182. package/core/built/admin/assets/ghost-dark-f309cf445255344e4861a95ecb8f1920.css +0 -1
  183. /package/core/built/admin/assets/{chunk.220.9ca2950240aba3fced21.js.LICENSE.txt → chunk.462.b66cfed1f66c8d2678b2.js.LICENSE.txt} +0 -0
@@ -1,123 +1,8 @@
1
- const nql = require('@tryghost/nql');
2
- const {BadRequestError} = require('@tryghost/errors');
3
- const tpl = require('@tryghost/tpl');
4
-
5
- const messages = {
6
- invalidVisibilityFilter: 'Invalid visibility filter.',
7
- invalidEmailSegment: 'The email segment parameter doesn\'t contain a valid filter'
8
- };
9
-
10
- class PostsService {
11
- constructor({urlUtils, models, isSet, stats, emailService}) {
12
- this.urlUtils = urlUtils;
13
- this.models = models;
14
- this.isSet = isSet;
15
- this.stats = stats;
16
- this.emailService = emailService;
17
- }
18
-
19
- async editPost(frame) {
20
- // Make sure the newsletter is matching an active newsletter
21
- // Note that this option is simply ignored if the post isn't published or scheduled
22
- if (frame.options.newsletter && frame.options.email_segment) {
23
- if (frame.options.email_segment !== 'all') {
24
- // check filter is valid
25
- try {
26
- await this.models.Member.findPage({filter: frame.options.email_segment, limit: 1});
27
- } catch (err) {
28
- return Promise.reject(new BadRequestError({
29
- message: tpl(messages.invalidEmailSegment),
30
- context: err.message
31
- }));
32
- }
33
- }
34
- }
35
-
36
- const model = await this.models.Post.edit(frame.data.posts[0], frame.options);
37
-
38
- /**Handle newsletter email */
39
- if (model.get('newsletter_id')) {
40
- const sendEmail = model.wasChanged() && this.shouldSendEmail(model.get('status'), model.previous('status'));
41
-
42
- if (sendEmail) {
43
- let postEmail = model.relations.email;
44
- let email;
45
-
46
- if (!postEmail) {
47
- email = await this.emailService.createEmail(model);
48
- } else if (postEmail && postEmail.get('status') === 'failed') {
49
- email = await this.emailService.retryEmail(postEmail);
50
- }
51
- if (email) {
52
- model.set('email', email);
53
- }
54
- }
55
- }
56
-
57
- return model;
58
- }
59
-
60
- async getProductsFromVisibilityFilter(visibilityFilter) {
61
- try {
62
- const allProducts = await this.models.Product.findAll();
63
- const visibilityFilterJson = nql(visibilityFilter).toJSON();
64
- const productsData = (visibilityFilterJson.product ? [visibilityFilterJson] : visibilityFilterJson.$or) || [];
65
- const tiers = productsData
66
- .map((data) => {
67
- return allProducts.find((p) => {
68
- return p.get('slug') === data.product;
69
- });
70
- }).filter(p => !!p).map((d) => {
71
- return d.toJSON();
72
- });
73
- return tiers;
74
- } catch (err) {
75
- return Promise.reject(new BadRequestError({
76
- message: tpl(messages.invalidVisibilityFilter),
77
- context: err.message
78
- }));
79
- }
80
- }
81
-
82
- /**
83
- * Calculates if the email should be tried to be sent out
84
- * @private
85
- * @param {String} currentStatus current status from the post model
86
- * @param {String} previousStatus previous status from the post model
87
- * @returns {Boolean}
88
- */
89
- shouldSendEmail(currentStatus, previousStatus) {
90
- return (['published', 'sent'].includes(currentStatus))
91
- && (!['published', 'sent'].includes(previousStatus));
92
- }
93
-
94
- handleCacheInvalidation(model) {
95
- let cacheInvalidate;
96
-
97
- if (
98
- model.get('status') === 'published' && model.wasChanged() ||
99
- model.get('status') === 'draft' && model.previous('status') === 'published'
100
- ) {
101
- cacheInvalidate = true;
102
- } else if (
103
- model.get('status') === 'draft' && model.previous('status') !== 'published' ||
104
- model.get('status') === 'scheduled' && model.wasChanged()
105
- ) {
106
- cacheInvalidate = {
107
- value: this.urlUtils.urlFor({
108
- relativeUrl: this.urlUtils.urlJoin('/p', model.get('uuid'), '/')
109
- })
110
- };
111
- } else {
112
- cacheInvalidate = false;
113
- }
114
-
115
- return cacheInvalidate;
116
- }
117
- }
1
+ const {PostsService, PostsExporter} = require('@tryghost/posts-service');
2
+ const url = require('../../../server/api/endpoints/utils/serializers/output/utils/url');
118
3
 
119
4
  /**
120
- * @returns {PostsService} instance of the PostsService
5
+ * @returns {InstanceType<PostsService>} instance of the PostsService
121
6
  */
122
7
  const getPostServiceInstance = () => {
123
8
  const urlUtils = require('../../../shared/url-utils');
@@ -125,15 +10,33 @@ const getPostServiceInstance = () => {
125
10
  const models = require('../../models');
126
11
  const PostStats = require('./stats/post-stats');
127
12
  const emailService = require('../email-service');
13
+ const settingsCache = require('../../../shared/settings-cache');
14
+ const settingsHelpers = require('../settings-helpers');
128
15
 
129
16
  const postStats = new PostStats();
130
17
 
18
+ const postsExporter = new PostsExporter({
19
+ models: {
20
+ Post: models.Post,
21
+ Newsletter: models.Newsletter,
22
+ Label: models.Label
23
+ },
24
+ getPostUrl(post) {
25
+ const jsonModel = post.toJSON();
26
+ url.forPost(post.id, jsonModel, {options: {}});
27
+ return jsonModel.url;
28
+ },
29
+ settingsCache,
30
+ settingsHelpers
31
+ });
32
+
131
33
  return new PostsService({
132
34
  urlUtils: urlUtils,
133
35
  models: models,
134
36
  isSet: flag => labs.isSet(flag), // don't use bind, that breaks test subbing of labs
135
37
  stats: postStats,
136
- emailService: emailService.service
38
+ emailService: emailService.service,
39
+ postsExporter
137
40
  });
138
41
  };
139
42
 
@@ -6,7 +6,7 @@ const ghostVersion = require('@tryghost/version');
6
6
 
7
7
  module.exports = function getConfigProperties() {
8
8
  const configProperties = {
9
- version: ghostVersion.full,
9
+ version: ghostVersion.original,
10
10
  environment: config.get('env'),
11
11
  database: databaseInfo.getEngine(),
12
12
  mail: isPlainObject(config.get('mail')) ? config.get('mail').transport : '',
@@ -1,6 +1,5 @@
1
1
  const DomainEvents = require('@tryghost/domain-events');
2
2
  const config = require('../../../shared/config');
3
- const labs = require('../../../shared/labs');
4
3
  const logging = require('@tryghost/logging');
5
4
 
6
5
  class SlackNotificationsServiceWrapper {
@@ -48,7 +47,7 @@ class SlackNotificationsServiceWrapper {
48
47
  const hostSettings = config.get('hostSettings');
49
48
  const urlUtils = require('../../../shared/url-utils');
50
49
  const siteUrl = urlUtils.getSiteUrl();
51
- const isEnabled = labs.isSet('milestoneEmails') && hostSettings?.milestones?.enabled && hostSettings?.milestones?.url;
50
+ const isEnabled = !!(hostSettings?.milestones?.enabled && hostSettings?.milestones?.url);
52
51
  const webhookUrl = hostSettings?.milestones?.url;
53
52
 
54
53
  this.#api = SlackNotificationsServiceWrapper.create({siteUrl, isEnabled, webhookUrl});
@@ -31,7 +31,7 @@ class WebhookTrigger {
31
31
  last_triggered_at: Date.now(),
32
32
  last_triggered_status: data.statusCode,
33
33
  last_triggered_error: data.error || null
34
- }, {id: webhook.id})
34
+ }, {id: webhook.id, autoRefresh: false})
35
35
  .catch(() => {
36
36
  logging.warn(`Unable to update "last_triggered" for webhook: ${webhook.id}`);
37
37
  });
@@ -102,7 +102,7 @@ class WebhookTrigger {
102
102
  body: reqPayload,
103
103
  headers,
104
104
  timeout: 2 * 1000,
105
- retry: 5
105
+ retry: process.env.NODE_ENV?.startsWith('test') ? 0 : 5
106
106
  };
107
107
 
108
108
  logging.info(`Triggering webhook for "${webhook.get('event')}" with url "${url}"`);
@@ -26,6 +26,8 @@ module.exports = function apiRoutes() {
26
26
 
27
27
  // ## Posts
28
28
  router.get('/posts', mw.authAdminApi, http(api.posts.browse));
29
+ router.get('/posts/export', mw.authAdminApi, http(api.posts.exportCSV));
30
+
29
31
  router.post('/posts', mw.authAdminApi, http(api.posts.add));
30
32
  router.get('/posts/:id', mw.authAdminApi, http(api.posts.read));
31
33
  router.get('/posts/slug/:slug', mw.authAdminApi, http(api.posts.read));
@@ -207,7 +209,6 @@ module.exports = function apiRoutes() {
207
209
 
208
210
  router.post('/db/media/inline',
209
211
  mw.authAdminApi,
210
- labs.enabledMiddleware('mediaInliner'),
211
212
  http(api.db.inlineMedia)
212
213
  );
213
214
 
@@ -210,12 +210,11 @@
210
210
  "arr": [
211
211
  {
212
212
  "currency": "usd",
213
- "values": [100, 1000, 10000, 50000, 100000, 250000, 500000, 1000000]
213
+ "values": [0, 100, 1000, 10000, 50000, 100000, 250000, 500000, 1000000]
214
214
  }
215
215
  ],
216
- "members": [100, 1000, 10000, 25000, 50000, 100000, 250000, 500000, 1000000],
216
+ "members": [0, 100, 1000, 10000, 25000, 50000, 100000, 250000, 500000, 1000000],
217
217
  "minDaysSinceImported": 7,
218
- "minDaysSinceLastEmail": 14,
219
- "maxPercentageFromMilestone": 0.1
218
+ "minDaysSinceLastEmail": 14
220
219
  }
221
220
  }
@@ -121,7 +121,9 @@
121
121
  },
122
122
  "internalImageSizes": {
123
123
  "icon": {"width": 256, "height": 256},
124
- "email-header-image": {"width": 1200}
124
+ "email-header-image": {"width": 1200},
125
+ "email-latest-posts-image": {"width": 200, "height": 200},
126
+ "email-latest-posts-image-mobile": {"width": 1200, "height": 960}
125
127
  }
126
128
  }
127
129
  }
@@ -28,17 +28,16 @@ const GA_FEATURES = [
28
28
  // input for the "labs" setting value
29
29
  const BETA_FEATURES = [
30
30
  'activitypub',
31
- 'webmentions',
32
- 'milestoneEmails'
31
+ 'webmentions'
33
32
  ];
34
33
 
35
34
  const ALPHA_FEATURES = [
36
35
  'urlCache',
37
- 'mediaInliner',
38
36
  'lexicalEditor',
39
37
  'websockets',
40
38
  'webmentionEmails',
41
- 'stripeAutomaticTax'
39
+ 'stripeAutomaticTax',
40
+ 'makingItRain'
42
41
  ];
43
42
 
44
43
  module.exports.GA_KEYS = [...GA_FEATURES];