fix(donate): allow unauthenticated donations for year-end

This commit is contained in:
Mrugesh Mohapatra
2019-12-18 04:15:55 +05:30
committed by mrugesh
parent fc25c281e4
commit 663f726c4e
4 changed files with 112 additions and 7 deletions

View File

@ -5,7 +5,7 @@ import { isEmail, isNumeric } from 'validator';
import {
durationKeysConfig,
// donationOneTimeConfig,
donationOneTimeConfig,
donationSubscriptionConfig
} from '../../../config/donation-settings';
import keys from '../../../config/secrets';
@ -14,6 +14,7 @@ const log = debug('fcc:boot:donate');
export default function donateBoot(app, done) {
let stripe = false;
const { User } = app.models;
const api = app.loopback.Router();
const donateRouter = app.loopback.Router();
@ -56,8 +57,7 @@ export default function donateBoot(app, done) {
isNumeric('' + amount) &&
durationKeysConfig.includes(duration) &&
duration === 'onetime'
? // eslint-disable-next-line no-inline-comments
amount > 1 // donationOneTimeConfig.includes(amount)
? donationOneTimeConfig.includes(amount)
: donationSubscriptionConfig.plans[duration];
}
@ -206,6 +206,104 @@ export default function donateBoot(app, done) {
});
}
function createStripeDonationYearEnd(req, res) {
const { user, body } = req;
const {
amount,
duration,
token: { email, id }
} = body;
if (amount < 1 || duration !== 'onetime' || !isEmail(email)) {
return res.status(500).send({
error: 'The donation form had invalid values for this submission.'
});
}
const fccUser = user
? Promise.resolve(user)
: new Promise((resolve, reject) =>
User.findOrCreate(
{ where: { email } },
{ email },
(err, instance, isNew) => {
log('is new user instance: ', isNew);
if (err) {
return reject(err);
}
return resolve(instance);
}
)
);
let donatingUser = {};
let donation = {
email,
amount,
duration,
provider: 'stripe',
startDate: new Date(Date.now()).toISOString()
};
const createCustomer = user => {
donatingUser = user;
return stripe.customers.create({
email,
card: id
});
};
const createOneTimeCharge = customer => {
donation.customerId = customer.id;
return stripe.charges.create({
amount: amount,
currency: 'usd',
customer: customer.id
});
};
const createAsyncUserDonation = () => {
donatingUser
.createDonation(donation)
.toPromise()
.catch(err => {
throw new Error(err);
});
};
return Promise.resolve(fccUser)
.then(nonDonatingUser => {
const { isDonating } = nonDonatingUser;
if (isDonating) {
throw {
message: `User already has active donation(s).`,
type: 'AlreadyDonatingError'
};
}
return nonDonatingUser;
})
.then(createCustomer)
.then(customer => {
return createOneTimeCharge(customer).then(charge => {
donation.subscriptionId = 'one-time-charge-prefix-' + charge.id;
return res.send(charge);
});
})
.then(createAsyncUserDonation)
.catch(err => {
if (
err.type === 'StripeCardError' ||
err.type === 'AlreadyDonatingError'
) {
return res.status(402).send({ error: err.message });
}
return res
.status(500)
.send({ error: 'Donation failed due to a server error.' });
});
}
function createHmacHash(req, res) {
const { user, body } = req;
@ -261,10 +359,12 @@ export default function donateBoot(app, done) {
done();
} else {
api.post('/charge-stripe', createStripeDonation);
api.post('/charge-stripe-year-end', createStripeDonationYearEnd);
api.post('/create-hmac-hash', createHmacHash);
donateRouter.use('/donate', api);
app.use(donateRouter);
app.use('/internal', donateRouter);
app.use('/unauthenticated', donateRouter);
connectToStripe().then(done);
}
}