A full-stack messenger application built with Spring Boot and Vanilla JavaScript, featuring real-time messaging, group chats, and user management.
git clone https://github.com/feyzollahi/simpleMessenger.git
cd simpleMessenger docker-compose up -d mvn clean install
mvn spring-boot:runStep 4: Use your application by visiting http://localhost:8081
- Features
- Tech Stack
- Prerequisites
- Installation & Setup
- API Endpoints
- Database Schema
- Configuration
- Usage
- Troubleshooting
- Contributing
- 🔐 User Authentication: JWT-based authentication with Spring Security
- 💬 Direct Messaging: One-on-one private conversations
- 👥 Group Chats: Create and manage group conversations
- 🔍 User Search: Find and connect with other users
- 📊 User Status: Active/inactive user tracking
- 🎨 Responsive UI: Clean, modern interface with vanilla JavaScript
- 🔒 Secure: Password encryption, CORS protection, and secure endpoints
- Java 21: Modern Java features and performance
- Spring Boot 3.5.6: Core framework
- Spring Security 6: Authentication and authorization
- Spring Data JPA: Database abstraction
- PostgreSQL 16: Relational database
- Lombok: Reduce boilerplate code
- JWT: Token-based authentication
- Vanilla JavaScript: No framework dependencies
- HTML5/CSS3: Modern web standards
- Fetch API: RESTful API consumption
- Docker Compose: Container orchestration
- pgAdmin 4: Database management
- Maven: Build automation
Before you begin, ensure you have the following installed:
- ☕ Java 21 or higher (Download)
- 🐳 Docker Desktop (Download)
- 📦 Maven 3.8+ (Download)
- 🖥️ Git (Download)
- RAM: 4GB minimum (8GB recommended)
- Disk Space: 2GB free space
- OS: Windows 10/11, macOS 10.15+, or Linux
git clone https://github.com/feyzollahi/simpleMessenger.git
cd simple-messengerIMPORTANT: Ensure port 5432 is not occupied by another PostgreSQL instance.
# Windows (PowerShell)
Get-Process -Id (Get-NetTCPConnection -LocalPort 5432).OwningProcess
# macOS/Linux
lsof -i :5432
# If port is occupied, stop the service:
# Windows: Stop PostgreSQL service from Services
# macOS: brew services stop postgresql
# Linux: sudo systemctl stop postgresql# Start PostgreSQL and pgAdmin
docker-compose up -d
# Verify containers are running
docker-compose ps
# Expected output:
# NAME IMAGE STATUS
# messenger_postgres postgres:16-alpine Up (healthy)
# messenger_pgadmin dpage/pgadmin4:latest UpWait 30 seconds for PostgreSQL to initialize completely.
# Connect to PostgreSQL
docker exec -it messenger_postgres psql -U messenger_user -d messenger_db
# You should see:
# messenger_db=#
# Exit with:
\qThe application is pre-configured in src/main/resources/application.properties:
# Database Configuration
spring.datasource.url=jdbc:postgresql://localhost:5432/messenger_db
spring.datasource.username=messenger_user
spring.datasource.password=messenger_pass_123
# JWT Configuration
jwt.secret=mySecretKeyForMessengerApp123456789012345678901234567890123456789012345678901234567890
jwt.expiration=86400000
# Server Port
server.port=8081# Clean and build
mvn clean install
# Run the application
mvn spring-boot:run
# Or build JAR and run
mvn clean package
java -jar target/simple_messenger-0.0.1-SNAPSHOT.jarLook for these log messages:
✓ HikariPool-1 - Starting... ✓ HikariPool-1 - Start completed. ✓ Initialized JPA EntityManagerFactory ✓ Started SimpleMessengerApplication in 3.456 seconds (process running for 4.123)
Application will be available at:
- Frontend: http://localhost:8081
- API: http://localhost:8081/api
- pgAdmin: http://localhost:5050
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /api/auth/register |
Register new user | ❌ |
| POST | /api/auth/login |
User login | ❌ |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /api/users/me |
Get current user info | ✅ |
| GET | /api/users/{id} |
Get user by ID | ✅ |
| GET | /api/users/active |
Get all active users | ✅ |
| GET | /api/users |
Get all users | ✅ |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /api/messages/private |
Send direct message | ✅ |
| POST | /api/messages/group |
Send message in group | ✅ |
| GET | /api/messages/private/{userId} |
Get conversation with user | ✅ |
| GET | /api/messages/unread |
Get unread conversations | ✅ |
| PUT | /api/messages/{messageId}/read} |
mark message as read | ✅ |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /api/groups |
Create new group | ✅ |
| GET | /api/groups |
Get All group | ✅ |
| GET | /api/groups/my |
Get user's groups | ✅ |
| GET | /api/groups/{id} |
Get group details | ✅ |
| POST | /api/groups/{id}/join |
Join a group | ✅ |
| POST | /api/groups/{id}/leave |
Leave a group | ✅ |
click on image to see it bigger with better details
Edit compose.yaml to change database credentials:
environment:
- POSTGRES_DB=messenger_db # Database name
- POSTGRES_USER=messenger_user # Username
- POSTGRES_PASSWORD=messenger_pass_123 # PasswordImportant: If you change these values, update application.properties accordingly.
Edit application.properties:
# JWT Secret Key (minimum 256 bits)
jwt.secret=your-super-secret-key-here
# Token expiration (milliseconds) - Default: 24 hours
jwt.expiration=86400000Security Note: Change the JWT secret in production!
# Default port
server.port=8081
# Change if port is occupied
# server.port=8080Edit SecurityConfig.java to allow specific origins:
configuration.setAllowedOrigins(Arrays.asList(
"http://localhost:8081",
"http://localhost:3000",
"https://yourdomain.com"
));- Open http://localhost:8081
- Click "ثبت نام" (Register)
- Fill in username and password
- Click submit
- Enter your credentials (just name!)
- Click "ورود" (Login)
- You'll be redirected to the chat interface
- Click "کاربران" (Users) tab
- Click on a user to start conversation
- Type message and press Enter or click send
- Click "گروهها" (Groups) tab
- Click "+ گروه جدید" (New Group)
- Enter group name
- Click create
- Browse available groups
- Click "عضویت" (Join) to join
- Click "خروج" (Leave) to leave a group
- Open http://localhost:5050
- Login with:
- Email:
admin@messenger.com - Password:
admin123
- Email:
- Add server:
- Host:
messenger_postgres - Port:
5432 - Username:
messenger_user - Password:
messenger_pass_123
- Host:
# Find process using port
netstat -ano | findstr :5432
# Stop existing PostgreSQL
# Windows: Services → PostgreSQL → Stop
# macOS: brew services stop postgresql
# Linux: sudo systemctl stop postgresql# Check Docker Desktop is running
docker --version
# Remove old containers and volumes
docker-compose down -v
# Restart
docker-compose up -d# Check PostgreSQL health
docker-compose logs postgres
# Wait for this message:
# "database system is ready to accept connections"
# Test connection
docker exec -it messenger_postgres psql -U messenger_user -d messenger_db# Check Java version
java --version # Must be 21+
# Clean Maven cache
mvn clean
# Rebuild
mvn clean install -DskipTests
# Check logs
mvn spring-boot:run- Check browser console (F12) for errors
- Verify API is running: http://localhost:8081/api/users/active
- Check CORS settings in
SecurityConfig.java - Clear browser cache
- Tokens expire after 24 hours (default)
- Login again to get a new token
- Or increase
jwt.expirationinapplication.properties
- ✅ Password encryption with BCrypt
- ✅ JWT token authentication
- ✅ CORS protection
- ✅ SQL injection prevention (JPA)
- ✅ XSS protection
- ✅ CSRF protection disabled (stateless API)
- ✅ Secure headers configuration
# Build Docker image
docker build -t simple-messenger .
# Run container
docker run -p 8081:8081 simple-messenger- Change JWT secret key
- Use environment variables for credentials
- Enable HTTPS
- Configure production database
- Set up monitoring and logging
- Enable rate limiting
- Configure backup strategy
- Update CORS allowed origins
- File sharing (images, documents)
- Voice/Video calls
- Message encryption (E2E)
- Message reactions and replies
- User profiles with avatars
- Push notifications
- Mobile app (React Native)
- Message search functionality
- Read receipts
- Typing indicators
Contributions are welcome! Please follow these steps:
- 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
- Follow Java naming conventions
- Write meaningful commit messages
- Add Javadoc for public methods
- Include unit tests for new features
- Update documentation
- Mahdi Feyzollahi - Initial work - My Github
- Spring Boot team for excellent framework
- PostgreSQL community
- All contributors and users
For support and questions:
- 📧 Email: feyzollahi.m@gmail.com
- 🐛 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions
Made with ❤️ using Spring Boot and Vanilla JavaScript
