ghost 4.18.0 → 4.20.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.
- package/.eslintrc.js +9 -8
- package/Gruntfile.js +1 -1
- package/PRIVACY.md +3 -0
- package/content/adapters/README.md +2 -2
- package/core/boot.js +17 -12
- package/core/bridge.js +9 -1
- package/core/built/assets/{chunk.3.b80d3e1e6b8556aaff3c.js → chunk.3.777d43e2ce954ba8b2f5.js} +25 -25
- package/core/built/assets/codemirror/{codemirror-21a09582262987037db73b152fb35f7c.js → codemirror-d25c379b87ec8b33d54ac7149bc0b6ae.js} +14 -14
- package/core/built/assets/ghost-dark-20e2892d4f30d0d1183c9ac725ea37d0.css +1 -0
- package/core/built/assets/{ghost.min-88d647a008a5b1dd678a89ae1e55c038.js → ghost.min-26e427944e719b616b8dc7fbb3bbd2f9.js} +709 -422
- package/core/built/assets/ghost.min-57e46fd3b1145ecf2cbd185a13611f3b.css +1 -0
- package/core/built/assets/icons/arrow-left-small.svg +0 -4
- package/core/built/assets/icons/paintbrush.svg +10 -1
- package/core/built/assets/icons/post.svg +3 -1
- package/core/built/assets/img/footer-marketplace-bg-572b6c6486a7e26316954d599eaa9f30.png +0 -0
- package/core/built/assets/img/marketing/offers-1-f2e1b653c4d5bb90eea9d7a2862530f9.jpg +0 -0
- package/core/built/assets/img/marketing/offers-2-28a225d34cc39d133748431536961d00.jpg +0 -0
- package/core/built/assets/img/marketing/offers-3-2094c91ab21a16c37fbe6ec16c140160.jpg +0 -0
- package/core/built/assets/img/themes/Alto-f4db5af43ca9771c7ac1f754de3ddf2f.png +0 -0
- package/core/built/assets/img/themes/Bulletin-57d45b992ff0e26e0acdce7ed4cccd67.png +0 -0
- package/core/built/assets/img/themes/Casper-c7e784d7188cc5d7f097d9b6c97b0263.jpg +0 -0
- package/core/built/assets/img/themes/Dawn-be81aa8c8caae8fcfb5d5fbec823fdcc.png +0 -0
- package/core/built/assets/img/themes/Digest-d3467ac22a290e1ad3a543014758286e.png +0 -0
- package/core/built/assets/img/themes/Dope-6f8e0bbc199ce4af9a60859e9e6a74ad.png +0 -0
- package/core/built/assets/img/themes/Ease-9c279ea6cec3c0f1823f81c9dd24b116.png +0 -0
- package/core/built/assets/img/themes/Edge-0258906309e11fd075a1d9880aa09b20.png +0 -0
- package/core/built/assets/img/themes/Edition-d8f508e93bc24bdf2716ae6f8b3d44f8.png +0 -0
- package/core/built/assets/img/themes/Editorial-a25a4a34c04dedd858bd5e05ef388b1c.jpg +0 -0
- package/core/built/assets/img/themes/Journal-accf0031bbae0919900a049061e65a04.png +0 -0
- package/core/built/assets/img/themes/London-3f07efcee9e5bfb9a33827064eb77e70.jpg +0 -0
- package/core/built/assets/img/themes/Massively-06edf00108429f7fb8e65f190fba34fe.jpg +0 -0
- package/core/built/assets/img/themes/Ruby-11a53c62015612f4b3aca8f503121225.png +0 -0
- package/core/built/assets/img/themes/Wave-86e8044c2d76cb57a9030e4c24ac9520.png +0 -0
- package/core/built/assets/simplemde/{simplemde-232f69d126310434489071a1891e6d8b.js → simplemde-3ffc0ec9e9fecf29b9a499db678c9e65.js} +14 -14
- package/core/built/assets/{vendor.min-7dc7cf9c92175ebfb9cea95c120ee8a7.js → vendor.min-af502ac4142871500fc424f6a5a254ec.js} +2206 -1859
- package/core/frontend/apps/amp/lib/router.js +1 -1
- package/core/frontend/helpers/match.js +17 -23
- package/core/frontend/meta/author-url.js +1 -1
- package/core/frontend/meta/url.js +1 -1
- package/core/{server → frontend}/public/favicon.ico +0 -0
- package/core/{server → frontend}/public/ghost.css +0 -0
- package/core/{server → frontend}/public/ghost.min.css +0 -0
- package/core/{server → frontend}/public/robots.txt +0 -0
- package/core/{server → frontend}/public/sitemap.xsl +0 -0
- package/core/frontend/services/proxy.js +1 -1
- package/core/frontend/services/rendering.js +1 -1
- package/core/frontend/services/routing/CollectionRouter.js +3 -49
- package/core/frontend/services/routing/ParentRouter.js +1 -4
- package/core/frontend/services/routing/StaticPagesRouter.js +3 -5
- package/core/frontend/services/routing/StaticRoutesRouter.js +4 -6
- package/core/frontend/services/routing/TaxonomyRouter.js +4 -5
- package/core/frontend/services/routing/controllers/collection.js +2 -2
- package/core/frontend/services/routing/controllers/email-post.js +2 -2
- package/core/frontend/services/routing/controllers/entry.js +2 -2
- package/core/frontend/services/routing/controllers/preview.js +2 -2
- package/core/frontend/services/routing/index.js +6 -12
- package/core/frontend/services/routing/registry.js +13 -0
- package/core/frontend/services/routing/router-manager.js +185 -0
- package/core/frontend/services/rss/generate-feed.js +2 -2
- package/core/frontend/services/theme-engine/i18n/i18n.js +267 -28
- package/core/frontend/services/theme-engine/i18n/index.js +1 -1
- package/core/frontend/services/theme-engine/i18n/theme-i18n.js +73 -0
- package/core/frontend/web/index.js +1 -0
- package/core/{server/web/site → frontend/web}/middleware/handle-image-sizes.js +4 -4
- package/core/{server/web/site → frontend/web}/middleware/index.js +0 -0
- package/core/{server/web/site → frontend/web}/middleware/redirect-ghost-to-admin.js +3 -3
- package/core/{server/web/site → frontend/web}/middleware/serve-favicon.js +6 -6
- package/core/{server/web/site → frontend/web}/middleware/serve-public-file.js +2 -2
- package/core/{server/web/site → frontend/web}/middleware/static-theme.js +3 -3
- package/core/frontend/web/routes.js +13 -0
- package/core/{server/web/site/app.js → frontend/web/site.js} +12 -16
- package/core/server/adapters/storage/LocalFileStorage.js +35 -39
- package/core/server/adapters/storage/index.js +12 -2
- package/core/server/api/canary/custom-theme-settings.js +2 -2
- package/core/server/api/canary/images.js +1 -1
- package/core/server/api/canary/oembed.js +2 -2
- package/core/server/api/canary/offers.js +29 -1
- package/core/server/api/canary/posts-public.js +6 -2
- package/core/server/api/canary/products.js +6 -2
- package/core/server/api/canary/tags-public.js +6 -2
- package/core/server/api/canary/users.js +9 -4
- package/core/server/api/canary/utils/serializers/output/custom-theme-settings.js +2 -2
- package/core/server/api/canary/utils/serializers/output/notifications.js +1 -0
- package/core/server/api/canary/utils/serializers/output/settings.js +2 -3
- package/core/server/api/canary/utils/serializers/output/utils/url.js +1 -1
- package/core/server/api/canary/utils/validators/input/oembed.js +4 -1
- package/core/server/api/canary/utils/validators/input/passwordreset.js +8 -3
- package/core/server/api/canary/utils/validators/input/settings.js +5 -4
- package/core/server/api/canary/utils/validators/input/setup.js +6 -2
- package/core/server/api/canary/utils/validators/input/users.js +6 -2
- package/core/server/api/canary/utils/validators/input/webhooks.js +8 -3
- package/core/server/api/v2/images.js +1 -1
- package/core/server/api/v2/utils/serializers/output/authentication.js +9 -4
- package/core/server/api/v2/utils/serializers/output/notifications.js +1 -0
- package/core/server/api/v2/utils/serializers/output/users.js +5 -3
- package/core/server/api/v2/utils/serializers/output/utils/url.js +1 -1
- package/core/server/api/v2/utils/validators/input/images.js +11 -6
- package/core/server/api/v2/utils/validators/input/invitations.js +14 -6
- package/core/server/api/v2/utils/validators/input/invites.js +6 -2
- package/core/server/api/v2/utils/validators/input/oembed.js +6 -2
- package/core/server/api/v2/utils/validators/input/passwordreset.js +8 -3
- package/core/server/api/v2/utils/validators/input/settings.js +10 -4
- package/core/server/api/v2/utils/validators/input/setup.js +6 -2
- package/core/server/api/v2/utils/validators/input/users.js +5 -2
- package/core/server/api/v3/authentication.js +6 -2
- package/core/server/api/v3/authors-public.js +6 -2
- package/core/server/api/v3/email.js +9 -4
- package/core/server/api/v3/images.js +1 -1
- package/core/server/api/v3/integrations.js +7 -3
- package/core/server/api/v3/invites.js +6 -3
- package/core/server/api/v3/labels.js +10 -5
- package/core/server/api/v3/memberSigninUrls.js +5 -2
- package/core/server/api/v3/oembed.js +2 -2
- package/core/server/api/v3/pages-public.js +5 -2
- package/core/server/api/v3/pages.js +6 -3
- package/core/server/api/v3/posts-public.js +5 -3
- package/core/server/api/v3/posts.js +7 -3
- package/core/server/api/v3/preview.js +5 -3
- package/core/server/api/v3/session.js +7 -3
- package/core/server/api/v3/settings.js +8 -3
- package/core/server/api/v3/slugs.js +5 -4
- package/core/server/api/v3/utils/serializers/output/authentication.js +10 -4
- package/core/server/api/v3/utils/serializers/output/notifications.js +1 -0
- package/core/server/api/v3/utils/serializers/output/settings.js +2 -3
- package/core/server/api/v3/utils/serializers/output/users.js +6 -2
- package/core/server/api/v3/utils/serializers/output/utils/url.js +1 -1
- package/core/server/api/v3/utils/validators/input/images.js +12 -7
- package/core/server/api/v3/utils/validators/input/invitations.js +14 -6
- package/core/server/api/v3/utils/validators/input/invites.js +6 -2
- package/core/server/api/v3/utils/validators/input/oembed.js +6 -2
- package/core/server/api/v3/utils/validators/input/passwordreset.js +8 -3
- package/core/server/api/v3/utils/validators/input/settings.js +5 -4
- package/core/server/api/v3/utils/validators/input/setup.js +6 -2
- package/core/server/api/v3/utils/validators/input/users.js +6 -2
- package/core/server/api/v3/utils/validators/input/webhooks.js +8 -3
- package/core/server/data/exporter/table-lists.js +2 -1
- package/core/server/data/importer/handlers/image.js +1 -1
- package/core/server/data/importer/importers/image.js +1 -1
- package/core/server/data/migrations/init/1-create-tables.js +7 -8
- package/core/server/data/migrations/init/2-create-fixtures.js +8 -8
- package/core/server/data/migrations/versions/4.19/01-add-active-column-to-offers.js +7 -0
- package/core/server/data/migrations/versions/4.19/02-add-offer-redemptions-table.js +8 -0
- package/core/server/data/migrations/versions/4.20/01-remove-offer-redemptions-table.js +19 -0
- package/core/server/data/migrations/versions/4.20/02-remove-offers-table.js +30 -0
- package/core/server/data/migrations/versions/4.20/03-add-offers-table.js +21 -0
- package/core/server/data/migrations/versions/4.20/04-add-offer-redemptions-table.js +9 -0
- package/core/server/data/migrations/versions/4.20/05-remove-not-null-constraint-from-portal-title.js +41 -0
- package/core/server/data/schema/fixtures/utils.js +150 -143
- package/core/server/data/schema/schema.js +15 -3
- package/core/server/frontend/ghost.min.css +1 -0
- package/core/server/lib/image/blog-icon.js +10 -10
- package/core/server/lib/image/image-size.js +5 -5
- package/core/server/lib/image/image-utils.js +4 -4
- package/core/server/lib/image/index.js +1 -2
- package/core/server/lib/mobiledoc.js +3 -2
- package/core/server/models/action.js +7 -4
- package/core/server/models/base/plugins/overrides.js +19 -6
- package/core/server/models/custom-theme-setting.js +56 -1
- package/core/server/models/index.js +4 -45
- package/core/server/models/member.js +5 -0
- package/core/server/models/offer-redemption.js +10 -0
- package/core/server/models/user.js +2 -1
- package/core/server/overrides.js +6 -2
- package/core/server/run-update-check.js +0 -3
- package/core/server/services/adapter-manager/config.js +1 -0
- package/core/server/services/adapter-manager/index.js +9 -5
- package/core/server/services/adapter-manager/options-resolver.js +18 -0
- package/core/server/services/bulk-email/bulk-email-processor.js +6 -2
- package/core/server/services/bulk-email/mailgun.js +1 -1
- package/core/server/services/custom-theme-settings.js +10 -4
- package/core/server/services/invites/index.js +0 -2
- package/core/server/services/invites/invites.js +5 -5
- package/core/server/services/mail/GhostMailer.js +18 -10
- package/core/server/services/mega/mega.js +3 -3
- package/core/server/services/mega/post-email-serializer.js +2 -2
- package/core/server/services/members/api.js +3 -4
- package/core/server/services/members/emails/signin.js +1 -1
- package/core/server/services/members/emails/signup.js +1 -1
- package/core/server/services/members/emails/subscribe.js +1 -1
- package/core/server/services/members/middleware.js +10 -0
- package/core/server/services/members/service.js +2 -1
- package/core/server/services/notifications/index.js +1 -1
- package/core/server/services/notifications/notifications.js +40 -35
- package/core/server/services/oembed.js +4 -9
- package/core/server/services/offers/service.js +16 -6
- package/core/server/services/permissions/public.js +6 -2
- package/core/server/services/route-settings/route-settings.js +1 -1
- package/core/server/services/settings/index.js +3 -1
- package/core/server/services/settings/settings-bread-service.js +42 -20
- package/core/server/services/slack.js +1 -1
- package/core/server/services/themes/activate.js +2 -2
- package/core/server/services/themes/activation-bridge.js +6 -6
- package/core/server/services/themes/storage.js +1 -1
- package/core/{frontend → server}/services/url/Queue.js +0 -0
- package/core/{frontend → server}/services/url/Resource.js +0 -0
- package/core/{frontend → server}/services/url/Resources.js +2 -2
- package/core/{frontend → server}/services/url/UrlGenerator.js +14 -14
- package/core/{frontend → server}/services/url/UrlService.js +12 -15
- package/core/{frontend → server}/services/url/Urls.js +1 -1
- package/core/{frontend → server}/services/url/configs/canary.js +0 -0
- package/core/{frontend → server}/services/url/configs/v2.js +0 -0
- package/core/{frontend → server}/services/url/configs/v3.js +0 -0
- package/core/{frontend → server}/services/url/configs/v4.js +0 -0
- package/core/{frontend → server}/services/url/index.js +0 -0
- package/core/server/services/xmlrpc.js +1 -1
- package/core/server/update-check.js +3 -3
- package/core/server/web/admin/controller.js +11 -0
- package/core/server/web/admin/views/default-prod.html +4 -4
- package/core/server/web/admin/views/default.html +4 -4
- package/core/server/web/api/app.js +8 -9
- package/core/server/web/members/app.js +1 -0
- package/core/server/web/oauth/app.js +4 -2
- package/core/server/web/parent/backend.js +3 -3
- package/core/server/web/parent/frontend.js +2 -2
- package/core/server/web/shared/middlewares/api/spam-prevention.js +0 -2
- package/core/server/web/shared/middlewares/custom-redirects.js +0 -8
- package/core/server/web/shared/middlewares/maintenance.js +1 -1
- package/core/server/web/well-known.js +10 -10
- package/core/shared/config/defaults.json +2 -2
- package/core/shared/config/overrides.json +1 -1
- package/core/shared/express.js +10 -0
- package/core/shared/html-to-plaintext.js +2 -2
- package/core/shared/labs.js +14 -6
- package/loggingrc.js +10 -0
- package/package.json +60 -57
- package/yarn.lock +1317 -914
- package/core/built/assets/ghost-dark-13627f10941a7dbb2b12e1d41dc51c34.css +0 -1
- package/core/built/assets/ghost.min-d9cbfb4eb2db8915fcd2bf2416218616.css +0 -1
- package/core/built/assets/img/themes/London-68501c8ab797de7f2851cf9ea0a28e26.jpg +0 -0
- package/core/frontend/services/routing/bootstrap.js +0 -114
- package/core/server/public/404-ghost.png +0 -0
- package/core/server/public/404-ghost@2x.png +0 -0
- package/core/server/web/site/index.js +0 -1
- package/core/server/web/site/routes.js +0 -9
- package/core/shared/i18n/i18n.js +0 -312
- package/core/shared/i18n/index.js +0 -6
- package/core/shared/i18n/translations/en.json +0 -675
|
@@ -29,27 +29,25 @@ class LocalFileStore extends StorageBase {
|
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Saves a buffer in the targetPath
|
|
32
|
-
*
|
|
33
|
-
*
|
|
32
|
+
* @param {Buffer} buffer is an instance of Buffer
|
|
33
|
+
* @param {String} targetPath path to which the buffer should be written
|
|
34
|
+
* @returns {Promise<String>} a URL to retrieve the data
|
|
34
35
|
*/
|
|
35
|
-
saveRaw(buffer, targetPath) {
|
|
36
|
+
async saveRaw(buffer, targetPath) {
|
|
36
37
|
const storagePath = path.join(this.storagePath, targetPath);
|
|
37
38
|
const targetDir = path.dirname(storagePath);
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return fullUrl;
|
|
52
|
-
});
|
|
40
|
+
await fs.mkdirs(targetDir);
|
|
41
|
+
await fs.writeFile(storagePath, buffer);
|
|
42
|
+
|
|
43
|
+
// For local file system storage can use relative path so add a slash
|
|
44
|
+
const fullUrl = (
|
|
45
|
+
urlUtils.urlJoin('/', urlUtils.getSubdir(),
|
|
46
|
+
urlUtils.STATIC_IMAGE_URL_PREFIX,
|
|
47
|
+
targetPath)
|
|
48
|
+
).replace(new RegExp(`\\${path.sep}`, 'g'), '/');
|
|
49
|
+
|
|
50
|
+
return fullUrl;
|
|
53
51
|
}
|
|
54
52
|
|
|
55
53
|
/**
|
|
@@ -57,34 +55,32 @@ class LocalFileStore extends StorageBase {
|
|
|
57
55
|
* - image is the express image object
|
|
58
56
|
* - returns a promise which ultimately returns the full url to the uploaded image
|
|
59
57
|
*
|
|
60
|
-
* @param image
|
|
61
|
-
* @param targetDir
|
|
62
|
-
* @returns {
|
|
58
|
+
* @param {StorageBase.Image} image
|
|
59
|
+
* @param {String} targetDir
|
|
60
|
+
* @returns {Promise<String>}
|
|
63
61
|
*/
|
|
64
|
-
save(image, targetDir) {
|
|
62
|
+
async save(image, targetDir) {
|
|
65
63
|
let targetFilename;
|
|
66
64
|
|
|
67
65
|
// NOTE: the base implementation of `getTargetDir` returns the format this.storagePath/YYYY/MM
|
|
68
66
|
targetDir = targetDir || this.getTargetDir(this.storagePath);
|
|
69
67
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
return Promise.reject(e);
|
|
87
|
-
});
|
|
68
|
+
const filename = await this.getUniqueFileName(image, targetDir);
|
|
69
|
+
|
|
70
|
+
targetFilename = filename;
|
|
71
|
+
await fs.mkdirs(targetDir);
|
|
72
|
+
|
|
73
|
+
await fs.copy(image.path, targetFilename);
|
|
74
|
+
|
|
75
|
+
// The src for the image must be in URI format, not a file system path, which in Windows uses \
|
|
76
|
+
// For local file system storage can use relative path so add a slash
|
|
77
|
+
const fullUrl = (
|
|
78
|
+
urlUtils.urlJoin('/', urlUtils.getSubdir(),
|
|
79
|
+
urlUtils.STATIC_IMAGE_URL_PREFIX,
|
|
80
|
+
path.relative(this.storagePath, targetFilename))
|
|
81
|
+
).replace(new RegExp(`\\${path.sep}`, 'g'), '/');
|
|
82
|
+
|
|
83
|
+
return fullUrl;
|
|
88
84
|
}
|
|
89
85
|
|
|
90
86
|
exists(fileName, targetDir) {
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
const adapterManager = require('../../services/adapter-manager');
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* @param {'images'|'videos'|'audios'} [feature] - name for the "feature" to enable through adapter, e.g.: images or videos storage
|
|
5
|
+
* @returns {Object} adapter instance
|
|
6
|
+
*/
|
|
7
|
+
function getStorage(feature) {
|
|
8
|
+
let adapterName = 'storage';
|
|
9
|
+
|
|
10
|
+
if (feature) {
|
|
11
|
+
adapterName += `:${feature}`;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return adapterManager.getAdapter(adapterName);
|
|
5
15
|
}
|
|
6
16
|
|
|
7
17
|
module.exports.getStorage = getStorage;
|
|
@@ -6,7 +6,7 @@ module.exports = {
|
|
|
6
6
|
browse: {
|
|
7
7
|
permissions: true,
|
|
8
8
|
query() {
|
|
9
|
-
return customThemeSettingsService.listSettings();
|
|
9
|
+
return customThemeSettingsService.api.listSettings();
|
|
10
10
|
}
|
|
11
11
|
},
|
|
12
12
|
|
|
@@ -16,7 +16,7 @@ module.exports = {
|
|
|
16
16
|
},
|
|
17
17
|
permissions: true,
|
|
18
18
|
query(frame) {
|
|
19
|
-
return customThemeSettingsService.updateSettings(frame.data.custom_theme_settings);
|
|
19
|
+
return customThemeSettingsService.api.updateSettings(frame.data.custom_theme_settings);
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const config = require('../../../shared/config');
|
|
2
2
|
const externalRequest = require('../../lib/request-external');
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
const OEmbed = require('../../services/oembed');
|
|
5
|
-
const oembed = new OEmbed({config, externalRequest
|
|
5
|
+
const oembed = new OEmbed({config, externalRequest});
|
|
6
6
|
|
|
7
7
|
module.exports = {
|
|
8
8
|
docName: 'oembed',
|
|
@@ -1,12 +1,21 @@
|
|
|
1
|
+
const tpl = require('@tryghost/tpl');
|
|
2
|
+
const errors = require('@tryghost/errors');
|
|
1
3
|
const offersService = require('../../services/offers');
|
|
2
4
|
|
|
5
|
+
const messages = {
|
|
6
|
+
offerNotFound: 'Offer not found.'
|
|
7
|
+
};
|
|
8
|
+
|
|
3
9
|
module.exports = {
|
|
4
10
|
docName: 'offers',
|
|
5
11
|
|
|
6
12
|
browse: {
|
|
13
|
+
options: [
|
|
14
|
+
'filter'
|
|
15
|
+
],
|
|
7
16
|
permissions: true,
|
|
8
17
|
async query(frame) {
|
|
9
|
-
const offers = await offersService.api.listOffers();
|
|
18
|
+
const offers = await offersService.api.listOffers(frame.options);
|
|
10
19
|
frame.response = {
|
|
11
20
|
offers
|
|
12
21
|
};
|
|
@@ -18,6 +27,12 @@ module.exports = {
|
|
|
18
27
|
permissions: true,
|
|
19
28
|
async query(frame) {
|
|
20
29
|
const offer = await offersService.api.getOffer(frame.data);
|
|
30
|
+
if (!offer) {
|
|
31
|
+
throw new errors.NotFoundError({
|
|
32
|
+
message: tpl(messages.offerNotFound)
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
21
36
|
frame.response = {
|
|
22
37
|
offers: [offer]
|
|
23
38
|
};
|
|
@@ -27,11 +42,21 @@ module.exports = {
|
|
|
27
42
|
edit: {
|
|
28
43
|
options: ['id'],
|
|
29
44
|
permissions: true,
|
|
45
|
+
headers: {
|
|
46
|
+
cacheInvalidate: true
|
|
47
|
+
},
|
|
30
48
|
async query(frame) {
|
|
31
49
|
const offer = await offersService.api.updateOffer({
|
|
32
50
|
...frame.data.offers[0],
|
|
33
51
|
id: frame.options.id
|
|
34
52
|
});
|
|
53
|
+
|
|
54
|
+
if (!offer) {
|
|
55
|
+
throw new errors.NotFoundError({
|
|
56
|
+
message: tpl(messages.offerNotFound)
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
35
60
|
frame.response = {
|
|
36
61
|
offers: [offer]
|
|
37
62
|
};
|
|
@@ -40,6 +65,9 @@ module.exports = {
|
|
|
40
65
|
|
|
41
66
|
add: {
|
|
42
67
|
permissions: true,
|
|
68
|
+
headers: {
|
|
69
|
+
cacheInvalidate: true
|
|
70
|
+
},
|
|
43
71
|
async query(frame) {
|
|
44
72
|
const offer = await offersService.api.createOffer(frame.data.offers[0]);
|
|
45
73
|
frame.response = {
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
const models = require('../../models');
|
|
2
|
-
const
|
|
2
|
+
const tpl = require('@tryghost/tpl');
|
|
3
3
|
const errors = require('@tryghost/errors');
|
|
4
4
|
const allowedIncludes = ['tags', 'authors'];
|
|
5
5
|
|
|
6
|
+
const messages = {
|
|
7
|
+
postNotFound: 'Post not found.'
|
|
8
|
+
};
|
|
9
|
+
|
|
6
10
|
module.exports = {
|
|
7
11
|
docName: 'posts',
|
|
8
12
|
|
|
@@ -63,7 +67,7 @@ module.exports = {
|
|
|
63
67
|
.then((model) => {
|
|
64
68
|
if (!model) {
|
|
65
69
|
throw new errors.NotFoundError({
|
|
66
|
-
message:
|
|
70
|
+
message: tpl(messages.postNotFound)
|
|
67
71
|
});
|
|
68
72
|
}
|
|
69
73
|
|
|
@@ -3,10 +3,14 @@
|
|
|
3
3
|
const errors = require('@tryghost/errors');
|
|
4
4
|
const membersService = require('../../services/members');
|
|
5
5
|
|
|
6
|
-
const
|
|
6
|
+
const tpl = require('@tryghost/tpl');
|
|
7
7
|
|
|
8
8
|
const allowedIncludes = ['stripe_prices', 'monthly_price', 'yearly_price', 'benefits'];
|
|
9
9
|
|
|
10
|
+
const messages = {
|
|
11
|
+
productNotFound: 'Product not found.'
|
|
12
|
+
};
|
|
13
|
+
|
|
10
14
|
module.exports = {
|
|
11
15
|
docName: 'products',
|
|
12
16
|
|
|
@@ -56,7 +60,7 @@ module.exports = {
|
|
|
56
60
|
|
|
57
61
|
if (!model) {
|
|
58
62
|
throw new errors.NotFoundError({
|
|
59
|
-
message:
|
|
63
|
+
message: tpl(messages.productNotFound)
|
|
60
64
|
});
|
|
61
65
|
}
|
|
62
66
|
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
const Promise = require('bluebird');
|
|
2
|
-
const
|
|
2
|
+
const tpl = require('@tryghost/tpl');
|
|
3
3
|
const errors = require('@tryghost/errors');
|
|
4
4
|
const models = require('../../models');
|
|
5
5
|
|
|
6
6
|
const ALLOWED_INCLUDES = ['count.posts'];
|
|
7
7
|
|
|
8
|
+
const messages = {
|
|
9
|
+
tagNotFound: 'Tag not found.'
|
|
10
|
+
};
|
|
11
|
+
|
|
8
12
|
module.exports = {
|
|
9
13
|
docName: 'tags',
|
|
10
14
|
|
|
@@ -56,7 +60,7 @@ module.exports = {
|
|
|
56
60
|
.then((model) => {
|
|
57
61
|
if (!model) {
|
|
58
62
|
return Promise.reject(new errors.NotFoundError({
|
|
59
|
-
message:
|
|
63
|
+
message: tpl(messages.tagNotFound)
|
|
60
64
|
}));
|
|
61
65
|
}
|
|
62
66
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const Promise = require('bluebird');
|
|
2
|
-
const
|
|
2
|
+
const tpl = require('@tryghost/tpl');
|
|
3
3
|
const errors = require('@tryghost/errors');
|
|
4
4
|
const models = require('../../models');
|
|
5
5
|
const permissionsService = require('../../services/permissions');
|
|
@@ -12,11 +12,16 @@ const userService = new UsersService({dbBackup, models, auth, apiMail, apiSettin
|
|
|
12
12
|
const ALLOWED_INCLUDES = ['count.posts', 'permissions', 'roles', 'roles.permissions'];
|
|
13
13
|
const UNSAFE_ATTRS = ['status', 'roles'];
|
|
14
14
|
|
|
15
|
+
const messages = {
|
|
16
|
+
noPermissionToAction: 'You do not have permission to perform this action',
|
|
17
|
+
userNotFound: 'User not found.'
|
|
18
|
+
};
|
|
19
|
+
|
|
15
20
|
function permissionOnlySelf(frame) {
|
|
16
21
|
const targetId = getTargetId(frame);
|
|
17
22
|
const userId = frame.user.id;
|
|
18
23
|
if (targetId !== userId) {
|
|
19
|
-
return Promise.reject(new errors.NoPermissionError({message:
|
|
24
|
+
return Promise.reject(new errors.NoPermissionError({message: tpl(messages.noPermissionToAction)}));
|
|
20
25
|
}
|
|
21
26
|
return Promise.resolve();
|
|
22
27
|
}
|
|
@@ -88,7 +93,7 @@ module.exports = {
|
|
|
88
93
|
.then((model) => {
|
|
89
94
|
if (!model) {
|
|
90
95
|
return Promise.reject(new errors.NotFoundError({
|
|
91
|
-
message:
|
|
96
|
+
message: tpl(messages.userNotFound)
|
|
92
97
|
}));
|
|
93
98
|
}
|
|
94
99
|
|
|
@@ -121,7 +126,7 @@ module.exports = {
|
|
|
121
126
|
.then((model) => {
|
|
122
127
|
if (!model) {
|
|
123
128
|
return Promise.reject(new errors.NotFoundError({
|
|
124
|
-
message:
|
|
129
|
+
message: tpl(messages.userNotFound)
|
|
125
130
|
}));
|
|
126
131
|
}
|
|
127
132
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
module.exports = {
|
|
2
2
|
browse(models, apiConfig, frame) {
|
|
3
3
|
frame.response = {
|
|
4
|
-
|
|
4
|
+
custom_theme_settings: models
|
|
5
5
|
};
|
|
6
6
|
},
|
|
7
7
|
|
|
8
8
|
edit(models, apiConfig, frame) {
|
|
9
9
|
frame.response = {
|
|
10
|
-
|
|
10
|
+
custom_theme_settings: models
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
13
|
};
|
|
@@ -55,9 +55,8 @@ module.exports = {
|
|
|
55
55
|
this.browse(...arguments);
|
|
56
56
|
},
|
|
57
57
|
|
|
58
|
-
edit(
|
|
59
|
-
|
|
60
|
-
this.browse(settingsKeyedJSON, apiConfig, frame);
|
|
58
|
+
edit() {
|
|
59
|
+
this.browse(...arguments);
|
|
61
60
|
},
|
|
62
61
|
|
|
63
62
|
download(bytes, apiConfig, frame) {
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
const Promise = require('bluebird');
|
|
2
2
|
const tpl = require('@tryghost/tpl');
|
|
3
3
|
const errors = require('@tryghost/errors');
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
const messages = {
|
|
6
|
+
noUrlProvided: 'No url provided.'
|
|
7
|
+
};
|
|
5
8
|
|
|
6
9
|
module.exports = {
|
|
7
10
|
read(apiConfig, frame) {
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
const Promise = require('bluebird');
|
|
2
2
|
const validator = require('@tryghost/validator');
|
|
3
3
|
const debug = require('@tryghost/debug')('api:canary:utils:validators:input:passwordreset');
|
|
4
|
-
const
|
|
4
|
+
const tpl = require('@tryghost/tpl');
|
|
5
5
|
const errors = require('@tryghost/errors');
|
|
6
6
|
|
|
7
|
+
const messages = {
|
|
8
|
+
newPasswordsDoNotMatch: 'Your new passwords do not match',
|
|
9
|
+
invalidEmailReceived: 'The server did not receive a valid email'
|
|
10
|
+
};
|
|
11
|
+
|
|
7
12
|
module.exports = {
|
|
8
13
|
resetPassword(apiConfig, frame) {
|
|
9
14
|
debug('resetPassword');
|
|
@@ -12,7 +17,7 @@ module.exports = {
|
|
|
12
17
|
|
|
13
18
|
if (data.newPassword !== data.ne2Password) {
|
|
14
19
|
return Promise.reject(new errors.ValidationError({
|
|
15
|
-
message:
|
|
20
|
+
message: tpl(messages.newPasswordsDoNotMatch)
|
|
16
21
|
}));
|
|
17
22
|
}
|
|
18
23
|
},
|
|
@@ -24,7 +29,7 @@ module.exports = {
|
|
|
24
29
|
|
|
25
30
|
if (typeof email !== 'string' || !validator.isEmail(email)) {
|
|
26
31
|
throw new errors.BadRequestError({
|
|
27
|
-
message:
|
|
32
|
+
message: tpl(messages.invalidEmailReceived)
|
|
28
33
|
});
|
|
29
34
|
}
|
|
30
35
|
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
const Promise = require('bluebird');
|
|
2
2
|
const _ = require('lodash');
|
|
3
|
-
const
|
|
3
|
+
const tpl = require('@tryghost/tpl');
|
|
4
4
|
const {NotFoundError, ValidationError, BadRequestError} = require('@tryghost/errors');
|
|
5
5
|
const validator = require('@tryghost/validator');
|
|
6
6
|
|
|
7
7
|
const messages = {
|
|
8
8
|
invalidEmailReceived: 'Please send a valid email',
|
|
9
|
-
invalidEmailTypeReceived: 'Invalid email type received'
|
|
9
|
+
invalidEmailTypeReceived: 'Invalid email type received',
|
|
10
|
+
problemFindingSetting: 'Problem finding setting: {key}'
|
|
10
11
|
};
|
|
11
12
|
|
|
12
13
|
module.exports = {
|
|
@@ -14,7 +15,7 @@ module.exports = {
|
|
|
14
15
|
// @NOTE: was removed https://github.com/TryGhost/Ghost/issues/10373
|
|
15
16
|
if (frame.options.key === 'ghost_head' || frame.options.key === 'ghost_foot') {
|
|
16
17
|
return Promise.reject(new NotFoundError({
|
|
17
|
-
message:
|
|
18
|
+
message: tpl(messages.problemFindingSetting, {
|
|
18
19
|
key: frame.options.key
|
|
19
20
|
})
|
|
20
21
|
}));
|
|
@@ -28,7 +29,7 @@ module.exports = {
|
|
|
28
29
|
if (setting.key === 'ghost_head' || setting.key === 'ghost_foot') {
|
|
29
30
|
// @NOTE: was removed https://github.com/TryGhost/Ghost/issues/10373
|
|
30
31
|
errors.push(new NotFoundError({
|
|
31
|
-
message:
|
|
32
|
+
message: tpl(messages.problemFindingSetting, {
|
|
32
33
|
key: setting.key
|
|
33
34
|
})
|
|
34
35
|
}));
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
const debug = require('@tryghost/debug')('api:canary:utils:validators:input:updateSetup');
|
|
2
|
-
const
|
|
2
|
+
const tpl = require('@tryghost/tpl');
|
|
3
3
|
const errors = require('@tryghost/errors');
|
|
4
4
|
|
|
5
|
+
const messages = {
|
|
6
|
+
notTheBlogOwner: 'You are not the site owner.'
|
|
7
|
+
};
|
|
8
|
+
|
|
5
9
|
module.exports = {
|
|
6
10
|
updateSetup(apiConfig, frame) {
|
|
7
11
|
debug('resetPassword');
|
|
8
12
|
|
|
9
13
|
if (!frame.options.context || !frame.options.context.user) {
|
|
10
|
-
throw new errors.NoPermissionError({message:
|
|
14
|
+
throw new errors.NoPermissionError({message: tpl(messages.notTheBlogOwner)});
|
|
11
15
|
}
|
|
12
16
|
}
|
|
13
17
|
};
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
const Promise = require('bluebird');
|
|
2
2
|
const debug = require('@tryghost/debug')('api:canary:utils:validators:input:users');
|
|
3
|
-
const
|
|
3
|
+
const tpl = require('@tryghost/tpl');
|
|
4
4
|
const errors = require('@tryghost/errors');
|
|
5
5
|
|
|
6
|
+
const messages = {
|
|
7
|
+
newPasswordsDoNotMatch: 'Your new passwords do not match'
|
|
8
|
+
};
|
|
9
|
+
|
|
6
10
|
module.exports = {
|
|
7
11
|
changePassword(apiConfig, frame) {
|
|
8
12
|
debug('changePassword');
|
|
@@ -11,7 +15,7 @@ module.exports = {
|
|
|
11
15
|
|
|
12
16
|
if (data.newPassword !== data.ne2Password) {
|
|
13
17
|
return Promise.reject(new errors.ValidationError({
|
|
14
|
-
message:
|
|
18
|
+
message: tpl(messages.newPasswordsDoNotMatch)
|
|
15
19
|
}));
|
|
16
20
|
}
|
|
17
21
|
}
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
const _ = require('lodash');
|
|
2
2
|
const errors = require('@tryghost/errors');
|
|
3
|
-
const
|
|
3
|
+
const tpl = require('@tryghost/tpl');
|
|
4
4
|
const jsonSchema = require('../utils/json-schema');
|
|
5
5
|
|
|
6
|
+
const messages = {
|
|
7
|
+
schemaValidationFailed: 'Validation failed for \'{key}\'.',
|
|
8
|
+
noIntegrationIdProvidedContext: 'You may only create webhooks with \'integration_id\' when using session authentication.'
|
|
9
|
+
};
|
|
10
|
+
|
|
6
11
|
module.exports = {
|
|
7
12
|
add(apiConfig, frame) {
|
|
8
13
|
if (!_.get(frame, 'options.context.integration.id') && !_.get(frame.data, 'webhooks[0].integration_id')) {
|
|
9
14
|
return Promise.reject(new errors.ValidationError({
|
|
10
|
-
message:
|
|
15
|
+
message: tpl(messages.schemaValidationFailed, {
|
|
11
16
|
key: 'integration_id'
|
|
12
17
|
}),
|
|
13
|
-
context:
|
|
18
|
+
context: tpl(messages.noIntegrationIdProvidedContext),
|
|
14
19
|
property: 'integration_id'
|
|
15
20
|
}));
|
|
16
21
|
}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
const
|
|
1
|
+
const tpl = require('@tryghost/tpl');
|
|
2
2
|
const mapper = require('./utils/mapper');
|
|
3
3
|
const debug = require('@tryghost/debug')('api:v2:utils:serializers:output:authentication');
|
|
4
|
+
const messages = {
|
|
5
|
+
checkEmailForInstructions: 'Check your email for further instructions.',
|
|
6
|
+
passwordChanged: 'Password changed successfully.',
|
|
7
|
+
invitationAccepted: 'Invitation accepted.'
|
|
8
|
+
};
|
|
4
9
|
|
|
5
10
|
module.exports = {
|
|
6
11
|
setup(user, apiConfig, frame) {
|
|
@@ -28,7 +33,7 @@ module.exports = {
|
|
|
28
33
|
generateResetToken(data, apiConfig, frame) {
|
|
29
34
|
frame.response = {
|
|
30
35
|
passwordreset: [{
|
|
31
|
-
message:
|
|
36
|
+
message: tpl(messages.checkEmailForInstructions)
|
|
32
37
|
}]
|
|
33
38
|
};
|
|
34
39
|
},
|
|
@@ -36,7 +41,7 @@ module.exports = {
|
|
|
36
41
|
resetPassword(data, apiConfig, frame) {
|
|
37
42
|
frame.response = {
|
|
38
43
|
passwordreset: [{
|
|
39
|
-
message:
|
|
44
|
+
message: tpl(messages.passwordChanged)
|
|
40
45
|
}]
|
|
41
46
|
};
|
|
42
47
|
},
|
|
@@ -46,7 +51,7 @@ module.exports = {
|
|
|
46
51
|
|
|
47
52
|
frame.response = {
|
|
48
53
|
invitation: [
|
|
49
|
-
{message:
|
|
54
|
+
{message: tpl(messages.invitationAccepted)}
|
|
50
55
|
]
|
|
51
56
|
};
|
|
52
57
|
},
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
const debug = require('@tryghost/debug')('api:v2:utils:serializers:output:users');
|
|
2
|
-
const
|
|
2
|
+
const tpl = require('@tryghost/tpl');
|
|
3
3
|
const mapper = require('./utils/mapper');
|
|
4
|
-
|
|
4
|
+
const messages = {
|
|
5
|
+
pwdChangedSuccessfully: 'Password changed successfully.'
|
|
6
|
+
};
|
|
5
7
|
module.exports = {
|
|
6
8
|
browse(models, apiConfig, frame) {
|
|
7
9
|
debug('browse');
|
|
@@ -29,7 +31,7 @@ module.exports = {
|
|
|
29
31
|
debug('changePassword');
|
|
30
32
|
|
|
31
33
|
frame.response = {
|
|
32
|
-
password: [{message:
|
|
34
|
+
password: [{message: tpl(messages.pwdChangedSuccessfully)}]
|
|
33
35
|
};
|
|
34
36
|
},
|
|
35
37
|
|