ghost 4.23.0 → 4.26.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/.eslintrc.js +39 -0
- package/content/themes/casper/assets/built/casper.js +1 -1
- package/content/themes/casper/assets/built/casper.js.map +1 -1
- 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/global.css +6 -1
- package/content/themes/casper/assets/css/screen.css +50 -215
- package/content/themes/casper/default.hbs +2 -2
- package/content/themes/casper/package.json +3 -2
- package/content/themes/casper/post.hbs +1 -1
- package/content/themes/casper/yarn.lock +173 -123
- package/core/app.js +20 -5
- package/core/boot.js +77 -36
- package/core/bridge.js +10 -10
- package/core/built/assets/ghost-dark-ef86e3bc7f0fb83d39d3d6a49bff8dd5.css +1 -0
- package/core/built/assets/ghost.min-57c1e677f42d596942d317ce93e8a62c.css +1 -0
- package/core/built/assets/{ghost.min-cccc107e881b74c7aaf1a73e1e5e0dee.js → ghost.min-f3c6886e191d34450e9ffca0c8fa056e.js} +543 -618
- package/core/built/assets/icons/audio-upload.svg +8 -0
- package/core/built/assets/{vendor.min-c9002845b6c30ac978abdadde9f33d7c.js → vendor.min-b6b8d2a31d61830c2d8f65c5ba54236a.js} +2656 -2118
- package/core/frontend/apps/amp/lib/helpers/amp_content.js +2 -2
- package/core/frontend/apps/amp/lib/views/amp.hbs +75 -0
- package/core/frontend/apps/private-blogging/index.js +1 -1
- package/core/frontend/helpers/url.js +18 -1
- package/core/frontend/services/apps/index.js +1 -1
- package/core/frontend/services/apps/loader.js +3 -3
- package/core/frontend/services/card-assets/index.js +0 -12
- package/core/frontend/services/card-assets/service.js +22 -21
- package/core/frontend/services/helpers/handlebars.js +1 -1
- package/core/frontend/services/theme-engine/middleware/ensure-active-theme.js +34 -0
- package/core/frontend/services/theme-engine/middleware/index.js +6 -0
- package/core/frontend/services/theme-engine/middleware/update-global-template-options.js +116 -0
- package/core/frontend/services/theme-engine/middleware/update-local-template-data.js +9 -0
- package/core/frontend/services/theme-engine/middleware/update-local-template-options.js +57 -0
- package/core/frontend/src/cards/css/audio.css +186 -0
- package/core/frontend/src/cards/css/blockquote.css +27 -0
- package/core/frontend/src/cards/css/bookmark.css +7 -0
- package/core/frontend/src/cards/css/button.css +4 -0
- package/core/frontend/src/cards/css/callout.css +23 -15
- package/core/frontend/src/cards/css/gallery.css +13 -3
- package/core/frontend/src/cards/css/toggle.css +48 -15
- package/core/frontend/src/cards/js/audio.js +137 -0
- package/core/frontend/web/middleware/error-handler.js +93 -0
- package/core/frontend/web/middleware/handle-image-sizes.js +3 -6
- package/core/frontend/web/middleware/index.js +1 -0
- package/core/frontend/web/middleware/serve-public-file.js +25 -8
- package/core/frontend/web/site.js +2 -5
- package/core/server/adapters/scheduling/SchedulingDefault.js +2 -2
- package/core/server/adapters/storage/LocalStorageBase.js +2 -2
- package/core/server/api/canary/db.js +2 -2
- package/core/server/api/canary/media.js +3 -2
- package/core/server/api/canary/oembed.js +16 -1
- package/core/server/api/canary/session.js +1 -1
- package/core/server/api/canary/slugs.js +1 -1
- package/core/server/api/canary/utils/permissions.js +2 -2
- package/core/server/api/canary/utils/serializers/output/config.js +2 -6
- package/core/server/api/v2/db.js +2 -2
- package/core/server/api/v2/session.js +1 -1
- package/core/server/api/v2/slugs.js +1 -1
- package/core/server/api/v2/utils/permissions.js +2 -2
- package/core/server/api/v3/db.js +2 -2
- package/core/server/api/v3/session.js +1 -1
- package/core/server/api/v3/slugs.js +1 -1
- package/core/server/api/v3/utils/permissions.js +2 -2
- package/core/server/data/db/state-manager.js +4 -4
- package/core/server/data/exporter/export-filename.js +1 -1
- package/core/server/data/importer/handlers/json.js +1 -1
- package/core/server/data/importer/import-manager.js +1 -1
- package/core/server/data/importer/importers/data/base.js +1 -1
- package/core/server/data/migrations/utils.js +2 -2
- package/core/server/data/migrations/versions/1.25/1-update-koenig-beta-html.js +1 -0
- package/core/server/data/migrations/versions/3.1/08-add-uuid-values-to-members.js +1 -0
- package/core/server/data/migrations/versions/3.22/02-settings-key-renames.js +2 -0
- package/core/server/data/migrations/versions/3.22/05-migrate-members-subscription-settings.js +3 -0
- package/core/server/data/migrations/versions/3.22/06-migrate-stripe-connect-settings.js +2 -0
- package/core/server/data/migrations/versions/3.23/01-migrate-bulk-email-settings.js +1 -0
- package/core/server/data/migrations/versions/3.29/01-remove-duplicate-subscriptions.js +2 -0
- package/core/server/data/migrations/versions/3.29/02-remove-duplicate-customers.js +2 -0
- package/core/server/data/migrations/versions/3.38/04-populate-recipient-filter-column.js +2 -0
- package/core/server/data/migrations/versions/4.0/01-update-mobiledoc.js +2 -0
- package/core/server/data/migrations/versions/4.0/03-populate-status-column-for-members.js +4 -0
- package/core/server/data/migrations/versions/4.0/06-populate-members-subscribe-events-table.js +1 -0
- package/core/server/data/migrations/versions/4.0/17-populate-members-status-events-table.js +1 -0
- package/core/server/data/migrations/versions/4.0/18-transform-urls-absolute-to-transform-ready.js +5 -0
- package/core/server/data/migrations/versions/4.0/22-solve-orphaned-webhooks.js +1 -0
- package/core/server/data/migrations/versions/4.0/23-regenerate-posts-html.js +1 -0
- package/core/server/data/migrations/versions/4.0/25-populate-members-paid-subscription-events-table.js +2 -1
- package/core/server/data/migrations/versions/4.12/02-fix-member-statuses.js +1 -0
- package/core/server/data/migrations/versions/4.14/01-fix-comped-member-statuses.js +3 -0
- package/core/server/data/migrations/versions/4.14/02-fix-free-members-status-events.js +1 -0
- package/core/server/data/migrations/versions/4.20/05-remove-not-null-constraint-from-portal-title.js +2 -0
- package/core/server/data/migrations/versions/4.23/01-truncate-offer-names.js +1 -0
- package/core/server/data/migrations/versions/4.3/04-attach-members-to-product.js +1 -0
- package/core/server/data/migrations/versions/4.4/01-restore-free-members-signup-setting-from-backup.js +1 -0
- package/core/server/data/migrations/versions/4.6/01-remove-comped-status.js +1 -0
- package/core/server/data/migrations/versions/4.8/04-migrate-show-newsletter-header-setting.js +1 -0
- package/core/server/data/migrations/versions/4.9/05-fix-missed-mobiledoc-url-transforms.js +1 -0
- package/core/server/data/migrations/versions/4.9/06-add-comped-status.js +1 -0
- package/core/server/data/migrations/versions/4.9/07-update-comped-members-status-events.js +1 -0
- package/core/server/data/schema/commands.js +2 -2
- package/core/server/ghost-server.js +2 -2
- package/core/server/lib/image/image-size.js +2 -2
- package/core/server/models/base/listeners.js +2 -2
- package/core/server/models/member-email-change-event.js +2 -2
- package/core/server/models/member-login-event.js +2 -2
- package/core/server/models/member-paid-subscription-event.js +3 -3
- package/core/server/models/member-payment-event.js +3 -3
- package/core/server/models/member-product-event.js +6 -6
- package/core/server/models/member-status-event.js +5 -3
- package/core/server/models/member-subscribe-event.js +9 -3
- package/core/server/models/relations/authors.js +1 -1
- package/core/server/models/settings.js +1 -1
- package/core/server/notify.js +1 -2
- package/core/server/services/auth/passwordreset.js +1 -1
- package/core/server/services/auth/setup.js +1 -1
- package/core/server/services/email-analytics/jobs/index.js +1 -1
- package/core/server/services/mega/mega.js +6 -4
- package/core/server/services/mega/template.js +47 -17
- package/core/server/services/members/api.js +22 -0
- package/core/server/services/members/config.js +1 -1
- package/core/server/services/members/emails/signup-paid.js +168 -0
- package/core/server/services/members/service.js +6 -2
- package/core/server/services/members/stripe-connect.js +4 -2
- package/core/server/services/nft-oembed.js +7 -2
- package/core/server/services/oembed.js +15 -3
- package/core/server/services/permissions/can-this.js +1 -1
- package/core/server/services/redirects/api.js +20 -25
- package/core/server/services/redirects/index.js +18 -10
- package/core/server/services/redirects/utils.js +14 -0
- package/core/server/services/redirects/validation.js +10 -0
- package/core/server/services/route-settings/default-settings-manager.js +1 -1
- package/core/server/services/route-settings/index.js +40 -17
- package/core/server/services/route-settings/route-settings.js +120 -115
- package/core/server/services/route-settings/settings-loader.js +18 -36
- package/core/server/services/route-settings/yaml-parser.js +1 -1
- package/core/server/services/slack.js +1 -1
- package/core/server/services/themes/activation-bridge.js +3 -3
- package/core/server/services/themes/storage.js +2 -2
- package/core/server/services/twitter-embed.js +81 -0
- package/core/server/services/url/LocalFileCache.js +75 -0
- package/core/server/services/url/UrlService.js +15 -47
- package/core/server/services/url/index.js +17 -4
- package/core/server/services/xmlrpc.js +2 -2
- package/core/server/web/admin/app.js +2 -5
- package/core/server/web/admin/controller.js +35 -12
- package/core/server/web/admin/middleware/redirect-admin-urls.js +15 -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/canary/admin/app.js +0 -3
- package/core/server/web/api/canary/admin/middleware.js +1 -1
- package/core/server/web/api/canary/content/app.js +0 -3
- package/core/server/web/api/v2/admin/app.js +0 -3
- package/core/server/web/api/v2/admin/middleware.js +1 -1
- package/core/server/web/api/v2/content/app.js +0 -3
- package/core/server/web/api/v3/admin/app.js +0 -3
- package/core/server/web/api/v3/admin/middleware.js +1 -1
- package/core/server/web/api/v3/content/app.js +0 -3
- package/core/server/web/members/app.js +0 -3
- package/core/server/web/oauth/app.js +0 -4
- package/core/server/web/parent/app.js +2 -13
- package/core/server/web/parent/backend.js +2 -0
- package/core/server/web/shared/middleware/error-handler.js +57 -162
- package/core/server/web/shared/middleware/index.js +0 -4
- package/core/shared/config/defaults.json +7 -1
- package/core/shared/express.js +1 -1
- package/core/shared/labs.js +12 -7
- package/core/shared/sentry.js +1 -1
- package/package.json +41 -40
- package/yarn.lock +799 -948
- package/content/themes/casper/assets/js/gallery-card.js +0 -24
- package/core/built/assets/ghost-dark-42cf6e0c730578940ec069bda45aea41.css +0 -1
- package/core/built/assets/ghost.min-fcf6a0738421f86c47c55f20d00c5ba9.css +0 -1
- package/core/frontend/services/theme-engine/middleware.js +0 -209
- package/core/server/web/shared/middleware/maintenance.js +0 -25
|
@@ -5,6 +5,7 @@ const logging = require('@tryghost/logging');
|
|
|
5
5
|
module.exports = createTransactionalMigration(
|
|
6
6
|
async function up(knex) {
|
|
7
7
|
logging.info('Updating members.status based on members_stripe_customers_subscriptions.status');
|
|
8
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
8
9
|
const paidMemberIds = (await knex('members')
|
|
9
10
|
.select('members.id')
|
|
10
11
|
.innerJoin(
|
|
@@ -24,6 +25,7 @@ module.exports = createTransactionalMigration(
|
|
|
24
25
|
}
|
|
25
26
|
)).map(({id}) => id);
|
|
26
27
|
|
|
28
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
27
29
|
const compedMemberIds = (await knex('members')
|
|
28
30
|
.select('members.id')
|
|
29
31
|
.innerJoin(
|
|
@@ -54,6 +56,7 @@ module.exports = createTransactionalMigration(
|
|
|
54
56
|
|
|
55
57
|
const paidMemberIdChunks = chunk(paidMemberIds, chunkSize);
|
|
56
58
|
|
|
59
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
57
60
|
for (const paidMemberIdsChunk of paidMemberIdChunks) {
|
|
58
61
|
await knex('members')
|
|
59
62
|
.update('status', 'paid')
|
|
@@ -62,6 +65,7 @@ module.exports = createTransactionalMigration(
|
|
|
62
65
|
|
|
63
66
|
const compedMemberIdChunks = chunk(compedMemberIds, chunkSize);
|
|
64
67
|
|
|
68
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
65
69
|
for (const compedMemberIdsChunk of compedMemberIdChunks) {
|
|
66
70
|
await knex('members')
|
|
67
71
|
.update('status', 'comped')
|
package/core/server/data/migrations/versions/4.0/06-populate-members-subscribe-events-table.js
CHANGED
|
@@ -42,6 +42,7 @@ module.exports = createTransactionalMigration(
|
|
|
42
42
|
|
|
43
43
|
const eventChunks = chunk(allEvents, chunkSize);
|
|
44
44
|
|
|
45
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
45
46
|
for (const events of eventChunks) {
|
|
46
47
|
await knex.insert(events).into('members_subscribe_events');
|
|
47
48
|
}
|
|
@@ -28,6 +28,7 @@ module.exports = createTransactionalMigration(
|
|
|
28
28
|
|
|
29
29
|
const eventChunks = chunk(membersStatusEvents, chunkSize);
|
|
30
30
|
|
|
31
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
31
32
|
for (const events of eventChunks) {
|
|
32
33
|
await knex.insert(events).into('members_status_events');
|
|
33
34
|
}
|
package/core/server/data/migrations/versions/4.0/18-transform-urls-absolute-to-transform-ready.js
CHANGED
|
@@ -18,6 +18,7 @@ module.exports = createIrreversibleMigration(async (knex) => {
|
|
|
18
18
|
// pushing all queries into the query builder buffer in parallel
|
|
19
19
|
// https://stackoverflow.com/questions/54105280/how-to-loop-through-multi-line-sql-query-and-use-them-in-knex-transactions
|
|
20
20
|
|
|
21
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
21
22
|
for (const postIdRow of postIdRows) {
|
|
22
23
|
const {id} = postIdRow;
|
|
23
24
|
const [post] = await knex('posts')
|
|
@@ -80,6 +81,7 @@ module.exports = createIrreversibleMigration(async (knex) => {
|
|
|
80
81
|
.forUpdate()
|
|
81
82
|
.select('id');
|
|
82
83
|
|
|
84
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
83
85
|
for (const userIdRow of userIdRows) {
|
|
84
86
|
const {id} = userIdRow;
|
|
85
87
|
const [user] = await knex('users')
|
|
@@ -108,6 +110,7 @@ module.exports = createIrreversibleMigration(async (knex) => {
|
|
|
108
110
|
.forUpdate()
|
|
109
111
|
.select('id');
|
|
110
112
|
|
|
113
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
111
114
|
for (const tagIdRow of tagIdRows) {
|
|
112
115
|
const {id} = tagIdRow;
|
|
113
116
|
const [tag] = await knex('tags')
|
|
@@ -148,6 +151,7 @@ module.exports = createIrreversibleMigration(async (knex) => {
|
|
|
148
151
|
.forUpdate()
|
|
149
152
|
.select('id');
|
|
150
153
|
|
|
154
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
151
155
|
for (const snippetIdRow of snippetIdRows) {
|
|
152
156
|
const {id} = snippetIdRow;
|
|
153
157
|
const [snippet] = await knex('snippets')
|
|
@@ -180,6 +184,7 @@ module.exports = createIrreversibleMigration(async (knex) => {
|
|
|
180
184
|
'twitter_image'
|
|
181
185
|
]);
|
|
182
186
|
|
|
187
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
183
188
|
for (const settingRow of settingsRows) {
|
|
184
189
|
let {key, value} = settingRow;
|
|
185
190
|
|
|
@@ -17,6 +17,7 @@ module.exports = createIrreversibleMigration(async (knex) => {
|
|
|
17
17
|
// pushing all queries into the query builder buffer in parallel
|
|
18
18
|
// https://stackoverflow.com/questions/54105280/how-to-loop-through-multi-line-sql-query-and-use-them-in-knex-transactions
|
|
19
19
|
|
|
20
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
20
21
|
for (const postIdRow of postIdRows) {
|
|
21
22
|
const {id} = postIdRow;
|
|
22
23
|
const [post] = await knex('posts')
|
|
@@ -44,7 +44,7 @@ module.exports = createTransactionalMigration(
|
|
|
44
44
|
return amount * 30;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
throw new errors.
|
|
47
|
+
throw new errors.InternalServerError({
|
|
48
48
|
message: tpl(messages.unknownSubscriptionIntervalError , {
|
|
49
49
|
interval
|
|
50
50
|
})
|
|
@@ -116,6 +116,7 @@ module.exports = createTransactionalMigration(
|
|
|
116
116
|
|
|
117
117
|
const eventChunks = chunk(allEvents, chunkSize);
|
|
118
118
|
|
|
119
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
119
120
|
for (const events of eventChunks) {
|
|
120
121
|
await knex.insert(events).into('members_paid_subscription_events');
|
|
121
122
|
}
|
|
@@ -3,6 +3,7 @@ const {createTransactionalMigration} = require('../../utils');
|
|
|
3
3
|
const logging = require('@tryghost/logging');
|
|
4
4
|
|
|
5
5
|
module.exports = createTransactionalMigration(async function up(knex) {
|
|
6
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
6
7
|
const compedMemberIds = (await knex('members')
|
|
7
8
|
.select('members.id')
|
|
8
9
|
.innerJoin(
|
|
@@ -44,12 +45,14 @@ module.exports = createTransactionalMigration(async function up(knex) {
|
|
|
44
45
|
|
|
45
46
|
const compedMemberIdChunks = chunk(compedMemberIds, chunkSize);
|
|
46
47
|
|
|
48
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
47
49
|
for (const compedMemberIdsChunk of compedMemberIdChunks) {
|
|
48
50
|
await knex('members')
|
|
49
51
|
.update('status', 'comped')
|
|
50
52
|
.whereIn('id', compedMemberIdsChunk);
|
|
51
53
|
}
|
|
52
54
|
|
|
55
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
53
56
|
for (const memberId of compedMemberIds) {
|
|
54
57
|
const mostRecentStatusEvent = await knex('members_status_events')
|
|
55
58
|
.select('*')
|
|
@@ -49,6 +49,7 @@ module.exports = createTransactionalMigration(
|
|
|
49
49
|
// and so we're left with 998 for our WHERE IN clause values
|
|
50
50
|
const chunkedEventsToUpdate = _.chunk(eventsToUpdate, 998);
|
|
51
51
|
|
|
52
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
52
53
|
for (const chunk of chunkedEventsToUpdate) {
|
|
53
54
|
logging.info(`Updating a chunk of ${chunk.length} member status events`);
|
|
54
55
|
await knex('members_status_events')
|
package/core/server/data/migrations/versions/4.20/05-remove-not-null-constraint-from-portal-title.js
CHANGED
|
@@ -15,6 +15,7 @@ module.exports = createNonTransactionalMigration(
|
|
|
15
15
|
});
|
|
16
16
|
|
|
17
17
|
if (knex.client.config.client === 'sqlite3') {
|
|
18
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
18
19
|
for (const column of ['name', 'code', 'stripe_coupon_id']) {
|
|
19
20
|
await addUnique('offers', column, knex);
|
|
20
21
|
}
|
|
@@ -32,6 +33,7 @@ module.exports = createNonTransactionalMigration(
|
|
|
32
33
|
});
|
|
33
34
|
|
|
34
35
|
if (knex.client.config.client === 'sqlite3') {
|
|
36
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
35
37
|
for (const column of ['name', 'code', 'stripe_coupon_id']) {
|
|
36
38
|
await addUnique('offers', column, knex);
|
|
37
39
|
}
|
|
@@ -47,6 +47,7 @@ module.exports = createTransactionalMigration(
|
|
|
47
47
|
return offers.concat(updatedRow);
|
|
48
48
|
}, []);
|
|
49
49
|
|
|
50
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
50
51
|
for (const truncatedOffer of truncatedOffers) {
|
|
51
52
|
await knex('offers')
|
|
52
53
|
.update('name', truncatedOffer.name)
|
|
@@ -38,6 +38,7 @@ module.exports = createTransactionalMigration(
|
|
|
38
38
|
const chunkSize = 333;
|
|
39
39
|
const memberProductRelationsChunks = chunk(memberProductRelations, chunkSize);
|
|
40
40
|
|
|
41
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
41
42
|
for (const relations of memberProductRelationsChunks) {
|
|
42
43
|
await knex.insert(relations).into('members_products');
|
|
43
44
|
}
|
package/core/server/data/migrations/versions/4.8/04-migrate-show-newsletter-header-setting.js
CHANGED
|
@@ -27,6 +27,7 @@ module.exports = createTransactionalMigration(
|
|
|
27
27
|
const newSettingKeys = ['newsletter_show_header_title', 'newsletter_show_header_icon'];
|
|
28
28
|
const now = connection.raw('CURRENT_TIMESTAMP');
|
|
29
29
|
|
|
30
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
30
31
|
for (const settingKey of newSettingKeys) {
|
|
31
32
|
const existingSetting = await connection('settings').where('key', settingKey).first();
|
|
32
33
|
|
|
@@ -3,6 +3,7 @@ const {createTransactionalMigration} = require('../../utils.js');
|
|
|
3
3
|
|
|
4
4
|
module.exports = createTransactionalMigration(
|
|
5
5
|
async function up(knex) {
|
|
6
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
6
7
|
const compedMemberIds = (await knex('members')
|
|
7
8
|
.select('members.id')
|
|
8
9
|
.innerJoin(
|
|
@@ -15,6 +15,7 @@ module.exports = createTransactionalMigration(
|
|
|
15
15
|
logging.info(`Found ${compedMembers.length} comped members - checking members_status_events`);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
18
19
|
for (const member of compedMembers) {
|
|
19
20
|
const mostRecentStatusEvent = await knex('members_status_events')
|
|
20
21
|
.select('*')
|
|
@@ -139,7 +139,7 @@ async function hasForeignSQLite({fromTable, fromColumn, toTable, toColumn, trans
|
|
|
139
139
|
const client = knex.client.config.client;
|
|
140
140
|
|
|
141
141
|
if (client !== 'sqlite3') {
|
|
142
|
-
throw new errors.
|
|
142
|
+
throw new errors.InternalServerError({
|
|
143
143
|
message: tpl(messages.hasForeignSQLite3)
|
|
144
144
|
});
|
|
145
145
|
}
|
|
@@ -265,7 +265,7 @@ async function hasPrimaryKeySQLite(tableName, transaction) {
|
|
|
265
265
|
const client = knex.client.config.client;
|
|
266
266
|
|
|
267
267
|
if (client !== 'sqlite3') {
|
|
268
|
-
throw new errors.
|
|
268
|
+
throw new errors.InternalServerError({
|
|
269
269
|
message: tpl(messages.hasPrimaryKeySQLiteError)
|
|
270
270
|
});
|
|
271
271
|
}
|
|
@@ -107,13 +107,13 @@ class GhostServer {
|
|
|
107
107
|
let ghostError;
|
|
108
108
|
|
|
109
109
|
if (error.code === 'EADDRINUSE') {
|
|
110
|
-
ghostError = new errors.
|
|
110
|
+
ghostError = new errors.InternalServerError({
|
|
111
111
|
message: tpl(messages.addressInUse.error),
|
|
112
112
|
context: tpl(messages.addressInUse.context, {port: config.get('server').port}),
|
|
113
113
|
help: tpl(messages.addressInUse.help)
|
|
114
114
|
});
|
|
115
115
|
} else {
|
|
116
|
-
ghostError = new errors.
|
|
116
|
+
ghostError = new errors.InternalServerError({
|
|
117
117
|
message: tpl(messages.otherError.error, {errorNumber: error.errno}),
|
|
118
118
|
context: tpl(messages.otherError.context),
|
|
119
119
|
help: tpl(messages.otherError.help)
|
|
@@ -177,7 +177,7 @@ class ImageSize {
|
|
|
177
177
|
context: err.url || imagePath
|
|
178
178
|
}));
|
|
179
179
|
}).catch(function (err) {
|
|
180
|
-
if (errors.utils.
|
|
180
|
+
if (errors.utils.isGhostError(err)) {
|
|
181
181
|
return Promise.reject(err);
|
|
182
182
|
}
|
|
183
183
|
|
|
@@ -241,7 +241,7 @@ class ImageSize {
|
|
|
241
241
|
}
|
|
242
242
|
}));
|
|
243
243
|
}).catch((err) => {
|
|
244
|
-
if (errors.utils.
|
|
244
|
+
if (errors.utils.isGhostError(err)) {
|
|
245
245
|
return Promise.reject(err);
|
|
246
246
|
}
|
|
247
247
|
|
|
@@ -69,13 +69,13 @@ events.on('settings.timezone.edited', function (settingModel, options) {
|
|
|
69
69
|
try {
|
|
70
70
|
await models.Post.edit(post.toJSON(), _.merge({id: post.id}, options));
|
|
71
71
|
} catch (err) {
|
|
72
|
-
logging.error(new errors.
|
|
72
|
+
logging.error(new errors.InternalServerError({
|
|
73
73
|
err
|
|
74
74
|
}));
|
|
75
75
|
}
|
|
76
76
|
});
|
|
77
77
|
} catch (err) {
|
|
78
|
-
logging.error(new errors.
|
|
78
|
+
logging.error(new errors.InternalServerError({
|
|
79
79
|
err: err,
|
|
80
80
|
level: 'critical'
|
|
81
81
|
}));
|
|
@@ -9,11 +9,11 @@ const MemberEmailChangeEvent = ghostBookshelf.Model.extend({
|
|
|
9
9
|
}
|
|
10
10
|
}, {
|
|
11
11
|
async edit() {
|
|
12
|
-
throw new errors.IncorrectUsageError('Cannot edit MemberEmailChangeEvent');
|
|
12
|
+
throw new errors.IncorrectUsageError({message: 'Cannot edit MemberEmailChangeEvent'});
|
|
13
13
|
},
|
|
14
14
|
|
|
15
15
|
async destroy() {
|
|
16
|
-
throw new errors.IncorrectUsageError('Cannot destroy MemberEmailChangeEvent');
|
|
16
|
+
throw new errors.IncorrectUsageError({message: 'Cannot destroy MemberEmailChangeEvent'});
|
|
17
17
|
}
|
|
18
18
|
});
|
|
19
19
|
|
|
@@ -9,11 +9,11 @@ const MemberLoginEvent = ghostBookshelf.Model.extend({
|
|
|
9
9
|
}
|
|
10
10
|
}, {
|
|
11
11
|
async edit() {
|
|
12
|
-
throw new errors.IncorrectUsageError('Cannot edit MemberLoginEvent');
|
|
12
|
+
throw new errors.IncorrectUsageError({message: 'Cannot edit MemberLoginEvent'});
|
|
13
13
|
},
|
|
14
14
|
|
|
15
15
|
async destroy() {
|
|
16
|
-
throw new errors.IncorrectUsageError('Cannot destroy MemberLoginEvent');
|
|
16
|
+
throw new errors.IncorrectUsageError({message: 'Cannot destroy MemberLoginEvent'});
|
|
17
17
|
}
|
|
18
18
|
});
|
|
19
19
|
|
|
@@ -11,7 +11,7 @@ const MemberPaidSubscriptionEvent = ghostBookshelf.Model.extend({
|
|
|
11
11
|
customQuery(qb, options) {
|
|
12
12
|
if (options.aggregateMRRDeltas) {
|
|
13
13
|
if (options.limit || options.filter) {
|
|
14
|
-
throw new errors.IncorrectUsageError('aggregateMRRDeltas does not work when passed a filter or limit');
|
|
14
|
+
throw new errors.IncorrectUsageError({message: 'aggregateMRRDeltas does not work when passed a filter or limit'});
|
|
15
15
|
}
|
|
16
16
|
const knex = ghostBookshelf.knex;
|
|
17
17
|
return qb.clear('select')
|
|
@@ -33,11 +33,11 @@ const MemberPaidSubscriptionEvent = ghostBookshelf.Model.extend({
|
|
|
33
33
|
return options;
|
|
34
34
|
},
|
|
35
35
|
async edit() {
|
|
36
|
-
throw new errors.IncorrectUsageError('Cannot edit MemberPaidSubscriptionEvent');
|
|
36
|
+
throw new errors.IncorrectUsageError({message: 'Cannot edit MemberPaidSubscriptionEvent'});
|
|
37
37
|
},
|
|
38
38
|
|
|
39
39
|
async destroy() {
|
|
40
|
-
throw new errors.IncorrectUsageError('Cannot destroy MemberPaidSubscriptionEvent');
|
|
40
|
+
throw new errors.IncorrectUsageError({message: 'Cannot destroy MemberPaidSubscriptionEvent'});
|
|
41
41
|
}
|
|
42
42
|
});
|
|
43
43
|
|
|
@@ -11,7 +11,7 @@ const MemberPaymentEvent = ghostBookshelf.Model.extend({
|
|
|
11
11
|
customQuery(qb, options) {
|
|
12
12
|
if (options.aggregatePaymentVolume) {
|
|
13
13
|
if (options.limit || options.filter) {
|
|
14
|
-
throw new errors.IncorrectUsageError('aggregatePaymentVolume does not work when passed a filter or limit');
|
|
14
|
+
throw new errors.IncorrectUsageError({message: 'aggregatePaymentVolume does not work when passed a filter or limit'});
|
|
15
15
|
}
|
|
16
16
|
const knex = ghostBookshelf.knex;
|
|
17
17
|
return qb.clear('select')
|
|
@@ -33,11 +33,11 @@ const MemberPaymentEvent = ghostBookshelf.Model.extend({
|
|
|
33
33
|
return options;
|
|
34
34
|
},
|
|
35
35
|
async edit() {
|
|
36
|
-
throw new errors.IncorrectUsageError('Cannot edit MemberPaymentEvent');
|
|
36
|
+
throw new errors.IncorrectUsageError({message: 'Cannot edit MemberPaymentEvent'});
|
|
37
37
|
},
|
|
38
38
|
|
|
39
39
|
async destroy() {
|
|
40
|
-
throw new errors.IncorrectUsageError('Cannot destroy MemberPaymentEvent');
|
|
40
|
+
throw new errors.IncorrectUsageError({message: 'Cannot destroy MemberPaymentEvent'});
|
|
41
41
|
}
|
|
42
42
|
});
|
|
43
43
|
|
|
@@ -19,15 +19,15 @@ const MemberProductEvent = ghostBookshelf.Model.extend({
|
|
|
19
19
|
|
|
20
20
|
}, {
|
|
21
21
|
async edit() {
|
|
22
|
-
throw new errors.IncorrectUsageError(
|
|
23
|
-
tpl(messages.cannotPerformAction, 'edit')
|
|
24
|
-
);
|
|
22
|
+
throw new errors.IncorrectUsageError({
|
|
23
|
+
message: tpl(messages.cannotPerformAction, 'edit')
|
|
24
|
+
});
|
|
25
25
|
},
|
|
26
26
|
|
|
27
27
|
async destroy() {
|
|
28
|
-
throw new errors.IncorrectUsageError(
|
|
29
|
-
tpl(messages.cannotPerformAction, 'destroy')
|
|
30
|
-
);
|
|
28
|
+
throw new errors.IncorrectUsageError({
|
|
29
|
+
message: tpl(messages.cannotPerformAction, 'destroy')
|
|
30
|
+
});
|
|
31
31
|
}
|
|
32
32
|
});
|
|
33
33
|
|
|
@@ -11,7 +11,9 @@ const MemberStatusEvent = ghostBookshelf.Model.extend({
|
|
|
11
11
|
customQuery(qb, options) {
|
|
12
12
|
if (options.aggregateStatusCounts) {
|
|
13
13
|
if (options.limit || options.filter) {
|
|
14
|
-
throw new errors.IncorrectUsageError(
|
|
14
|
+
throw new errors.IncorrectUsageError({
|
|
15
|
+
message: 'aggregateStatusCounts does not work when passed a filter or limit'
|
|
16
|
+
});
|
|
15
17
|
}
|
|
16
18
|
const knex = ghostBookshelf.knex;
|
|
17
19
|
return qb.clear('select')
|
|
@@ -46,11 +48,11 @@ const MemberStatusEvent = ghostBookshelf.Model.extend({
|
|
|
46
48
|
return options;
|
|
47
49
|
},
|
|
48
50
|
async edit() {
|
|
49
|
-
throw new errors.IncorrectUsageError('Cannot edit MemberStatusEvent');
|
|
51
|
+
throw new errors.IncorrectUsageError({message: 'Cannot edit MemberStatusEvent'});
|
|
50
52
|
},
|
|
51
53
|
|
|
52
54
|
async destroy() {
|
|
53
|
-
throw new errors.IncorrectUsageError('Cannot destroy MemberStatusEvent');
|
|
55
|
+
throw new errors.IncorrectUsageError({message: 'Cannot destroy MemberStatusEvent'});
|
|
54
56
|
}
|
|
55
57
|
});
|
|
56
58
|
|
|
@@ -11,7 +11,9 @@ const MemberSubscribeEvent = ghostBookshelf.Model.extend({
|
|
|
11
11
|
customQuery(qb, options) {
|
|
12
12
|
if (options.aggregateSubscriptionDeltas) {
|
|
13
13
|
if (options.limit || options.filter) {
|
|
14
|
-
throw new errors.IncorrectUsageError(
|
|
14
|
+
throw new errors.IncorrectUsageError({
|
|
15
|
+
message: 'aggregateSubscriptionDeltas does not work when passed a filter or limit'
|
|
16
|
+
});
|
|
15
17
|
}
|
|
16
18
|
const knex = ghostBookshelf.knex;
|
|
17
19
|
return qb.clear('select')
|
|
@@ -32,11 +34,15 @@ const MemberSubscribeEvent = ghostBookshelf.Model.extend({
|
|
|
32
34
|
return options;
|
|
33
35
|
},
|
|
34
36
|
async edit() {
|
|
35
|
-
throw new errors.IncorrectUsageError(
|
|
37
|
+
throw new errors.IncorrectUsageError({
|
|
38
|
+
message: 'Cannot edit MemberSubscribeEvent'
|
|
39
|
+
});
|
|
36
40
|
},
|
|
37
41
|
|
|
38
42
|
async destroy() {
|
|
39
|
-
throw new errors.IncorrectUsageError(
|
|
43
|
+
throw new errors.IncorrectUsageError({
|
|
44
|
+
message: 'Cannot destroy MemberSubscribeEvent'
|
|
45
|
+
});
|
|
40
46
|
}
|
|
41
47
|
});
|
|
42
48
|
|
|
@@ -324,7 +324,7 @@ module.exports.extendModel = function extendModel(Post, Posts, ghostBookshelf) {
|
|
|
324
324
|
.then(() => response);
|
|
325
325
|
})
|
|
326
326
|
.catch((err) => {
|
|
327
|
-
throw new errors.
|
|
327
|
+
throw new errors.InternalServerError({err: err});
|
|
328
328
|
});
|
|
329
329
|
});
|
|
330
330
|
|
|
@@ -346,7 +346,7 @@ Settings = ghostBookshelf.Model.extend({
|
|
|
346
346
|
);
|
|
347
347
|
|
|
348
348
|
if (validationErrors.length) {
|
|
349
|
-
throw new errors.ValidationError(validationErrors.join('\n'));
|
|
349
|
+
throw new errors.ValidationError({message: validationErrors.join('\n')});
|
|
350
350
|
}
|
|
351
351
|
},
|
|
352
352
|
async labs(model) {
|
package/core/server/notify.js
CHANGED
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
|
|
9
9
|
// Required Ghost internals
|
|
10
10
|
const config = require('../shared/config');
|
|
11
|
-
const logging = require('@tryghost/logging');
|
|
12
11
|
|
|
13
12
|
let notified = {
|
|
14
13
|
started: false,
|
|
@@ -53,7 +52,7 @@ async function notify(type, error = null) {
|
|
|
53
52
|
let socketAddress = config.get('bootstrap-socket');
|
|
54
53
|
if (socketAddress) {
|
|
55
54
|
const bootstrapSocket = require('@tryghost/bootstrap-socket');
|
|
56
|
-
return bootstrapSocket.connectAndSend(socketAddress,
|
|
55
|
+
return bootstrapSocket.connectAndSend(socketAddress, message);
|
|
57
56
|
}
|
|
58
57
|
|
|
59
58
|
return Promise.resolve();
|
|
@@ -148,7 +148,7 @@ function doReset(options, tokenParts, settingsAPI) {
|
|
|
148
148
|
return Promise.reject(err);
|
|
149
149
|
})
|
|
150
150
|
.catch((err) => {
|
|
151
|
-
if (errors.utils.
|
|
151
|
+
if (errors.utils.isGhostError(err)) {
|
|
152
152
|
return Promise.reject(err);
|
|
153
153
|
}
|
|
154
154
|
return Promise.reject(new errors.UnauthorizedError({err: err}));
|
|
@@ -59,7 +59,7 @@ async function setupUser(userData) {
|
|
|
59
59
|
const owner = await models.User.findOne({role: 'Owner', status: 'all'});
|
|
60
60
|
|
|
61
61
|
if (!owner) {
|
|
62
|
-
throw new errors.
|
|
62
|
+
throw new errors.InternalServerError({
|
|
63
63
|
message: tpl(messages.setupUnableToRun)
|
|
64
64
|
});
|
|
65
65
|
}
|
|
@@ -12,7 +12,7 @@ module.exports = {
|
|
|
12
12
|
!hasScheduled &&
|
|
13
13
|
config.get('emailAnalytics') &&
|
|
14
14
|
config.get('backgroundJobs:emailAnalytics') &&
|
|
15
|
-
!process.env.NODE_ENV.
|
|
15
|
+
!process.env.NODE_ENV.startsWith('test')
|
|
16
16
|
) {
|
|
17
17
|
// Don't register email analytics job if we have no emails,
|
|
18
18
|
// processor usage from many sites spinning up threads can be high.
|
|
@@ -131,7 +131,7 @@ const transformEmailRecipientFilter = (emailRecipientFilter, {errorProperty = 'e
|
|
|
131
131
|
// `paid` and `free` were swapped out for NQL filters in 4.5.0, we shouldn't see them here now
|
|
132
132
|
case 'paid':
|
|
133
133
|
case 'free':
|
|
134
|
-
throw new errors.
|
|
134
|
+
throw new errors.InternalServerError({
|
|
135
135
|
message: tpl(messages.unexpectedFilterError, {
|
|
136
136
|
property: errorProperty,
|
|
137
137
|
value: emailRecipientFilter
|
|
@@ -140,7 +140,7 @@ const transformEmailRecipientFilter = (emailRecipientFilter, {errorProperty = 'e
|
|
|
140
140
|
case 'all':
|
|
141
141
|
return 'subscribed:true';
|
|
142
142
|
case 'none':
|
|
143
|
-
throw new errors.
|
|
143
|
+
throw new errors.InternalServerError({
|
|
144
144
|
message: tpl(messages.noneFilterError, {
|
|
145
145
|
property: errorProperty
|
|
146
146
|
})
|
|
@@ -352,7 +352,7 @@ async function sendEmailJob({emailModel, options}) {
|
|
|
352
352
|
error: errorMessage
|
|
353
353
|
}, {patch: true});
|
|
354
354
|
|
|
355
|
-
throw new errors.
|
|
355
|
+
throw new errors.InternalServerError({
|
|
356
356
|
err: error,
|
|
357
357
|
context: tpl(messages.sendEmailRequestFailed)
|
|
358
358
|
});
|
|
@@ -416,7 +416,9 @@ function partitionMembersBySegment(memberRows, segments) {
|
|
|
416
416
|
segmentedMemberRows = memberRows.filter(member => member.status !== 'free');
|
|
417
417
|
memberRows = memberRows.filter(member => member.status === 'free');
|
|
418
418
|
} else {
|
|
419
|
-
throw new errors.ValidationError(
|
|
419
|
+
throw new errors.ValidationError({
|
|
420
|
+
message: tpl(messages.invalidSegment)
|
|
421
|
+
});
|
|
420
422
|
}
|
|
421
423
|
|
|
422
424
|
partitions[memberSegment] = segmentedMemberRows;
|