diff --git a/server/models/contests/addGroup.js b/server/models/contests/addGroup.js index 42b4c8d..37ba70f 100644 --- a/server/models/contests/addGroup.js +++ b/server/models/contests/addGroup.js @@ -13,30 +13,24 @@ function addGroup({ params, body, username }) { const { contest_id: contestId } = params const { group_id: groupId } = body pool.query( - `SELECT * FROM contests_moderators WHERE contest_id=? AND moderator=?`, - [contestId, username], - (error, results) => { - if (error) { + `INSERT INTO contests_groups (contest_id, group_id) SELECT contest_id, ? FROM contests_moderators WHERE contest_id=? AND moderator=?`, + [groupId, contestId, username], + (error, res) => { + if (error || res === undefined) { + const { code } = error + if (code === 'ER_DUP_ENTRY') { + return reject('The group is already added') + } return reject(error) - } else if (!results || !results.length) { - return reject( - 'Invalid contest ID or you do not have moderator access to the contest' - ) - } - pool.query( - `INSERT INTO contests_groups (contest_id, group_id) VALUES (?,?)`, - [contestId, groupId], - (error, res) => { - if (error || res === undefined) { - const { code } = error - if (code === 'ER_DUP_ENTRY') { - return reject('The group is already added') - } - return reject(error) - } - return resolve('Successfully added group') + } else { + const { affectedRows } = res + if (!affectedRows) { + return reject( + 'The user do not have moderator access of the contest' + ) } - ) + return resolve('Successfully added group') + } } ) }) diff --git a/server/models/contests/addModerator.js b/server/models/contests/addModerator.js index 6750793..29511ad 100644 --- a/server/models/contests/addModerator.js +++ b/server/models/contests/addModerator.js @@ -13,30 +13,24 @@ function addModerator({ params, body, username }) { const { contest_id: contestId } = params const { moderator: moderatorUsername } = body pool.query( - `SELECT * FROM contests_moderators WHERE contest_id=? AND moderator=?`, - [contestId, username], - (error, results) => { - if (error) { + `INSERT INTO contests_moderators (contest_id, moderator) SELECT contest_id, ? FROM contests_moderators WHERE contest_id=? AND moderator=?`, + [moderatorUsername, contestId, username], + (error, res) => { + if (error || res === undefined) { + const { code } = error + if (code === 'ER_DUP_ENTRY') { + return reject('The user is already a moderator') + } return reject(error) - } else if (!results || !results.length) { - return reject( - 'Invalid contest ID or you do not have moderator access to the contest' - ) - } - pool.query( - `INSERT INTO contests_moderators (contest_id, moderator) VALUES (?,?)`, - [contestId, moderatorUsername], - (error, res) => { - if (error || res === undefined) { - const { code } = error - if (code === 'ER_DUP_ENTRY') { - return reject('The user is already a moderator') - } - return reject(error) - } - return resolve('Successfully made moderator!!') + } else { + const { affectedRows } = res + if (!affectedRows) { + return reject( + 'The user do not have moderator access of the contest' + ) } - ) + return resolve('Successfully made moderator!!') + } } ) }) diff --git a/server/models/contests/createContest.js b/server/models/contests/createContest.js index 39ba0fa..e38d6dc 100644 --- a/server/models/contests/createContest.js +++ b/server/models/contests/createContest.js @@ -20,71 +20,74 @@ function createContest({ username, body }) { } = body const startTime = new Date(start_time) const endTime = new Date(end_time) + let about = body.about || null + let rules = body.rules || null + let prizes = body.prizes || null + let confidentialQuestions = body.confidential_questions || null let currentId - pool.query( - `INSERT INTO contests (creator, name, show_leaderboard, public, start_time, end_time, participants_count) VALUES (?,?,?,?,?,?,?)`, - [username, name, showLeaderboard, public, startTime, endTime, 0], - (error, results) => { - if (error || results === undefined) { - return reject(error) + pool.getConnection((error, connection) => { + if (error) { + return reject(error) + } + connection.beginTransaction((error) => { + if (error) { + return connection.rollback(() => { + connection.release() + return reject(error) + }) } - const { insertId } = results - currentId = insertId - pool.query( - `INSERT INTO contests_moderators (contest_id, moderator) VALUES (?,?)`, - [currentId, username], - (error, res) => { - if (error || res === undefined) { - return reject(error) - } - const { - about, - rules, - prizes, - confidential_questions: confidentialQuestions, - } = body - let query = `UPDATE contests SET ` - let arr = [] - if (about) { - query += `about=?,` - arr.push(about) - } - if (rules) { - query += `rules=?,` - arr.push(rules) - } - if (prizes) { - query += `prizes=?,` - arr.push(prizes) - } - if (confidentialQuestions !== undefined) { - query += `confidential_questions=?,` - arr.push(confidentialQuestions) - } - - if (query[query.length - 1] === ',') { - query = query.substr(0, query.length - 1) - } else { - return resolve({ - message: 'Contest created successfully', - contestId: currentId, + connection.query( + `INSERT INTO contests (creator, name, show_leaderboard, public, start_time, end_time, about, rules, prizes, confidential_questions) VALUES (?,?,?,?,?,?,?,?,?,?)`, + [ + username, + name, + showLeaderboard, + public, + startTime, + endTime, + about, + rules, + prizes, + confidentialQuestions, + ], + (error, results) => { + if (error || results === undefined) { + return connection.rollback(() => { + connection.release() + return reject(error) }) } - query += ` WHERE id=?` - arr.push(currentId) - pool.query(query, arr, (error, res) => { - if (error || res === undefined) { - return reject(error) + const { insertId } = results + currentId = insertId + connection.query( + `INSERT INTO contests_moderators (contest_id, moderator) VALUES (?,?)`, + [currentId, username], + (error, insertionResults) => { + if (error || insertionResults === undefined) { + return connection.rollback(() => { + connection.release() + return reject(error) + }) + } + connection.commit((error) => { + if (error) { + return connection.rollback(() => { + connection.release() + return reject(error) + }) + } + connection.release() + return resolve({ + message: 'Contest created successfully', + contestId: currentId, + }) + }) } - return resolve({ - message: 'Contest created successfully', - contestId: currentId, - }) - }) + ) } ) - } - ) + }) + }) }) } diff --git a/server/models/contests/removeGroup.js b/server/models/contests/removeGroup.js index 99e32b1..51a3319 100644 --- a/server/models/contests/removeGroup.js +++ b/server/models/contests/removeGroup.js @@ -13,30 +13,19 @@ function removeGroup({ params, body, username }) { const { contest_id: contestId } = params const { group_id: groupId } = body pool.query( - `SELECT * FROM contests_moderators WHERE contest_id=? AND moderator=?`, - [contestId, username], - (error, results) => { - if (error) { + `DELETE FROM contests_groups WHERE (SELECT COUNT(id) FROM contests_moderators WHERE contest_id=? AND moderator=?) AND contest_id=? AND group_id=?`, + [contestId, username, contestId, groupId], + (error, res) => { + if (error || res === undefined) { return reject(error) - } else if (!results || !results.length) { + } + const { affectedRows } = res + if (affectedRows === 0) { return reject( - 'Invalid contest ID or you do not have moderator access to the contest' + 'Either the group is not a part of the contest or you do not have the required permissions' ) } - pool.query( - `DELETE FROM contests_groups WHERE contest_id=? AND group_id=?`, - [contestId, groupId], - (error, res) => { - if (error || res === undefined) { - return reject(error) - } - const { affectedRows } = res - if (affectedRows === 0) { - return reject('The group is not a part of the contest') - } - return resolve('Successfully removed group') - } - ) + return resolve('Successfully removed group') } ) }) diff --git a/server/models/contests/removeModerator.js b/server/models/contests/removeModerator.js index 20a3fd5..c85da0e 100644 --- a/server/models/contests/removeModerator.js +++ b/server/models/contests/removeModerator.js @@ -4,40 +4,28 @@ const { pool } = require('../database') * @param {*} param0 * @param {Object} param0.body * @param {Object} param0.params - * @param {String} param0.username * @return {Promise} */ -function removeModerator({ params, body, username }) { +function removeModerator({ params, body }) { return new Promise((resolve, reject) => { const { contest_id: contestId } = params const { moderator: moderatorUsername } = body pool.query( - `SELECT * FROM contests_moderators WHERE contest_id=? AND moderator=?`, - [contestId, username], - (error, results) => { - if (error) { + `DELETE FROM contests_moderators WHERE contest_id=? AND moderator=? + AND moderator NOT IN (SELECT creator FROM contests WHERE contest_id=?)`, + [contestId, moderatorUsername, contestId], + (error, res) => { + if (error || res === undefined) { return reject(error) - } else if (!results || !results.length) { + } + const { affectedRows } = res + if (!affectedRows) { return reject( - 'Invalid contest ID or you do not have moderator access to the contest' + 'Either the person is already not a moderator or you do not have the required permissions' ) } - pool.query( - `DELETE FROM contests_moderators WHERE contest_id=? AND moderator=? - AND moderator NOT IN (SELECT creator FROM contests WHERE contest_id=?)`, - [contestId, moderatorUsername, contestId], - (error, res) => { - if (error || res === undefined) { - return reject(error) - } - const { affectedRows } = res - if (affectedRows === 0) { - return reject('Either user was a creator or not a moderator') - } - return resolve('Successfully removed as moderator') - } - ) + return resolve('Successfully removed as moderator') } ) }) diff --git a/server/models/contests/updateContest.js b/server/models/contests/updateContest.js index c4a5bc7..d6b8ce5 100644 --- a/server/models/contests/updateContest.js +++ b/server/models/contests/updateContest.js @@ -3,94 +3,84 @@ const { pool } = require('../database') /** * * @param {*} param0 - * @param {String} param0.username * @param {Object} param0.body * @param {Object} param0.params + * @param {String} param0.username * @return {Promise} * */ -function updateContest({ username, body, params }) { +function updateContest({ body, params, username }) { return new Promise((resolve, reject) => { const { name, show_leaderboard: showLeaderboard, public, - start_time, - end_time, + start_time: startTime, + end_time: endTime, about, rules, prizes, confidential_questions: confidentialQuestions, } = body - const startTime = new Date(start_time) - const endTime = new Date(end_time) const { contest_id: contestId } = params - pool.query( - `SELECT * FROM contests_moderators WHERE contest_id=? AND moderator=?`, - [contestId, username], - (error, results) => { - if (error) { - return reject(error) - } else if (!results || !results.length) { - return reject( - 'Invalid contest ID or you do not have moderator access to the contest' - ) - } - let query = `UPDATE contests SET ` - let arr = [] - if (name) { - query += `name=?,` - arr.push(name) - } - if (showLeaderboard !== undefined) { - query += `show_leaderboard=?,` - arr.push(showLeaderboard) - } - if (public !== undefined) { - query += `public=?,` - arr.push(public) - } - if (startTime) { - query += `start_time=?,` - arr.push(startTime) - } - if (endTime) { - query += `end_time=?,` - arr.push(endTime) - } - if (about) { - query += `about=?,` - arr.push(about) - } - if (rules) { - query += `rules=?,` - arr.push(rules) - } - if (prizes) { - query += `prizes=?,` - arr.push(prizes) - } - if (confidentialQuestions !== undefined) { - query += `confidential_questions=?,` - arr.push(confidentialQuestions) - } + let query = `UPDATE contests SET ` + let arr = [] + if (name) { + query += `name=?,` + arr.push(name) + } + if (showLeaderboard !== undefined) { + query += `show_leaderboard=?,` + arr.push(showLeaderboard) + } + if (public !== undefined) { + query += `public=?,` + arr.push(public) + } + if (startTime && !isNaN(Date.parse(startTime))) { + query += `start_time=?,` + arr.push(new Date(startTime)) + } + if (endTime && !isNaN(Date.parse(endTime))) { + query += `end_time=?,` + arr.push(new Date(endTime)) + } + if (about) { + query += `about=?,` + arr.push(about) + } + if (rules) { + query += `rules=?,` + arr.push(rules) + } + if (prizes) { + query += `prizes=?,` + arr.push(prizes) + } + if (confidentialQuestions !== undefined) { + query += `confidential_questions=?,` + arr.push(confidentialQuestions) + } - if (query[query.length - 1] === ',') { - query = query.substr(0, query.length - 1) - } else { - return reject('Contest is already upto date') + if (query[query.length - 1] === ',') { + query = query.substr(0, query.length - 1) + } else { + return reject('Contest is already upto date') + } + query += ` WHERE (SELECT COUNT(id) FROM contests_moderators WHERE contest_id=? AND moderator=? )AND id=?` + arr.push(contestId, username, contestId) + pool.query(query, arr, (error, res) => { + if (error || res === undefined) { + return reject(error) + } else { + const { affectedRows } = res + if (!affectedRows) { + return reject('The user do not have moderator access of the contest') } - query += ` WHERE id=?` - arr.push(contestId) - pool.query(query, arr, (error, res) => { - if (error || res === undefined) { - return reject(error) - } - return resolve('Contest updated successfully') - }) + return resolve('Contest updated successfully') } - ) + }) }) } diff --git a/server/routes/middlewares/index.js b/server/routes/middlewares/index.js index 0920e3c..3276d0c 100644 --- a/server/routes/middlewares/index.js +++ b/server/routes/middlewares/index.js @@ -1,4 +1,5 @@ const verifyUserAccessToken = require('./verifyUser') const verifyAdmin = require('./verifyAdmin') +const verifyContestModerator = require('./verifyContestModerator') -module.exports = { verifyUserAccessToken, verifyAdmin } +module.exports = { verifyUserAccessToken, verifyAdmin, verifyContestModerator } diff --git a/server/routes/middlewares/verifyContestModerator.js b/server/routes/middlewares/verifyContestModerator.js new file mode 100644 index 0000000..d60b0b4 --- /dev/null +++ b/server/routes/middlewares/verifyContestModerator.js @@ -0,0 +1,44 @@ +// Should be used after the middleware 'verifyUserAccessToken' +const { pool } = require('../../models/database') + +/** + * @typedef {import { Request } from "express";} Request + * @typedef {import { Response } from "express";} Response + * @typedef {import { next } from "express";} Next + */ + +/** + * + * @param {Request} request + * @param {Response} response + * @param {Next} next + */ + +function verifyContestModerator(request, response, next) { + const { contest_id: contestId } = request.params + const { username } = request + pool.query( + `SELECT * FROM contests_moderators WHERE contest_id=? AND moderator=?`, + [contestId, username], + (error, results) => { + if (error) { + response.status(401).json({ + success: false, + results: null, + error, + }) + } + if (!results || !results.length) { + response.status(401).json({ + success: false, + results: null, + error: + 'Invalid contest ID or you do not have moderator access to the contest', + }) + } + next() + } + ) +} + +module.exports = verifyContestModerator