0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-03-18 02:21:47 -05:00

Fixed error responses when missing data

no-issue

We should error early when recieving a request that does not contain the
required data.
This commit is contained in:
Fabien O'Carroll 2021-01-19 10:42:39 +00:00
parent 07fea2c68c
commit 6412cfe3c6
2 changed files with 93 additions and 78 deletions
ghost/members-api
index.js
lib/controllers/router

View file

@ -260,6 +260,11 @@ module.exports = function MembersApi({
res.writeHead(400);
return res.end();
}
if (!req.body || !req.headers['stripe-signature']) {
res.writeHead(400);
return res.end();
}
let event;
try {
event = stripeWebhookService.parseWebhook(req.body, req.headers['stripe-signature']);

View file

@ -47,99 +47,109 @@ module.exports = class RouterController {
}
async updateSubscription(req, res) {
const identity = req.body.identity;
const subscriptionId = req.params.id;
const cancelAtPeriodEnd = req.body.cancel_at_period_end;
const cancellationReason = req.body.cancellation_reason;
const planName = req.body.planName;
if (cancelAtPeriodEnd === undefined && planName === undefined) {
throw new errors.BadRequestError({
message: 'Updating subscription failed!',
help: 'Request should contain "cancel_at_period_end" or "planName" field.'
});
}
if ((cancelAtPeriodEnd === undefined || cancelAtPeriodEnd === false) && cancellationReason !== undefined) {
throw new errors.BadRequestError({
message: 'Updating subscription failed!',
help: '"cancellation_reason" field requires the "cancel_at_period_end" field to be true.'
});
}
if (cancellationReason && cancellationReason.length > 500) {
throw new errors.BadRequestError({
message: 'Updating subscription failed!',
help: '"cancellation_reason" field can be a maximum of 500 characters.'
});
}
let email;
try {
if (!identity) {
const identity = req.body.identity;
const subscriptionId = req.params.id;
const cancelAtPeriodEnd = req.body.cancel_at_period_end;
const cancellationReason = req.body.cancellation_reason;
const planName = req.body.planName;
if (cancelAtPeriodEnd === undefined && planName === undefined) {
throw new errors.BadRequestError({
message: 'Updating subscription failed!',
help: 'Request should contain "cancel_at_period_end" or "planName" field.'
});
}
if ((cancelAtPeriodEnd === undefined || cancelAtPeriodEnd === false) && cancellationReason !== undefined) {
throw new errors.BadRequestError({
message: 'Updating subscription failed!',
help: '"cancellation_reason" field requires the "cancel_at_period_end" field to be true.'
});
}
if (cancellationReason && cancellationReason.length > 500) {
throw new errors.BadRequestError({
message: 'Updating subscription failed!',
help: '"cancellation_reason" field can be a maximum of 500 characters.'
});
}
let email;
try {
if (!identity) {
throw new errors.BadRequestError({
message: 'Updating subscription failed! Could not find member'
});
}
const claims = await this._tokenService.decodeToken(identity);
email = claims && claims.sub;
} catch (err) {
res.writeHead(401);
return res.end('Unauthorized');
}
const member = email ? await this._memberRepository.get({email}, {withRelated: ['stripeSubscriptions']}) : null;
if (!member) {
throw new errors.BadRequestError({
message: 'Updating subscription failed! Could not find member'
});
}
const claims = await this._tokenService.decodeToken(identity);
email = claims && claims.sub;
} catch (err) {
res.writeHead(401);
return res.end('Unauthorized');
}
// Don't allow removing subscriptions that don't belong to the member
const subscription = member.related('stripeSubscriptions').models.find(
subscription => subscription.get('subscription_id') === subscriptionId
);
if (!subscription) {
res.writeHead(403);
return res.end('No permission');
}
const member = email ? await this._memberRepository.get({email}, {withRelated: ['stripeSubscriptions']}) : null;
if (!member) {
throw new errors.BadRequestError({
message: 'Updating subscription failed! Could not find member'
});
}
// Don't allow removing subscriptions that don't belong to the member
const subscription = member.related('stripeSubscriptions').models.find(
subscription => subscription.get('subscription_id') === subscriptionId
);
if (!subscription) {
res.writeHead(403);
return res.end('No permission');
}
let updatedSubscription;
if (planName !== undefined) {
const plan = this._stripePlansService.getPlans().find(plan => plan.nickname === planName);
if (!plan) {
throw new errors.BadRequestError({
message: 'Updating subscription failed! Could not find plan'
let updatedSubscription;
if (planName !== undefined) {
const plan = this._stripePlansService.getPlans().find(plan => plan.nickname === planName);
if (!plan) {
throw new errors.BadRequestError({
message: 'Updating subscription failed! Could not find plan'
});
}
updatedSubscription = await this._stripeAPIService.changeSubscriptionPlan(subscriptionId, plan.id);
} else if (cancelAtPeriodEnd !== undefined) {
if (cancelAtPeriodEnd) {
updatedSubscription = await this._stripeAPIService.cancelSubscriptionAtPeriodEnd(
subscriptionId, cancellationReason
);
} else {
updatedSubscription = await this._stripeAPIService.continueSubscriptionAtPeriodEnd(
subscriptionId
);
}
}
if (updatedSubscription) {
await this._memberRepository.linkSubscription({
id: member.id,
subscription: updatedSubscription
});
}
updatedSubscription = await this._stripeAPIService.changeSubscriptionPlan(subscriptionId, plan.id);
} else if (cancelAtPeriodEnd !== undefined) {
if (cancelAtPeriodEnd) {
updatedSubscription = await this._stripeAPIService.cancelSubscriptionAtPeriodEnd(
subscriptionId, cancellationReason
);
} else {
updatedSubscription = await this._stripeAPIService.continueSubscriptionAtPeriodEnd(
subscriptionId
);
}
}
if (updatedSubscription) {
await this._memberRepository.linkSubscription({
id: member.id,
subscription: updatedSubscription
});
}
res.writeHead(204);
res.end();
res.writeHead(204);
res.end();
} catch (err) {
res.writeHead(err.statusCode || 500);
res.end(err.message);
}
}
async createCheckoutSetupSession(req, res) {
const identity = req.body.identity;
if (!identity) {
res.writeHead(400);
return res.end();
}
let email;
try {
if (!identity) {