Skip to content
71 changes: 71 additions & 0 deletions api/main_endpoints/routes/MembershipPayment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
const express = require('express');
const router = express.Router();
const bodyParser = require('body-parser');
router.use(bodyParser.json());
const {
BAD_REQUEST,
SERVER_ERROR,
NOT_FOUND,
OK,
} = require('../../util/constants').STATUS_CODES;
const membershipState = require('../../util/constants').MEMBERSHIP_STATE;
const User = require('../models/User');
const { getMemberExpirationDate, updateMembershipExpiration } = require('../util/userHelpers');
const { findVerifyPayment, rejectPayment } = require('../util/membershipPaymentQueries');
const { decodeToken } = require('../util/token-functions.js');

router.post('/verifyMembership', async (req, res) => {
const decoded = await decodeToken(req, membershipState.PENDING);
if (decoded.status !== OK) {
return res.sendStatus(decoded.status);
}

const { confirmationCode } = req.body;
const userId = decoded.token._id;

if (!confirmationCode) {
return res.sendStatus(BAD_REQUEST);
}

const paymentDocument = await findVerifyPayment(confirmationCode, userId);
if (paymentDocument === null){
return res.sendStatus(SERVER_ERROR);
}
if (paymentDocument === false){
return res.sendStatus(NOT_FOUND);
}

const paymentId = paymentDocument._id;
const { amount } = paymentDocument;

if (amount < 20){
const rejected = await rejectPayment(paymentId);
if (rejected === null){
return res.sendStatus(SERVER_ERROR);
}
if (rejected === false){
return res.sendStatus(NOT_FOUND);
}
return res.sendStatus(BAD_REQUEST);
}

let semestersToAdd = 0;
if (amount >= 30) {
semestersToAdd = 2;
} else {
semestersToAdd = 1;
}

const membershipUpdateResult = await updateMembershipExpiration(
decoded.token._id,
semestersToAdd
);

if (membershipUpdateResult === null) {
return res.sendStatus(SERVER_ERROR);
}
if (membershipUpdateResult === false) {
return res.status(NOT_FOUND).send('User not found.');
}
return res.sendStatus(OK);
});
62 changes: 62 additions & 0 deletions api/main_endpoints/util/membershipPaymentQueries.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import MembershipPayment from '../main_endpoints/models/MembershipPayment.js';

const status = {
PENDING: 'pending',
COMPLETED: 'completed',
REJECTED: 'rejected',
};

function findVerifyPayment(confirmationCode, userId) {
return new Promise((resolve) => {
try {
MembershipPayment.findOneAndUpdate(
{
confirmationCode,
status: status.PENDING,
},
{
$set: { userId, status: status.COMPLETED },
},
{
new: true,
runValidators: true,
},
(error, result) => {
if (error) {
return resolve(null);
}
if (!result) {
return resolve(false);
}
return resolve(result);
}
);
} catch (error) {
return resolve(null);
}
});
}

function rejectPayment(paymentId) {
return new Promise((resolve) => {
try {
MembershipPayment.findByIdAndUpdate(
paymentId,
{ $set: { status: status.REJECTED } },
(error, result) => {
if (error) {
return resolve(null);
}
if (!result) {
return resolve(false);
}
return resolve(true);
}
);
} catch (error) {
return resolve(null);
}
});
}

module.exports = { findVerifyPayment, rejectPayment };
25 changes: 25 additions & 0 deletions api/main_endpoints/util/userHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,30 @@ function checkIfPageCountResets(lastLogin) {
return lastLoginWasOverOneWeekAgo || aSundayHasPassedSinceLastLogin;
}

/**
* Update a user's membershipValidUntil date
* @param {String} userId - The user's ID
* @param {Number} numberOfSemestersToSignUpFor - Number of semesters to extend
* @returns {Object} result - Contains success status and message
*/
async function updateMembershipExpiration(userId, numberOfSemestersToSignUpFor) {
try {
const newExpiration = getMemberExpirationDate(numberOfSemestersToSignUpFor);
const user = await User.findByIdAndUpdate(
userId,
{ membershipValidUntil: newExpiration },
{ new: true },
);
if (!user) {
return false;
}
return true;
} catch (error) {
logger.error('Error updating membership:', error);
return null;
}
}

module.exports = {
registerUser,
getMemberExpirationDate,
Expand All @@ -211,4 +235,5 @@ module.exports = {
userWithEmailExists,
checkIfPageCountResets,
findPasswordReset,
updateMembershipExpiration
};