Ghost/core/server/services/settings/index.js
Kevin Ansfield a485509a2f
🐛 Fixed GA labs flags not appearing enabled in settings API (#13681)
no issue

The way GA flags were introduced means that they stop existing in the `'labs'` setting in the db and are instead forced to always return `true` when checking the flag in the labs service. However, Admin which uses the flags fetches them via the `/settings/` API endpoint which was only returning the raw labs setting db value meaning GA flags appeared to be disabled unless the flag had previously been enabled and no settings save had occured.

- updated the settings bread service to replace the labs setting value with the JSON stringified output of `labs.getAll()` which is the ultimate source-of-truth for a feature being enabled/disabled
  - extracted `browse()` behaviour to an internal `_formatBrowse()` method so we can apply the same filtering/modification for output of `browse()` and `edit()`

Co-authored-by: Fabien O'Carroll <fabien@allou.is>
2021-10-22 19:59:13 +01:00

78 lines
2.4 KiB
JavaScript

/**
* Settings Lib
* A collection of utilities for handling settings including a cache
*/
const events = require('../../lib/common/events');
const models = require('../../models');
const labs = require('../../../shared/labs');
const SettingsCache = require('../../../shared/settings-cache');
const SettingsBREADService = require('./settings-bread-service');
const {obfuscatedSetting, isSecretSetting, hideValueIfSecret} = require('./settings-utils');
/**
* @returns {SettingsBREADService} instance of the PostsService
*/
const getSettingsBREADServiceInstance = () => {
return new SettingsBREADService({
SettingsModel: models.Settings,
settingsCache: SettingsCache,
labsService: labs
});
};
module.exports = {
/**
* Initialize the cache, used in boot and in testing
*/
async init() {
const settingsCollection = await models.Settings.populateDefaults();
SettingsCache.init(events, settingsCollection);
},
/**
* Shutdown the cache, used in force boot during testing
*/
shutdown() {
SettingsCache.reset(events);
},
/**
* Handles synchronization of routes.yaml hash loaded in the frontend with
* the value stored in the settings table.
* getRoutesHash is a function to allow keeping "frontend" decoupled from settings
*
* @param {function} getRoutesHash function fetching currently loaded routes file hash
*/
async syncRoutesHash(getRoutesHash) {
const currentRoutesHash = await getRoutesHash();
if (SettingsCache.get('routes_hash') !== currentRoutesHash) {
return await models.Settings.edit([{
key: 'routes_hash',
value: currentRoutesHash
}], {context: {internal: true}});
}
},
/**
* Handles email setting synchronization when email has been verified per instance
*
* @param {boolean} configValue current email verification value from local config
*/
async syncEmailSettings(configValue) {
const isEmailDisabled = SettingsCache.get('email_verification_required');
if (configValue === true && isEmailDisabled) {
return await models.Settings.edit([{
key: 'email_verification_required',
value: false
}], {context: {internal: true}});
}
},
obfuscatedSetting,
isSecretSetting,
hideValueIfSecret,
getSettingsBREADServiceInstance
};