Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions ghost/core/core/server/services/settings/settings-bread-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,30 @@ const sentry = require('../../../shared/sentry');

const EMAIL_KEYS = ['members_support_address'];
const PUBLIC_SITE_ACCESS_LOCKED_KEYS = ['is_private', 'password'];
const AUTOMATIONS_LABS_FLAG = 'automations';
const messages = {
problemFindingSetting: 'Problem finding setting: {key}',
accessCoreSettingFromExtReq: 'Attempted to access core setting from external request',
invalidEmail: 'Invalid email address',
publicSiteAccessLocked: 'Site visibility and access code cannot be changed.'
};

function parseLabsValue(value) {
if (!value) {
return {};
}

if (typeof value === 'string') {
try {
return JSON.parse(value);
} catch (err) {
return {};
}
}

return value;
}

class SettingsBREADService {
/**
*
Expand Down Expand Up @@ -244,13 +261,23 @@ class SettingsBREADService {
}
}

const shouldLogAutomationsEnabled = this._shouldLogAutomationsEnabled(filteredSettings);

// remove any email properties that are not allowed to be set without verification
const {filteredSettings: refilteredSettings, emailsToVerify} = await this.prepSettingsForEmailVerification(filteredSettings, getSetting);

const modelArray = await this.SettingsModel.edit(refilteredSettings, options).then((result) => {
return this._formatBrowse(_.keyBy(_.invokeMap(result, 'toJSON'), 'key'), options.context);
});

if (shouldLogAutomationsEnabled) {
logging.info({
event: {
name: 'automations.beta_flag_enabled'
}
}, 'Automations beta flag enabled');
}

return this.respondWithEmailVerification(modelArray, emailsToVerify);
}

Expand Down Expand Up @@ -333,6 +360,21 @@ class SettingsBREADService {
return Boolean(this.limitsService && this.limitsService.isDisabled('publicSiteAccess'));
}

_shouldLogAutomationsEnabled(settings) {
const labsSetting = settings.find(setting => setting.key === 'labs');
if (!labsSetting) {
return false;
}

const previousLabs = this.labs.getAll();
if (previousLabs[AUTOMATIONS_LABS_FLAG] === true) {
return false;
}

const nextLabs = parseLabsValue(labsSetting.value);
return nextLabs[AUTOMATIONS_LABS_FLAG] === true;
}

/**
* @private
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const SettingsBreadService = require('../../../../../core/server/services/settin
const urlUtils = require('../../../../../core/shared/url-utils.js');
const {mockManager} = require('../../../../utils/e2e-framework');
const emailAddress = require('../../../../../core/server/services/email-address');
const logging = require('@tryghost/logging');
describe('UNIT > Settings BREAD Service:', function () {
let emailMockReceiver;

Expand Down Expand Up @@ -133,6 +134,38 @@ describe('UNIT > Settings BREAD Service:', function () {
});

describe('edit', function () {
function createLabsService({automations = false} = {}) {
const labsSetting = {
key: 'labs',
value: JSON.stringify({automations}),
group: 'labs'
};

return new SettingsBreadService({
SettingsModel: {
async edit(changes) {
return changes.map(change => ({
toJSON: () => ({...labsSetting, ...change})
}));
}
},
settingsCache: {
get: sinon
.stub()
.withArgs('labs', {resolve: false})
.returns(labsSetting)
},
mail,
urlUtils,
singleUseTokenProvider: {},
labsService: {
getAll() {
return {automations};
}
}
});
}

it('cannot set stripe_connect_secret_key ', async function () {
const defaultSettingsManager = new SettingsBreadService({
SettingsModel: {
Expand Down Expand Up @@ -215,6 +248,46 @@ describe('UNIT > Settings BREAD Service:', function () {
emailMockReceiver.matchPlaintextSnapshot();
emailMockReceiver.matchMetadataSnapshot();
});

it('logs when automations labs flag is enabled', async function () {
const logStub = sinon.stub(logging, 'info');
const service = createLabsService({automations: false});

await service.edit([{
key: 'labs',
value: JSON.stringify({automations: true})
}], {}, null);

sinon.assert.calledOnceWithExactly(logStub, {
event: {
name: 'automations.beta_flag_enabled'
}
}, 'Automations beta flag enabled');
});

it('does not log when automations labs flag is already enabled', async function () {
const logStub = sinon.stub(logging, 'info');
const service = createLabsService({automations: true});

await service.edit([{
key: 'labs',
value: JSON.stringify({automations: true})
}], {}, null);

sinon.assert.notCalled(logStub);
});

it('does not log when automations labs flag is disabled', async function () {
const logStub = sinon.stub(logging, 'info');
const service = createLabsService({automations: true});

await service.edit([{
key: 'labs',
value: JSON.stringify({automations: false})
}], {}, null);

sinon.assert.notCalled(logStub);
});
});

describe('publicSiteAccess limit', function () {
Expand Down
Loading