Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
Add v2.20.1
Browse files Browse the repository at this point in the history
  • Loading branch information
YannickRe committed Apr 17, 2019
1 parent a048bd7 commit 91b010b
Show file tree
Hide file tree
Showing 51 changed files with 623 additions and 335 deletions.
10 changes: 0 additions & 10 deletions content/settings/routes.yaml

This file was deleted.

This file was deleted.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

This file was deleted.

2 changes: 1 addition & 1 deletion core/server/api/v2/members.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const memberUserObject = require('../../services/members').api.memberUserObject;
const memberUserObject = require('../../services/members').api.members;

const members = {
docName: 'members',
Expand Down
21 changes: 17 additions & 4 deletions core/server/api/v2/notifications.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,25 @@ module.exports = {
allNotifications = _.orderBy(allNotifications, 'addedAt', 'desc');

allNotifications = allNotifications.filter((notification) => {
// NOTE: Filtering by version below is just a patch for bigger problem - notifications are not removed
// after Ghost update. Logic below should be removed when Ghost upgrade detection
// is done (https://github.com/TryGhost/Ghost/issues/10236) and notifications are
// be removed permanently on upgrade event.
const ghost20RegEx = /Ghost 2.0 is now available/gi;

// CASE: do not return old release notification
if (!notification.custom && notification.message) {
const notificationVersion = notification.message.match(/(\d+\.)(\d+\.)(\d+)/),
blogVersion = ghostVersion.full.match(/^(\d+\.)(\d+\.)(\d+)/);
if (notification.message && (!notification.custom || notification.message.match(ghost20RegEx))) {
let notificationVersion = notification.message.match(/(\d+\.)(\d+\.)(\d+)/);

if (notification.message.match(ghost20RegEx)) {
notificationVersion = '2.0.0';
} else if (notificationVersion){
notificationVersion = notificationVersion[0];
}

const blogVersion = ghostVersion.full.match(/^(\d+\.)(\d+\.)(\d+)/);

if (notificationVersion && blogVersion && semver.gt(notificationVersion[0], blogVersion[0])) {
if (notificationVersion && blogVersion && semver.gt(notificationVersion, blogVersion[0])) {
return true;
} else {
return false;
Expand Down
10 changes: 9 additions & 1 deletion core/server/api/v2/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ const urlService = require('../../services/url');
const common = require('../../lib/common');
const settingsCache = require('../../services/settings/cache');

const SETTINGS_BLACKLIST = [
'members_public_key',
'members_private_key',
'members_session_secret'
];

module.exports = {
docName: 'settings',

Expand All @@ -28,7 +34,9 @@ module.exports = {
// CASE: omit core settings unless internal request
if (!frame.options.context.internal) {
settings = _.filter(settings, (setting) => {
return setting.type !== 'core';
const isCore = setting.type === 'core';
const isBlacklisted = SETTINGS_BLACKLIST.includes(setting.key);
return !isBlacklisted && !isCore;
});
}

Expand Down
3 changes: 3 additions & 0 deletions core/server/data/schema/default-settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
},
"session_secret": {
"defaultValue": null
},
"theme_session_secret": {
"defaultValue": null
}
},
"blog": {
Expand Down
94 changes: 63 additions & 31 deletions core/server/lib/members/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ module.exports = function MembersApi({
privateKey,
publicKey,
sessionSecret,
ssoOrigin
ssoOrigin,
accessControl
},
paymentConfig,
validateAudience,
createMember,
validateMember,
updateMember,
Expand Down Expand Up @@ -53,6 +53,20 @@ module.exports = function MembersApi({
/* session */
const {getCookie, setCookie, removeCookie} = Cookies(sessionSecret);

function validateAccess({audience, origin}) {
const audienceLookup = accessControl[origin] || {
[origin]: accessControl['*']
};

const tokenSettings = audienceLookup[audience];

if (tokenSettings) {
return Promise.resolve(tokenSettings);
}

return Promise.reject();
}

/* token */
apiRouter.post('/token', getData('audience'), (req, res) => {
const {signedin} = getCookie(req);
Expand All @@ -65,19 +79,16 @@ module.exports = function MembersApi({

const {audience, origin} = req.data;

validateAudience({audience, origin, id: signedin})
.then(() => {
return users.get({id: signedin});
validateAccess({audience, origin})
.then(({tokenLength}) => {
return users.get({id: signedin})
.then(member => encodeToken({
sub: member.id,
plans: member.subscriptions.map(sub => sub.plan),
exp: tokenLength,
aud: audience
}));
})
.then(member => encodeToken({
sub: member.id,
plans: member.subscriptions.map(sub => sub.plan),
exp: member.subscriptions
.map(sub => sub.validUntil)
.reduce((a, b) => Math.min(a, b),
Math.floor((Date.now() / 1000) + (60 * 60 * 24 * 30))),
aud: audience
}))
.then(token => res.end(token))
.catch(handleError(403, res));
});
Expand All @@ -89,9 +100,10 @@ module.exports = function MembersApi({
return subscriptions.getPublicConfig(adapter);
}));
})
.then(data => res.json({
paymentConfig: data,
siteConfig: siteConfig
.then(paymentConfig => res.json({
paymentConfig,
issuer,
siteConfig
}))
.catch(handleError(500, res));
});
Expand All @@ -106,7 +118,7 @@ module.exports = function MembersApi({
}

/* subscriptions */
apiRouter.post('/subscription', getData('adapter', 'plan', 'stripeToken'), ssoOriginCheck, (req, res) => {
apiRouter.post('/subscription', getData('adapter', 'plan', 'stripeToken', {name: 'coupon', required: false}), ssoOriginCheck, (req, res) => {
const {signedin} = getCookie(req);
if (!signedin) {
res.writeHead(401, {
Expand All @@ -115,7 +127,7 @@ module.exports = function MembersApi({
return res.end();
}

const {plan, adapter, stripeToken} = req.data;
const {plan, adapter, stripeToken, coupon} = req.data;

subscriptions.getAdapters()
.then((adapters) => {
Expand All @@ -128,7 +140,8 @@ module.exports = function MembersApi({
return subscriptions.createSubscription(member, {
adapter,
plan,
stripeToken
stripeToken,
coupon
});
})
.then(() => {
Expand Down Expand Up @@ -195,9 +208,19 @@ module.exports = function MembersApi({
/* http */
const staticRouter = Router();
staticRouter.use('/static', static(require('path').join(__dirname, './static/auth/dist')));
staticRouter.use('/gateway', static(require('path').join(__dirname, './static/gateway')));
staticRouter.get('/gateway', (req, res) => {
res.status(200).send(`
<script>
window.membersApiUrl = "${issuer}";
</script>
<script src="bundle.js"></script>
`);
});
staticRouter.get('/bundle.js', (req, res) => {
res.status(200).sendFile(require('path').join(__dirname, './static/gateway/bundle.js'));
});
staticRouter.get('/*', (req, res) => {
res.sendFile(require('path').join(__dirname, './static/auth/dist/index.html'));
res.status(200).sendFile(require('path').join(__dirname, './static/auth/dist/index.html'));
});

/* http */
Expand All @@ -210,14 +233,23 @@ module.exports = function MembersApi({
});
});

function httpHandler(req, res, next) {
return router.handle(req, res, next);
}

httpHandler.staticRouter = staticRouter;
httpHandler.apiRouter = apiRouter;
httpHandler.memberUserObject = users;
httpHandler.reconfigureSettings = function (data) {
const apiInstance = {
staticRouter,
apiRouter
};
apiInstance.members = users;
apiInstance.getPublicConfig = function () {
return Promise.resolve({
publicKey,
issuer
});
};
apiInstance.getMember = function (id, token) {
return decodeToken(token).then(() => {
return users.get({id});
});
};
apiInstance.reconfigureSettings = function (data) {
subscriptions = new Subscriptions(data.paymentConfig);
users = Users({
subscriptions,
Expand All @@ -233,5 +265,5 @@ module.exports = function MembersApi({
siteConfig = data.siteConfig;
};

return httpHandler;
return apiInstance;
};
19 changes: 19 additions & 0 deletions core/server/lib/members/static/auth/components/CouponInput.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import FormInput from './FormInput';
import { IconName } from './icons';

export default ({value, disabled, error, children, onInput, className}) => (
<FormInput
type="text"
name="coupon"
label="coupon"
value={value}
error={error}
icon={IconName}
placeholder="Coupon..."
required={false}
disabled={disabled}
className={className}
onInput={onInput}>
{children}
</FormInput>
);
4 changes: 2 additions & 2 deletions core/server/lib/members/static/auth/components/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ export default class Form extends Component {
return (e) => {
e.preventDefault();

const requiredFields = children.map(c => c.attributes.bindTo).filter(x => !!x)
if (!requiredFields.some(x => !data[x])) {
const requiredFields = children.map(c => c.attributes && c.attributes.bindTo).filter(x => !!x)
if (!requiredFields.some(x => data[x] == null)) {
onSubmit(this.state.data)
}
this.setState({
Expand Down
3 changes: 2 additions & 1 deletion core/server/lib/members/static/auth/components/FormInput.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default ({type, name, placeholder, value = '', error, onInput, required, className, children, icon}) => (
export default ({type, name, placeholder, value = '', error, onInput, required, disabled = false, className, children, icon}) => (
<div className="gm-form-element">
<div className={[
(className ? className : ""),
Expand All @@ -12,6 +12,7 @@ export default ({type, name, placeholder, value = '', error, onInput, required,
value={ value }
onInput={ (e) => onInput(e, name) }
required={ required }
disabled={ disabled }
className={[
(value ? "gm-input-filled" : ""),
(error ? "gm-error" : "")
Expand Down
Loading

0 comments on commit 91b010b

Please sign in to comment.