A lightweight, secure, end-to-end encrypted chatroom application designed for deployment on local servers. Built with emphasis on privacy, security, and ease of deployment.
- Real-time Messaging: WebSocket-based instant messaging with sub-second latency
- Multiple Chatrooms: Create and join unlimited rooms with unique IDs
- Message Replies: Thread conversations with reply functionality
- Online Status: Real-time user presence tracking
- Message History: Load older messages on demand with infinite scroll
- Responsive Design: Optimized for desktop, tablet, and mobile devices
- End-to-End Encryption: AES-GCM 256-bit encryption on client-side
- Zero Knowledge: Server never sees unencrypted messages
- Challenge-Response Authentication: No plaintext password transmission
- Session Management: Secure token-based sessions (24-hour expiry)
- HTTPS Support: SSL/TLS for local network deployment
- Key Derivation: PBKDF2 with 100,000 iterations
- Ollama Integration: Connect local LLM models for AI-powered responses
- Auto-Reconnection: Graceful handling of network interruptions
- RTL Support: Bidirectional text support (LTR/RTL)
┌─────────────┐ ┌─────────────┐ ┌──────────────┐
│ Browser │◄───────►│ FastAPI │◄───────►│ │
│ (Client) │ WSS/ │ Server │ SQL │ SQL Database │
│ + Crypto │ HTTPS │ + Auth │ │ │
└─────────────┘ └─────────────┘ └──────────────┘
Technology Stack:
- Frontend: Vanilla JavaScript, Web Crypto API, DOMPurify
- Backend: FastAPI, Python 3.10+
- Database: PostgreSQL with asyncpg
- Real-time: WebSockets
- Security: HTTPS (mkcert for local), challenge-response auth
- Python 3.10 or higher
- PostgreSQL 12 or higher
- Node.js (optional, for mkcert)
- Modern web browser with Web Crypto API support
Get up and running in 5 minutes:
# 1. Clone and enter directory
git clone https://github.com/ErfanZmp/chatroom.git
cd chatroom
# 2. Install dependencies
pip install -r requirements.txt
# 3. Create database
createdb chatdb
# 4. Configure environment
echo 'DATABASE_URL=postgresql://postgres:yourpassword@localhost/chatdb' > .env
# 5. Run migrations
python migrate.py migrate
# 6. Start server
uvicorn app:app --reload --host 0.0.0.0 --port 8000Access at: http://localhost:8000
Using Make (optional):
make setup # Install deps + run migrations
make dev # Start development servergit clone https://github.com/ErfanZmp/chatroom.git
cd chatroompython -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txtCreate a PostgreSQL database and configure the connection:
createdb chatdbCreate .env file:
DATABASE_URL=postgresql://postgres:yourpassword@localhost/chatdbRun database migrations to create tables:
python migrate.py migrateThis will create:
chatroomtable - stores room metadata and hashed keyschat_messagetable - stores encrypted messages- Required indexes for performance
schema_migrationstable - tracks applied migrations
Alternative: Manual SQL
If you prefer manual setup, run the SQL in migrations/001_initial_schema.sql:
psql -d chatdb -f migrations/001_initial_schema.sqlInstall mkcert:
# macOS
brew install mkcert
# Linux
sudo apt install mkcert # or equivalent
# Windows
choco install mkcertThe start-ssl.sh script will automatically generate certificates for your local IP.
uvicorn app:app --reload --host 0.0.0.0 --port 8000Access at: http://localhost:8000
chmod +x start-ssl.sh
./start-ssl.shAccess at: https://your-local-ip:8000
- Open the application in your browser
- Enter a Display Name (your username)
- Enter a Room ID (unique identifier)
- Enter a Room Key (passphrase for encryption)
- Click Join
Note: The first user to join creates the room. Others must use the exact same Room ID and Room Key to enter.
- Install Ollama locally
- Pull a model:
ollama pull llama2 - Start Ollama:
ollama serve - Access chatroom via:
https://your-ip:8000/ai - Enter Ollama port (default:
11434) - Send messages in format:
<model> <prompt>
Example: llama2 What is the meaning of life?
✅ All message content
✅ Message history
✅ User-generated content
❌ Usernames (needed for display)
❌ Timestamps (needed for ordering)
❌ Room IDs (needed for routing)
❌ Online status (needed for presence)
- Use strong, unique room keys (20+ characters recommended)
- Don't share room keys over insecure channels
- Use HTTPS in production environments
- Regularly update dependencies
- Deploy behind a firewall for internal use only
- Metadata (usernames, message count, timestamps) is visible to server
- No perfect forward secrecy (PFS)
- Stored credentials in localStorage (can be migrated to sessionStorage)
chatroom/
├── app.py # FastAPI backend
├── requirements.txt # Python dependencies
├── .env # Environment variables (create this)
├── start-ssl.sh # HTTPS setup script
├── static/
│ ├── index.html # Frontend UI
│ ├── script/
│ │ ├── chat.js # Client-side logic
│ │ ├── contextMenu.js
│ │ ├── purify.min.js # XSS sanitization
│ └── style/
│ └── style.css # Styling
└── README.md
# Database
DATABASE_URL=postgresql://user:pass@host:port/dbname
# Optional: Session Configuration
SESSION_EXPIRY=86400 # 24 hours in seconds
CHALLENGE_EXPIRY=300 # 5 minutes in seconds
# Optional: Auto-delete messages at midnight
MIDNIGHT_CLEANUP=false # Set to 'true' to enableMessage Auto-Deletion: When MIDNIGHT_CLEANUP=true, all messages in the chat_message table are automatically deleted daily at 00:00 server time. Useful for temporary/ephemeral chat scenarios.
Edit constants in static/script/chat.js:
const maxReconnectAttempts = 5;
const baseReconnectDelay = 1000; // milliseconds
const maxReconnectDelay = 30000; // milliseconds
const SESSION_EXPIRY = 86400; // seconds# Apply all pending migrations
python migrate.py migrate
# Check migration status
python migrate.py status
# Rollback last migration
python migrate.py rollbackTables:
chatroom- Room metadata (chat_id, key_hash, created_at)chat_message- Encrypted messages (id, chat_id, username, message, sent_at, reply_to)schema_migrations- Tracks applied migrations
Indexes:
- Fast message retrieval by room and timestamp
- Optimized reply thread lookups
- Room creation time queries
See migrations/README.md for detailed schema documentation.
- Configure firewall to allow port 8000
- Run with
start-ssl.shto enable HTTPS - Share the local IP and room credentials with users
- Ensure PostgreSQL is accessible
Create Dockerfile:
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]Run:
docker build -t nitrochat .
docker run -p 8000:8000 --env-file .env nitrochatContributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow PEP 8 for Python code
- Use meaningful variable names
- Add comments for complex logic
- Test security features thoroughly
- Check firewall settings
- Verify HTTPS certificates are trusted
- Ensure server is bound to correct IP (
0.0.0.0)
- Verify PostgreSQL is running:
pg_isready - Check
DATABASE_URLin.env - Ensure database and tables exist
- Start PostgreSQL if needed:
- macOS:
brew services start postgresql - Linux:
sudo service postgresql start
- macOS:
# Ensure user has database creation privileges
psql -U postgres -c "ALTER USER yourusername CREATEDB;"- Already applied error: Database is already initialized
- Reset database:
python migrate.py rollback # or dropdb chatdb && createdb chatdb && python migrate.py migrate
- Check status:
python migrate.py status
- Verify all users use identical Room Key
- Check browser console for Web Crypto API errors
- Ensure HTTPS is enabled (required for crypto APIs)
- Sessions expire after 24 hours
- Clear localStorage and re-login
- Check system time synchronization
This project is open source and available under the MIT License.
- FastAPI for the excellent web framework
- PostgreSQL for reliable data storage
- Web Crypto API for browser-native encryption
- Ollama for local LLM integration
For issues, questions, or contributions:
- GitHub Issues: Report a bug
- Pull Requests: Contribute code