mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-09-23 02:49:03 +03:00
Enabled Members for all sites (#12582)
no-issue This removes all references to the members labs setting, any code that was run conditionally behind this flag now runs unconditionally. * Removed usage of Members labs flag * Removed tests for Members disabled * Added dynamic keypair generation for when setting is missing
This commit is contained in:
parent
26ee648397
commit
73f6fd8c51
@ -2,7 +2,7 @@
|
|||||||
// Usage: `{{ghost_head}}`
|
// Usage: `{{ghost_head}}`
|
||||||
//
|
//
|
||||||
// Outputs scripts and other assets at the top of a Ghost theme
|
// Outputs scripts and other assets at the top of a Ghost theme
|
||||||
const {metaData, escapeExpression, SafeString, logging, settingsCache, config, blogIcon, labs, urlUtils} = require('../services/proxy');
|
const {metaData, escapeExpression, SafeString, logging, settingsCache, config, blogIcon, urlUtils} = require('../services/proxy');
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const debug = require('ghost-ignition').debug('ghost_head');
|
const debug = require('ghost-ignition').debug('ghost_head');
|
||||||
const templateStyles = require('./tpl/styles');
|
const templateStyles = require('./tpl/styles');
|
||||||
@ -167,7 +167,7 @@ module.exports = function ghost_head(options) { // eslint-disable-line camelcase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_.includes(context, 'amp') && labs.isSet('members')) {
|
if (!_.includes(context, 'amp')) {
|
||||||
head.push(getMembersHelper());
|
head.push(getMembersHelper());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,11 @@
|
|||||||
const debug = require('ghost-ignition').debug('services:routing:controllers:unsubscribe');
|
const debug = require('ghost-ignition').debug('services:routing:controllers:unsubscribe');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const megaService = require('../../../../server/services/mega');
|
const megaService = require('../../../../server/services/mega');
|
||||||
const labsService = require('../../../../server/services/labs');
|
|
||||||
const helpers = require('../../../services/routing/helpers');
|
const helpers = require('../../../services/routing/helpers');
|
||||||
|
|
||||||
module.exports = async function unsubscribeController(req, res, next) {
|
module.exports = async function unsubscribeController(req, res) {
|
||||||
debug('unsubscribeController');
|
debug('unsubscribeController');
|
||||||
|
|
||||||
if (!labsService.isSet('members')) {
|
|
||||||
return next();
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = {};
|
let data = {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
const membersService = require('../../../../../../services/members');
|
const membersService = require('../../../../../../services/members');
|
||||||
const labs = require('../../../../../../services/labs');
|
|
||||||
|
|
||||||
// @TODO: reconsider the location of this - it's part of members and adds a property to the API
|
// @TODO: reconsider the location of this - it's part of members and adds a property to the API
|
||||||
const forPost = (attrs, frame) => {
|
const forPost = (attrs, frame) => {
|
||||||
@ -8,21 +7,18 @@ const forPost = (attrs, frame) => {
|
|||||||
attrs.access = true;
|
attrs.access = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle members being enabled
|
const memberHasAccess = membersService.contentGating.checkPostAccess(attrs, frame.original.context.member);
|
||||||
if (labs.isSet('members')) {
|
|
||||||
const memberHasAccess = membersService.contentGating.checkPostAccess(attrs, frame.original.context.member);
|
|
||||||
|
|
||||||
if (!memberHasAccess) {
|
if (!memberHasAccess) {
|
||||||
['plaintext', 'html'].forEach((field) => {
|
['plaintext', 'html'].forEach((field) => {
|
||||||
if (attrs[field] !== undefined) {
|
if (attrs[field] !== undefined) {
|
||||||
attrs[field] = '';
|
attrs[field] = '';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Object.prototype.hasOwnProperty.call(frame.options, 'columns') || (frame.options.columns.includes('access'))) {
|
if (!Object.prototype.hasOwnProperty.call(frame.options, 'columns') || (frame.options.columns.includes('access'))) {
|
||||||
attrs.access = memberHasAccess;
|
attrs.access = memberHasAccess;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return attrs;
|
return attrs;
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
const membersService = require('../../../../../../services/members');
|
const membersService = require('../../../../../../services/members');
|
||||||
const labs = require('../../../../../../services/labs');
|
|
||||||
|
|
||||||
const forPost = (attrs, frame) => {
|
const forPost = (attrs, frame) => {
|
||||||
if (labs.isSet('members')) {
|
const memberHasAccess = membersService.contentGating.checkPostAccess(attrs, frame.original.context.member);
|
||||||
const memberHasAccess = membersService.contentGating.checkPostAccess(attrs, frame.original.context.member);
|
|
||||||
|
|
||||||
if (!memberHasAccess) {
|
if (!memberHasAccess) {
|
||||||
['plaintext', 'html'].forEach((field) => {
|
['plaintext', 'html'].forEach((field) => {
|
||||||
if (attrs[field] !== undefined) {
|
if (attrs[field] !== undefined) {
|
||||||
attrs[field] = '';
|
attrs[field] = '';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return attrs;
|
return attrs;
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
const membersService = require('../../../../../../services/members');
|
const membersService = require('../../../../../../services/members');
|
||||||
const labs = require('../../../../../../services/labs');
|
|
||||||
|
|
||||||
// @TODO: reconsider the location of this - it's part of members and adds a property to the API
|
// @TODO: reconsider the location of this - it's part of members and adds a property to the API
|
||||||
const forPost = (attrs, frame) => {
|
const forPost = (attrs, frame) => {
|
||||||
@ -8,21 +7,18 @@ const forPost = (attrs, frame) => {
|
|||||||
attrs.access = true;
|
attrs.access = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle members being enabled
|
const memberHasAccess = membersService.contentGating.checkPostAccess(attrs, frame.original.context.member);
|
||||||
if (labs.isSet('members')) {
|
|
||||||
const memberHasAccess = membersService.contentGating.checkPostAccess(attrs, frame.original.context.member);
|
|
||||||
|
|
||||||
if (!memberHasAccess) {
|
if (!memberHasAccess) {
|
||||||
['plaintext', 'html'].forEach((field) => {
|
['plaintext', 'html'].forEach((field) => {
|
||||||
if (attrs[field] !== undefined) {
|
if (attrs[field] !== undefined) {
|
||||||
attrs[field] = '';
|
attrs[field] = '';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Object.prototype.hasOwnProperty.call(frame.options, 'columns') || (frame.options.columns.includes('access'))) {
|
if (!Object.prototype.hasOwnProperty.call(frame.options, 'columns') || (frame.options.columns.includes('access'))) {
|
||||||
attrs.access = memberHasAccess;
|
attrs.access = memberHasAccess;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return attrs;
|
return attrs;
|
||||||
|
@ -45,7 +45,7 @@ Post = ghostBookshelf.Model.extend({
|
|||||||
defaults: function defaults() {
|
defaults: function defaults() {
|
||||||
let visibility = 'public';
|
let visibility = 'public';
|
||||||
|
|
||||||
if (settingsCache.get('labs') && (settingsCache.get('labs').members === true) && settingsCache.get('default_content_visibility')) {
|
if (settingsCache.get('default_content_visibility')) {
|
||||||
visibility = settingsCache.get('default_content_visibility');
|
visibility = settingsCache.get('default_content_visibility');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ const ghostBookshelf = require('./base');
|
|||||||
const {i18n} = require('../lib/common');
|
const {i18n} = require('../lib/common');
|
||||||
const errors = require('@tryghost/errors');
|
const errors = require('@tryghost/errors');
|
||||||
const validation = require('../data/validation');
|
const validation = require('../data/validation');
|
||||||
const settingsCache = require('../services/settings/cache');
|
|
||||||
const internalContext = {context: {internal: true}};
|
const internalContext = {context: {internal: true}};
|
||||||
let Settings;
|
let Settings;
|
||||||
let defaultSettings;
|
let defaultSettings;
|
||||||
@ -298,25 +297,6 @@ Settings = ghostBookshelf.Model.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
permissible: function permissible(modelId, action, context, unsafeAttrs, loadedPermissions, hasUserPermission, hasApiKeyPermission) {
|
permissible: function permissible(modelId, action, context, unsafeAttrs, loadedPermissions, hasUserPermission, hasApiKeyPermission) {
|
||||||
let isEdit = (action === 'edit');
|
|
||||||
let isOwner;
|
|
||||||
|
|
||||||
function isChangingMembers() {
|
|
||||||
if (unsafeAttrs && unsafeAttrs.key === 'labs') {
|
|
||||||
let editedValue = JSON.parse(unsafeAttrs.value);
|
|
||||||
if (editedValue.members !== undefined) {
|
|
||||||
return editedValue.members !== settingsCache.get('labs').members;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isOwner = loadedPermissions.user && _.some(loadedPermissions.user.roles, {name: 'Owner'});
|
|
||||||
|
|
||||||
if (isEdit && isChangingMembers()) {
|
|
||||||
// Only allow owner to toggle members flag
|
|
||||||
hasUserPermission = isOwner;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasUserPermission && hasApiKeyPermission) {
|
if (hasUserPermission && hasApiKeyPermission) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
const labs = require('../labs');
|
|
||||||
const errors = require('@tryghost/errors');
|
const errors = require('@tryghost/errors');
|
||||||
const {i18n} = require('../../lib/common');
|
const {i18n} = require('../../lib/common');
|
||||||
|
|
||||||
@ -9,7 +8,7 @@ const authorize = {
|
|||||||
if (hasApiKey) {
|
if (hasApiKey) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
if (labs.isSet('members') && hasMember) {
|
if (hasMember) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
return next(new errors.NoPermissionError({
|
return next(new errors.NoPermissionError({
|
||||||
|
@ -1,18 +1,11 @@
|
|||||||
const jwt = require('express-jwt');
|
const jwt = require('express-jwt');
|
||||||
const membersService = require('../../members');
|
const membersService = require('../../members');
|
||||||
const labs = require('../../labs');
|
|
||||||
const config = require('../../../../shared/config');
|
const config = require('../../../../shared/config');
|
||||||
|
|
||||||
let UNO_MEMBERINO;
|
let UNO_MEMBERINO;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
get authenticateMembersToken() {
|
get authenticateMembersToken() {
|
||||||
if (!labs.isSet('members')) {
|
|
||||||
return function (req, res, next) {
|
|
||||||
return next();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!UNO_MEMBERINO) {
|
if (!UNO_MEMBERINO) {
|
||||||
const url = require('url');
|
const url = require('url');
|
||||||
const {protocol, host} = url.parse(config.get('url'));
|
const {protocol, host} = url.parse(config.get('url'));
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
const {URL} = require('url');
|
const {URL} = require('url');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
|
const createKeypair = require('keypair');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const COMPLIMENTARY_PLAN = {
|
const COMPLIMENTARY_PLAN = {
|
||||||
@ -230,10 +231,20 @@ class MembersConfigProvider {
|
|||||||
this._urlUtils.urlFor('admin', true)
|
this._urlUtils.urlFor('admin', true)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let privateKey = this._settingsCache.get('members_private_key');
|
||||||
|
let publicKey = this._settingsCache.get('members_public_key');
|
||||||
|
|
||||||
|
if (!privateKey || !publicKey) {
|
||||||
|
this._logging.warn('Could not find members_private_key, using dynamically generated keypair');
|
||||||
|
const keypair = createKeypair({bits: 1024});
|
||||||
|
privateKey = keypair.private;
|
||||||
|
publicKey = keypair.public;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
issuer: membersApiUrl,
|
issuer: membersApiUrl,
|
||||||
publicKey: this._settingsCache.get('members_public_key'),
|
publicKey,
|
||||||
privateKey: this._settingsCache.get('members_private_key')
|
privateKey
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const logging = require('../../../shared/logging');
|
const logging = require('../../../shared/logging');
|
||||||
const labsService = require('../labs');
|
|
||||||
const membersService = require('./index');
|
const membersService = require('./index');
|
||||||
const urlUtils = require('../../../shared/url-utils');
|
const urlUtils = require('../../../shared/url-utils');
|
||||||
const ghostVersion = require('../../lib/ghost-version');
|
const ghostVersion = require('../../lib/ghost-version');
|
||||||
@ -10,10 +9,6 @@ const {formattedMemberResponse} = require('./utils');
|
|||||||
// @TODO: This piece of middleware actually belongs to the frontend, not to the member app
|
// @TODO: This piece of middleware actually belongs to the frontend, not to the member app
|
||||||
// Need to figure a way to separate these things (e.g. frontend actually talks to members API)
|
// Need to figure a way to separate these things (e.g. frontend actually talks to members API)
|
||||||
const loadMemberSession = async function (req, res, next) {
|
const loadMemberSession = async function (req, res, next) {
|
||||||
if (!labsService.isSet('members')) {
|
|
||||||
req.member = null;
|
|
||||||
return next();
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
const member = await membersService.ssr.getMemberDataFromSession(req, res);
|
const member = await membersService.ssr.getMemberDataFromSession(req, res);
|
||||||
Object.assign(req, {member});
|
Object.assign(req, {member});
|
||||||
|
@ -88,31 +88,30 @@ module.exports = function apiRoutes() {
|
|||||||
router.del('/tags/:id', mw.authAdminApi, http(apiCanary.tags.destroy));
|
router.del('/tags/:id', mw.authAdminApi, http(apiCanary.tags.destroy));
|
||||||
|
|
||||||
// ## Members
|
// ## Members
|
||||||
router.get('/members', shared.middlewares.labs.members, mw.authAdminApi, http(apiCanary.members.browse));
|
router.get('/members', mw.authAdminApi, http(apiCanary.members.browse));
|
||||||
router.post('/members', shared.middlewares.labs.members, mw.authAdminApi, http(apiCanary.members.add));
|
router.post('/members', mw.authAdminApi, http(apiCanary.members.add));
|
||||||
|
|
||||||
router.get('/members/stats', shared.middlewares.labs.members, mw.authAdminApi, http(apiCanary.members.stats));
|
router.get('/members/stats', mw.authAdminApi, http(apiCanary.members.stats));
|
||||||
|
|
||||||
router.get('/members/upload', shared.middlewares.labs.members, mw.authAdminApi, http(apiCanary.members.exportCSV));
|
router.get('/members/upload', mw.authAdminApi, http(apiCanary.members.exportCSV));
|
||||||
router.post('/members/upload',
|
router.post('/members/upload',
|
||||||
shared.middlewares.labs.members,
|
|
||||||
mw.authAdminApi,
|
mw.authAdminApi,
|
||||||
apiMw.upload.single('membersfile'),
|
apiMw.upload.single('membersfile'),
|
||||||
apiMw.upload.validation({type: 'members'}),
|
apiMw.upload.validation({type: 'members'}),
|
||||||
http(apiCanary.members.importCSV)
|
http(apiCanary.members.importCSV)
|
||||||
);
|
);
|
||||||
|
|
||||||
router.get('/members/hasActiveStripeSubscriptions', shared.middlewares.labs.members, mw.authAdminApi, http(apiCanary.members.hasActiveStripeSubscriptions));
|
router.get('/members/hasActiveStripeSubscriptions', mw.authAdminApi, http(apiCanary.members.hasActiveStripeSubscriptions));
|
||||||
|
|
||||||
router.get('/members/stripe_connect', shared.middlewares.labs.members, mw.authAdminApi, http(apiCanary.membersStripeConnect.auth));
|
router.get('/members/stripe_connect', mw.authAdminApi, http(apiCanary.membersStripeConnect.auth));
|
||||||
|
|
||||||
router.get('/members/:id', shared.middlewares.labs.members, mw.authAdminApi, http(apiCanary.members.read));
|
router.get('/members/:id', mw.authAdminApi, http(apiCanary.members.read));
|
||||||
router.put('/members/:id', shared.middlewares.labs.members, mw.authAdminApi, http(apiCanary.members.edit));
|
router.put('/members/:id', mw.authAdminApi, http(apiCanary.members.edit));
|
||||||
router.del('/members/:id', shared.middlewares.labs.members, mw.authAdminApi, http(apiCanary.members.destroy));
|
router.del('/members/:id', mw.authAdminApi, http(apiCanary.members.destroy));
|
||||||
|
|
||||||
router.put('/members/:id/subscriptions/:subscription_id', shared.middlewares.labs.members, mw.authAdminApi, http(apiCanary.members.editSubscription));
|
router.put('/members/:id/subscriptions/:subscription_id', mw.authAdminApi, http(apiCanary.members.editSubscription));
|
||||||
|
|
||||||
router.get('/members/:id/signin_urls', shared.middlewares.labs.members, mw.authAdminApi, http(apiCanary.memberSigninUrls.read));
|
router.get('/members/:id/signin_urls', mw.authAdminApi, http(apiCanary.memberSigninUrls.read));
|
||||||
|
|
||||||
// ## Labels
|
// ## Labels
|
||||||
router.get('/labels', mw.authAdminApi, http(apiCanary.labels.browse));
|
router.get('/labels', mw.authAdminApi, http(apiCanary.labels.browse));
|
||||||
|
@ -88,31 +88,30 @@ module.exports = function apiRoutes() {
|
|||||||
router.del('/tags/:id', mw.authAdminApi, http(api.tags.destroy));
|
router.del('/tags/:id', mw.authAdminApi, http(api.tags.destroy));
|
||||||
|
|
||||||
// ## Members
|
// ## Members
|
||||||
router.get('/members', shared.middlewares.labs.members, mw.authAdminApi, http(api.members.browse));
|
router.get('/members', mw.authAdminApi, http(api.members.browse));
|
||||||
router.post('/members', shared.middlewares.labs.members, mw.authAdminApi, http(api.members.add));
|
router.post('/members', mw.authAdminApi, http(api.members.add));
|
||||||
|
|
||||||
router.get('/members/stats', shared.middlewares.labs.members, mw.authAdminApi, http(api.members.stats));
|
router.get('/members/stats', mw.authAdminApi, http(api.members.stats));
|
||||||
|
|
||||||
router.get('/members/upload', shared.middlewares.labs.members, mw.authAdminApi, http(api.members.exportCSV));
|
router.get('/members/upload', mw.authAdminApi, http(api.members.exportCSV));
|
||||||
router.post('/members/upload',
|
router.post('/members/upload',
|
||||||
shared.middlewares.labs.members,
|
|
||||||
mw.authAdminApi,
|
mw.authAdminApi,
|
||||||
apiMw.upload.single('membersfile'),
|
apiMw.upload.single('membersfile'),
|
||||||
apiMw.upload.validation({type: 'members'}),
|
apiMw.upload.validation({type: 'members'}),
|
||||||
http(api.members.importCSV)
|
http(api.members.importCSV)
|
||||||
);
|
);
|
||||||
|
|
||||||
router.get('/members/hasActiveStripeSubscriptions', shared.middlewares.labs.members, mw.authAdminApi, http(api.members.hasActiveStripeSubscriptions));
|
router.get('/members/hasActiveStripeSubscriptions', mw.authAdminApi, http(api.members.hasActiveStripeSubscriptions));
|
||||||
|
|
||||||
router.get('/members/stripe_connect', shared.middlewares.labs.members, mw.authAdminApi, http(api.membersStripeConnect.auth));
|
router.get('/members/stripe_connect', mw.authAdminApi, http(api.membersStripeConnect.auth));
|
||||||
|
|
||||||
router.get('/members/:id', shared.middlewares.labs.members, mw.authAdminApi, http(api.members.read));
|
router.get('/members/:id', mw.authAdminApi, http(api.members.read));
|
||||||
router.put('/members/:id', shared.middlewares.labs.members, mw.authAdminApi, http(api.members.edit));
|
router.put('/members/:id', mw.authAdminApi, http(api.members.edit));
|
||||||
router.del('/members/:id', shared.middlewares.labs.members, mw.authAdminApi, http(api.members.destroy));
|
router.del('/members/:id', mw.authAdminApi, http(api.members.destroy));
|
||||||
|
|
||||||
router.put('/members/:id/subscriptions/:subscription_id', shared.middlewares.labs.members, mw.authAdminApi, http(api.members.editSubscription));
|
router.put('/members/:id/subscriptions/:subscription_id', mw.authAdminApi, http(api.members.editSubscription));
|
||||||
|
|
||||||
router.get('/members/:id/signin_urls', shared.middlewares.labs.members, mw.authAdminApi, http(api.memberSigninUrls.read));
|
router.get('/members/:id/signin_urls', mw.authAdminApi, http(api.memberSigninUrls.read));
|
||||||
|
|
||||||
// ## Labels
|
// ## Labels
|
||||||
router.get('/labels', mw.authAdminApi, http(api.labels.browse));
|
router.get('/labels', mw.authAdminApi, http(api.labels.browse));
|
||||||
|
@ -15,9 +15,6 @@ module.exports = function setupMembersApp() {
|
|||||||
// send 503 json response in case of maintenance
|
// send 503 json response in case of maintenance
|
||||||
membersApp.use(shared.middlewares.maintenance);
|
membersApp.use(shared.middlewares.maintenance);
|
||||||
|
|
||||||
// Entire app is behind labs flag
|
|
||||||
membersApp.use(shared.middlewares.labs.members);
|
|
||||||
|
|
||||||
// Support CORS for requests from the frontend
|
// Support CORS for requests from the frontend
|
||||||
const siteUrl = new URL(urlUtils.getSiteUrl());
|
const siteUrl = new URL(urlUtils.getSiteUrl());
|
||||||
membersApp.use(cors(siteUrl.origin));
|
membersApp.use(cors(siteUrl.origin));
|
||||||
|
@ -9,6 +9,4 @@ const labs = flag => (req, res, next) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
labs.members = labs('members');
|
|
||||||
|
|
||||||
module.exports = labs;
|
module.exports = labs;
|
||||||
|
@ -16,155 +16,78 @@ describe('Basic Members Routes', function () {
|
|||||||
request = supertest.agent(configUtils.config.get('url'));
|
request = supertest.agent(configUtils.config.get('url'));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Members enabled', function () {
|
before(function () {
|
||||||
before(function () {
|
const originalSettingsCacheGetFn = settingsCache.get;
|
||||||
const originalSettingsCacheGetFn = settingsCache.get;
|
|
||||||
|
|
||||||
sinon.stub(settingsCache, 'get').callsFake(function (key, options) {
|
sinon.stub(settingsCache, 'get').callsFake(function (key, options) {
|
||||||
if (key === 'labs') {
|
if (key === 'labs') {
|
||||||
return {members: true};
|
return {members: true};
|
||||||
}
|
}
|
||||||
|
|
||||||
return originalSettingsCacheGetFn(key, options);
|
return originalSettingsCacheGetFn(key, options);
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function () {
|
|
||||||
sinon.restore();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Routes', function () {
|
|
||||||
it('should error serving webhook endpoint without any parameters', async function () {
|
|
||||||
await request.post('/members/webhooks/stripe')
|
|
||||||
.expect(400);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should error when invalid member token is passed into session', async function () {
|
|
||||||
await request.get('/members/api/session')
|
|
||||||
.expect(400);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return no content when removing member sessions', async function () {
|
|
||||||
await request.del('/members/api/session')
|
|
||||||
.expect(204);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should error for invalid member token on member data endpoint', async function () {
|
|
||||||
await request.get('/members/api/member')
|
|
||||||
.expect(400);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should serve member site endpoint', async function () {
|
|
||||||
await request.get('/members/api/site')
|
|
||||||
.expect(200);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should error for invalid data on member magic link endpoint', async function () {
|
|
||||||
await request.post('/members/api/send-magic-link')
|
|
||||||
.expect(400);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should error for invalid data on members create checkout session endpoint', async function () {
|
|
||||||
await request.post('/members/api/create-stripe-checkout-session')
|
|
||||||
.expect(400);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should error for invalid data on members create update session endpoint', async function () {
|
|
||||||
await request.post('/members/api/create-stripe-update-session')
|
|
||||||
.expect(400);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should error for invalid data on members subscription endpoint', async function () {
|
|
||||||
await request.put('/members/api/subscriptions/123')
|
|
||||||
.expect(400);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should serve theme 404 on members endpoint', async function () {
|
|
||||||
await request.get('/members/')
|
|
||||||
.expect(404)
|
|
||||||
.expect('Content-Type', 'text/html; charset=utf-8');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should redirect invalid token on members endpoint', async function () {
|
|
||||||
await request.get('/members/?token=abc&action=signup')
|
|
||||||
.expect(302)
|
|
||||||
.expect('Location', '/?action=signup&success=false');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Members disabled', function () {
|
after(function () {
|
||||||
before(function () {
|
sinon.restore();
|
||||||
const originalSettingsCacheGetFn = settingsCache.get;
|
});
|
||||||
|
|
||||||
sinon.stub(settingsCache, 'get').callsFake(function (key, options) {
|
describe('Routes', function () {
|
||||||
if (key === 'labs') {
|
it('should error serving webhook endpoint without any parameters', async function () {
|
||||||
return {members: false};
|
await request.post('/members/webhooks/stripe')
|
||||||
}
|
.expect(400);
|
||||||
|
|
||||||
return originalSettingsCacheGetFn(key, options);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
after(function () {
|
it('should error when invalid member token is passed into session', async function () {
|
||||||
sinon.restore();
|
await request.get('/members/api/session')
|
||||||
|
.expect(400);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Routes', function () {
|
it('should return no content when removing member sessions', async function () {
|
||||||
it('should not serve webhook endpoint', async function () {
|
await request.del('/members/api/session')
|
||||||
await request.post('/members/webhooks/stripe')
|
.expect(204);
|
||||||
.expect(404);
|
});
|
||||||
});
|
|
||||||
|
|
||||||
it('should not serve session endpoint', async function () {
|
it('should error for invalid member token on member data endpoint', async function () {
|
||||||
await request.get('/members/api/session')
|
await request.get('/members/api/member')
|
||||||
.expect(404);
|
.expect(400);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not serve session removal endpoint', async function () {
|
it('should serve member site endpoint', async function () {
|
||||||
await request.del('/members/api/session')
|
await request.get('/members/api/site')
|
||||||
.expect(404);
|
.expect(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not serve member data endpoint', async function () {
|
it('should error for invalid data on member magic link endpoint', async function () {
|
||||||
await request.get('/members/api/member')
|
await request.post('/members/api/send-magic-link')
|
||||||
.expect(404);
|
.expect(400);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not serve member site endpoint', async function () {
|
it('should error for invalid data on members create checkout session endpoint', async function () {
|
||||||
await request.get('/members/api/site')
|
await request.post('/members/api/create-stripe-checkout-session')
|
||||||
.expect(404);
|
.expect(400);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not serve member magic link endpoint', async function () {
|
it('should error for invalid data on members create update session endpoint', async function () {
|
||||||
await request.post('/members/api/send-magic-link')
|
await request.post('/members/api/create-stripe-update-session')
|
||||||
.expect(404);
|
.expect(400);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not serve members create checkout session endpoint', async function () {
|
it('should error for invalid data on members subscription endpoint', async function () {
|
||||||
await request.post('/members/api/create-stripe-checkout-session')
|
await request.put('/members/api/subscriptions/123')
|
||||||
.expect(404);
|
.expect(400);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not serve members create update session endpoint', async function () {
|
it('should serve theme 404 on members endpoint', async function () {
|
||||||
await request.post('/members/api/create-stripe-update-session')
|
await request.get('/members/')
|
||||||
.expect(404);
|
.expect(404)
|
||||||
});
|
.expect('Content-Type', 'text/html; charset=utf-8');
|
||||||
|
});
|
||||||
|
|
||||||
it('should not serve members subscription endpoint', async function () {
|
it('should redirect invalid token on members endpoint', async function () {
|
||||||
await request.put('/members/api/subscriptions/123')
|
await request.get('/members/?token=abc&action=signup')
|
||||||
.expect(404);
|
.expect(302)
|
||||||
});
|
.expect('Location', '/?action=signup&success=false');
|
||||||
|
|
||||||
it('should serve 404 on members endpoint', async function () {
|
|
||||||
await request.get('/members/')
|
|
||||||
.expect(404);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not redirect members endpoint with token', async function () {
|
|
||||||
await request.get('/members/?token=abc&action=signup')
|
|
||||||
.expect(404);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -363,43 +363,6 @@ describe('Settings API (canary)', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can toggle member setting', function () {
|
|
||||||
return request.get(localUtils.API.getApiQuery('settings/'))
|
|
||||||
.set('Origin', config.get('url'))
|
|
||||||
.expect('Content-Type', /json/)
|
|
||||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
||||||
.then(function (res) {
|
|
||||||
const jsonResponse = res.body;
|
|
||||||
|
|
||||||
const settingToChange = {
|
|
||||||
settings: [
|
|
||||||
{
|
|
||||||
key: 'labs',
|
|
||||||
value: '{"subscribers":false,"members":false}'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
should.exist(jsonResponse);
|
|
||||||
should.exist(jsonResponse.settings);
|
|
||||||
|
|
||||||
return request.put(localUtils.API.getApiQuery('settings/'))
|
|
||||||
.set('Origin', config.get('url'))
|
|
||||||
.send(settingToChange)
|
|
||||||
.expect('Content-Type', /json/)
|
|
||||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
||||||
.expect(200)
|
|
||||||
.then(function ({body, headers}) {
|
|
||||||
const putBody = body;
|
|
||||||
headers['x-cache-invalidate'].should.eql('/*');
|
|
||||||
should.exist(putBody);
|
|
||||||
|
|
||||||
putBody.settings[0].key.should.eql('labs');
|
|
||||||
putBody.settings[0].value.should.eql(JSON.stringify({subscribers: false, members: false}));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can\'t edit permalinks', function (done) {
|
it('can\'t edit permalinks', function (done) {
|
||||||
const settingToChange = {
|
const settingToChange = {
|
||||||
settings: [{key: 'permalinks', value: '/:primary_author/:slug/'}]
|
settings: [{key: 'permalinks', value: '/:primary_author/:slug/'}]
|
||||||
@ -521,31 +484,6 @@ describe('Settings API (canary)', function () {
|
|||||||
return localUtils.doAuth(request);
|
return localUtils.doAuth(request);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('cannot toggle member setting', function (done) {
|
|
||||||
const settingToChange = {
|
|
||||||
settings: [
|
|
||||||
{
|
|
||||||
key: 'labs',
|
|
||||||
value: '{"subscribers":false,"members":true}'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
request.put(localUtils.API.getApiQuery('settings/'))
|
|
||||||
.set('Origin', config.get('url'))
|
|
||||||
.send(settingToChange)
|
|
||||||
.expect('Content-Type', /json/)
|
|
||||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
||||||
.expect(403)
|
|
||||||
.end(function (err, res) {
|
|
||||||
if (err) {
|
|
||||||
return done(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('As Editor', function () {
|
describe('As Editor', function () {
|
||||||
|
@ -368,44 +368,6 @@ describe('Settings API (v2)', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can toggle member setting', function () {
|
|
||||||
return request.get(localUtils.API.getApiQuery('settings/'))
|
|
||||||
.set('Origin', config.get('url'))
|
|
||||||
.expect('Content-Type', /json/)
|
|
||||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
||||||
.then(function (res) {
|
|
||||||
const jsonResponse = res.body;
|
|
||||||
const changedValue = [];
|
|
||||||
|
|
||||||
const settingToChange = {
|
|
||||||
settings: [
|
|
||||||
{
|
|
||||||
key: 'labs',
|
|
||||||
value: '{"subscribers":false,"members":false}'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
should.exist(jsonResponse);
|
|
||||||
should.exist(jsonResponse.settings);
|
|
||||||
|
|
||||||
return request.put(localUtils.API.getApiQuery('settings/'))
|
|
||||||
.set('Origin', config.get('url'))
|
|
||||||
.send(settingToChange)
|
|
||||||
.expect('Content-Type', /json/)
|
|
||||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
||||||
.expect(200)
|
|
||||||
.then(function ({body, headers}) {
|
|
||||||
const putBody = body;
|
|
||||||
headers['x-cache-invalidate'].should.eql('/*');
|
|
||||||
should.exist(putBody);
|
|
||||||
|
|
||||||
putBody.settings[0].key.should.eql('labs');
|
|
||||||
putBody.settings[0].value.should.eql(JSON.stringify({subscribers: false, members: false}));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can\'t edit permalinks', function (done) {
|
it('can\'t edit permalinks', function (done) {
|
||||||
const settingToChange = {
|
const settingToChange = {
|
||||||
settings: [{key: 'permalinks', value: '/:primary_author/:slug/'}]
|
settings: [{key: 'permalinks', value: '/:primary_author/:slug/'}]
|
||||||
@ -524,31 +486,6 @@ describe('Settings API (v2)', function () {
|
|||||||
return localUtils.doAuth(request);
|
return localUtils.doAuth(request);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('cannot toggle member setting', function (done) {
|
|
||||||
const settingToChange = {
|
|
||||||
settings: [
|
|
||||||
{
|
|
||||||
key: 'labs',
|
|
||||||
value: '{"subscribers":false,"members":true}'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
request.put(localUtils.API.getApiQuery('settings/'))
|
|
||||||
.set('Origin', config.get('url'))
|
|
||||||
.send(settingToChange)
|
|
||||||
.expect('Content-Type', /json/)
|
|
||||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
||||||
.expect(403)
|
|
||||||
.end(function (err, res) {
|
|
||||||
if (err) {
|
|
||||||
return done(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('As Editor', function () {
|
describe('As Editor', function () {
|
||||||
|
@ -408,43 +408,6 @@ describe('Settings API (v3)', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can toggle member setting', function () {
|
|
||||||
return request.get(localUtils.API.getApiQuery('settings/'))
|
|
||||||
.set('Origin', config.get('url'))
|
|
||||||
.expect('Content-Type', /json/)
|
|
||||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
||||||
.then(function (res) {
|
|
||||||
const jsonResponse = res.body;
|
|
||||||
|
|
||||||
const settingToChange = {
|
|
||||||
settings: [
|
|
||||||
{
|
|
||||||
key: 'labs',
|
|
||||||
value: '{"subscribers":false,"members":false}'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
should.exist(jsonResponse);
|
|
||||||
should.exist(jsonResponse.settings);
|
|
||||||
|
|
||||||
return request.put(localUtils.API.getApiQuery('settings/'))
|
|
||||||
.set('Origin', config.get('url'))
|
|
||||||
.send(settingToChange)
|
|
||||||
.expect('Content-Type', /json/)
|
|
||||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
||||||
.expect(200)
|
|
||||||
.then(function ({body, headers}) {
|
|
||||||
const putBody = body;
|
|
||||||
headers['x-cache-invalidate'].should.eql('/*');
|
|
||||||
should.exist(putBody);
|
|
||||||
|
|
||||||
putBody.settings[0].key.should.eql('labs');
|
|
||||||
putBody.settings[0].value.should.eql(JSON.stringify({subscribers: false, members: false}));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can\'t edit permalinks', function (done) {
|
it('can\'t edit permalinks', function (done) {
|
||||||
const settingToChange = {
|
const settingToChange = {
|
||||||
settings: [{key: 'permalinks', value: '/:primary_author/:slug/'}]
|
settings: [{key: 'permalinks', value: '/:primary_author/:slug/'}]
|
||||||
@ -566,31 +529,6 @@ describe('Settings API (v3)', function () {
|
|||||||
return localUtils.doAuth(request);
|
return localUtils.doAuth(request);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('cannot toggle member setting', function (done) {
|
|
||||||
const settingToChange = {
|
|
||||||
settings: [
|
|
||||||
{
|
|
||||||
key: 'labs',
|
|
||||||
value: '{"subscribers":false,"members":true}'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
request.put(localUtils.API.getApiQuery('settings/'))
|
|
||||||
.set('Origin', config.get('url'))
|
|
||||||
.send(settingToChange)
|
|
||||||
.expect('Content-Type', /json/)
|
|
||||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
||||||
.expect(403)
|
|
||||||
.end(function (err, res) {
|
|
||||||
if (err) {
|
|
||||||
return done(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('As Editor', function () {
|
describe('As Editor', function () {
|
||||||
|
@ -39,6 +39,9 @@ describe('Unit: canary/utils/serializers/output/utils/mapper', function () {
|
|||||||
|
|
||||||
it('calls mapper on relations', function () {
|
it('calls mapper on relations', function () {
|
||||||
const frame = {
|
const frame = {
|
||||||
|
original: {
|
||||||
|
context: {}
|
||||||
|
},
|
||||||
options: {
|
options: {
|
||||||
withRelated: ['tags', 'authors'],
|
withRelated: ['tags', 'authors'],
|
||||||
context: {}
|
context: {}
|
||||||
|
@ -1,137 +1,115 @@
|
|||||||
const should = require('should');
|
const should = require('should');
|
||||||
const sinon = require('sinon');
|
|
||||||
const labs = require('../../../../../../../../core/server/services/labs');
|
|
||||||
const gating = require('../../../../../../../../core/server/api/canary/utils/serializers/output/utils/post-gating');
|
const gating = require('../../../../../../../../core/server/api/canary/utils/serializers/output/utils/post-gating');
|
||||||
|
|
||||||
describe('Unit: canary/utils/serializers/output/utils/post-gating', function () {
|
describe('Unit: canary/utils/serializers/output/utils/post-gating', function () {
|
||||||
describe('for post', function () {
|
describe('for post', function () {
|
||||||
it('does not modify attributes when members is disabled', function () {
|
it('should NOT hide content attributes when visibility is public', function () {
|
||||||
const attrs = {
|
const attrs = {
|
||||||
|
visibility: 'public',
|
||||||
plaintext: 'no touching',
|
plaintext: 'no touching',
|
||||||
html: '<p>I am here to stay</p>'
|
html: '<p>I am here to stay</p>'
|
||||||
};
|
};
|
||||||
|
|
||||||
const frame = {
|
const frame = {
|
||||||
options: {}
|
options: {},
|
||||||
|
original: {
|
||||||
|
context: {}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
gating.forPost(attrs, frame);
|
gating.forPost(attrs, frame);
|
||||||
|
|
||||||
attrs.plaintext.should.eql('no touching');
|
attrs.plaintext.should.eql('no touching');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('labs.members enabled', function () {
|
it('should hide content attributes when visibility is "members"', function () {
|
||||||
before(function () {
|
const attrs = {
|
||||||
sinon.stub(labs, 'isSet').returns(true);
|
visibility: 'members',
|
||||||
});
|
plaintext: 'no touching. secret stuff',
|
||||||
|
html: '<p>I am here to stay</p>'
|
||||||
|
};
|
||||||
|
|
||||||
it('should NOT hide content attributes when visibility is public', function () {
|
const frame = {
|
||||||
const attrs = {
|
options: {},
|
||||||
visibility: 'public',
|
original: {
|
||||||
plaintext: 'no touching',
|
context: {}
|
||||||
html: '<p>I am here to stay</p>'
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const frame = {
|
gating.forPost(attrs, frame);
|
||||||
options: {},
|
|
||||||
original: {
|
attrs.plaintext.should.eql('');
|
||||||
context: {}
|
attrs.html.should.eql('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should NOT hide content attributes when visibility is "members" and member is present', function () {
|
||||||
|
const attrs = {
|
||||||
|
visibility: 'members',
|
||||||
|
plaintext: 'I see dead people',
|
||||||
|
html: '<p>What\'s the matter?</p>'
|
||||||
|
};
|
||||||
|
|
||||||
|
const frame = {
|
||||||
|
options: {},
|
||||||
|
original: {
|
||||||
|
context: {
|
||||||
|
member: {}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
gating.forPost(attrs, frame);
|
gating.forPost(attrs, frame);
|
||||||
|
|
||||||
attrs.plaintext.should.eql('no touching');
|
attrs.plaintext.should.eql('I see dead people');
|
||||||
});
|
attrs.html.should.eql('<p>What\'s the matter?</p>');
|
||||||
|
});
|
||||||
|
|
||||||
it('should hide content attributes when visibility is "members"', function () {
|
it('should hide content attributes when visibility is "paid" and member has status of "free"', function () {
|
||||||
const attrs = {
|
const attrs = {
|
||||||
visibility: 'members',
|
visibility: 'paid',
|
||||||
plaintext: 'no touching. secret stuff',
|
plaintext: 'I see dead people',
|
||||||
html: '<p>I am here to stay</p>'
|
html: '<p>What\'s the matter?</p>'
|
||||||
};
|
};
|
||||||
|
|
||||||
const frame = {
|
const frame = {
|
||||||
options: {},
|
options: {},
|
||||||
original: {
|
original: {
|
||||||
context: {}
|
context: {
|
||||||
}
|
member: {
|
||||||
};
|
status: 'free'
|
||||||
|
|
||||||
gating.forPost(attrs, frame);
|
|
||||||
|
|
||||||
attrs.plaintext.should.eql('');
|
|
||||||
attrs.html.should.eql('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should NOT hide content attributes when visibility is "members" and member is present', function () {
|
|
||||||
const attrs = {
|
|
||||||
visibility: 'members',
|
|
||||||
plaintext: 'I see dead people',
|
|
||||||
html: '<p>What\'s the matter?</p>'
|
|
||||||
};
|
|
||||||
|
|
||||||
const frame = {
|
|
||||||
options: {},
|
|
||||||
original: {
|
|
||||||
context: {
|
|
||||||
member: {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
gating.forPost(attrs, frame);
|
gating.forPost(attrs, frame);
|
||||||
|
|
||||||
attrs.plaintext.should.eql('I see dead people');
|
attrs.plaintext.should.eql('');
|
||||||
attrs.html.should.eql('<p>What\'s the matter?</p>');
|
attrs.html.should.eql('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should hide content attributes when visibility is "paid" and member has status of "free"', function () {
|
it('should NOT hide content attributes when visibility is "paid" and member has status of "paid"', function () {
|
||||||
const attrs = {
|
const attrs = {
|
||||||
visibility: 'paid',
|
visibility: 'paid',
|
||||||
plaintext: 'I see dead people',
|
plaintext: 'Secret paid content',
|
||||||
html: '<p>What\'s the matter?</p>'
|
html: '<p>Can read this</p>'
|
||||||
};
|
};
|
||||||
|
|
||||||
const frame = {
|
const frame = {
|
||||||
options: {},
|
options: {},
|
||||||
original: {
|
original: {
|
||||||
context: {
|
context: {
|
||||||
member: {
|
member: {
|
||||||
status: 'free'
|
status: 'paid'
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
gating.forPost(attrs, frame);
|
gating.forPost(attrs, frame);
|
||||||
|
|
||||||
attrs.plaintext.should.eql('');
|
attrs.plaintext.should.eql('Secret paid content');
|
||||||
attrs.html.should.eql('');
|
attrs.html.should.eql('<p>Can read this</p>');
|
||||||
});
|
|
||||||
|
|
||||||
it('should NOT hide content attributes when visibility is "paid" and member has status of "paid"', function () {
|
|
||||||
const attrs = {
|
|
||||||
visibility: 'paid',
|
|
||||||
plaintext: 'Secret paid content',
|
|
||||||
html: '<p>Can read this</p>'
|
|
||||||
};
|
|
||||||
|
|
||||||
const frame = {
|
|
||||||
options: {},
|
|
||||||
original: {
|
|
||||||
context: {
|
|
||||||
member: {
|
|
||||||
status: 'paid'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
gating.forPost(attrs, frame);
|
|
||||||
|
|
||||||
attrs.plaintext.should.eql('Secret paid content');
|
|
||||||
attrs.html.should.eql('<p>Can read this</p>');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -39,6 +39,9 @@ describe('Unit: v2/utils/serializers/output/utils/mapper', function () {
|
|||||||
|
|
||||||
it('calls mapper on relations', function () {
|
it('calls mapper on relations', function () {
|
||||||
const frame = {
|
const frame = {
|
||||||
|
original: {
|
||||||
|
context: {}
|
||||||
|
},
|
||||||
options: {
|
options: {
|
||||||
withRelated: ['tags', 'authors'],
|
withRelated: ['tags', 'authors'],
|
||||||
context: {}
|
context: {}
|
||||||
|
@ -1,133 +1,132 @@
|
|||||||
const should = require('should');
|
const should = require('should');
|
||||||
const sinon = require('sinon');
|
|
||||||
const labs = require('../../../../../../../../core/server/services/labs');
|
|
||||||
const gating = require('../../../../../../../../core/server/api/v2/utils/serializers/output/utils/post-gating');
|
const gating = require('../../../../../../../../core/server/api/v2/utils/serializers/output/utils/post-gating');
|
||||||
|
|
||||||
describe('Unit: v2/utils/serializers/output/utils/post-gating', function () {
|
describe('Unit: v2/utils/serializers/output/utils/post-gating', function () {
|
||||||
describe('for post', function () {
|
describe('for post', function () {
|
||||||
it('does not modify attributes when members is disabled', function () {
|
it('should NOT hide content attributes when visibility is public', function () {
|
||||||
const attrs = {
|
const attrs = {
|
||||||
|
visibility: 'public',
|
||||||
plaintext: 'no touching',
|
plaintext: 'no touching',
|
||||||
html: '<p>I am here to stay</p>'
|
html: '<p>I am here to stay</p>'
|
||||||
};
|
};
|
||||||
|
|
||||||
const frame = {
|
const frame = {
|
||||||
options: {}
|
original: {
|
||||||
|
context: {}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
gating.forPost(attrs, frame);
|
gating.forPost(attrs, frame);
|
||||||
|
|
||||||
attrs.plaintext.should.eql('no touching');
|
attrs.plaintext.should.eql('no touching');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('labs.members enabled', function () {
|
it('should hide content attributes when visibility is "members"', function () {
|
||||||
before(function () {
|
const attrs = {
|
||||||
sinon.stub(labs, 'isSet').returns(true);
|
visibility: 'members',
|
||||||
});
|
plaintext: 'no touching. secret stuff',
|
||||||
|
html: '<p>I am here to stay</p>'
|
||||||
|
};
|
||||||
|
|
||||||
it('should NOT hide content attributes when visibility is public', function () {
|
const frame = {
|
||||||
const attrs = {
|
original: {
|
||||||
visibility: 'public',
|
context: {}
|
||||||
plaintext: 'no touching',
|
}
|
||||||
html: '<p>I am here to stay</p>'
|
};
|
||||||
};
|
|
||||||
|
|
||||||
const frame = {
|
gating.forPost(attrs, frame);
|
||||||
original: {
|
|
||||||
context: {}
|
attrs.plaintext.should.eql('');
|
||||||
|
attrs.html.should.eql('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should NOT hide content attributes when visibility is "members" and member is present', function () {
|
||||||
|
const attrs = {
|
||||||
|
visibility: 'members',
|
||||||
|
plaintext: 'I see dead people',
|
||||||
|
html: '<p>What\'s the matter?</p>'
|
||||||
|
};
|
||||||
|
|
||||||
|
const frame = {
|
||||||
|
original: {
|
||||||
|
context: {
|
||||||
|
member: {}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
gating.forPost(attrs, frame);
|
gating.forPost(attrs, frame);
|
||||||
|
|
||||||
attrs.plaintext.should.eql('no touching');
|
attrs.plaintext.should.eql('I see dead people');
|
||||||
});
|
attrs.html.should.eql('<p>What\'s the matter?</p>');
|
||||||
|
});
|
||||||
|
|
||||||
it('should hide content attributes when visibility is "members"', function () {
|
it('should hide content attributes when visibility is "paid" and member has no subscription', function () {
|
||||||
const attrs = {
|
const attrs = {
|
||||||
visibility: 'members',
|
visibility: 'paid',
|
||||||
plaintext: 'no touching. secret stuff',
|
plaintext: 'I see dead people',
|
||||||
html: '<p>I am here to stay</p>'
|
html: '<p>What\'s the matter?</p>'
|
||||||
};
|
};
|
||||||
|
|
||||||
const frame = {
|
const frame = {
|
||||||
original: {
|
original: {
|
||||||
context: {}
|
context: {
|
||||||
|
member: {}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
gating.forPost(attrs, frame);
|
gating.forPost(attrs, frame);
|
||||||
|
|
||||||
attrs.plaintext.should.eql('');
|
attrs.plaintext.should.eql('');
|
||||||
attrs.html.should.eql('');
|
attrs.html.should.eql('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT hide content attributes when visibility is "members" and member is present', function () {
|
it('should hide content attributes when visibility is "paid" and member has status of "free"', function () {
|
||||||
const attrs = {
|
const attrs = {
|
||||||
visibility: 'members',
|
visibility: 'paid',
|
||||||
plaintext: 'I see dead people',
|
plaintext: 'I see dead people',
|
||||||
html: '<p>What\'s the matter?</p>'
|
html: '<p>What\'s the matter?</p>'
|
||||||
};
|
};
|
||||||
|
|
||||||
const frame = {
|
const frame = {
|
||||||
original: {
|
original: {
|
||||||
context: {
|
context: {
|
||||||
member: {}
|
member: {
|
||||||
|
status: 'free'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
gating.forPost(attrs, frame);
|
gating.forPost(attrs, frame);
|
||||||
|
|
||||||
attrs.plaintext.should.eql('I see dead people');
|
attrs.plaintext.should.eql('');
|
||||||
attrs.html.should.eql('<p>What\'s the matter?</p>');
|
attrs.html.should.eql('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should hide content attributes when visibility is "paid" and member has status of "free"', function () {
|
it('should NOT hide content attributes when visibility is "paid" and member has status of "paid"', function () {
|
||||||
const attrs = {
|
const attrs = {
|
||||||
visibility: 'paid',
|
visibility: 'paid',
|
||||||
plaintext: 'I see dead people',
|
plaintext: 'Secret paid content',
|
||||||
html: '<p>What\'s the matter?</p>'
|
html: '<p>Can read this</p>'
|
||||||
};
|
};
|
||||||
|
|
||||||
const frame = {
|
const frame = {
|
||||||
original: {
|
options: {},
|
||||||
context: {
|
original: {
|
||||||
member: {
|
context: {
|
||||||
status: 'free'
|
member: {
|
||||||
}
|
status: 'paid'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
gating.forPost(attrs, frame);
|
gating.forPost(attrs, frame);
|
||||||
|
|
||||||
attrs.plaintext.should.eql('');
|
attrs.plaintext.should.eql('Secret paid content');
|
||||||
attrs.html.should.eql('');
|
attrs.html.should.eql('<p>Can read this</p>');
|
||||||
});
|
|
||||||
|
|
||||||
it('should NOT hide content attributes when visibility is "paid" and member has status of "paid"', function () {
|
|
||||||
const attrs = {
|
|
||||||
visibility: 'paid',
|
|
||||||
plaintext: 'Secret paid content',
|
|
||||||
html: '<p>Can read this</p>'
|
|
||||||
};
|
|
||||||
|
|
||||||
const frame = {
|
|
||||||
options: {},
|
|
||||||
original: {
|
|
||||||
context: {
|
|
||||||
member: {
|
|
||||||
status: 'paid'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
gating.forPost(attrs, frame);
|
|
||||||
|
|
||||||
attrs.plaintext.should.eql('Secret paid content');
|
|
||||||
attrs.html.should.eql('<p>Can read this</p>');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -39,6 +39,9 @@ describe('Unit: v3/utils/serializers/output/utils/mapper', function () {
|
|||||||
|
|
||||||
it('calls mapper on relations', function () {
|
it('calls mapper on relations', function () {
|
||||||
const frame = {
|
const frame = {
|
||||||
|
original: {
|
||||||
|
context: {}
|
||||||
|
},
|
||||||
options: {
|
options: {
|
||||||
withRelated: ['tags', 'authors'],
|
withRelated: ['tags', 'authors'],
|
||||||
context: {}
|
context: {}
|
||||||
|
Loading…
Reference in New Issue
Block a user