mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-10 23:36:14 -05:00
Extended public settings to include portal settings (#14801)
refs https://github.com/TryGhost/Team/issues/1599 - adds `portal_*` settings to public settings endpoint - adds calculated `firstpromoter_account` setting for public settings endpoint - also adds Ghost `version` information
This commit is contained in:
parent
de118b0b04
commit
f4066067e4
10 changed files with 92 additions and 24 deletions
|
@ -1,5 +1,6 @@
|
||||||
const settingsCache = require('../../../shared/settings-cache');
|
const settingsCache = require('../../../shared/settings-cache');
|
||||||
const urlUtils = require('../../../shared/url-utils');
|
const urlUtils = require('../../../shared/url-utils');
|
||||||
|
const ghostVersion = require('@tryghost/version');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
docName: 'settings',
|
docName: 'settings',
|
||||||
|
@ -10,7 +11,8 @@ module.exports = {
|
||||||
// @TODO: decouple settings cache from API knowledge
|
// @TODO: decouple settings cache from API knowledge
|
||||||
// The controller fetches models (or cached models) and the API frame for the target API version formats the response.
|
// The controller fetches models (or cached models) and the API frame for the target API version formats the response.
|
||||||
return Object.assign({}, settingsCache.getPublic(), {
|
return Object.assign({}, settingsCache.getPublic(), {
|
||||||
url: urlUtils.urlFor('home', true)
|
url: urlUtils.urlFor('home', true),
|
||||||
|
version: ghostVersion.safe
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,6 +122,13 @@ module.exports = {
|
||||||
return this.isMembersEnabled() && this.getActiveStripeKeys() !== null;
|
return this.isMembersEnabled() && this.getActiveStripeKeys() !== null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getFirstpromoterId() {
|
||||||
|
if (!SettingsCache.get('firstpromoter')) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return SettingsCache.get('firstpromoter_id');
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -131,6 +138,7 @@ module.exports = {
|
||||||
fields.push(new CalculatedField({key: 'members_enabled', type: 'boolean', group: 'members', fn: this.isMembersEnabled.bind(this), dependents: ['members_signup_access']}));
|
fields.push(new CalculatedField({key: 'members_enabled', type: 'boolean', group: 'members', fn: this.isMembersEnabled.bind(this), dependents: ['members_signup_access']}));
|
||||||
fields.push(new CalculatedField({key: 'members_invite_only', type: 'boolean', group: 'members', fn: this.isMembersInviteOnly.bind(this), dependents: ['members_signup_access']}));
|
fields.push(new CalculatedField({key: 'members_invite_only', type: 'boolean', group: 'members', fn: this.isMembersInviteOnly.bind(this), dependents: ['members_signup_access']}));
|
||||||
fields.push(new CalculatedField({key: 'paid_members_enabled', type: 'boolean', group: 'members', fn: this.isStripeConnected.bind(this), dependents: ['members_signup_access', 'stripe_secret_key', 'stripe_publishable_key', 'stripe_connect_secret_key', 'stripe_connect_publishable_key']}));
|
fields.push(new CalculatedField({key: 'paid_members_enabled', type: 'boolean', group: 'members', fn: this.isStripeConnected.bind(this), dependents: ['members_signup_access', 'stripe_secret_key', 'stripe_publishable_key', 'stripe_connect_secret_key', 'stripe_connect_publishable_key']}));
|
||||||
|
fields.push(new CalculatedField({key: 'firstpromoter_account', type: 'string', group: 'firstpromoter', fn: this.getFirstpromoterId.bind(this), dependents: ['firstpromoter', 'firstpromoter_id']}));
|
||||||
|
|
||||||
return fields;
|
return fields;
|
||||||
},
|
},
|
||||||
|
|
|
@ -29,5 +29,12 @@ module.exports = {
|
||||||
members_support_address: 'members_support_address',
|
members_support_address: 'members_support_address',
|
||||||
members_enabled: 'members_enabled',
|
members_enabled: 'members_enabled',
|
||||||
members_invite_only: 'members_invite_only',
|
members_invite_only: 'members_invite_only',
|
||||||
paid_members_enabled: 'paid_members_enabled'
|
paid_members_enabled: 'paid_members_enabled',
|
||||||
|
firstpromoter_account: 'firstpromoter_account',
|
||||||
|
portal_button_style: 'portal_button_style',
|
||||||
|
portal_button_signup_text: 'portal_button_signup_text',
|
||||||
|
portal_button_icon: 'portal_button_icon',
|
||||||
|
portal_plans: 'portal_plans',
|
||||||
|
portal_name: 'portal_name',
|
||||||
|
portal_button: 'portal_button'
|
||||||
};
|
};
|
||||||
|
|
|
@ -1082,6 +1082,15 @@ Object {
|
||||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||||
"value": true,
|
"value": true,
|
||||||
},
|
},
|
||||||
|
Object {
|
||||||
|
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||||
|
"group": "firstpromoter",
|
||||||
|
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||||
|
"key": "firstpromoter_account",
|
||||||
|
"type": "string",
|
||||||
|
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||||
|
"value": null,
|
||||||
|
},
|
||||||
Object {
|
Object {
|
||||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||||
"flags": null,
|
"flags": null,
|
||||||
|
@ -1112,7 +1121,7 @@ exports[`Settings API Can request all settings 2: [headers] 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||||
"content-length": "18289",
|
"content-length": "18486",
|
||||||
"content-type": "application/json; charset=utf-8",
|
"content-type": "application/json; charset=utf-8",
|
||||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||||
"vary": "Origin, Accept-Encoding",
|
"vary": "Origin, Accept-Encoding",
|
||||||
|
|
|
@ -2,7 +2,7 @@ const assert = require('assert');
|
||||||
const {agentProvider, fixtureManager, mockManager, matchers} = require('../../utils/e2e-framework');
|
const {agentProvider, fixtureManager, mockManager, matchers} = require('../../utils/e2e-framework');
|
||||||
const {stringMatching, anyEtag, anyObjectId, anyISODateTime} = matchers;
|
const {stringMatching, anyEtag, anyObjectId, anyISODateTime} = matchers;
|
||||||
|
|
||||||
const CURRENT_SETTINGS_COUNT = 86;
|
const CURRENT_SETTINGS_COUNT = 87;
|
||||||
|
|
||||||
const settingsMatcher = {
|
const settingsMatcher = {
|
||||||
id: anyObjectId,
|
id: anyObjectId,
|
||||||
|
|
|
@ -10,6 +10,7 @@ Object {
|
||||||
"cover_image": "https://static.ghost.org/v4.0.0/images/publication-cover.jpg",
|
"cover_image": "https://static.ghost.org/v4.0.0/images/publication-cover.jpg",
|
||||||
"description": "Thoughts, stories and ideas",
|
"description": "Thoughts, stories and ideas",
|
||||||
"facebook": "ghost",
|
"facebook": "ghost",
|
||||||
|
"firstpromoter_account": null,
|
||||||
"icon": null,
|
"icon": null,
|
||||||
"lang": "en",
|
"lang": "en",
|
||||||
"locale": "en",
|
"locale": "en",
|
||||||
|
@ -45,6 +46,14 @@ Object {
|
||||||
"og_image": null,
|
"og_image": null,
|
||||||
"og_title": null,
|
"og_title": null,
|
||||||
"paid_members_enabled": true,
|
"paid_members_enabled": true,
|
||||||
|
"portal_button": true,
|
||||||
|
"portal_button_icon": null,
|
||||||
|
"portal_button_signup_text": "Subscribe",
|
||||||
|
"portal_button_style": "icon-and-text",
|
||||||
|
"portal_name": true,
|
||||||
|
"portal_plans": Array [
|
||||||
|
"free",
|
||||||
|
],
|
||||||
"secondary_navigation": Array [
|
"secondary_navigation": Array [
|
||||||
Object {
|
Object {
|
||||||
"label": "Data & privacy",
|
"label": "Data & privacy",
|
||||||
|
@ -66,6 +75,7 @@ Object {
|
||||||
"twitter_image": null,
|
"twitter_image": null,
|
||||||
"twitter_title": null,
|
"twitter_title": null,
|
||||||
"url": "http://127.0.0.1:2369/",
|
"url": "http://127.0.0.1:2369/",
|
||||||
|
"version": Any<String>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -86,7 +96,7 @@ exports[`Settings Content API Can request settings 2: [headers] 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"access-control-allow-origin": "*",
|
"access-control-allow-origin": "*",
|
||||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||||
"content-length": "1021",
|
"content-length": "1235",
|
||||||
"content-type": "application/json; charset=utf-8",
|
"content-type": "application/json; charset=utf-8",
|
||||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||||
"vary": "Accept-Encoding",
|
"vary": "Accept-Encoding",
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
const {agentProvider, fixtureManager, matchers} = require('../../utils/e2e-framework');
|
const {agentProvider, fixtureManager, matchers} = require('../../utils/e2e-framework');
|
||||||
const {anyEtag} = matchers;
|
const {anyEtag} = matchers;
|
||||||
|
|
||||||
|
const settingsMatcher = {
|
||||||
|
version: matchers.anyString
|
||||||
|
};
|
||||||
|
|
||||||
describe('Settings Content API', function () {
|
describe('Settings Content API', function () {
|
||||||
let agent;
|
let agent;
|
||||||
|
|
||||||
|
@ -16,6 +20,8 @@ describe('Settings Content API', function () {
|
||||||
.matchHeaderSnapshot({
|
.matchHeaderSnapshot({
|
||||||
etag: anyEtag
|
etag: anyEtag
|
||||||
})
|
})
|
||||||
.matchBodySnapshot();
|
.matchBodySnapshot({
|
||||||
|
settings: settingsMatcher
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -488,6 +488,7 @@ Object {
|
||||||
"cover_image": "https://static.ghost.org/v4.0.0/images/publication-cover.jpg",
|
"cover_image": "https://static.ghost.org/v4.0.0/images/publication-cover.jpg",
|
||||||
"description": "Thoughts, stories and ideas",
|
"description": "Thoughts, stories and ideas",
|
||||||
"facebook": "ghost",
|
"facebook": "ghost",
|
||||||
|
"firstpromoter_account": null,
|
||||||
"icon": null,
|
"icon": null,
|
||||||
"lang": "en",
|
"lang": "en",
|
||||||
"locale": "en",
|
"locale": "en",
|
||||||
|
@ -523,6 +524,14 @@ Object {
|
||||||
"og_image": null,
|
"og_image": null,
|
||||||
"og_title": null,
|
"og_title": null,
|
||||||
"paid_members_enabled": true,
|
"paid_members_enabled": true,
|
||||||
|
"portal_button": true,
|
||||||
|
"portal_button_icon": null,
|
||||||
|
"portal_button_signup_text": "Subscribe",
|
||||||
|
"portal_button_style": "icon-and-text",
|
||||||
|
"portal_name": true,
|
||||||
|
"portal_plans": Array [
|
||||||
|
"free",
|
||||||
|
],
|
||||||
"secondary_navigation": Array [
|
"secondary_navigation": Array [
|
||||||
Object {
|
Object {
|
||||||
"label": "Data & privacy",
|
"label": "Data & privacy",
|
||||||
|
@ -544,6 +553,7 @@ Object {
|
||||||
"twitter_image": null,
|
"twitter_image": null,
|
||||||
"twitter_title": null,
|
"twitter_title": null,
|
||||||
"url": "http://127.0.0.1:2369/",
|
"url": "http://127.0.0.1:2369/",
|
||||||
|
"version": Any<String>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -552,10 +562,10 @@ exports[`API Versioning Content API responds with current content version header
|
||||||
Object {
|
Object {
|
||||||
"access-control-allow-origin": "*",
|
"access-control-allow-origin": "*",
|
||||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||||
"content-length": "1021",
|
"content-length": "1235",
|
||||||
"content-type": "application/json; charset=utf-8",
|
"content-type": "application/json; charset=utf-8",
|
||||||
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
|
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
|
||||||
"etag": "W/\\"3fd-PXBX1gYn1ftAeK+GoVbEnAsmVAE\\"",
|
"etag": "W/\\"4d3-mq2QrkgGnMZ8/BMmziwONEMrvLM\\"",
|
||||||
"vary": "Accept-Encoding",
|
"vary": "Accept-Encoding",
|
||||||
"x-powered-by": "Express",
|
"x-powered-by": "Express",
|
||||||
}
|
}
|
||||||
|
@ -571,6 +581,7 @@ Object {
|
||||||
"cover_image": "https://static.ghost.org/v4.0.0/images/publication-cover.jpg",
|
"cover_image": "https://static.ghost.org/v4.0.0/images/publication-cover.jpg",
|
||||||
"description": "Thoughts, stories and ideas",
|
"description": "Thoughts, stories and ideas",
|
||||||
"facebook": "ghost",
|
"facebook": "ghost",
|
||||||
|
"firstpromoter_account": null,
|
||||||
"icon": null,
|
"icon": null,
|
||||||
"lang": "en",
|
"lang": "en",
|
||||||
"locale": "en",
|
"locale": "en",
|
||||||
|
@ -606,6 +617,14 @@ Object {
|
||||||
"og_image": null,
|
"og_image": null,
|
||||||
"og_title": null,
|
"og_title": null,
|
||||||
"paid_members_enabled": true,
|
"paid_members_enabled": true,
|
||||||
|
"portal_button": true,
|
||||||
|
"portal_button_icon": null,
|
||||||
|
"portal_button_signup_text": "Subscribe",
|
||||||
|
"portal_button_style": "icon-and-text",
|
||||||
|
"portal_name": true,
|
||||||
|
"portal_plans": Array [
|
||||||
|
"free",
|
||||||
|
],
|
||||||
"secondary_navigation": Array [
|
"secondary_navigation": Array [
|
||||||
Object {
|
Object {
|
||||||
"label": "Data & privacy",
|
"label": "Data & privacy",
|
||||||
|
@ -627,6 +646,7 @@ Object {
|
||||||
"twitter_image": null,
|
"twitter_image": null,
|
||||||
"twitter_title": null,
|
"twitter_title": null,
|
||||||
"url": "http://127.0.0.1:2369/",
|
"url": "http://127.0.0.1:2369/",
|
||||||
|
"version": Any<String>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -635,9 +655,9 @@ exports[`API Versioning Content API responds with no content version header when
|
||||||
Object {
|
Object {
|
||||||
"access-control-allow-origin": "*",
|
"access-control-allow-origin": "*",
|
||||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||||
"content-length": "1021",
|
"content-length": "1235",
|
||||||
"content-type": "application/json; charset=utf-8",
|
"content-type": "application/json; charset=utf-8",
|
||||||
"etag": "W/\\"3fd-PXBX1gYn1ftAeK+GoVbEnAsmVAE\\"",
|
"etag": "W/\\"4d3-mq2QrkgGnMZ8/BMmziwONEMrvLM\\"",
|
||||||
"vary": "Accept-Encoding",
|
"vary": "Accept-Encoding",
|
||||||
"x-powered-by": "Express",
|
"x-powered-by": "Express",
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
const {agentProvider, fixtureManager, matchers, mockManager} = require('../../utils/e2e-framework');
|
const {agentProvider, fixtureManager, matchers, mockManager} = require('../../utils/e2e-framework');
|
||||||
const {anyErrorId, stringMatching, anyObjectId, anyLocationFor, anyISODateTime, anyEtag} = matchers;
|
const {anyErrorId, stringMatching, anyObjectId, anyLocationFor, anyISODateTime, anyEtag, anyString} = matchers;
|
||||||
|
|
||||||
|
const settingsMatcher = {
|
||||||
|
settings: {
|
||||||
|
version: anyString
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
describe('API Versioning', function () {
|
describe('API Versioning', function () {
|
||||||
describe('Admin API', function () {
|
describe('Admin API', function () {
|
||||||
|
@ -260,7 +266,7 @@ describe('API Versioning', function () {
|
||||||
await agentContentAPI.get('settings/')
|
await agentContentAPI.get('settings/')
|
||||||
.expectStatus(200)
|
.expectStatus(200)
|
||||||
.matchHeaderSnapshot()
|
.matchHeaderSnapshot()
|
||||||
.matchBodySnapshot();
|
.matchBodySnapshot(settingsMatcher);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('responds with current content version header when requested version is BEHIND current version and CAN respond', async function () {
|
it('responds with current content version header when requested version is BEHIND current version and CAN respond', async function () {
|
||||||
|
@ -270,7 +276,7 @@ describe('API Versioning', function () {
|
||||||
.matchHeaderSnapshot({
|
.matchHeaderSnapshot({
|
||||||
'content-version': stringMatching(/v\d+\.\d+/)
|
'content-version': stringMatching(/v\d+\.\d+/)
|
||||||
})
|
})
|
||||||
.matchBodySnapshot();
|
.matchBodySnapshot(settingsMatcher);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Does an internal rewrite with accept version set when version is included in the URL', async function () {
|
it('Does an internal rewrite with accept version set when version is included in the URL', async function () {
|
||||||
|
|
|
@ -264,6 +264,16 @@ const defaultSettingsKeyTypes = [
|
||||||
type: 'string',
|
type: 'string',
|
||||||
group: 'portal'
|
group: 'portal'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'firstpromoter',
|
||||||
|
type: 'boolean',
|
||||||
|
group: 'firstpromoter'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'firstpromoter_id',
|
||||||
|
type: 'string',
|
||||||
|
group: 'firstpromoter'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'portal_button_icon',
|
key: 'portal_button_icon',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
@ -384,16 +394,6 @@ const defaultSettingsKeyTypes = [
|
||||||
type: 'string',
|
type: 'string',
|
||||||
group: 'newsletter'
|
group: 'newsletter'
|
||||||
},
|
},
|
||||||
{
|
|
||||||
key: 'firstpromoter',
|
|
||||||
type: 'boolean',
|
|
||||||
group: 'firstpromoter'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'firstpromoter_id',
|
|
||||||
type: 'string',
|
|
||||||
group: 'firstpromoter'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: 'oauth_client_id',
|
key: 'oauth_client_id',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
@ -426,7 +426,7 @@ const defaultSettingsKeyTypes = [
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const calculatedSettingsTypes = ['members_enabled', 'members_invite_only', 'paid_members_enabled'];
|
const calculatedSettingsTypes = ['members_enabled', 'members_invite_only', 'paid_members_enabled', 'firstpromoter_account'];
|
||||||
|
|
||||||
describe('Settings API (canary)', function () {
|
describe('Settings API (canary)', function () {
|
||||||
let request;
|
let request;
|
||||||
|
|
Loading…
Add table
Reference in a new issue