KO
|
EN
gitlite — search
Search
#python
#java
#python3
#arduino
#golang
#machine-learning
#rust
#html
#flask
#javascript
#seismology
#nodejs
pulse-chat
★ 23
Open GitHub ↗
No description available.
Download README (.md)
Explore Similar Repositories
branch_db
:
Automatic per-branch PostgreSQL databases for Rails development
video-background-remover-cli
:
Remove background from video using RMBG-1.4 - Output as animated WebP or GIF
skillful-agent-system-builder
:
Skillful Agent System Builder helps you create custom AI agent teams without writing complex prompts from scratch.
sftp-go
:
No description available.
pi-lab
:
Pi extensions from your friends at Continua
// repository documentation
Was this content helpful?
★ 0
(0 ratings)
Select Rating:
★
★
★
★
★
Submit Feedback
Recent Feedback
×
Download README
Do you want to download the
README.md
file for
pulse-chat
?
Download (.md)
<p align="center"> <img src="https://raw.githubusercontent.com/plsechat/pulse-chat/main/apps/client/public/logo.png" alt="Pulse Chat" width="100" /> </p> <h1 align="center">Pulse Chat</h1> <p align="center"> A self-hosted chat platform built for privacy, voice, and connecting communities. <br /> <a href="https://plse.chat"><strong>plse.chat</strong></a> · <a href="README-SELFHOSTED-SUPABASE.md">Self-Hosting Guide</a> · <a href="https://github.com/plsechat/pulse-chat/releases">Releases</a> </p> <p align="center"> <a href="LICENSE"><img src="https://img.shields.io/badge/License-AGPL--3.0-blue.svg" alt="License" /></a> <a href="https://github.com/plsechat/pulse-chat/commits"><img src="https://img.shields.io/github/last-commit/plsechat/pulse-chat" alt="Last Commit" /></a> </p> <!-- <p align="center"><img src="docs/screenshot.png" alt="Screenshot" width="720" /></p> --> --- > [!NOTE] > Pulse Chat is in alpha (v0.3.0). Expect bugs and breaking changes between updates. > [!WARNING] > **The federation wire format changed in v0.2.0.** Signed requests embed the request body's SHA-256 in a `sha256` JWT claim, plus `iss`/`aud`/`jti` claims for replay and cross-instance protection. A v0.2.x server **cannot** federate with a pre-v0.2 peer — both sides must be on v0.2 or newer. ## Why Pulse? Pulse is a self-hosted alternative to Discord and Slack that puts you in control. Every message can be end-to-end encrypted, voice and video stay on your infrastructure, and federation lets separate instances talk to each other — no central service required. ## What's included | | | |---|---| | **Encrypted messaging** | Signal Protocol (X3DH + Double Ratchet) for DMs and channels, with TOFU identity pinning and safety-number verification | | **Voice & video** | WebRTC-powered calls with screen sharing via Mediasoup | | **Federation** | Link multiple Pulse instances so users can discover and join across servers | | **Forum channels** | Threaded discussions with tags for long-form topics | | **Channels & DMs** | Real-time text with file uploads, reactions, threads, and mentions | | **Roles & permissions** | Granular access control at the server, channel, and user level | | **Custom emojis** | Upload and manage emojis per server | | **Automod** | Keyword filters, regex rules, mention limits, and link blocking | | **Webhooks** | Push events to external services | | **Plugins** | Extend the server with installable plugins — event hooks and slash commands — via the plugin SDK | | **OAuth & SSO login** | Google, Discord, Facebook, Twitch (Supabase mode), plus native OpenID Connect SSO — Authentik, Keycloak, Zitadel, Auth0, or any OIDC provider (works with either auth backend) | | **Invite-only mode** | Lock down registration so only invited users can join | ## Getting started Pulse runs against either of two auth backends — pick whichever fits: | Backend | Needs | When to use | |---|---|---| | **`local`** (default) | Just PostgreSQL + an `AUTH_SECRET` | Single-node deployments, homelabs, anything where you don't want a SaaS dep. Email + password **and** native OIDC SSO (Authentik / Keycloak / …). No Supabase-mediated social logins. | | **`supabase`** | Supabase Cloud or a self-hosted Supabase stack | Social OAuth providers (Google / Discord / Facebook / Twitch) and setups that already run Supabase. Native OIDC SSO works here too. | Both modes share the same database schema and federate with each other — the auth backend choice is local to each instance. ### Quickest path — local auth + bundled Postgres Spin up Pulse with its own PostgreSQL container, no SaaS required: ```bash # Generate a session-signing secret (>=32 chars) and pin local mode cat > .env <<EOF AUTH_BACKEND=local AUTH_SECRET=$(openssl rand -base64 48 | tr -d '\n') EOF docker compose --profile local up -d ``` Pulse listens on `5443`; the bundled `postgres:16-alpine` is on `5432`. Open `http://localhost:5443` and the first user to register becomes the operator. ### Docker (existing Postgres / Supabase) ```bash docker run \ -p 5443:5443/tcp \ -p 40000-40020:40000-40020/tcp \ -p 40000-40020:40000-40020/udp \ -v ./data:/root/.config/pulse \ -e AUTH_BACKEND=local \ -e AUTH_SECRET="$(openssl rand -base64 48 | tr -d '\n')" \ -e DATABASE_URL=postgresql://user:pass@host:5432/dbname \ --name pulse \ ghcr.io/plsechat/pulse-chat:latest ``` For Supabase mode (OAuth, hosted auth) bundled with Pulse, use [docker-compose-supabase.yml](docker-compose-supabase.yml) — see the [Self-Hosted Guide](README-SELFHOSTED-SUPABASE.md). ### Linux binary ```bash curl -L https://github.com/plsechat/pulse-chat/releases/latest/download/pulse-linux-x64 -o pulse chmod +x pulse export AUTH_BACKEND=local export AUTH_SECRET="$(openssl rand -base64 48 | tr -d '\n')" export DATABASE_URL=postgresql://user:pass@localhost:5432/pulse ./pulse ``` ### After first launch 1. Open `http://localhost:5443` 2. A **security token** prints to the server console on first run — save it 3. Register and log in 4. Claim ownership: open the browser console and run `useToken('your_token_here')` ## Configuration ### Environment | Variable | Required when | What it does | |---|---|---| | `AUTH_BACKEND` | always (defaults inferred) | `local` or `supabase`. Defaults to `supabase` if `SUPABASE_URL` is set, else `local`. | | `AUTH_SECRET` | `AUTH_BACKEND=local` | ≥32 random chars; HS256 signing key for session tokens. **Rotating invalidates every session.** | | `DATABASE_URL` | always | Full Postgres connection string | | `SUPABASE_URL` / `SUPABASE_ANON_KEY` / `SUPABASE_SERVICE_ROLE_KEY` | `AUTH_BACKEND=supabase` | Managed or self-hosted Supabase Auth | | `PUBLIC_IP` | production behind NAT | Public IP for WebRTC ICE candidates | | `REGISTRATION_DISABLED` | optional | Lock down registration instance-wide (all methods; invites still work) | | `REGISTRATION_PASSWORD_ENABLED` / `REGISTRATION_OIDC_ENABLED` / `REGISTRATION_SOCIAL_ENABLED` | optional | Per-method signup switches (default `true`). Set to `false` to disable that method's self-registration; a valid invite still bypasses it. For OIDC-only signups, set the password + social ones to `false`. | | `FEDERATION_ALLOW_PRIVATE_CIDRS` | optional | Comma-separated IPv4 CIDRs to allow as federation peers (e.g. `192.168.1.0/24`). Default: all RFC1918 / loopback / link-local blocked. | | `OIDC_OAUTH_ENABLED` | optional | Set `true` to enable native OpenID Connect SSO (works under either auth backend). See [Single Sign-On (OIDC)](#single-sign-on-oidc). | | `OIDC_ISSUER` / `OIDC_CLIENT_ID` / `OIDC_SECRET` | `OIDC_OAUTH_ENABLED=true` | Your IdP's issuer URL and client credentials. Endpoints are discovered at `<issuer>/.well-known/openid-configuration`. | | `OIDC_LABEL` | optional | Login-button text (default `Single Sign-On`) | | `OIDC_REDIRECT_URI` | optional | Overrides the auto-derived `<pulse-url>/auth/oidc/callback` | | `GOOGLE_OAUTH_ENABLED` / `DISCORD_OAUTH_ENABLED` / `FACEBOOK_OAUTH_ENABLED` / `TWITCH_OAUTH_ENABLED` | `AUTH_BACKEND=supabase` | Toggle each Supabase-mediated social provider | | `GIPHY_API_KEY` | optional | Enables GIF search in the composer | | `TRUST_PROXY` | behind a reverse proxy | Trust `X-Forwarded-*` headers for client IP / protocol | | `DEBUG_LOGGING` | optional | Write JSON debug events to `log/debug.log` | | `DEBUG_LOG_MAX_SIZE_MB` / `DEBUG_LOG_MAX_FILES` | optional | Rotation limits for `debug.log` (used with `DEBUG_LOGGING`) | Full, commented templates — copy the one that matches your setup to `.env`: - [.env.local.example](.env.local.example) — local backend, no Supabase (the default path above). - [.env.supabase-public.example](.env.supabase-public.example) — `AUTH_BACKEND=supabase` against a managed/external Supabase project. - [.env.supabase-local.example](.env.supabase-local.example) — the bundled self-hosted Supabase stack (`docker-compose-supabase.yml`); see the [Self-Hosted Guide](README-SELFHOSTED-SUPABASE.md). ### config.ini A config file is generated at `~/.config/pulse/config.ini` on first run. | Section | Key | Default | What it does | |---|---|---|---| | server | `port` | `5443` | HTTP / WebSocket port | | server | `debug` | `false` | Verbose logging | | server | `autoupdate` | `false` | Auto-check for updates | | http | `maxFiles` | `40` | Max files per upload | | http | `maxFileSize` | `100` | Max file size (MB) | | mediasoup | `worker.rtcMinPort` | `40000` | WebRTC port range start | | mediasoup | `worker.rtcMaxPort` | `40020` | WebRTC port range end | | mediasoup | `video.initialAvailableOutgoingBitrate` | `6000000` | Bandwidth per stream (bps) | | federation | `enabled` | `false` | Turn on federation | | federation | `domain` | — | Your public domain (required for federation) | > [!IMPORTANT] > The port range `rtcMinPort`–`rtcMaxPort` controls how many concurrent voice/video connections are possible. Each connection uses one UDP port. Open these ports (TCP + UDP) in your firewall, and map the range in Docker if applicable. ## Single Sign-On (OIDC) Pulse can authenticate against any standards-compliant OpenID Connect provider — Authentik, Keycloak, Zitadel, Auth0, and others. Unlike the social providers (which are mediated by Supabase), OIDC is handled by Pulse itself, so it works under **both** the `local` and `supabase` auth backends and needs no Supabase. 1. In your IdP, create an OAuth2 / OIDC application (confidential client) and set its redirect URI to: ``` https://<your-pulse-url>/auth/oidc/callback ``` 2. Add to your `.env` (and make sure `AUTH_SECRET` is set — it signs the session token): ```env OIDC_OAUTH_ENABLED=true OIDC_LABEL=Authentik # login-button text OIDC_ISSUER=https://auth.example.com/application/o/<app-slug>/ OIDC_CLIENT_ID=your-client-id OIDC_SECRET=your-client-secret ``` Pulse fetches `<OIDC_ISSUER>/.well-known/openid-configuration` to discover endpoints and verifies the `id_token` (RS256 via the provider's JWKS, or HS256 with the client secret when the provider has no signing certificate). 3. Restart Pulse. A button labeled `OIDC_LABEL` appears on the login screen. First-time users are provisioned automatically (subject to your registration / invite policy). ## HTTPS Pulse doesn't terminate TLS. Put a reverse proxy in front — Caddy, Nginx, or Traefik all work. The [Self-Hosted Guide](README-SELFHOSTED-SUPABASE.md#set-up-https) has example configs for Caddy and Nginx. ## Architecture Subsystem deep-dives for contributors live in [docs/](docs/): [federation wire protocol](docs/federation.md) · [E2EE sender keys](docs/e2ee-sender-keys.md) · [voice lifecycle](docs/voice.md) ## Built with [Bun](https://bun.sh) · [React](https://react.dev) · [tRPC](https://trpc.io) · [Drizzle ORM](https://orm.drizzle.team) · [Mediasoup](https://mediasoup.org) · [Tailwind CSS](https://tailwindcss.com) · [Signal Protocol](https://signal.org/docs/) · optional [Supabase](https://supabase.com) ## License [AGPL-3.0](LICENSE)