ghost 5.4.1 → 5.5.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-custom-theme-settings-service-0.0.0.tgz +0 -0
- package/components/tryghost-domain-events-0.0.0.tgz +0 -0
- package/components/tryghost-email-analytics-provider-mailgun-0.0.0.tgz +0 -0
- package/components/tryghost-email-analytics-service-0.0.0.tgz +0 -0
- package/components/tryghost-express-dynamic-redirects-0.0.0.tgz +0 -0
- package/components/tryghost-magic-link-0.0.0.tgz +0 -0
- package/components/tryghost-member-analytics-service-0.0.0.tgz +0 -0
- package/components/tryghost-member-events-0.0.0.tgz +0 -0
- package/components/tryghost-members-analytics-ingress-0.0.0.tgz +0 -0
- package/components/tryghost-members-api-0.0.0.tgz +0 -0
- package/components/tryghost-members-csv-0.0.0.tgz +0 -0
- package/components/tryghost-members-events-service-0.0.0.tgz +0 -0
- package/components/tryghost-members-importer-0.0.0.tgz +0 -0
- package/components/tryghost-members-offers-0.0.0.tgz +0 -0
- package/components/tryghost-members-payments-0.0.0.tgz +0 -0
- package/components/tryghost-members-ssr-0.0.0.tgz +0 -0
- package/components/tryghost-members-stripe-service-0.0.0.tgz +0 -0
- package/components/tryghost-verification-trigger-0.0.0.tgz +0 -0
- package/content/themes/casper/assets/built/global.css +1 -1
- package/content/themes/casper/assets/built/global.css.map +1 -1
- package/content/themes/casper/assets/built/screen.css +1 -1
- package/content/themes/casper/assets/built/screen.css.map +1 -1
- package/content/themes/casper/assets/css/screen.css +9 -1
- package/content/themes/casper/gulpfile.js +1 -1
- package/content/themes/casper/package.json +9 -9
- package/content/themes/casper/yarn.lock +1154 -1249
- package/core/boot.js +5 -0
- package/core/built/assets/{chunk.3.dc389a0f93cb5fabd695.js → chunk.3.550552fbc71864fb9738.js} +20 -20
- package/core/built/assets/fonts/Inter.ttf +0 -0
- package/core/built/assets/ghost-dark-5c2a961b35311d7298136e02289d98b2.css +1 -0
- package/core/built/assets/ghost.min-a89d10b3b58c1a5ebaca68cef93a404c.css +1 -0
- package/core/built/assets/{ghost.min-36b64813b14c45075770658269d4b478.js → ghost.min-c75f224decd20f9538179d7564cd2ab4.js} +3005 -2874
- package/core/built/assets/icons/event-comment.svg +3 -0
- package/core/built/assets/{vendor.min-be0129c9c6897c9f10425e2402881d77.js → vendor.min-cf3af99dca0c71937669305afb3686a1.js} +6110 -3186
- package/core/frontend/helpers/comments.js +22 -10
- package/core/frontend/helpers/ghost_head.js +22 -4
- package/core/frontend/utils/frontend-apps.js +33 -0
- package/core/server/api/endpoints/comments-comments.js +50 -32
- package/core/server/api/endpoints/utils/serializers/output/config.js +2 -1
- package/core/server/api/endpoints/utils/serializers/output/mappers/activity-feed-events.js +17 -0
- package/core/server/api/endpoints/utils/serializers/output/mappers/comments.js +18 -0
- package/core/server/api/endpoints/utils/serializers/output/mappers/index.js +1 -0
- package/core/server/api/endpoints/utils/serializers/output/members.js +12 -1
- package/core/server/data/exporter/table-lists.js +2 -1
- package/core/server/data/migrations/versions/5.5/2022-07-18-14-29-add-comment-reporting-permissions.js +10 -0
- package/core/server/data/migrations/versions/5.5/2022-07-18-14-31-drop-reports-reason.js +3 -0
- package/core/server/data/migrations/versions/5.5/2022-07-18-14-32-drop-nullable-member-id-from-likes.js +4 -0
- package/core/server/data/migrations/versions/5.5/2022-07-18-14-33-fix-comments-on-delete-foreign-keys.js +119 -0
- package/core/server/data/migrations/versions/5.5/2022-07-21-08-56-add-jobs-table.js +11 -0
- package/core/server/data/schema/commands.js +7 -2
- package/core/server/data/schema/fixtures/fixtures.json +5 -0
- package/core/server/data/schema/schema.js +12 -4
- package/core/server/ghost-server.js +0 -22
- package/core/server/models/comment-report.js +34 -0
- package/core/server/models/comment.js +8 -7
- package/core/server/models/job.js +9 -0
- package/core/server/services/comments/email-templates/new-comment-reply.hbs +2 -2
- package/core/server/services/comments/email-templates/new-comment-reply.txt.js +7 -8
- package/core/server/services/comments/email-templates/new-comment.hbs +2 -2
- package/core/server/services/comments/email-templates/new-comment.txt.js +7 -6
- package/core/server/services/comments/email-templates/report.hbs +199 -0
- package/core/server/services/comments/email-templates/report.txt.js +16 -0
- package/core/server/services/comments/emails.js +57 -1
- package/core/server/services/comments/service.js +194 -2
- package/core/server/services/jobs/job-service.js +24 -1
- package/core/server/services/mail/GhostMailer.js +1 -0
- package/core/server/services/members/api.js +2 -1
- package/core/server/services/public-config/config.js +2 -1
- package/core/server/services/stripe/service.js +9 -1
- 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/testmode/jobs/graceful-job.js +2 -2
- package/core/server/web/api/testmode/routes.js +14 -0
- package/core/server/web/comments/routes.js +2 -0
- package/core/shared/config/defaults.json +12 -7
- package/core/shared/config/env/config.testing.json +3 -2
- package/package.json +70 -56
- package/yarn.lock +1763 -1796
- package/core/built/assets/ghost-dark-739c1f5546bd048eeeb253965ef36712.css +0 -1
- package/core/built/assets/ghost.min-5211776b9497f36fac8c9e5f2584cbcc.css +0 -1
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
const tpl = require('@tryghost/tpl');
|
|
2
|
+
const errors = require('@tryghost/errors');
|
|
3
|
+
const {MemberCommentEvent} = require('@tryghost/member-events');
|
|
4
|
+
const DomainEvents = require('@tryghost/domain-events');
|
|
5
|
+
|
|
6
|
+
const messages = {
|
|
7
|
+
commentNotFound: 'Comment could not be found',
|
|
8
|
+
memberNotFound: 'Unable to find member',
|
|
9
|
+
likeNotFound: 'Unable to find like',
|
|
10
|
+
alreadyLiked: 'This comment was liked already',
|
|
11
|
+
replyToReply: 'Can not reply to a reply'
|
|
12
|
+
};
|
|
13
|
+
|
|
1
14
|
class CommentsService {
|
|
2
15
|
constructor({config, logging, models, mailer, settingsCache, urlService, urlUtils}) {
|
|
3
16
|
this.config = config;
|
|
@@ -13,11 +26,190 @@ class CommentsService {
|
|
|
13
26
|
}
|
|
14
27
|
|
|
15
28
|
async sendNewCommentNotifications(comment) {
|
|
16
|
-
this.emails.notifyPostAuthors(comment);
|
|
29
|
+
await this.emails.notifyPostAuthors(comment);
|
|
17
30
|
|
|
18
31
|
if (comment.get('parent_id')) {
|
|
19
|
-
this.emails.notifyParentCommentAuthor(comment);
|
|
32
|
+
await this.emails.notifyParentCommentAuthor(comment);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async reportComment(commentId, reporter) {
|
|
37
|
+
const comment = await this.models.Comment.findOne({id: commentId}, {require: true});
|
|
38
|
+
|
|
39
|
+
// Check if this reporter already reported this comment (then don't send an email)?
|
|
40
|
+
const existing = await this.models.CommentReport.findOne({
|
|
41
|
+
comment_id: comment.id,
|
|
42
|
+
member_id: reporter.id
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
if (existing) {
|
|
46
|
+
// Ignore silently for now
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Save report model
|
|
51
|
+
await this.models.CommentReport.add({
|
|
52
|
+
comment_id: comment.id,
|
|
53
|
+
member_id: reporter.id
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
await this.emails.notifiyReport(comment, reporter);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @param {string} id - The ID of the Comment to get
|
|
61
|
+
* @param {any} options
|
|
62
|
+
*/
|
|
63
|
+
async getCommentByID(id, options) {
|
|
64
|
+
const model = await this.models.Comment.findOne({id}, options);
|
|
65
|
+
|
|
66
|
+
if (!model) {
|
|
67
|
+
throw new errors.NotFoundError({
|
|
68
|
+
messages: tpl(messages.commentNotFound)
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return model;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @param {string} post - The ID of the Post to comment on
|
|
77
|
+
* @param {string} member - The ID of the Member to comment as
|
|
78
|
+
* @param {string} comment - The HTML content of the Comment
|
|
79
|
+
* @param {any} options
|
|
80
|
+
*/
|
|
81
|
+
async commentOnPost(post, member, comment, options) {
|
|
82
|
+
await this.models.Member.findOne({
|
|
83
|
+
id: member
|
|
84
|
+
}, {
|
|
85
|
+
require: true,
|
|
86
|
+
...options
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const model = await this.models.Comment.add({
|
|
90
|
+
post_id: post,
|
|
91
|
+
member_id: member,
|
|
92
|
+
parent_id: null,
|
|
93
|
+
html: comment,
|
|
94
|
+
status: 'published'
|
|
95
|
+
}, options);
|
|
96
|
+
|
|
97
|
+
if (!options.context.internal) {
|
|
98
|
+
await this.sendNewCommentNotifications(model);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
DomainEvents.dispatch(MemberCommentEvent.create({
|
|
102
|
+
memberId: member,
|
|
103
|
+
postId: post,
|
|
104
|
+
commentId: model.id
|
|
105
|
+
}));
|
|
106
|
+
|
|
107
|
+
return model;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @param {string} parent - The ID of the Comment to reply to
|
|
112
|
+
* @param {string} member - The ID of the Member to comment as
|
|
113
|
+
* @param {string} comment - The HTML content of the Comment
|
|
114
|
+
* @param {any} options
|
|
115
|
+
*/
|
|
116
|
+
async replyToComment(parent, member, comment, options) {
|
|
117
|
+
await this.models.Member.findOne({
|
|
118
|
+
id: member
|
|
119
|
+
}, {
|
|
120
|
+
require: true,
|
|
121
|
+
...options
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const parentComment = await this.getCommentByID(parent, options);
|
|
125
|
+
if (!parentComment) {
|
|
126
|
+
throw new errors.BadRequestError({
|
|
127
|
+
message: tpl(messages.commentNotFound)
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (parentComment.get('parent_id') !== null) {
|
|
132
|
+
throw new errors.BadRequestError({
|
|
133
|
+
message: tpl(messages.replyToReply)
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const model = await this.models.Comment.add({
|
|
138
|
+
post_id: parentComment.get('post_id'),
|
|
139
|
+
member_id: member,
|
|
140
|
+
parent_id: parentComment.id,
|
|
141
|
+
html: comment,
|
|
142
|
+
status: 'published'
|
|
143
|
+
}, options);
|
|
144
|
+
|
|
145
|
+
if (!options.context.internal) {
|
|
146
|
+
await this.sendNewCommentNotifications(model);
|
|
20
147
|
}
|
|
148
|
+
|
|
149
|
+
DomainEvents.dispatch(MemberCommentEvent.create({
|
|
150
|
+
memberId: member,
|
|
151
|
+
postId: parentComment.get('post_id'),
|
|
152
|
+
commentId: model.id
|
|
153
|
+
}));
|
|
154
|
+
|
|
155
|
+
return model;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* @param {string} id - The ID of the Comment to delete
|
|
160
|
+
* @param {string} member - The ID of the Member to delete as
|
|
161
|
+
* @param {any} options
|
|
162
|
+
*/
|
|
163
|
+
async deleteComment(id, member, options) {
|
|
164
|
+
const existingComment = await this.getCommentByID(id, options);
|
|
165
|
+
|
|
166
|
+
if (existingComment.get('member_id') !== member) {
|
|
167
|
+
throw new errors.NoPermissionError({
|
|
168
|
+
// todo fix message
|
|
169
|
+
message: tpl(messages.memberNotFound)
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const model = await this.models.Comment.edit({
|
|
174
|
+
status: 'deleted'
|
|
175
|
+
}, {
|
|
176
|
+
id,
|
|
177
|
+
require: true,
|
|
178
|
+
...options
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
return model;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* @param {string} id - The ID of the Comment to edit
|
|
186
|
+
* @param {string} member - The ID of the Member to edit as
|
|
187
|
+
* @param {string} comment - The new HTML content of the Comment
|
|
188
|
+
* @param {any} options
|
|
189
|
+
*/
|
|
190
|
+
async editCommentContent(id, member, comment, options) {
|
|
191
|
+
const existingComment = await this.getCommentByID(id, options);
|
|
192
|
+
|
|
193
|
+
if (!comment) {
|
|
194
|
+
return existingComment;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (existingComment.get('member_id') !== member) {
|
|
198
|
+
throw new errors.NoPermissionError({
|
|
199
|
+
// todo fix message
|
|
200
|
+
message: tpl(messages.memberNotFound)
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const model = await this.models.Comment.edit({
|
|
205
|
+
html: comment
|
|
206
|
+
}, {
|
|
207
|
+
id,
|
|
208
|
+
require: true,
|
|
209
|
+
...options
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
return model;
|
|
21
213
|
}
|
|
22
214
|
}
|
|
23
215
|
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
const JobManager = require('@tryghost/job-manager');
|
|
7
7
|
const logging = require('@tryghost/logging');
|
|
8
|
+
const models = require('../../models');
|
|
8
9
|
const sentry = require('../../../shared/sentry');
|
|
9
10
|
|
|
10
11
|
const errorHandler = (error, workerMeta) => {
|
|
@@ -17,6 +18,28 @@ const workerMessageHandler = ({name, message}) => {
|
|
|
17
18
|
logging.info(`Worker for job ${name} sent a message: ${message}`);
|
|
18
19
|
};
|
|
19
20
|
|
|
20
|
-
const
|
|
21
|
+
const initTestMode = () => {
|
|
22
|
+
// Output job queue length every 5 seconds
|
|
23
|
+
setInterval(() => {
|
|
24
|
+
logging.warn(`${jobManager.queue.length()} jobs in the queue. Idle: ${jobManager.queue.idle()}`);
|
|
25
|
+
|
|
26
|
+
const runningScheduledjobs = Object.keys(jobManager.bree.workers);
|
|
27
|
+
if (Object.keys(jobManager.bree.workers).length) {
|
|
28
|
+
logging.warn(`${Object.keys(jobManager.bree.workers).length} jobs running: ${runningScheduledjobs}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const scheduledJobs = Object.keys(jobManager.bree.intervals);
|
|
32
|
+
if (Object.keys(jobManager.bree.intervals).length) {
|
|
33
|
+
logging.warn(`${Object.keys(jobManager.bree.intervals).length} scheduled jobs: ${scheduledJobs}`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (runningScheduledjobs.length === 0 && scheduledJobs.length === 0) {
|
|
37
|
+
logging.warn('No scheduled or running jobs');
|
|
38
|
+
}
|
|
39
|
+
}, 5000);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const jobManager = new JobManager({errorHandler, workerMessageHandler, JobModel: models.Job});
|
|
21
43
|
|
|
22
44
|
module.exports = jobManager;
|
|
45
|
+
module.exports.initTestMode = initTestMode;
|
|
@@ -95,6 +95,7 @@ module.exports = class GhostMailer {
|
|
|
95
95
|
* @param {string} message.html - email content
|
|
96
96
|
* @param {string} message.to - email recipient address
|
|
97
97
|
* @param {string} [message.from] - sender email address
|
|
98
|
+
* @param {string} [message.text] - text version of this message
|
|
98
99
|
* @param {boolean} [message.forceTextContent] - maps to generateTextFromHTML nodemailer option
|
|
99
100
|
* which is: "if set to true uses HTML to generate plain text body part from the HTML if the text is not defined"
|
|
100
101
|
* (ref: https://github.com/nodemailer/nodemailer/tree/da2f1d278f91b4262e940c0b37638e7027184b1d#e-mail-message-fields)
|
|
@@ -189,7 +189,8 @@ function createApiInstance(config) {
|
|
|
189
189
|
StripeProduct: models.StripeProduct,
|
|
190
190
|
StripePrice: models.StripePrice,
|
|
191
191
|
Product: models.Product,
|
|
192
|
-
Settings: models.Settings
|
|
192
|
+
Settings: models.Settings,
|
|
193
|
+
Comment: models.Comment
|
|
193
194
|
},
|
|
194
195
|
stripeAPIService: stripeService.api,
|
|
195
196
|
offersAPI: offersService.api,
|
|
@@ -18,7 +18,8 @@ module.exports = function getConfigProperties() {
|
|
|
18
18
|
mailgunIsConfigured: !!(config.get('bulkEmail') && config.get('bulkEmail').mailgun),
|
|
19
19
|
emailAnalytics: config.get('emailAnalytics'),
|
|
20
20
|
hostSettings: config.get('hostSettings'),
|
|
21
|
-
tenor: config.get('tenor')
|
|
21
|
+
tenor: config.get('tenor'),
|
|
22
|
+
editor: config.get('editor')
|
|
22
23
|
};
|
|
23
24
|
|
|
24
25
|
const billingUrl = config.get('hostSettings:billing:enabled') ? config.get('hostSettings:billing:url') : '';
|
|
@@ -25,7 +25,15 @@ const debouncedConfigureApi = _.debounce(() => {
|
|
|
25
25
|
|
|
26
26
|
module.exports = new StripeService({
|
|
27
27
|
membersService,
|
|
28
|
-
models: _.pick(models, [
|
|
28
|
+
models: _.pick(models, [
|
|
29
|
+
'Product',
|
|
30
|
+
'StripePrice',
|
|
31
|
+
'StripeCustomerSubscription',
|
|
32
|
+
'StripeProduct',
|
|
33
|
+
'MemberStripeCustomer',
|
|
34
|
+
'Offer',
|
|
35
|
+
'Settings'
|
|
36
|
+
]),
|
|
29
37
|
StripeWebhook: {
|
|
30
38
|
async get() {
|
|
31
39
|
return {
|
|
@@ -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%2F%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%2F%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.5%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" />
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
<link rel="stylesheet" href="assets/vendor.min-4a6661c574707ceca220aa2e76558995.css">
|
|
41
|
-
<link rel="stylesheet" href="assets/ghost.min-
|
|
41
|
+
<link rel="stylesheet" href="assets/ghost.min-a89d10b3b58c1a5ebaca68cef93a404c.css" title="light">
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
<div id="ember-basic-dropdown-wormhole"></div>
|
|
57
57
|
|
|
58
58
|
|
|
59
|
-
<script src="assets/vendor.min-
|
|
60
|
-
<script src="assets/ghost.min-
|
|
59
|
+
<script src="assets/vendor.min-cf3af99dca0c71937669305afb3686a1.js"></script>
|
|
60
|
+
<script src="assets/ghost.min-c75f224decd20f9538179d7564cd2ab4.js"></script>
|
|
61
61
|
|
|
62
62
|
</body>
|
|
63
63
|
</html>
|
|
@@ -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%2F%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%2F%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.5%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" />
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
<link rel="stylesheet" href="assets/vendor.min-4a6661c574707ceca220aa2e76558995.css">
|
|
41
|
-
<link rel="stylesheet" href="assets/ghost.min-
|
|
41
|
+
<link rel="stylesheet" href="assets/ghost.min-a89d10b3b58c1a5ebaca68cef93a404c.css" title="light">
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
<div id="ember-basic-dropdown-wormhole"></div>
|
|
57
57
|
|
|
58
58
|
|
|
59
|
-
<script src="assets/vendor.min-
|
|
60
|
-
<script src="assets/ghost.min-
|
|
59
|
+
<script src="assets/vendor.min-cf3af99dca0c71937669305afb3686a1.js"></script>
|
|
60
|
+
<script src="assets/ghost.min-c75f224decd20f9538179d7564cd2ab4.js"></script>
|
|
61
61
|
|
|
62
62
|
</body>
|
|
63
63
|
</html>
|
|
@@ -37,7 +37,7 @@ const internalContext = {context: {internal: true}};
|
|
|
37
37
|
|
|
38
38
|
if (shutdown) {
|
|
39
39
|
postParentPortMessage(`Job shutting down gracefully`);
|
|
40
|
-
|
|
40
|
+
parentPort.postMessage('done');
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
postParentPortMessage(`Fetching posts`);
|
|
@@ -46,5 +46,5 @@ const internalContext = {context: {internal: true}};
|
|
|
46
46
|
postParentPortMessage(`Found ${posts.data.length} posts. First one: ${posts.data[0].toJSON().slug}`);
|
|
47
47
|
postParentPortMessage('Graceful job has completed!');
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
parentPort.postMessage('done');
|
|
50
50
|
})();
|
|
@@ -44,6 +44,20 @@ module.exports = function testRoutes() {
|
|
|
44
44
|
res.sendStatus(202);
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
+
router.get('/oneoff/:name', (req, res) => {
|
|
48
|
+
logging.info('Create Slow Job with timeout of', req.params.name);
|
|
49
|
+
|
|
50
|
+
const options = {};
|
|
51
|
+
|
|
52
|
+
options.solo = true;
|
|
53
|
+
options.name = req.params.name;
|
|
54
|
+
options.job = path.resolve(__dirname, 'jobs', `${options.name}.js`);
|
|
55
|
+
|
|
56
|
+
jobsService.addOneOffJob(options);
|
|
57
|
+
|
|
58
|
+
res.sendStatus(202);
|
|
59
|
+
});
|
|
60
|
+
|
|
47
61
|
router.get('/schedule/:schedule/:name*?', (req, res) => {
|
|
48
62
|
if (!req.params.schedule) {
|
|
49
63
|
return res.sendStatus(400, 'schedule parameter cannot be mepty');
|
|
@@ -24,5 +24,7 @@ module.exports = function apiRoutes() {
|
|
|
24
24
|
router.post('/:id/like', http(api.commentsComments.like));
|
|
25
25
|
router.delete('/:id/like', http(api.commentsComments.unlike));
|
|
26
26
|
|
|
27
|
+
router.post('/:id/report', http(api.commentsComments.report));
|
|
28
|
+
|
|
27
29
|
return router;
|
|
28
30
|
};
|
|
@@ -133,12 +133,21 @@
|
|
|
133
133
|
"emailAnalytics": true
|
|
134
134
|
},
|
|
135
135
|
"portal": {
|
|
136
|
-
"url": "https://
|
|
136
|
+
"url": "https://cdn.jsdelivr.net/npm/@tryghost/portal@~{version}/umd/portal.min.js",
|
|
137
137
|
"version": "2.3"
|
|
138
138
|
},
|
|
139
139
|
"sodoSearch": {
|
|
140
|
-
"url": "https://
|
|
141
|
-
"
|
|
140
|
+
"url": "https://cdn.jsdelivr.net/npm/@tryghost/sodo-search@~{version}/umd/sodo-search.min.js",
|
|
141
|
+
"styles": "https://cdn.jsdelivr.net/npm/@tryghost/sodo-search@~{version}/umd/main.css",
|
|
142
|
+
"version": "1.1"
|
|
143
|
+
},
|
|
144
|
+
"comments": {
|
|
145
|
+
"url": "https://cdn.jsdelivr.net/npm/@tryghost/comments-ui@~{version}/umd/comments-ui.min.js",
|
|
146
|
+
"styles": "https://cdn.jsdelivr.net/npm/@tryghost/comments-ui@~{version}/umd/main.css",
|
|
147
|
+
"version": "0.2"
|
|
148
|
+
},
|
|
149
|
+
"editor": {
|
|
150
|
+
"url": ""
|
|
142
151
|
},
|
|
143
152
|
"tenor": {
|
|
144
153
|
"publicReadOnlyApiKey": null,
|
|
@@ -152,9 +161,5 @@
|
|
|
152
161
|
},
|
|
153
162
|
"gravatar": {
|
|
154
163
|
"url": "https://www.gravatar.com/avatar/{hash}?s={size}&r={rating}&d={_default}"
|
|
155
|
-
},
|
|
156
|
-
"comments": {
|
|
157
|
-
"url": "https://unpkg.com/@tryghost/comments-ui@~0.1.0/umd/comments-ui.min.js",
|
|
158
|
-
"version": "0.1.0"
|
|
159
164
|
}
|
|
160
165
|
}
|
|
@@ -56,7 +56,8 @@
|
|
|
56
56
|
"urlCache": "test/utils/fixtures/urls"
|
|
57
57
|
},
|
|
58
58
|
"sodoSearch": {
|
|
59
|
-
"url": "https://
|
|
60
|
-
"
|
|
59
|
+
"url": "https://cdn.jsdelivr.net/npm/@tryghost/sodo-search@~{version}/umd/sodo-search.min.js",
|
|
60
|
+
"styles": "https://cdn.jsdelivr.net/npm/@tryghost/sodo-search@~{version}/umd/main.css",
|
|
61
|
+
"version": "1.0"
|
|
61
62
|
}
|
|
62
63
|
}
|