From b5547cb100e5c9f84b7a113da32d0b58fd388385 Mon Sep 17 00:00:00 2001 From: NouhailaAater Date: Mon, 24 Feb 2025 04:09:55 -0500 Subject: [PATCH] Ensure room title uniqueness by normalizing case sensitivity --- .../pages/Teacher/ManageRoom/RoomContext.tsx | 2 +- server/controllers/room.js | 452 +++++++++--------- server/models/room.js | 7 +- 3 files changed, 235 insertions(+), 226 deletions(-) diff --git a/client/src/pages/Teacher/ManageRoom/RoomContext.tsx b/client/src/pages/Teacher/ManageRoom/RoomContext.tsx index 0ea0451..98913f7 100644 --- a/client/src/pages/Teacher/ManageRoom/RoomContext.tsx +++ b/client/src/pages/Teacher/ManageRoom/RoomContext.tsx @@ -26,7 +26,7 @@ export const RoomProvider = ({ children }: { children: React.ReactNode }) => { setSelectedRoom(defaultRoom); localStorage.setItem('selectedRoomId', defaultRoom._id); } else { - const randomRoomName = `Room-${Math.floor(Math.random() * 10000)}`; + const randomRoomName = `Room-${Math.floor(Math.random() * 1000000)}`; await createRoom(randomRoomName); } }; diff --git a/server/controllers/room.js b/server/controllers/room.js index 905d9cc..2c17cf2 100644 --- a/server/controllers/room.js +++ b/server/controllers/room.js @@ -1,236 +1,242 @@ -const AppError = require('../middleware/AppError.js'); -const { MISSING_REQUIRED_PARAMETER, ROOM_NOT_FOUND, ROOM_ALREADY_EXISTS, GETTING_ROOM_ERROR, DELETE_ROOM_ERROR, UPDATE_ROOM_ERROR } = require('../constants/errorCodes'); +const AppError = require("../middleware/AppError.js"); +const { + MISSING_REQUIRED_PARAMETER, + ROOM_NOT_FOUND, + ROOM_ALREADY_EXISTS, + GETTING_ROOM_ERROR, + DELETE_ROOM_ERROR, + UPDATE_ROOM_ERROR, +} = require("../constants/errorCodes"); class RoomsController { + constructor(roomsModel) { + this.rooms = roomsModel; + this.getRoomTitle = this.getRoomTitle.bind(this); + } - constructor(roomsModel) { - this.rooms = roomsModel; - this.getRoomTitle = this.getRoomTitle.bind(this); - } - -create = async (req, res, next) => { + create = async (req, res, next) => { try { - const { title } = req.body; + const { title } = req.body; - if (!title) { - throw new AppError(MISSING_REQUIRED_PARAMETER); - } + if (!title) { + throw new AppError(MISSING_REQUIRED_PARAMETER); + } - const result = await this.rooms.create(title, req.user.userId); + const normalizedTitle = title.toLowerCase(); - if (!result) { - throw new AppError(ROOM_ALREADY_EXISTS); - } + const roomExists = await this.rooms.roomExists(normalizedTitle); - return res.status(200).json({ - message: 'Room cree avec succes.', - roomId: result.insertedId - }); + if (roomExists) { + throw new AppError(ROOM_ALREADY_EXISTS); + } + + const result = await this.rooms.create(normalizedTitle, req.user.userId); + return res.status(200).json({ + message: "Room cree avec succes.", + roomId: result.insertedId, + }); } catch (error) { - return next(error); + return next(error); } + }; + + getUserRooms = async (req, res, next) => { + try { + const rooms = await this.rooms.getUserRooms(req.user.userId); + + if (!rooms) { + throw new AppError(ROOM_NOT_FOUND); + } + + return res.status(200).json({ + data: rooms, + }); + } catch (error) { + return next(error); + } + }; + + getRoomContent = async (req, res, next) => { + try { + const { roomId } = req.params; + + if (!roomId) { + throw new AppError(MISSING_REQUIRED_PARAMETER); + } + + const owner = await this.rooms.getOwner(roomId); + + if (owner != req.user.userId) { + throw new AppError(ROOM_NOT_FOUND); + } + + const content = await this.rooms.getContent(roomId); + + if (!content) { + throw new AppError(GETTING_ROOM_ERROR); + } + + return res.status(200).json({ + data: content, + }); + } catch (error) { + return next(error); + } + }; + + delete = async (req, res, next) => { + try { + const { roomId } = req.params; + + if (!roomId) { + throw new AppError(MISSING_REQUIRED_PARAMETER); + } + + const owner = await this.rooms.getOwner(roomId); + + if (owner != req.user.userId) { + throw new AppError(ROOM_NOT_FOUND); + } + + const result = await this.rooms.delete(roomId); + + if (!result) { + throw new AppError(DELETE_ROOM_ERROR); + } + + return res.status(200).json({ + message: "Salle supprimé avec succès.", + }); + } catch (error) { + return next(error); + } + }; + + rename = async (req, res, next) => { + try { + const { roomId, newTitle } = req.body; + + if (!roomId || !newTitle) { + throw new AppError(MISSING_REQUIRED_PARAMETER); + } + + const owner = await this.rooms.getOwner(roomId); + + if (owner != req.user.userId) { + throw new AppError(ROOM_NOT_FOUND); + } + + const exists = await this.rooms.roomExists(newTitle, req.user.userId); + + if (exists) { + throw new AppError(ROOM_ALREADY_EXISTS); + } + + const result = await this.rooms.rename(roomId, req.user.userId, newTitle); + + if (!result) { + throw new AppError(UPDATE_ROOM_ERROR); + } + + return res.status(200).json({ + message: "Salle mis � jours avec succ�s.", + }); + } catch (error) { + return next(error); + } + }; + + getRoomById = async (req, res, next) => { + try { + const { roomId } = req.params; + + if (!roomId) { + throw new AppError(MISSING_REQUIRED_PARAMETER); + } + + // Is this room mine + const owner = await this.rooms.getOwner(roomId); + + if (owner != req.user.userId) { + throw new AppError(ROOM_NOT_FOUND); + } + + const room = await this.rooms.getRoomById(roomId); + + if (!room) { + throw new AppError(ROOM_NOT_FOUND); + } + + return res.status(200).json({ + data: room, + }); + } catch (error) { + return next(error); + } + }; + getRoomTitle = async (req, res, next) => { + try { + const { roomId } = req.params; + + if (!roomId) { + throw new AppError(MISSING_REQUIRED_PARAMETER); + } + + const room = await this.rooms.getRoomById(roomId); + + if (room instanceof Error) { + throw new AppError(ROOM_NOT_FOUND); + } + + return res.status(200).json({ title: room.title }); + } catch (error) { + return next(error); + } + }; + roomExists = async (req, res, next) => { + try { + const { title } = req.body; + + if (!title) { + throw new AppError(MISSING_REQUIRED_PARAMETER); + } + + const normalizedTitle = title.toLowerCase(); + + const exists = await this.rooms.roomExists(normalizedTitle); + + return res.status(200).json({ + message: `La salle avec le titre "${title}" existe déjà.`, + exists: exists, + }); + } catch (error) { + return next(error); + } + }; + getRoomTitleByUserId = async (req, res, next) => { + try { + const { userId } = req.params; + + if (!userId) { + throw new AppError(MISSING_REQUIRED_PARAMETER); + } + + const rooms = await this.rooms.getUserRooms(userId); + + if (!rooms || rooms.length === 0) { + throw new AppError(ROOM_NOT_FOUND); + } + + const roomTitles = rooms.map((room) => room.title); + + return res.status(200).json({ + titles: roomTitles, + }); + } catch (error) { + return next(error); + } + }; } - getUserRooms = async (req, res, next) => { - try { - const rooms = await this.rooms.getUserRooms(req.user.userId); - - if (!rooms) { - throw new AppError(ROOM_NOT_FOUND); - } - - return res.status(200).json({ - data: rooms - }); - - } catch (error) { - return next(error); - } - } - - getRoomContent = async (req, res, next) => { - try { - const { roomId } = req.params; - - if (!roomId) { - throw new AppError(MISSING_REQUIRED_PARAMETER); - } - - const owner = await this.rooms.getOwner(roomId); - - if (owner != req.user.userId) { - throw new AppError(ROOM_NOT_FOUND); - } - - const content = await this.rooms.getContent(roomId); - - if (!content) { - throw new AppError(GETTING_ROOM_ERROR); - } - - return res.status(200).json({ - data: content - }); - - } catch (error) { - return next(error); - } - } - - delete = async (req, res, next) => { - try { - const { roomId } = req.params; - - if (!roomId) { - throw new AppError(MISSING_REQUIRED_PARAMETER); - } - - const owner = await this.rooms.getOwner(roomId); - - if (owner != req.user.userId) { - throw new AppError(ROOM_NOT_FOUND); - } - - const result = await this.rooms.delete(roomId); - - if (!result) { - throw new AppError(DELETE_ROOM_ERROR); - } - - return res.status(200).json({ - message: 'Salle supprimé avec succès.' - }); - - } catch (error) { - return next(error); - } - } - - rename = async (req, res, next) => { - try { - const { roomId, newTitle } = req.body; - - if (!roomId || !newTitle) { - throw new AppError(MISSING_REQUIRED_PARAMETER); - } - - const owner = await this.rooms.getOwner(roomId); - - if (owner != req.user.userId) { - throw new AppError(ROOM_NOT_FOUND); - } - - const exists = await this.rooms.roomExists(newTitle, req.user.userId); - - if (exists) { - throw new AppError(ROOM_ALREADY_EXISTS); - } - - const result = await this.rooms.rename(roomId, req.user.userId, newTitle); - - if (!result) { - throw new AppError(UPDATE_ROOM_ERROR); - } - - return res.status(200).json({ - message: 'Salle mis � jours avec succ�s.' - }); - - } catch (error) { - return next(error); - } - } - - getRoomById = async (req, res, next) => { - try { - const { roomId } = req.params; - - if (!roomId) { - throw new AppError(MISSING_REQUIRED_PARAMETER); - } - - // Is this room mine - const owner = await this.rooms.getOwner(roomId); - - if (owner != req.user.userId) { - throw new AppError(ROOM_NOT_FOUND); - } - - const room = await this.rooms.getRoomById(roomId); - - if (!room) { - throw new AppError(ROOM_NOT_FOUND); - } - - return res.status(200).json({ - data: room - }); - } catch (error) { - return next(error); - } - } - getRoomTitle = async (req, res, next) => { - try { - const { roomId } = req.params; - - if (!roomId) { - throw new AppError(MISSING_REQUIRED_PARAMETER); - } - - const room = await this.rooms.getRoomById(roomId); - - if (room instanceof Error) { - throw new AppError(ROOM_NOT_FOUND); - } - - return res.status(200).json({ title: room.title }); - } catch (error) { - return next(error); - } - } - roomExists = async (req, res, next) => { - try { - const { title } = req.body; - - if (!title) { - throw new AppError(MISSING_REQUIRED_PARAMETER); - } - - const exists = await this.rooms.roomExists(title); - - return res.status(200).json({ - exists: exists - }); - } catch (error) { - return next(error); - } - } - getRoomTitleByUserId = async (req, res, next) => { - try { - const { userId } = req.params; - - if (!userId) { - throw new AppError(MISSING_REQUIRED_PARAMETER); - } - - const rooms = await this.rooms.getUserRooms(userId); - - if (!rooms || rooms.length === 0) { - throw new AppError(ROOM_NOT_FOUND); - } - - const roomTitles = rooms.map(room => room.title); - - return res.status(200).json({ - titles: roomTitles - }); - } catch (error) { - return next(error); - } - } - - -} - -module.exports = RoomsController; \ No newline at end of file +module.exports = RoomsController; diff --git a/server/models/room.js b/server/models/room.js index 2ef9cbe..a329608 100644 --- a/server/models/room.js +++ b/server/models/room.js @@ -16,7 +16,9 @@ class Rooms { const roomsCollection = conn.collection('rooms'); - const existingRoom = await roomsCollection.findOne({ title: title, userId: userId }); + const normalizedTitle = title.toLowerCase(); + + const existingRoom = await roomsCollection.findOne({ title: normalizedTitle, userId: userId }); if (existingRoom) { throw new Error('Room already exists'); @@ -101,7 +103,8 @@ class Rooms { const conn = this.db.getConnection(); const roomsCollection = conn.collection('rooms'); - const existingRoom = await roomsCollection.findOne({ title: title }); + const normalizedTitle = title.toLowerCase(); + const existingRoom = await roomsCollection.findOne({ title: normalizedTitle }); return existingRoom ? true : false; }