ghost 5.129.2 → 5.130.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/tryghost-i18n-5.130.0.tgz +0 -0
- package/core/built/admin/assets/admin-x-activitypub/admin-x-activitypub.js +2 -2
- package/core/built/admin/assets/admin-x-activitypub/{index-B12913rO.mjs → index-BhgdXgH_.mjs} +2 -2
- package/core/built/admin/assets/admin-x-activitypub/{index-B7EmcyVj.mjs → index-rDFm98Ub.mjs} +15498 -15418
- package/core/built/admin/assets/admin-x-settings/{CodeEditorView-l2Ex2555.mjs → CodeEditorView-bO8i1M7l.mjs} +2 -2
- package/core/built/admin/assets/admin-x-settings/admin-x-settings.js +3 -3
- package/core/built/admin/assets/admin-x-settings/{index-C6P_16OJ.mjs → index-BeD9DTp3.mjs} +2 -2
- package/core/built/admin/assets/admin-x-settings/index-DIak5kz8.mjs +30462 -0
- package/core/built/admin/assets/admin-x-settings/{modals-CY1xx4Em.mjs → modals-DLPpqlUq.mjs} +7537 -7543
- package/core/built/admin/assets/{chunk.524.c8313bccd308920abf9c.js → chunk.524.2443bfd380e6da0cbabd.js} +8 -8
- package/core/built/admin/assets/{chunk.582.e4feab981886cfc91835.js → chunk.582.434476dff5ddc79ed054.js} +10 -10
- package/core/built/admin/assets/{ghost-db9fcb8c1f65776f3ee11c39f19a660b.js → ghost-5d9c65b5c4ef960a664cd664b2616dea.js} +4 -4
- package/core/built/admin/assets/posts/posts.js +6641 -6621
- package/core/built/admin/assets/stats/stats.js +12770 -12724
- package/core/built/admin/index.html +3 -3
- package/core/frontend/helpers/match.js +3 -0
- package/core/frontend/meta/schema.js +19 -0
- package/core/server/api/endpoints/utils/serializers/input/settings.js +3 -1
- package/core/server/api/endpoints/utils/serializers/input/utils/settings-key-group-mapper.js +3 -1
- package/core/server/api/endpoints/utils/serializers/input/utils/settings-key-type-mapper.js +3 -1
- package/core/server/api/endpoints/utils/serializers/output/config.js +2 -1
- package/core/server/data/migrations/versions/5.130/2025-07-11-14-14-54-add-explore-settings.js +16 -0
- package/core/server/data/schema/default-settings/default-settings.json +18 -0
- package/core/server/services/activitypub/ActivityPubService.js +22 -2
- package/core/server/services/activitypub/ActivityPubService.ts +26 -6
- package/core/server/services/email-service/email-templates/partials/styles.hbs +0 -14
- package/core/server/services/explore-ping/ExplorePingService.js +44 -33
- package/core/server/services/public-config/config.js +4 -0
- package/core/server/services/themes/installer.js +17 -3
- package/core/shared/config/env/config.production.json +4 -0
- package/package.json +6 -6
- package/tsconfig.tsbuildinfo +1 -1
- package/yarn.lock +185 -154
- package/components/tryghost-i18n-5.129.2.tgz +0 -0
- package/core/built/admin/assets/admin-x-settings/index-DoLRADbr.mjs +0 -30308
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<title>Ghost</title>
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
<meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%22%2C%22cdnUrl%22%3A%22%22%2C%22editorUrl%22%3A%22%22%2C%22rootURL%22%3A%22%22%2C%22locationType%22%3A%22trailing-hash%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%2C%22Array%22%3Atrue%2C%22String%22%3Atrue%2C%22Function%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_JQUERY_INTEGRATION%22%3Atrue%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%225.
|
|
9
|
+
<meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%22%2C%22cdnUrl%22%3A%22%22%2C%22editorUrl%22%3A%22%22%2C%22rootURL%22%3A%22%22%2C%22locationType%22%3A%22trailing-hash%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%2C%22Array%22%3Atrue%2C%22String%22%3Atrue%2C%22Function%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_JQUERY_INTEGRATION%22%3Atrue%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%225.130%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22%40sentry%2Fember%22%3A%7B%22disablePerformance%22%3Atrue%2C%22sentry%22%3A%7B%7D%7D%2C%22ember-cli-mirage%22%3A%7B%22usingProxy%22%3Afalse%2C%22useDefaultPassthroughs%22%3Atrue%7D%2C%22exportApplicationGlobal%22%3Afalse%2C%22ember-load%22%3A%7B%22loadingIndicatorClass%22%3A%22ember-load-indicator%22%7D%2C%22editorFilename%22%3A%22koenig-lexical.umd.js%22%2C%22editorHash%22%3A%2237bd1e3e4d%22%2C%22adminXSettingsFilename%22%3A%22admin-x-settings.js%22%2C%22adminXSettingsHash%22%3A%2262b55e2aae%22%2C%22adminXActivitypubFilename%22%3A%22admin-x-activitypub.js%22%2C%22adminXActivitypubHash%22%3A%226d96d71fe8%22%2C%22postsFilename%22%3A%22posts.js%22%2C%22postsHash%22%3A%223ad9cd1892%22%2C%22statsFilename%22%3A%22stats.js%22%2C%22statsHash%22%3A%22701e8fc366%22%2C%22adminXActivitypubCustomUrl%22%3A%22https%3A%2F%2Fcdn.jsdelivr.net%2Fghost%2Fadmin-x-activitypub%400%2Fdist%2Fadmin-x-activitypub.js%22%7D" />
|
|
10
10
|
|
|
11
11
|
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1, minimal-ui, viewport-fit=cover" />
|
|
12
12
|
<meta name="pinterest" content="nopin" />
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
|
|
50
50
|
<script src="assets/vendor-c89102f24c3d9502e9db741509767580.js"></script>
|
|
51
51
|
<script src="assets/chunk.728.214803966b81ffdb1acd.js"></script>
|
|
52
|
-
<script src="assets/chunk.524.
|
|
53
|
-
<script src="assets/ghost-
|
|
52
|
+
<script src="assets/chunk.524.2443bfd380e6da0cbabd.js"></script>
|
|
53
|
+
<script src="assets/ghost-5d9c65b5c4ef960a664cd664b2616dea.js"></script>
|
|
54
54
|
</body>
|
|
55
55
|
</html>
|
|
@@ -57,6 +57,9 @@ const handleMatch = (data, operator, value) => {
|
|
|
57
57
|
case '<=':
|
|
58
58
|
result = data <= value;
|
|
59
59
|
break;
|
|
60
|
+
case '~':
|
|
61
|
+
result = _.isString(data) && _.isString(value) && data.includes(value);
|
|
62
|
+
break;
|
|
60
63
|
case '~^':
|
|
61
64
|
result = _.isString(data) && _.isString(value) && data.startsWith(value);
|
|
62
65
|
break;
|
|
@@ -78,6 +78,24 @@ function trimSameAs(author) {
|
|
|
78
78
|
return sameAs;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Build contributor objects for schema.org Article schema.
|
|
83
|
+
*
|
|
84
|
+
* @param {Object[]} authors - Array of author objects (excluding primary author)
|
|
85
|
+
*/
|
|
86
|
+
function buildContributorObjects(authors) {
|
|
87
|
+
return authors.map(author => trimSchema({
|
|
88
|
+
'@type': 'Person',
|
|
89
|
+
name: escapeExpression(author.name),
|
|
90
|
+
image: author.profile_image ? schemaImageObject({url: author.profile_image}) : null,
|
|
91
|
+
url: author.url || null,
|
|
92
|
+
sameAs: trimSameAs(author),
|
|
93
|
+
description: author.meta_description ?
|
|
94
|
+
escapeExpression(author.meta_description) :
|
|
95
|
+
null
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
|
|
81
99
|
function getPostSchema(metaData, data) {
|
|
82
100
|
// CASE: metaData.excerpt for post context is populated by either the custom excerpt, the meta description,
|
|
83
101
|
// or the automated excerpt of 50 words. It is empty for any other context.
|
|
@@ -101,6 +119,7 @@ function getPostSchema(metaData, data) {
|
|
|
101
119
|
escapeExpression(data[context].primary_author.metaDescription) :
|
|
102
120
|
null
|
|
103
121
|
},
|
|
122
|
+
contributor: data[context].authors && data[context].authors.length > 1 ? buildContributorObjects(data[context].authors.slice(1)) : null,
|
|
104
123
|
headline: escapeExpression(metaData.metaTitle),
|
|
105
124
|
url: metaData.url,
|
|
106
125
|
datePublished: metaData.publishedDate,
|
package/core/server/api/endpoints/utils/serializers/input/utils/settings-key-group-mapper.js
CHANGED
|
@@ -48,7 +48,9 @@ const keyGroupMapping = {
|
|
|
48
48
|
portal_name: 'portal',
|
|
49
49
|
portal_button: 'portal',
|
|
50
50
|
portal_plans: 'portal',
|
|
51
|
-
require_email_mfa: 'security'
|
|
51
|
+
require_email_mfa: 'security',
|
|
52
|
+
explore_ping: 'explore',
|
|
53
|
+
explore_ping_growth: 'explore'
|
|
52
54
|
};
|
|
53
55
|
|
|
54
56
|
const mapKeyToGroup = (key) => {
|
|
@@ -55,7 +55,9 @@ const keyTypeMapping = {
|
|
|
55
55
|
labs: 'object',
|
|
56
56
|
unsplash: 'object',
|
|
57
57
|
bulk_email_settings: 'object',
|
|
58
|
-
require_email_mfa: 'boolean'
|
|
58
|
+
require_email_mfa: 'boolean',
|
|
59
|
+
explore_ping: 'boolean',
|
|
60
|
+
explore_ping_growth: 'boolean'
|
|
59
61
|
};
|
|
60
62
|
|
|
61
63
|
const mapKeyToType = (key) => {
|
package/core/server/data/migrations/versions/5.130/2025-07-11-14-14-54-add-explore-settings.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const {combineTransactionalMigrations, addSetting} = require('../../utils');
|
|
2
|
+
|
|
3
|
+
module.exports = combineTransactionalMigrations(
|
|
4
|
+
addSetting({
|
|
5
|
+
key: 'explore_ping',
|
|
6
|
+
value: 'true',
|
|
7
|
+
type: 'boolean',
|
|
8
|
+
group: 'explore'
|
|
9
|
+
}),
|
|
10
|
+
addSetting({
|
|
11
|
+
key: 'explore_ping_growth',
|
|
12
|
+
value: 'false',
|
|
13
|
+
type: 'boolean',
|
|
14
|
+
group: 'explore'
|
|
15
|
+
})
|
|
16
|
+
);
|
|
@@ -628,5 +628,23 @@
|
|
|
628
628
|
},
|
|
629
629
|
"type": "boolean"
|
|
630
630
|
}
|
|
631
|
+
},
|
|
632
|
+
"explore": {
|
|
633
|
+
"explore_ping": {
|
|
634
|
+
"defaultValue": "true",
|
|
635
|
+
"validations": {
|
|
636
|
+
"isEmpty": false,
|
|
637
|
+
"isIn": [["true", "false"]]
|
|
638
|
+
},
|
|
639
|
+
"type": "boolean"
|
|
640
|
+
},
|
|
641
|
+
"explore_ping_growth": {
|
|
642
|
+
"defaultValue": "false",
|
|
643
|
+
"validations": {
|
|
644
|
+
"isEmpty": false,
|
|
645
|
+
"isIn": [["true", "false"]]
|
|
646
|
+
},
|
|
647
|
+
"type": "boolean"
|
|
648
|
+
}
|
|
631
649
|
}
|
|
632
650
|
}
|
|
@@ -18,12 +18,32 @@ class ActivityPubService {
|
|
|
18
18
|
this.identityTokenService = identityTokenService;
|
|
19
19
|
}
|
|
20
20
|
getExpectedWebhooks(secret) {
|
|
21
|
-
return [
|
|
21
|
+
return [
|
|
22
|
+
{
|
|
22
23
|
event: 'post.published',
|
|
23
24
|
target_url: new URL('.ghost/activitypub/v1/webhooks/post/published', this.siteUrl),
|
|
24
25
|
api_version: 'v5.100.0',
|
|
25
26
|
secret
|
|
26
|
-
}
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
event: 'post.deleted',
|
|
30
|
+
target_url: new URL('.ghost/activitypub/v1/webhooks/post/deleted', this.siteUrl),
|
|
31
|
+
api_version: 'v5.100.0',
|
|
32
|
+
secret
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
event: 'post.unpublished',
|
|
36
|
+
target_url: new URL('.ghost/activitypub/v1/webhooks/post/unpublished', this.siteUrl),
|
|
37
|
+
api_version: 'v5.100.0',
|
|
38
|
+
secret
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
event: 'post.published.edited',
|
|
42
|
+
target_url: new URL('.ghost/activitypub/v1/webhooks/post/updated', this.siteUrl),
|
|
43
|
+
api_version: 'v5.100.0',
|
|
44
|
+
secret
|
|
45
|
+
}
|
|
46
|
+
];
|
|
27
47
|
}
|
|
28
48
|
async checkWebhookState(expectedWebhooks, integration) {
|
|
29
49
|
this.logging.info(`Checking ActivityPub Webhook state`);
|
|
@@ -25,12 +25,32 @@ export class ActivityPubService {
|
|
|
25
25
|
) {}
|
|
26
26
|
|
|
27
27
|
getExpectedWebhooks(secret: string): ExpectedWebhook[] {
|
|
28
|
-
return [
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
return [
|
|
29
|
+
{
|
|
30
|
+
event: 'post.published',
|
|
31
|
+
target_url: new URL('.ghost/activitypub/v1/webhooks/post/published', this.siteUrl),
|
|
32
|
+
api_version: 'v5.100.0',
|
|
33
|
+
secret
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
event: 'post.deleted',
|
|
37
|
+
target_url: new URL('.ghost/activitypub/v1/webhooks/post/deleted', this.siteUrl),
|
|
38
|
+
api_version: 'v5.100.0',
|
|
39
|
+
secret
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
event: 'post.unpublished',
|
|
43
|
+
target_url: new URL('.ghost/activitypub/v1/webhooks/post/unpublished', this.siteUrl),
|
|
44
|
+
api_version: 'v5.100.0',
|
|
45
|
+
secret
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
event: 'post.published.edited',
|
|
49
|
+
target_url: new URL('.ghost/activitypub/v1/webhooks/post/updated', this.siteUrl),
|
|
50
|
+
api_version: 'v5.100.0',
|
|
51
|
+
secret
|
|
52
|
+
}
|
|
53
|
+
];
|
|
34
54
|
}
|
|
35
55
|
|
|
36
56
|
async checkWebhookState(expectedWebhooks: ExpectedWebhook[], integration: {id: string}) {
|
|
@@ -381,7 +381,6 @@ h6 + .kg-paywall .kg-paywall-hr td {
|
|
|
381
381
|
}
|
|
382
382
|
|
|
383
383
|
/* Exclude CTA cards with colored backgrounds from custom text color, but allow transparent ones */
|
|
384
|
-
{{#hasFeature "emailCustomization"}}
|
|
385
384
|
{{#each ctaBgColors}}
|
|
386
385
|
.post-content-row .kg-cta-bg-{{this}} .kg-cta-text p,
|
|
387
386
|
.post-content-row .kg-cta-bg-{{this}} .kg-cta-text ul,
|
|
@@ -391,17 +390,6 @@ h6 + .kg-paywall .kg-paywall-hr td {
|
|
|
391
390
|
color: inherit !important;
|
|
392
391
|
}
|
|
393
392
|
{{/each}}
|
|
394
|
-
{{else}}
|
|
395
|
-
.post-content-row .kg-cta-bg-grey .kg-cta-text p,
|
|
396
|
-
.post-content-row .kg-cta-bg-blue .kg-cta-text p,
|
|
397
|
-
.post-content-row .kg-cta-bg-green .kg-cta-text p,
|
|
398
|
-
.post-content-row .kg-cta-bg-yellow .kg-cta-text p,
|
|
399
|
-
.post-content-row .kg-cta-bg-red .kg-cta-text p,
|
|
400
|
-
.post-content-row .kg-cta-bg-pink .kg-cta-text p,
|
|
401
|
-
.post-content-row .kg-cta-bg-purple .kg-cta-text p {
|
|
402
|
-
color: inherit !important;
|
|
403
|
-
}
|
|
404
|
-
{{/hasFeature}}
|
|
405
393
|
|
|
406
394
|
.kg-cta-bg-none .kg-cta-sponsor-label span,
|
|
407
395
|
.kg-cta-bg-white .kg-cta-sponsor-label span {
|
|
@@ -2542,10 +2530,8 @@ table.btn-accent a {
|
|
|
2542
2530
|
{{/if}}
|
|
2543
2531
|
|
|
2544
2532
|
</style>
|
|
2545
|
-
{{#hasFeature "emailCustomization"}}
|
|
2546
2533
|
<!--[if mso]>
|
|
2547
2534
|
<style type="text/css">
|
|
2548
2535
|
ul, ol { margin-left: 1.5em !important; } {{!-- fix bullets/numbers not appearing for lists in older Outlook versions --}}
|
|
2549
2536
|
</style>
|
|
2550
2537
|
<![endif]-->
|
|
2551
|
-
{{/hasFeature}}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module.exports = class ExplorePingService {
|
|
2
2
|
/**
|
|
3
3
|
* @param {object} deps
|
|
4
|
-
* @param {{
|
|
4
|
+
* @param {{get: (string) => string}} deps.settingsCache
|
|
5
5
|
* @param {object} deps.config
|
|
6
6
|
* @param {object} deps.labs
|
|
7
7
|
* @param {object} deps.logging
|
|
@@ -14,6 +14,7 @@ module.exports = class ExplorePingService {
|
|
|
14
14
|
* }}} deps.posts
|
|
15
15
|
* @param {{stats: {
|
|
16
16
|
* getTotalMembers: () => Promise<number>
|
|
17
|
+
* getMRRHistory: () => Promise<number>
|
|
17
18
|
* }}} deps.members
|
|
18
19
|
*/
|
|
19
20
|
constructor({settingsCache, config, labs, logging, ghostVersion, request, posts, members}) {
|
|
@@ -28,45 +29,50 @@ module.exports = class ExplorePingService {
|
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
async constructPayload() {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
this.posts.stats.getMostRecentlyPublishedPostDate(),
|
|
38
|
-
this.posts.stats.getFirstPublishedPostDate()
|
|
39
|
-
]);
|
|
32
|
+
const payload = {
|
|
33
|
+
ghost: this.ghostVersion.full,
|
|
34
|
+
site_uuid: this.settingsCache.get('site_uuid'),
|
|
35
|
+
url: this.config.get('url'),
|
|
36
|
+
theme: this.settingsCache.get('active_theme')
|
|
37
|
+
};
|
|
40
38
|
|
|
41
|
-
// Get member statistics with error handling
|
|
42
|
-
let totalMembers = null;
|
|
43
39
|
try {
|
|
44
|
-
|
|
40
|
+
const [totalPosts, lastPublishedAt, firstPublishedAt] = await Promise.all([
|
|
41
|
+
this.posts.stats.getTotalPostsPublished(),
|
|
42
|
+
this.posts.stats.getMostRecentlyPublishedPostDate(),
|
|
43
|
+
this.posts.stats.getFirstPublishedPostDate()
|
|
44
|
+
]);
|
|
45
|
+
|
|
46
|
+
payload.posts_total = totalPosts;
|
|
47
|
+
payload.posts_last = lastPublishedAt ? lastPublishedAt.toISOString() : null;
|
|
48
|
+
payload.posts_first = firstPublishedAt ? firstPublishedAt.toISOString() : null;
|
|
45
49
|
} catch (err) {
|
|
46
|
-
this.logging.warn('Failed to fetch
|
|
50
|
+
this.logging.warn('Failed to fetch post statistics', {
|
|
47
51
|
error: err.message,
|
|
48
52
|
context: 'explore-ping-service'
|
|
49
53
|
});
|
|
50
|
-
|
|
54
|
+
payload.posts_total = null;
|
|
55
|
+
payload.posts_last = null;
|
|
56
|
+
payload.posts_first = null;
|
|
51
57
|
}
|
|
52
58
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
59
|
+
if (this.settingsCache.get('explore_ping_growth')) {
|
|
60
|
+
try {
|
|
61
|
+
const totalMembers = await this.members.stats.getTotalMembers();
|
|
62
|
+
const mrr = await this.members.stats.getMRRHistory();
|
|
63
|
+
payload.members_total = totalMembers;
|
|
64
|
+
payload.mrr = mrr;
|
|
65
|
+
} catch (err) {
|
|
66
|
+
this.logging.warn('Failed to fetch member statistics', {
|
|
67
|
+
error: err.message,
|
|
68
|
+
context: 'explore-ping-service'
|
|
69
|
+
});
|
|
70
|
+
payload.members_total = null;
|
|
71
|
+
payload.mrr = null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return payload;
|
|
70
76
|
}
|
|
71
77
|
|
|
72
78
|
async makeRequest(exploreUrl, payload) {
|
|
@@ -95,12 +101,17 @@ module.exports = class ExplorePingService {
|
|
|
95
101
|
return;
|
|
96
102
|
}
|
|
97
103
|
|
|
98
|
-
const exploreUrl = this.config.get('explore:
|
|
104
|
+
const exploreUrl = this.config.get('explore:update_url');
|
|
99
105
|
if (!exploreUrl) {
|
|
100
106
|
this.logging.warn('Explore URL not set');
|
|
101
107
|
return;
|
|
102
108
|
}
|
|
103
109
|
|
|
110
|
+
if (!this.settingsCache.get('explore_ping')) {
|
|
111
|
+
this.logging.info('Explore ping disabled');
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
104
115
|
const payload = await this.constructPayload();
|
|
105
116
|
await this.makeRequest(exploreUrl, payload);
|
|
106
117
|
}
|
|
@@ -25,6 +25,10 @@ module.exports = function getConfigProperties() {
|
|
|
25
25
|
security: config.get('security')
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
+
if (config.get('explore') && config.get('explore:testimonials_url')) {
|
|
29
|
+
configProperties.exploreTestimonialsUrl = config.get('explore:testimonials_url');
|
|
30
|
+
}
|
|
31
|
+
|
|
28
32
|
// WIP tinybird stats feature - it's entirely config driven instead of using an alpha flag for now
|
|
29
33
|
if (config.get('tinybird') && config.get('tinybird:stats')) {
|
|
30
34
|
const statsConfig = config.get('tinybird:stats');
|
|
@@ -19,9 +19,18 @@ const messages = {
|
|
|
19
19
|
const installFromGithub = async (ref) => {
|
|
20
20
|
const [org, repo] = ref.toLowerCase().split('/');
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
if (limitService.isLimited('customThemes')) {
|
|
23
|
+
// The custom theme limit might consist of only one single theme, so we can't rely on
|
|
24
|
+
// the org alone to determine if the request is allowed or not.
|
|
25
|
+
const noOtherThemesAllowed = limitService.limits.customThemes?.allowlist?.length === 1;
|
|
26
|
+
//TODO: move the organization check to config
|
|
27
|
+
const isNotOfficialThemeRequest = org.toLowerCase() !== 'tryghost';
|
|
28
|
+
|
|
29
|
+
const checkThemeLimit = noOtherThemesAllowed || isNotOfficialThemeRequest;
|
|
30
|
+
|
|
31
|
+
if (checkThemeLimit) {
|
|
32
|
+
await limitService.errorIfWouldGoOverLimit('customThemes', {value: repo.toLowerCase()});
|
|
33
|
+
}
|
|
25
34
|
}
|
|
26
35
|
|
|
27
36
|
// omit /:ref so we fetch the default branch
|
|
@@ -62,6 +71,11 @@ const installFromGithub = async (ref) => {
|
|
|
62
71
|
}));
|
|
63
72
|
}
|
|
64
73
|
|
|
74
|
+
if (e instanceof errors.HostLimitError) {
|
|
75
|
+
// If the error is a HostLimitError, we can assume that the theme name is not allowed
|
|
76
|
+
return Promise.reject(e);
|
|
77
|
+
}
|
|
78
|
+
|
|
65
79
|
throw e;
|
|
66
80
|
} finally {
|
|
67
81
|
// clean up tmp dir with downloaded file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ghost",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.130.0",
|
|
4
4
|
"description": "The professional publishing platform",
|
|
5
5
|
"author": "Ghost Foundation",
|
|
6
6
|
"homepage": "https://ghost.org",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"@tryghost/helpers": "1.1.97",
|
|
87
87
|
"@tryghost/html-to-plaintext": "1.0.4",
|
|
88
88
|
"@tryghost/http-cache-utils": "0.1.20",
|
|
89
|
-
"@tryghost/i18n": "file:components/tryghost-i18n-5.
|
|
89
|
+
"@tryghost/i18n": "file:components/tryghost-i18n-5.130.0.tgz",
|
|
90
90
|
"@tryghost/image-transform": "1.4.6",
|
|
91
91
|
"@tryghost/job-manager": "1.0.3",
|
|
92
92
|
"@tryghost/kg-card-factory": "5.1.2",
|
|
@@ -226,21 +226,21 @@
|
|
|
226
226
|
},
|
|
227
227
|
"devDependencies": {
|
|
228
228
|
"@actions/core": "1.11.1",
|
|
229
|
-
"@playwright/test": "1.
|
|
229
|
+
"@playwright/test": "1.54.1",
|
|
230
230
|
"@prettier/sync": "0.6.1",
|
|
231
231
|
"@tryghost/express-test": "0.15.0",
|
|
232
232
|
"@tryghost/webhook-mock-receiver": "0.2.17",
|
|
233
233
|
"@types/bookshelf": "1.2.9",
|
|
234
234
|
"@types/common-tags": "1.8.4",
|
|
235
235
|
"@types/jsonwebtoken": "9.0.10",
|
|
236
|
-
"@types/node": "22.16.
|
|
236
|
+
"@types/node": "22.16.4",
|
|
237
237
|
"@types/node-jose": "1.1.13",
|
|
238
238
|
"@types/nodemailer": "6.4.17",
|
|
239
239
|
"@types/sinon": "17.0.4",
|
|
240
240
|
"@types/supertest": "6.0.3",
|
|
241
241
|
"c8": "10.1.3",
|
|
242
242
|
"cli-progress": "3.12.0",
|
|
243
|
-
"cssnano": "7.0
|
|
243
|
+
"cssnano": "7.1.0",
|
|
244
244
|
"detect-indent": "6.1.0",
|
|
245
245
|
"detect-newline": "3.1.0",
|
|
246
246
|
"expect": "29.7.0",
|
|
@@ -274,7 +274,7 @@
|
|
|
274
274
|
"jackspeak": "2.3.6",
|
|
275
275
|
"moment": "2.24.0",
|
|
276
276
|
"moment-timezone": "0.5.45",
|
|
277
|
-
"@tryghost/i18n": "file:components/tryghost-i18n-5.
|
|
277
|
+
"@tryghost/i18n": "file:components/tryghost-i18n-5.130.0.tgz"
|
|
278
278
|
},
|
|
279
279
|
"nx": {
|
|
280
280
|
"targets": {
|