diff --git a/backend/src/routes/HousingRoutes.ts b/backend/src/routes/HousingRoutes.ts index 8661896d..7c19fbd3 100644 --- a/backend/src/routes/HousingRoutes.ts +++ b/backend/src/routes/HousingRoutes.ts @@ -8,9 +8,7 @@ import { import { housingReviewPictures } from '../server'; import { ObjectId } from 'mongodb'; import { - isAdmin, isAuthenticated, - isCourseReviewOwner, isHousingReviewOwner, } from '../middleware/authMiddleware'; @@ -22,7 +20,7 @@ const upload = multer({ storage: storage }); /** * @route GET /api/campus/housing * @desc Get all housing buildings - * @access Public + * @access isAuthenticated */ router.get('/', isAuthenticated, async (req: Request, res: Response) => { try { @@ -36,7 +34,7 @@ router.get('/', isAuthenticated, async (req: Request, res: Response) => { /** * @route GET /api/campus/housing/:building * @desc Get housing building by id - * @access Public + * @access isAuthenticated */ router.get( '/:building', @@ -72,7 +70,7 @@ router.get( /** * @route GET /campus/housing/:building/rooms * @desc Get all roms in a building (by building id) - * @access Public + * @access isAuthenticated */ router.get( '/:building/rooms', @@ -108,7 +106,7 @@ router.get( /** * @route GET /api/campus/:room/reviews * @desc Get housing reviews for a room - * @access Public + * @access isAuthenticated */ router.get( '/:room/reviews', @@ -195,7 +193,7 @@ router.get( /** * @route GET /api/campus/housing/:buildingId/:roomNumber/reviews * @desc Get reviews for a room by building id and room number - * @access Public + * @access isAuthenticated */ router.get( '/:buildingId/:roomNumber/reviews', @@ -285,7 +283,7 @@ router.get( /** * @route POST /api/campus/housing/:buildingId/:roomNumber/reviews * @desc Add new housing room review - * @access Public + * @access isAuthenticated */ router.post( '/:buildingId/:roomNumber/reviews', @@ -509,7 +507,7 @@ router.delete( /** * @route GET /api/campus/housing/review_pictures/:id * @desc Get review picture by id - * @access Public + * @access isAuthenticated */ router.get( '/review_pictures/:id', diff --git a/backend/src/routes/ReviewsRoutes.ts b/backend/src/routes/ReviewsRoutes.ts index 236a73cc..8a4f4035 100644 --- a/backend/src/routes/ReviewsRoutes.ts +++ b/backend/src/routes/ReviewsRoutes.ts @@ -1,167 +1,179 @@ import express, { Request, Response, Router } from 'express'; import { CourseReviews } from '../models/Courses'; +import { + isAuthenticated, + isCourseReviewOwner, +} from '../middleware/authMiddleware'; const router: Router = express.Router(); /** * @route GET /api/reviews/:id * @desc Get review by ID - * @access Public + * @access isAuthenticated */ -router.get('/reviews/:id', async (req: Request, res: Response) => { - try { - const reviewId = parseInt(req.params.id); - - // Check if conversion is valid - if (isNaN(reviewId)) { - res.status(400).json({ message: 'Invalid review ID format' }); - return; +router.get( + '/reviews/:id', + isAuthenticated, + async (req: Request, res: Response) => { + try { + const reviewId = parseInt(req.params.id); + + // Check if conversion is valid + if (isNaN(reviewId)) { + res.status(400).json({ message: 'Invalid review ID format' }); + return; + } + + const review = await CourseReviews.findOne({ + id: reviewId, + }); + + if (!review) { + res.status(404).json({ message: 'Review not found' }); + return; + } + + res.json(review); + } catch (err) { + console.error(err); + res.status(500).json({ message: 'Server error' }); } - - const review = await CourseReviews.findOne({ - id: reviewId, - }); - - if (!review) { - res.status(404).json({ message: 'Review not found' }); - return; - } - - res.json(review); - } catch (err) { - console.error(err); - res.status(500).json({ message: 'Server error' }); } -}); +); /** * @route POST /api/reviews * @desc Create new review - * @access Private + * @access isAuthenticated */ -router.post('/reviews', async (req: Request, res: Response) => { - try { - const { - id, - overall_rating, - challenge_rating, - inclusivity_rating, - work_per_week, - total_cost, - comments, - course_id, - instructor_id, - user_id, - } = req.body; - - // Check if review already exists - const reviewExists = await CourseReviews.findOne({ - id, - }); - if (reviewExists) { - res.status(400).json({ message: 'Review already exists' }); - return; +router.post( + '/reviews', + isAuthenticated, + async (req: Request, res: Response) => { + try { + const { + id, + overall_rating, + challenge_rating, + inclusivity_rating, + work_per_week, + total_cost, + comments, + course_id, + instructor_id, + user_id, + } = req.body; + + // Check if review already exists + const reviewExists = await CourseReviews.findOne({ + id, + }); + if (reviewExists) { + res.status(400).json({ message: 'Review already exists' }); + return; + } + + // Create new review + const newReview = new CourseReviews({ + id, + overall_rating, + challenge_rating, + inclusivity_rating, + work_per_week, + total_cost, + comments, + course_id, + instructor_id, + user_id, + }); + + const savedReview = await newReview.save(); + res.status(201).json(savedReview); + } catch (err) { + console.error(err); + res.status(500).json({ message: 'Server error' }); } - - // Create new review - const newReview = new CourseReviews({ - id, - overall_rating, - challenge_rating, - inclusivity_rating, - work_per_week, - total_cost, - comments, - course_id, - instructor_id, - user_id, - }); - - const savedReview = await newReview.save(); - res.status(201).json(savedReview); - } catch (err) { - console.error(err); - res.status(500).json({ message: 'Server error' }); } -}); +); /** * @route PUT /api/reviews/:id * @desc Update review - * @access Private + * @access isCourseReviewOwner */ -router.put('/reviews/:id', async (req: Request, res: Response) => { - try { - const reviewId = parseInt(req.params.id); - - // Check if conversion is valid - if (isNaN(reviewId)) { - res.status(400).json({ message: 'Invalid review ID format' }); - return; - } - - // Check if review exists - const review = await CourseReviews.findOne({ - id: reviewId, - }); - - if (!review) { - res.status(404).json({ message: 'Review not found' }); - return; +router.put( + '/reviews/:id', + isCourseReviewOwner, + async (req: Request, res: Response) => { + try { + const reviewId = parseInt(req.params.id); + + // Check if conversion is valid + if (isNaN(reviewId)) { + res.status(400).json({ message: 'Invalid review ID format' }); + return; + } + + // Check if review exists + const review = await CourseReviews.findOne({ + id: reviewId, + }); + + if (!review) { + res.status(404).json({ message: 'Review not found' }); + return; + } + + const updatedReview = await CourseReviews.findOneAndUpdate( + { id: reviewId }, + { $set: req.body }, + { new: true } + ); + + res.json(updatedReview); + } catch (err) { + console.error(err); + res.status(500).json({ message: 'Server error' }); } - - // TODO: Check if user is authorized to update this review - // For example, checking if req.user.id === review.user_id - // This can also be done somewhere else - - const updatedReview = await CourseReviews.findOneAndUpdate( - { id: reviewId }, - { $set: req.body }, - { new: true } - ); - - res.json(updatedReview); - } catch (err) { - console.error(err); - res.status(500).json({ message: 'Server error' }); } -}); +); /** * @route DELETE /api/reviews/:id * @desc Delete review - * @access Private + * @access isCourseReviewOwner */ -router.delete('/reviews/:id', async (req: Request, res: Response) => { - try { - const reviewId: number = parseInt(req.params.id); - - // Check if conversion is valid - if (isNaN(reviewId)) { - res.status(400).json({ message: 'Invalid review ID format' }); - return; - } - - // Check if review exists - const review = await CourseReviews.findOne({ - id: reviewId, - }); - - if (!review) { - res.status(404).json({ message: 'Review not found' }); - return; +router.delete( + '/reviews/:id', + isCourseReviewOwner, + async (req: Request, res: Response) => { + try { + const reviewId: number = parseInt(req.params.id); + + // Check if conversion is valid + if (isNaN(reviewId)) { + res.status(400).json({ message: 'Invalid review ID format' }); + return; + } + + // Check if review exists + const review = await CourseReviews.findOne({ + id: reviewId, + }); + + if (!review) { + res.status(404).json({ message: 'Review not found' }); + return; + } + + await CourseReviews.findOneAndDelete({ id: reviewId }); + res.json({ message: 'Review removed' }); + } catch (err) { + console.error(err); + res.status(500).json({ message: 'Server error' }); } - - // TODO: Check if user is authorized to delete this review - // For example, checking if req.user.id === review.user_id or if user is admin - // This can also be done somewhere else - - await CourseReviews.findOneAndDelete({ id: reviewId }); - res.json({ message: 'Review removed' }); - } catch (err) { - console.error(err); - res.status(500).json({ message: 'Server error' }); } -}); +); export default router; diff --git a/backend/src/routes/admin/PagesRoutes.ts b/backend/src/routes/admin/PagesRoutes.ts index 95e284cb..93bc419c 100644 --- a/backend/src/routes/admin/PagesRoutes.ts +++ b/backend/src/routes/admin/PagesRoutes.ts @@ -4,7 +4,11 @@ import { isAdmin, isAuthenticated } from '../../middleware/authMiddleware'; const router = express.Router(); -// Get all pages +/** + * @route GET /api/admin/pages + * @desc Get all pages + * @access + */ router.get('/', async (req: Request, res: Response) => { try { const pages = await PageContent.find({}); @@ -14,7 +18,11 @@ router.get('/', async (req: Request, res: Response) => { } }); -// Get the page by id +/** + * @route GET /api/admin/pages/:id + * @desc Get page by id + * @access isAuthenticated + */ router.get('/:id', isAuthenticated, async (req: Request, res: Response) => { try { const { id } = req.params; @@ -31,7 +39,11 @@ router.get('/:id', isAuthenticated, async (req: Request, res: Response) => { } }); -// Get all pages by header +/** + * @route GET /api/admin/pages/:header + * @desc Get pages by header + * @access + */ router.get('/header/:header', async (req: Request, res: Response) => { try { const { header } = req.params; @@ -42,7 +54,11 @@ router.get('/header/:header', async (req: Request, res: Response) => { } }); -// Create a new page +/** + * @route POST /api/admin/pages + * @desc Create a new page + * @access isAdmin + */ router.post('/', isAdmin, async (req: Request, res: Response) => { try { const { id, name, content, header, link } = req.body; @@ -79,7 +95,11 @@ router.post('/', isAdmin, async (req: Request, res: Response) => { } }); -// Update an existing page +/** + * @route PUT /api/admin/pages/:id + * @desc Update an existing page + * @access isAdmin + */ router.put('/:id', isAdmin, async (req: Request, res: Response) => { try { const { id } = req.params; @@ -116,7 +136,11 @@ router.put('/:id', isAdmin, async (req: Request, res: Response) => { } }); -// Delete a page by id +/** + * @route DELETE /api/admin/pages/:id + * @desc Delete a page by id + * @access isAdmin + */ router.delete('/:id', isAdmin, async (req: Request, res: Response) => { try { const { id } = req.params; diff --git a/backend/src/routes/admin/StaffRoutes.ts b/backend/src/routes/admin/StaffRoutes.ts index c10f409b..a10f6bf7 100644 --- a/backend/src/routes/admin/StaffRoutes.ts +++ b/backend/src/routes/admin/StaffRoutes.ts @@ -10,7 +10,11 @@ const router = express.Router(); const storage = multer.memoryStorage(); const upload = multer({ storage: storage }); -// Get all ids and names and positions of staff members +/** + * @route GET /api/members + * @desc Get all ids and names and positions of staff members + * @access + */ router.get('/', async (req: Request, res: Response) => { try { const staff = await Staff.find({}, { id: 1, name: 1, position: 1 }); @@ -20,7 +24,11 @@ router.get('/', async (req: Request, res: Response) => { } }); -// Get staff info by id +/** + * @route GET /api/members/:id + * @desc Get staff member info by id + * @access isAuthenticated + */ router.get('/:id', isAuthenticated, async (req: Request, res: Response) => { try { const { id } = req.params; @@ -36,7 +44,11 @@ router.get('/:id', isAuthenticated, async (req: Request, res: Response) => { } }); -// Get staff info by group +/** + * @route GET /api/members/:group + * @desc Get staff members by group + * @access isAuthenticated + */ router.get( '/group/:group', isAuthenticated, @@ -57,7 +69,11 @@ router.get( } ); -// Create staff member +/** + * @route POST /api/members + * @desc Create a new staff member + * @access isAdmin + */ router.post( '/', isAdmin, @@ -105,7 +121,11 @@ router.post( } ); -// Update staff info +/** + * @route PATCH /api/members/:id + * @desc Update staff member info + * @access isAdmin + */ router.patch( '/:id', isAdmin, @@ -177,7 +197,11 @@ router.patch( } ); -// Get profile picture by id +/** + * @route GET /api/members/profile-pic/:id + * @desc Get profile picture of staff by id + * @access + */ router.get('/profile-pic/:id', async (req: Request, res: Response) => { try { const fileId = new ObjectId(req.params.id); @@ -208,6 +232,11 @@ router.get('/profile-pic/:id', async (req: Request, res: Response) => { } }); +/** + * @route DELETE /api/members/:id + * @desc Delete member by id + * @access isAdmin + */ router.delete('/:id', isAdmin, async (req: Request, res: Response) => { try { const staff = await Staff.findOneAndDelete({ id: req.params.id });