π§ Project Status: Active Development (60% Complete)
A production-grade, real-time web application for instant text and image sharing between devices using temporary pairing codes. Built with modern engineering patterns and best practices for technical interviews.
ctrl+w enables seamless, secure real-time synchronization between devices (phones, laptops, tablets) using simple 6-digit pairing codes. No app installation or account creation required for basic useβjust enter a code and start syncing.
β Dual Authentication System
- Optional JWT-based auth with access + refresh token pattern
- Anonymous session support for privacy-focused users
- Role-based access control (user/admin)
- Secure password hashing with bcrypt (10 salt rounds)
β Database Architecture
- MongoDB Atlas cloud database with Mongoose ODM
- Four core models: User, Session, Message, File
- Optimized compound indexes for query performance
- TTL indexes for automatic session cleanup
β Security & Performance
- Rate limiting on authentication endpoints (5 attempts/15min)
- Helmet.js for security headers
- CORS configuration with credential support
- Token rotation on refresh for enhanced security
- httpOnly cookies for refresh token storage
β Developer Experience
- Comprehensive ESLint + Prettier configuration
- Jest unit and integration test suites
- Environment-based configuration
- Modular service-layer architecture
β³ Real-Time Communication (Week 3, Starting Soon)
- WebSocket server with Socket.io
- Room-based message broadcasting
- Presence detection and typing indicators
β³ File Upload System (Week 4)
- Cloudinary CDN integration
- 4MB file size limit with validation
- Image optimization and thumbnails
β³ Frontend Application (Week 5)
- Responsive UI (mobile + desktop)
- Vanilla JavaScript (no framework dependencies)
- WebSocket client for real-time updates
β³ Production Deployment (Week 6)
- CI/CD pipeline with GitHub Actions
- Vercel deployment configuration
- Environment management
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CLIENT LAYER β
β β’ Vanilla JS Frontend β
β β’ WebSocket Client (Socket.io) β
β β’ Responsive CSS (Mobile-first) β
βββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ
β
β HTTP/WebSocket
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β APPLICATION LAYER β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β β Auth Service β βSession Serviceβ β File Service β β
β β β β β β β β
β β β’ JWT Gen β β β’ Code Gen β β β’ Cloudinary β β
β β β’ Verify β β β’ Validation β β β’ Validation β β
β β β’ Refresh β β β’ Expiry β β β’ Metadata β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β MIDDLEWARE LAYER β β
β β β’ Auth (JWT verification) β β
β β β’ Rate Limiting (express-rate-limit) β β
β β β’ Validation (express-validator) β β
β β β’ Error Handling (centralized) β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β DATA LAYER β
β ββββββββββββββββββββ ββββββββββββββββββββ β
β β MongoDB Atlas β β Cloudinary β β
β β β β β β
β β β’ Users β β β’ Image Storage β β
β β β’ Sessions β β β’ CDN Delivery β β
β β β’ Messages β β β’ Optimization β β
β β β’ Files β β β β
β ββββββββββββββββββββ ββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
// User Model
{
email: String (unique, indexed),
password: String (bcrypt hashed),
role: Enum ['user', 'admin'],
refreshToken: String,
createdAt: Date,
updatedAt: Date
}
// Session Model
{
pairingCode: String (6-digit, unique, indexed),
creator: ObjectId (ref: User, optional),
participants: [{ socketId, deviceInfo, joinedAt }],
status: Enum ['active', 'expired', 'closed'],
expiresAt: Date (TTL indexed),
messageCount: Number,
fileCount: Number
}
// Message Model
{
session: ObjectId (ref: Session, indexed),
senderSocketId: String,
sender: ObjectId (ref: User, optional),
content: String (max 5000 chars),
type: Enum ['text', 'system'],
createdAt: Date
}
// File Model
{
session: ObjectId (ref: Session, indexed),
uploaderSocketId: String,
cloudinaryUrl: String,
cloudinaryPublicId: String,
originalName: String,
fileType: String,
fileSize: Number (max 4MB)
}- Node.js >= 18.0.0
- npm >= 9.0.0
- MongoDB Atlas account (free tier)
- Git for version control
- Clone the repository
git clone https://github.com/yourusername/ctrl-w.git
cd ctrl-w- Install dependencies
npm install- Set up environment variables
cp .env.example .envEdit .env with your credentials:
# MongoDB Atlas connection string
MONGO_URI=mongodb+srv://username:password@cluster.mongodb.net/ctrlw
# JWT secrets (generate with: node -e "console.log(require('crypto').randomBytes(64).toString('hex'))")
JWT_ACCESS_SECRET=your_generated_secret_here
JWT_REFRESH_SECRET=your_generated_secret_here
# Server configuration
PORT=5000
NODE_ENV=development- Start the development server
npm run devServer will start on http://localhost:5000
POST /api/auth/register
Content-Type: application/json
{
"email": "user@example.com",
"password": "password123"
}Response (201):
{
"success": true,
"message": "User registered successfully",
"data": {
"user": {
"id": "65abc...",
"email": "user@example.com",
"role": "user",
"createdAt": "2024-01-15T10:00:00.000Z"
},
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}POST /api/auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "password123"
}POST /api/auth/refresh
Content-Type: application/json
{
"refreshToken": "your_refresh_token"
}GET /api/auth/me
Authorization: Bearer <access_token>POST /api/auth/logout
Authorization: Bearer <access_token>npm testnpm test -- --coveragenpm run test:watch--------------------|---------|----------|---------|---------|
File | % Stmts | % Branch | % Funcs | % Lines |
--------------------|---------|----------|---------|---------|
All files | 87.5 | 82.3 | 90.1 | 88.2 |
models/ | 92.1 | 88.7 | 95.3 | 93.4 |
User.js | 95.2 | 91.2 | 97.1 | 96.3 |
Session.js | 91.8 | 87.5 | 94.2 | 92.7 |
Message.js | 89.3 | 85.1 | 92.8 | 90.1 |
File.js | 92.4 | 90.8 | 96.5 | 94.2 |
services/ | 85.7 | 78.9 | 88.3 | 86.5 |
authService.js | 85.7 | 78.9 | 88.3 | 86.5 |
middleware/ | 83.2 | 76.4 | 85.1 | 84.3 |
auth.js | 83.2 | 76.4 | 85.1 | 84.3 |
--------------------|---------|----------|---------|---------|
| Technology | Purpose | Interview Relevance |
|---|---|---|
| Node.js | Runtime environment | Non-blocking I/O, event loop |
| Express.js | Web framework | Middleware pattern, routing |
| MongoDB + Mongoose | Database | NoSQL, schema design, indexing |
| JWT | Authentication | Stateless auth, token lifecycle |
| bcrypt | Password hashing | Salt rounds, adaptive hashing |
| Socket.io | Real-time communication | WebSocket, rooms, events |
| Cloudinary | File storage | CDN, cloud services integration |
- Service Layer Pattern: Separation of business logic from HTTP layer
- Middleware Chain: Request processing pipeline
- Repository Pattern: Data access abstraction via Mongoose
- Factory Pattern: Token generation in auth service
- Strategy Pattern: Multiple authentication strategies (JWT, anonymous)
- β JWT with refresh token rotation
- β Password hashing with bcrypt (10 salt rounds)
- β Rate limiting (5 attempts/15min on auth endpoints)
- β CORS with credential support
- β Helmet.js security headers
- β Input validation with express-validator
- β httpOnly cookies for refresh tokens
- β Environment-based secrets management
-
Week 1: Project setup, MongoDB Atlas, authentication system
- npm initialization with comprehensive package.json
- ESLint + Prettier configuration
- MongoDB connection with pooling
- Environment variable management
-
Week 2: Database models and schema design
- User model with bcrypt hashing
- Session model with unique code generation
- Message model with session linking
- File model with Cloudinary integration
- Comprehensive test suite (Jest)
-
Week 3 (Partial): Authentication & JWT
- Auth service with JWT generation/verification
- Access + refresh token implementation
- Authentication middleware
- Rate limiting middleware
- Auth routes (register, login, refresh, logout)
- Week 3: WebSocket real-time layer
- Week 4: File uploads with Cloudinary
- Week 5: Frontend development
- Week 6: Testing, CI/CD, deployment
- Week 7: Documentation & polish
This project was built with technical interviews in mind. Key discussion points:
- "How would you design a real-time messaging system?"
- "How would you handle authentication at scale?"
- "How would you implement rate limiting?"
- Service layer pattern for business logic separation
- Middleware chain for request processing
- Stateless JWT authentication with refresh tokens
- Schema design: embedded vs referenced documents
- Indexing strategy for query optimization
- TTL indexes for automatic cleanup
- Token-based authentication
- Password hashing with adaptive algorithms
- Rate limiting for DDoS protection
- CORS and security headers
- Unit tests for model validation
- Integration tests for API endpoints
- Test coverage reporting
ctrl-w/
βββ backend/
β βββ config/
β β βββ database.js # MongoDB connection
β βββ models/
β β βββ User.js # User schema
β β βββ Session.js # Session schema
β β βββ Message.js # Message schema
β β βββ File.js # File schema
β β βββ index.js # Model exports
β βββ services/
β β βββ authService.js # Authentication logic
β βββ middleware/
β β βββ auth.js # JWT verification
β β βββ rateLimiter.js # Rate limiting
β βββ routes/
β β βββ auth.routes.js # Auth endpoints
β βββ tests/
β β βββ unit/
β β β βββ models/ # Model unit tests
β β βββ integration/
β β βββ models/ # Model integration tests
β βββ app.js # Express configuration
β βββ server.js # Server entry point
βββ .env.example # Environment template
βββ .eslintrc.json # ESLint configuration
βββ .prettierrc # Prettier configuration
βββ .gitignore # Git ignore rules
βββ jest.config.js # Jest configuration
βββ package.json # Dependencies
βββ README.md # This file
# Development
npm run dev # Start with nodemon (auto-reload)
# Production
npm start # Start production server
# Testing
npm test # Run all tests
npm run test:watch # Run tests in watch mode
# Code Quality
npm run lint # Check code with ESLint
npm run lint:fix # Fix ESLint issues
npm run format # Format code with Prettier
npm run format:check # Check formattingBackend Development:
- RESTful API design and implementation
- Database schema design with MongoDB
- JWT authentication with refresh tokens
- WebSocket real-time communication
- File upload handling and cloud storage
- Rate limiting and security best practices
Software Engineering:
- Service-oriented architecture
- Middleware pattern implementation
- Error handling strategies
- Testing (unit + integration)
- Environment configuration management
DevOps & Tools:
- Git version control
- npm package management
- ESLint and Prettier for code quality
- Jest for testing
- MongoDB Atlas cloud database
- Node.js Design Patterns (Book)
- Clean Code by Robert C. Martin
- System Design Interview by Alex Xu
This is a learning project for interview preparation. Feedback and suggestions are welcome!
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
[Yasin Hajilou]
- Built as part of technical interview preparation
- Inspired by modern real-time collaboration tools
- Thanks to the open-source community for excellent tools and libraries
β Star this repo if you found it helpful for your interview prep!
π§ Project actively under development - Check back for updates!