diff --git a/README.md b/README.md index 1c9e065..88f780e 100644 --- a/README.md +++ b/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. ![Node.js](https://img.shields.io/badge/Node.js-20+-green) ![React](https://img.shields.io/badge/React-18+-blue) @@ -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). --- diff --git a/compose.yml b/compose.yml index 29f54c5..2d809aa 100644 --- a/compose.yml +++ b/compose.yml @@ -6,7 +6,7 @@ services: - "3001:3001" env_file: ".env" volumes: - - uploads:/app/uploads + - ./uploads:/app/uploads - ./keys:/app/keys depends_on: postgres: @@ -48,7 +48,6 @@ services: volumes: pgdata: - uploads: dragonflydata: networks: