āāā backend
ā āāā app
ā ā āāā __init__.py
ā ā āāā config.py
ā ā āāā extensions.py
ā ā āāā models.py
ā ā āāā repository.py
ā ā āāā routes.py
ā ā āāā services.py
ā ā āāā sockets.py
ā āāā .dockerignore
ā āāā Dockerfile
ā āāā main.py
ā āāā requirements.txt
āāā frontend
ā āāā src
ā ā āāā components
ā ā ā āāā KillSwitch.svelte
ā ā ā āāā MessageComposer.svelte
ā ā ā āāā MessageFeed.svelte
ā ā ā āāā PassphraseModal.svelte
ā ā āāā services
ā ā ā āāā crypto.js
ā ā ā āāā socket.js
ā ā āāā state
ā ā ā āāā store.js
ā ā āāā App.svelte
ā ā āāā main.js
ā āāā .dockerignore
ā āāā Dockerfile
ā āāā index.html
ā āāā package-lock.json
ā āāā package.json
ā āāā vite.config.js
āāā .dockerignore
āāā .gitignore
āāā Makefile
āāā README.md
āāā docker-compose.yml
Whisper is a secure, real-time messaging system designed for investigative teams needing fully encrypted communication.
| Layer | Choice | Reason / Notes |
|---|---|---|
| Backend | Python, Flask, Flask-SocketIO | Lightweight, fast prototyping |
| Web Server | Gunicorn + Gevent | Handles Socket.IO concurrency |
| Frontend | Svelte + Vite | Fast SPA, minimal boilerplate |
| Database | SQLite | Simple persistence, avoids complex setup |
| Security | AES + SHA256 via crypto-js | Lightweight client-side encryption |
| API | REST | Simpler than GraphQL for MVP |
| Styling/UI | Minimal, no dark theme, basic HTML/CSS | Focus on functionality over aesthetics |
Activated by pressing ESC key 3 times consecutively.
Actions on activation:
No database wipe occurs ā backend ciphertext is preserved.
Implemented in frontend/src/components/KillSwitch.svelte + frontend/src/state/store.js.
Browser
ā
ā¼
Nginx (frontend container)
ā
āāā / ā Svelte SPA
ā
āāā /api ā Flask REST backend
ā
āāā /socket.io ā Flask-SocketIO
Run everything in one command:
docker compose up -d --build
Endpoints:
http://localhosthttp://localhost/api/healthws://localhost/socket.io/Stop everything:
docker compose down
Remove persistent SQLite volume:
docker compose down -v
Shared Secret: Client asks for "Team Passphrase" ā derives AES key.
Message Encryption: All plaintext encrypted locally using AES + SHA256 passphrase via crypto-js.
Frontend Simplicity:
Backend Logging: print() statements in sockets.py used instead of logging library.
SQLite over Postgres: Chosen for lightweight dev MVP, avoids multi-container DB setup.
REST API only: No GraphQL.
| Decision | Trade-Off / Reason |
|---|---|
| Symmetric AES | Fast & simple, avoids key exchange complexity |
| SQLite | Lightweight, single file DB; not suitable for heavy concurrency |
| REST API | Simpler to implement and debug for MVP |
| Minimal UI | Prioritize secure functionality & Kill Switch over aesthetics |
| No logging library | Quick debug via print() during MVP dev |
| SHA256 + crypto-js | Lightweight crypto suitable for client-side encryption |
| Kill Switch | Focused on security UX; intentionally does not wipe backend DB |
whisper-apiwhisper-frontendbackend:5000.whisper_data stores encrypted SQLite messages.Security Hygiene: No plaintext storage on server; encryption isolated.
Concurrency: Backend broadcasts messages without blocking; frontend appends efficiently.
Architectural Integrity: Kill Switch works without exposing data.
Code Quality: Clear separation: