This commit is contained in:
153
README.md
153
README.md
@@ -1,6 +1,6 @@
|
||||
# 🔴 Redlight
|
||||
|
||||
A modern, self-hosted BigBlueButton frontend with beautiful themes, federation, and powerful features.
|
||||
A modern, self-hosted BigBlueButton frontend with 25+ themes, federation, calendar, CalDAV, OAuth/OIDC, and powerful room management.
|
||||
|
||||

|
||||

|
||||
@@ -11,13 +11,18 @@ A modern, self-hosted BigBlueButton frontend with beautiful themes, federation,
|
||||
|
||||
### Core Features
|
||||
- 🎥 **Video Conferencing** - Integrated BigBlueButton support for professional video meetings
|
||||
- 🎨 **15+ Themes** - Dracula, Nord, Catppuccin, Rosé Pine, Gruvbox, and more
|
||||
- 🎨 **25+ 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** - Real-time notifications for room shares, federation invites, and calendar reminders
|
||||
- ✉️ **Email Verification** - Optional SMTP-based email verification for user registration
|
||||
- 👤 **User Profiles** - Customizable avatars, themes, and language preferences
|
||||
- 🔑 **OAuth / OIDC** - Login via OpenID Connect providers (Keycloak, Authentik, etc.) with PKCE
|
||||
- 👤 **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
|
||||
@@ -27,6 +32,7 @@ A modern, self-hosted BigBlueButton frontend with beautiful themes, federation,
|
||||
- 🏢 **Branding Customization** - Custom app name, logos, and default theme
|
||||
- 📊 **Dashboard** - Overview of system statistics
|
||||
- 🔧 **Settings Management** - System-wide configuration
|
||||
- ✉️ **Invite-Only Registration** - Generate invite tokens for controlled user signup
|
||||
|
||||
### Room Features
|
||||
- 🔑 **Access Codes** - Restrict room access with optional passwords
|
||||
@@ -37,11 +43,12 @@ A modern, self-hosted BigBlueButton frontend with beautiful themes, federation,
|
||||
- ✅ **Approval Mode** - Require moderator approval for participants
|
||||
- 🎙️ **Anyone Can Start** - Allow participants to start the meeting
|
||||
- 📹 **Recording Settings** - Control whether meetings are recorded
|
||||
- 📊 **Presentation Upload** - Upload PDF, PPTX, ODP, or image files as default slides
|
||||
- 📊 **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, and federation endpoints
|
||||
- 🛡️ **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 (5 MB) and presentation (50 MB) uploads reject early without buffering
|
||||
@@ -49,6 +56,7 @@ A modern, self-hosted BigBlueButton frontend with beautiful themes, federation,
|
||||
- 🔐 **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
|
||||
- 🔏 **HMAC-Secured Callbacks** - Learning analytics callback URLs signed with HMAC-SHA256
|
||||
|
||||
### Developer Features
|
||||
- 🐳 **Docker Support** - Easy deployment with Docker Compose (includes PostgreSQL + DragonflyDB)
|
||||
@@ -63,20 +71,24 @@ A modern, self-hosted BigBlueButton frontend with beautiful themes, federation,
|
||||
|
||||
| Feature | Redlight | Greenlight |
|
||||
|---------|----------|-----------|
|
||||
| **Theme System** | 15+ customizable themes | Limited theming |
|
||||
| **Theme System** | 25+ customizable themes | Limited theming |
|
||||
| **Learning Analytics** | ✅ Per-room engagement data | ❌ Not supported |
|
||||
| **Calendar / CalDAV** | ✅ Built-in calendar + CalDAV sync | ❌ Not supported |
|
||||
| **OAuth / OIDC** | ✅ OpenID Connect (PKCE) | ✅ Supported |
|
||||
| **Federation** | ✅ Cross-instance invites | ❌ Not supported |
|
||||
| **Notifications** | ✅ In-app + calendar reminders | ❌ Not supported |
|
||||
| **Language Support** | Multi-language ready | Multi-language ready |
|
||||
| **UI Framework** | React + Tailwind (Modern) | Rails-based (Traditional) |
|
||||
| **User Preferences** | Theme, language, avatar | Limited customization |
|
||||
| **User Preferences** | Theme, language, avatar, display name | Limited customization |
|
||||
| **Database Options** | SQLite / PostgreSQL | PostgreSQL only |
|
||||
| **Docker** | ✅ Supported | ✅ Supported |
|
||||
| **Admin Dashboard** | Modern React UI | Legacy Rails interface |
|
||||
| **Room Sharing** | ✅ Share rooms with users | ✅ Supported |
|
||||
| **Recording Management** | Full control per room | Standard management |
|
||||
| **Presentation Upload** | ✅ Supported | ✅ Supported |
|
||||
| **API** | RESTful JSON API | RESTful API |
|
||||
| **Setup Complexity** | Simple (5 min) | Moderate (10-15 min) |
|
||||
| **Customization** | Easy (Tailwind CSS) | Requires Ruby/Rails |
|
||||
| **Community** | doesn't exist lol | Established |
|
||||
|
||||
---
|
||||
|
||||
@@ -105,7 +117,7 @@ A modern, self-hosted BigBlueButton frontend with beautiful themes, federation,
|
||||
BBB_SECRET=your-bbb-shared-secret
|
||||
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://redlight:redlight@postgres:5432/redlight
|
||||
|
||||
POSTGRES_USER=redlight
|
||||
POSTGRES_PASSWORD=redlight
|
||||
@@ -118,18 +130,23 @@ A modern, self-hosted BigBlueButton frontend with beautiful themes, federation,
|
||||
# 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
|
||||
# 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.com
|
||||
|
||||
# Optional: OAuth / OIDC login
|
||||
# OAUTH_ISSUER=https://auth.your-domain.com/realms/your-realm
|
||||
# OAUTH_CLIENT_ID=redlight
|
||||
# OAUTH_CLIENT_SECRET=your-client-secret
|
||||
```
|
||||
|
||||
3. **Start the application**
|
||||
```bash
|
||||
docker-compose up -d
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
4. **Access the application**
|
||||
@@ -167,6 +184,8 @@ A modern, self-hosted BigBlueButton frontend with beautiful themes, federation,
|
||||
- **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
|
||||
|
||||
---
|
||||
@@ -176,20 +195,24 @@ A modern, self-hosted BigBlueButton frontend with beautiful themes, federation,
|
||||
```
|
||||
redlight/
|
||||
├── server/ # Node.js/Express backend
|
||||
│ ├── config/ # Database, Redis, mailer, BBB & federation config
|
||||
│ ├── middleware/ # JWT authentication & token blacklisting
|
||||
│ ├── routes/ # API endpoints (auth, rooms, recordings, admin, branding, federation)
|
||||
│ ├── 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
|
||||
│ ├── contexts/ # React context (Auth, Language, Theme, Branding)
|
||||
│ ├── 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/ # Tailwind theme config
|
||||
│ ├── themes/ # 25+ 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
|
||||
@@ -201,16 +224,19 @@ redlight/
|
||||
|
||||
- **JWT Authentication** - Secure token-based auth with 7-day expiration and `jti`-based blacklisting via DragonflyDB/Redis
|
||||
- **Mandatory JWT Secret** - Server refuses to start without a `JWT_SECRET` env var
|
||||
- **OAuth / OIDC** - OpenID Connect with PKCE (S256) and cryptographic state tokens
|
||||
- **HTTPS Ready** - Configure behind reverse proxy (nginx, Caddy); trust proxy via `TRUST_PROXY` env
|
||||
- **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_URL` in production, open in development
|
||||
- **Rate Limiting** - Login, register, profile, password, avatar, guest-join, and federation endpoints
|
||||
- **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 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`
|
||||
- **HMAC-Secured Callbacks** - Learning analytics callback URLs signed with HMAC-SHA256 derived from BBB_SECRET
|
||||
- **Admin Isolation** - Role-based access control with strict admin checks
|
||||
- **Network Isolation** - Docker Compose uses an internal backend network for DB and cache
|
||||
|
||||
---
|
||||
|
||||
@@ -232,23 +258,43 @@ redlight/
|
||||
- `GET /api/rooms` - List user's rooms (owned + shared)
|
||||
- `POST /api/rooms` - Create new room
|
||||
- `GET /api/rooms/:uid` - Get room details
|
||||
- `PUT /api/rooms/:uid` - Update room
|
||||
- `PUT /api/rooms/:uid` - Update room (incl. learning analytics toggle)
|
||||
- `DELETE /api/rooms/:uid` - Delete room
|
||||
- `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/status` - 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)
|
||||
- `POST /api/rooms/:uid/presentation` - Upload default presentation
|
||||
- `DELETE /api/rooms/:uid/presentation` - Remove presentation
|
||||
|
||||
### Recordings
|
||||
- `GET /api/recordings/:roomUid` - List room recordings
|
||||
- `PUT /api/recordings/:recordingId` - Publish/unpublish recording
|
||||
- `DELETE /api/recordings/:recordingId` - Delete recording
|
||||
- `GET /api/recordings/room/:uid` - List room recordings
|
||||
- `PUT /api/recordings/:recordID/publish` - Publish/unpublish recording
|
||||
- `DELETE /api/recordings/:recordID` - Delete recording
|
||||
|
||||
### Learning Analytics
|
||||
- `POST /api/analytics/callback/:uid?token=...` - BBB callback (HMAC-secured)
|
||||
- `GET /api/analytics/room/:uid` - Get analytics for a room
|
||||
- `DELETE /api/analytics/:id` - Delete analytics entry
|
||||
|
||||
### Calendar
|
||||
- `GET /api/calendar` - List calendar events
|
||||
- `POST /api/calendar` - Create event
|
||||
- `PUT /api/calendar/:uid` - Update event
|
||||
- `DELETE /api/calendar/:uid` - Delete event
|
||||
- `GET /api/calendar/caldav-tokens` - List CalDAV tokens
|
||||
- `POST /api/calendar/caldav-tokens` - Create CalDAV token
|
||||
- `DELETE /api/calendar/caldav-tokens/:id` - Delete CalDAV token
|
||||
|
||||
### Notifications
|
||||
- `GET /api/notifications` - List notifications
|
||||
- `PUT /api/notifications/:id/read` - Mark as read
|
||||
- `POST /api/notifications/read-all` - Mark all as read
|
||||
- `DELETE /api/notifications/:id` - Delete notification
|
||||
|
||||
### Admin
|
||||
- `GET /api/admin/users` - List all users
|
||||
@@ -263,6 +309,10 @@ redlight/
|
||||
- `POST /api/branding/logo` - Upload custom logo
|
||||
- `DELETE /api/branding/logo` - Remove custom logo
|
||||
|
||||
### OAuth
|
||||
- `GET /api/oauth/url` - Get OAuth authorization URL
|
||||
- `GET /api/oauth/callback` - OAuth callback (PKCE exchange)
|
||||
|
||||
### Federation
|
||||
- `GET /.well-known/redlight` - Instance discovery (domain, public key)
|
||||
- `POST /api/federation/invite` - Send invitation to remote user
|
||||
@@ -271,6 +321,11 @@ redlight/
|
||||
- `PUT /api/federation/invitations/:id` - Accept / decline invitation
|
||||
- `DELETE /api/federation/invitations/:id` - Delete invitation
|
||||
|
||||
### CalDAV
|
||||
- `PROPFIND /caldav/` - CalDAV discovery
|
||||
- `REPORT /caldav/:user/calendar/` - Calendar query
|
||||
- `GET/PUT/DELETE /caldav/:user/calendar/:uid.ics` - Event CRUD
|
||||
|
||||
---
|
||||
|
||||
## 🌍 Internationalization (i18n)
|
||||
@@ -290,15 +345,25 @@ Redlight comes with built-in support for multiple languages. Currently supported
|
||||
|
||||
## 🎨 Themes
|
||||
|
||||
Redlight includes the following themes:
|
||||
- 🌙 Dracula
|
||||
Redlight includes 25+ themes:
|
||||
- ☀️ Light / 🌙 Dark (default)
|
||||
- 🐱 Catppuccin Mocha / Latte
|
||||
- 🧛 Dracula
|
||||
- ❄️ Nord
|
||||
- 🐱 Catppuccin
|
||||
- 🌹 Rosé Pine
|
||||
- 🍂 Gruvbox (Dark, Light)
|
||||
- 💜 One Dark
|
||||
- 🌊 Tokyo Night
|
||||
- And more...
|
||||
- 💜 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`.
|
||||
|
||||
@@ -309,14 +374,16 @@ Themes are fully customizable by editing `src/themes/index.js`.
|
||||
### Using Docker Compose (Recommended)
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Services:
|
||||
- **redlight** - Node.js application
|
||||
- **postgres** - PostgreSQL database
|
||||
- **redlight** - Node.js application (port 3001)
|
||||
- **postgres** - PostgreSQL 17 database
|
||||
- **dragonfly** - DragonflyDB (Redis-compatible) for JWT blacklisting
|
||||
|
||||
The `compose.yml` uses isolated networks: `frontend` (public) and `backend` (internal, no external access). Data is persisted via named volumes (`pgdata`, `uploads`, `dragonflydata`). Federation keys are mounted from `./keys`.
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Required | Default | Description |
|
||||
@@ -333,6 +400,11 @@ Services:
|
||||
| `SMTP_USER` | No | - | SMTP username |
|
||||
| `SMTP_PASS` | No | - | SMTP password |
|
||||
| `FEDERATION_DOMAIN` | No | - | Domain for federation (enables cross-instance invites) |
|
||||
| `OAUTH_ISSUER` | No | - | OIDC issuer URL (enables OAuth login) |
|
||||
| `OAUTH_CLIENT_ID` | No | - | OIDC client ID |
|
||||
| `OAUTH_CLIENT_SECRET` | No | - | OIDC client secret |
|
||||
| `ADMIN_EMAIL` | No | `admin@example.com` | Default admin email (first start only) |
|
||||
| `ADMIN_PASSWORD` | No | `admin123` | Default admin password (first start only) |
|
||||
|
||||
### Production Deployment
|
||||
|
||||
@@ -376,8 +448,9 @@ Federation allows users on different Redlight instances to invite each other int
|
||||
### Setup
|
||||
|
||||
1. Set `FEDERATION_DOMAIN=your-domain.com` in `.env`.
|
||||
2. On first start, an Ed25519 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`.
|
||||
2. On first start, an Ed25519 key pair is generated automatically and stored in `keys/federation_key.pem`.
|
||||
3. In Docker, mount `./keys:/app/keys` (already configured in `compose.yml`).
|
||||
4. Other instances discover your public key via `GET /.well-known/redlight`.
|
||||
|
||||
### How it works
|
||||
|
||||
@@ -413,7 +486,7 @@ curl "https://your-bbb-server/bigbluebutton/api/getMeetings?checksum=..."
|
||||
**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).
|
||||
**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).
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user