No description
  • TypeScript 50.9%
  • Rust 41.8%
  • SCSS 5.9%
  • Dockerfile 0.9%
  • HTML 0.5%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Fabian Stamm 118a2f7ecd Support private CAs for the OIDC issuer and log full error causes
- Trust system root store and optional OIDC_CA_FILE when talking to Dex
- Log the complete error chain for auth failures instead of 'Request failed'
- Disable redirects and add a timeout for identity provider requests
- k8s example: screenshare-ca ConfigMap mounted and wired to OIDC_CA_FILE
2026-11-05 17:51:46 +01:00
backend Support private CAs for the OIDC issuer and log full error causes 2026-11-05 17:51:46 +01:00
deploy Support private CAs for the OIDC issuer and log full error causes 2026-11-05 17:51:46 +01:00
frontend Add Kubernetes example, app icon and switch frontend to Bun 2026-11-05 17:28:40 +01:00
.dockerignore Rewrite as Rust backend with React/Carbon frontend 2026-11-05 17:21:54 +01:00
.editorconfig Working on better thing 2023-07-02 15:51:49 +02:00
.gitignore Rewrite as Rust backend with React/Carbon frontend 2026-11-05 17:21:54 +01:00
Dockerfile Add Kubernetes example, app icon and switch frontend to Bun 2026-11-05 17:28:40 +01:00
README.md Support private CAs for the OIDC issuer and log full error causes 2026-11-05 17:51:46 +01:00

ScreenSharingThing

Self-hosted screen sharing, voice and chat that runs fully offline.

  • Backend: Rust (axum, sqlx/PostgreSQL). Serves the API, the WebSocket signalling and the built frontend.
  • Frontend: React + Carbon (@carbon/react), built with Vite and managed with Bun; fonts bundled (no CDN).
  • Auth: OpenID Connect against Dex (code flow + PKCE, handled by the backend; the browser only gets an encrypted HttpOnly cookie).
  • Media: peer-to-peer WebRTC mesh (best for ~2–6 people). coturn relays traffic between subnets.
  • Sessions are public (listed for everyone signed in) or private (invite by e-mail). Owners can name moderators, who can mute/remove members.

State lives only in PostgreSQL (sessions, invites, chat history). Who is currently online is in memory, so run a single backend instance.

Development

docker compose -f deploy/docker-compose.dev.yml up -d      # Postgres, Dex (:5556), coturn
cd backend && cp .env.example .env && set -a && . ./.env && set +a && cargo run
cd frontend && bun install && bun run dev                  # http://localhost:5173

Dev users in Dex: alice@example.com / bob@example.com, password password.

Production

Build one image (docker build -t screenshare .) and run it next to your Postgres and Dex. See deploy/docker-compose.yml.

Variable Description
DATABASE_URL Postgres connection string (migrations run on start)
PUBLIC_URL URL users open in the browser, must be HTTPS in production. <PUBLIC_URL>/auth/callback must be a redirect URI of the Dex client
OIDC_ISSUER, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET Dex client; the issuer must be reachable from backend and browser under the same URL
OIDC_CA_FILE optional PEM file with extra CA certificate(s) to trust for the issuer (private/internal CA). The system store is honoured too (SSL_CERT_FILE/SSL_CERT_DIR)
COOKIE_SECRET ≥ 64 chars; keeps logins valid across restarts
TURN_URLS, TURN_SECRET e.g. turn:host:3478?transport=udp; shared secret of coturn (use-auth-secret)
STUN_URLS optional
LISTEN_ADDR, STATIC_DIR default 0.0.0.0:8080, public

Microphone and screen capture only work in a secure context. On an offline LAN use a reverse proxy with an internal CA (e.g. Caddy) in front of the app.