Files
Messenger/README.md
T
vantablackTea c79a3cfe68
CI / Go (build + vet + test) (push) Canceled after 0s
CI / Web (build + lint) (push) Canceled after 0s
backend barebone done, big chunk of work done
2026-09-27 19:42:49 +03:00

4.4 KiB

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;").

# 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)

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.