ghost 4.22.0 → 4.22.4

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 (127) hide show
  1. package/.c8rc.json +24 -0
  2. package/.eslintrc.js +6 -0
  3. package/Gruntfile.js +1 -1
  4. package/content/public/README.md +3 -0
  5. package/core/boot.js +20 -12
  6. package/core/built/assets/{chunk.3.1148677ff3b78e5aeaee.js → chunk.3.8f95b516d88ff4eec64c.js} +18 -18
  7. package/core/built/assets/{ghost-dark-684ad238e1a858c7cb5be6988de7c6f5.css → ghost-dark-42cf6e0c730578940ec069bda45aea41.css} +1 -1
  8. package/core/built/assets/{ghost.min-efbfb823467b66f4acc66537d033aa55.js → ghost.min-2e3e64eb258cf424c59c3e308b4bc6e6.js} +215 -155
  9. package/core/built/assets/{ghost.min-66e08535f8bb797a8c40e0a2b31f1e9e.css → ghost.min-fcf6a0738421f86c47c55f20d00c5ba9.css} +1 -1
  10. package/core/built/assets/icons/powered-by-tenor.svg +35 -0
  11. package/core/built/assets/icons/tenor.svg +7 -0
  12. package/core/built/assets/{vendor.min-7c8fdd90f7ecd2e94328a07ea3b64608.js → vendor.min-c9002845b6c30ac978abdadde9f33d7c.js} +8189 -7601
  13. package/core/frontend/apps/amp/lib/views/amp.hbs +104 -0
  14. package/core/frontend/apps/private-blogging/lib/router.js +1 -1
  15. package/core/frontend/services/card-assets/service.js +21 -13
  16. package/core/frontend/services/routing/CollectionRouter.js +4 -5
  17. package/core/frontend/services/routing/EmailRouter.js +1 -1
  18. package/core/frontend/services/routing/ParentRouter.js +0 -8
  19. package/core/frontend/services/routing/PreviewRouter.js +1 -1
  20. package/core/frontend/services/routing/StaticPagesRouter.js +1 -1
  21. package/core/frontend/services/routing/StaticRoutesRouter.js +4 -4
  22. package/core/frontend/services/routing/TaxonomyRouter.js +3 -3
  23. package/core/frontend/services/routing/{middlewares → middleware}/index.js +0 -0
  24. package/core/frontend/services/routing/{middlewares → middleware}/page-param.js +0 -0
  25. package/core/frontend/services/routing/router-manager.js +7 -2
  26. package/core/frontend/services/rss/generate-feed.js +2 -1
  27. package/core/frontend/src/cards/css/bookmark.css +66 -48
  28. package/core/frontend/src/cards/css/button.css +30 -0
  29. package/core/frontend/src/cards/css/callout.css +50 -0
  30. package/core/frontend/src/cards/css/gallery.css +8 -13
  31. package/core/frontend/src/cards/css/nft.css +94 -0
  32. package/core/frontend/src/cards/css/toggle.css +47 -0
  33. package/core/frontend/src/cards/js/toggle.js +16 -0
  34. package/core/frontend/web/middleware/serve-public-file.js +14 -8
  35. package/core/frontend/web/routes.js +0 -1
  36. package/core/frontend/web/site.js +15 -12
  37. package/core/server/adapters/storage/LocalFilesStorage.js +17 -0
  38. package/core/server/adapters/storage/LocalImagesStorage.js +1 -0
  39. package/core/server/adapters/storage/LocalMediaStorage.js +2 -1
  40. package/core/server/adapters/storage/LocalStorageBase.js +30 -5
  41. package/core/server/api/canary/authentication.js +1 -1
  42. package/core/server/api/canary/files.js +19 -0
  43. package/core/server/api/canary/index.js +4 -0
  44. package/core/server/api/canary/media.js +25 -5
  45. package/core/server/api/canary/oembed.js +3 -0
  46. package/core/server/api/canary/utils/serializers/input/index.js +4 -0
  47. package/core/server/api/canary/utils/serializers/input/media.js +8 -0
  48. package/core/server/api/canary/utils/serializers/output/config.js +21 -14
  49. package/core/server/api/canary/utils/serializers/output/files.js +27 -0
  50. package/core/server/api/canary/utils/serializers/output/index.js +4 -0
  51. package/core/server/api/canary/utils/serializers/output/media.js +9 -0
  52. package/core/server/api/canary/utils/validators/input/files.js +7 -0
  53. package/core/server/api/canary/utils/validators/input/index.js +4 -0
  54. package/core/server/api/canary/utils/validators/input/media.js +4 -0
  55. package/core/server/api/v2/authentication.js +1 -1
  56. package/core/server/api/v3/authentication.js +1 -1
  57. package/core/server/data/db/connection.js +7 -0
  58. package/core/server/data/importer/importers/data/data-importer.js +3 -3
  59. package/core/server/data/migrations/init/2-create-fixtures.js +3 -20
  60. package/core/server/data/migrations/versions/1.21/1-add-contributor-role.js +5 -5
  61. package/core/server/data/migrations/versions/2.15/2-insert-zapier-integration.js +3 -3
  62. package/core/server/data/migrations/versions/2.2/3-insert-admin-integration-role.js +5 -5
  63. package/core/server/data/migrations/versions/2.27/1-insert-ghost-db-backup-role.js +5 -6
  64. package/core/server/data/migrations/versions/2.27/2-insert-db-backup-integration.js +3 -4
  65. package/core/server/data/migrations/versions/2.28/3-insert-ghost-scheduler-role.js +7 -7
  66. package/core/server/data/migrations/versions/2.28/4-insert-scheduler-integration.js +3 -3
  67. package/core/server/data/schema/fixtures/fixture-manager.js +340 -0
  68. package/core/server/data/schema/fixtures/index.js +8 -2
  69. package/core/server/services/mega/post-email-serializer.js +5 -1
  70. package/core/server/services/mega/segment-parser.js +1 -2
  71. package/core/server/services/mega/template.js +69 -1
  72. package/core/server/services/nft-oembed.js +57 -0
  73. package/core/server/services/oembed.js +149 -110
  74. package/core/server/services/public-config/config.js +2 -1
  75. package/core/server/services/stripe/index.js +4 -2
  76. package/core/server/services/url/Resource.js +1 -1
  77. package/core/server/services/url/Resources.js +36 -23
  78. package/core/server/services/url/UrlGenerator.js +23 -20
  79. package/core/server/services/url/UrlService.js +123 -21
  80. package/core/server/services/url/Urls.js +7 -2
  81. package/core/server/services/url/index.js +9 -1
  82. package/core/server/web/admin/app.js +6 -6
  83. package/core/server/web/admin/views/default-prod.html +3 -3
  84. package/core/server/web/admin/views/default.html +3 -3
  85. package/core/server/web/api/app.js +1 -1
  86. package/core/server/web/api/canary/admin/app.js +4 -4
  87. package/core/server/web/api/canary/admin/middleware.js +6 -6
  88. package/core/server/web/api/canary/admin/routes.js +20 -5
  89. package/core/server/web/api/canary/content/app.js +4 -4
  90. package/core/server/web/api/canary/content/middleware.js +3 -3
  91. package/core/server/web/api/middleware/cors.js +7 -7
  92. package/core/server/web/api/v2/admin/app.js +4 -4
  93. package/core/server/web/api/v2/admin/middleware.js +6 -6
  94. package/core/server/web/api/v2/admin/routes.js +5 -5
  95. package/core/server/web/api/v2/content/app.js +4 -4
  96. package/core/server/web/api/v2/content/middleware.js +3 -3
  97. package/core/server/web/api/v3/admin/app.js +4 -4
  98. package/core/server/web/api/v3/admin/middleware.js +6 -6
  99. package/core/server/web/api/v3/admin/routes.js +5 -5
  100. package/core/server/web/api/v3/content/app.js +4 -4
  101. package/core/server/web/api/v3/content/middleware.js +3 -3
  102. package/core/server/web/members/app.js +7 -7
  103. package/core/server/web/oauth/app.js +1 -1
  104. package/core/server/web/parent/app.js +2 -3
  105. package/core/server/web/parent/frontend.js +1 -1
  106. package/core/server/web/shared/index.js +2 -2
  107. package/core/server/web/shared/{middlewares → middleware}/api/index.js +0 -0
  108. package/core/server/web/shared/{middlewares → middleware}/api/spam-prevention.js +0 -0
  109. package/core/server/web/shared/{middlewares → middleware}/brute.js +0 -0
  110. package/core/server/web/shared/{middlewares → middleware}/cache-control.js +0 -0
  111. package/core/server/web/shared/{middlewares → middleware}/error-handler.js +0 -0
  112. package/core/server/web/shared/{middlewares → middleware}/index.js +0 -0
  113. package/core/server/web/shared/{middlewares → middleware}/maintenance.js +0 -0
  114. package/core/server/web/shared/{middlewares → middleware}/pretty-urls.js +0 -0
  115. package/core/server/web/shared/{middlewares → middleware}/uncapitalise.js +0 -0
  116. package/core/server/web/shared/{middlewares → middleware}/url-redirects.js +0 -0
  117. package/core/shared/config/defaults.json +10 -2
  118. package/core/shared/config/helpers.js +44 -0
  119. package/core/shared/config/loader.js +1 -1
  120. package/core/shared/config/overrides.json +2 -2
  121. package/core/shared/labs.js +8 -1
  122. package/loggingrc.js +19 -20
  123. package/package.json +36 -36
  124. package/urls.json +597 -0
  125. package/yarn.lock +666 -354
  126. package/core/server/data/schema/fixtures/utils.js +0 -321
  127. package/core/server/web/parent/vhost-utils.js +0 -39
@@ -1,7 +1,9 @@
1
+ const fs = require('fs-extra');
1
2
  const _debug = require('@tryghost/debug')._base;
2
3
  const debug = _debug('ghost:services:url:service');
3
4
  const _ = require('lodash');
4
5
  const errors = require('@tryghost/errors');
6
+ const labs = require('../../../shared/labs');
5
7
  const UrlGenerator = require('./UrlGenerator');
6
8
  const Queue = require('./Queue');
7
9
  const Urls = require('./Urls');
@@ -17,15 +19,28 @@ const events = require('../../lib/common/events');
17
19
  * It will tell you if the url generation is in progress or not.
18
20
  */
19
21
  class UrlService {
20
- constructor() {
22
+ /**
23
+ *
24
+ * @param {Object} options
25
+ * @param {String} [options.urlsCachePath] - cached URLs storage path
26
+ * @param {String} [options.resourcesCachePath] - cached resources storage path
27
+ */
28
+ constructor({urlsCachePath, resourcesCachePath} = {}) {
21
29
  this.utils = urlUtils;
22
-
30
+ this.urlsCachePath = urlsCachePath;
31
+ this.resourcesCachePath = resourcesCachePath;
32
+ this.onFinished = null;
23
33
  this.finished = false;
24
34
  this.urlGenerators = [];
25
35
 
26
- this.urls = new Urls();
36
+ // Get urls
27
37
  this.queue = new Queue();
28
- this.resources = new Resources(this.queue);
38
+ // NOTE: Urls and Resources should not be initialized here but only in the init method.
39
+ // Way too many tests fail if the initialization is removed so leaving it as is for time being
40
+ this.urls = new Urls();
41
+ this.resources = new Resources({
42
+ queue: this.queue
43
+ });
29
44
 
30
45
  this._listeners();
31
46
  }
@@ -68,26 +83,41 @@ class UrlService {
68
83
  _onQueueEnded(event) {
69
84
  if (event === 'init') {
70
85
  this.finished = true;
86
+ if (this.onFinished) {
87
+ this.onFinished();
88
+ }
71
89
  }
72
90
  }
73
91
 
74
92
  /**
75
93
  * @description Router was created, connect it with a url generator.
76
- * @param {ExpressRouter} router
94
+ * @param {String} identifier frontend router ID reference
95
+ * @param {String} filter NQL filter
96
+ * @param {String} resourceType
97
+ * @param {String} permalink
77
98
  */
78
- onRouterAddedType(router) {
79
- debug('Registering route: ', router.name);
80
-
81
- let urlGenerator = new UrlGenerator(router, this.queue, this.resources, this.urls, this.urlGenerators.length);
99
+ onRouterAddedType(identifier, filter, resourceType, permalink) {
100
+ debug('Registering route: ', filter, resourceType, permalink);
101
+
102
+ let urlGenerator = new UrlGenerator({
103
+ identifier,
104
+ filter,
105
+ resourceType,
106
+ permalink,
107
+ queue: this.queue,
108
+ resources: this.resources,
109
+ urls: this.urls,
110
+ position: this.urlGenerators.length
111
+ });
82
112
  this.urlGenerators.push(urlGenerator);
83
113
  }
84
114
 
85
115
  /**
86
116
  * @description Router update handler - regenerates it's resources
87
- * @param {ExpressRouter} router
117
+ * @param {String} identifier router ID linked to the UrlGenerator
88
118
  */
89
- onRouterUpdated(router) {
90
- const generator = this.urlGenerators.find(g => g.router.id === router.id);
119
+ onRouterUpdated(identifier) {
120
+ const generator = this.urlGenerators.find(g => g.identifier === identifier);
91
121
  generator.regenerateResources();
92
122
  }
93
123
 
@@ -246,7 +276,7 @@ class UrlService {
246
276
  let urlGenerator;
247
277
 
248
278
  this.urlGenerators.every((_urlGenerator) => {
249
- if (_urlGenerator.router.identifier === routerId) {
279
+ if (_urlGenerator.identifier === routerId) {
250
280
  urlGenerator = _urlGenerator;
251
281
  return false;
252
282
  }
@@ -276,18 +306,90 @@ class UrlService {
276
306
  return null;
277
307
  }
278
308
 
279
- return _.find(this.urlGenerators, {uid: object.generatorId}).router.getPermalinks()
280
- .getValue(options);
309
+ const permalink = _.find(this.urlGenerators, {uid: object.generatorId}).permalink;
310
+
311
+ if (options.withUrlOptions) {
312
+ return urlUtils.urlJoin(permalink, '/:options(edit)?/');
313
+ }
314
+
315
+ return permalink;
281
316
  }
282
317
 
283
318
  /**
284
- * @description Internal helper to re-trigger fetching resources on theme change.
285
- *
286
- * @TODO: Either remove this helper or rename to `_init`, because it's a little confusing,
287
- * because this service get's initalised via events.
319
+ * @description Initializes components needed for the URL Service to function
320
+ * @param {Object} options
321
+ * @param {Function} [options.onFinished] - callback when url generation is finished
288
322
  */
289
- init() {
290
- this.resources.fetchResources();
323
+ async init(options = {}) {
324
+ this.onFinished = options.onFinished;
325
+
326
+ let persistedUrls;
327
+ let persistedResources;
328
+
329
+ if (labs.isSet('urlCache')) {
330
+ persistedUrls = await this.readCacheFile(this.urlsCachePath);
331
+ persistedResources = await this.readCacheFile(this.resourcesCachePath);
332
+ }
333
+
334
+ if (persistedUrls && persistedResources) {
335
+ this.urls = new Urls({
336
+ urls: persistedUrls
337
+ });
338
+ this.resources = new Resources({
339
+ queue: this.queue,
340
+ resources: persistedResources
341
+ });
342
+ this.resources.initResourceConfig();
343
+ this.resources.initEvenListeners();
344
+
345
+ this._onQueueEnded('init');
346
+ } else {
347
+ this.resources.initResourceConfig();
348
+ this.resources.initEvenListeners();
349
+ await this.resources.fetchResources();
350
+ // CASE: all resources are fetched, start the queue
351
+ this.queue.start({
352
+ event: 'init',
353
+ tolerance: 100,
354
+ requiredSubscriberCount: 1
355
+ });
356
+ }
357
+ }
358
+
359
+ async shutdown() {
360
+ if (!labs.isSet('urlCache')) {
361
+ return null;
362
+ }
363
+
364
+ await this.persistToCacheFile(this.urlsCachePath, this.urls.urls);
365
+ await this.persistToCacheFile(this.resourcesCachePath, this.resources.getAll());
366
+ }
367
+
368
+ async persistToCacheFile(filePath, data) {
369
+ return fs.writeFile(filePath, JSON.stringify(data, null, 4));
370
+ }
371
+
372
+ async readCacheFile(filePath) {
373
+ let cacheExists = false;
374
+ let cacheData;
375
+
376
+ try {
377
+ await fs.stat(filePath);
378
+ cacheExists = true;
379
+ } catch (e) {
380
+ cacheExists = false;
381
+ }
382
+
383
+ if (cacheExists) {
384
+ try {
385
+ const cacheFile = await fs.readFile(filePath, 'utf8');
386
+ cacheData = JSON.parse(cacheFile);
387
+ } catch (e) {
388
+ //noop as we'd start a long boot process if there are any errors in the file
389
+ }
390
+ }
391
+
392
+ return cacheData;
291
393
  }
292
394
 
293
395
  /**
@@ -20,8 +20,13 @@ const events = require('../../lib/common/events');
20
20
  * You can easily ask `this.urls[resourceId]`.
21
21
  */
22
22
  class Urls {
23
- constructor() {
24
- this.urls = {};
23
+ /**
24
+ *
25
+ * @param {Object} [options]
26
+ * @param {Object} [options.urls] map of available URLs with their resources
27
+ */
28
+ constructor({urls = {}} = {}) {
29
+ this.urls = urls;
25
30
  }
26
31
 
27
32
  /**
@@ -1,5 +1,13 @@
1
+ const path = require('path');
2
+ const config = require('../../../shared/config');
1
3
  const UrlService = require('./UrlService');
2
- const urlService = new UrlService();
4
+
5
+ // NOTE: instead of a path we could give UrlService a "data-resolver" of some sort
6
+ // so it doesn't have to contain the logic to read data at all. This would be
7
+ // a possible improvement in the future
8
+ const urlsCachePath = path.join(config.getContentPath('data'), 'urls.json');
9
+ const resourcesCachePath = path.join(config.getContentPath('data'), 'resources.json');
10
+ const urlService = new UrlService({urlsCachePath, resourcesCachePath});
3
11
 
4
12
  // Singleton
5
13
  module.exports = urlService;
@@ -27,19 +27,19 @@ module.exports = function setupAdminApp() {
27
27
  }
28
28
 
29
29
  // Render error page in case of maintenance
30
- adminApp.use(shared.middlewares.maintenance);
30
+ adminApp.use(shared.middleware.maintenance);
31
31
 
32
32
  // Force SSL if required
33
33
  // must happen AFTER asset loading and BEFORE routing
34
- adminApp.use(shared.middlewares.urlRedirects.adminSSLAndHostRedirect);
34
+ adminApp.use(shared.middleware.urlRedirects.adminSSLAndHostRedirect);
35
35
 
36
36
  // Add in all trailing slashes & remove uppercase
37
37
  // must happen AFTER asset loading and BEFORE routing
38
- adminApp.use(shared.middlewares.prettyUrls);
38
+ adminApp.use(shared.middleware.prettyUrls);
39
39
 
40
40
  // Cache headers go last before serving the request
41
41
  // Admin is currently set to not be cached at all
42
- adminApp.use(shared.middlewares.cacheControl('private'));
42
+ adminApp.use(shared.middleware.cacheControl('private'));
43
43
 
44
44
  // Special redirects for the admin (these should have their own cache-control headers)
45
45
  adminApp.use(adminMiddleware);
@@ -47,8 +47,8 @@ module.exports = function setupAdminApp() {
47
47
  // Finally, routing
48
48
  adminApp.get('*', require('./controller'));
49
49
 
50
- adminApp.use(shared.middlewares.errorHandler.pageNotFound);
51
- adminApp.use(shared.middlewares.errorHandler.handleHTMLResponse);
50
+ adminApp.use(shared.middleware.errorHandler.pageNotFound);
51
+ adminApp.use(shared.middleware.errorHandler.handleHTMLResponse);
52
52
 
53
53
  debug('Admin setup end');
54
54
 
@@ -41,7 +41,7 @@
41
41
 
42
42
 
43
43
  <link rel="stylesheet" href="assets/vendor.min-987af30228885bce50f05c4723fe6f53.css">
44
- <link rel="stylesheet" href="assets/ghost.min-66e08535f8bb797a8c40e0a2b31f1e9e.css" title="light">
44
+ <link rel="stylesheet" href="assets/ghost.min-fcf6a0738421f86c47c55f20d00c5ba9.css" title="light">
45
45
 
46
46
 
47
47
 
@@ -59,8 +59,8 @@
59
59
  <div id="ember-basic-dropdown-wormhole"></div>
60
60
 
61
61
 
62
- <script src="assets/vendor.min-7c8fdd90f7ecd2e94328a07ea3b64608.js"></script>
63
- <script src="assets/ghost.min-efbfb823467b66f4acc66537d033aa55.js"></script>
62
+ <script src="assets/vendor.min-c9002845b6c30ac978abdadde9f33d7c.js"></script>
63
+ <script src="assets/ghost.min-2e3e64eb258cf424c59c3e308b4bc6e6.js"></script>
64
64
 
65
65
  </body>
66
66
  </html>
@@ -41,7 +41,7 @@
41
41
 
42
42
 
43
43
  <link rel="stylesheet" href="assets/vendor.min-987af30228885bce50f05c4723fe6f53.css">
44
- <link rel="stylesheet" href="assets/ghost.min-66e08535f8bb797a8c40e0a2b31f1e9e.css" title="light">
44
+ <link rel="stylesheet" href="assets/ghost.min-fcf6a0738421f86c47c55f20d00c5ba9.css" title="light">
45
45
 
46
46
 
47
47
 
@@ -59,8 +59,8 @@
59
59
  <div id="ember-basic-dropdown-wormhole"></div>
60
60
 
61
61
 
62
- <script src="assets/vendor.min-7c8fdd90f7ecd2e94328a07ea3b64608.js"></script>
63
- <script src="assets/ghost.min-efbfb823467b66f4acc66537d033aa55.js"></script>
62
+ <script src="assets/vendor.min-c9002845b6c30ac978abdadde9f33d7c.js"></script>
63
+ <script src="assets/ghost.min-2e3e64eb258cf424c59c3e308b4bc6e6.js"></script>
64
64
 
65
65
  </body>
66
66
  </html>
@@ -2,7 +2,7 @@ const debug = require('@tryghost/debug')('web:api:default:app');
2
2
  const config = require('../../../shared/config');
3
3
  const express = require('../../../shared/express');
4
4
  const urlUtils = require('../../../shared/url-utils');
5
- const errorHandler = require('../shared/middlewares/error-handler');
5
+ const errorHandler = require('../shared/middleware/error-handler');
6
6
 
7
7
  module.exports = function setupApiApp() {
8
8
  debug('Parent API setup start');
@@ -20,21 +20,21 @@ module.exports = function setupApiApp() {
20
20
  apiApp.use(boolParser());
21
21
 
22
22
  // send 503 json response in case of maintenance
23
- apiApp.use(shared.middlewares.maintenance);
23
+ apiApp.use(shared.middleware.maintenance);
24
24
 
25
25
  // Check version matches for API requests, depends on res.locals.safeVersion being set
26
26
  // Therefore must come after themeHandler.ghostLocals, for now
27
27
  apiApp.use(apiMw.versionMatch);
28
28
 
29
29
  // Admin API shouldn't be cached
30
- apiApp.use(shared.middlewares.cacheControl('private'));
30
+ apiApp.use(shared.middleware.cacheControl('private'));
31
31
 
32
32
  // Routing
33
33
  apiApp.use(routes());
34
34
 
35
35
  // API error handling
36
- apiApp.use(shared.middlewares.errorHandler.resourceNotFound);
37
- apiApp.use(shared.middlewares.errorHandler.handleJSONResponseV2);
36
+ apiApp.use(shared.middleware.errorHandler.resourceNotFound);
37
+ apiApp.use(shared.middleware.errorHandler.handleJSONResponseV2);
38
38
 
39
39
  debug('Admin API canary setup end');
40
40
 
@@ -59,8 +59,8 @@ module.exports.authAdminApi = [
59
59
  auth.authorize.authorizeAdminApi,
60
60
  apiMw.updateUserLastSeen,
61
61
  apiMw.cors,
62
- shared.middlewares.urlRedirects.adminSSLAndHostRedirect,
63
- shared.middlewares.prettyUrls,
62
+ shared.middleware.urlRedirects.adminSSLAndHostRedirect,
63
+ shared.middleware.prettyUrls,
64
64
  notImplemented
65
65
  ];
66
66
 
@@ -73,8 +73,8 @@ module.exports.authAdminApiWithUrl = [
73
73
  auth.authorize.authorizeAdminApi,
74
74
  apiMw.updateUserLastSeen,
75
75
  apiMw.cors,
76
- shared.middlewares.urlRedirects.adminSSLAndHostRedirect,
77
- shared.middlewares.prettyUrls,
76
+ shared.middleware.urlRedirects.adminSSLAndHostRedirect,
77
+ shared.middleware.prettyUrls,
78
78
  notImplemented
79
79
  ];
80
80
 
@@ -83,7 +83,7 @@ module.exports.authAdminApiWithUrl = [
83
83
  */
84
84
  module.exports.publicAdminApi = [
85
85
  apiMw.cors,
86
- shared.middlewares.urlRedirects.adminSSLAndHostRedirect,
87
- shared.middlewares.prettyUrls,
86
+ shared.middleware.urlRedirects.adminSSLAndHostRedirect,
87
+ shared.middleware.prettyUrls,
88
88
  notImplemented
89
89
  ];
@@ -204,8 +204,8 @@ module.exports = function apiRoutes() {
204
204
  router.get('/session', mw.authAdminApi, http(api.session.read));
205
205
  // We don't need auth when creating a new session (logging in)
206
206
  router.post('/session',
207
- shared.middlewares.brute.globalBlock,
208
- shared.middlewares.brute.userLogin,
207
+ shared.middleware.brute.globalBlock,
208
+ shared.middleware.brute.userLogin,
209
209
  http(api.session.add)
210
210
  );
211
211
  router.del('/session', mw.authAdminApi, http(api.session.delete));
@@ -215,11 +215,11 @@ module.exports = function apiRoutes() {
215
215
 
216
216
  // ## Authentication
217
217
  router.post('/authentication/passwordreset',
218
- shared.middlewares.brute.globalReset,
219
- shared.middlewares.brute.userReset,
218
+ shared.middleware.brute.globalReset,
219
+ shared.middleware.brute.userReset,
220
220
  http(api.authentication.generateResetToken)
221
221
  );
222
- router.put('/authentication/passwordreset', shared.middlewares.brute.globalBlock, http(api.authentication.resetPassword));
222
+ router.put('/authentication/passwordreset', shared.middleware.brute.globalBlock, http(api.authentication.resetPassword));
223
223
  router.post('/authentication/invitation', http(api.authentication.acceptInvitation));
224
224
  router.get('/authentication/invitation', http(api.authentication.isInvitation));
225
225
  router.post('/authentication/setup', http(api.authentication.setup));
@@ -244,6 +244,21 @@ module.exports = function apiRoutes() {
244
244
  apiMw.upload.mediaValidation({type: 'media'}),
245
245
  http(api.media.upload)
246
246
  );
247
+ router.put('/media/thumbnail/upload',
248
+ labs.enabledMiddleware('mediaAPI'),
249
+ mw.authAdminApi,
250
+ apiMw.upload.single('file'),
251
+ apiMw.upload.validation({type: 'images'}),
252
+ http(api.media.uploadThumbnail)
253
+ );
254
+
255
+ // ## files
256
+ router.post('/files/upload',
257
+ labs.enabledMiddleware('filesAPI'),
258
+ mw.authAdminApi,
259
+ apiMw.upload.single('file'),
260
+ http(api.files.upload)
261
+ );
247
262
 
248
263
  // ## Invites
249
264
  router.get('/invites', mw.authAdminApi, http(api.invites.browse));
@@ -18,17 +18,17 @@ module.exports = function setupApiApp() {
18
18
  apiApp.use(boolParser());
19
19
 
20
20
  // send 503 json response in case of maintenance
21
- apiApp.use(shared.middlewares.maintenance);
21
+ apiApp.use(shared.middleware.maintenance);
22
22
 
23
23
  // API shouldn't be cached
24
- apiApp.use(shared.middlewares.cacheControl('private'));
24
+ apiApp.use(shared.middleware.cacheControl('private'));
25
25
 
26
26
  // Routing
27
27
  apiApp.use(routes());
28
28
 
29
29
  // API error handling
30
- apiApp.use(shared.middlewares.errorHandler.resourceNotFound);
31
- apiApp.use(shared.middlewares.errorHandler.handleJSONResponse);
30
+ apiApp.use(shared.middleware.errorHandler.resourceNotFound);
31
+ apiApp.use(shared.middleware.errorHandler.handleJSONResponse);
32
32
 
33
33
  debug('Content API canary setup end');
34
34
 
@@ -14,10 +14,10 @@ const shared = require('../../../shared');
14
14
  * Authentication for public endpoints
15
15
  */
16
16
  module.exports.authenticatePublic = [
17
- shared.middlewares.brute.contentApiKey,
17
+ shared.middleware.brute.contentApiKey,
18
18
  auth.authenticate.authenticateContentApi,
19
19
  auth.authorize.authorizeContentApi,
20
20
  cors(),
21
- shared.middlewares.urlRedirects.adminSSLAndHostRedirect,
22
- shared.middlewares.prettyUrls
21
+ shared.middleware.urlRedirects.adminSSLAndHostRedirect,
22
+ shared.middleware.prettyUrls
23
23
  ];
@@ -3,7 +3,7 @@ const url = require('url');
3
3
  const os = require('os');
4
4
  const urlUtils = require('../../../../shared/url-utils');
5
5
 
6
- let whitelist = [];
6
+ let allowlist = [];
7
7
  const ENABLE_CORS = {origin: true, maxAge: 86400};
8
8
  const DISABLE_CORS = {origin: false};
9
9
 
@@ -46,16 +46,16 @@ function getUrls() {
46
46
  return urls;
47
47
  }
48
48
 
49
- function getWhitelist() {
49
+ function getAllowlist() {
50
50
  // This needs doing just one time after init
51
- if (whitelist.length === 0) {
51
+ if (allowlist.length === 0) {
52
52
  // origins that always match: localhost, local IPs, etc.
53
- whitelist = whitelist.concat(getIPs());
53
+ allowlist = allowlist.concat(getIPs());
54
54
  // Trusted urls from config.js
55
- whitelist = whitelist.concat(getUrls());
55
+ allowlist = allowlist.concat(getUrls());
56
56
  }
57
57
 
58
- return whitelist;
58
+ return allowlist;
59
59
  }
60
60
 
61
61
  /**
@@ -73,7 +73,7 @@ function handleCORS(req, cb) {
73
73
  }
74
74
 
75
75
  // Origin matches whitelist
76
- if (getWhitelist().indexOf(url.parse(origin).hostname) > -1) {
76
+ if (getAllowlist().indexOf(url.parse(origin).hostname) > -1) {
77
77
  return cb(null, ENABLE_CORS);
78
78
  }
79
79
 
@@ -20,21 +20,21 @@ module.exports = function setupApiApp() {
20
20
  apiApp.use(boolParser());
21
21
 
22
22
  // send 503 json response in case of maintenance
23
- apiApp.use(shared.middlewares.maintenance);
23
+ apiApp.use(shared.middleware.maintenance);
24
24
 
25
25
  // Check version matches for API requests, depends on res.locals.safeVersion being set
26
26
  // Therefore must come after themeHandler.ghostLocals, for now
27
27
  apiApp.use(apiMw.versionMatch);
28
28
 
29
29
  // Admin API shouldn't be cached
30
- apiApp.use(shared.middlewares.cacheControl('private'));
30
+ apiApp.use(shared.middleware.cacheControl('private'));
31
31
 
32
32
  // Routing
33
33
  apiApp.use(routes());
34
34
 
35
35
  // API error handling
36
- apiApp.use(shared.middlewares.errorHandler.resourceNotFound);
37
- apiApp.use(shared.middlewares.errorHandler.handleJSONResponseV2);
36
+ apiApp.use(shared.middleware.errorHandler.resourceNotFound);
37
+ apiApp.use(shared.middleware.errorHandler.handleJSONResponseV2);
38
38
 
39
39
  debug('Admin API v2 setup end');
40
40
 
@@ -55,8 +55,8 @@ module.exports.authAdminApi = [
55
55
  auth.authorize.authorizeAdminApi,
56
56
  apiMw.updateUserLastSeen,
57
57
  apiMw.cors,
58
- shared.middlewares.urlRedirects.adminSSLAndHostRedirect,
59
- shared.middlewares.prettyUrls,
58
+ shared.middleware.urlRedirects.adminSSLAndHostRedirect,
59
+ shared.middleware.prettyUrls,
60
60
  notImplemented
61
61
  ];
62
62
 
@@ -69,8 +69,8 @@ module.exports.authAdminApiWithUrl = [
69
69
  auth.authorize.authorizeAdminApi,
70
70
  apiMw.updateUserLastSeen,
71
71
  apiMw.cors,
72
- shared.middlewares.urlRedirects.adminSSLAndHostRedirect,
73
- shared.middlewares.prettyUrls,
72
+ shared.middleware.urlRedirects.adminSSLAndHostRedirect,
73
+ shared.middleware.prettyUrls,
74
74
  notImplemented
75
75
  ];
76
76
 
@@ -79,7 +79,7 @@ module.exports.authAdminApiWithUrl = [
79
79
  */
80
80
  module.exports.publicAdminApi = [
81
81
  apiMw.cors,
82
- shared.middlewares.urlRedirects.adminSSLAndHostRedirect,
83
- shared.middlewares.prettyUrls,
82
+ shared.middleware.urlRedirects.adminSSLAndHostRedirect,
83
+ shared.middleware.prettyUrls,
84
84
  notImplemented
85
85
  ];
@@ -142,19 +142,19 @@ module.exports = function apiRoutes() {
142
142
  router.get('/session', mw.authAdminApi, http(api.session.read));
143
143
  // We don't need auth when creating a new session (logging in)
144
144
  router.post('/session',
145
- shared.middlewares.brute.globalBlock,
146
- shared.middlewares.brute.userLogin,
145
+ shared.middleware.brute.globalBlock,
146
+ shared.middleware.brute.userLogin,
147
147
  http(api.session.add)
148
148
  );
149
149
  router.del('/session', mw.authAdminApi, http(api.session.delete));
150
150
 
151
151
  // ## Authentication
152
152
  router.post('/authentication/passwordreset',
153
- shared.middlewares.brute.globalReset,
154
- shared.middlewares.brute.userReset,
153
+ shared.middleware.brute.globalReset,
154
+ shared.middleware.brute.userReset,
155
155
  http(api.authentication.generateResetToken)
156
156
  );
157
- router.put('/authentication/passwordreset', shared.middlewares.brute.globalBlock, http(api.authentication.resetPassword));
157
+ router.put('/authentication/passwordreset', shared.middleware.brute.globalBlock, http(api.authentication.resetPassword));
158
158
  router.post('/authentication/invitation', http(api.authentication.acceptInvitation));
159
159
  router.get('/authentication/invitation', http(api.authentication.isInvitation));
160
160
  router.post('/authentication/setup', http(api.authentication.setup));
@@ -18,17 +18,17 @@ module.exports = function setupApiApp() {
18
18
  apiApp.use(boolParser());
19
19
 
20
20
  // send 503 json response in case of maintenance
21
- apiApp.use(shared.middlewares.maintenance);
21
+ apiApp.use(shared.middleware.maintenance);
22
22
 
23
23
  // API shouldn't be cached
24
- apiApp.use(shared.middlewares.cacheControl('private'));
24
+ apiApp.use(shared.middleware.cacheControl('private'));
25
25
 
26
26
  // Routing
27
27
  apiApp.use(routes());
28
28
 
29
29
  // API error handling
30
- apiApp.use(shared.middlewares.errorHandler.resourceNotFound);
31
- apiApp.use(shared.middlewares.errorHandler.handleJSONResponse);
30
+ apiApp.use(shared.middleware.errorHandler.resourceNotFound);
31
+ apiApp.use(shared.middleware.errorHandler.handleJSONResponse);
32
32
 
33
33
  debug('Content API v2 setup end');
34
34
 
@@ -14,10 +14,10 @@ const shared = require('../../../shared');
14
14
  * Authentication for public endpoints
15
15
  */
16
16
  module.exports.authenticatePublic = [
17
- shared.middlewares.brute.contentApiKey,
17
+ shared.middleware.brute.contentApiKey,
18
18
  auth.authenticate.authenticateContentApi,
19
19
  auth.authorize.authorizeContentApi,
20
20
  cors(),
21
- shared.middlewares.urlRedirects.adminSSLAndHostRedirect,
22
- shared.middlewares.prettyUrls
21
+ shared.middleware.urlRedirects.adminSSLAndHostRedirect,
22
+ shared.middleware.prettyUrls
23
23
  ];
@@ -20,21 +20,21 @@ module.exports = function setupApiApp() {
20
20
  apiApp.use(boolParser());
21
21
 
22
22
  // send 503 json response in case of maintenance
23
- apiApp.use(shared.middlewares.maintenance);
23
+ apiApp.use(shared.middleware.maintenance);
24
24
 
25
25
  // Check version matches for API requests, depends on res.locals.safeVersion being set
26
26
  // Therefore must come after themeHandler.ghostLocals, for now
27
27
  apiApp.use(apiMw.versionMatch);
28
28
 
29
29
  // Admin API shouldn't be cached
30
- apiApp.use(shared.middlewares.cacheControl('private'));
30
+ apiApp.use(shared.middleware.cacheControl('private'));
31
31
 
32
32
  // Routing
33
33
  apiApp.use(routes());
34
34
 
35
35
  // API error handling
36
- apiApp.use(shared.middlewares.errorHandler.resourceNotFound);
37
- apiApp.use(shared.middlewares.errorHandler.handleJSONResponseV2);
36
+ apiApp.use(shared.middleware.errorHandler.resourceNotFound);
37
+ apiApp.use(shared.middleware.errorHandler.handleJSONResponseV2);
38
38
 
39
39
  debug('Admin API v3 setup end');
40
40