106 lines
4.4 KiB
Markdown
106 lines
4.4 KiB
Markdown
# Messenger
|
|
|
|
Self-hosted messenger for family and friends. Built from scratch: Go backend,
|
|
React PWA frontend, PostgreSQL, WebRTC calls. Deployed on a home-lab mini PC.
|
|
|
|
> **Status:** Phase 1 — auth (JWT + refresh in httpOnly cookies, argon2id),
|
|
> contacts, direct-message chats, real-time delivery over WebSocket
|
|
> (messages, typing, presence, read receipts). Backend is complete and tested;
|
|
> the frontend still shows the Phase 0 status screen.
|
|
|
|
## Repository layout
|
|
|
|
```
|
|
server/ Go API
|
|
cmd/api/ entrypoint (wiring, migrations, graceful shutdown)
|
|
internal/api/ HTTP handlers: auth, users, contacts, conversations, messages
|
|
internal/auth/ argon2id hashing, JWT access tokens, refresh tokens
|
|
internal/realtime/ WebSocket hub: events, presence, typing, read receipts
|
|
internal/store/ PostgreSQL access (pgx), embedded migrations
|
|
internal/platform/ config, structured logging
|
|
web/ React + TypeScript + Vite frontend (PWA-ready)
|
|
deploy/ docker-compose and operational config
|
|
docs/ architecture, ADR, OpenAPI
|
|
.github/ CI workflows
|
|
```
|
|
|
|
## API (Phase 1)
|
|
|
|
All endpoints under `/api/v1`. Auth via httpOnly cookies (`messenger_access`
|
|
= JWT 15 min, `messenger_refresh` = opaque token 30 days, rotated on refresh).
|
|
|
|
| Method | Path | Description |
|
|
|--------|-----------------------------------|---------------------------------|
|
|
| POST | `/api/v1/auth/register` | Create account (sets cookies) |
|
|
| POST | `/api/v1/auth/login` | Sign in (sets cookies) |
|
|
| POST | `/api/v1/auth/refresh` | Rotate refresh token |
|
|
| POST | `/api/v1/auth/logout` | Revoke session, clear cookies |
|
|
| GET | `/api/v1/users/me` | Current user |
|
|
| GET | `/api/v1/users?q=` | Search users by username/name |
|
|
| GET | `/api/v1/contacts` | Contact list |
|
|
| POST | `/api/v1/contacts` | `{user_id}` — add contact |
|
|
| DELETE | `/api/v1/contacts/{user_id}` | Remove contact |
|
|
| GET | `/api/v1/conversations` | List chats + unread counts |
|
|
| POST | `/api/v1/conversations` | `{user_id}` — create/find DM |
|
|
| GET | `/api/v1/conversations/{id}/messages` | History, keyset `?before=` |
|
|
| POST | `/api/v1/conversations/{id}/messages` | `{body, temp_id}` — send |
|
|
| GET | `/ws` | WebSocket (auth via cookie) |
|
|
|
|
WebSocket event types: `message.created`, `typing`, `presence`, `read`.
|
|
|
|
## Prerequisites
|
|
|
|
- Go 1.27+
|
|
- Node.js 22+
|
|
- Docker + Docker Compose (for deployment)
|
|
|
|
## Local development
|
|
|
|
Requires a local PostgreSQL (e.g. `sudo -u postgres psql -c "CREATE ROLE messenger LOGIN PASSWORD 'messenger';"` and
|
|
`sudo -u postgres psql -c "CREATE DATABASE messenger OWNER messenger;"`).
|
|
|
|
```bash
|
|
# Backend (migrations run automatically on start)
|
|
cd server
|
|
go run ./cmd/api # listen on :8080
|
|
|
|
# Frontend (separate terminal)
|
|
cd web
|
|
npm install
|
|
npm run dev # Vite on :5173, proxies /api -> :8080
|
|
```
|
|
|
|
The frontend calls `/api/v1/ping` on load and renders the server response.
|
|
|
|
## Useful endpoints
|
|
|
|
| Endpoint | Purpose |
|
|
|--------------|----------------------------------|
|
|
| `/healthz` | Liveness probe |
|
|
| `/readyz` | Readiness probe |
|
|
| `/api/v1/ping` | Round-trip check (JSON) |
|
|
|
|
## Deployment (Docker Compose)
|
|
|
|
```bash
|
|
cp deploy/.env.example deploy/.env # adjust secrets
|
|
cd deploy
|
|
docker compose up -d --build
|
|
```
|
|
|
|
The API container is a single static binary that also serves the built
|
|
frontend (`/app/web`). PostgreSQL runs alongside with a healthcheck.
|
|
|
|
## Roadmap
|
|
|
|
- **Phase 0** — skeleton, CI, Docker ✅
|
|
- **Phase 1** — auth (JWT + refresh in httpOnly cookie, argon2id), contacts, DMs, WebSocket delivery, receipts, typing ✅ (backend)
|
|
- Phase 1.5 — frontend: auth screens, chat UI, realtime client (PWA)
|
|
- Phase 2 — groups, reactions, media upload + thumbnails (S3-like storage interface)
|
|
- Phase 3 — search (pg_trgm), Web Push (VAPID), PWA offline
|
|
- Phase 4 — P2P WebRTC calls via our WebSocket signalling + coturn TURN fallback
|
|
- Phase 5 — metrics (Prometheus + VictoriaMetrics + Grafana), docs, hardening
|
|
|
|
## License
|
|
|
|
Proprietary for now; open-sourcing at v1.0. |