discord/README.md
2026-02-13 17:45:29 +01:00

103 lines
2.9 KiB
Markdown

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