Skip to content

Commit

Permalink
Update (#54)
Browse files Browse the repository at this point in the history
* Update (#4)

* Fix bug: wrong import

* Remove redundancy

* Update README.md

* Change port number to be different from user service

* Update README.md with the new port numbers

* Implement authentication for all question services

* Update package*.json files

* Add user service and update all the port numbers

* Remove unnecessary import

* Fix bug: wrong url

* Remove token upon logging out or deletion of account

* Route all unauthenticated requests to /login page

* Include token in request header to question service

* Modify authenticate token URL to be production-based

* Add comments to clarify URL choice

* add Adding Question Components

* update QuestionDialog to take up whole container

* add delete question functionalities

---------

Co-authored-by: Eugene <ekweirui@gmail.com>
Co-authored-by: Tan-Jia-Rong <tanjiarongtjr@gmail.com>
Co-authored-by: Wei Rui <95850532+ekweirui@users.noreply.github.com>
Co-authored-by: Jia Rong <71122323+Tan-Jia-Rong@users.noreply.github.com>

* Update collab service terminate session logic

* Implement chatbox

* Update (#5)

* Fix bug: wrong import

* Remove redundancy

* Update README.md

* Change port number to be different from user service

* Update README.md with the new port numbers

* Implement authentication for all question services

* Update package*.json files

* Add user service and update all the port numbers

* Remove unnecessary import

* Fix bug: wrong url

* Remove token upon logging out or deletion of account

* Route all unauthenticated requests to /login page

* Include token in request header to question service

* Modify authenticate token URL to be production-based

* Add comments to clarify URL choice

* add Adding Question Components

* update QuestionDialog to take up whole container

* add delete question functionalities

* update Question Page View

* remove irrelevant files

* update package-lock.json name

* Deploy website publicly

---------

Co-authored-by: Eugene <ekweirui@gmail.com>
Co-authored-by: Tan-Jia-Rong <tanjiarongtjr@gmail.com>
Co-authored-by: Wei Rui <95850532+ekweirui@users.noreply.github.com>
Co-authored-by: Jia Rong <71122323+Tan-Jia-Rong@users.noreply.github.com>
Co-authored-by: Kenvyn Kwek <kenvynkwek@gmail.com>

* Update (#6)

* Fix bug: wrong import

* Remove redundancy

* Update README.md

* Change port number to be different from user service

* Update README.md with the new port numbers

* Implement authentication for all question services

* Update package*.json files

* Add user service and update all the port numbers

* Remove unnecessary import

* Fix bug: wrong url

* Remove token upon logging out or deletion of account

* Route all unauthenticated requests to /login page

* Include token in request header to question service

* Modify authenticate token URL to be production-based

* Add comments to clarify URL choice

* add Adding Question Components

* update QuestionDialog to take up whole container

* add delete question functionalities

* update Question Page View

* remove irrelevant files

* update package-lock.json name

* Deploy website publicly

---------

Co-authored-by: Eugene <ekweirui@gmail.com>
Co-authored-by: Tan-Jia-Rong <tanjiarongtjr@gmail.com>
Co-authored-by: Wei Rui <95850532+ekweirui@users.noreply.github.com>
Co-authored-by: Jia Rong <71122323+Tan-Jia-Rong@users.noreply.github.com>
Co-authored-by: Kenvyn Kwek <kenvynkwek@gmail.com>

* Update to use userid

* Update

* Backend for collab service

* Update accordingly to pr comments

* Setup frontend for testing of collab service

* Set up Collab Service Backend (#37)

* Update Group

* Add account service and account login api

* no message

* Update according to PR comments + UI changes

* Convert flask and python to node.js and express

* Update to use demo app and demo service

* Revert "Update according to merge conflicts"

This reverts commit 363778f, reversing
changes made to 0e44887.
undo commit

* Resolve merge conflict

* Update delete api

* Shift Login and Delete auth to frontend

* Delete env

* Added profile icon to question page

* no message

* Decoupled questioncontroller based on pr review

* Backend for collab service

* Update accordingly to pr comments

* Update some cmts

* Update dual column view

Question and question details on the left, textarea on the right (temporary black/pink border for development ease/visuals).

* Update left side question frontend

Added title, difficulty, topics and description.

* Update leftside question view

Added question id and examples.

* Update leftside question view

Added question constraints.

* Add border

* Install shadcn menubar

* Revert "Install shadcn menubar"

This reverts commit 8452ba1.

* Add navigation bar

* Update collab service terminate session logic

* Implement chatbox

* Update (#5)

* Fix bug: wrong import

* Remove redundancy

* Update README.md

* Change port number to be different from user service

* Update README.md with the new port numbers

* Implement authentication for all question services

* Update package*.json files

* Add user service and update all the port numbers

* Remove unnecessary import

* Fix bug: wrong url

* Remove token upon logging out or deletion of account

* Route all unauthenticated requests to /login page

* Include token in request header to question service

* Modify authenticate token URL to be production-based

* Add comments to clarify URL choice

* add Adding Question Components

* update QuestionDialog to take up whole container

* add delete question functionalities

* update Question Page View

* remove irrelevant files

* update package-lock.json name

* Deploy website publicly

---------

Co-authored-by: Eugene <ekweirui@gmail.com>
Co-authored-by: Tan-Jia-Rong <tanjiarongtjr@gmail.com>
Co-authored-by: Wei Rui <95850532+ekweirui@users.noreply.github.com>
Co-authored-by: Jia Rong <71122323+Tan-Jia-Rong@users.noreply.github.com>
Co-authored-by: Kenvyn Kwek <kenvynkwek@gmail.com>

* Update (#6)

* Fix bug: wrong import

* Remove redundancy

* Update README.md

* Change port number to be different from user service

* Update README.md with the new port numbers

* Implement authentication for all question services

* Update package*.json files

* Add user service and update all the port numbers

* Remove unnecessary import

* Fix bug: wrong url

* Remove token upon logging out or deletion of account

* Route all unauthenticated requests to /login page

* Include token in request header to question service

* Modify authenticate token URL to be production-based

* Add comments to clarify URL choice

* add Adding Question Components

* update QuestionDialog to take up whole container

* add delete question functionalities

* update Question Page View

* remove irrelevant files

* update package-lock.json name

* Deploy website publicly

---------

Co-authored-by: Eugene <ekweirui@gmail.com>
Co-authored-by: Tan-Jia-Rong <tanjiarongtjr@gmail.com>
Co-authored-by: Wei Rui <95850532+ekweirui@users.noreply.github.com>
Co-authored-by: Jia Rong <71122323+Tan-Jia-Rong@users.noreply.github.com>
Co-authored-by: Kenvyn Kwek <kenvynkwek@gmail.com>

* Update to use userid

* Update to include collab svc in docker compose + if one user terminates session, session ends for both users

* Remove merge conflict

* Update (#8)

* Fix bug: wrong import

* Remove redundancy

* Update README.md

* Change port number to be different from user service

* Update README.md with the new port numbers

* Implement authentication for all question services

* Update package*.json files

* Add user service and update all the port numbers

* Remove unnecessary import

* Fix bug: wrong url

* Remove token upon logging out or deletion of account

* Route all unauthenticated requests to /login page

* Include token in request header to question service

* Modify authenticate token URL to be production-based

* Add comments to clarify URL choice

* add Adding Question Components

* update QuestionDialog to take up whole container

* add delete question functionalities

* update Question Page View

* remove irrelevant files

* update package-lock.json name

* Deploy website publicly

* add some functions for matching service

* add matchingService

* update docker-compose

* add user authentication

* Implement MatchingButton with Timer

* Integrate matching service's frontend and backend to work together

* Remove console logging lines

* Fix bug where queue names were wrongly constructed

* Add matching service backend url

* Change localStorage to sessionStorage to isolate storage to within sessions/tabs instead of browser

* Remove test routes

* Allow CORS for public frontend website

* Update README with deploying instructions for matching service

* Remove test controller

* Update to follow PR comments: Remove users from socket map after a match

* Implement question matching service

* Implement question matching service

* Add logging statements for token authentication and verification

* Remove redundant CORS mapping

* Update README to include new build arguments for question matching functionality

* add try-catch-finally blocks

* Remove redundant files

---------

Co-authored-by: Eugene <ekweirui@gmail.com>
Co-authored-by: Tan-Jia-Rong <tanjiarongtjr@gmail.com>
Co-authored-by: Wei Rui <95850532+ekweirui@users.noreply.github.com>
Co-authored-by: Jia Rong <71122323+Tan-Jia-Rong@users.noreply.github.com>
Co-authored-by: Kenvyn Kwek <kenvynkwek@gmail.com>

* doesnt work yet

* Connect matching svc to collab svc

---------

Co-authored-by: Eugene <ekweirui@gmail.com>
Co-authored-by: Tan-Jia-Rong <tanjiarongtjr@gmail.com>
Co-authored-by: Wei Rui <95850532+ekweirui@users.noreply.github.com>
Co-authored-by: Jia Rong <71122323+Tan-Jia-Rong@users.noreply.github.com>
Co-authored-by: Kenvyn Kwek <kenvynkwek@gmail.com>
  • Loading branch information
6 people authored Oct 23, 2024
1 parent 420f7ba commit e4b5e45
Show file tree
Hide file tree
Showing 21 changed files with 3,453 additions and 42 deletions.
2 changes: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ VITE_QUESTION_SERVICE_BACKEND_URL=http://localhost:5002
VITE_MATCHING_SERVICE_BACKEND_URL=ws://localhost:5003/matching
REDIS_URL=redis://redis:6379
RABBITMQ_URL=amqp://user:password@rabbitmq:5672
VITE_COLLAB_SERVICE_BACKEND_URL=http://localhost:5004
COLLAB_SERVICE_CREATE_SESSION_BACKEND_URL=http://collab_service:5004/create-session
26 changes: 26 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@


# dependencies
/node_modules
*/node_modules

/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
6 changes: 5 additions & 1 deletion backend/collab_service/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ RUN npm install

COPY . .

EXPOSE 5001
ARG USER_SERVICE_BACKEND_URL

ENV USER_SERVICE_BACKEND_URL=$USER_SERVICE_BACKEND_URL

EXPOSE 5004

CMD ["npm", "start"]
3 changes: 2 additions & 1 deletion backend/collab_service/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const express = require("express");
const bodyParser = require("body-parser");
const collabRoutes = require('./routes/collabRoutes');
const firebaseConfig = require("./config/firebaseConfig"); // Ensure Firebase is initialized
const authenticateToken = require('./middleware/authenticateToken');
const app = express();

// Allow requests from http://localhost:3000 (production frontend) and http://localhost:5173 (development frontend) with credentials
Expand All @@ -14,7 +15,7 @@ app.use(cors({
// Middleware
app.use(express.json()); // Parse JSON request bodies
app.use(express.urlencoded({ extended: true })); // Handle URL-encoded data

app.use(authenticateToken);
// Routes
app.use('/', collabRoutes);

Expand Down
83 changes: 80 additions & 3 deletions backend/collab_service/controllers/collabController.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
const { db } = require('../config/firebaseConfig');
const socketSessions = {};

class CollabController {
joinSession = async (req, res) => {
const { sessionId, userId } = req.body;
/*joinSession = async (req, res) => {
const { sessionId } = req.body;
const userId = req.socket.id;
try {
const sessionRef = db.collection('sessions').doc(sessionId);
Expand All @@ -21,6 +23,76 @@ class CollabController {
res.status(500).json({ error: 'Failed to join session' });
}
}
*/

handleSessionCreated = async (req, res) => {
// Debugging: Log incoming request data
console.log('Incoming request data:', req.body);

const { sessionId, sessionData, questionData} = req.body; // Assuming this is how you're getting data

// Check if sessionId and sessionData are provided
if (!sessionId || !sessionData) {
console.error('Missing sessionId or sessionData:', { sessionId, sessionData });
return res.status(400).json({ message: 'Both sessionId and sessionData are required.' });
}

// Debugging: Log sessionId and sessionData
console.log('Session ID:', sessionId);
console.log('Session Data:', sessionData);

// Initialize session if it doesn't exist
if (!socketSessions[sessionId]) {
socketSessions[sessionId] = {
users: [], // Array to hold user IDs
prevUserSessionData: {}, // Object for previous user session data
currUserSessionData: {} // Object for current user session data
};
}

// Extract previous and current user session data
const { prevUserSessionData, currUserSessionData } = sessionData;

// Add previous user session data if it exists
if (prevUserSessionData && prevUserSessionData.uid) {
socketSessions[sessionId].prevUserSessionData = prevUserSessionData;
console.log(`Previous user session data added to session ${sessionId}:`, prevUserSessionData);

// Add the previous user to the session
if (!socketSessions[sessionId].users.includes(prevUserSessionData.uid)) {
socketSessions[sessionId].users.push(prevUserSessionData.uid); // Add previous user
console.log(`User ${prevUserSessionData.uid} added to session ${sessionId}.`);
} else {
console.log(`User ${prevUserSessionData.uid} is already in session ${sessionId}.`);
}
}

// Add current user session data if it exists
if (currUserSessionData && currUserSessionData.uid) {
socketSessions[sessionId].currUserSessionData = currUserSessionData;
console.log(`Current user session data added to session ${sessionId}:`, currUserSessionData);
console.log('Current socketSessions:', socketSessions);

// Add the current user to the session
if (!socketSessions[sessionId].users.includes(currUserSessionData.uid)) {
socketSessions[sessionId].users.push(currUserSessionData.uid); // Add current user
console.log(`User ${currUserSessionData.uid} added to session ${sessionId}.`);
} else {
console.log(`User ${currUserSessionData.uid} is already in session ${sessionId}.`);
}
}

try {
const sessionRef = db.collection('sessions').doc(sessionId);
socketSessions[sessionId].questionData = questionData; // Add questionData to session data
await sessionRef.set(socketSessions[sessionId]); // Save all session data including questionData
} catch (error) {
console.error('Error saving session data to Firestore:', error);
return res.status(500).json({ message: 'Failed to save session data.' });
}

return res.status(200).json({ message: 'Users added to session successfully.', sessionData: socketSessions[sessionId] });
}

terminateSession = async (req, res) => {
const { sessionId } = req.body;
Expand All @@ -34,4 +106,9 @@ class CollabController {
}
}

module.exports = new CollabController();
const collabControllerInstance = new CollabController();

module.exports = {
collabController: collabControllerInstance, // Export the instance
socketSessions, // Export socketSessions
};
31 changes: 31 additions & 0 deletions backend/collab_service/middleware/authenticateToken.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const authenticateToken = async (req, res, next) => {
const authHeader = req.headers.authorization;
const token = authHeader && authHeader.split(' ')[1];

if (token == null) return res.status(401).json({ message: 'Token required' });

try {
// Verify the token with the user service
const userServiceBackendUrl = process.env.USER_SERVICE_BACKEND_URL || "http://localhost:5001/verify-token";
const response = await fetch(userServiceBackendUrl, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
});

if (response.ok) {
const userData = await response.json();
req.user = userData; // Store user data in the request
next();
} else {
const errorData = await response.json(); // Get the error response
res.status(response.status).json({ message: errorData.message || 'Invalid Token' });
}
} catch (error) {
res.status(500).json({ message: 'Internal Collab Service Server Error' });
}
};

module.exports = authenticateToken;
8 changes: 8 additions & 0 deletions backend/collab_service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js"
},
"keywords": [
"api",
"express",
"jokes",
"docker"
],
"author": "Jai Lulla",
"license": "ISC",
"dependencies": {
"bcryptjs": "^2.4.3",
"body-parser": "^1.20.2",
Expand Down
9 changes: 6 additions & 3 deletions backend/collab_service/routes/collabRoutes.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
// routes/collabRoutes.js
const express = require('express');
const router = express.Router();
const CollabController = require('../controllers/collabController');
const { collabController, socketSessions } = require('../controllers/collabController');


// Route for joining a session
router.post('/join-session', CollabController.joinSession);
//router.post('/join-session', CollabController.joinSession);

// Route to terminate a session
router.post('/terminate-session', CollabController.terminateSession);
router.post('/terminate-session', collabController.terminateSession);

router.post('/create-session', collabController.handleSessionCreated);

module.exports = router;

68 changes: 63 additions & 5 deletions backend/collab_service/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ const io = socketIo(server, {
}
});

const collabRoutes = require('./routes/collabRoutes');
app.use(express.json());
app.use('/', collabRoutes);

const { collabController, socketSessions } = require('./controllers/collabController');
console.log('socketSessions initialized:', socketSessions);

// Handle new socket connections
io.on('connection', (socket) => {
console.log('A user connected:', socket.id);
Expand All @@ -20,20 +27,71 @@ io.on('connection', (socket) => {
console.error('Socket error:', err);
});


// Joining a specific collaboration session
socket.on('joinSession', (sessionId) => {
/*socket.on('joinSession', ({ sessionId, userId }) => {
socket.join(sessionId);
console.log(`User ${socket.id} joined session ${sessionId}`);
// Emit the sessionId and userId back to the client
socket.emit('sessionJoined', { sessionId, userId: socket.id });
});
*/

/*socket.on('matched', async (data) => {
console.log('Received matched data:', data);
// Here, emit the question data to the corresponding user in the collaboration session
data.sessionData.uid = socket.id; // Get the userId from sessionData
socket.to(userId).emit('questionDataReceived', data.questionData);
});
*/

socket.on('sessionJoined', (sessionId) => {
console.log(`Received sessionId:`, sessionId);
console.log('Current socketSessions:', socketSessions);
console.log(`User ${socket.id} is trying to join session ${sessionId}`);
if (socketSessions && socketSessions[sessionId]) {
socket.join(sessionId);
console.log(`User ${socket.id} joined session ${sessionId}`);

const sessionData = socketSessions[sessionId];
console.log(`Emitting session data for session ${sessionId}:`, JSON.stringify(sessionData, null, 2));

io.to(sessionId).emit('sessionData', {
sessionIdObj: sessionId, // Renamed sessionId to sessionIdObj for consistency
socketId: socket.id,
questionData: sessionData.questionData, // Include questionData
});

console.log(`Session data emitted for socket ${socket.id}`); // Debugging statement
} else {
console.error('No session data found for session ID:', sessionId); // Debugging statement
}
});

// Handle real-time code updates
socket.on('codeUpdate', (data) => {
const { sessionId, code } = data;
const { sessionIdObj, code } = data;
// Broadcast the code update to all users in the same session
socket.to(sessionId).emit('codeUpdated', { code });
console.log(`Code updated in session ${sessionId}: ${code}`);
console.log(`Received code update request for session: ${sessionIdObj}`);
socket.to(sessionIdObj).emit('codeUpdated', { code });
console.log(`Code updated in session ${sessionIdObj}: ${code}`);
});

socket.on('sendMessage', (data) => {
const { sessionId, message} = data; // Extract sessionId, message, and username
io.to(sessionId).emit('messageReceived', {
username: socket.id, // Send the current user's username
message, // Send the message
});
});


socket.on('terminateSession', (sessionId) => {
// Notify all users in the session except the one who terminated it
socket.to(sessionId).emit('sessionTerminated', { userId: socket.id });
});

// Handle disconnect
socket.on('disconnect', () => {
console.log('A user disconnected:', socket.id);
Expand All @@ -51,4 +109,4 @@ server.listen(5004, (err) => {
console.log('Listening for WebSocket connections...');
});

module.exports = { io };
module.exports = { io };
2 changes: 2 additions & 0 deletions backend/matching_service/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ ARG USER_SERVICE_BACKEND_URL
ARG QUESTION_SERVICE_TOPIC_AND_DIFFICULTY_BACKEND_URL
ARG REDIS_URL
ARG RABBITMQ_URL
ARG COLLAB_SERVICE_CREATE_SESSION_BACKEND_URL

ENV USER_SERVICE_BACKEND_URL=$USER_SERVICE_BACKEND_URL
ENV QUESTION_SERVICE_TOPIC_AND_DIFFICULTY_BACKEND_URL=$QUESTION_SERVICE_TOPIC_AND_DIFFICULTY_BACKEND_URL
ENV REDIS_URL=$REDIS_URL
ENV RABBITMQ_URL=$RABBITMQ_URL
ENV COLLAB_SERVICE_CREATE_SESSION_BACKEND_URL=$COLLAB_SERVICE_CREATE_SESSION_BACKEND_URL

EXPOSE 5003

Expand Down
Loading

0 comments on commit e4b5e45

Please sign in to comment.