No description
  • Rust 57%
  • JavaScript 24.2%
  • CSS 9.9%
  • HTML 8.9%
Find a file
pavel 9d7f658fc0
All checks were successful
/ upload (release) Successful in 3m39s
periodic update check
2026-02-28 15:15:42 +01:00
.forgejo/workflows skip version commit 2026-02-27 15:00:17 +01:00
build test 2026-02-27 00:33:47 +01:00
desktop crazy refactor 2026-02-27 20:34:33 +01:00
migrations init 2026-02-13 17:45:29 +01:00
scripts crazy refactor 2026-02-27 20:34:33 +01:00
shared-html crazy refactor 2026-02-27 20:34:33 +01:00
src crazy refactor 2026-02-27 20:34:33 +01:00
static fix volume slider 2026-02-28 13:43:03 +01:00
.env.example crazy refactor 2026-02-27 20:34:33 +01:00
.gitignore a 2026-02-25 14:57:46 +01:00
Cargo.lock crazy refactor 2026-02-27 20:34:33 +01:00
Cargo.toml crazy refactor 2026-02-27 20:34:33 +01:00
main.js periodic update check 2026-02-28 15:15:42 +01:00
package-lock.json chore: bump version to 0.0.50 [skip ci] 2026-02-27 13:37:20 +00:00
package.json refactor 2026-02-27 15:57:39 +01:00
README.md crazy refactor 2026-02-27 20:34:33 +01:00
test.html sdfg 2026-02-24 23:18:46 +01:00
test_output.txt test 2026-02-24 21:37:18 +01:00

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)
  • HttpOnly 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:
  2. Create DB:
CREATE DATABASE chattz;
  1. Configure env:
cp .env.example .env
# edit .env values

For voice reliability on restrictive networks, configure TURN in .env:

  • TURN_URLS
  • TURN_USERNAME
  • TURN_PASSWORD

For production deployments:

  • APP_BASE_URL must be your public app origin and should use https
  • MEDIA_BASE_URL should be a separate media origin for user uploads
  • uploads and soundboard require R2/object storage to be configured
  1. Run app:
cargo run

Migrations are applied automatically during startup.

Server binds to 0.0.0.0:${PORT} (defaults to 3000). Web UI is available at http://localhost:${PORT}/.

Authentik setup notes

Create an Authentik OAuth2/OIDC provider + application and set:

  • Redirect URI: ${APP_BASE_URL}/auth/callback
  • Scopes including at least: openid profile email

If you change PORT, update OIDC_REDIRECT_URL and this redirect URI to match.

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. Authenticated WebSocket connections (/ws, /channels/:channel_id/voice/ws) also use the same cookie session.

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. User uploads are served from the configured media origin, not from /static.

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