Update README.md to reflect new features, security enhancements, and environment variable requirements
All checks were successful
Build & Push Docker Image / build (push) Successful in 6m24s

This commit is contained in:
2026-02-28 20:11:14 +01:00
parent 1fb999d73b
commit 2831f80ab4

152
README.md
View File

@@ -1,8 +1,8 @@
# 🔴 Redlight # 🔴 Redlight
A modern, self-hosted BigBlueButton frontend with beautiful themes and powerful features. A modern, self-hosted BigBlueButton frontend with beautiful themes, federation, and powerful features.
![Node.js](https://img.shields.io/badge/Node.js-18+-green) ![Node.js](https://img.shields.io/badge/Node.js-20+-green)
![React](https://img.shields.io/badge/React-18+-blue) ![React](https://img.shields.io/badge/React-18+-blue)
![License](https://img.shields.io/badge/License-MIT-yellow) ![License](https://img.shields.io/badge/License-MIT-yellow)
![BigBlueButton](https://img.shields.io/badge/BigBlueButton-Compatible-red) ![BigBlueButton](https://img.shields.io/badge/BigBlueButton-Compatible-red)
@@ -11,32 +11,47 @@ A modern, self-hosted BigBlueButton frontend with beautiful themes and powerful
### Core Features ### Core Features
- 🎥 **Video Conferencing** Integrated BigBlueButton support for professional video meetings - 🎥 **Video Conferencing** Integrated BigBlueButton support for professional video meetings
- 🎨 **15+ Themes** Dracula, Nord, Catppuccin, Rosé Pine, Gruvbox, and more - 🎨 **15+ Themes** Dracula, Nord, Catppuccin, Rosé Pine, Gruvbox, and more (extensible via volume mount)
- 📝 **Room Management** Create unlimited rooms with custom settings and access codes - 📝 **Room Management** Create unlimited rooms with custom settings, access codes, and moderator codes
- 🔐 **User Management** Registration, login, role-based access control (Admin/User) - 🔐 **User Management** Registration, login, role-based access control (Admin/User)
- 📹 **Recording Management** View, publish, and delete meeting recordings per room - 📹 **Recording Management** View, publish, and delete meeting recordings per room
- 🌍 **Multi-Language Support** German (Deutsch) and English built-in, easily extensible - 🌍 **Multi-Language Support** German (Deutsch) and English built-in, easily extensible
- ✉️ **Email Verification** Optional SMTP-based email verification for user registration - ✉️ **Email Verification** Optional SMTP-based email verification for user registration
- 👤 **User Profiles** Customizable avatars, themes, and language preferences - 👤 **User Profiles** Customizable avatars, themes, and language preferences
- 📱 **Responsive Design** Works seamlessly on mobile, tablet, and desktop - 📱 **Responsive Design** Works seamlessly on mobile, tablet, and desktop
- 🌐 **Federation** Invite users from remote Redlight instances via RSA-signed messages
- 🐉 **DragonflyDB / Redis** JWT blacklisting for secure token revocation on logout
### Admin Features ### Admin Features
- 👥 **User Administration** Manage users and roles - 👥 **User Administration** Manage users and roles
- 🏢 **Branding Customization** Custom app name and logos - 🏢 **Branding Customization** Custom app name, logos, and default theme
- 📊 **Dashboard** Overview of system statistics - 📊 **Dashboard** Overview of system statistics
- 🔧 **Settings Management** System-wide configuration - 🔧 **Settings Management** System-wide configuration
### Room Features ### Room Features
- 🔑 **Access Codes** Restrict room access with optional passwords - 🔑 **Access Codes** Restrict room access with optional passwords
- 🚪 **Guest Access** Allow unauthenticated users to join meetings - 🔐 **Moderator Codes** Separate code to grant moderator privileges
- 🚪 **Guest Access** Allow unauthenticated users to join meetings (rate-limited)
- ⏱️ **Max Participants** Set limits on concurrent participants - ⏱️ **Max Participants** Set limits on concurrent participants
- 🎤 **Mute on Join** Automatically mute new participants - 🎤 **Mute on Join** Automatically mute new participants
-**Approval Mode** Require moderator approval for participants -**Approval Mode** Require moderator approval for participants
- 🎙️ **Anyone Can Start** Allow participants to start the meeting - 🎙️ **Anyone Can Start** Allow participants to start the meeting
- 📹 **Recording Settings** Control whether meetings are recorded - 📹 **Recording Settings** Control whether meetings are recorded
- 📊 **Presentation Upload** Upload PDF, PPTX, ODP, or image files as default slides
- 🤝 **Room Sharing** Share rooms with other registered users
### Security
- 🛡️ **Comprehensive Rate Limiting** Login, register, profile, avatar, guest-join, and federation endpoints
- 🔒 **Input Validation** Email format, field length limits, theme/language allowlists, color format validation
- 🕐 **Timing-Safe Comparisons** Access codes and moderator codes compared with `crypto.timingSafeEqual`
- 📏 **Streaming Upload Limits** Avatar (5 MB) and presentation (50 MB) uploads reject early without buffering
- 🧹 **XSS Prevention** HTML-escaped emails, XML-escaped BBB parameters, SVG sanitization
- 🔐 **JWT Blacklist** Token revocation via DragonflyDB/Redis on logout
- 🌐 **CORS Restriction** Locked to `APP_URL` in production
- ⚙️ **Configurable Trust Proxy** `TRUST_PROXY` env var for reverse proxy setups
### Developer Features ### Developer Features
- 🐳 **Docker Support** Easy deployment with Docker Compose - 🐳 **Docker Support** Easy deployment with Docker Compose (includes PostgreSQL + DragonflyDB)
- 🗄️ **Database Flexibility** SQLite (default) or PostgreSQL support - 🗄️ **Database Flexibility** SQLite (default) or PostgreSQL support
- 🔌 **REST API** Comprehensive API for custom integrations - 🔌 **REST API** Comprehensive API for custom integrations
- 📦 **Open Source** Full source code transparency - 📦 **Open Source** Full source code transparency
@@ -49,6 +64,7 @@ A modern, self-hosted BigBlueButton frontend with beautiful themes and powerful
| Feature | Redlight | Greenlight | | Feature | Redlight | Greenlight |
|---------|----------|-----------| |---------|----------|-----------|
| **Theme System** | 15+ customizable themes | Limited theming | | **Theme System** | 15+ customizable themes | Limited theming |
| **Federation** | ✅ Cross-instance invites | ❌ Not supported |
| **Language Support** | Multi-language ready | Multi-language ready | | **Language Support** | Multi-language ready | Multi-language ready |
| **UI Framework** | React + Tailwind (Modern) | Rails-based (Traditional) | | **UI Framework** | React + Tailwind (Modern) | Rails-based (Traditional) |
| **User Preferences** | Theme, language, avatar | Limited customization | | **User Preferences** | Theme, language, avatar | Limited customization |
@@ -87,18 +103,28 @@ A modern, self-hosted BigBlueButton frontend with beautiful themes and powerful
```env ```env
BBB_URL=https://your-bbb-server.com/bigbluebutton/api/ BBB_URL=https://your-bbb-server.com/bigbluebutton/api/
BBB_SECRET=your-bbb-shared-secret BBB_SECRET=your-bbb-shared-secret
JWT_SECRET=your-secret-key JWT_SECRET=your-secret-key # REQUIRED app won't start without this
APP_URL=https://your-domain.com # Used for CORS and email links
DATABASE_URL=postgres://user:password@postgres:5432/redlight DATABASE_URL=postgres://user:password@postgres:5432/redlight
POSTGRES_USER=redlight POSTGRES_USER=redlight
POSTGRES_PASSWORD=redlight POSTGRES_PASSWORD=redlight
POSTGRES_DB=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 # Optional: Email verification
SMTP_HOST=smtp.gmail.com SMTP_HOST=smtp.gmail.com
SMTP_PORT=587 SMTP_PORT=587
SMTP_USER=your-email@gmail.com SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-password SMTP_PASS=your-app-password
# Optional: Federation (cross-instance room invites)
# FEDERATION_DOMAIN=your-domain.com
``` ```
3. **Start the application** 3. **Start the application**
@@ -137,8 +163,9 @@ A modern, self-hosted BigBlueButton frontend with beautiful themes and powerful
### Tech Stack ### Tech Stack
- **Frontend**: React 18, Tailwind CSS, React Router, Lucide Icons - **Frontend**: React 18, Tailwind CSS, React Router, Lucide Icons
- **Backend**: Node.js, Express, JWT, Bcrypt - **Backend**: Node.js 20, Express, JWT, Bcrypt
- **Database**: SQLite / PostgreSQL with better-sqlite3 / pg - **Database**: SQLite / PostgreSQL with better-sqlite3 / pg
- **Cache**: DragonflyDB / Redis (ioredis) JWT blacklisting
- **Email**: Nodemailer - **Email**: Nodemailer
- **Build**: Vite - **Build**: Vite
@@ -149,9 +176,9 @@ A modern, self-hosted BigBlueButton frontend with beautiful themes and powerful
``` ```
redlight/ redlight/
├── server/ # Node.js/Express backend ├── server/ # Node.js/Express backend
│ ├── config/ # Database & mailer config │ ├── config/ # Database, Redis, mailer, BBB & federation config
│ ├── middleware/ # JWT authentication │ ├── middleware/ # JWT authentication & token blacklisting
│ ├── routes/ # API endpoints │ ├── routes/ # API endpoints (auth, rooms, recordings, admin, branding, federation)
│ └── index.js # Server entry point │ └── index.js # Server entry point
├── src/ # React frontend ├── src/ # React frontend
│ ├── components/ # Reusable components │ ├── components/ # Reusable components
@@ -159,12 +186,12 @@ redlight/
│ ├── i18n/ # Translations (DE, EN) │ ├── i18n/ # Translations (DE, EN)
│ ├── pages/ # Page components │ ├── pages/ # Page components
│ ├── services/ # API client │ ├── services/ # API client
│ ├── themes/ # Tailwind theme config │ ├── themes/ # Tailwind theme config (volume-mountable)
│ └── main.jsx # Frontend entry point │ └── main.jsx # Frontend entry point
├── public/ # Static assets ├── public/ # Static assets
├── uploads/ # User avatars (runtime) ├── uploads/ # User avatars, branding & presentations (runtime)
├── compose.yml # Docker Compose configuration ├── compose.yml # Docker Compose (Redlight + PostgreSQL + DragonflyDB)
├── Dockerfile # Container image definition ├── Dockerfile # Multi-stage container image
└── package.json # Dependencies └── package.json # Dependencies
``` ```
@@ -172,12 +199,18 @@ redlight/
## 🔐 Security ## 🔐 Security
- **JWT Authentication** Secure token-based auth with 7-day expiration - **JWT Authentication** Secure token-based auth with 7-day expiration and `jti`-based blacklisting via DragonflyDB/Redis
- **HTTPS Ready** Configure behind reverse proxy (nginx, Caddy) - **Mandatory JWT Secret** Server refuses to start without a `JWT_SECRET` env var
- **Password Hashing** bcryptjs with salt rounds 12 - **HTTPS Ready** Configure behind reverse proxy (nginx, Caddy); trust proxy via `TRUST_PROXY` env
- **Email Verification** Optional SMTP-based email verification - **Password Hashing** bcryptjs with salt rounds 12, minimum 8-character passwords
- **CORS Protection** Configurable CORS settings - **Email Verification** Optional SMTP-based email verification with resend support
- **Admin Isolation** Role-based access control - **CORS Protection** Restricted to `APP_URL` in production, open in development
- **Rate Limiting** Login, register, profile, password, avatar, guest-join, and federation endpoints
- **Input Validation** Email regex, field length limits, theme/language allowlists, hex-color format checks
- **Timing-Safe Comparisons** Access codes and moderator codes compared via `crypto.timingSafeEqual`
- **Upload Safety** Streaming body size limits (avatar 5 MB, presentation 50 MB) abort early without buffering
- **XSS / Injection Prevention** HTML-escaped emails, XML-escaped BBB API parameters, SVG logos served as `attachment`
- **Admin Isolation** Role-based access control with strict admin checks
--- ---
@@ -186,20 +219,31 @@ redlight/
### Authentication ### Authentication
- `POST /api/auth/register` Register new user - `POST /api/auth/register` Register new user
- `POST /api/auth/login` Login user - `POST /api/auth/login` Login user
- `POST /api/auth/logout` Logout (blacklists JWT)
- `GET /api/auth/verify-email?token=...` Verify email with token - `GET /api/auth/verify-email?token=...` Verify email with token
- `POST /api/auth/resend-verification` Resend verification email - `POST /api/auth/resend-verification` Resend verification email
- `GET /api/auth/me` Get current user info - `GET /api/auth/me` Get current user info
- `PUT /api/auth/profile` Update profile - `PUT /api/auth/profile` Update profile (theme, language, display name)
- `PUT /api/auth/password` Change password - `PUT /api/auth/password` Change password
- `POST /api/auth/avatar` Upload avatar image - `POST /api/auth/avatar` Upload avatar image
- `DELETE /api/auth/avatar` Remove avatar image
### Rooms ### Rooms
- `GET /api/rooms` List user's rooms - `GET /api/rooms` List user's rooms (owned + shared)
- `POST /api/rooms` Create new room - `POST /api/rooms` Create new room
- `GET /api/rooms/:uid` Get room details - `GET /api/rooms/:uid` Get room details
- `PUT /api/rooms/:uid` Update room - `PUT /api/rooms/:uid` Update room
- `DELETE /api/rooms/:uid` Delete room - `DELETE /api/rooms/:uid` Delete room
- `POST /api/rooms/:uid/start` Start meeting - `POST /api/rooms/:uid/start` Start meeting
- `POST /api/rooms/:uid/join` Join meeting as authenticated user
- `POST /api/rooms/:uid/guest-join` Join meeting as guest (rate-limited)
- `POST /api/rooms/:uid/end` End meeting
- `GET /api/rooms/:uid/running` Check if meeting is running
- `GET /api/rooms/:uid/shares` List shared users
- `POST /api/rooms/:uid/shares` Share room with user
- `DELETE /api/rooms/:uid/shares/:userId` Remove share
- `POST /api/rooms/:uid/presentation` Upload default presentation (PDF, PPTX, ODP, images)
- `DELETE /api/rooms/:uid/presentation` Remove presentation
### Recordings ### Recordings
- `GET /api/recordings/:roomUid` List room recordings - `GET /api/recordings/:roomUid` List room recordings
@@ -209,12 +253,23 @@ redlight/
### Admin ### Admin
- `GET /api/admin/users` List all users - `GET /api/admin/users` List all users
- `GET /api/admin/stats` System statistics - `GET /api/admin/stats` System statistics
- `POST /api/admin/users` Create user (admin)
- `PUT /api/admin/users/:id` Update user - `PUT /api/admin/users/:id` Update user
- `DELETE /api/admin/users/:id` Delete user - `DELETE /api/admin/users/:id` Delete user
### Branding ### Branding
- `GET /api/branding` Get branding settings - `GET /api/branding` Get branding settings
- `PUT /api/branding` Update branding (admin only) - `PUT /api/branding` Update branding (admin only)
- `POST /api/branding/logo` Upload custom logo
- `DELETE /api/branding/logo` Remove custom logo
### Federation
- `GET /.well-known/redlight` Instance discovery (domain, public key)
- `POST /api/federation/invite` Send invitation to remote user
- `POST /api/federation/receive` Receive invitation from remote instance (rate-limited)
- `GET /api/federation/invitations` List received invitations
- `PUT /api/federation/invitations/:id` Accept / decline invitation
- `DELETE /api/federation/invitations/:id` Delete invitation
--- ---
@@ -260,6 +315,24 @@ docker-compose up -d
Services: Services:
- **redlight** Node.js application - **redlight** Node.js application
- **postgres** PostgreSQL database - **postgres** PostgreSQL database
- **dragonfly** DragonflyDB (Redis-compatible) for JWT blacklisting
### Environment Variables
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `BBB_URL` | Yes | | BigBlueButton API URL |
| `BBB_SECRET` | Yes | | BigBlueButton shared secret |
| `JWT_SECRET` | Yes | | Secret for signing JWTs (server won't start without it) |
| `APP_URL` | Recommended | | Public URL of the app (used for CORS + email links) |
| `DATABASE_URL` | No | SQLite | PostgreSQL connection string |
| `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 |
| `FEDERATION_DOMAIN` | No | | Domain for federation (enables cross-instance invites) |
### Production Deployment ### Production Deployment
@@ -292,10 +365,38 @@ server {
} }
``` ```
> **Note:** When running behind a reverse proxy, set `TRUST_PROXY=1` (or the appropriate value) in `.env` so Express reads the correct client IP for rate limiting.
---
## 🌐 Federation
Federation allows users on different Redlight instances to invite each other into rooms.
### Setup
1. Set `FEDERATION_DOMAIN=your-domain.com` in `.env`.
2. On first start, an RSA 2048-bit key pair is generated automatically and stored in `server/config/federation_key.pem`.
3. Other instances discover your public key via `GET /.well-known/redlight`.
### How it works
1. **User A** on `instance-a.com` sends an invite to `userB@instance-b.com`.
2. Redlight looks up `instance-b.com/.well-known/redlight` to discover the federation API.
3. The invite payload is signed with instance A's private key and POSTed to instance B's `/api/federation/receive`.
4. Instance B verifies the RSA signature against instance A's public key.
5. **User B** sees the invitation and can accept or decline. Accepting provides a join link to the remote room.
--- ---
## 🐛 Troubleshooting ## 🐛 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" ### Issue: "Email verification not working"
**Solution**: Ensure SMTP is configured in `.env`. If `SMTP_HOST` is not set, email verification is disabled. **Solution**: Ensure SMTP is configured in `.env`. If `SMTP_HOST` is not set, email verification is disabled.
@@ -311,6 +412,9 @@ curl "https://your-bbb-server/bigbluebutton/api/getMeetings?checksum=..."
### Issue: "Theme not applying" ### Issue: "Theme not applying"
**Solution**: Clear browser cache (Ctrl+Shift+Del) or restart dev server with `npm run dev`. **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 ## 📝 License