Skip to content

Commit

Permalink
Minor Fix on the Collaboration Service (CS3219-AY2425S1#86)
Browse files Browse the repository at this point in the history
* Minor Fix on the Collaboration Service Database
- Fix the part where the room is initialised as api/collaboration/room_id
to only room_id

* Minor Fix to Collaboration Service Based On Comments
- Remove guard clause
- Change the way of handling the authorise under webSocketService

* Feed roomId as docName

---------

Co-authored-by: Samuel Lim <samuelim01@gmail.com>
  • Loading branch information
KhoonSun47 and samuelim01 authored Nov 8, 2024
1 parent 1794597 commit 9ff60da
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 16 deletions.
3 changes: 0 additions & 3 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ YJS_DB_LOCAL_URI=mongodb://collaboration-db:27017/yjs-documents
HISTORY_DB_CLOUD_URI=<FILL-THIS-IN>
HISTORY_DB_LOCAL_URI=mongodb://history-db:27017/history

# Will use cloud MongoDB Atlas database
ENV=PROD

# Broker
BROKER_URL=amqp://broker:5672

Expand Down
1 change: 1 addition & 0 deletions services/collaboration/src/controllers/roomController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ export const updateUserStatusInRoomController = async (req: Request, res: Respon

// Check if all users in the room have forfeited
const allUsersForfeited = updatedRoom.users.every(user => user.isForfeit === true);
console.log('All users forfeited check:', allUsersForfeited, updatedRoom.users);
if (allUsersForfeited) {
// Close the room if both users have forfeited
const result = await closeRoomById(roomId);
Expand Down
11 changes: 9 additions & 2 deletions services/collaboration/src/services/mongodbService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,10 @@ export const createYjsDocument = async (roomId: string) => {
*/
export const deleteYjsDocument = async (roomId: string) => {
try {
console.log(`Attempting to delete Yjs document collection for room: ${roomId}`);
const db = await connectToYJSDB();
await db.collection(roomId).drop();
console.log(`Yjs document collection for room ${roomId} deleted`);
const result = await db.collection(roomId).drop();
console.log(`Yjs document collection for room ${roomId} deleted successfully: ${result}`);
} catch (error) {
console.error(`Failed to delete Yjs document for room ${roomId}:`, error);
throw error;
Expand Down Expand Up @@ -196,6 +197,12 @@ export const closeRoomById = async (roomId: string) => {
}
};

/**
* Update the user isForfeit status in a room
* @param roomId
* @param userId
* @param isForfeit
*/
export const updateRoomUserStatus = async (roomId: string, userId: string, isForfeit: boolean) => {
try {
const db = await connectToRoomDB();
Expand Down
30 changes: 19 additions & 11 deletions services/collaboration/src/services/webSocketService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,20 @@ const { setPersistence, setupWSConnection } = require('../utils/utility.js');

const URL_REGEX = /^.*\/([0-9a-f]{24})\?accessToken=([a-zA-Z0-9\-._~%]{1,})$/;

const authorize = async (ws: WebSocket, request: IncomingMessage): Promise<boolean> => {
/**
* Verifies the user's access to a specific room by validating the JWT token,
* checking the room's status, and ensuring the user has not forfeited.
* Returns `roomId` if the access is authorized, or `null` otherwise.
* @param ws
* @param request
* @returns
*/
const authorize = async (ws: WebSocket, request: IncomingMessage): Promise<string | null> => {
const url = request.url ?? '';
const match = url?.match(URL_REGEX);
if (!match) {
handleAuthFailed(ws, 'Authorization failed: Invalid format');
return false;
return null;
}
const roomId = match[1];
const accessToken = match[2];
Expand All @@ -34,27 +42,27 @@ const authorize = async (ws: WebSocket, request: IncomingMessage): Promise<boole
});
if (!user) {
handleAuthFailed(ws, 'Authorization failed: Invalid token');
return false;
return null;
}

const room = await findRoomById(roomId, user.id);
if (!room) {
handleAuthFailed(ws, 'Authorization failed');
return false;
return null;
}

if (!room.room_status) {
handleRoomClosed(ws);
return false;
return null;
}

const userInRoom = room.users.find((u: { id: string }) => u.id === user.id);
if (userInRoom?.isForfeit) {
handleAuthFailed(ws, 'Authorization failed: User has forfeited');
return false;
return null;
}
console.log('WebSocket connection established for room:', roomId);
return true;
return roomId;
};

/**
Expand All @@ -65,13 +73,13 @@ export const startWebSocketServer = (server: Server) => {
const wss = new WebSocketServer({ server });

wss.on('connection', async (conn: WebSocket, req: IncomingMessage) => {
const isAuthorized = await authorize(conn, req);
if (!isAuthorized) {
const roomId = await authorize(conn, req);
if (!roomId) {
return;
}

try {
setupWSConnection(conn, req);
setupWSConnection(conn, req, { docName: roomId });
} catch (error) {
console.error('Failed to set up WebSocket connection:', error);
handleAuthFailed(conn, 'Authorization failed');
Expand All @@ -85,7 +93,7 @@ export const startWebSocketServer = (server: Server) => {
console.log(`Loaded persisted document for ${docName}`);

const newUpdates = Y.encodeStateAsUpdate(ydoc);
mdb.storeUpdate(docName, newUpdates);
await mdb.storeUpdate(docName, newUpdates);

Y.applyUpdate(ydoc, Y.encodeStateAsUpdate(persistedYdoc));

Expand Down

0 comments on commit 9ff60da

Please sign in to comment.