Overview
MeetMates is a college-exclusive video chat platform built with a modern, full-stack architecture. The system enables random peer-to-peer video connections between authenticated college students using WebRTC for media streaming and Socket.IO for real-time signaling.High-Level Architecture
Tech Stack
Frontend Technologies
| Technology | Version | Purpose |
|---|---|---|
| React | 19.0.0 | UI framework for building interactive components |
| Vite | 6.2.3 | Build tool and development server with HMR |
| Socket.IO Client | 4.8.1 | Real-time bidirectional event-based communication |
| Axios | 1.8.4 | HTTP client for REST API calls |
| Tailwind CSS | 4.0.13 | Utility-first CSS framework for styling |
| Lucide React | 0.525.0 | Icon library for UI elements |
| Firebase | 11.5.0 | Additional services integration (optional) |
Backend Technologies
| Technology | Version | Purpose |
|---|---|---|
| Node.js | - | JavaScript runtime environment |
| Express | 4.21.2 | Web application framework for REST APIs |
| Socket.IO | 4.8.1 | WebSocket server for real-time communication |
| MongoDB | 6.15.0 | NoSQL database for user data |
| Mongoose | 8.13.2 | MongoDB ODM for data modeling |
| JWT | 9.0.2 | JSON Web Tokens for authentication |
| bcrypt | 6.0.0 | Password hashing |
| Google Auth Library | 10.1.0 | Google OAuth 2.0 client verification |
| Tesseract.js | 6.0.1 | OCR for ID card authentication |
| Multer | 1.4.5-lts.2 | File upload middleware |
| UUID | 11.1.0 | Unique identifier generation |
| CORS | 2.8.5 | Cross-Origin Resource Sharing middleware |
Development Tools
- ESLint - Code linting and quality enforcement
- Nodemon - Auto-restart for backend development
- Dotenv - Environment variable management
Directory Structure
Backend Structure
Frontend Structure
Core Components
1. Authentication System
MeetMates implements multiple authentication methods:A. Google OAuth 2.0 (Primary)
Flow:- User clicks “Continue with Google” button
- Frontend initializes Google Sign-In (
googleAuth.js) - User selects Google account
- Google returns credential token to frontend
- Frontend sends credential to backend
/api/auth/google-login - Backend verifies token with Google OAuth2Client
- Backend checks if user exists in database:
- New user: Create user document with Google profile data
- Existing user: Update Google-related fields if needed
- Backend generates JWT token with user ID and email
- Frontend stores JWT in localStorage
- Frontend includes JWT in Authorization header for protected routes
- Frontend:
src/components/Login.jsx:8-60,src/googleAuth.js - Backend:
routes/auth.js:94-194
B. Email/Password Authentication
Flow:- User enters college email (
@adgitmdelhi.ac.in) and password - Frontend validates email domain
- Frontend sends credentials to
/api/auth/signupor/api/auth/login - Backend validates email format and domain
- For signup: Hash password with bcrypt, create user
- For login: Compare hashed password, generate JWT
- Frontend stores JWT and redirects to main app
- Frontend:
src/components/Login.jsx:62-120 - Backend:
routes/auth.js:21-92 - Model:
models/User.js:64-77(password hashing)
C. ID Card OCR Authentication
Flow:- User uploads photo of college ID card
- Frontend sends image to
/api/auth/image-login - Backend uses Multer to save image temporarily
- Tesseract.js extracts text from image
- Backend parses enrollment number (11-digit) and name
- Backend generates user ID:
firstname.lastname[first3digits]@adgitmdelhi.ac.in - Backend returns generated credentials
- User can use these credentials for email/password login
- Frontend:
src/components/Login.jsx:122-170 - Backend:
routes/imageAuth.js
2. User Matching System
The backend implements an intelligent matching algorithm inserver.js:323-386.
Data Structures:
-
User requests chat (
findChatevent):- Add user to
waitingUsersarray - Add to
videoEnabledUsersset if video requested - Emit “waiting” state to user
- Add user to
-
Preference-based matching (
matchUsersByVideoPreference):- Match video users with video users
- Match text-only users with text-only users
- Creates optimal pairs based on preferences
-
Cross-preference matching (
matchRemainingUsers):- If video and text-only users remain unpaired
- Match them together (video enabled for the pair)
-
Create chat pair (
createChatPair):- Generate unique room ID (UUID)
- Join both users to Socket.IO room
- Store pair in
chatPairsobject - Emit “chatStart” event to both users
- Log match with user emails (if authenticated)
- Backend:
server.js:119-386
3. WebRTC Video Communication
WebRTC enables peer-to-peer video/audio streaming between matched users. Signaling Flow:server.js:224-267):
- ready-to-connect: Users signal they’re ready to establish WebRTC
- create-offer: Server tells lower socket ID to create offer (prevents race conditions)
- webrtc-offer: Relay SDP offer from User A to User B
- webrtc-answer: Relay SDP answer from User B to User A
- ice-candidate: Relay ICE candidates between peers
components/VideoChat.jsx):
- Create RTCPeerConnection
- Add local media stream tracks
- Handle ICE candidate generation
- Create and send offer/answer
- Set remote description when received
- Display remote stream when received
- Backend:
server.js:224-267 - Frontend:
src/components/VideoChat.jsx
4. Real-Time Messaging
Text chat works alongside video using Socket.IO. Message Flow:- User types message in ChatRoom component
- Frontend emits “sendMessage” event with message text
- Backend receives message from sender’s socket
- Backend looks up chat pair to find partner
- Backend emits “message” event to entire room (both users)
- Both clients receive message with:
sender: Socket IDtext: Message contentsenderEmail: User’s email (if authenticated)timestamp: ISO timestamp
- Frontend renders message in chat UI
- Backend:
server.js:173-183 - Frontend:
src/components/ChatRoom.jsx
5. Connection Lifecycle
Connection:Database Schema
User Collection
email: Unique index for fast user lookupgoogleId: Unique sparse index for OAuth usersgeneratedUserId: Sparse index for ID card users
comparePassword(candidatePassword): Verify password hashupdateLastLogin(): Update last login timestamp
pre('save'): Hash password before saving (for non-Google users)
Security Architecture
Authentication Security
-
JWT Token Security:
- Tokens signed with
JWT_SECRET - 7-day expiration
- Includes
userId,email,isGoogleUser - Verified on protected routes
- Tokens signed with
-
Password Security:
- Hashed with bcrypt (salt rounds: 10)
- Never stored or transmitted in plain text
- Minimum length: 6 characters
-
Google OAuth Security:
- Tokens verified with Google’s servers
- Client ID validation
- Email verification required
Network Security
-
CORS Configuration:
- Whitelist specific origins
- Credentials allowed only for trusted origins
- Blocks unauthorized domains
-
Socket.IO Security:
- Optional authentication middleware available
- Token verification for socket connections
- Room-based isolation (users only receive messages from their room)
-
WebRTC Security:
- Peer-to-peer encryption (DTLS-SRTP)
- Signaling through authenticated Socket.IO connection
- No media passes through server
Input Validation
-
Email Validation:
- Domain restriction (
@adgitmdelhi.ac.in) - Format validation with regex
- Normalization (lowercase, trim)
- Domain restriction (
-
File Upload Security:
- Multer middleware for controlled uploads
- Files stored in temporary directory
- Immediate deletion after processing
- No permanent storage of user images
Data Flow Examples
Example 1: Complete User Journey (Google OAuth + Video Chat)
- User opens app →
App.jsxloads - No JWT in localStorage → Redirects to
Login.jsx - User clicks Google Sign-In →
googleAuth.jsinitializes OAuth - Google returns credential → Frontend POSTs to
/api/auth/google-login - Backend verifies with Google → Creates/updates user in MongoDB
- Backend returns JWT → Frontend stores in localStorage
- Frontend connects Socket.IO →
Socket.jsxestablishes connection - User clicks “Start Video Chat” → Emits
findChatwithwithVideo=true - Backend adds to waiting queue → Waits for another video user
- Another user requests video → Backend matches both users
- Backend emits “chatStart” → Both clients receive match notification
- Clients emit “ready-to-connect” → Backend determines offer/answer roles
- User A creates WebRTC offer → Sends to backend via
webrtc-offer - Backend relays to User B → User B receives offer
- User B creates answer → Sends via
webrtc-answer - ICE candidates exchanged → Direct P2P connection established
- Video streams → Direct between peers, not through server
- User sends message → Goes through Socket.IO for text
- User clicks “Next” → Backend disconnects pair, re-queues both
Example 2: Authentication Middleware Flow
Protected Route Request:Performance Considerations
Backend Optimization
-
Connection Pooling:
- MongoDB uses connection pooling by default
- Socket.IO maintains persistent connections
-
Efficient Matching:
- O(n) matching algorithm
- Preference-based pairing reduces wait time
- Immediate matching when pairs available
-
Memory Management:
- In-memory queues for active users only
- Cleanup on disconnect
- No session storage (stateless JWT)
Frontend Optimization
-
Vite Build:
- Fast HMR during development
- Optimized production builds
- Code splitting
- Tree shaking
-
React Optimization:
- Component-based architecture
- Conditional rendering
- Event handler optimization
-
WebRTC:
- Direct P2P reduces server load
- Adaptive bitrate
- ICE candidate optimization
Scalability Considerations
Current Limitations
-
Single Server:
- All connections to one Node.js instance
- In-memory matching state
- Limited by single server capacity
-
No Load Balancing:
- Sticky sessions required if scaled
- Socket.IO state not shared across instances
Scaling Strategies
-
Horizontal Scaling:
- Use Redis adapter for Socket.IO
- Share matching queue via Redis
- Enable load balancing with session affinity
-
Database Scaling:
- MongoDB replica sets for read scaling
- Sharding for large user bases
- Caching layer (Redis) for frequent queries
-
CDN:
- Serve static frontend assets via CDN
- Reduce server load
- Improve global latency
-
Microservices (Future):
- Separate authentication service
- Dedicated matching service
- WebRTC TURN/STUN servers for NAT traversal
Monitoring & Debugging
Backend Logging
Frontend Debugging
- React DevTools: Component hierarchy and state
- Browser Console: Socket.IO events and WebRTC logs
- Network Tab: API calls, WebSocket frames, STUN/TURN
Metrics to Monitor
- Total online users
- Users in waiting queue
- Active chat pairs
- Average wait time
- Connection success rate
- WebRTC connection failures
- Authentication failures
- Database query performance
Next Steps
- Complete Local Development Setup
- Configure Environment Variables
- Explore Authentication API and Socket Events
- Review Features Documentation