ghost 5.10.1 → 5.12.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/components/{tryghost-adapter-manager-5.10.1.tgz → tryghost-adapter-manager-5.12.1.tgz} +0 -0
- package/components/tryghost-api-framework-5.12.1.tgz +0 -0
- package/components/tryghost-api-version-compatibility-service-5.12.1.tgz +0 -0
- package/components/{tryghost-bootstrap-socket-5.10.1.tgz → tryghost-bootstrap-socket-5.12.1.tgz} +0 -0
- package/components/tryghost-constants-5.12.1.tgz +0 -0
- package/components/{tryghost-custom-theme-settings-service-5.10.1.tgz → tryghost-custom-theme-settings-service-5.12.1.tgz} +0 -0
- package/components/tryghost-domain-events-5.12.1.tgz +0 -0
- package/components/{tryghost-email-analytics-provider-mailgun-5.10.1.tgz → tryghost-email-analytics-provider-mailgun-5.12.1.tgz} +0 -0
- package/components/{tryghost-email-analytics-service-5.10.1.tgz → tryghost-email-analytics-service-5.12.1.tgz} +0 -0
- package/components/{tryghost-email-content-generator-5.10.1.tgz → tryghost-email-content-generator-5.12.1.tgz} +0 -0
- package/components/tryghost-express-dynamic-redirects-5.12.1.tgz +0 -0
- package/components/tryghost-extract-api-key-5.12.1.tgz +0 -0
- package/components/{tryghost-html-to-plaintext-5.10.1.tgz → tryghost-html-to-plaintext-5.12.1.tgz} +0 -0
- package/components/{tryghost-job-manager-5.10.1.tgz → tryghost-job-manager-5.12.1.tgz} +0 -0
- package/components/tryghost-magic-link-5.12.1.tgz +0 -0
- package/components/tryghost-mailgun-client-5.12.1.tgz +0 -0
- package/components/tryghost-member-analytics-service-5.12.1.tgz +0 -0
- package/components/tryghost-member-attribution-5.12.1.tgz +0 -0
- package/components/tryghost-member-events-5.12.1.tgz +0 -0
- package/components/{tryghost-members-analytics-ingress-5.10.1.tgz → tryghost-members-analytics-ingress-5.12.1.tgz} +0 -0
- package/components/tryghost-members-api-5.12.1.tgz +0 -0
- package/components/{tryghost-members-csv-5.10.1.tgz → tryghost-members-csv-5.12.1.tgz} +0 -0
- package/components/{tryghost-members-events-service-5.10.1.tgz → tryghost-members-events-service-5.12.1.tgz} +0 -0
- package/components/tryghost-members-importer-5.12.1.tgz +0 -0
- package/components/tryghost-members-offers-5.12.1.tgz +0 -0
- package/components/{tryghost-members-payments-5.10.1.tgz → tryghost-members-payments-5.12.1.tgz} +0 -0
- package/components/tryghost-members-ssr-5.12.1.tgz +0 -0
- package/components/{tryghost-members-stripe-service-5.10.1.tgz → tryghost-members-stripe-service-5.12.1.tgz} +0 -0
- package/components/tryghost-minifier-5.12.1.tgz +0 -0
- package/components/tryghost-mw-api-version-mismatch-5.12.1.tgz +0 -0
- package/components/{tryghost-mw-cache-control-5.10.1.tgz → tryghost-mw-cache-control-5.12.1.tgz} +0 -0
- package/components/tryghost-mw-error-handler-5.12.1.tgz +0 -0
- package/components/{tryghost-mw-session-from-token-5.10.1.tgz → tryghost-mw-session-from-token-5.12.1.tgz} +0 -0
- package/components/tryghost-mw-update-user-last-seen-5.12.1.tgz +0 -0
- package/components/tryghost-mw-vhost-5.12.1.tgz +0 -0
- package/components/{tryghost-oembed-service-5.10.1.tgz → tryghost-oembed-service-5.12.1.tgz} +0 -0
- package/components/{tryghost-package-json-5.10.1.tgz → tryghost-package-json-5.12.1.tgz} +0 -0
- package/components/{tryghost-security-5.10.1.tgz → tryghost-security-5.12.1.tgz} +0 -0
- package/components/{tryghost-session-service-5.10.1.tgz → tryghost-session-service-5.12.1.tgz} +0 -0
- package/components/tryghost-settings-path-manager-5.12.1.tgz +0 -0
- package/components/tryghost-staff-service-5.12.1.tgz +0 -0
- package/components/{tryghost-update-check-service-5.10.1.tgz → tryghost-update-check-service-5.12.1.tgz} +0 -0
- package/components/tryghost-verification-trigger-5.12.1.tgz +0 -0
- package/components/{tryghost-version-notifications-data-service-5.10.1.tgz → tryghost-version-notifications-data-service-5.12.1.tgz} +0 -0
- package/core/boot.js +2 -0
- package/core/built/admin/assets/chunk.143.cae75c9fa9b7050ffee8.js +49 -0
- package/core/built/admin/assets/{chunk.174.0364e8abdae8210d8e6d.js → chunk.174.ae492405065373dbe102.js} +1 -1
- package/core/built/admin/assets/{chunk.178.bb46965ba0483c3e79ae.js → chunk.178.0487ee9895eefb6e2baf.js} +4 -4
- package/core/built/admin/assets/{chunk.351.ea4a4ff4b40d5f2ad141.js → chunk.579.65e09dd89eec70d059a0.js} +3 -11
- package/core/built/admin/assets/{chunk.351.ea4a4ff4b40d5f2ad141.js.LICENSE.txt → chunk.579.65e09dd89eec70d059a0.js.LICENSE.txt} +0 -0
- package/core/built/admin/assets/{ghost-ced03a7ac75c3148e0ea7d1bf51e39fc.js → ghost-0526c96b20843697927c1d06a9010197.js} +779 -610
- package/core/built/admin/assets/ghost-0bbbef127e5dc0c0651fc442c4fdba8e.css +1 -0
- package/core/built/admin/assets/ghost-dark-27e002e66fbfdfaf3efcde63d5429c38.css +1 -0
- package/core/built/admin/assets/icons/calendar-stroke.svg +1 -0
- package/core/built/admin/assets/icons/event-canceled-subscription--feature-attribution.svg +6 -0
- package/core/built/admin/assets/icons/event-comment--feature-attribution.svg +3 -0
- package/core/built/admin/assets/icons/event-email-delivery-failed--feature-attribution.svg +6 -0
- package/core/built/admin/assets/icons/event-logged-in--feature-attribution.svg +5 -0
- package/core/built/admin/assets/icons/event-made-a-payment--feature-attribution.svg +7 -0
- package/core/built/admin/assets/icons/event-opened-email--feature-attribution.svg +6 -0
- package/core/built/admin/assets/icons/event-received-email--feature-attribution.svg +5 -0
- package/core/built/admin/assets/icons/event-signed-up--feature-attribution.svg +6 -0
- package/core/built/admin/assets/icons/event-started-subscription--feature-attribution.svg +6 -0
- package/core/built/admin/assets/icons/event-subscribed-to-email--feature-attribution.svg +8 -0
- package/core/built/admin/assets/icons/event-subscriptions--feature-attribution.svg +5 -0
- package/core/built/admin/assets/icons/event-unsubscribed-from-email--feature-attribution.svg +5 -0
- package/core/built/admin/assets/icons/pen-stroke.svg +1 -0
- package/core/built/admin/assets/{vendor-a1ae7a38d5c38fcba5609eed4e37f02a.js → vendor-52613f40d62355e9ac64cbfa211169bb.js} +88 -60
- package/core/built/admin/index.html +6 -6
- package/core/frontend/helpers/search.js +5 -20
- package/core/frontend/meta/get-meta.js +1 -2
- package/core/frontend/meta/image-dimensions.js +47 -39
- package/core/server/api/endpoints/comments-members.js +10 -7
- package/core/server/api/endpoints/invites.js +1 -9
- package/core/server/api/endpoints/labels.js +1 -7
- package/core/server/api/endpoints/members.js +3 -13
- package/core/server/api/endpoints/offers.js +2 -2
- package/core/server/api/endpoints/pages.js +2 -10
- package/core/server/api/endpoints/posts.js +1 -9
- package/core/server/api/endpoints/settings.js +0 -94
- package/core/server/api/endpoints/snippets.js +1 -9
- package/core/server/api/endpoints/tags.js +1 -7
- package/core/server/api/endpoints/utils/serializers/input/pages.js +1 -1
- package/core/server/api/endpoints/utils/serializers/output/members.js +2 -1
- package/core/server/api/endpoints/utils/serializers/output/site.js +1 -0
- package/core/server/api/endpoints/utils/serializers/output/utils/clean.js +6 -7
- package/core/server/api/endpoints/utils/validators/input/settings.js +1 -20
- package/core/server/api/endpoints/webhooks.js +2 -19
- package/core/server/data/migrations/versions/5.11/2022-08-22-11-03-add-member-alert-settings-columns-to-users.js +21 -0
- package/core/server/data/migrations/versions/5.11/2022-08-23-13-41-backfill-members-created-events.js +32 -0
- package/core/server/data/migrations/versions/5.11/2022-08-23-13-59-fix-page-resource-type.js +22 -0
- package/core/server/data/schema/fixtures/fixtures.json +3 -0
- package/core/server/data/schema/schema.js +23 -4
- package/core/server/lib/image/gravatar.js +8 -7
- package/core/server/lib/image/image-size.js +60 -56
- package/core/server/models/action.js +6 -19
- package/core/server/models/base/plugins/actions.js +26 -3
- package/core/server/models/member-created-event.js +10 -2
- package/core/server/models/member-paid-subscription-event.js +4 -0
- package/core/server/models/member.js +18 -0
- package/core/server/models/offer.js +3 -0
- package/core/server/models/post.js +2 -3
- package/core/server/models/product.js +3 -0
- package/core/server/models/settings.js +4 -0
- package/core/server/models/subscription-created-event.js +10 -2
- package/core/server/models/user.js +41 -7
- package/core/server/services/auth/api-key/admin.js +0 -3
- package/core/server/services/auth/passwordreset.js +0 -3
- package/core/server/services/explore/service.js +7 -6
- package/core/server/services/mega/mega.js +7 -4
- package/core/server/services/mega/template.js +44 -16
- package/core/server/services/member-attribution/index.js +34 -6
- package/core/server/services/members/api.js +4 -0
- package/core/server/services/members/middleware.js +6 -2
- package/core/server/services/members/service.js +6 -3
- package/core/server/services/public-config/site.js +1 -0
- package/core/server/services/route-settings/default-settings-manager.js +19 -17
- package/core/server/services/staff/index.js +26 -0
- package/core/server/services/webhooks/trigger.js +14 -5
- package/core/server/web/api/endpoints/admin/middleware.js +1 -3
- package/core/server/web/api/endpoints/admin/routes.js +0 -7
- package/core/shared/config/defaults.json +3 -2
- package/core/shared/labs.js +8 -7
- package/package.json +86 -84
- package/yarn.lock +134 -181
- package/components/tryghost-api-framework-5.10.1.tgz +0 -0
- package/components/tryghost-api-version-compatibility-service-5.10.1.tgz +0 -0
- package/components/tryghost-constants-5.10.1.tgz +0 -0
- package/components/tryghost-domain-events-5.10.1.tgz +0 -0
- package/components/tryghost-express-dynamic-redirects-5.10.1.tgz +0 -0
- package/components/tryghost-extract-api-key-5.10.1.tgz +0 -0
- package/components/tryghost-magic-link-5.10.1.tgz +0 -0
- package/components/tryghost-mailgun-client-5.10.1.tgz +0 -0
- package/components/tryghost-member-analytics-service-5.10.1.tgz +0 -0
- package/components/tryghost-member-attribution-5.10.1.tgz +0 -0
- package/components/tryghost-member-events-5.10.1.tgz +0 -0
- package/components/tryghost-members-api-5.10.1.tgz +0 -0
- package/components/tryghost-members-importer-5.10.1.tgz +0 -0
- package/components/tryghost-members-offers-5.10.1.tgz +0 -0
- package/components/tryghost-members-ssr-5.10.1.tgz +0 -0
- package/components/tryghost-minifier-5.10.1.tgz +0 -0
- package/components/tryghost-mw-api-version-mismatch-5.10.1.tgz +0 -0
- package/components/tryghost-mw-error-handler-5.10.1.tgz +0 -0
- package/components/tryghost-mw-update-user-last-seen-5.10.1.tgz +0 -0
- package/components/tryghost-mw-vhost-5.10.1.tgz +0 -0
- package/components/tryghost-settings-path-manager-5.10.1.tgz +0 -0
- package/components/tryghost-verification-trigger-5.10.1.tgz +0 -0
- package/core/built/admin/assets/chunk.143.71da0e884297554a8ec4.js +0 -41
- package/core/built/admin/assets/ghost-13baab17b3f54b21f341fb8f36f83110.css +0 -1
- package/core/built/admin/assets/ghost-dark-b0500577a42e2770994e6aef0e70f182.css +0 -1
|
@@ -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%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.
|
|
11
|
+
<meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%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.12%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22moment%22%3A%7B%22includeTimezone%22%3A%22all%22%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%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-bc9d2c9e5c8a33f0c92e81189d48e04c.css">
|
|
40
|
-
<link integrity="" rel="stylesheet" href="assets/ghost-
|
|
40
|
+
<link integrity="" rel="stylesheet" href="assets/ghost-0bbbef127e5dc0c0651fc442c4fdba8e.css" title="light">
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
</head>
|
|
@@ -53,9 +53,9 @@
|
|
|
53
53
|
|
|
54
54
|
<div id="ember-basic-dropdown-wormhole"></div>
|
|
55
55
|
|
|
56
|
-
<script src="assets/vendor-
|
|
57
|
-
<script src="assets/chunk.
|
|
58
|
-
<script src="assets/chunk.143.
|
|
59
|
-
<script src="assets/ghost-
|
|
56
|
+
<script src="assets/vendor-52613f40d62355e9ac64cbfa211169bb.js"></script>
|
|
57
|
+
<script src="assets/chunk.579.65e09dd89eec70d059a0.js"></script>
|
|
58
|
+
<script src="assets/chunk.143.cae75c9fa9b7050ffee8.js"></script>
|
|
59
|
+
<script src="assets/ghost-0526c96b20843697927c1d06a9010197.js"></script>
|
|
60
60
|
</body>
|
|
61
61
|
</html>
|
|
@@ -4,26 +4,11 @@ const {SafeString} = require('../services/handlebars');
|
|
|
4
4
|
const {labs} = require('../services/proxy');
|
|
5
5
|
|
|
6
6
|
function search() {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
height: 32px;
|
|
13
|
-
padding: 0;
|
|
14
|
-
border: 0;
|
|
15
|
-
color: inherit;
|
|
16
|
-
background-color: transparent;
|
|
17
|
-
cursor: pointer;
|
|
18
|
-
outline: none;
|
|
19
|
-
}</style>
|
|
20
|
-
<button class="gh-search-icon" aria-label="search" data-ghost-search>
|
|
21
|
-
<svg width="20" height="20" fill="none" viewBox="0 0 24 24">
|
|
22
|
-
<path d="M14.949 14.949a1 1 0 0 1 1.414 0l6.344 6.344a1 1 0 0 1-1.414 1.414l-6.344-6.344a1 1 0 0 1 0-1.414Z"
|
|
23
|
-
fill="currentColor"/>
|
|
24
|
-
<path d="M10 3a7 7 0 1 0 0 14 7 7 0 0 0 0-14Zm-9 7a9 9 0 1 1 18 0 9 9 0 0 1-18 0Z" fill="currentColor"/>
|
|
25
|
-
</svg>
|
|
26
|
-
</button>`;
|
|
7
|
+
// We want this to output as one line, but splitting for readability
|
|
8
|
+
const svg = '<button class="gh-search-icon" aria-label="search" data-ghost-search '
|
|
9
|
+
+ 'style="display: inline-flex; justify-content: center; align-items: center; width: 32px; height: 32px; padding: 0; border: 0; color: inherit; background-color: transparent; cursor: pointer; outline: none;">'
|
|
10
|
+
+ '<svg width="20" height="20" fill="none" viewBox="0 0 24 24"><path d="M14.949 14.949a1 1 0 0 1 1.414 0l6.344 6.344a1 1 0 0 1-1.414 1.414l-6.344-6.344a1 1 0 0 1 0-1.414Z" fill="currentColor"/>'
|
|
11
|
+
+ '<path d="M10 3a7 7 0 1 0 0 14 7 7 0 0 0 0-14Zm-9 7a9 9 0 1 1 18 0 9 9 0 0 1-18 0Z" fill="currentColor"/></svg></button>';
|
|
27
12
|
|
|
28
13
|
return new SafeString(svg);
|
|
29
14
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const Promise = require('bluebird');
|
|
2
1
|
const settingsCache = require('../../shared/settings-cache');
|
|
3
2
|
const urlUtils = require('../../shared/url-utils');
|
|
4
3
|
const logging = require('@tryghost/logging');
|
|
@@ -81,7 +80,7 @@ function getMetaData(data, root) {
|
|
|
81
80
|
}
|
|
82
81
|
|
|
83
82
|
// @TODO: wrap this in a utility function
|
|
84
|
-
return
|
|
83
|
+
return getImageDimensions(metaData).then(function () {
|
|
85
84
|
metaData.structuredData = getStructuredData(metaData);
|
|
86
85
|
metaData.schema = getSchema(metaData, data);
|
|
87
86
|
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
const Promise = require('bluebird');
|
|
2
1
|
const _ = require('lodash');
|
|
3
2
|
const imageSizeCache = require('../../server/lib/image').cachedImageSizeFromUrl;
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* Get Image dimensions
|
|
7
6
|
* @param {object} metaData
|
|
8
|
-
* @returns {object} metaData
|
|
7
|
+
* @returns {Promise<object>} metaData
|
|
9
8
|
* @description for image properties in meta data (coverImage, authorImage and site.logo), `getCachedImageSizeFromUrl` is
|
|
10
9
|
* called to receive image width and height
|
|
11
10
|
*/
|
|
12
|
-
function getImageDimensions(metaData) {
|
|
11
|
+
async function getImageDimensions(metaData) {
|
|
13
12
|
const fetch = {
|
|
14
13
|
coverImage: imageSizeCache.getCachedImageSizeFromUrl(metaData.coverImage.url),
|
|
15
14
|
authorImage: imageSizeCache.getCachedImageSizeFromUrl(metaData.authorImage.url),
|
|
@@ -17,45 +16,54 @@ function getImageDimensions(metaData) {
|
|
|
17
16
|
logo: imageSizeCache.getCachedImageSizeFromUrl(metaData.site.logo.url)
|
|
18
17
|
};
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
.
|
|
22
|
-
.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
19
|
+
const [coverImage, authorImage, ogImage, logo] = await Promise.all([
|
|
20
|
+
fetch.coverImage,
|
|
21
|
+
fetch.authorImage,
|
|
22
|
+
fetch.ogImage,
|
|
23
|
+
fetch.logo
|
|
24
|
+
]);
|
|
25
|
+
const imageObj = {
|
|
26
|
+
coverImage,
|
|
27
|
+
authorImage,
|
|
28
|
+
ogImage,
|
|
29
|
+
logo
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
_.forEach(imageObj, function (key, value) {
|
|
33
|
+
if (_.has(key, 'width') && _.has(key, 'height')) {
|
|
34
|
+
// We have some restrictions for publisher.logo:
|
|
35
|
+
// The image needs to be <=600px wide and <=60px high (ideally exactly 600px x 60px).
|
|
36
|
+
// Unless we have proper image-handling (see https://github.com/TryGhost/Ghost/issues/4453),
|
|
37
|
+
// we will fake it in some cases or not produce an imageObject at all.
|
|
38
|
+
if (value === 'logo') {
|
|
39
|
+
if (key.height <= 60 && key.width <= 600) {
|
|
40
|
+
_.assign(metaData.site[value], {
|
|
41
|
+
dimensions: {
|
|
42
|
+
width: key.width,
|
|
43
|
+
height: key.height
|
|
45
44
|
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
45
|
+
});
|
|
46
|
+
} else if (key.width === key.height) {
|
|
47
|
+
// CASE: the logo is too large, but it is a square. We fake it...
|
|
48
|
+
_.assign(metaData.site[value], {
|
|
49
|
+
dimensions: {
|
|
50
|
+
width: 60,
|
|
51
|
+
height: 60
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
54
|
}
|
|
55
|
-
}
|
|
55
|
+
} else {
|
|
56
|
+
_.assign(metaData[value], {
|
|
57
|
+
dimensions: {
|
|
58
|
+
width: key.width,
|
|
59
|
+
height: key.height
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
});
|
|
56
65
|
|
|
57
|
-
|
|
58
|
-
});
|
|
66
|
+
return metaData;
|
|
59
67
|
}
|
|
60
68
|
|
|
61
69
|
module.exports = getImageDimensions;
|
|
@@ -189,8 +189,6 @@ module.exports = {
|
|
|
189
189
|
validation: {},
|
|
190
190
|
permissions: true,
|
|
191
191
|
query(frame) {
|
|
192
|
-
frame.options.require = true;
|
|
193
|
-
|
|
194
192
|
// TODO: move to likes service
|
|
195
193
|
if (frame.options?.context?.member?.id) {
|
|
196
194
|
return models.CommentLike.destroy({
|
|
@@ -198,12 +196,17 @@ module.exports = {
|
|
|
198
196
|
destroyBy: {
|
|
199
197
|
member_id: frame.options.context.member.id,
|
|
200
198
|
comment_id: frame.options.id
|
|
201
|
-
}
|
|
199
|
+
},
|
|
200
|
+
require: true
|
|
202
201
|
}).then(() => null)
|
|
203
|
-
.catch(
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
202
|
+
.catch((err) => {
|
|
203
|
+
if (err instanceof models.CommentLike.NotFoundError) {
|
|
204
|
+
return Promise.reject(new errors.NotFoundError({
|
|
205
|
+
message: tpl(messages.likeNotFound)
|
|
206
|
+
}));
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
throw err;
|
|
207
210
|
});
|
|
208
211
|
} else {
|
|
209
212
|
return Promise.reject(new errors.NotFoundError({
|
|
@@ -76,15 +76,7 @@ module.exports = {
|
|
|
76
76
|
},
|
|
77
77
|
permissions: true,
|
|
78
78
|
query(frame) {
|
|
79
|
-
frame.options
|
|
80
|
-
|
|
81
|
-
return models.Invite.destroy(frame.options)
|
|
82
|
-
.then(() => null)
|
|
83
|
-
.catch(models.Invite.NotFoundError, () => {
|
|
84
|
-
return Promise.reject(new errors.NotFoundError({
|
|
85
|
-
message: tpl(messages.inviteNotFound)
|
|
86
|
-
}));
|
|
87
|
-
});
|
|
79
|
+
return models.Invite.destroy({...frame.options, require: true});
|
|
88
80
|
}
|
|
89
81
|
},
|
|
90
82
|
|
|
@@ -150,13 +150,7 @@ module.exports = {
|
|
|
150
150
|
},
|
|
151
151
|
permissions: true,
|
|
152
152
|
query(frame) {
|
|
153
|
-
return models.Label.destroy(frame.options)
|
|
154
|
-
.then(() => null)
|
|
155
|
-
.catch(models.Label.NotFoundError, () => {
|
|
156
|
-
return Promise.reject(new errors.NotFoundError({
|
|
157
|
-
message: tpl(messages.labelNotFound)
|
|
158
|
-
}));
|
|
159
|
-
});
|
|
153
|
+
return models.Label.destroy({...frame.options, require: true});
|
|
160
154
|
}
|
|
161
155
|
}
|
|
162
156
|
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// NOTE: We must not cache references to membersService.api
|
|
2
2
|
// as it is a getter and may change during runtime.
|
|
3
|
-
const Promise = require('bluebird');
|
|
4
3
|
const moment = require('moment-timezone');
|
|
5
4
|
const errors = require('@tryghost/errors');
|
|
6
5
|
const models = require('../../models');
|
|
@@ -253,20 +252,11 @@ module.exports = {
|
|
|
253
252
|
},
|
|
254
253
|
permissions: true,
|
|
255
254
|
async query(frame) {
|
|
256
|
-
|
|
257
|
-
frame.options.cancelStripeSubscriptions = frame.options.cancel;
|
|
258
|
-
|
|
259
|
-
await Promise.resolve(membersService.api.members.destroy({
|
|
255
|
+
return membersService.api.members.destroy({
|
|
260
256
|
id: frame.options.id
|
|
261
|
-
},
|
|
262
|
-
|
|
263
|
-
message: tpl(messages.resourceNotFound, {
|
|
264
|
-
resource: 'Member'
|
|
265
|
-
})
|
|
266
|
-
});
|
|
257
|
+
}, {
|
|
258
|
+
...frame.options, require: true, cancelStripeSubscriptions: frame.options.cancel
|
|
267
259
|
});
|
|
268
|
-
|
|
269
|
-
return null;
|
|
270
260
|
}
|
|
271
261
|
},
|
|
272
262
|
|
|
@@ -49,7 +49,7 @@ module.exports = {
|
|
|
49
49
|
const offer = await offersService.api.updateOffer({
|
|
50
50
|
...frame.data.offers[0],
|
|
51
51
|
id: frame.options.id
|
|
52
|
-
});
|
|
52
|
+
}, frame.options);
|
|
53
53
|
|
|
54
54
|
if (!offer) {
|
|
55
55
|
throw new errors.NotFoundError({
|
|
@@ -69,7 +69,7 @@ module.exports = {
|
|
|
69
69
|
cacheInvalidate: true
|
|
70
70
|
},
|
|
71
71
|
async query(frame) {
|
|
72
|
-
const offer = await offersService.api.createOffer(frame.data.offers[0]);
|
|
72
|
+
const offer = await offersService.api.createOffer(frame.data.offers[0], frame.options);
|
|
73
73
|
return {
|
|
74
74
|
data: [offer]
|
|
75
75
|
};
|
|
@@ -2,7 +2,7 @@ const models = require('../../models');
|
|
|
2
2
|
const tpl = require('@tryghost/tpl');
|
|
3
3
|
const errors = require('@tryghost/errors');
|
|
4
4
|
const getPostServiceInstance = require('../../services/posts/posts-service');
|
|
5
|
-
const ALLOWED_INCLUDES = ['tags', 'authors', 'authors.roles', 'tiers'];
|
|
5
|
+
const ALLOWED_INCLUDES = ['tags', 'authors', 'authors.roles', 'tiers', 'count.signups', 'count.conversions'];
|
|
6
6
|
const UNSAFE_ATTRS = ['status', 'authors', 'visibility'];
|
|
7
7
|
|
|
8
8
|
const messages = {
|
|
@@ -186,15 +186,7 @@ module.exports = {
|
|
|
186
186
|
unsafeAttrs: UNSAFE_ATTRS
|
|
187
187
|
},
|
|
188
188
|
query(frame) {
|
|
189
|
-
frame.options
|
|
190
|
-
|
|
191
|
-
return models.Post.destroy(frame.options)
|
|
192
|
-
.then(() => null)
|
|
193
|
-
.catch(models.Post.NotFoundError, () => {
|
|
194
|
-
return Promise.reject(new errors.NotFoundError({
|
|
195
|
-
message: tpl(messages.pageNotFound)
|
|
196
|
-
}));
|
|
197
|
-
});
|
|
189
|
+
return models.Post.destroy({...frame.options, require: true});
|
|
198
190
|
}
|
|
199
191
|
}
|
|
200
192
|
};
|
|
@@ -192,15 +192,7 @@ module.exports = {
|
|
|
192
192
|
unsafeAttrs: unsafeAttrs
|
|
193
193
|
},
|
|
194
194
|
query(frame) {
|
|
195
|
-
frame.options
|
|
196
|
-
|
|
197
|
-
return models.Post.destroy(frame.options)
|
|
198
|
-
.then(() => null)
|
|
199
|
-
.catch(models.Post.NotFoundError, () => {
|
|
200
|
-
return Promise.reject(new errors.NotFoundError({
|
|
201
|
-
message: tpl(messages.postNotFound)
|
|
202
|
-
}));
|
|
203
|
-
});
|
|
195
|
+
return models.Post.destroy({...frame.options, require: true});
|
|
204
196
|
}
|
|
205
197
|
}
|
|
206
198
|
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const Promise = require('bluebird');
|
|
2
1
|
const _ = require('lodash');
|
|
3
2
|
const models = require('../../models');
|
|
4
3
|
const routeSettings = require('../../services/route-settings');
|
|
@@ -6,13 +5,8 @@ const {BadRequestError} = require('@tryghost/errors');
|
|
|
6
5
|
const settingsService = require('../../services/settings/settings-service');
|
|
7
6
|
const membersService = require('../../services/members');
|
|
8
7
|
const stripeService = require('../../services/stripe');
|
|
9
|
-
const tpl = require('@tryghost/tpl');
|
|
10
8
|
const settingsBREADService = settingsService.getSettingsBREADServiceInstance();
|
|
11
9
|
|
|
12
|
-
const messages = {
|
|
13
|
-
failedSendingEmail: 'Failed Sending Email'
|
|
14
|
-
};
|
|
15
|
-
|
|
16
10
|
async function getStripeConnectData(frame) {
|
|
17
11
|
const stripeConnectIntegrationToken = frame.data.settings.find(setting => setting.key === 'stripe_connect_integration_token');
|
|
18
12
|
|
|
@@ -77,94 +71,6 @@ module.exports = {
|
|
|
77
71
|
}
|
|
78
72
|
},
|
|
79
73
|
|
|
80
|
-
/**
|
|
81
|
-
* @deprecated
|
|
82
|
-
*/
|
|
83
|
-
updateMembersEmail: {
|
|
84
|
-
statusCode: 204,
|
|
85
|
-
permissions: {
|
|
86
|
-
method: 'edit'
|
|
87
|
-
},
|
|
88
|
-
data: [
|
|
89
|
-
'email',
|
|
90
|
-
'type'
|
|
91
|
-
],
|
|
92
|
-
async query(frame) {
|
|
93
|
-
const {email, type} = frame.data;
|
|
94
|
-
|
|
95
|
-
try {
|
|
96
|
-
// Mapped internally to the newer method of changing emails
|
|
97
|
-
const actionToKeyMapping = {
|
|
98
|
-
supportAddressUpdate: 'members_support_address'
|
|
99
|
-
};
|
|
100
|
-
const edit = {
|
|
101
|
-
key: actionToKeyMapping[type],
|
|
102
|
-
value: email
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
await settingsBREADService.edit([edit], frame.options, null);
|
|
106
|
-
} catch (err) {
|
|
107
|
-
throw new BadRequestError({
|
|
108
|
-
err,
|
|
109
|
-
message: tpl(messages.failedSendingEmail)
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
},
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* @todo can get removed, since this is moved to verifyKeyUpdate
|
|
117
|
-
* @deprecated: keep to not break existing email verification links, but remove after 1 - 2 releases
|
|
118
|
-
*/
|
|
119
|
-
validateMembersEmailUpdate: {
|
|
120
|
-
options: [
|
|
121
|
-
'token',
|
|
122
|
-
'action'
|
|
123
|
-
],
|
|
124
|
-
permissions: false,
|
|
125
|
-
validation: {
|
|
126
|
-
options: {
|
|
127
|
-
token: {
|
|
128
|
-
required: true
|
|
129
|
-
},
|
|
130
|
-
action: {
|
|
131
|
-
values: ['supportaddressupdate']
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
},
|
|
135
|
-
async query(frame) {
|
|
136
|
-
// This is something you have to do if you want to use the "framework" with access to the raw req/res
|
|
137
|
-
frame.response = async function (req, res) {
|
|
138
|
-
try {
|
|
139
|
-
const {token, action} = frame.options;
|
|
140
|
-
const updatedEmailAddress = await membersService.settings.getEmailFromToken({token});
|
|
141
|
-
const actionToKeyMapping = {
|
|
142
|
-
supportAddressUpdate: 'members_support_address'
|
|
143
|
-
};
|
|
144
|
-
if (updatedEmailAddress) {
|
|
145
|
-
return models.Settings.edit({
|
|
146
|
-
key: actionToKeyMapping[action],
|
|
147
|
-
value: updatedEmailAddress
|
|
148
|
-
}).then(() => {
|
|
149
|
-
// Redirect to Ghost-Admin settings page
|
|
150
|
-
const adminLink = membersService.settings.getAdminRedirectLink({type: action});
|
|
151
|
-
res.redirect(adminLink);
|
|
152
|
-
});
|
|
153
|
-
} else {
|
|
154
|
-
return Promise.reject(new BadRequestError({
|
|
155
|
-
message: 'Invalid token!'
|
|
156
|
-
}));
|
|
157
|
-
}
|
|
158
|
-
} catch (err) {
|
|
159
|
-
return Promise.reject(new BadRequestError({
|
|
160
|
-
err,
|
|
161
|
-
message: 'Invalid token!'
|
|
162
|
-
}));
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
},
|
|
167
|
-
|
|
168
74
|
disconnectStripeConnectIntegration: {
|
|
169
75
|
statusCode: 204,
|
|
170
76
|
permissions: {
|
|
@@ -101,15 +101,7 @@ module.exports = {
|
|
|
101
101
|
},
|
|
102
102
|
permissions: true,
|
|
103
103
|
query(frame) {
|
|
104
|
-
frame.options
|
|
105
|
-
|
|
106
|
-
return models.Snippet.destroy(frame.options)
|
|
107
|
-
.then(() => null)
|
|
108
|
-
.catch(models.Snippet.NotFoundError, () => {
|
|
109
|
-
return Promise.reject(new errors.NotFoundError({
|
|
110
|
-
message: tpl(messages.snippetNotFound)
|
|
111
|
-
}));
|
|
112
|
-
});
|
|
104
|
+
return models.Snippet.destroy({...frame.options, require: true});
|
|
113
105
|
}
|
|
114
106
|
}
|
|
115
107
|
};
|
|
@@ -147,13 +147,7 @@ module.exports = {
|
|
|
147
147
|
},
|
|
148
148
|
permissions: true,
|
|
149
149
|
query(frame) {
|
|
150
|
-
return models.Tag.destroy(frame.options)
|
|
151
|
-
.then(() => null)
|
|
152
|
-
.catch(models.Tag.NotFoundError, () => {
|
|
153
|
-
return Promise.reject(new errors.NotFoundError({
|
|
154
|
-
message: tpl(messages.tagNotFound)
|
|
155
|
-
}));
|
|
156
|
-
});
|
|
150
|
+
return models.Tag.destroy({...frame.options, require: true});
|
|
157
151
|
}
|
|
158
152
|
}
|
|
159
153
|
};
|
|
@@ -23,7 +23,7 @@ function defaultRelations(frame) {
|
|
|
23
23
|
return false;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
frame.options.withRelated = ['tags', 'authors', 'authors.roles', 'tiers'];
|
|
26
|
+
frame.options.withRelated = ['tags', 'authors', 'authors.roles', 'tiers', 'count.signups', 'count.conversions'];
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
function setDefaultOrder(frame) {
|
|
@@ -128,7 +128,8 @@ function serializeMember(member, options) {
|
|
|
128
128
|
email_open_rate: json.email_open_rate,
|
|
129
129
|
email_recipients: json.email_recipients,
|
|
130
130
|
status: json.status,
|
|
131
|
-
last_seen_at: json.last_seen_at
|
|
131
|
+
last_seen_at: json.last_seen_at,
|
|
132
|
+
attribution: json.attribution
|
|
132
133
|
};
|
|
133
134
|
|
|
134
135
|
if (json.products) {
|
|
@@ -32,6 +32,9 @@ const author = (attrs, frame) => {
|
|
|
32
32
|
delete attrs.status;
|
|
33
33
|
delete attrs.email;
|
|
34
34
|
delete attrs.comment_notifications;
|
|
35
|
+
delete attrs.free_member_signup_notification;
|
|
36
|
+
delete attrs.paid_subscription_started_notification;
|
|
37
|
+
delete attrs.paid_subscription_canceled_notification;
|
|
35
38
|
|
|
36
39
|
// @NOTE: used for night shift
|
|
37
40
|
delete attrs.accessibility;
|
|
@@ -130,9 +133,6 @@ const post = (attrs, frame) => {
|
|
|
130
133
|
|
|
131
134
|
const action = (attrs) => {
|
|
132
135
|
if (attrs.actor) {
|
|
133
|
-
delete attrs.actor_id;
|
|
134
|
-
delete attrs.resource_id;
|
|
135
|
-
|
|
136
136
|
if (attrs.actor_type === 'user') {
|
|
137
137
|
attrs.actor = _.pick(attrs.actor, ['id', 'name', 'slug', 'profile_image']);
|
|
138
138
|
attrs.actor.image = attrs.actor.profile_image;
|
|
@@ -142,12 +142,11 @@ const action = (attrs) => {
|
|
|
142
142
|
attrs.actor.image = attrs.actor.icon_image;
|
|
143
143
|
delete attrs.actor.icon_image;
|
|
144
144
|
}
|
|
145
|
-
}
|
|
146
|
-
delete attrs.actor_id;
|
|
147
|
-
delete attrs.resource_id;
|
|
145
|
+
}
|
|
148
146
|
|
|
147
|
+
if (attrs.resource) {
|
|
149
148
|
// @NOTE: we only support posts right now
|
|
150
|
-
attrs.resource = _.pick(attrs.resource, ['id', 'title', 'slug', 'feature_image']);
|
|
149
|
+
attrs.resource = _.pick(attrs.resource, ['id', 'title', 'slug', 'feature_image', 'name']);
|
|
151
150
|
attrs.resource.image = attrs.resource.feature_image;
|
|
152
151
|
delete attrs.resource.feature_image;
|
|
153
152
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const Promise = require('bluebird');
|
|
2
2
|
const _ = require('lodash');
|
|
3
|
-
const {ValidationError
|
|
3
|
+
const {ValidationError} = require('@tryghost/errors');
|
|
4
4
|
const validator = require('@tryghost/validator');
|
|
5
5
|
const tpl = require('@tryghost/tpl');
|
|
6
6
|
|
|
@@ -71,24 +71,5 @@ module.exports = {
|
|
|
71
71
|
if (errors.length) {
|
|
72
72
|
return Promise.reject(errors[0]);
|
|
73
73
|
}
|
|
74
|
-
},
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* @deprecated
|
|
78
|
-
*/
|
|
79
|
-
updateMembersEmail(apiConfig, frame) {
|
|
80
|
-
const {email, type} = frame.data;
|
|
81
|
-
|
|
82
|
-
if (typeof email !== 'string' || !validator.isEmail(email)) {
|
|
83
|
-
throw new BadRequestError({
|
|
84
|
-
message: messages.invalidEmailReceived
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (!type || !['supportAddressUpdate'].includes(type)) {
|
|
89
|
-
throw new BadRequestError({
|
|
90
|
-
message: messages.invalidEmailTypeReceived
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
74
|
}
|
|
94
75
|
};
|
|
@@ -78,14 +78,7 @@ module.exports = {
|
|
|
78
78
|
}
|
|
79
79
|
},
|
|
80
80
|
query({data, options}) {
|
|
81
|
-
return models.Webhook.edit(data.webhooks[0],
|
|
82
|
-
.catch(models.Webhook.NotFoundError, () => {
|
|
83
|
-
throw new errors.NotFoundError({
|
|
84
|
-
message: tpl(messages.resourceNotFound, {
|
|
85
|
-
resource: 'Webhook'
|
|
86
|
-
})
|
|
87
|
-
});
|
|
88
|
-
});
|
|
81
|
+
return models.Webhook.edit(data.webhooks[0], {...options, require: true});
|
|
89
82
|
}
|
|
90
83
|
},
|
|
91
84
|
|
|
@@ -130,17 +123,7 @@ module.exports = {
|
|
|
130
123
|
}
|
|
131
124
|
},
|
|
132
125
|
query(frame) {
|
|
133
|
-
frame.options
|
|
134
|
-
|
|
135
|
-
return models.Webhook.destroy(frame.options)
|
|
136
|
-
.then(() => null)
|
|
137
|
-
.catch(models.Webhook.NotFoundError, () => {
|
|
138
|
-
return Promise.reject(new errors.NotFoundError({
|
|
139
|
-
message: tpl(messages.resourceNotFound, {
|
|
140
|
-
resource: 'Webhook'
|
|
141
|
-
})
|
|
142
|
-
}));
|
|
143
|
-
});
|
|
126
|
+
return models.Webhook.destroy({...frame.options, require: true});
|
|
144
127
|
}
|
|
145
128
|
}
|
|
146
129
|
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const {createAddColumnMigration, combineNonTransactionalMigrations} = require('../../utils');
|
|
2
|
+
|
|
3
|
+
module.exports = combineNonTransactionalMigrations(
|
|
4
|
+
createAddColumnMigration('users', 'free_member_signup_notification', {
|
|
5
|
+
type: 'boolean',
|
|
6
|
+
nullable: false,
|
|
7
|
+
defaultTo: true
|
|
8
|
+
}),
|
|
9
|
+
|
|
10
|
+
createAddColumnMigration('users', 'paid_subscription_canceled_notification', {
|
|
11
|
+
type: 'boolean',
|
|
12
|
+
nullable: false,
|
|
13
|
+
defaultTo: false
|
|
14
|
+
}),
|
|
15
|
+
|
|
16
|
+
createAddColumnMigration('users', 'paid_subscription_started_notification', {
|
|
17
|
+
type: 'boolean',
|
|
18
|
+
nullable: false,
|
|
19
|
+
defaultTo: true
|
|
20
|
+
})
|
|
21
|
+
);
|