- JavaScript 96.3%
- CSS 3.3%
- Dockerfile 0.2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
All checks were successful
Build & Push Docker Image / build (push) Successful in 3m48s
|
||
| .gitea/workflows | ||
| public | ||
| screenshots | ||
| server | ||
| src | ||
| test | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| CLAUDE.md | ||
| compose.yml | ||
| docker-entrypoint.sh | ||
| Dockerfile | ||
| index.html | ||
| LICENSE | ||
| migrate-from-greenlight.mjs | ||
| package-lock.json | ||
| package.json | ||
| postcss.config.js | ||
| README.md | ||
| vite.config.js | ||
🔴 Redlight
⚠️ Warning: This project is entirely vibe coded and meant to be a fun/hobby project. Use at your own risk!
A modern, self-hosted BigBlueButton frontend with 24 themes, federation, calendar, CalDAV, OAuth/OIDC, and powerful room management.
🖼️ Pictures
✨ Features
Core Features
- 🎥 Video Conferencing - Integrated BigBlueButton support for professional video meetings
- 🎨 24 Themes - Dracula, Nord, Catppuccin, Rosé Pine, Gruvbox, Tokyo Night, Solarized, Everforest, Ayu, Kanagawa, Moonlight, Cyberpunk, Cotton Candy, and more
- 📝 Room Management - Create unlimited rooms with custom settings, access codes, and moderator codes
- 🔐 User Management - Registration, login, role-based access control (Admin/User)
- 📹 Recording Management - View, publish, and delete meeting recordings per room
- 📊 Learning Analytics - Collect and view per-room participant engagement data (talk time, messages, reactions) via BBB callbacks, secured with HMAC tokens
- 📅 Calendar - Built-in calendar with event creation, sharing, customizable reminders, and room linking
- 📆 CalDAV Server - Full CalDAV support for syncing calendars with Thunderbird, Apple Calendar, GNOME Calendar, DAVx⁵ (Android), and other standard clients
- 🌍 Multi-Language Support - German (Deutsch) and English built-in, easily extensible
- 🔔 In-App Notifications - Notifications for room shares, federation invites, and calendar reminders
- ✉️ Email Verification - Optional SMTP-based email verification for user registration
- 🔑 OAuth / OIDC - Login via OpenID Connect providers (Keycloak, Authentik, etc.) with PKCE, configured in the admin panel
- 🔒 Two-Factor Authentication - Optional TOTP 2FA for local accounts
- 👤 User Profiles - Customizable display names, avatars, themes, and language preferences
- 📱 Responsive Design - Works seamlessly on mobile, tablet, and desktop
- 🌐 Federation - Invite users from remote Redlight instances via Ed25519-signed messages
- 🐉 DragonflyDB / Redis - JWT blacklisting for secure token revocation on logout
Admin Features
- 👥 User Administration - Create and delete users, assign the admin/user role, reset passwords
- 🏠 Room Overview - List of all rooms on the instance with their owners
- 🏢 Branding Customization - Custom app name, logo, default theme, imprint and privacy links
- 🔧 Settings Management - Registration mode and OpenID Connect configuration
- ✉️ Invite-Only Registration - Generate invite tokens for controlled user signup
Room Features
- 🔑 Access Codes - Restrict room access with optional passwords
- 🔐 Moderator Codes - Separate code to grant moderator privileges
- 🚪 Guest Access - Unauthenticated users can join via the room link (rate-limited)
- 👤 Signed-In Users Only - Optionally close a room to guests entirely
- ⏱️ Max Participants - Set limits on concurrent participants
- 🎤 Mute on Join - Automatically mute new participants
- ✅ Approval Mode - Guests and non-members wait in BBB's waiting room until a moderator admits them
- 🎙️ Anyone Can Start - Allow participants to start the meeting
- 📹 Recording Settings - Control whether meetings are recorded
- 📊 Learning Analytics - Toggle per-room to collect participant engagement data after each meeting
- 📑 Presentation Upload - Upload PDF, PPTX, ODP, DOC, DOCX as default slides
- 🤝 Room Sharing - Share rooms with other registered users
Security
- 🛡️ Comprehensive Rate Limiting - Login, register, profile, avatar, guest-join, OAuth, and federation endpoints
- 🔒 Input Validation - Email format, field length limits, ID format checks, color format validation
- 🕐 Timing-Safe Comparisons - Access codes and moderator codes compared with
crypto.timingSafeEqual - 📏 Streaming Upload Limits - Avatar (2 MB) and presentation (50 MB) uploads reject early without buffering
- 🧹 XSS Prevention - HTML-escaped emails, XML-escaped BBB parameters, uploaded SVG logos served as downloads, Content-Security-Policy
- 🔐 JWT Blacklist - Token revocation via DragonflyDB/Redis on logout
- 🌐 SSRF-Safe Federation - Peer requests only reach public addresses, never follow redirects
- 🌐 CORS Restriction - Locked to
APP_URLin production - ⚙️ Configurable Trust Proxy -
TRUST_PROXYenv var for reverse proxy setups - 🔏 HMAC-Secured Callbacks - Learning analytics callback URLs signed with HMAC-SHA256
Developer Features
- 🐳 Docker Support - Easy deployment with Docker Compose (includes PostgreSQL + DragonflyDB)
- 🗄️ Database Flexibility - SQLite (default) or PostgreSQL support
- 🔌 JSON API - The API behind the web app (JWT bearer auth), listed below
- 📦 Open Source - Full source code transparency
- 🛠️ Self-Hosted - Complete data privacy and control
📊 Comparison: Redlight vs Greenlight v3
The Greenlight column reflects Greenlight v3 (release 3.9, checked October 2026). Corrections welcome.
| Feature | Redlight | Greenlight v3 |
|---|---|---|
| Frontend | React 19, Tailwind CSS 4, Vite | React 17, React-Bootstrap (Bootstrap 5), esbuild |
| Backend | Node.js, Express 5 | Ruby on Rails 7.2 (JSON API) |
| Database | SQLite (default) or PostgreSQL | PostgreSQL |
| Redis | Optional (logout token blacklist, rate limits) | Required in production |
| Deployment | Docker Compose; reverse proxy/TLS set up manually | Docker Compose; official install scripts incl. nginx + Let's Encrypt |
| UI languages | 2 (English, German) | 25 (community translations) |
| Look & feel | 24 built-in themes, selectable per user; admin sets the default | Admin-defined brand colour and logo |
| Login | Local accounts, OpenID Connect (PKCE), built-in TOTP 2FA | Local accounts, OpenID Connect; no built-in 2FA |
| Registration modes | Open, invite-only | Open, invite-only, admin approval; allowed email domains |
| Roles & permissions | Fixed: admin / user | Custom roles with configurable permissions (e.g. room limit, recording, sharing) |
| Room settings | Access code, moderator code, mute on join, guest approval (waiting room), signed-in users only, anyone can start, all join as moderator, max participants, welcome message, recording | Viewer/moderator access codes, mute on start, guest approval, require sign-in, anyone can start, all join as moderator, recording; admins can enforce or hide each option |
| Room sharing | ✅ | ✅ (can be disabled by admins) |
| Presentation upload | ✅ PDF, PPT/PPTX, ODP, DOC/DOCX (50 MB) | ✅ Office, OpenDocument, PDF, images (30 MB); optional ClamAV scan |
| Recordings | List, publish/unpublish, delete (per room) | Rename, delete, five visibility levels incl. protected/public, public recordings list on room page, admin overview |
| Learning analytics | ✅ Stored per room, export as CSV/XLSX/PDF | ❌ (BBB's in-meeting Learning Dashboard is available with both) |
| Calendar / CalDAV | ✅ Built-in calendar, CalDAV server, ICS export | ❌ |
| Federation | ✅ Room and calendar invites between Redlight instances | ❌ |
| Notifications | In-app (room shares, invites, calendar reminders) + email | Email (invitations, sign-up approvals) |
| Admin panel | Users, invites, rooms, branding, registration mode, OIDC | Users (incl. pending/banned), roles, server rooms, server recordings, room configuration, site settings, tenants |
| Multi-tenancy / Scalelite tags | ❌ | ✅ |
| File storage | Local disk | Local disk, S3, Google Cloud Storage |
| License | GPL-3.0-or-later | LGPL-3.0 |
Coming from Greenlight? migrate-from-greenlight.mjs imports users (incl. SSO users), rooms with their settings, shares and selected site settings from a Greenlight v3 database. Uploaded files (presentations, avatars, custom logo) and recording visibility are not migrated; see the header of the script for details.
🚀 Quick Start
Prerequisites
- Docker & Docker Compose
- BigBlueButton server (with API access)
- SMTP server (optional, for email verification)
Installation
-
Clone the repository
git clone https://git.scrunkly.cat/Michelle/redlight cd redlight -
Configure environment
cp .env.example .envEdit
.envwith your settings:BBB_URL=https://your-bbb-server.com/bigbluebutton/api/ BBB_SECRET=your-bbb-shared-secret JWT_SECRET=your-secret-key # REQUIRED - app won't start without this APP_URL=https://your-domain.com # REQUIRED in production - used for CORS and email links ADMIN_PASSWORD=choose-a-strong-one # REQUIRED on first start - initial admin password DATABASE_URL=postgres://redlight:redlight@postgres:5432/redlight POSTGRES_USER=redlight POSTGRES_PASSWORD=redlight POSTGRES_DB=redlight # DragonflyDB / Redis (JWT blacklist for logout) REDIS_URL=redis://dragonfly:6379 # Reverse proxy trust (default: loopback) # TRUST_PROXY=loopback # Optional: Email verification # SMTP_HOST=smtp.gmail.com # SMTP_PORT=587 # SMTP_USER=your-email@gmail.com # SMTP_PASS=your-app-password # Optional: Federation (cross-instance room invites) # FEDERATION_DOMAIN=your-domain.comOAuth / OpenID Connect is not configured via
.env: set the issuer, client ID and secret in the admin panel after the first login. -
Start the application
docker compose up -d -
Access the application
- Open
http://localhost:3001in your browser - Log in as
admin@example.com(or yourADMIN_EMAIL) with theADMIN_PASSWORDyou set
- Open
🛠️ Development
Local Setup
-
Install dependencies
npm install -
Start development server
npm run dev- Frontend: http://localhost:5173
- Backend: http://localhost:3001
-
Run the tests
npm test -
Build for production
npm run build npm start
Tech Stack
- Frontend: React 19, Tailwind CSS 4, React Router 7, Lucide Icons
- Backend: Node.js 22, Express 5, JWT, bcryptjs
- Database: SQLite / PostgreSQL with better-sqlite3 / pg
- Cache: DragonflyDB / Redis (ioredis) - JWT blacklisting
- Email: Nodemailer
- CalDAV: xml2js-based WebDAV/CalDAV server
- Auth: JWT + OAuth/OIDC (PKCE)
- Build: Vite
📁 Project Structure
redlight/
├── server/ # Node.js/Express backend
│ ├── config/ # Database, Redis, mailer, BBB, federation, OAuth & notification config
│ ├── i18n/ # Server-side translations (email templates)
│ ├── jobs/ # Background jobs (federation sync, calendar reminders)
│ ├── middleware/ # JWT authentication, logging & token blacklisting
│ ├── routes/ # API endpoints (auth, rooms, recordings, admin, branding,
│ │ # federation, calendar, caldav, notifications, oauth, analytics)
│ └── index.js # Server entry point
├── src/ # React frontend
│ ├── components/ # Reusable components (RecordingList, AnalyticsList, etc.)
│ ├── contexts/ # React context (Auth, Language, Theme, Branding, Notification)
│ ├── i18n/ # Translations (DE, EN)
│ ├── pages/ # Page components
│ ├── services/ # API client
│ ├── themes/ # 24 theme definitions
│ └── main.jsx # Frontend entry point
├── public/ # Static assets
├── uploads/ # User avatars, branding & presentations (runtime)
├── keys/ # Federation Ed25519 key pair (auto-generated)
├── compose.yml # Docker Compose (Redlight + PostgreSQL + DragonflyDB)
├── Dockerfile # Multi-stage container image
└── package.json # Dependencies
🔐 Security
- JWT Authentication - Secure token-based auth with 7-day expiration and
jti-based blacklisting via DragonflyDB/Redis; password changes and resets revoke all sessions and CalDAV tokens - Mandatory Secrets - Server refuses to start without
JWT_SECRET, and in production withoutAPP_URLandBBB_SECRET - OAuth / OIDC - OpenID Connect with PKCE (S256) and single-use state tokens bound to the browser
- Two-Factor Authentication - TOTP with per-account attempt limits and replay protection
- HTTPS Ready - Configure behind reverse proxy (nginx, Caddy); trust proxy via
TRUST_PROXYenv - Password Hashing - bcryptjs with salt rounds 12, minimum 8-character passwords
- Email Verification - Optional SMTP-based email verification with resend support
- CORS Protection - Restricted to
APP_URLin production, open in development - Rate Limiting - Login, register, profile, password, avatar, guest-join, OAuth, and federation endpoints
- Input Validation - Email regex, field length limits, ID format checks, hex-color format checks
- Timing-Safe Comparisons - Access codes and moderator codes compared via
crypto.timingSafeEqual - Upload Safety - Streaming body size limits (avatar 2 MB, presentation 50 MB) abort early without buffering; file types are checked by content
- XSS / Injection Prevention - HTML-escaped emails, XML-escaped BBB API parameters, SVG logos served as
attachment, escaped ICS/CalDAV output, Content-Security-Policy - HMAC-Secured Callbacks - Learning analytics callback URLs signed with HMAC-SHA256 derived from BBB_SECRET
- Federation Hardening - Ed25519-signed payloads; outbound requests are SSRF-guarded (public addresses only, connection pinned to the checked IP, no redirects); optional domain allowlist
- Log Hygiene - Tokens and codes in request URLs are redacted from the access log
- Admin Isolation - Role-based access control with strict admin checks
- Container Hardening - The Docker image runs as an unprivileged user; Docker Compose publishes the app on localhost only and uses an internal backend network for DB and cache
📦 API Endpoints
All routes are under /api and use Authorization: Bearer <jwt> unless noted. The API is the one the SPA uses; it is not versioned.
Authentication
POST /api/auth/register- Register (invite token required in invite-only mode)GET /api/auth/verify-email?token=...- Verify email with tokenPOST /api/auth/resend-verification- Resend verification emailPOST /api/auth/forgot-password/POST /api/auth/reset-password- Password reset by emailPOST /api/auth/login- Login (returns a 2FA step token if 2FA is enabled)POST /api/auth/login/2fa- Complete login with a TOTP codePOST /api/auth/logout- Logout (blacklists the JWT)GET /api/auth/me- Current userPUT /api/auth/profile- Update username, display name, email, theme, language, avatar colourPUT /api/auth/password- Change passwordPOST /api/auth/avatar/DELETE /api/auth/avatar- Upload / remove avatarGET /api/auth/2fa/status,POST /api/auth/2fa/setup,POST /api/auth/2fa/enable,POST /api/auth/2fa/disable- Manage TOTP 2FA
Rooms
GET /api/rooms/POST /api/rooms- List own and shared rooms / create a roomGET /api/rooms/:uid/PUT /api/rooms/:uid/DELETE /api/rooms/:uid- Room details / update / deleteGET /api/rooms/users/search?q=...- Search users to share a room withGET /api/rooms/:uid/public- Public room info for the guest page (no auth)POST /api/rooms/:uid/start- Start meetingPOST /api/rooms/:uid/join- Join meeting as signed-in userPOST /api/rooms/:uid/guest-join- Join as guest (no auth, rate-limited; uses the account if signed in)POST /api/rooms/:uid/end- End meetingGET /api/rooms/:uid/status- Is the meeting running (no auth)GET /api/rooms/:uid/shares,POST /api/rooms/:uid/shares,DELETE /api/rooms/:uid/shares/:userId- Room sharingPOST /api/rooms/:uid/presentation/DELETE /api/rooms/:uid/presentation- Default presentationPOST /api/rooms/invite-email- Email invitations to guests
Recordings
GET /api/recordings/room/:uid- List room recordings (GET /api/recordings?meetingID=...also works)PUT /api/recordings/:recordID/publish- Publish / unpublishDELETE /api/recordings/:recordID- DeletePOST /api/recordings/recording-ready- BBB recording-ready callback (signed by BBB)
Learning Analytics
POST /api/analytics/callback/:uid?token=...- BBB callback (HMAC-secured)GET /api/analytics/room/:uid- Analytics of a roomGET /api/analytics/:id/export/:format- Export ascsv,xlsxorpdfDELETE /api/analytics/:id- Delete an entry
Calendar
GET /api/calendar/events/POST /api/calendar/events- List / create eventsGET /api/calendar/events/:id,PUT /api/calendar/events/:id,DELETE /api/calendar/events/:id- Event details / update / deleteGET /api/calendar/events/:id/ics- Download as ICSPOST /api/calendar/events/:id/share,DELETE /api/calendar/events/:id/share/:userId- Invite / remove local usersPOST /api/calendar/events/:id/email- Email invitation with ICS attachmentPOST /api/calendar/events/:id/federation- Send to a user on another Redlight instanceGET /api/calendar/local-invitations,POST /api/calendar/local-invitations/:id/accept,DELETE /api/calendar/local-invitations/:id- Invitations from local usersGET /api/calendar/caldav-tokens,POST /api/calendar/caldav-tokens,DELETE /api/calendar/caldav-tokens/:id- CalDAV tokens
Notifications
GET /api/notifications- List notificationsPOST /api/notifications/:id/read/POST /api/notifications/read-all- Mark as readDELETE /api/notifications/:id/DELETE /api/notifications/all- Delete
Admin
GET /api/admin/users/POST /api/admin/users- List / create usersPUT /api/admin/users/:id/role- Change rolePUT /api/admin/users/:id/password- Reset passwordDELETE /api/admin/users/:id- Delete userGET /api/admin/invites,POST /api/admin/invites,DELETE /api/admin/invites/:id- Registration invitesGET /api/admin/rooms- All rooms with ownersGET /api/admin/oauth,PUT /api/admin/oauth,DELETE /api/admin/oauth- OpenID Connect configuration
Branding
GET /api/branding- Branding settings (public)GET /api/branding/logo- Logo (public);POST/DELETEto upload or remove it (admin)PUT /api/branding/name,/default-theme,/registration-mode,/imprint-url,/privacy-url,/hide-app-name- Update settings (admin)
OAuth
GET /api/oauth/providers- Configured provider (public)GET /api/oauth/authorize?return_to=/path- Start the OIDC flow (redirects to the provider)GET /api/oauth/callback- Provider callback (PKCE code exchange)
Federation
GET /.well-known/redlight- Instance discovery (domain, public key)POST /api/federation/invite- Invite a remote user to a roomGET /api/federation/invitations,GET /api/federation/invitations/pending-count- Received room invitationsPOST /api/federation/invitations/:id/accept,DELETE /api/federation/invitations/:id- Accept / declineGET /api/federation/calendar-invitations,POST .../:id/accept,DELETE .../:id- Received calendar invitationsGET /api/federation/federated-rooms,DELETE /api/federation/federated-rooms/:id- Accepted remote roomsPOST /api/federation/receive,/calendar-event,/room-sync,/room-deleted,/calendar-event-deleted- Instance-to-instance calls (Ed25519-signed, rate-limited)
CalDAV
Basic auth with email:caldav-token; clients can discover the server via /.well-known/caldav.
PROPFIND /caldav/- CalDAV discoveryPROPFIND/REPORT /caldav/:user/calendar/- Calendar metadata and queriesGET/PUT/DELETE /caldav/:user/calendar/:uid.ics- Event CRUD
🌍 Internationalization (i18n)
Redlight comes with built-in support for multiple languages. Currently supported:
- 🇩🇪 Deutsch (German)
- 🇬🇧 English
Adding a new language
- Create
src/i18n/xx.json(e.g.,fr.jsonfor French) - Copy structure from
de.jsonoren.json - Translate all strings
- Update
src/i18n/index.jsto include the new language
🎨 Themes
Redlight includes 24 themes:
- ☀️ Light / 🌙 Dark (default)
- 🐱 Catppuccin Mocha / Latte
- 🧛 Dracula
- ❄️ Nord
- 🌊 Tokyo Night
- 💜 One Dark
- 🐙 GitHub Dark
- 🌹 Rosé Pine / Rosé Pine Dawn
- 🍂 Gruvbox Dark / Gruvbox Light
- ☀️ Solarized Dark / Solarized Light
- 🌲 Everforest Dark / Everforest Light
- 🌊 Kanagawa
- 🌙 Moonlight
- 🎮 Cyberpunk
- 🌸 Ayu Dark
- 🔴 Red Modular Light
- 🍬 Cotton Candy Light
- 🐱 scrunkly.cat Dark
Themes are fully customizable by editing src/themes/index.js.
🐳 Docker Deployment
Using Docker Compose (Recommended)
docker compose up -d
Services:
- redlight - Node.js application (port 3001, published on
127.0.0.1only; put a TLS-terminating reverse proxy in front) - postgres - PostgreSQL 17 database
- dragonfly - DragonflyDB (Redis-compatible) for JWT blacklisting and rate limits
The compose.yml uses isolated networks: frontend and backend (internal, no external access). PostgreSQL and DragonflyDB data live in named volumes (pgdata, dragonflydata); uploads and federation keys are bind-mounted from ./uploads and ./keys. The container runs as the unprivileged node user; on start it hands ownership of /app/uploads, /app/data and /app/keys to that user, so volumes from older releases keep working.
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
BBB_URL |
Yes | - | BigBlueButton API URL (must end with /) |
BBB_SECRET |
Yes | - | BigBlueButton shared secret; server won't start without it in production |
JWT_SECRET |
Yes | - | Secret for signing JWTs (server won't start without it); also encrypts the stored OIDC client secret |
APP_URL |
Yes (production) | - | Public URL of the app (used for CORS + email links); server won't start without it in production |
DATABASE_URL |
No | SQLite | PostgreSQL connection string |
SQLITE_PATH |
No | ./redlight.db |
SQLite file (when DATABASE_URL is not set) |
REDIS_URL |
No | redis://localhost:6379 |
DragonflyDB / Redis URL |
TRUST_PROXY |
No | loopback |
Express trust proxy setting (number or string) |
SMTP_HOST |
No | - | SMTP server for email verification |
SMTP_PORT |
No | 587 |
SMTP port |
SMTP_USER |
No | - | SMTP username |
SMTP_PASS |
No | - | SMTP password |
SMTP_FROM |
No | SMTP_USER |
Sender address |
FEDERATION_DOMAIN |
No | - | Domain for federation (enables cross-instance invites) |
FEDERATION_KEY_PATH |
No | /app/keys/federation_key.pem |
Location of the Ed25519 federation key |
FEDERATION_ALLOWED_DOMAINS |
No | - (any) | Comma-separated list of peer domains to federate with |
TRANSCRIPTION_API_URL / TRANSCRIPTION_API_KEY |
No | - | Optional recording transcription / AI summary service |
ADMIN_EMAIL |
No | admin@example.com |
Default admin email (first start only) |
ADMIN_PASSWORD |
First start | - | Initial admin password, 8-64 characters (first start only; no default) |
OAuth / OpenID Connect is configured in the admin panel, not via environment variables.
Production Deployment
Behind a reverse proxy (nginx example):
upstream redlight {
server localhost:3001;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
client_max_body_size 50M; # presentations may be up to 50 MB
location / {
proxy_pass http://redlight;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Note: When running behind a reverse proxy, set
TRUST_PROXY=1(or the appropriate value) in.envso Express reads the correct client IP for rate limiting.
🌐 Federation
Federation allows users on different Redlight instances to invite each other into rooms.
Setup
- Set
FEDERATION_DOMAIN=your-domain.comin.env. - On first start, an Ed25519 key pair is generated automatically and stored in
keys/federation_key.pem. - In Docker, mount
./keys:/app/keys(already configured incompose.yml). - Other instances discover your public key via
GET /.well-known/redlight. - Optional: restrict federation to known instances with
FEDERATION_ALLOWED_DOMAINS=a.example,b.example. By default any instance can send invitations to your users.
How it works
- User A on
instance-a.comsends an invite touserB@instance-b.com. - Redlight looks up
instance-b.com/.well-known/redlightto discover the federation API. - The invite payload is signed with instance A's private key and POSTed to instance B's
/api/federation/receive. - Instance B verifies the Ed25519 signature against instance A's public key.
- User B sees the invitation and can accept or decline. Accepting provides a join link to the remote room.
🐛 Troubleshooting
Issue: "ERR_ERL_PERMISSIVE_TRUST_PROXY"
Solution: Set TRUST_PROXY in .env. Use loopback (default) or 1 when behind a single reverse proxy.
Issue: "JWT_SECRET is not set"
Solution: The server requires a JWT_SECRET environment variable and will refuse to start without one. Add it to your .env file.
Issue: "Email verification not working"
Solution: Ensure SMTP is configured in .env. If SMTP_HOST is not set, email verification is disabled.
Issue: "BigBlueButton API error"
Solution: Verify BBB_URL and BBB_SECRET are correct. Test the connection with:
curl "https://your-bbb-server/bigbluebutton/api/getMeetings?checksum=..."
Issue: "Database connection failed"
Solution: Check DATABASE_URL format. For PostgreSQL: postgres://user:password@host:5432/redlight
Issue: "Theme not applying"
Solution: Clear browser cache (Ctrl+Shift+Del) or restart dev server with npm run dev.
Issue: "DragonflyDB connection error"
Solution: Ensure DragonflyDB (or Redis) is running and REDIS_URL is correct. If unavailable, the app still works - JWT blacklisting degrades gracefully (logout won't revoke tokens immediately).
📝 License
This project is licensed under the GNU GPL v3 (or later) - see LICENSE file for details.
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request


