- TypeScript 57.2%
- Handlebars 25.1%
- CSS 7.3%
- PLpgSQL 5%
- Shell 4.2%
- Other 1.2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
Currently translated at 6.9% (136 of 1944 strings) Co-authored-by: jandi <alcornoqui@disroot.org> Translate-URL: https://weblate.holos.social/projects/holos-relay/holos-relay/es/ Translation: Holos Relay/Holos Relay |
||
| docs | ||
| scripts | ||
| src | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| Caddyfile | ||
| docker-compose.yml | ||
| Dockerfile | ||
| ecosystem.config.cjs | ||
| LICENSE | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
| tunnel-relay.js | ||
| vitest.config.ts | ||
Holos Relay Server
Identity relay server for mobile Fediverse instances
What is this?
This server acts as a stable identity provider for mobile ActivityPub instances that run directly on smartphones.
The Problem
Mobile apps running their own ActivityPub server face a challenge: their public URL changes constantly because:
- Tunnel URLs change every session (e.g.,
https://random-abc.tunnel-service.com→https://random-xyz.tunnel-service.com) - Mobile IP addresses change (WiFi → 4G → WiFi)
- Users can't have a stable ActivityPub identity like
@alice@mobile-url.com
The Solution
This relay server provides:
- Stable identities:
@alice@yourdomain.comstays the same forever - Automatic proxying: All ActivityPub requests are forwarded to the current mobile tunnel URL
- Heartbeat system: Tracks which mobile instances are online/offline
- Simple registration: Users register via web or mobile app, then use OAuth 2.0 for Mastodon instance authentication
How It Works
graph TB
mastodon["Mastodon Server<br/>wants to reach @alice@yourdomain.com"]
relay["Holos Relay Server (this project)<br/>hosted on yourdomain.com<br/>looks up the current tunnel URL<br/>proxies to the user's mobile tunnel"]
phone["Mobile Phone (user device)<br/>local ActivityPub server<br/>tunnel random-id.tunnel-svc.com<br/>heartbeat every 30s"]
mastodon -->|ActivityPub request| relay
relay -->|HTTP proxy| phone
Use Cases
- Mobile Fediverse apps that want to run their own instance
- Privacy-focused users who want full control of their data
- Intermittent presence - only online when you want to be
- Self-hosted on phone - complete control over your instance without relying on third-party servers
Features
Core Features
- Stable identities for mobile instances with changing tunnel URLs
- ActivityPub proxy to mobile instances
- WebFinger support for actor discovery
- Heartbeat system to track online/offline status
- Automatic cleanup of inactive instances
Data & Caching
- PostgreSQL persistence with user management
- Redis caching for fast lookups and distributed rate limiting
- Email verification to prevent bots
- Prometheus metrics with real-time and historical data
Security & Moderation
- Admin panel for user moderation (ban/unban, temporary bans)
- Secure authentication with bcrypt password hashing
- OAuth 2.0 authentication system with JWT tokens
- Rate limiting per IP, per user, and globally (configurable)
- Outbound rate limiting per-domain request queues to prevent 429 errors from Fediverse servers
- Two-Factor Authentication (2FA) with TOTP and backup codes
- API Keys for automation with scopes and per-key rate limits
- Security logging with login attempts, admin actions, and alerts
- Domain blocklist with import/export (Mastodon-compatible)
Real-Time & Notifications
- WebSocket real-time updates - Instant delivery when online
- Push Notifications - UnifiedPush integration for offline delivery
- Activity queue - Persistent storage with automatic cleanup
- Notification preferences - Per-user control over notification types
- See docs/WEBSOCKET-API.md for details
Admin & Management
- Multi-admin system - Super Admin, Admin, and Moderator roles with permissions
- Team invitations - Secure token-based invitation system for new admins
- Custom emojis - Upload and manage custom emojis for the instance
- NodeInfo protocol - Fediverse discovery and statistics (/.well-known/nodeinfo)
- Server metadata - Configurable name, description, rules, contact email
- Email/SMTP configuration - Test mode and encrypted password storage
- Account migration - ActivityPub Move activity support
- Internationalization (i18n) - English and French translations
Identity & Discovery
- WebFinger support - Provides stable identities for mobile instances (@user@relay-domain.com)
- Transparent proxy - Routes ActivityPub requests to mobile tunnel URLs
- Profile caching - User profiles always visible; posts cached with configurable TTL
- Note: Account search and timeline construction are handled by the mobile app
Quick Start
Choose your preferred setup method:
1. Automated Installation (Recommended)
Production-ready installation with one command. Includes automatic nginx configuration and SSL setup.
# Interactive mode
sudo ./scripts/install.sh
# Or automated mode
sudo ./scripts/install.sh --docker \
--domain yourdomain.com \
--tunnel-domain tunnel.yourdomain.com
→ Complete guide: docs/INSTALL.md
2. Docker (Advanced)
For custom Docker setups or existing infrastructure. Uses nginx on host by default.
cp .env.example .env.docker
# Configure: DB_PASSWORD, REDIS_PASSWORD, JWT_SECRET, ENCRYPTION_KEY, ADMIN_PASSWORD, DOMAIN
docker compose up -d
# Optional: Use Caddy for automatic SSL (dedicated server only)
docker compose --profile caddy up -d
→ Complete guide: docs/DOCKER.md
3. Development Setup
Quick local setup for development:
./scripts/dev-setup.sh # Checks dependencies, creates DB, installs packages
npm run dev
4. Manual Installation
Full control over installation and configuration.
→ Complete guide: docs/DEPLOYMENT.md (Manual Deployment section)
For production deployment and detailed configuration, see:
- docs/INSTALL.md - Automated installation script (recommended)
- docs/DOCKER.md - Docker deployment guide
- docs/DEPLOYMENT.md - Manual production deployment guide
- docs/DATABASE-SETUP.md - Database configuration
Documentation
Core Documentation
- README.md - This file (overview & quick start)
- docs/INSTALL.md - Automated production installation (recommended)
- docs/ARCHITECTURE.md - System architecture and components
- docs/DEPLOYMENT.md - Manual production deployment guide (nginx, SSL, PM2, backups)
- docs/DOCKER.md - Docker deployment with nginx (Caddy optional)
- docs/DATABASE-SETUP.md - Database setup, schema, and admin API
- docs/TUNNEL-SERVER.md - Tunnel server setup (required for mobile app connectivity)
API Documentation
- docs/mobile-api/README.md - Mobile API overview and OAuth authentication
- docs/mobile-api/OAUTH.md - OAuth 2.0 authentication flow (primary method)
- docs/mobile-api/TUNNEL.md - Tunnel management (OAuth-authenticated)
- docs/mobile-api/PROFILE.md - Profile caching for ActivityPub
- docs/mobile-api/IMAGES.md - Avatar and header image upload
- docs/mobile-api/PUSH.md - Push notifications, activity sync, retention settings
- docs/WEBSOCKET-API.md - WebSocket real-time events API
- docs/USER-API.md - User account management API
- docs/API-KEYS.md - API keys for automation and scripts
Admin Documentation
- docs/ADMIN-ROLES.md - Admin roles, permissions, and team management
Development
Project Structure
src/
├── config.ts # Environment configuration
├── index.ts # Application entry point
├── server.ts # Express app setup
├── tunnel-server.ts # Tunnel server for mobile app connectivity
│
├── database/ # Database layer
│ ├── db.ts # PostgreSQL connection & pool
│ ├── schema.sql # Complete database schema
│ └── run-migration.ts # Migration runner
│
├── middleware/ # Express middleware (10+ files)
│ ├── auth.ts # Authentication middleware
│ ├── rateLimit.ts # Rate limiting
│ ├── jwtAuth.ts # JWT validation
│ └── ... # CSRF, permissions, metrics, etc.
│
├── routes/ # API endpoints (23 files)
│ ├── activitypub.ts # ActivityPub proxy
│ ├── admin/ # Admin dashboard routes
│ ├── auth.ts # User authentication
│ ├── oauth.ts # OAuth 2.0 flow
│ ├── mobile.ts # Mobile client API
│ ├── tunnel.ts # Tunnel management
│ └── ... # 2FA, API keys, reports, etc.
│
├── services/ # Business logic (28 files)
│ ├── UserRegistryDB.ts # User & session management
│ ├── ProxyService.ts # ActivityPub request proxying
│ ├── OAuthService.ts # OAuth token management
│ ├── EmailService.ts # Email notifications
│ ├── MetricsService.ts # Prometheus metrics
│ ├── OutboundRateLimiter.ts # Per-domain outbound rate limiting
│ └── ... # Image storage, caching, 2FA, etc.
│
├── utils/ # Helper utilities
│ ├── crypto.ts # Password hashing & tokens
│ ├── validators.ts # Input validation
│ ├── i18n.ts # Internationalization
│ └── ... # Template engine, API errors, etc.
│
├── types/ # TypeScript type definitions
├── views/ # Handlebars templates (admin UI, auth pages)
└── public/ # Static assets (CSS, images, JS)
Scripts
npm run dev- Development with hot reloadnpm run build- Build TypeScriptnpm start- Start production servernpm run lint- Lint codenpm run format- Format code
License
AGPL-3.0