root 476afaf329
Some checks failed
CI / Rust Format (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Test Server (push) Has been cancelled
CI / Frontend Check (push) Has been cancelled
CI / Tauri Client Check (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Build Tauri (Linux) (push) Has been cancelled
feat: Tauri v2 release workflow and frontend API migration
- Update release workflow with matrix strategy for Linux/macOS/Windows
- Upgrade @tauri-apps/api from v1 to v2 in frontend
- Change all tauri/tauri imports to tauri/core (Tauri v2)
- Sync tauri.conf.json across project root and src-tauri
2026-04-29 13:49:25 +02:00

EifelDC

Discord-like Matrix chat platform built with Rust, Svelte, and Tauri.

Architecture

Component Crate Description
Server eifeldc-server Axum web server, Matrix SDK, LiveKit voice, SQLite sessions
Bot SDK eifeldc-bot-sdk SDK for building Matrix bots
Client eifeldc-client Tauri desktop app
Frontend Svelte + TypeScript UI

Prerequisites

  • Rust 1.82+ (stable)
  • Node.js 20+
  • A running Matrix Synapse homeserver
  • LiveKit server (for voice)

Quick Start

Build Server & Bot SDK

cargo build --release -p eifeldc-server -p eifeldc-bot-sdk

Build Frontend

cd client/src-ui
npm ci
npm run build

Build Tauri Desktop App

Requires system dependencies:

# Ubuntu/Debian
sudo apt-get install -y libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev libssl-dev
cargo build --release -p eifeldc-client

Run the Server

cargo run -p eifeldc-server

The server starts on http://0.0.0.0:3000 and serves the frontend from client/src-ui/dist.

Environment Variables

Variable Default Description
EIFELDC_DB eifeldc.db SQLite database path for session storage
EIFELDC_STATIC_DIR client/src-ui/dist Path to frontend static files
LIVEKIT_API_KEY devkey LiveKit API key
LIVEKIT_API_SECRET devsecret LiveKit API secret
LIVEKIT_URL ws://localhost:7880 LiveKit server URL
RUST_LOG Logging filter (e.g. eifeldc_server=info)
EIFELDC_LOG_FORMAT pretty Log format: pretty or json
EIFELDC_CORS_ORIGINS * Comma-separated allowed origins (e.g. https://app.example.org,https://dev.example.org)
EIFELDC_SESSION_TTL Session TTL in seconds (no expiry if unset)
EIFELDC_RATE_LIMIT 60 Max requests per minute per client
EIFELDC_MAX_UPLOAD_MB 50 Max upload size in MB

Docker Deployment

# Configure environment
cp infra/.env.example infra/.env
# Edit infra/.env with your domain and secrets

# Setup infrastructure (generates secrets, configs, certs)
bash infra/scripts/setup.sh your.domain.com

# Or manually:
cd infra
docker compose up -d

Services: EifelDC server, Synapse, PostgreSQL, LiveKit, coturn, nginx.

Useful Commands

make docker-build    # Build Docker image
make docker-up        # Start containers
make docker-down      # Stop containers
make docker-logs      # Follow EifelDC logs
make health           # Run healthcheck
make backup           # Backup data

API Reference

All endpoints are under /api. Public endpoints require no auth. Protected endpoints require a Bearer token in the Authorization header.

Authentication

Method Endpoint Auth Description
POST /api/login No Login with Matrix credentials
POST /api/register No Register a new Matrix user
GET /api/current-user No Get current user ID from token
POST /api/logout Yes Logout and invalidate session

Login Request:

{ "homeserver": "https://matrix.example.org", "username": "alice", "password": "secret" }

Login Response:

{ "success": true, "user_id": "@alice:example.org", "token": "uuid-token", "error": null }

Rooms

Method Endpoint Description
GET /api/rooms List joined rooms
POST /api/rooms/create Create a new room
POST /api/rooms/join Join a room by ID or alias
POST /api/rooms/{room_id}/leave Leave a room
GET /api/rooms/{room_id}/members List room members
POST /api/rooms/{room_id}/name Set room name
POST /api/rooms/{room_id}/topic Set room topic
POST /api/rooms/{room_id}/avatar Set room avatar (multipart)
GET /api/rooms/unread Get unread notification counts
POST /api/rooms/{room_id}/read Mark room as read

Messages

Method Endpoint Description
GET /api/rooms/{room_id}/messages Get room messages
POST /api/rooms/{room_id}/send Send a message
POST /api/rooms/{room_id}/edit Edit a message
POST /api/rooms/{room_id}/delete/{event_id} Delete a message
POST /api/rooms/{room_id}/react React to a message
POST /api/rooms/{room_id}/typing Set typing notification
POST /api/rooms/{room_id}/upload Upload a file (multipart)

Threads

Method Endpoint Description
GET /api/rooms/{room_id}/threads List threads in a room
GET /api/rooms/{room_id}/threads/{thread_id} Get thread messages
POST /api/rooms/{room_id}/threads/{thread_id}/reply Reply in a thread
POST /api/rooms/{room_id}/reply Reply to a message

Voice (LiveKit)

Method Endpoint Description
POST /api/voice/join Join a voice channel
POST /api/voice/leave Leave voice channel
POST /api/voice/toggle-mute Toggle mute
POST /api/voice/toggle-deafen Toggle deafen
GET /api/voice/participants Get voice participants

Presence

Method Endpoint Description
POST /api/presence/set Set presence status
GET /api/presence/{user_id} Get user presence

Profile

Method Endpoint Description
GET /api/profile/me Get own profile
GET /api/profile/{user_id} Get user profile
POST /api/profile/displayname Set display name
POST /api/profile/avatar Upload avatar (multipart)

Emoji & Roles

Method Endpoint Description
GET /api/rooms/{room_id}/emoji Get custom emoji
POST /api/rooms/{room_id}/emoji/upload Upload custom emoji
GET /api/rooms/{room_id}/roles Get room roles
POST /api/rooms/{room_id}/roles/assign Assign role to user
POST /api/rooms/{room_id}/roles/remove Remove role from user
GET /api/rooms/{room_id}/permissions/{user_id} Get user permissions

Media & WebSocket

Method Endpoint Description
GET /api/media/{mxc_path} Proxy Matrix media
GET /api/metrics Prometheus metrics endpoint
GET /api/ws?token={token} WebSocket for real-time events

WebSocket Events

Monitoring

Prometheus Metrics are exposed at /api/metrics:

Metric Type Description
eifeldc_http_requests_total Counter Total HTTP requests
eifeldc_active_sessions Gauge Active user sessions
eifeldc_active_websockets Gauge Active WebSocket connections
eifeldc_messages_sent_total Counter Total messages sent
eifeldc_rooms_joined_total Counter Total room join operations
eifeldc_uploads_total Counter Total file uploads
eifeldc_voice_participants Gauge Current voice participants

Structured Logging — set EIFELDC_LOG_FORMAT=json for JSON output:

{"timestamp":"2026-04-29T10:00:00Z","level":"INFO","target":"eifeldc_server::routes::auth","fields":{"message":"LiveKit URL: ws://localhost:7880"}}

Use RUST_LOG for filtering: RUST_LOG=eifeldc_server=debug,tower_http=info

WebSocket Events

{ "type": "message", "room_id": "...", "event_id": "...", "sender": "...", "body": "...", "timestamp": 0 }
{ "type": "message_edited", "room_id": "...", "event_id": "...", "new_body": "..." }
{ "type": "message_deleted", "room_id": "...", "redacts": "..." }
{ "type": "reaction", "room_id": "...", "event_id": "...", "key": "👍", "sender": "..." }
{ "type": "room_joined", "room_id": "...", "name": "..." }
{ "type": "room_left", "room_id": "..." }
{ "type": "presence", "user_id": "...", "status": "online|idle|offline", "status_msg": "..." }
{ "type": "typing", "room_id": "...", "user_id": "...", "typing": true }
{ "type": "voice_state_update", "room_id": "...", "user_id": "...", "muted": false, "deafened": false }
{ "type": "voice_user_joined", "room_id": "...", "user_id": "..." }
{ "type": "voice_user_left", "room_id": "...", "user_id": "..." }
{ "type": "thread_reply", "room_id": "...", "root_event_id": "...", "event_id": "...", "sender": "...", "body": "...", "timestamp": 0 }

Bot SDK

use std::sync::Arc;
use eifeldc_bot_sdk::{BotClient, BotEvent, CommandContext};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let mut bot = BotClient::new("https://matrix.example.org")
        .with_auth("botuser", "botpassword");

    bot.on_event(|event| {
        match event {
            BotEvent::Message { room_id, sender, body, .. } => {
                println!("{} in {}: {}", sender, room_id, body);
            }
            _ => {}
        }
    });

    bot.on_command("hello", Arc::new(|ctx: CommandContext| {
        println!("Hello command from {} in {}!", ctx.sender, ctx.room_id);
    }));

    bot.start().await?;
    Ok(())
}

Development

# Check compilation
cargo check -p eifeldc-server -p eifeldc-bot-sdk

# Run linter
cargo clippy -p eifeldc-server -p eifeldc-bot-sdk -- -D warnings

# Check formatting
cargo fmt --all -- --check

# Run tests
cargo test -p eifeldc-server -p eifeldc-bot-sdk

# Build frontend
cd client/src-ui && npm ci && npm run build

# Run dev server
cargo run -p eifeldc-server

License

All rights reserved.

Description
No description provided
Readme 345 KiB
Languages
Rust 60.7%
Svelte 22.8%
TypeScript 9.9%
Shell 5.1%
Dockerfile 0.7%
Other 0.8%