SecureChat is a privacy-focused, end-to-end encrypted (E2EE) real-time messaging application for web and Mobile supporting text messaging, group communication, media sharing, and peer-to-peer voice/video calls.
This project was developed as my final year project in university exploring secure, accessible and scalable communication systems with self hosting support.
The application consists of:
- A React Native (Expo) front-end for web and mobile support.
- A Python-based back-end.
- Images
- Features
- Architecture Overview
- Project Structure
- Running the Project Locally
- Running with Docker
- API Overview
- Development Requirements
- End-to-End Encrypted Messaging (E2EE)
- Real-time messaging using WebSockets
- Group chats with role-based permissions
- Encrypted file and image sharing
- Peer-to-peer voice and video calls (WebRTC)
- Real-time collaborative document editing
- Cross-platform support (Web + Mobile-ready architecture)
- JWT-based authentication & secure session handling
- Self-hosting support
The system follows a modular Client → Server → Database architecture:
- Frontend: React Native + Expo
- Backend: Python (FastAPI + Socket.IO)
- Database: SQLite
- Encryption: Client-side public/private key cryptography
- Real-time Communication: WebSockets + WebRTC
All encryption occurs client-side. The backend only routes encrypted payloads and stores minimal metadata.
- /frontend → React frontend application
- /backend → Python FastAPI backend
Navigate to the frontend directory:
cd frontend
npm install
npm run devNavigate to the frontend directory:
cd backend
python -m venv venvsource venv/bin/activatevenv\Scripts\activatepip install -r requirements.txt
#Local Only
uvicorn main:app --reload
#Or if you want other devices to be able to communicate with the backend.
uvicorn main:app --reload --host 0.0.0.0Docker lets you run the entire app (frontend + backend) in isolated containers with a single command — no need to install Node.js, Python, or any dependencies manually.
You only need one thing installed: Docker Desktop (which includes both docker and docker compose).
- Go to https://www.docker.com/products/docker-desktop/
- Click Download for Mac (choose Apple Silicon if you have an M1/M2/M3/M4 Mac, or Intel for older Macs)
- Not sure which? Click the Apple logo top-left → About This Mac → look for "Apple M..." or "Intel"
- Open the downloaded
.dmgfile - Drag Docker into Applications
- Open Docker Desktop from Applications — it will ask for your password to finish setup
- Wait until the Docker icon in the menu bar shows a steady state (not animating)
- Open Terminal and verify it works:
You should see version numbers for both. If you get "command not found", restart your terminal.
docker --version docker compose version
- Enable WSL 2 (Windows Subsystem for Linux) — Docker needs this:
- Open PowerShell as Administrator (right-click Start → "Terminal (Admin)" or "PowerShell (Admin)")
- Run:
wsl --install - Restart your computer when prompted
- After reboot, a Ubuntu window may open asking you to create a username/password — do so (this is just for WSL, pick anything)
- Go to https://www.docker.com/products/docker-desktop/
- Click Download for Windows
- Run the installer (
.exefile) — keep all defaults, make sure "Use WSL 2" is checked - Restart your computer if prompted
- Open Docker Desktop — let it finish starting up (the whale icon in the system tray should stop animating)
- Open Command Prompt or PowerShell and verify:
Both should return version numbers. If not, restart your terminal or PC.
docker --version docker compose version
-
Open a terminal and run these commands one by one:
# Update your package list sudo apt update # Install prerequisites sudo apt install -y ca-certificates curl gnupg # Add Docker's official GPG key sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg # Add Docker's repository echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # Install Docker Engine + Compose sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
-
Allow your user to run Docker without
sudo:sudo usermod -aG docker $USERLog out and log back in (or restart) for this to take effect.
-
Verify installation:
docker --version docker compose version
Fedora/Arch/other distros: See the official Docker docs for your specific distro.
-
Clone the repository (or download and extract the ZIP):
git clone https://github.com/JaredWestley/Encrypted-Messaging-App.git cd Encrypted-Messaging-App -
(Optional) Create a
.envfile in the project root to customise settings:# .env (create this file next to docker-compose.yml) SECRET_KEY=your-secret-key-here MINIMAX_API_KEY=your-api-key-here FRONTEND_PORT=3000 BACKEND_PORT=8000If you skip this step, defaults will be used (which is fine for local testing).
-
Build and start both containers:
docker compose up --build
The first build takes a few minutes (downloading base images and installing dependencies). Subsequent starts are much faster.
-
Open the app in your browser:
- Frontend: http://localhost:3000
- Backend API: http://localhost:8000
-
Stop the app by pressing
Ctrl + Cin the terminal, or run:docker compose down
| Command | What It Does |
|---|---|
docker compose up --build |
Build images and start the app |
docker compose up -d |
Start in the background (detached) |
docker compose down |
Stop and remove containers |
docker compose logs -f |
View live logs from both services |
docker compose logs backend |
View only backend logs |
docker compose ps |
Check which containers are running |
docker compose down -v |
Stop and delete all data (database, uploads) |
| Problem | Solution |
|---|---|
| "docker: command not found" | Make sure Docker Desktop is installed and running. Restart your terminal. |
| "permission denied" on Linux | Run sudo usermod -aG docker $USER then log out and back in. |
| Port 3000 or 8000 already in use | Change the ports in your .env file: FRONTEND_PORT=3001 |
| Containers exit immediately | Check logs with docker compose logs for error details. |
| "WSL 2 is not installed" on Windows | Run wsl --install in PowerShell as Admin, then restart. |
| Changes not showing after code edit | Run docker compose up --build to rebuild with your changes. |
- POST /api/auth/register - Register a new user
- POST /api/auth/login - Login and receive acess + refresh tokens
- POST /api/auth/logout - Invalidate current session token
- POST /api/auth/refresh - Exchange refresh token for new access token
- GET /api/users/me - Get current user profile
- PUT /api/users/me - Update profile (username, bio, etc.)
- PUT /api/users/me/icon - Upload proile picture
- GET /api/servers - List all servers the user is in
- POST /api/servers - Create a new server
- GET /api/servers/{server_id} - Get server details
- PUT /api/servers/{server_id} - Update server settings
- DELETE /api/servers/{server_id} - Delete a server
- GET /api/servers/{server_id}/users - List server members
- POST /api/servers/{server_id}/kick - Kick a member
- POST /api/servers/{server_id}/ban - Ban a member
- POST /api/servers/{server_id}/leave - Leave a server
- POST /api/servers/{server_id}/generate-invite - Generate invite link
- POST /api/invite/{invite_token} - Join server via invite
- GET /api/messages - Fetch messages for a server
- POST /api/messages - Send a message to a server
- PUT /api/messages/{message_id} - Edit a message
- DELETE /api/messages/{message_id} - Delete a message
- POST /api/messages/{message_id}/reactions - Add a reaction to a message
- POST /api/messages/summarize - AI summarise a message thread
- GET /api/conversations - List all DM conversations
- POST /api/conversations - Start a new DM conversation
- GET /api/conversations/{conversation_id}/messages - Get messages in a conversation
- POST /api/conversations/{conversation_id}/messages - Send a DM
- POST /api/friends/request - Send a friend request
- POST /api/friends/{friendship_id}/accept - Accept a friend request
- POST /api/friends/{friendship_id}/reject - Reject a friend request
- GET /api/friends - List friends
- POST /api/servers/{server_id}/roles - Create a role
- PUT /api/servers/{server_id}/roles/{role_id} - Update a role
- DELETE /api/servers/{server_id}/roles/{role_id} - Delete a role
- POST /api/servers/{server_id}/roles/assign - Assign a role to a member
- GET /api/roles/permissions - List all available permissions
- POST /api/attachments/upload - Upload a file attachment
- GET /api/attachments/{attachment_id} - Download an attachment
- POST /api/keys/public - Upload user's public key
- GET /api/keys/public/{user_id} - Get a user's public key
- GET /api/keys/server/{server_id} - Get server encryption key
- POST /api/keys/server - Upload server encryption key
- GET /api/servers/{server_id}/voice-channels - List voice channels in a server
- POST /api/servers/{server_id}/voice-channels - Create a voice channel
- DELETE /api/voice-channels/{channel_id} - Delete a voice channel
- GET /api/servers/{server_id}/documents - List documents in a server
- POST /api/servers/{server_id}/documents - Create a document
- GET /api/documents/{document_id} - Get a document
- PUT /api/documents/{document_id} - Update a document
- DELETE /api/documents/{document_id} - Delete a document
- GET /api/documents/{document_id}/versions - List document version history
- WS /api/ws/{server_id} - real time server chat connection
- WS /api/ws/dm - real time direct message connection
- Node.js v20.9+
- Python 3.10+
- npm
- pip
Run frontend and backend in separate terminals.

