# Chattz A simple single-instance Discord-style monolith in Rust using: - `axum` HTTP server - `SeaORM` + PostgreSQL for persistence - Authentik OIDC for login ## What this includes - OIDC login flow (`/auth/login`, `/auth/callback`, `/auth/logout`) - Signed session cookie auth - Channel voice chat over WebRTC (P2P mesh) with server WebSocket signaling - Guild invite codes (create + join) - Direct messages (DM) between users - Core resources: - users - guilds + guild membership - channels - messages - direct_messages - Basic JSON APIs for creating guilds/channels and posting/listing messages ## Quick start 1. Create DB and apply schema: 1. Create DB: ```sql CREATE DATABASE chattz; ``` 2. Configure env: ```bash cp .env.example .env # edit .env values ``` For voice reliability on restrictive networks, configure TURN in `.env`: - `TURN_URLS` - `TURN_USERNAME` - `TURN_PASSWORD` 3. Run app: ```bash cargo run ``` Migrations are applied automatically during startup. Server starts on `http://localhost:3000`. Web UI is available at `http://localhost:3000/`. ## Authentik setup notes Create an Authentik OAuth2/OIDC provider + application and set: - Redirect URI: `http://localhost:3000/auth/callback` - Scopes including at least: `openid profile email` Then copy provider endpoints into env: - `OIDC_AUTHORIZE_URL` - `OIDC_TOKEN_URL` - `OIDC_USERINFO_URL` For Authentik these are commonly under `/application/o/...` for the app slug. ## API summary - `GET /health` - `GET /auth/login` - `GET /auth/callback?code=...&state=...` - `POST /auth/logout` - `GET /me` - `GET /dms` - `GET /dms/:other_user_id/messages?limit=50` - `POST /dms/:other_user_id/messages` body: `{ "body": "hello" }` - `GET /rtc-config` - `GET /guilds` - `POST /guilds` body: `{ "name": "My Guild" }` - `GET /guilds/:guild_id/members` - `GET /guilds/:guild_id/voice-presence` - `POST /guilds/:guild_id/invites` body: `{ "max_uses": 50, "expires_in_hours": 24 }` - `POST /invites/:code/join` - `GET /guilds/:guild_id/channels` - `POST /channels` body: `{ "guild_id": "...", "name": "general", "kind": "text|voice" }` - `GET /channels/:channel_id/messages?limit=50` - `POST /channels/:channel_id/messages` body: `{ "body": "hello" }` - `GET /channels/:channel_id/voice/ws` (WebSocket signaling) All endpoints except health and auth flow require the session cookie from successful login. ## Notes This is intentionally minimal and monolithic (single process, single Postgres instance). Voice is implemented as browser-to-browser WebRTC audio with signaling in this server. For two users behind strict NAT/firewall, you may need TURN for reliable connectivity. The web UI remembers the last selected guild in browser local storage and auto-selects it on reload. Mic filter modes in the UI: - `NSNet2 (Compat)`: always-on denoising mode (implemented using DeepFilterNet3 with lighter suppression preset) Noise processing requires browsers with `AudioWorklet` support (modern Chrome/Edge/Firefox).