diff --git a/backend/endpoints/bonusChallenge/controller/getRandomBonusChallenge.js b/backend/endpoints/bonusChallenge/controller/getRandomBonusChallenge.js index ad67ff4..df5544d 100644 --- a/backend/endpoints/bonusChallenge/controller/getRandomBonusChallenge.js +++ b/backend/endpoints/bonusChallenge/controller/getRandomBonusChallenge.js @@ -9,11 +9,13 @@ module.exports = (db) => { */ return async (req, res) => { try { + // Check to see if the user gets a bonus question if (Math.random() >= 0.4) { return res.status(200).json({ success: true }); } - const bonusChallenge = await db + // Get a random bonus question from the database + const response = await db .collection('bonusChallenge') .aggregate([ { @@ -35,13 +37,14 @@ module.exports = (db) => { })) ); - if (!bonusChallenge) { + // Check if a bonus question was chosen + if (!response) { return res .status(404) .json({ success: false, error: 'No active bonus challenges found' }); } - return res.status(200).json({ success: true, body: bonusChallenge[0] }); + return res.status(200).json({ success: true, body: response[0] }); } catch (error) { return res.status(500).json({ success: false, error: error.message }); } diff --git a/backend/endpoints/checkFocus/controller/getRandomFocus.js b/backend/endpoints/checkFocus/controller/getRandomFocus.js index c5a4857..60f17ed 100644 --- a/backend/endpoints/checkFocus/controller/getRandomFocus.js +++ b/backend/endpoints/checkFocus/controller/getRandomFocus.js @@ -9,10 +9,12 @@ module.exports = (db) => { */ return async (req, res) => { try { + // Check to see if the user gets a focus if (Math.random() >= 0.2) { return res.status(200).json({ success: true, body: null }); } + // Get a random focus from the database const checkFocus = await db .collection('checkFocus') .aggregate([ @@ -35,6 +37,7 @@ module.exports = (db) => { })) ); + // Check if a focus was chosen if (!checkFocus[0]) { return res.status(404).json({ success: false, error: 'No active focuses found' }); } diff --git a/backend/endpoints/checkFocus/route.js b/backend/endpoints/checkFocus/route.js index f319c43..0c7ea87 100644 --- a/backend/endpoints/checkFocus/route.js +++ b/backend/endpoints/checkFocus/route.js @@ -1,5 +1,8 @@ +/** + * @param {import('mongodb').Db} db + */ module.exports = (db) => require('express') .Router() - + // GET .get('/check-focus/random', require('./controller/getRandomFocus')(db)); diff --git a/backend/endpoints/hpc/controller/addHpc.js b/backend/endpoints/hpc/controller/addHpc.js index 930fb0a..7a53325 100644 --- a/backend/endpoints/hpc/controller/addHpc.js +++ b/backend/endpoints/hpc/controller/addHpc.js @@ -11,39 +11,48 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { name } = req.body || {}; + const { name: rawName } = req.body || {}; // Check name - if (!name) { - return res.status(400).json({ success: false, error: 'Missing hpc name' }); + if (rawName === undefined || rawName === null) { + return res.status(400).json({ success: false, error: 'Missing cluster name' }); } - const sanitizedName = String(name).trim(); + if (typeof rawName !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The cluster name provided is not a string' }); + } + + const clusterName = rawName.trim(); - if (sanitizedName.length == 0) { - return res.status(400).json({ success: false, error: 'The name provided is empty' }); + if (!clusterName) { + return res + .status(400) + .json({ success: false, error: 'The cluster name provided is empty' }); } // Check if hpc already exists - const existingHpc = await db.collection('cluster').findOne({ + const existing = await db.collection('cluster').findOne({ name: { - $regex: `^${sanitizedName}$`, + $regex: `^${clusterName}$`, $options: 'i' } }); - if (existingHpc) { - return res.status(409).json({ success: false, error: 'HPC already exits' }); + if (existing) { + return res.status(409).json({ success: false, error: 'Cluster already exits' }); } // Add it to the database const clusterId = await db .collection('cluster') .insertOne({ - name: sanitizedName + name: clusterName }) .then((res) => res.insertedId.toString()); + // Populate the database with generic instructions and methods for the cluster templateIt(clusterId, db); return res.status(200).json({ success: true }); diff --git a/backend/endpoints/hpc/controller/addHpcToPool.js b/backend/endpoints/hpc/controller/addHpcToPool.js index 835d437..7983d84 100644 --- a/backend/endpoints/hpc/controller/addHpcToPool.js +++ b/backend/endpoints/hpc/controller/addHpcToPool.js @@ -11,68 +11,82 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id } = req.params || {}; - const { poolId } = req.body || {}; + const { id: rawClusterId } = req.params || {}; + const { poolId: rawPoolId } = req.body || {}; - // Check id - if (!id) { - return res.status(400).json({ success: false, error: 'Missing cluster id' }); + // Check cluster id + if (rawClusterId === undefined || rawClusterId === null) { + return res.status(400).json({ success: false, error: 'Missing cluster ID' }); } - if (!poolId) { - return res.status(400).json({ success: false, error: 'Missing pool id' }); + if (typeof rawClusterId !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The cluster ID provided is not a string' }); } - const sanitizedId = String(id).trim(); + const clusterId = rawClusterId.trim(); - if (sanitizedId.length === 0) { + if (!clusterId) { return res .status(400) - .json({ success: false, error: 'The cluster id provided is empty' }); + .json({ success: false, error: 'The cluster ID provided is empty' }); + } + + if (!ObjectId.isValid(clusterId)) { + return res.status(400).json({ success: false, error: 'Invalid cluster ID provided' }); } - const sanitizedPoolId = String(poolId).trim(); + // Check pool id + if (rawPoolId === undefined || rawPoolId === null) { + return res.status(400).json({ success: false, error: 'Missing pool ID' }); + } - if (sanitizedPoolId.length === 0) { - return res.status(400).json({ success: false, error: 'The pool id provided is empty' }); + if (typeof rawPoolId !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The pool ID provided is not a string' }); } - if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid cluster id provided' }); + const poolId = rawPoolId.trim(); + + if (!poolId) { + return res.status(400).json({ success: false, error: 'The pool ID provided is empty' }); } - if (!ObjectId.isValid(sanitizedPoolId)) { - return res.status(400).json({ success: false, error: 'Invalid pool id provided' }); + if (!ObjectId.isValid(poolId)) { + return res.status(400).json({ success: false, error: 'Invalid pool ID provided' }); } // Get the cluster - const results = await db.collection('cluster').findOne({ - _id: new ObjectId(sanitizedId) + const cluster = await db.collection('cluster').findOne({ + _id: new ObjectId(clusterId) }); - if (!results) { + if (!cluster) { return res.status(404).json({ success: false, error: "Cluster doesn't exist" }); } - if (results.poolId === sanitizedPoolId) { + if (cluster.poolId === clusterId) { return res .status(400) .json({ success: false, error: 'Cluster already assigned to pool' }); } - const poolResults = await db.collection('pool').findOne({ - _id: new ObjectId(sanitizedPoolId) + // Get pool + const pool = await db.collection('pool').findOne({ + _id: new ObjectId(poolId) }); - if (!poolResults) { + if (!pool) { return res.status(404).json({ success: false, error: "Pool doesn't exist" }); } db.collection('cluster').updateOne( - { _id: new ObjectId(sanitizedId) }, + { _id: new ObjectId(clusterId) }, { $set: { - poolId: sanitizedPoolId + poolId: poolId } } ); @@ -80,9 +94,9 @@ module.exports = (db) => { return res.status(200).json({ success: true, body: { - id: sanitizedId, - name: results.name, - poolId: sanitizedPoolId + id: clusterId, + name: cluster.name, + poolId: poolId } }); } catch (error) { diff --git a/backend/endpoints/hpc/controller/deleteHpc.js b/backend/endpoints/hpc/controller/deleteHpc.js index bba09a4..fcce06d 100644 --- a/backend/endpoints/hpc/controller/deleteHpc.js +++ b/backend/endpoints/hpc/controller/deleteHpc.js @@ -11,31 +11,37 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id } = req.params; + const { id: rawClusterId } = req.params; - // Check id - if (!id) { - return res.status(400).json({ success: false, error: 'Missing hpc id' }); + // Check cluster id + if (rawClusterId === undefined || rawClusterId === null) { + return res.status(400).json({ success: false, error: 'Missing cluster ID' }); } - const sanitizedId = String(id).trim(); + if (typeof rawClusterId !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The cluster ID provided is not a string' }); + } + + const clusterId = rawClusterId.trim(); - if (sanitizedId.length === 0) { + if (!clusterId) { return res .status(400) - .json({ success: false, error: "The hpc id you've provided is empty" }); + .json({ success: false, error: 'The cluster ID provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid cluster id provided' }); + if (!ObjectId.isValid(clusterId)) { + return res.status(400).json({ success: false, error: 'Invalid cluster ID provided' }); } - // Check cluster exists - const existingCluster = await db.collection('cluster').findOneAndDelete({ - _id: new ObjectId(sanitizedId) + // Get cluster + const cluster = await db.collection('cluster').findOneAndDelete({ + _id: new ObjectId(clusterId) }); - if (!existingCluster) { + if (!cluster) { return res.status(409).json({ success: false, error: "HPC doesn't exists" @@ -46,7 +52,7 @@ module.exports = (db) => { const reports = await db .collection('report') .find({ - clusterId: sanitizedId + clusterId: clusterId }) .toArray() .then((res) => @@ -74,7 +80,7 @@ module.exports = (db) => { const instructions = await db .collection('instruction') .find({ - clusterId: new ObjectId(sanitizedId) + clusterId: new ObjectId(clusterId) }) .toArray() .then((res) => diff --git a/backend/endpoints/hpc/controller/getHpcById.js b/backend/endpoints/hpc/controller/getHpcById.js index 6755c5b..218970b 100644 --- a/backend/endpoints/hpc/controller/getHpcById.js +++ b/backend/endpoints/hpc/controller/getHpcById.js @@ -11,41 +11,41 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id } = req.params || {}; + const { id: rawClusterId } = req.params || {}; - // Check id - if (typeof id !== 'string') { - return res - .status(400) - .json({ success: false, error: 'The cluster id provided is not a string' }); + // Check cluster id + if (rawClusterId === undefined || rawClusterId === null) { + return res.status(400).json({ success: false, error: 'Missing cluster ID' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing cluster id' }); + if (typeof rawClusterId !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The cluster ID provided is not a string' }); } - const sanitizedId = String(id).trim(); + const clusterId = rawClusterId.trim(); - if (sanitizedId.length === 0) { + if (!clusterId) { return res .status(400) - .json({ success: false, error: 'The cluster id provided is empty' }); + .json({ success: false, error: 'The cluster ID provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid cluster id provided' }); + if (!ObjectId.isValid(clusterId)) { + return res.status(400).json({ success: false, error: 'Invalid cluster ID provided' }); } // Get the cluster const response = await db.collection('cluster').findOne({ - _id: new ObjectId(sanitizedId) + _id: new ObjectId(clusterId) }); if (!response) { return res.status(404).json({ success: false, error: "Cluster doesn't exist" }); } - response.id = sanitizedId; + response.id = clusterId; delete response._id; return res.status(200).json({ diff --git a/backend/endpoints/hpc/controller/getHpcByName.js b/backend/endpoints/hpc/controller/getHpcByName.js index 938c954..6ac78bb 100644 --- a/backend/endpoints/hpc/controller/getHpcByName.js +++ b/backend/endpoints/hpc/controller/getHpcByName.js @@ -9,29 +9,29 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { name } = req.params || {}; + const { name: rawName } = req.params || {}; // Check name - if (typeof name !== 'string') { - return res - .status(400) - .json({ success: false, error: 'The name provided is not a string' }); + if (rawName === undefined || rawName === null) { + return res.status(400).json({ success: false, error: 'Missing cluster name' }); } - if (!name) { - return res.status(400).json({ success: false, error: 'Missing cluster name' }); + if (typeof rawName !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The cluster name provided is not a string' }); } - const sanitizedName = String(name).trim(); + const name = rawName.trim(); - if (sanitizedName.length == 0) { + if (!name) { return res.status(400).json({ success: false, error: 'The name provided is empty' }); } // Get the cluster const response = await db.collection('cluster').findOne({ name: { - $regex: `^${sanitizedName}$`, + $regex: `^${name}$`, $options: 'i' } }); diff --git a/backend/endpoints/hpc/controller/getHpcByPool.js b/backend/endpoints/hpc/controller/getHpcByPool.js index c267562..2dadc54 100644 --- a/backend/endpoints/hpc/controller/getHpcByPool.js +++ b/backend/endpoints/hpc/controller/getHpcByPool.js @@ -11,27 +11,34 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id } = req.params || {}; + const { id: rawPoolId } = req.params || {}; - if (!id) { - return res.status(400).json({ success: false, error: 'Missing pool id' }); + // Check pool id + if (rawPoolId === undefined || rawPoolId === null) { + return res.status(400).json({ success: false, error: 'Missing pool ID' }); } - const sanitizedId = String(id).trim(); + if (typeof rawPoolId !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The pool ID provided is not a string' }); + } + + const poolId = rawPoolId.trim(); - if (sanitizedId.length === 0) { - return res.status(400).json({ success: false, error: 'The pool id provided is empty' }); + if (poolId.length === 0) { + return res.status(400).json({ success: false, error: 'The pool ID provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid pool id provided' }); + if (!ObjectId.isValid(poolId)) { + return res.status(400).json({ success: false, error: 'Invalid pool ID provided' }); } // Get the cluster - const data = await db + const response = await db .collection('cluster') .find({ - poolId: sanitizedId + poolId: poolId }) .toArray() .then((res) => @@ -41,7 +48,7 @@ module.exports = (db) => { })) ); - return res.status(200).json({ success: true, body: data }); + return res.status(200).json({ success: true, body: response }); } catch (error) { return res.status(500).json({ success: false, error: error.message }); } diff --git a/backend/endpoints/hpc/controller/getHpcNotInPool.js b/backend/endpoints/hpc/controller/getHpcNotInPool.js index 3714368..e36a5cf 100644 --- a/backend/endpoints/hpc/controller/getHpcNotInPool.js +++ b/backend/endpoints/hpc/controller/getHpcNotInPool.js @@ -11,34 +11,34 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id } = req.params || {}; + const { id: rawPoolId } = req.params || {}; - // Check id - if (typeof id !== 'string') { - return res - .status(400) - .json({ success: false, error: 'The team id provided is not a string' }); + // Check pool id + if (rawPoolId === undefined || rawPoolId === null) { + return res.status(400).json({ success: false, error: 'Missing pool id' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing pool id' }); + if (typeof rawPoolId !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The pool id provided is not a string' }); } - const sanitizedId = String(id).trim(); + const poolId = String(rawPoolId).trim(); - if (sanitizedId.length === 0) { + if (poolId.length === 0) { return res.status(400).json({ success: false, error: 'The pool id provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { + if (!ObjectId.isValid(poolId)) { return res.status(400).json({ success: false, error: 'Invalid pool id provided' }); } // Get the cluster - const data = await db + const response = await db .collection('cluster') .find({ - poolId: { $ne: sanitizedId } + poolId: { $ne: poolId } }) .toArray() .then((res) => @@ -48,7 +48,7 @@ module.exports = (db) => { })) ); - return res.status(200).json({ success: true, body: data }); + return res.status(200).json({ success: true, body: response }); } catch (error) { return res.status(500).json({ success: false, error: error.message }); } diff --git a/backend/endpoints/hpc/controller/removeHpcFromPool.js b/backend/endpoints/hpc/controller/removeHpcFromPool.js index b0b041f..f399609 100644 --- a/backend/endpoints/hpc/controller/removeHpcFromPool.js +++ b/backend/endpoints/hpc/controller/removeHpcFromPool.js @@ -11,63 +11,78 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id } = req.params || {}; - const { poolId } = req.body || {}; + const { id: rawClusterId } = req.params || {}; + const { poolId: rawPoolId } = req.body || {}; // Check id - if (!id) { + if (rawClusterId === undefined || rawClusterId === null) { return res.status(400).json({ success: false, error: 'Missing cluster id' }); } - if (!poolId) { - return res.status(400).json({ success: false, error: 'Missing pool id' }); + if (typeof rawClusterId !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The cluster id provided is not a string' }); } - const sanitizedId = String(id).trim(); + const clusterId = rawClusterId.trim(); - if (sanitizedId.length === 0) { + if (!clusterId) { return res .status(400) .json({ success: false, error: 'The cluster id provided is empty' }); } - const sanitizedPoolId = String(poolId).trim(); + if (!ObjectId.isValid(clusterId)) { + return res.status(400).json({ success: false, error: 'Invalid cluster id provided' }); + } - if (sanitizedPoolId.length === 0) { - return res.status(400).json({ success: false, error: 'The pool id provided is empty' }); + // Check pool id + if (rawPoolId === undefined || rawPoolId === null) { + return res.status(400).json({ success: false, error: 'Missing pool id' }); } - if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid cluster id provided' }); + if (typeof rawPoolId !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The pool id provided is not a string' }); + } + + const poolId = rawPoolId.trim(); + + if (!poolId) { + return res.status(400).json({ success: false, error: 'The pool id provided is empty' }); } - if (!ObjectId.isValid(sanitizedPoolId)) { + if (!ObjectId.isValid(poolId)) { return res.status(400).json({ success: false, error: 'Invalid pool id provided' }); } // Get the cluster - const results = await db.collection('cluster').findOne({ - _id: new ObjectId(sanitizedId) + const cluster = await db.collection('cluster').findOne({ + _id: new ObjectId(clusterId) }); - if (!results) { + if (!cluster) { return res.status(404).json({ success: false, error: "Cluster doesn't exist" }); } - const poolResults = await db.collection('pool').findOne({ - _id: new ObjectId(sanitizedPoolId) + // Get the pool + const pool = await db.collection('pool').findOne({ + _id: new ObjectId(poolId) }); - if (!poolResults) { + if (!pool) { return res.status(404).json({ success: false, error: "Pool doesn't exist" }); } - if (!results.poolId === sanitizedPoolId) { + if (!cluster.poolId === poolId) { return res.status(400).json({ success: false, error: 'Cluster not assigned to pool' }); } + // Update database db.collection('cluster').updateOne( - { _id: new ObjectId(sanitizedId) }, + { _id: new ObjectId(clusterId) }, { $unset: { poolId: '' @@ -78,8 +93,8 @@ module.exports = (db) => { return res.status(200).json({ success: true, body: { - id: sanitizedId, - name: results.name + id: clusterId, + name: cluster.name } }); } catch (error) { diff --git a/backend/endpoints/instruction/controller/addInstruction.js b/backend/endpoints/instruction/controller/addInstruction.js index d389f75..14cc23a 100644 --- a/backend/endpoints/instruction/controller/addInstruction.js +++ b/backend/endpoints/instruction/controller/addInstruction.js @@ -11,131 +11,135 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { title, expectedTime, description, clusterId, good, bad } = req.body || {}; + const { + title: rawTitle, + expectedTime: rawExpectedTime, + description: rawDescription, + clusterId: rawClusterId, + good: rawGood, + bad: rawBad + } = req.body || {}; + + console.log(req.body); // Check title - if (typeof title !== 'string') { + if (rawTitle === undefined || rawTitle === null) { + return res.status(400).json({ success: false, error: 'Missing instruction title' }); + } + + if (typeof rawTitle !== 'string') { return res .status(400) .json({ success: false, error: 'The title provided is not a string' }); } - if (!title) { - return res.status(400).json({ success: false, error: 'Missing instruction title' }); - } - - const sanitizedTitle = String(title).trim(); + const title = rawTitle.trim(); - if (sanitizedTitle.length == 0) { + if (!title) { return res.status(400).json({ success: false, error: 'The title provided is empty' }); } // Check expected time - if (typeof expectedTime !== 'string') { + if (rawExpectedTime === undefined || rawExpectedTime === null) { + return res.status(400).json({ success: false, error: 'Missing expected time' }); + } + + if (typeof rawExpectedTime !== 'string') { return res .status(400) .json({ success: false, error: 'The expected time provided is not a string' }); } - if (!expectedTime) { - return res.status(400).json({ success: false, error: 'Missing expected time' }); - } + const expectedTime = rawExpectedTime.trim(); - const sanitizedExpectedTime = String(expectedTime).trim(); - - if (sanitizedExpectedTime.length == 0) { + if (!expectedTime) { return res .status(400) .json({ success: false, error: 'The expected time provided is empty' }); } // Check description - if (typeof description !== 'string') { + if (rawDescription === undefined || rawDescription === null) { + return res.status(400).json({ success: false, error: 'Missing description' }); + } + + if (typeof rawDescription !== 'string') { return res .status(400) .json({ success: false, error: 'The description provided is not a string' }); } - if (!description) { - return res.status(400).json({ success: false, error: 'Missing description' }); - } - - const sanitizedDescription = String(description).trim(); + const description = rawDescription.trim(); - if (sanitizedDescription.length == 0) { + if (!description) { return res .status(400) .json({ success: false, error: 'The descriptions provided is empty' }); } // Check cluster id - if (typeof clusterId !== 'string') { + if (rawClusterId === undefined || rawClusterId === null) { + return res.status(400).json({ success: false, error: 'Missing cluster id' }); + } + + if (typeof rawClusterId !== 'string') { return res .status(400) .json({ success: false, error: 'The cluster id provided is not a string' }); } - if (!clusterId) { - return res.status(400).json({ success: false, error: 'Missing cluster id' }); - } - - const sanitizedClusterId = String(clusterId).trim(); + const clusterId = rawClusterId.trim(); - if (sanitizedClusterId.length == 0) { + if (!clusterId) { return res .status(400) .json({ success: false, error: 'The cluster id provided is empty' }); } - if (!ObjectId.isValid(sanitizedClusterId)) { + if (!ObjectId.isValid(clusterId)) { return res.status(400).json({ success: false, error: 'Invalid cluster id provided' }); } // Check good - if (typeof good !== 'string') { + if (rawGood === undefined || rawGood === null) { + return res.status(400).json({ success: false, error: 'Missing good' }); + } + + if (typeof rawGood !== 'string') { return res .status(400) .json({ success: false, error: 'The good provided is not a string' }); } - if (!good) { - return res.status(400).json({ success: false, error: 'Missing instruction title' }); - } + const good = rawGood.trim(); - const sanitizedGood = String(good).trim(); - - if (sanitizedGood.length == 0) { + if (!good) { return res.status(400).json({ success: false, error: 'The good provided is empty' }); } // Check bad - if (typeof bad !== 'string') { + if (rawBad === undefined || rawBad === null) { + return res.status(400).json({ success: false, error: 'Missing bad' }); + } + + if (typeof rawBad !== 'string') { return res .status(400) .json({ success: false, error: 'The bad provided is not a string' }); } - if (!bad) { - return res.status(400).json({ success: false, error: 'Missing instruction title' }); - } + const bad = rawBad.trim(); - const sanitizedBad = String(bad).trim(); - - if (sanitizedBad.length == 0) { + if (bad.length == 0) { return res.status(400).json({ success: false, error: 'The bad provided is empty' }); } - // Get new instructions position - const currentTotalInstructions = await db - .collection('instruction') - .countDocuments({ clusterId: sanitizedClusterId }); - - // Check if cluster exists - const clusterExists = await db.collection('cluster').findOne({ - _id: new ObjectId(sanitizedClusterId) + // Get cluster + const cluster = await db.collection('cluster').findOne({ + _id: new ObjectId(clusterId) }); - if (!clusterExists) { + if (!cluster) { return res .status(404) .json({ success: false, error: 'The cluster specified does not exits' }); @@ -143,13 +147,14 @@ module.exports = (db) => { // Add to database await db.collection('instruction').insertOne({ - title: sanitizedTitle, - expectedTime: sanitizedExpectedTime, - description: sanitizedDescription, - clusterId: sanitizedClusterId, - good: sanitizedGood, - bad: sanitizedBad, - position: currentTotalInstructions + 1 + title: title, + expectedTime: expectedTime, + description: description, + clusterId: clusterId, + good: good, + bad: bad, + position: + (await db.collection('instruction').countDocuments({ clusterId: clusterId })) + 1 }); return res.status(200).json({ success: true }); diff --git a/backend/endpoints/instruction/controller/deleteInstruction.js b/backend/endpoints/instruction/controller/deleteInstruction.js index 9ff9b09..03c5318 100644 --- a/backend/endpoints/instruction/controller/deleteInstruction.js +++ b/backend/endpoints/instruction/controller/deleteInstruction.js @@ -11,38 +11,36 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id } = req.params; + const { id: rawInstructionId } = req.params; - // Check id - if (typeof id !== 'string') { - return res - .status(400) - .json({ success: false, error: 'The instruction id provided is not a string' }); + // Check instruction id + if (rawInstructionId === undefined || rawInstructionId === null) { + return res.status(400).json({ success: false, error: 'Missing instruction ID' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing instruction id' }); + if (typeof rawInstructionId !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The instruction ID provided is not a string' }); } - const sanitizedId = String(id).trim(); + const instructionId = rawInstructionId.trim(); - if (sanitizedId.length == 0) { - return res.status(400).json({ success: false, error: 'The id provided is empty' }); + if (!instructionId) { + return res.status(400).json({ success: false, error: 'The ID provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'The id provided is invalid' }); + if (!ObjectId.isValid(instructionId)) { + return res.status(400).json({ success: false, error: 'The ID provided is invalid' }); } // Delete instruction await db.collection('instruction').deleteOne({ - _id: new ObjectId(sanitizedId) + _id: new ObjectId(instructionId) }); // Delete all the methods associated with the instruction - await db.collection('method').deleteMany({ - instructionId: sanitizedId - }); + await db.collection('method').deleteMany({ instructionId }); return res.status(200).json({ success: true }); } catch (error) { diff --git a/backend/endpoints/instruction/controller/getAllInstructionsData.js b/backend/endpoints/instruction/controller/getAllInstructionsData.js index 9b162ad..2e6babf 100644 --- a/backend/endpoints/instruction/controller/getAllInstructionsData.js +++ b/backend/endpoints/instruction/controller/getAllInstructionsData.js @@ -11,29 +11,29 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id } = req.params || {}; + const { id: rawClusterId } = req.params || {}; - // Check id - if (typeof id !== 'string') { - return res - .status(400) - .json({ success: false, error: 'The cluster id provided is not a string' }); + // Check cluster id + if (rawClusterId === undefined || rawClusterId === null) { + return res.status(400).json({ success: false, error: 'Missing cluster ID' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing cluster id' }); + if (typeof rawClusterId !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The cluster ID provided is not a string' }); } - const sanitizedId = String(id).trim(); + const clusterId = rawClusterId.trim(); - if (sanitizedId.length === 0) { + if (!clusterId) { return res .status(400) - .json({ success: false, error: 'The cluster id provided is empty' }); + .json({ success: false, error: 'The cluster ID provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid cluster id provided' }); + if (!ObjectId.isValid(clusterId)) { + return res.status(400).json({ success: false, error: 'Invalid cluster ID provided' }); } const response = []; @@ -41,9 +41,7 @@ module.exports = (db) => { // Get all the instructions const instructions = await db .collection('instruction') - .find({ - clusterId: sanitizedId - }) + .find({ clusterId }) .toArray() .then((res) => res.map(({ _id, ...rest }) => ({ @@ -73,7 +71,6 @@ module.exports = (db) => { const methodData = m; methodData.id = m.id; delete methodData._id; - i.methods.push(methodData); }); diff --git a/backend/endpoints/instruction/controller/getAllInstructionsOnly.js b/backend/endpoints/instruction/controller/getAllInstructionsOnly.js index 9953088..c04ac1c 100644 --- a/backend/endpoints/instruction/controller/getAllInstructionsOnly.js +++ b/backend/endpoints/instruction/controller/getAllInstructionsOnly.js @@ -11,48 +11,47 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id } = req.params || {}; + const { id: rawClusterId } = req.params || {}; - // Check id - if (typeof id !== 'string') { - return res - .status(400) - .json({ success: false, error: 'The cluster id provided is not a string' }); + // Check cluster id + if (rawClusterId === undefined || rawClusterId === null) { + return res.status(400).json({ success: false, error: 'Missing cluster ID' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing cluster id' }); + if (typeof rawClusterId !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The cluster ID provided is not a string' }); } - const sanitizedId = String(id).trim(); + const clusterId = rawClusterId.trim(); - if (sanitizedId.length === 0) { + if (!clusterId) { return res .status(400) - .json({ success: false, error: 'The cluster id provided is empty' }); + .json({ success: false, error: 'The cluster Id provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid cluster id provided' }); + if (!ObjectId.isValid(clusterId)) { + return res.status(400).json({ success: false, error: 'Invalid cluster ID provided' }); } // Get all the instructions - const response = await db - .collection('instruction') - .find({ - clusterId: sanitizedId - }) - .toArray() - .then((res) => - res.map(({ _id, ...rest }) => ({ - id: _id.toString(), - ...rest - })) - ); - - return res - .status(200) - .json({ success: true, body: response.sort((a, b) => a.position - b.position) }); + return res.status(200).json({ + success: true, + body: await db + .collection('instruction') + .find({ clusterId }) + .toArray() + .then((res) => + res + .map(({ _id, ...rest }) => ({ + id: _id.toString(), + ...rest + })) + .sort((a, b) => a.position - b.position) + ) + }); } catch (error) { return res.status(500).json({ success: false, error: error.message }); } diff --git a/backend/endpoints/instruction/controller/getInstructionsAllById.js b/backend/endpoints/instruction/controller/getInstructionsAllById.js index 5712774..acb114a 100644 --- a/backend/endpoints/instruction/controller/getInstructionsAllById.js +++ b/backend/endpoints/instruction/controller/getInstructionsAllById.js @@ -11,28 +11,28 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id } = req.params || {}; + const { id: rawInstructionId } = req.params || {}; - // Check id - if (typeof id !== 'string') { + // Check instruction id + if (rawInstructionId === undefined || rawInstructionId === null) { + return res.status(400).json({ success: false, error: 'Missing instruction id' }); + } + + if (typeof rawInstructionId !== 'string') { return res .status(400) .json({ success: false, error: 'The instruction id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing instruction id' }); - } + const instructionId = rawInstructionId.trim(); - const sanitizedId = String(id).trim(); - - if (sanitizedId.length === 0) { + if (!instructionId) { return res .status(400) .json({ success: false, error: 'The instruction id provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { + if (!ObjectId.isValid(instructionId)) { return res .status(400) .json({ success: false, error: 'Invalid instruction id provided' }); @@ -40,7 +40,7 @@ module.exports = (db) => { // Get the instruction const response = await db.collection('instruction').findOne({ - _id: new ObjectId(sanitizedId) + _id: new ObjectId(instructionId) }); if (!response) { @@ -52,27 +52,25 @@ module.exports = (db) => { response.methods = []; // Get methods for the instruction - const methods = await db + await db .collection('method') - .find({ - instructionId: response.id - }) + .find({ instructionId }) .toArray() - .then((result) => - result.map(({ _id, ...rest }) => ({ + .then((res) => + res.map(({ _id, ...rest }) => ({ id: _id.toString(), ...rest })) + ) + .then((res) => + res.forEach((m) => { + const methodData = m; + methodData.id = m.id; + delete methodData._id; + response.methods.push(methodData); + }) ); - methods.forEach((m) => { - const methodData = m; - methodData.id = m.id; - delete methodData._id; - - response.methods.push(methodData); - }); - return res .status(200) .json({ success: true, body: response.sort((a, b) => a.position - b.position) }); diff --git a/backend/endpoints/instruction/controller/getInstructionsOnlyById.js b/backend/endpoints/instruction/controller/getInstructionsOnlyById.js index 3b787da..327b581 100644 --- a/backend/endpoints/instruction/controller/getInstructionsOnlyById.js +++ b/backend/endpoints/instruction/controller/getInstructionsOnlyById.js @@ -11,28 +11,28 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id } = req.params || {}; + const { id: rawInstructionId } = req.params || {}; - // Check id - if (typeof id !== 'string') { + // Check instruction id + if (rawInstructionId === undefined || rawInstructionId === null) { + return res.status(400).json({ success: false, error: 'Missing instruction id' }); + } + + if (typeof rawInstructionId !== 'string') { return res .status(400) .json({ success: false, error: 'The instruction id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing instruction id' }); - } - - const sanitizedId = String(id).trim(); + const instructionId = rawInstructionId.trim(); - if (sanitizedId.length === 0) { + if (!instructionId) { return res .status(400) .json({ success: false, error: 'The instruction id provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { + if (!ObjectId.isValid(instructionId)) { return res .status(400) .json({ success: false, error: 'Invalid instruction id provided' }); @@ -40,7 +40,7 @@ module.exports = (db) => { // Get instruction const response = await db.collection('instruction').findOne({ - _id: new ObjectId(sanitizedId) + _id: new ObjectId(instructionId) }); if (!response) { diff --git a/backend/endpoints/instruction/controller/updateInstruction.js b/backend/endpoints/instruction/controller/updateInstruction.js index ca93935..2eeb7bd 100644 --- a/backend/endpoints/instruction/controller/updateInstruction.js +++ b/backend/endpoints/instruction/controller/updateInstruction.js @@ -11,27 +11,31 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id, ...rest } = req.body || {}; + const { id: rawInstructionId, ...rest } = req.body || {}; - // Check id - if (typeof id !== 'string') { - return res - .status(400) - .json({ success: false, error: 'The instruction provided is not a string' }); + // Check instruction id + if (rawInstructionId === undefined || rawInstructionId === null) { + return res.status(400).json({ success: false, error: 'Missing instruction ID' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing instruction id' }); + if (typeof rawInstructionId !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The instruction ID provided is not a string' }); } - const sanitizedId = String(id).trim(); + const instructionId = rawInstructionId.trim(); - if (sanitizedId.length == 0) { - return res.status(400).json({ success: false, error: 'The id provided is empty' }); + if (!instructionId) { + return res + .status(400) + .json({ success: false, error: 'The instruction ID provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'The id provided is invalid' }); + if (!ObjectId.isValid(instructionId)) { + return res + .status(400) + .json({ success: false, error: 'The instruction ID provided is invalid' }); } // Check updates @@ -48,7 +52,7 @@ module.exports = (db) => { // Check instruction exists const instructionExists = await db .collection('instruction') - .findOne({ _id: new ObjectId(sanitizedId) }); + .findOne({ _id: new ObjectId(instructionId) }); if (!instructionExists) { return res .status(404) @@ -71,7 +75,7 @@ module.exports = (db) => { .json({ success: false, error: 'The new instruction position is invalid' }); } - instructions = instructions.filter((i) => !i._id.equals(new ObjectId(id))); + instructions = instructions.filter((i) => !i._id.equals(new ObjectId(instructionId))); instructions.splice(updates.position - 1, 0, instructionExists); await db.collection('instruction').bulkWrite( @@ -86,12 +90,9 @@ module.exports = (db) => { ); } - if (updates.length > 0) { - // Do not remove this if the database validation will fail - await db - .collection('instruction') - .updateOne({ _id: new ObjectId(sanitizedId) }, { $set: updates }); - } + await db + .collection('instruction') + .updateOne({ _id: new ObjectId(instructionId) }, { $set: updates }); return res.status(200).json({ success: true }); } catch (error) { diff --git a/backend/endpoints/method/controller/addMethod.js b/backend/endpoints/method/controller/addMethod.js index 27a35e2..21946e1 100644 --- a/backend/endpoints/method/controller/addMethod.js +++ b/backend/endpoints/method/controller/addMethod.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id, content } = req.body || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing instruction id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The instruction id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing instruction id' }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { diff --git a/backend/endpoints/method/controller/deleteMethod.js b/backend/endpoints/method/controller/deleteMethod.js index 04597fb..3016dfd 100644 --- a/backend/endpoints/method/controller/deleteMethod.js +++ b/backend/endpoints/method/controller/deleteMethod.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id } = req.params; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing method id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The method id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing method id' }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { diff --git a/backend/endpoints/method/controller/getMethodById.js b/backend/endpoints/method/controller/getMethodById.js index e8c4903..93eb706 100644 --- a/backend/endpoints/method/controller/getMethodById.js +++ b/backend/endpoints/method/controller/getMethodById.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id } = req.params || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing method id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The method id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing method id' }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { diff --git a/backend/endpoints/method/controller/getMethods.js b/backend/endpoints/method/controller/getMethods.js index d07953f..5b80c8b 100644 --- a/backend/endpoints/method/controller/getMethods.js +++ b/backend/endpoints/method/controller/getMethods.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id } = req.params || {}; // check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing instruction id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The instruction id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing instruction id' }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { diff --git a/backend/endpoints/method/controller/updateMethod.js b/backend/endpoints/method/controller/updateMethod.js index 5ec5a9c..2ec7b3a 100644 --- a/backend/endpoints/method/controller/updateMethod.js +++ b/backend/endpoints/method/controller/updateMethod.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id, content } = req.body; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing method id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The method id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing method id' }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { @@ -37,16 +37,16 @@ module.exports = (db) => { } // Check content + if (!content) { + return res.status(400).json({ success: false, error: 'Missing method content' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The content provided is not a string' }); } - if (!content) { - return res.status(400).json({ success: false, error: 'Missing method content' }); - } - const sanitizedContent = String(content).trim(); if (sanitizedContent.length == 0) { diff --git a/backend/endpoints/people/controller/addPeople.js b/backend/endpoints/people/controller/addPeople.js index f61d369..97606fb 100644 --- a/backend/endpoints/people/controller/addPeople.js +++ b/backend/endpoints/people/controller/addPeople.js @@ -12,16 +12,16 @@ module.exports = (db) => { const { name } = req.body || {}; // Check name + if (!name) { + return res.status(400).json({ success: false, error: 'Missing the persons name' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The name provided is not a string' }); } - if (!name) { - return res.status(400).json({ success: false, error: 'Missing the persons name' }); - } - const sanitizedName = String(name).trim(); if (sanitizedName.length === 0) { @@ -29,14 +29,14 @@ module.exports = (db) => { } // Make sure the person exists - const existingPerson = await db.collection('person').findOne({ + const person = await db.collection('person').findOne({ name: { $regex: `^${sanitizedName}$`, $options: 'i' } }); - if (existingPerson) { + if (person) { return res.status(409).json({ success: false, error: 'Person already exits' }); } diff --git a/backend/endpoints/people/controller/addPeopleToTeam.js b/backend/endpoints/people/controller/addPeopleToTeam.js index 4739e38..0750227 100644 --- a/backend/endpoints/people/controller/addPeopleToTeam.js +++ b/backend/endpoints/people/controller/addPeopleToTeam.js @@ -15,16 +15,16 @@ module.exports = (db) => { const { teamId } = req.body || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: "Missing person's id" }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The persons id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: "Missing person's id" }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { @@ -38,16 +38,16 @@ module.exports = (db) => { } // Check team id + if (!teamId) { + return res.status(400).json({ success: false, error: "Missing team's id" }); + } + if (typeof teamId !== 'string') { return res .status(400) .json({ success: false, error: 'The team id provided is not a string' }); } - if (!teamId) { - return res.status(400).json({ success: false, error: "Missing team's id" }); - } - const sanitizedTeamId = String(teamId).trim(); if (sanitizedTeamId.length === 0) { @@ -61,18 +61,18 @@ module.exports = (db) => { } // Check if the person exists - const personExists = await db.collection('person').findOne({ + const person = await db.collection('person').findOne({ _id: new ObjectId(sanitizedId) }); - if (!personExists) { + if (!person) { return res.status(404).json({ success: false, error: "Person doesn't exist" }); } // Check if clusters current team wont be left without clusters - if (personExists.teamId) { + if (person.teamId) { const cluster_count = await db.collection('cluster').countDocuments({ - teamId: personExists.teamId + teamId: person.teamId }); if (cluster_count <= 1) { diff --git a/backend/endpoints/people/controller/deletePeople.js b/backend/endpoints/people/controller/deletePeople.js index fa31fa0..67e81f2 100644 --- a/backend/endpoints/people/controller/deletePeople.js +++ b/backend/endpoints/people/controller/deletePeople.js @@ -18,6 +18,12 @@ module.exports = (db) => { return res.status(400).json({ success: false, error: 'Missing persons id' }); } + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The persons id provided is not a string' }); + } + if (!ObjectId.isValid(id)) { return res.status(400).json({ success: false, error: 'Invalid person id provided' }); } diff --git a/backend/endpoints/people/controller/getPeopleById.js b/backend/endpoints/people/controller/getPeopleById.js index 6bc9be3..2c94f18 100644 --- a/backend/endpoints/people/controller/getPeopleById.js +++ b/backend/endpoints/people/controller/getPeopleById.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id } = req.params || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing persons id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The persons id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing persons id' }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { diff --git a/backend/endpoints/people/controller/getPeopleByName.js b/backend/endpoints/people/controller/getPeopleByName.js index 3a20342..3ad0788 100644 --- a/backend/endpoints/people/controller/getPeopleByName.js +++ b/backend/endpoints/people/controller/getPeopleByName.js @@ -12,16 +12,16 @@ module.exports = (db) => { const { name } = req.params || {}; // Check name + if (!name) { + return res.status(400).json({ success: false, error: 'Missing persons name' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The persons name provided is not a string' }); } - if (!name) { - return res.status(400).json({ success: false, error: 'Missing persons name' }); - } - const sanitizedName = String(name).trim(); if (sanitizedName.length == 0) { diff --git a/backend/endpoints/people/controller/getPeopleByTeam.js b/backend/endpoints/people/controller/getPeopleByTeam.js index ebe6760..393c2bf 100644 --- a/backend/endpoints/people/controller/getPeopleByTeam.js +++ b/backend/endpoints/people/controller/getPeopleByTeam.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id } = req.params || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing team id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The team id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing team id' }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { diff --git a/backend/endpoints/people/controller/getPeopleNotInTeam.js b/backend/endpoints/people/controller/getPeopleNotInTeam.js index 09189f0..b724cb8 100644 --- a/backend/endpoints/people/controller/getPeopleNotInTeam.js +++ b/backend/endpoints/people/controller/getPeopleNotInTeam.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id } = req.params || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing team id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The team id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing team id' }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { diff --git a/backend/endpoints/pool/controller/addPoolToTeam.js b/backend/endpoints/pool/controller/addPoolToTeam.js index 3fc03f3..1c31072 100644 --- a/backend/endpoints/pool/controller/addPoolToTeam.js +++ b/backend/endpoints/pool/controller/addPoolToTeam.js @@ -14,53 +14,75 @@ module.exports = (db) => { const { teamId } = req.body || {}; const { id } = req.params || {}; + // Check id if (!id) { return res.status(400).json({ success: false, error: 'missing pool ID' }); } - if (!teamId) { - return res.status(400).json({ success: false, error: 'missing team ID' }); + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The pool ID provided is not a string' }); } const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { - return res.status(400).json({ success: false, error: 'The pool id provided is empty' }); + return res.status(400).json({ success: false, error: 'The pool ID provided is empty' }); + } + + if (!ObjectId.isValid(sanitizedId)) { + return res.status(400).json({ success: false, error: 'Invalid pool ID provided' }); + } + + // Check team id + if (!teamId) { + return res.status(400).json({ success: false, error: 'missing team ID' }); + } + + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The team ID provided is not a string' }); } const sanitizedTeamId = String(teamId).trim(); if (sanitizedTeamId.length === 0) { - return res.status(400).json({ success: false, error: 'The team id provided is empty' }); + return res.status(400).json({ success: false, error: 'The team ID provided is empty' }); + } + + if (!ObjectId.isValid(sanitizedTeamId)) { + return res.status(400).json({ success: false, error: 'Invalid team ID provided' }); } - const poolResults = await db - .collection('pool') - .findOne({ _id: new ObjectId(sanitizedId) }); + // Get pool + const pool = await db.collection('pool').findOne({ _id: new ObjectId(sanitizedId) }); - if (!poolResults) { + if (!pool) { return res.status(404).json({ success: false, error: 'Pool with that ID not found' }); } - const teamResults = await db - .collection('team') - .findOne({ _id: new ObjectId(sanitizedTeamId) }); + // Get team + const team = await db.collection('team').findOne({ _id: new ObjectId(sanitizedTeamId) }); - if (!teamResults) { + if (!team) { return res.status(404).json({ success: false, error: 'Team with that ID not found' }); } - const teamPoolResults = await db.collection('teampool').findOne({ + // Team pool + const teamPool = await db.collection('teampool').findOne({ teamId: sanitizedTeamId, poolId: sanitizedId }); - if (teamPoolResults) { + if (teamPool) { return res .status(400) .json({ success: false, error: 'Pool is already assigned to team' }); } + // Add to database const result = await db.collection('teampool').insertOne({ teamId: sanitizedTeamId, poolId: sanitizedId diff --git a/backend/endpoints/pool/controller/createPool.js b/backend/endpoints/pool/controller/createPool.js index 2afd5b7..fbd7502 100644 --- a/backend/endpoints/pool/controller/createPool.js +++ b/backend/endpoints/pool/controller/createPool.js @@ -16,6 +16,12 @@ module.exports = (db) => { return res.status(400).json({ success: false, error: "Missing pool's name" }); } + if (typeof name !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The name provided is not a string' }); + } + const sanitizedName = String(name).trim(); if (sanitizedName.length === 0) { @@ -23,14 +29,14 @@ module.exports = (db) => { } // Make sure the person exists - const existingPerson = await db.collection('pool').findOne({ + const person = await db.collection('pool').findOne({ name: { $regex: `^${sanitizedName}$`, $options: 'i' } }); - if (existingPerson) { + if (person) { return res .status(409) .json({ success: false, error: 'Pool with this name already exits' }); diff --git a/backend/endpoints/pool/controller/deletePool.js b/backend/endpoints/pool/controller/deletePool.js index afa3930..433cbfd 100644 --- a/backend/endpoints/pool/controller/deletePool.js +++ b/backend/endpoints/pool/controller/deletePool.js @@ -15,16 +15,24 @@ module.exports = (db) => { // Check id if (!id) { - return res.status(400).json({ success: false, error: 'Missing pool id' }); + return res.status(400).json({ success: false, error: 'Missing pool ID' }); } - if (!ObjectId.isValid(id)) { - return res.status(400).json({ success: false, error: 'Invalid pool id provided' }); + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The pool ID provided is not a string' }); + } + + const sanitizedId = String(id).trim(); + + if (!ObjectId.isValid(sanitizedId)) { + return res.status(400).json({ success: false, error: 'Invalid pool ID provided' }); } // Check if pool exits const existingPerson = await db.collection('pool').findOne({ - _id: new ObjectId(id) + _id: new ObjectId(sanitizedId) }); if (!existingPerson) { @@ -36,7 +44,7 @@ module.exports = (db) => { // Check if pool has clusters const hasClusters = await db.collection('cluster').findOne({ - poolId: id + poolId: sanitizedId }); if (hasClusters) { @@ -47,7 +55,7 @@ module.exports = (db) => { // Check if pool is assigned to a team const isAssigned = await db.collection('teampool').findOne({ - poolId: id + poolId: sanitizedId }); if (isAssigned) { @@ -58,7 +66,7 @@ module.exports = (db) => { // Delete the pool from the database await db.collection('pool').deleteOne({ - _id: new ObjectId(id) + _id: new ObjectId(sanitizedId) }); return res.status(200).json({ success: true }); diff --git a/backend/endpoints/pool/controller/getPool.js b/backend/endpoints/pool/controller/getPool.js index 07760b6..803bc2b 100644 --- a/backend/endpoints/pool/controller/getPool.js +++ b/backend/endpoints/pool/controller/getPool.js @@ -15,25 +15,31 @@ module.exports = (db) => { // Check id if (!id) { - return res.status(400).json({ success: false, error: 'Missing pool id' }); + return res.status(400).json({ success: false, error: 'Missing pool ID' }); + } + + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The pool ID provided is not a string' }); } const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { - return res.status(400).json({ success: false, error: 'The id provided is empty' }); + return res.status(400).json({ success: false, error: 'The pool ID provided is empty' }); } if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid pool id provided' }); + return res.status(400).json({ success: false, error: 'Invalid pool ID provided' }); } // Get the pool from the database - const results = await db.collection('pool').findOne({ + const pool = await db.collection('pool').findOne({ _id: new ObjectId(sanitizedId) }); - if (!results) { + if (!pool) { return res.status(404).json({ success: false, error: "Pool doesn't exist" }); } @@ -41,7 +47,7 @@ module.exports = (db) => { success: true, body: { id: sanitizedId, - name: results.name + name: pool.name } }); } catch (error) { diff --git a/backend/endpoints/pool/controller/getPoolByCluster.js b/backend/endpoints/pool/controller/getPoolByCluster.js index 48566d5..0c92e93 100644 --- a/backend/endpoints/pool/controller/getPoolByCluster.js +++ b/backend/endpoints/pool/controller/getPoolByCluster.js @@ -15,29 +15,37 @@ module.exports = (db) => { // Check id if (!id) { - return res.status(400).json({ success: false, error: 'Missing cluster id' }); + return res.status(400).json({ success: false, error: 'Missing cluster ID' }); + } + + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The cluster ID provided is not a string' }); } const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { - return res.status(400).json({ success: false, error: 'The id provided is empty' }); + return res + .status(400) + .json({ success: false, error: 'The cluster ID provided is empty' }); } if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid cluster id provided' }); + return res.status(400).json({ success: false, error: 'Invalid cluster ID provided' }); } // Get the cluster from the database - const results = await db.collection('cluster').findOne({ + const cluster = await db.collection('cluster').findOne({ _id: new ObjectId(sanitizedId) }); - if (!results) { + if (!cluster) { return res.status(404).json({ success: false, error: "Cluster doesn't exist" }); } - if (!results.poolId) { + if (!cluster.poolId) { return res.status(404).json({ success: false, error: 'Cluster not assigned to pool' }); } @@ -45,7 +53,7 @@ module.exports = (db) => { success: true, body: { id: sanitizedId, - pool: results.poolId + pool: cluster.poolId } }); } catch (error) { diff --git a/backend/endpoints/pool/controller/getPoolsByTeam.js b/backend/endpoints/pool/controller/getPoolsByTeam.js index fd96dcd..3023376 100644 --- a/backend/endpoints/pool/controller/getPoolsByTeam.js +++ b/backend/endpoints/pool/controller/getPoolsByTeam.js @@ -15,25 +15,31 @@ module.exports = (db) => { // Check id if (!id) { - return res.status(400).json({ success: false, error: 'Missing team id' }); + return res.status(400).json({ success: false, error: 'Missing team ID' }); + } + + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The team ID provided is not a string' }); } const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { - return res.status(400).json({ success: false, error: 'The team id provided is empty' }); + return res.status(400).json({ success: false, error: 'The team ID provided is empty' }); } if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid team id provided' }); + return res.status(400).json({ success: false, error: 'Invalid team ID provided' }); } - const poolResults = await db.collection('team').findOne({ + const pool = await db.collection('team').findOne({ _id: new ObjectId(sanitizedId) }); - if (!poolResults) { - return res.status(404).json({ success: false, error: "team doesn't exist" }); + if (!pool) { + return res.status(404).json({ success: false, error: "Team doesn't exist" }); } // Get the teamPool @@ -43,23 +49,18 @@ module.exports = (db) => { return res.status(404).json({ success: false, error: 'Team does not have any pools' }); } - // Get all pool IDs - const poolIds = teamPools.map((tp) => new ObjectId(tp.poolId)); - // Fetch all pool documents - const pools = await db + const allPools = await db .collection('pool') - .find({ _id: { $in: poolIds } }) + .find({ _id: { $in: teamPools.map((tp) => new ObjectId(tp.poolId)) } }) .toArray(); - const response = pools.map(({ _id, ...pool }) => ({ - id: _id, - ...pool - })); - return res.json({ success: true, - body: response + body: allPools.map(({ _id, ...pool }) => ({ + id: _id, + ...pool + })) }); } catch (error) { return res.status(500).json({ success: false, error: error.message }); diff --git a/backend/endpoints/pool/controller/getPoolsNotInTeam.js b/backend/endpoints/pool/controller/getPoolsNotInTeam.js index 7dd2b9b..af13fc4 100644 --- a/backend/endpoints/pool/controller/getPoolsNotInTeam.js +++ b/backend/endpoints/pool/controller/getPoolsNotInTeam.js @@ -15,25 +15,32 @@ module.exports = (db) => { // Check id if (!id) { - return res.status(400).json({ success: false, error: 'Missing team id' }); + return res.status(400).json({ success: false, error: 'Missing team ID' }); + } + + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The team ID provided is not a string' }); } const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { - return res.status(400).json({ success: false, error: 'The team id provided is empty' }); + return res.status(400).json({ success: false, error: 'The team ID provided is empty' }); } if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid team id provided' }); + return res.status(400).json({ success: false, error: 'Invalid team ID provided' }); } - const poolResults = await db.collection('team').findOne({ + // Get pool + const pool = await db.collection('team').findOne({ _id: new ObjectId(sanitizedId) }); - if (!poolResults) { - return res.status(404).json({ success: false, error: "team doesn't exist" }); + if (!pool) { + return res.status(404).json({ success: false, error: "Team doesn't exist" }); } // Get the teamPool @@ -47,19 +54,17 @@ module.exports = (db) => { const poolIds = teamPools.map((tp) => new ObjectId(tp.poolId)); // Fetch all pool documents - const pools = await db + const allPools = await db .collection('pool') .find({ _id: { $nin: poolIds } }) .toArray(); - const response = pools.map(({ _id, ...pool }) => ({ - id: _id, - ...pool - })); - return res.json({ success: true, - body: response + body: allPools.map(({ _id, ...pool }) => ({ + id: _id, + ...pool + })) }); } catch (error) { return res.status(500).json({ success: false, error: error.message }); diff --git a/backend/endpoints/pool/controller/removePoolFromTeam.js b/backend/endpoints/pool/controller/removePoolFromTeam.js index dcafeec..ca07909 100644 --- a/backend/endpoints/pool/controller/removePoolFromTeam.js +++ b/backend/endpoints/pool/controller/removePoolFromTeam.js @@ -14,61 +14,81 @@ module.exports = (db) => { const { teamId } = req.body || {}; const { id } = req.params || {}; + // Check id if (!id) { return res.status(400).json({ success: false, error: 'missing pool ID' }); } - if (!teamId) { - return res.status(400).json({ success: false, error: 'missing team ID' }); + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The pool ID provided is not a string' }); } const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { - return res.status(400).json({ success: false, error: 'The pool id provided is empty' }); + return res.status(400).json({ success: false, error: 'The pool ID provided is empty' }); + } + + if (!ObjectId.isValid(sanitizedId)) { + return res.status(400).json({ success: false, error: 'Invalid pool ID provided' }); + } + + // Check team id + if (!teamId) { + return res.status(400).json({ success: false, error: 'missing team ID' }); + } + + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The team ID provided is not a string' }); } const sanitizedTeamId = String(teamId).trim(); if (sanitizedTeamId.length === 0) { - return res.status(400).json({ success: false, error: 'The team id provided is empty' }); + return res.status(400).json({ success: false, error: 'The team ID provided is empty' }); + } + + if (!ObjectId.isValid(sanitizedTeamId)) { + return res.status(400).json({ success: false, error: 'Invalid team ID provided' }); } - const poolResults = await db - .collection('pool') - .findOne({ _id: new ObjectId(sanitizedId) }); + // Get pool + const pool = await db.collection('pool').findOne({ _id: new ObjectId(sanitizedId) }); - if (!poolResults) { + if (!pool) { return res.status(404).json({ success: false, error: 'Pool with that ID not found' }); } - const teamResults = await db - .collection('team') - .findOne({ _id: new ObjectId(sanitizedTeamId) }); + // Get team + const team = await db.collection('team').findOne({ _id: new ObjectId(sanitizedTeamId) }); - if (!teamResults) { + if (!team) { return res.status(404).json({ success: false, error: 'Team with that ID not found' }); } - const teamPoolResults = await db.collection('teampool').findOne({ + // Check if pool is assigned to team + const teamPool = await db.collection('teampool').findOne({ teamId: sanitizedTeamId, poolId: sanitizedId }); - if (!teamPoolResults) { + if (!teamPool) { return res .status(400) .json({ success: false, error: 'Pool is not assigned to this team' }); } + // Delete from database await db.collection('teampool').deleteOne({ teamId: sanitizedTeamId, poolId: sanitizedId }); - return res.status(200).json({ - success: true - }); + return res.status(200).json({ success: true }); } catch (error) { return res.status(500).json({ success: false, error: error.message }); } diff --git a/backend/endpoints/report/controller/addReport.js b/backend/endpoints/report/controller/addReport.js index 3f9e000..59712ce 100644 --- a/backend/endpoints/report/controller/addReport.js +++ b/backend/endpoints/report/controller/addReport.js @@ -22,14 +22,14 @@ module.exports = (db) => { } = req.body || {}; // Check cluster id + if (!clusterId) { + return res.status(400).json({ success: false, error: 'Missing cluster ID' }); + } + if (typeof clusterId !== 'string') { return res .status(400) - .json({ success: false, error: 'The cluster id provided is not a string' }); - } - - if (!clusterId) { - return res.status(400).json({ success: false, error: 'Missing cluster id' }); + .json({ success: false, error: 'The cluster ID provided is not a string' }); } const sanitizedClusterId = String(clusterId).trim(); @@ -37,7 +37,7 @@ module.exports = (db) => { if (sanitizedClusterId.length === 0) { return res .status(400) - .json({ success: false, error: 'The person id provided is empty' }); + .json({ success: false, error: 'The person ID provided is empty' }); } if (!ObjectId.isValid(sanitizedClusterId)) { @@ -55,14 +55,14 @@ module.exports = (db) => { } // Check person id + if (!personId) { + return res.status(400).json({ success: false, error: 'Missing persons ID' }); + } + if (typeof personId !== 'string') { return res .status(400) - .json({ success: false, error: 'The persons id provided is not a string' }); - } - - if (!personId) { - return res.status(400).json({ success: false, error: 'Missing persons id' }); + .json({ success: false, error: 'The persons ID provided is not a string' }); } const sanitizedPersonId = String(personId).trim(); @@ -70,11 +70,11 @@ module.exports = (db) => { if (sanitizedPersonId.length === 0) { return res .status(400) - .json({ success: false, error: 'The person id provided is empty' }); + .json({ success: false, error: 'The person ID provided is empty' }); } if (!ObjectId.isValid(sanitizedPersonId)) { - return res.status(400).json({ success: false, error: 'Invalid person id provided' }); + return res.status(400).json({ success: false, error: 'Invalid person ID provided' }); } const personExists = await db.collection('person').findOne({ @@ -88,27 +88,27 @@ module.exports = (db) => { } // Check start time + if (!startTime) { + return res.status(400).json({ success: false, error: 'Missing start time' }); + } + if (typeof startTime !== 'number') { return res .status(400) .json({ success: false, error: 'The start time provided is not a number' }); } - if (!startTime) { - return res.status(400).json({ success: false, error: 'Missing start time' }); + // Check end time + if (!endTime) { + return res.status(400).json({ success: false, error: 'Missing end time' }); } - // Check end time if (typeof endTime !== 'number') { return res .status(400) .json({ success: false, error: 'The end time provided is not a number' }); } - if (!endTime) { - return res.status(400).json({ success: false, error: 'Missing end time' }); - } - // Check results if (!results) { return res.status(400).json({ success: false, error: 'Missing results' }); diff --git a/backend/endpoints/report/controller/getDailyOverviewReport.js b/backend/endpoints/report/controller/getDailyOverviewReport.js index b1805a3..b09e5cb 100644 --- a/backend/endpoints/report/controller/getDailyOverviewReport.js +++ b/backend/endpoints/report/controller/getDailyOverviewReport.js @@ -13,6 +13,13 @@ module.exports = (db) => { try { const { date } = req.query || {}; + // Check date + if (typeof date !== 'number') { + return res + .status(400) + .json({ success: false, error: 'The data provided is not a number' }); + } + // Get people const people = await db .collection('person') @@ -41,7 +48,7 @@ module.exports = (db) => { const startOfDay = date ? new Date(date) : new Date(); startOfDay.setHours(0, 0, 0, 0); - const endOfDay = new Date(); + const endOfDay = new Date(startOfDay); endOfDay.setHours(23, 59, 59, 999); const overviewReport = await db.collection('overviewReport').findOne({ @@ -72,18 +79,16 @@ module.exports = (db) => { .toArray(); const ResultsWithTitles = await Promise.all( - results - .map(async (data) => { - const instruction = await db - .collection('instruction') - .findOne({ _id: new ObjectId(data.instructionId) }); - - return { - title: instruction.title, - ...data - }; - }) - .filter((r) => r.note || !r.passed) + results.map(async (data) => { + const instruction = await db + .collection('instruction') + .findOne({ _id: new ObjectId(data.instructionId) }); + + return { + title: instruction.title, + ...data + }; + }) ); return { @@ -91,7 +96,7 @@ module.exports = (db) => { person: people.find((p) => p.id === rest.personId)?.name, cluster: cluster.find((c) => c.id === rest.clusterId)?.name, ...rest, - results: ResultsWithTitles + results: ResultsWithTitles.filter((r) => r.note || !r.passed) }; }) ); diff --git a/backend/endpoints/report/controller/getReportByCluster.js b/backend/endpoints/report/controller/getReportByCluster.js index a6a5852..42dab67 100644 --- a/backend/endpoints/report/controller/getReportByCluster.js +++ b/backend/endpoints/report/controller/getReportByCluster.js @@ -18,16 +18,16 @@ module.exports = (db) => { const skip = (page - 1) * limit; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing cluster id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The cluster id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing cluster id' }); - } - const sanitizedClusterId = String(id).trim(); if (sanitizedClusterId.length === 0) { diff --git a/backend/endpoints/report/controller/getReportById.js b/backend/endpoints/report/controller/getReportById.js index 3ba18cd..77f5c7d 100644 --- a/backend/endpoints/report/controller/getReportById.js +++ b/backend/endpoints/report/controller/getReportById.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id } = req.params || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing the report id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The report id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing the report id' }); - } - const sanitisedId = String(id).trim(); if (sanitisedId.length === 0) { @@ -36,6 +36,7 @@ module.exports = (db) => { return res.status(400).json({ success: false, error: 'Invalid report id' }); } + // Get report const report = await db.collection('report').findOne({ _id: new ObjectId(sanitisedId) }); diff --git a/backend/endpoints/report/controller/getTodaysReportByCluster.js b/backend/endpoints/report/controller/getTodaysReportByCluster.js index e85c59d..d1fee35 100644 --- a/backend/endpoints/report/controller/getTodaysReportByCluster.js +++ b/backend/endpoints/report/controller/getTodaysReportByCluster.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id } = req.params || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing cluster id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The cluster id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing cluster id' }); - } - const sanitisedId = String(id).trim(); if (sanitisedId.length === 0) { diff --git a/backend/endpoints/rota/controller/addClosedDay.js b/backend/endpoints/rota/controller/addClosedDay.js index 2eda2a1..6ee65e3 100644 --- a/backend/endpoints/rota/controller/addClosedDay.js +++ b/backend/endpoints/rota/controller/addClosedDay.js @@ -12,17 +12,26 @@ module.exports = (db) => { const { day } = req.body || {}; // Check day + if (!day) { + return res.status(400).json({ success: false, error: 'Missing day' }); + } + if (typeof day !== 'string') { return res .status(400) .json({ success: false, error: 'The day provided is not a string' }); } - if (!day) { - return res.status(400).json({ success: false, error: 'Missing day' }); + const sanitisedDay = String(day).trim(); + + if (sanitisedDay.length === 0) { + return res + .status(400) + .json({ success: false, error: 'The report id provided is empty' }); } - const date = new Date(day); + // Get date + const date = new Date(sanitisedDay); if (isNaN(date.getTime())) { return res.status(400).json({ success: false, error: 'Invalid date' }); @@ -30,8 +39,8 @@ module.exports = (db) => { date.setHours(0, 0, 0, 0); - const collection = db.collection('closedDay'); - const existing = await collection.findOne({ day: date }); + // Check if the day is in the database already + const existing = await db.collection('closedDay').findOne({ day: date }); if (existing) { return res @@ -39,9 +48,9 @@ module.exports = (db) => { .json({ success: false, error: 'Office already marked closed for this day' }); } - await collection.insertOne({ day: date }); + await db.collection('closedDay').insertOne({ day: date }); - return res.status(201).json({ success: true, body: { day } }); + return res.status(201).json({ success: true, body: { day: sanitisedDay } }); } catch (error) { return res.status(500).json({ success: false, error: error.message }); } diff --git a/backend/endpoints/rota/controller/getRotaByPerson.js b/backend/endpoints/rota/controller/getRotaByPerson.js index f8177f9..aade624 100644 --- a/backend/endpoints/rota/controller/getRotaByPerson.js +++ b/backend/endpoints/rota/controller/getRotaByPerson.js @@ -15,40 +15,45 @@ module.exports = (db) => { try { const { id } = req.params || {}; + // Check id if (!id) { - return res.status(400).json({ - success: false, - error: 'Missing person id' - }); + return res.status(400).json({ success: false, error: 'Missing person ID' }); } - if (!ObjectId.isValid(id)) { - return res.status(400).json({ - success: false, - error: 'Invalid person id provided' - }); + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The person ID provided is not a string' }); + } + + const sanitisedId = String(id).trim(); + + if (sanitisedId.length === 0) { + return res + .status(400) + .json({ success: false, error: 'The report id provided is empty' }); } - // 1. Fetch person + if (!ObjectId.isValid(sanitisedId)) { + return res.status(400).json({ success: false, error: 'Invalid report id' }); + } + + // Get person const person = await db.collection('person').findOne({ - _id: new ObjectId(id) + _id: new ObjectId(sanitisedId) }); if (!person) { - return res.status(404).json({ - success: false, - error: 'Person not found' - }); + return res.status(404).json({ success: false, error: 'Person not found' }); } if (!person.teamId) { - return res.status(404).json({ - success: false, - error: 'Person is not assigned to a team' - }); + return res + .status(404) + .json({ success: false, error: 'Person is not assigned to a team' }); } - // 2. Get today's schedule + // Get today's schedule const today = new Date(); const scheduleForToday = await getDaily(db, today); @@ -69,10 +74,7 @@ module.exports = (db) => { body: { [person.name]: personEntry } }); } catch (error) { - return res.status(500).json({ - success: false, - error: error.message - }); + return res.status(500).json({ success: false, error: error.message }); } }; }; diff --git a/backend/endpoints/team/controller/addTeam.js b/backend/endpoints/team/controller/addTeam.js index a830540..121bf3f 100644 --- a/backend/endpoints/team/controller/addTeam.js +++ b/backend/endpoints/team/controller/addTeam.js @@ -12,16 +12,16 @@ module.exports = (db) => { const { name } = req.body || {}; // Check name + if (!name) { + return res.status(400).json({ success: false, error: "Missing team's name" }); + } + if (typeof name !== 'string') { return res .status(400) .json({ success: false, error: 'The name provided is not a string' }); } - if (!name) { - return res.status(400).json({ success: false, error: "Missing team's name" }); - } - const sanitizedName = String(name).trim(); if (sanitizedName.length == 0) { diff --git a/backend/endpoints/team/controller/deleteTeam.js b/backend/endpoints/team/controller/deleteTeam.js index d21ee26..d7a6bf2 100644 --- a/backend/endpoints/team/controller/deleteTeam.js +++ b/backend/endpoints/team/controller/deleteTeam.js @@ -15,17 +15,23 @@ module.exports = (db) => { // Check id if (!id) { - return res.status(400).json({ success: false, error: "Missing team's id" }); + return res.status(400).json({ success: false, error: 'Missing team ID' }); + } + + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The team ID provided is not a string' }); } const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { - return res.status(400).json({ success: false, error: 'The team id provided is empty' }); + return res.status(400).json({ success: false, error: 'The team ID provided is empty' }); } if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid team id provided' }); + return res.status(400).json({ success: false, error: 'Invalid team ID provided' }); } // Check if team exists @@ -38,26 +44,26 @@ module.exports = (db) => { } // Check if people are linked to the team - const hasPeople = await db + const people = await db .collection('person') .find({ teamId: sanitizedId }) .toArray(); - if (hasPeople.length > 0) { + if (people.length > 0) { return res.status(409).json({ success: false, error: 'This team has people' }); } // Check if clusters are linked to the team - const hasClusters = await db + const clusters = await db .collection('teampool') .find({ teamId: sanitizedId }) .toArray(); - if (hasClusters.length > 0) { + if (clusters.length > 0) { return res.status(409).json({ success: false, error: 'This team has pools' }); } diff --git a/backend/endpoints/team/controller/getTeamById.js b/backend/endpoints/team/controller/getTeamById.js index 7616732..484555f 100644 --- a/backend/endpoints/team/controller/getTeamById.js +++ b/backend/endpoints/team/controller/getTeamById.js @@ -14,24 +14,24 @@ module.exports = (db) => { const { id } = req.params || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing teams ID' }); + } + if (typeof id !== 'string') { return res .status(400) - .json({ success: false, error: 'The team id provided is not a string' }); - } - - if (!id) { - return res.status(400).json({ success: false, error: 'Missing teams id' }); + .json({ success: false, error: 'The team ID provided is not a string' }); } const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { - return res.status(400).json({ success: false, error: 'The team id provided is empty' }); + return res.status(400).json({ success: false, error: 'The team ID provided is empty' }); } if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid team id provided' }); + return res.status(400).json({ success: false, error: 'Invalid team ID provided' }); } // Get the team diff --git a/backend/endpoints/team/controller/getTeamByName.js b/backend/endpoints/team/controller/getTeamByName.js index 8073d59..02c92e8 100644 --- a/backend/endpoints/team/controller/getTeamByName.js +++ b/backend/endpoints/team/controller/getTeamByName.js @@ -12,16 +12,16 @@ module.exports = (db) => { const { name } = req.params || {}; // Check name + if (!name) { + return res.status(400).json({ success: false, error: 'Missing team name' }); + } + if (typeof name !== 'string') { return res .status(400) .json({ success: false, error: 'The team name provided is not a string' }); } - if (!name) { - return res.status(400).json({ success: false, error: 'Missing teams name' }); - } - const sanitizedName = String(name).trim(); if (sanitizedName.length == 0) { diff --git a/backend/endpoints/team/controller/getTeamByPool.js b/backend/endpoints/team/controller/getTeamByPool.js index e91fc7e..7e1056d 100644 --- a/backend/endpoints/team/controller/getTeamByPool.js +++ b/backend/endpoints/team/controller/getTeamByPool.js @@ -15,43 +15,47 @@ module.exports = (db) => { // Check id if (!id) { - return res.status(400).json({ success: false, error: 'Missing pool id' }); + return res.status(400).json({ success: false, error: 'Missing pool ID' }); + } + + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The team ID provided is not a string' }); } const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { - return res.status(400).json({ success: false, error: 'The pool id provided is empty' }); + return res.status(400).json({ success: false, error: 'The pool ID provided is empty' }); } if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid pool id provided' }); + return res.status(400).json({ success: false, error: 'Invalid pool ID provided' }); } - const poolResults = await db.collection('pool').findOne({ + const pool = await db.collection('pool').findOne({ _id: new ObjectId(sanitizedId) }); - if (!poolResults) { + if (!pool) { return res.status(404).json({ success: false, error: "Pool doesn't exist" }); } // Get the teamPool - const results = await db.collection('teampool').find({ poolId: sanitizedId }).toArray(); + const teamPool = await db.collection('teampool').find({ poolId: sanitizedId }).toArray(); - if (results.length === 0) { + if (teamPool.length === 0) { return res.status(404).json({ success: false, error: 'Pool does not have any teams' }); } - const formattedResponse = results.map((result) => ({ - poolId: sanitizedId, - teamId: result.teamId - })); - // Return the team information return res.status(200).json({ success: true, - body: formattedResponse + body: teamPool.map((result) => ({ + poolId: sanitizedId, + teamId: result.teamId + })) }); } catch (error) { return res.status(500).json({ success: false, error: error.message }); diff --git a/backend/endpoints/team/controller/updateTeamSettings.js b/backend/endpoints/team/controller/updateTeamSettings.js index f18f093..dc557fb 100644 --- a/backend/endpoints/team/controller/updateTeamSettings.js +++ b/backend/endpoints/team/controller/updateTeamSettings.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id, ...rest } = req.body || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing team id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The team id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing team id' }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { diff --git a/backend/eslint.config.mjs b/backend/eslint.config.mjs index 76b33bf..4fd5a41 100644 --- a/backend/eslint.config.mjs +++ b/backend/eslint.config.mjs @@ -9,7 +9,7 @@ export default defineConfig([ { files: ['**/*.{js,mjs,cjs}'], languageOptions: { - sourceType: 'module', // ✅ FIX: allows import/export + sourceType: 'module', globals: { ...globals.node } diff --git a/backend/services/dailyReport/dailyReport.js b/backend/services/dailyReport/dailyReport.js index 664a7bb..3b8257c 100644 --- a/backend/services/dailyReport/dailyReport.js +++ b/backend/services/dailyReport/dailyReport.js @@ -69,6 +69,7 @@ module.exports = async (db) => { clusterId: value })) ); + const missingReports = []; if (rotaDaily.length != reports.length) { rotaDaily.forEach((person) => { diff --git a/frontend/app/components/ClusterSettings.jsx b/frontend/app/components/ClusterSettings.jsx index 2274524..87e0d43 100644 --- a/frontend/app/components/ClusterSettings.jsx +++ b/frontend/app/components/ClusterSettings.jsx @@ -7,7 +7,6 @@ import { useState, useEffect, useMemo, useCallback } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; import { FaDatabase, FaUser } from 'react-icons/fa'; import { IoIosArrowForward } from 'react-icons/io'; -import { Listbox, ListboxButton, ListboxOptions, ListboxOption } from '@headlessui/react'; export default function ClusterSettingsPage() { const searchParams = useSearchParams(); @@ -55,12 +54,16 @@ export default function ClusterSettingsPage() { const [editedInstructionTitle, setEditedInstructionTitle] = useState(''); const [editedInstructionDescription, setEditedInstructionDescription] = useState(''); const [editedInstructionExpectedTime, setEditedInstructionExpectedTime] = useState(''); + const [editedInstructionGood, setEditedInstructionGood] = useState(''); + const [editedInstructionBad, setEditedInstructionBad] = useState(''); const [editedInstructionPosition, setEditedInstructionPosition] = useState(0); const [addingInstruction, setAddingInstruction] = useState(false); const [newInstructionTitle, setNewInstructionTitle] = useState(''); const [newInstructionDescription, setNewInstructionDescription] = useState(''); const [newInstructionExpectedTime, setNewInstructionExpectedTime] = useState(''); + const [newInstructionGood, setNewInstructionGood] = useState(''); + const [newInstructionBad, setNewInstructionBad] = useState(''); const [reports, setReports] = useState([]); @@ -238,7 +241,7 @@ export default function ClusterSettingsPage() { } } - async function updateInstruction(id, title, description, expectedTime, position) { + async function updateInstruction(id, title, description, expectedTime, bad, good, position) { try { const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/instruction`, { method: 'PATCH', @@ -248,6 +251,8 @@ export default function ClusterSettingsPage() { title, description, expectedTime, + bad, + good, position }) }); @@ -270,9 +275,11 @@ export default function ClusterSettingsPage() { const title = newInstructionTitle.trim(); const description = newInstructionDescription.trim(); const expectedTime = newInstructionExpectedTime.trim(); + const good = newInstructionGood.trim(); + const bad = newInstructionBad.trim(); - if (!title || !description) { - alert('Title and description are required'); + if (!title || !description || !expectedTime || !good || !bad) { + alert('All inputs are required'); return; } @@ -283,7 +290,9 @@ export default function ClusterSettingsPage() { clusterId, title, description, - expectedTime + expectedTime, + good, + bad }) }); @@ -297,6 +306,8 @@ export default function ClusterSettingsPage() { setNewInstructionTitle(''); setNewInstructionDescription(''); setNewInstructionExpectedTime(''); + setNewInstructionGood(''); + setNewInstructionBad(''); } catch (err) { console.error(err); alert(err.message); @@ -481,6 +492,20 @@ export default function ClusterSettingsPage() { className="w-full rounded-xl border border-slate-700 bg-slate-900 p-3 text-white" /> + setNewInstructionGood(e.target.value)} + placeholder="Good outcome" + className="w-full rounded-xl border border-slate-700 bg-slate-900 p-3 text-white" + /> + + setNewInstructionBad(e.target.value)} + placeholder="Bad outcome" + className="w-full rounded-xl border border-slate-700 bg-slate-900 p-3 text-white" + /> +