From eeabd1c9852903bfcfab579dcd436114d3e5f760 Mon Sep 17 00:00:00 2001 From: Yannick Reekmans Date: Fri, 16 Apr 2021 16:56:22 +0000 Subject: [PATCH] Add v3.42.5 --- core/server/api/canary/settings.js | 12 +++++++++--- core/server/api/v2/settings.js | 11 +++++++++-- core/server/api/v3/settings.js | 12 +++++++++--- core/server/services/settings/index.js | 22 +++++++++++++++++++++- package.json | 2 +- 5 files changed, 49 insertions(+), 10 deletions(-) diff --git a/core/server/api/canary/settings.js b/core/server/api/canary/settings.js index 77eb21a7ac..9be2f352f0 100644 --- a/core/server/api/canary/settings.js +++ b/core/server/api/canary/settings.js @@ -26,12 +26,14 @@ module.exports = { })); } - // CASE: omit core settings unless internal request if (!frame.options.context.internal) { + // CASE: omit core settings unless internal request settings = _.filter(settings, (setting) => { const isCore = setting.group === 'core'; return !isCore; }); + // CASE: omit secret settings unless internal request + settings = settings.map(settingsService.hideValueIfSecret); } return settings; @@ -70,6 +72,8 @@ module.exports = { })); } + setting = settingsService.hideValueIfSecret(setting); + return { [frame.options.key]: setting }; @@ -217,8 +221,8 @@ module.exports = { async query(frame) { const stripeConnectIntegrationToken = frame.data.settings.find(setting => setting.key === 'stripe_connect_integration_token'); - // The `stripe_connect_integration_token` "setting" is only used to set the `stripe_connect_*` settings. const settings = frame.data.settings.filter((setting) => { + // The `stripe_connect_integration_token` "setting" is only used to set the `stripe_connect_*` settings. return ![ 'stripe_connect_integration_token', 'stripe_connect_publishable_key', @@ -226,7 +230,9 @@ module.exports = { 'stripe_connect_livemode', 'stripe_connect_account_id', 'stripe_connect_display_name' - ].includes(setting.key); + ].includes(setting.key) + // Remove obfuscated settings + && !(setting.value === settingsService.obfuscatedSetting && settingsService.isSecretSetting(setting)); }); const getSetting = setting => settingsCache.get(setting.key, {resolve: false}); diff --git a/core/server/api/v2/settings.js b/core/server/api/v2/settings.js index 06ce01c80e..0a9fcf6d5b 100644 --- a/core/server/api/v2/settings.js +++ b/core/server/api/v2/settings.js @@ -24,12 +24,14 @@ module.exports = { })); } - // CASE: omit core settings unless internal request if (!frame.options.context.internal) { + // CASE: omit core settings unless internal request settings = _.filter(settings, (setting) => { const isCore = setting.group === 'core'; return !isCore; }); + // CASE: omit secret settings unless internal request + settings = settings.map(settingsService.hideValueIfSecret); } return settings; @@ -68,6 +70,8 @@ module.exports = { })); } + setting = settingsService.hideValueIfSecret(setting); + return { [frame.options.key]: setting }; @@ -108,7 +112,10 @@ module.exports = { } frame.data.settings = _.reject(frame.data.settings, (setting) => { - return setting.key === 'type'; + return setting.key === 'type' + // Remove obfuscated settings + || (setting.value === settingsService.obfuscatedSetting + && settingsService.isSecretSetting(setting)); }); const errors = []; diff --git a/core/server/api/v3/settings.js b/core/server/api/v3/settings.js index 77eb21a7ac..9be2f352f0 100644 --- a/core/server/api/v3/settings.js +++ b/core/server/api/v3/settings.js @@ -26,12 +26,14 @@ module.exports = { })); } - // CASE: omit core settings unless internal request if (!frame.options.context.internal) { + // CASE: omit core settings unless internal request settings = _.filter(settings, (setting) => { const isCore = setting.group === 'core'; return !isCore; }); + // CASE: omit secret settings unless internal request + settings = settings.map(settingsService.hideValueIfSecret); } return settings; @@ -70,6 +72,8 @@ module.exports = { })); } + setting = settingsService.hideValueIfSecret(setting); + return { [frame.options.key]: setting }; @@ -217,8 +221,8 @@ module.exports = { async query(frame) { const stripeConnectIntegrationToken = frame.data.settings.find(setting => setting.key === 'stripe_connect_integration_token'); - // The `stripe_connect_integration_token` "setting" is only used to set the `stripe_connect_*` settings. const settings = frame.data.settings.filter((setting) => { + // The `stripe_connect_integration_token` "setting" is only used to set the `stripe_connect_*` settings. return ![ 'stripe_connect_integration_token', 'stripe_connect_publishable_key', @@ -226,7 +230,9 @@ module.exports = { 'stripe_connect_livemode', 'stripe_connect_account_id', 'stripe_connect_display_name' - ].includes(setting.key); + ].includes(setting.key) + // Remove obfuscated settings + && !(setting.value === settingsService.obfuscatedSetting && settingsService.isSecretSetting(setting)); }); const getSetting = setting => settingsCache.get(setting.key, {resolve: false}); diff --git a/core/server/services/settings/index.js b/core/server/services/settings/index.js index e4ef0b6551..7f94bb4fcd 100644 --- a/core/server/services/settings/index.js +++ b/core/server/services/settings/index.js @@ -5,6 +5,22 @@ const models = require('../../models'); const SettingsCache = require('./cache'); +// The string returned when a setting is set as write-only +const obfuscatedSetting = '••••••••'; + +// The function used to decide whether a setting is write-only +function isSecretSetting(setting) { + return /secret/.test(setting.key); +} + +// The function that obfuscates a write-only setting +function hideValueIfSecret(setting) { + if (setting.value && isSecretSetting(setting)) { + return {...setting, value: obfuscatedSetting}; + } + return setting; +} + module.exports = { async init() { const settingsCollection = await models.Settings.populateDefaults(); @@ -44,5 +60,9 @@ module.exports = { value: currentRoutesHash }], {context: {internal: true}}); } - } + }, + + obfuscatedSetting, + isSecretSetting, + hideValueIfSecret }; diff --git a/package.json b/package.json index 877153f599..8686df27e7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghost", - "version": "3.42.4", + "version": "3.42.5", "description": "The professional publishing platform", "author": "Ghost Foundation", "homepage": "https://ghost.org",