A modern Twitter-like social media application with real-time updates, secure authentication, and multi-user interactions.
- Secure Registration/Login with JWT tokens
- HttpOnly Cookies for enhanced security (no localStorage vulnerabilities)
- Password Hashing with bcryptjs
- User Session Management
- Create Posts with text and image uploads
- Like/Unlike Posts with real-time updates
- Comment System with nested author population
- Multi-User Interactions - users can interact with each other's content
- WebSocket Integration with Socket.IO
- Live Post Updates - new posts appear instantly
- Real-time Like Counts - see likes update immediately
- Instant Comments - comments appear without refresh
- Rate Limiting - 5 posts per 15 minutes per user
- File Upload Security with Multer (5MB limit)
- CORS Protection with credentials support
- Input Validation and sanitization
- Node.js with Express.js framework
- MongoDB Atlas (Cloud Database)
- Mongoose ODM for data modeling
- JWT for authentication
- Socket.IO for real-time communication
- Multer for file uploads
- bcryptjs for password hashing
- express-rate-limit for API protection
- cookie-parser for secure cookie handling
- React 19.2.0 with TypeScript
- Vite for fast development and building
- Axios for API communication
- Socket.IO Client for real-time updates
- React Context for state management
- CSS Modules for styling
Ensure you have the following installed:
- Node.js (v16 or higher) - Download here
- npm (comes with Node.js)
- Git - Download here
- Clone the repository:
git clone <repository-url>
cd Ey- Install Backend Dependencies:
cd backend
npm install- Install Frontend Dependencies:
cd ../frontend/twitter
npm installCreate a .env file in the backend directory:
# Server Configuration
PORT=5000
# MongoDB Atlas Configuration
MONGODB_URI=mongodb+srv://<username>:<password>@<cluster>.mongodb.net/<database>?retryWrites=true&w=majority
# JWT Secret (Use a strong, unique secret in production)
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production-min-32-chars
# Environment
NODE_ENV=development-
Create MongoDB Atlas Account:
- Go to MongoDB Atlas
- Sign up for a free account
-
Create a Cluster:
- Click "Build a Database"
- Choose "FREE" tier
- Select your preferred region
- Create cluster
-
Create Database User:
- Go to "Database Access"
- Click "Add New Database User"
- Choose "Password" authentication
- Create username and strong password
- Grant "Read and write to any database" role
-
Configure Network Access:
- Go to "Network Access"
- Click "Add IP Address"
- Choose "Allow Access from Anywhere" (0.0.0.0/0) for development
- For production, use specific IP addresses
-
Get Connection String:
- Go to "Database" โ "Connect"
- Choose "Connect your application"
- Copy the connection string
- Replace
<password>with your database user password - Replace
<database>with your database name (e.g.,twitter-lite)
cd backend
npm run devโ
Backend will run on: http://localhost:5000
cd frontend/twitter
npm run devโ
Frontend will run on: http://localhost:5173
cd backend
npm run seedThis creates test users: Alice, Bob, and Charlie for easy testing.
| Method | Endpoint | Description | Body |
|---|---|---|---|
| POST | /api/auth/register |
Register new user | {username, email, password} |
| POST | /api/auth/login |
Login user | {email, password} |
| GET | /api/auth/me |
Get current user | - |
| POST | /api/auth/logout |
Logout user | - |
| Method | Endpoint | Description | Body |
|---|---|---|---|
| GET | /api/posts |
Get all posts | - |
| POST | /api/posts |
Create new post | {content, image?} |
| POST | /api/posts/:id/like |
Like/unlike post | - |
| POST | /api/posts/:id/comment |
Add comment | {content} |
{
"_id": "post123",
"content": "Hello World!",
"image": "image.jpg",
"author": {
"_id": "user123",
"username": "john",
"avatar": "avatar.jpg"
},
"likes": [
{
"_id": "user456",
"username": "alice",
"avatar": "alice.jpg",
"createdAt": "2025-12-25T10:00:00Z"
}
],
"comments": [
{
"_id": "comment123",
"content": "Great post!",
"author": {
"_id": "user789",
"username": "bob"
},
"createdAt": "2025-12-25T11:00:00Z"
}
],
"createdAt": "2025-12-25T09:00:00Z"
}{
_id: ObjectId,
username: String (unique, required),
email: String (unique, required),
password: String (hashed, required),
avatar: String (default: ''),
createdAt: Date (default: Date.now)
}{
_id: ObjectId,
content: String (required, max: 280 chars),
image: String (optional),
author: ObjectId (ref: 'User'),
likes: [ObjectId] (ref: 'User'),
comments: [ObjectId] (ref: 'Comment'),
createdAt: Date (default: Date.now)
}{
_id: ObjectId,
content: String (required, max: 280 chars),
author: ObjectId (ref: 'User'),
post: ObjectId (ref: 'Post'),
createdAt: Date (default: Date.now)
}newPost- Broadcast when new post is createdpostLiked- Broadcast when post is liked/unlikednewComment- Broadcast when comment is added
// Backend - Broadcasting events
io.emit('newPost', post);
io.emit('postLiked', { postId, likes });
io.emit('newComment', { postId, comment });
// Frontend - Listening to events
socket.on('newPost', handleNewPost);
socket.on('postLiked', handlePostLiked);
socket.on('newComment', handleNewComment);- HttpOnly Cookies - Tokens stored in secure cookies, not localStorage
- JWT Expiration - 7-day token lifetime
- Password Hashing - bcryptjs with salt rounds
- CORS Configuration - Restricted origins with credentials
- Rate Limiting - 5 posts per 15 minutes
- File Upload Limits - 5MB maximum file size
- Input Validation - Mongoose schema validation
- Error Handling - Secure error messages
- Chrome: Login as Alice
- Firefox: Login as Bob
- Edge/Incognito: Login as Charlie
- Create posts and interact across browsers
- Alice creates a post
- Bob likes Alice's post
- Charlie comments on Alice's post
- All users see real-time updates
Ey/
โโโ backend/
โ โโโ middleware/
โ โ โโโ auth.js # JWT authentication middleware
โ โโโ models/
โ โ โโโ User.js # User schema
โ โ โโโ Post.js # Post schema
โ โ โโโ Comment.js # Comment schema
โ โโโ routes/
โ โ โโโ auth.js # Authentication routes
โ โ โโโ posts.js # Posts and comments routes
โ โโโ uploads/ # File upload directory
โ โโโ .env # Environment variables
โ โโโ index.js # Server entry point
โ โโโ seedUsers.js # Test user seeder
โ โโโ package.json # Backend dependencies
โโโ frontend/twitter/
โ โโโ src/
โ โ โโโ components/ # React components
โ โ โ โโโ Auth.tsx # Login/Register form
โ โ โ โโโ AuthProvider.tsx # Auth context provider
โ โ โ โโโ Feed.tsx # Main feed component
โ โ โ โโโ Post.tsx # Individual post component
โ โ โ โโโ CreatePost.tsx # Post creation form
โ โ โโโ hooks/ # Custom React hooks
โ โ โโโ services/ # API services
โ โ โโโ types/ # TypeScript type definitions
โ โ โโโ App.tsx # Main app component
โ โโโ package.json # Frontend dependencies
โ โโโ vite.config.ts # Vite configuration
โโโ README.md # This file
MongoDB Connection Error:
Error: MongoNetworkError: failed to connect to server
Solution:
- Check MongoDB Atlas connection string
- Verify database user credentials
- Ensure IP address is whitelisted
- Check network connectivity
JWT Secret Error:
Error: secretOrPrivateKey has a minimum key size of 256 bits
Solution:
- Use a JWT secret with at least 32 characters
- Update
.envfile with a stronger secret
CORS Error:
Access to XMLHttpRequest at 'http://localhost:5000' from origin 'http://localhost:5173' has been blocked by CORS policy
Solution:
- Ensure backend CORS is configured for
http://localhost:5173 - Check if backend server is running
Cookie Not Set:
User not authenticated after login
Solution:
- Verify
withCredentials: truein axios configuration - Check if cookies are enabled in browser
- Ensure backend sets
credentials: truein CORS
If ports 5000 or 5173 are in use:
Backend (Port 5000):
# Change PORT in .env file
PORT=3001Frontend (Port 5173):
# Use different port
npm run dev -- --port 3000npm run dev # Start development server with nodemon
npm start # Start production server
npm run seed # Create test usersnpm run dev # Start development server
npm run build # Build for production
npm run preview # Preview production build
npm run lint # Run ESLintNODE_ENV=production
PORT=5000
MONGODB_URI=mongodb+srv://...
JWT_SECRET=your-production-secret-min-32-chars- Use strong JWT secret (32+ characters)
- Enable MongoDB Atlas IP whitelisting
- Set
NODE_ENV=production - Use HTTPS in production
- Configure proper CORS origins
- Set secure cookie flags
- Enable rate limiting
- Validate all inputs
- Fork the repository
- Create a feature branch:
git checkout -b feature-name - Commit changes:
git commit -m 'Add feature' - Push to branch:
git push origin feature-name - Submit a pull request
This project is licensed under the ISC License.
If you encounter any issues:
- Check the troubleshooting section above
- Verify all prerequisites are installed
- Ensure environment variables are correctly set
- Check that both backend and frontend servers are running
Happy Coding! ๐