ghost 4.15.1 → 4.16.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/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 +1 -1
- package/content/themes/casper/default.hbs +2 -2
- package/content/themes/casper/package.json +1 -1
- package/content/themes/casper/page.hbs +28 -26
- package/content/themes/casper/partials/post-card.hbs +2 -2
- package/content/themes/casper/post.hbs +67 -65
- package/content/themes/casper/tag.hbs +2 -2
- package/core/built/assets/ghost-dark-bb2831fc27fcb02893ed0a761207dc63.css +1 -0
- package/core/built/assets/{ghost.min-e35cfee26d942c364166f57f3dcc9e75.js → ghost.min-d1d99f3ed6e0f427874b2a11e7078475.js} +228 -187
- package/core/built/assets/ghost.min-e7612edfa72b0fe2c201b387923e6fc7.css +1 -0
- package/core/built/assets/icons/discount-bubble.svg +1 -0
- package/core/built/assets/{vendor.min-ca33abc718f21a51327841d58f8875d0.js → vendor.min-3660ec7864887f1496fe7a27fd23ab76.js} +44 -42
- package/core/frontend/helpers/ghost_head.js +7 -1
- package/core/frontend/services/settings/loader.js +2 -2
- package/core/frontend/services/theme-engine/middleware.js +4 -1
- package/core/server/api/canary/settings.js +13 -144
- package/core/server/api/canary/utils/validators/input/settings.js +23 -1
- package/core/server/api/v3/settings.js +13 -132
- package/core/server/api/v3/utils/validators/input/settings.js +23 -1
- package/core/server/data/exporter/table-lists.js +1 -0
- package/core/server/data/importer/import-manager.js +398 -0
- package/core/server/data/importer/importers/data/data-importer.js +162 -0
- package/core/server/data/importer/importers/data/index.js +1 -162
- package/core/server/data/importer/index.js +1 -379
- package/core/server/data/migrations/versions/4.16/01-add-custom-theme-settings-table.js +9 -0
- package/core/server/data/schema/schema.js +16 -0
- package/core/server/models/custom-theme-setting.js +9 -0
- package/core/server/models/index.js +2 -0
- package/core/server/services/custom-theme-settings.js +8 -0
- package/core/server/services/members/api.js +1 -0
- package/core/server/services/settings/index.js +13 -16
- package/core/server/services/settings/settings-bread-service.js +188 -0
- package/core/server/services/settings/settings-utils.js +32 -0
- package/core/server/services/themes/ThemeStorage.js +5 -4
- package/core/server/services/themes/activation-bridge.js +14 -0
- package/core/server/services/themes/validate.js +5 -2
- 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/members/app.js +2 -0
- package/core/shared/custom-theme-settings-cache.js +3 -0
- package/core/shared/labs.js +2 -1
- package/package.json +28 -27
- package/yarn.lock +806 -795
- package/core/built/assets/ghost-dark-faf931d90e92535e6c03ca16793cbe7b.css +0 -1
- package/core/built/assets/ghost.min-7aa074ad556a8455155ac88ceaca03ab.css +0 -1
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
const Promise = require('bluebird');
|
|
2
2
|
const _ = require('lodash');
|
|
3
|
-
const validator = require('@tryghost/validator');
|
|
4
3
|
const models = require('../../models');
|
|
5
4
|
const routeSettings = require('../../services/route-settings');
|
|
6
5
|
const frontendSettings = require('../../../frontend/services/settings');
|
|
7
6
|
const i18n = require('../../../shared/i18n');
|
|
8
|
-
const {BadRequestError
|
|
7
|
+
const {BadRequestError} = require('@tryghost/errors');
|
|
9
8
|
const settingsService = require('../../services/settings');
|
|
10
|
-
const settingsCache = require('../../../shared/settings-cache');
|
|
11
9
|
const membersService = require('../../services/members');
|
|
12
10
|
|
|
11
|
+
const settingsBREADService = settingsService.getSettingsBREADServiceInstance();
|
|
12
|
+
|
|
13
13
|
module.exports = {
|
|
14
14
|
docName: 'settings',
|
|
15
15
|
|
|
@@ -17,26 +17,7 @@ module.exports = {
|
|
|
17
17
|
options: ['group'],
|
|
18
18
|
permissions: true,
|
|
19
19
|
query(frame) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
// CASE: no context passed (functional call)
|
|
23
|
-
if (!frame.options.context) {
|
|
24
|
-
return Promise.resolve(settings.filter((setting) => {
|
|
25
|
-
return setting.group === 'site';
|
|
26
|
-
}));
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (!frame.options.context.internal) {
|
|
30
|
-
// CASE: omit core settings unless internal request
|
|
31
|
-
settings = _.filter(settings, (setting) => {
|
|
32
|
-
const isCore = setting.group === 'core';
|
|
33
|
-
return !isCore;
|
|
34
|
-
});
|
|
35
|
-
// CASE: omit secret settings unless internal request
|
|
36
|
-
settings = settings.map(settingsService.hideValueIfSecret);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return settings;
|
|
20
|
+
return settingsBREADService.browse(frame.options.context);
|
|
40
21
|
}
|
|
41
22
|
},
|
|
42
23
|
|
|
@@ -55,41 +36,7 @@ module.exports = {
|
|
|
55
36
|
}
|
|
56
37
|
},
|
|
57
38
|
query(frame) {
|
|
58
|
-
|
|
59
|
-
if (frame.options.key === 'slack') {
|
|
60
|
-
const slackURL = settingsCache.get('slack_url', {resolve: false});
|
|
61
|
-
const slackUsername = settingsCache.get('slack_username', {resolve: false});
|
|
62
|
-
|
|
63
|
-
setting = slackURL || slackUsername;
|
|
64
|
-
setting.key = 'slack';
|
|
65
|
-
setting.value = [{
|
|
66
|
-
url: slackURL && slackURL.value,
|
|
67
|
-
username: slackUsername && slackUsername.value
|
|
68
|
-
}];
|
|
69
|
-
} else {
|
|
70
|
-
setting = settingsCache.get(frame.options.key, {resolve: false});
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (!setting) {
|
|
74
|
-
return Promise.reject(new NotFoundError({
|
|
75
|
-
message: i18n.t('errors.api.settings.problemFindingSetting', {
|
|
76
|
-
key: frame.options.key
|
|
77
|
-
})
|
|
78
|
-
}));
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// @TODO: handle in settings model permissible fn
|
|
82
|
-
if (setting.group === 'core' && !(frame.options.context && frame.options.context.internal)) {
|
|
83
|
-
return Promise.reject(new NoPermissionError({
|
|
84
|
-
message: i18n.t('errors.api.settings.accessCoreSettingFromExtReq')
|
|
85
|
-
}));
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
setting = settingsService.hideValueIfSecret(setting);
|
|
89
|
-
|
|
90
|
-
return {
|
|
91
|
-
[frame.options.key]: setting
|
|
92
|
-
};
|
|
39
|
+
return settingsBREADService.read(frame.options.key, frame.options.context);
|
|
93
40
|
}
|
|
94
41
|
},
|
|
95
42
|
|
|
@@ -153,17 +100,7 @@ module.exports = {
|
|
|
153
100
|
],
|
|
154
101
|
async query(frame) {
|
|
155
102
|
const {email, type} = frame.data;
|
|
156
|
-
if (typeof email !== 'string' || !validator.isEmail(email)) {
|
|
157
|
-
throw new BadRequestError({
|
|
158
|
-
message: i18n.t('errors.api.settings.invalidEmailReceived')
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
103
|
|
|
162
|
-
if (!type || !['fromAddressUpdate', 'supportAddressUpdate'].includes(type)) {
|
|
163
|
-
throw new BadRequestError({
|
|
164
|
-
message: 'Invalid email type recieved'
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
104
|
try {
|
|
168
105
|
// Send magic link to update fromAddress
|
|
169
106
|
await membersService.settings.sendEmailAddressUpdateMagicLink({
|
|
@@ -225,91 +162,23 @@ module.exports = {
|
|
|
225
162
|
permissions: {
|
|
226
163
|
unsafeAttrsObject(frame) {
|
|
227
164
|
return _.find(frame.data.settings, {key: 'labs'});
|
|
228
|
-
},
|
|
229
|
-
async before(frame) {
|
|
230
|
-
if (frame.options.context && frame.options.context.internal) {
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
const firstCoreSetting = frame.data.settings.find(setting => setting.group === 'core');
|
|
235
|
-
if (firstCoreSetting) {
|
|
236
|
-
throw new NoPermissionError({
|
|
237
|
-
message: i18n.t('errors.api.settings.accessCoreSettingFromExtReq')
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
165
|
}
|
|
241
166
|
},
|
|
242
167
|
async query(frame) {
|
|
168
|
+
let stripeConnectData;
|
|
243
169
|
const stripeConnectIntegrationToken = frame.data.settings.find(setting => setting.key === 'stripe_connect_integration_token');
|
|
244
170
|
|
|
245
|
-
const settings = frame.data.settings.filter((setting) => {
|
|
246
|
-
// The `stripe_connect_integration_token` "setting" is only used to set the `stripe_connect_*` settings.
|
|
247
|
-
return ![
|
|
248
|
-
'stripe_connect_integration_token',
|
|
249
|
-
'stripe_connect_publishable_key',
|
|
250
|
-
'stripe_connect_secret_key',
|
|
251
|
-
'stripe_connect_livemode',
|
|
252
|
-
'stripe_connect_account_id',
|
|
253
|
-
'stripe_connect_display_name'
|
|
254
|
-
].includes(setting.key)
|
|
255
|
-
// Remove obfuscated settings
|
|
256
|
-
&& !(setting.value === settingsService.obfuscatedSetting && settingsService.isSecretSetting(setting));
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
const getSetting = setting => settingsCache.get(setting.key, {resolve: false});
|
|
260
|
-
|
|
261
|
-
const firstUnknownSetting = settings.find(setting => !getSetting(setting));
|
|
262
|
-
|
|
263
|
-
if (firstUnknownSetting) {
|
|
264
|
-
throw new NotFoundError({
|
|
265
|
-
message: i18n.t('errors.api.settings.problemFindingSetting', {
|
|
266
|
-
key: firstUnknownSetting.key
|
|
267
|
-
})
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
if (!(frame.options.context && frame.options.context.internal)) {
|
|
272
|
-
const firstCoreSetting = settings.find(setting => getSetting(setting).group === 'core');
|
|
273
|
-
if (firstCoreSetting) {
|
|
274
|
-
throw new NoPermissionError({
|
|
275
|
-
message: i18n.t('errors.api.settings.accessCoreSettingFromExtReq')
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
171
|
if (stripeConnectIntegrationToken && stripeConnectIntegrationToken.value) {
|
|
281
172
|
const getSessionProp = prop => frame.original.session[prop];
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
settings.push({
|
|
289
|
-
key: 'stripe_connect_secret_key',
|
|
290
|
-
value: data.secret_key
|
|
291
|
-
});
|
|
292
|
-
settings.push({
|
|
293
|
-
key: 'stripe_connect_livemode',
|
|
294
|
-
value: data.livemode
|
|
295
|
-
});
|
|
296
|
-
settings.push({
|
|
297
|
-
key: 'stripe_connect_display_name',
|
|
298
|
-
value: data.display_name
|
|
299
|
-
});
|
|
300
|
-
settings.push({
|
|
301
|
-
key: 'stripe_connect_account_id',
|
|
302
|
-
value: data.account_id
|
|
303
|
-
});
|
|
304
|
-
} catch (err) {
|
|
305
|
-
throw new BadRequestError({
|
|
306
|
-
err,
|
|
307
|
-
message: 'The Stripe Connect token could not be parsed.'
|
|
308
|
-
});
|
|
309
|
-
}
|
|
173
|
+
|
|
174
|
+
stripeConnectData = await settingsBREADService.getStripeConnectData(
|
|
175
|
+
stripeConnectIntegrationToken,
|
|
176
|
+
getSessionProp,
|
|
177
|
+
membersService.stripeConnect.getStripeConnectTokenData
|
|
178
|
+
);
|
|
310
179
|
}
|
|
311
180
|
|
|
312
|
-
return
|
|
181
|
+
return await settingsBREADService.edit(frame.data.settings, frame.options, stripeConnectData);
|
|
313
182
|
}
|
|
314
183
|
},
|
|
315
184
|
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
const Promise = require('bluebird');
|
|
2
2
|
const _ = require('lodash');
|
|
3
3
|
const i18n = require('../../../../../../shared/i18n');
|
|
4
|
-
const {NotFoundError, ValidationError} = require('@tryghost/errors');
|
|
4
|
+
const {NotFoundError, ValidationError, BadRequestError} = require('@tryghost/errors');
|
|
5
|
+
const validator = require('@tryghost/validator');
|
|
6
|
+
|
|
7
|
+
const messages = {
|
|
8
|
+
invalidEmailReceived: 'Please send a valid email',
|
|
9
|
+
invalidEmailTypeReceived: 'Invalid email type received'
|
|
10
|
+
};
|
|
5
11
|
|
|
6
12
|
module.exports = {
|
|
7
13
|
read(apiConfig, frame) {
|
|
@@ -62,5 +68,21 @@ module.exports = {
|
|
|
62
68
|
if (errors.length) {
|
|
63
69
|
return Promise.reject(errors[0]);
|
|
64
70
|
}
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
updateMembersEmail(apiConfig, frame) {
|
|
74
|
+
const {email, type} = frame.data;
|
|
75
|
+
|
|
76
|
+
if (typeof email !== 'string' || !validator.isEmail(email)) {
|
|
77
|
+
throw new BadRequestError({
|
|
78
|
+
message: messages.invalidEmailReceived
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!type || !['fromAddressUpdate', 'supportAddressUpdate'].includes(type)) {
|
|
83
|
+
throw new BadRequestError({
|
|
84
|
+
message: messages.invalidEmailTypeReceived
|
|
85
|
+
});
|
|
86
|
+
}
|
|
65
87
|
}
|
|
66
88
|
};
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
const Promise = require('bluebird');
|
|
2
2
|
const _ = require('lodash');
|
|
3
|
-
const validator = require('@tryghost/validator');
|
|
4
3
|
const models = require('../../models');
|
|
5
4
|
const routeSettings = require('../../services/route-settings');
|
|
6
5
|
const frontendSettings = require('../../../frontend/services/settings');
|
|
7
6
|
const i18n = require('../../../shared/i18n');
|
|
8
|
-
const {BadRequestError, NoPermissionError
|
|
7
|
+
const {BadRequestError, NoPermissionError} = require('@tryghost/errors');
|
|
9
8
|
const settingsService = require('../../services/settings');
|
|
10
|
-
const settingsCache = require('../../../shared/settings-cache');
|
|
11
9
|
const membersService = require('../../services/members');
|
|
12
10
|
|
|
11
|
+
const settingsBREADService = settingsService.getSettingsBREADServiceInstance();
|
|
12
|
+
|
|
13
13
|
module.exports = {
|
|
14
14
|
docName: 'settings',
|
|
15
15
|
|
|
@@ -17,26 +17,7 @@ module.exports = {
|
|
|
17
17
|
options: ['type', 'group'],
|
|
18
18
|
permissions: true,
|
|
19
19
|
query(frame) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
// CASE: no context passed (functional call)
|
|
23
|
-
if (!frame.options.context) {
|
|
24
|
-
return Promise.resolve(settings.filter((setting) => {
|
|
25
|
-
return setting.group === 'site';
|
|
26
|
-
}));
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (!frame.options.context.internal) {
|
|
30
|
-
// CASE: omit core settings unless internal request
|
|
31
|
-
settings = _.filter(settings, (setting) => {
|
|
32
|
-
const isCore = setting.group === 'core';
|
|
33
|
-
return !isCore;
|
|
34
|
-
});
|
|
35
|
-
// CASE: omit secret settings unless internal request
|
|
36
|
-
settings = settings.map(settingsService.hideValueIfSecret);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return settings;
|
|
20
|
+
return settingsBREADService.browse(frame.options.context);
|
|
40
21
|
}
|
|
41
22
|
},
|
|
42
23
|
|
|
@@ -55,41 +36,7 @@ module.exports = {
|
|
|
55
36
|
}
|
|
56
37
|
},
|
|
57
38
|
query(frame) {
|
|
58
|
-
|
|
59
|
-
if (frame.options.key === 'slack') {
|
|
60
|
-
const slackURL = settingsCache.get('slack_url', {resolve: false});
|
|
61
|
-
const slackUsername = settingsCache.get('slack_username', {resolve: false});
|
|
62
|
-
|
|
63
|
-
setting = slackURL || slackUsername;
|
|
64
|
-
setting.key = 'slack';
|
|
65
|
-
setting.value = [{
|
|
66
|
-
url: slackURL && slackURL.value,
|
|
67
|
-
username: slackUsername && slackUsername.value
|
|
68
|
-
}];
|
|
69
|
-
} else {
|
|
70
|
-
setting = settingsCache.get(frame.options.key, {resolve: false});
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (!setting) {
|
|
74
|
-
return Promise.reject(new NotFoundError({
|
|
75
|
-
message: i18n.t('errors.api.settings.problemFindingSetting', {
|
|
76
|
-
key: frame.options.key
|
|
77
|
-
})
|
|
78
|
-
}));
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// @TODO: handle in settings model permissible fn
|
|
82
|
-
if (setting.group === 'core' && !(frame.options.context && frame.options.context.internal)) {
|
|
83
|
-
return Promise.reject(new NoPermissionError({
|
|
84
|
-
message: i18n.t('errors.api.settings.accessCoreSettingFromExtReq')
|
|
85
|
-
}));
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
setting = settingsService.hideValueIfSecret(setting);
|
|
89
|
-
|
|
90
|
-
return {
|
|
91
|
-
[frame.options.key]: setting
|
|
92
|
-
};
|
|
39
|
+
return settingsBREADService.read(frame.options.key, frame.options.context);
|
|
93
40
|
}
|
|
94
41
|
},
|
|
95
42
|
|
|
@@ -153,17 +100,7 @@ module.exports = {
|
|
|
153
100
|
],
|
|
154
101
|
async query(frame) {
|
|
155
102
|
const {email, type} = frame.data;
|
|
156
|
-
if (typeof email !== 'string' || !validator.isEmail(email)) {
|
|
157
|
-
throw new BadRequestError({
|
|
158
|
-
message: i18n.t('errors.api.settings.invalidEmailReceived')
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
103
|
|
|
162
|
-
if (!type || !['fromAddressUpdate', 'supportAddressUpdate'].includes(type)) {
|
|
163
|
-
throw new BadRequestError({
|
|
164
|
-
message: 'Invalid email type recieved'
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
104
|
try {
|
|
168
105
|
// Send magic link to update fromAddress
|
|
169
106
|
await membersService.settings.sendEmailAddressUpdateMagicLink({
|
|
@@ -232,76 +169,20 @@ module.exports = {
|
|
|
232
169
|
}
|
|
233
170
|
},
|
|
234
171
|
async query(frame) {
|
|
172
|
+
let stripeConnectData;
|
|
235
173
|
const stripeConnectIntegrationToken = frame.data.settings.find(setting => setting.key === 'stripe_connect_integration_token');
|
|
236
174
|
|
|
237
|
-
const settings = frame.data.settings.filter((setting) => {
|
|
238
|
-
// The `stripe_connect_integration_token` "setting" is only used to set the `stripe_connect_*` settings.
|
|
239
|
-
return ![
|
|
240
|
-
'stripe_connect_integration_token',
|
|
241
|
-
'stripe_connect_publishable_key',
|
|
242
|
-
'stripe_connect_secret_key',
|
|
243
|
-
'stripe_connect_livemode',
|
|
244
|
-
'stripe_connect_account_id',
|
|
245
|
-
'stripe_connect_display_name'
|
|
246
|
-
].includes(setting.key)
|
|
247
|
-
// Remove obfuscated settings
|
|
248
|
-
&& !(setting.value === settingsService.obfuscatedSetting && settingsService.isSecretSetting(setting));
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
const getSetting = setting => settingsCache.get(setting.key, {resolve: false});
|
|
252
|
-
|
|
253
|
-
const firstUnknownSetting = settings.find(setting => !getSetting(setting));
|
|
254
|
-
|
|
255
|
-
if (firstUnknownSetting) {
|
|
256
|
-
throw new NotFoundError({
|
|
257
|
-
message: i18n.t('errors.api.settings.problemFindingSetting', {
|
|
258
|
-
key: firstUnknownSetting.key
|
|
259
|
-
})
|
|
260
|
-
});
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
if (!(frame.options.context && frame.options.context.internal)) {
|
|
264
|
-
const firstCoreSetting = settings.find(setting => getSetting(setting).group === 'core');
|
|
265
|
-
if (firstCoreSetting) {
|
|
266
|
-
throw new NoPermissionError({
|
|
267
|
-
message: i18n.t('errors.api.settings.accessCoreSettingFromExtReq')
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
175
|
if (stripeConnectIntegrationToken && stripeConnectIntegrationToken.value) {
|
|
273
176
|
const getSessionProp = prop => frame.original.session[prop];
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
settings.push({
|
|
281
|
-
key: 'stripe_connect_secret_key',
|
|
282
|
-
value: data.secret_key
|
|
283
|
-
});
|
|
284
|
-
settings.push({
|
|
285
|
-
key: 'stripe_connect_livemode',
|
|
286
|
-
value: data.livemode
|
|
287
|
-
});
|
|
288
|
-
settings.push({
|
|
289
|
-
key: 'stripe_connect_display_name',
|
|
290
|
-
value: data.display_name
|
|
291
|
-
});
|
|
292
|
-
settings.push({
|
|
293
|
-
key: 'stripe_connect_account_id',
|
|
294
|
-
value: data.account_id
|
|
295
|
-
});
|
|
296
|
-
} catch (err) {
|
|
297
|
-
throw new BadRequestError({
|
|
298
|
-
err,
|
|
299
|
-
message: 'The Stripe Connect token could not be parsed.'
|
|
300
|
-
});
|
|
301
|
-
}
|
|
177
|
+
|
|
178
|
+
stripeConnectData = await settingsBREADService.getStripeConnectData(
|
|
179
|
+
stripeConnectIntegrationToken,
|
|
180
|
+
getSessionProp,
|
|
181
|
+
membersService.stripeConnect.getStripeConnectTokenData
|
|
182
|
+
);
|
|
302
183
|
}
|
|
303
184
|
|
|
304
|
-
return
|
|
185
|
+
return await settingsBREADService.edit(frame.data.settings, frame.options, stripeConnectData);
|
|
305
186
|
}
|
|
306
187
|
},
|
|
307
188
|
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
const Promise = require('bluebird');
|
|
2
2
|
const _ = require('lodash');
|
|
3
3
|
const i18n = require('../../../../../../shared/i18n');
|
|
4
|
-
const {NotFoundError, ValidationError} = require('@tryghost/errors');
|
|
4
|
+
const {NotFoundError, ValidationError, BadRequestError} = require('@tryghost/errors');
|
|
5
|
+
const validator = require('@tryghost/validator');
|
|
6
|
+
|
|
7
|
+
const messages = {
|
|
8
|
+
invalidEmailReceived: 'Please send a valid email',
|
|
9
|
+
invalidEmailTypeReceived: 'Invalid email type received'
|
|
10
|
+
};
|
|
5
11
|
|
|
6
12
|
module.exports = {
|
|
7
13
|
read(apiConfig, frame) {
|
|
@@ -62,5 +68,21 @@ module.exports = {
|
|
|
62
68
|
if (errors.length) {
|
|
63
69
|
return Promise.reject(errors[0]);
|
|
64
70
|
}
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
updateMembersEmail(apiConfig, frame) {
|
|
74
|
+
const {email, type} = frame.data;
|
|
75
|
+
|
|
76
|
+
if (typeof email !== 'string' || !validator.isEmail(email)) {
|
|
77
|
+
throw new BadRequestError({
|
|
78
|
+
message: messages.invalidEmailReceived
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!type || !['fromAddressUpdate', 'supportAddressUpdate'].includes(type)) {
|
|
83
|
+
throw new BadRequestError({
|
|
84
|
+
message: messages.invalidEmailTypeReceived
|
|
85
|
+
});
|
|
86
|
+
}
|
|
65
87
|
}
|
|
66
88
|
};
|