README_DE.md

August 11, 2026 · View on GitHub

🌐 Andere Sprachen: äž­æ–‡ · English · æ—„æœŹèȘž · 한ꔭ얎 · Français · РуссĐșĐžĐč · Español

Eine WeChat-Ă€hnliche Ende-zu-Ende-verschlĂŒsselte Instant-Messaging-App mit zustandslosem ECDH + XSalsa20-Poly1305 Pro-Nachricht-VerschlĂŒsselung, Echtzeit-Videoanrufen, Cloudflare R2 Dateispeicher, Mehrsprachigkeit und iOS PWA-Bereitstellung.

Rust React TypeScript MySQL Redis WebRTC License: AGPL v3

Deploy on Zeabur

Version

Google Play App Store Windows Mac


📾 Screenshots (zum Erweitern klicken) ui1 ui2 ui3 ui4 ui5 ui6 ui7 ui8 ui9 ui10 ui11 ui12 ui13 ui14 ui15 ui16 ui17 ui18

Funktionen

FunktionBeschreibung
🔐 Ende-zu-Ende-VerschlĂŒsselungZustandsloses ECDH + XSalsa20-Poly1305 — EinmalschlĂŒssel pro Nachricht, Forward Secrecy, Signal-Ă€hnliche Sicherheitsnummernverifizierung
đŸ—ïž Zero-Knowledge-ServerServer speichert nur Chiffretext; private SchlĂŒssel verlassen niemals das GerĂ€t
đŸ“č Video- & AudioanrufeLiveKit-SFU fĂŒr 1:1-Anrufe und Konferenzen (bis zu 100 Teilnehmer), Alle stummschalten und Vortragsmodus
đŸŽ™ïž StimmverzerrerEchtzeit-Stimmeffekte fĂŒr Sprachnachrichten, 1:1-Anrufe und Gruppenanrufe — 3 Modi (0.8x tief / 1.0x normal / 1.2x hoch), basierend auf Web Audio API
đŸ“± Sitzungspersistenz30-minĂŒtige Access Tokens mit automatisch verlĂ€ngerten 90-Tage-GerĂ€te-Refresh-Sitzungen; Netzwerk-, IP-, VPN- und Proxywechsel werden ohne Passworteingabe wiederhergestellt
📹 ZuverlĂ€ssige NachrichtensynchronisierungBidirektionaler Heartbeat, Erkennung halboffener Verbindungen, persistenter Postausgang, idempotente Nachrichten-IDs und Cursor-Nachsynchronisierung ĂŒber Serversequenzen
📮 Offline-ZugriffKontogetrennter Cache fĂŒr Kontakte, Gruppen, bis zu 2.000 Nachrichten je Unterhaltung, Momente, Timeline und Medien; Offline-Sendungen werden automatisch wiederholt
🔎 Unicode-FreundessucheIME-Kompositionsschutz, NFC-Normalisierung und UTF-8-Abfragekodierung ermöglichen die zuverlĂ€ssige Suche chinesischer Benutzernamen und Spitznamen
đŸ‘„ GruppenchatBis zu 2000 Mitglieder, umschaltbare Modi „VerschlĂŒsselt" / „UnverschlĂŒsselt" (nur Besitzer, Umschalten löscht den Chatverlauf). VerschlĂŒsselter Modus verwendet das Signal-Sender-Key-Protokoll (XSalsa20-Poly1305 symmetrische VerschlĂŒsselung + ECDH-SchlĂŒsselverteilung) — nur Gruppenmitglieder können Nachrichten entschlĂŒsseln; Bots sind im verschlĂŒsselten Modus deaktiviert. Nicht-stören-Modus, Mitgliederverwaltung
đŸ‘« FreundesystemFreundschaftsanfragen erfordern Genehmigung mit bis zu 512 Zeichen Nachricht; Spitznamen; Multi-Tag-Gruppierung
⏱ Automatisches Löschen5 Stufen (nie / 1 Tag / 3 Tage / 1 Woche / 1 Monat), von beiden Seiten in DMs einstellbar, nur Besitzer in Gruppen
🔔 Push-BenachrichtigungenWeb Push (VAPID) + FCM + OneSignal + ntfy + APNS FĂŒnf-Kanal — Benachrichtigungen auch offline (iOS nativ + chinesische Android-GerĂ€te ohne Google-Dienste)
🌐 MehrsprachigChinesisch, Englisch, Japanisch, Koreanisch, Französisch, Deutsch, Russisch, Spanisch — Autoerkennung + manueller Wechsel
đŸ“± iOS — Ohne UnternehmenszertifikatPWA ĂŒber Safari „Zum Home-Bildschirm hinzufĂŒgen", funktioniert dauerhaft ohne Apple-Signierung
đŸ“± Android Native AppVerfĂŒgbar bei Google Play, mit FCM-Push-UnterstĂŒtzung
đŸ“± iOS Native AppVerfĂŒgbar im App Store, mit APNS-Push-UnterstĂŒtzung
đŸ–„ïž Windows Desktop-ClientNative Windows-Desktopanwendung, hier herunterladen
🍎 Mac Desktop-ClientNative Mac-Desktopanwendung, hier herunterladen
💬 Rich-MessagingText, Bilder, Video, Dokumentdateien, Sprachnachrichten, 200+ Emojis, Telegram-Stickerpakete, LesebestĂ€tigungen, Tippanzeigen
đŸ“€ Datei-UploadBis zu 500 MB pro Datei, Cloudflare R2 oder lokaler Speicher, mit Fortschrittsanimation
🌐 MomenteWeChat-Ă€hnlicher sozialer Feed: Text + bis zu 9 Fotos oder 1 Video (≀ 10 Min.), Likes, Kommentare, Tag-basierte Sichtbarkeit
đŸ‘€ BenutzerprofilKontaktprofilseite mit bidirektionalen Momente-Datenschutzkontrollen
📰 TimelineXiaohongshu-Ă€hnlicher öffentlicher Feed — zweispaltiges Masonry-Layout, anonyme BeitrĂ€ge, Likes & Kommentare
đŸ·ïž Freund-TagsMehrere Tags pro Freund vergeben (12-Farben-Palette), Kontakte nach Tag filtern
đŸ—‚ïž R2 ObjektspeicherCloudflare R2 fĂŒr Bild-/Sprachdateien — optionale öffentliche CDN-URL
🔑 Zwei-Faktor-Authentifizierung (2FA)Google Authenticator–kompatibles TOTP, 8 Wiederherstellungscodes, erzwungen bei Anmeldung
đŸ“· QR-Code scannen & teilenQR-Codes scannen zum HinzufĂŒgen von Freunden oder Beitreten von Gruppen mit konfigurierbarem Ablaufdatum
đŸ—ïž Selbst-HostingDocker Compose, Zeabur One-Click oder Frontend auf Vercel
🌐 Proxy-EinstellungenSOCKS5 / HTTP / HTTPS Proxy-UnterstĂŒtzung — konfigurierbar auf Login- und Einstellungsseiten mit Serveradresse, Port, Benutzername und Passwort fĂŒr eingeschrĂ€nkte Netzwerkumgebungen
đŸ›Ąïž InhaltsmoderationBenutzermeldungen (6 Kategorien) + Benutzer blockieren (sofortige Ausblendung von BeitrĂ€gen/Nachrichten) + Nutzungsbedingungen (EULA)
🔧 Admin-PanelEingebettetes Web-Admin-Dashboard (/admin, Pfad konfigurierbar), passwortgeschĂŒtzt, Meldungen prĂŒfen, Inhalte löschen, Benutzer sperren — 8 Sprachen

Neu in v2.3.9

  • Alte einseitige FreundschaftseintrĂ€ge fĂŒhrten zur Meldung „Bereits befreundet“, obwohl der Kontakt unsichtbar blieb und kein Chat möglich war. Beim erneuten HinzufĂŒgen werden nun beide Richtungen automatisch repariert und die Kontaktliste sofort aktualisiert.

Neu in v2.3.8

  • Die nicht reagierende ZurĂŒck-SchaltflĂ€che nach dem Start der QR-Kamera wurde behoben; beim Schließen wird die Kamera nun sofort gestoppt und freigegeben.
  • Doppelte Freundschaftsanfragen an bestehende Freunde beschĂ€digen die Freundschaft nicht mehr; Suchergebnisse zeigen jetzt „Bereits befreundet“ an.
  • Ausgehende Privatnachrichten werden direkt nach der Ende-zu-Ende-VerschlĂŒsselung als Chiffretext im optimistischen Nachrichtenobjekt gespeichert; beim Warten auf die ServerbestĂ€tigung landet kein Klartext im Offline-Cache.
  • Sprachnachrichten stoppen automatisch nach 120 Sekunden; die Ausgabe mit Stimmeffekt hat dasselbe Limit.
  • Bei Aufnahmen und Anrufen bleibt der Bildschirm wach; beim Verlassen werden AufnahmegerĂ€te und Timer zuverlĂ€ssig freigegeben.
  • Android schĂŒtzt SchlĂŒssel und Chat-Caches zusĂ€tzlich mit Android Keystore und AES-256-GCM; der Web-Client verwendet weiterhin Browser-Speicher.

Sitzungswiederherstellung und NachrichtenzuverlÀssigkeit

PaperPhonePlus behandelt lokalen Kontostatus, Echtzeitverbindung und Nachrichtensynchronisierung getrennt. Ein offener WebSocket gilt erst nach auth_ok als einsatzbereit. Bidirektionale ping/pong-Heartbeats erkennen halboffene Verbindungen nach VPN-/IP-Wechseln, WLAN-/MobilfunkĂŒbergĂ€ngen oder App-Unterbrechungen.

  • Access Tokens gelten 30 Minuten. GerĂ€te-Refresh-Tokens gelten 90 Tage und werden bei aktiver Nutzung verlĂ€ngert, sodass die Erneuerung ohne Passworteingabe erfolgt.
  • Bereits mit einer Ă€lteren Version angemeldete GerĂ€te werden automatisch aktualisiert, solange ihr vorhandenes Token gĂŒltig ist. Ist es bereits abgelaufen, ist eine einmalige erneute Anmeldung erforderlich.
  • Jede ausgehende Nachricht besitzt eine stabile client_msg_id. Nachrichten ohne Server-ACK bleiben im persistenten lokalen Postausgang und werden mit derselben ID erneut gesendet; eine Eindeutigkeitsbedingung verhindert doppelte EintrĂ€ge.
  • Jede gespeicherte Nachricht besitzt eine monoton steigende server_seq. Nach Anmeldung, Wiederverbindung und RĂŒckkehr in den Vordergrund synchronisiert der Client per Cursor fehlende Nachrichten nach.
  • Explizite Abmeldung und GerĂ€tewiderruf machen die dauerhafte Serversitzung ungĂŒltig. Gewöhnliche Transportfehler und IP-Wechsel erhalten sie.

Important

Bei einem Upgrade zuerst den Server und danach die Clients bereitstellen. Der Server fĂŒhrt die ZuverlĂ€ssigkeitsmigration automatisch aus und verweigert den Start, wenn kritische Spalten fehlen. Vor Produktions-Upgrades MySQL sichern.


Technologie-Stack

Backend (server/)
  Rust (Axum 0.8) — Hochleistungs-Async-Web-Framework
  sqlx + MySQL 8.0 — Benutzer-/Nachrichtenpersistenz
  deadpool-redis + Redis 7 — Online-PrĂ€senz + knotenĂŒbergreifendes Routing
  aws-sdk-s3 — Cloudflare R2 Dateispeicher (S3-kompatible API)
  argon2 + jsonwebtoken Authentifizierung

Frontend (client/)
  React 19 + TypeScript + Vite 6
  Zustand Zustandsverwaltung
  libsodium-wrappers-sumo (WebAssembly — Curve25519 / XSalsa20-Poly1305)
  WebRTC API — Video-/Sprachanrufe
  Web Audio API — Echtzeit-Stimmverzerrer (ScriptProcessorNode Audio-Kette)
  PWA: manifest.json + Service Worker

Kryptographische Schicht
  Zustandsloses ECDH + XSalsa20-Poly1305 — Einmal-SchlĂŒsselpaar pro Nachricht
  Vierstufige SchlĂŒsselpersistenz: Speicher → localStorage → sessionStorage → IndexedDB
  Alle privaten SchlĂŒssel nur auf dem GerĂ€t gespeichert — niemals an den Server gesendet

📖 Detaillierte Bereitstellungsanleitung (äž­æ–‡) | Deployment Guide (English) — VollstĂ€ndige Schritt-fĂŒr-Schritt-Anleitung fĂŒr Zeabur + Vercel Hybrid-Bereitstellung, Docker Compose + Nginx lokale Bereitstellung und Client-Server-Adresskonfiguration.

Option 0: Zeabur One-Click Cloud-Bereitstellung

Deploy on Zeabur

Zeabur-NetzwerkeinschrĂ€nkung: Die Vorlage stellt LiveKit ĂŒber WebSocket/API 7880 und ICE/TCP 7881 bereit. Zeabur unterstĂŒtzt derzeit keine öffentlichen UDP-Dienstports; 1:1-Anrufe und Konferenzen verwenden daher TCP-Fallback. FĂŒr produktive Anrufe empfiehlt sich LiveKit Cloud oder eine VM mit UDP-UnterstĂŒtzung.

Serverseitige Nginx-Konfiguration

Verwenden Sie die Zwei-Domain-Produktionskonfiguration deploy/nginx/paperphone-plus.conf. Ersetzen Sie api.example.com und meeting.example.com, beziehen Sie TLS-Zertifikate, kopieren Sie die Datei nach /etc/nginx/sites-available/paperphone-plus, aktivieren Sie sie und fĂŒhren Sie sudo nginx -t && sudo systemctl reload nginx aus. Setzen Sie im Backend LIVEKIT_URL=wss://meeting.example.com. Nginx proxyt nur API und WebSocket; TCP 7881 und UDP 7882 mĂŒssen direkt in Host- und Cloud-Firewall geöffnet werden.

Tip

Erweitert: Zeabur + Vercel Hybrid-Bereitstellung Nach der Bereitstellung auf Zeabur können Sie den client-Dienst manuell löschen und das Frontend stattdessen auf Vercel bereitstellen (siehe Option 2 unten). So werden Server/MySQL/Redis auf Zeabur gehostet, wĂ€hrend das Frontend durch Vercels globales CDN beschleunigt wird. Das Frontend benötigt keine Umgebungsvariablen auf Vercel — Benutzer geben einfach die Backend-Serveradresse auf der Anmeldeseite ein.

Option 1: Docker Compose (Empfohlen)

git clone <repo-url> && cd paperphone-plus
cp server/.env.example server/.env
# Bearbeiten: DB_PASS / JWT_SECRET / LIVEKIT_URL usw.
docker compose up -d
open http://localhost

Option 2: Frontend auf Vercel

# 1. Dieses Repository forken
# 2. In Vercel importieren: Root Directory = client/, Build = npm run build, Output = dist/
#    Keine Umgebungsvariablen erforderlich
# 3. Backend ĂŒber Docker oder Zeabur bereitstellen
# 4. Vercel-Frontend öffnen, Backend-Serveradresse auf der Anmeldeseite eingeben
#    z.B. https://your-server.zeabur.app

Option 3: Lokale Entwicklung

# Backend (Rust)
cd server && cp .env.example .env && cargo run --release

# Frontend (React)
cd client && npm install && npm run dev

Stimmverzerrer

Sprachnachrichten, 1:1-Anrufe und Gruppenanrufe unterstĂŒtzen Echtzeit-Stimmverzerrung mit 3 wĂ€hlbaren Modi:

ModusGeschwindigkeitEffekt
🐱 Langsam0.8xTiefere, dunklere Stimme — ideal fĂŒr AnonymitĂ€t
🔊 Normal1.0xOriginalstimme, keine Verarbeitung
🐇 Schnell1.2xHöhere Stimme — lustig und verspielt

Funktionsweise: Verwendet die Web Audio API zum Aufbau einer Audio-Verarbeitungskette (AudioContext → MediaStreamSource → ScriptProcessorNode → MediaStreamDestination), die Tonhöhe/Geschwindigkeit des Mikrofoneingangs in Echtzeit anpasst.

  • Sprachnachrichten: Stimmmodus wĂ€hrend der Aufnahme wĂ€hlen. Die exportierte .webm-Datei enthĂ€lt bereits den Stimmeffekt — EmpfĂ€nger können die Originalstimme nicht wiederherstellen, was echtes anonymes Messaging ermöglicht
  • 1:1 / Gruppenanrufe: Tippen Sie wĂ€hrend eines Anrufs auf die Stimmverzerrer-Taste, um durch die Modi zu wechseln. Die verarbeitete Audiospur ersetzt das Original ĂŒber LiveKit LocalAudioTrack.replaceTrack()

Keine serverseitige Konfiguration erforderlich. Der Stimmverzerrer lÀuft vollstÀndig clientseitig.


Umgebungsvariablen

VariableBeschreibungStandard
PORTServer-Port3000
JWT_SECRETJWT-SignierungsschlĂŒssel (in Produktion Ă€ndern)dev_secret
DB_HOST / DB_PASS / DB_NAMEMySQL-Verbindung—
REDIS_HOST / REDIS_PASSRedis-Verbindung—
R2_ACCOUNT_IDCloudflare Account-ID—
R2_ACCESS_KEY_IDR2 API Token Access Key—
R2_SECRET_ACCESS_KEYR2 API Token Secret Key—
R2_BUCKETR2 Bucket-Name—
R2_PUBLIC_URLÖffentliche R2-Basis-URL (optional)—
LIVEKIT_URLÖffentliche LiveKit-WebSocket-Adresse fĂŒr alle Anrufe—
LIVEKIT_API_KEYGemeinsamer API-SchlĂŒssel fĂŒr Server und LiveKit—
LIVEKIT_API_SECRETGemeinsames API-Secret fĂŒr Server und LiveKit—
VAPID_PUBLIC_KEYWeb Push VAPID Public Key (optional)—
VAPID_PRIVATE_KEYWeb Push VAPID Private Key (optional)—
VAPID_SUBJECTVAPID Kontakt-E-Mail (optional)mailto:admin@paperphoneplus.app
FCM_PROJECT_IDFirebase Projekt-ID (optional, Capacitor Android)—
FCM_CLIENT_EMAILFirebase-Dienstkonto-E-Mail (optional)—
FCM_PRIVATE_KEYFirebase-Dienstkonto Private Key (optional, unterstĂŒtzt sowohl \n-Escape als auch echte ZeilenumbrĂŒche; siehe unten)—
FCM_RELAY_SECRETFCM Push-Relay-Geheimnis (optional, auf Relay-Host setzen)—
FCM_RELAY_URLFCM Push-Relay-URL (optional, selbstgehostete Server zeigen auf Relay-Host)—
FCM_RELAY_KEYFCM Push-Relay-Auth-SchlĂŒssel (optional, muss mit FCM_RELAY_SECRET des Relay-Hosts ĂŒbereinstimmen)—
ONESIGNAL_APP_IDOneSignal App ID (optional)—
ONESIGNAL_REST_KEYOneSignal REST API Key (optional)—
ONESIGNAL_RELAY_SECRETOneSignal Push-Relay-Geheimnis (optional, auf Relay-Host setzen)—
ONESIGNAL_RELAY_URLOneSignal Push-Relay-URL (optional, selbstgehostete Server zeigen auf Relay-Host)—
ONESIGNAL_RELAY_KEYOneSignal Push-Relay-Auth-SchlĂŒssel (optional, muss mit ONESIGNAL_RELAY_SECRET des Relay-Hosts ĂŒbereinstimmen)—
NTFY_BASE_URLntfy Server-URL (optional, nutzt standardmĂ€ĂŸig öffentlichen ntfy.sh-Dienst)https://ntfy.sh
NTFY_TOKENntfy Auth-Token (optional, fĂŒr selbstgehostete Server)—
APNS_TEAM_IDApple Developer Team ID (optional, iOS native Push)—
APNS_KEY_IDAPNS Auth Key ID (optional)—
APNS_PRIVATE_KEYAPNS .p8 Private Key Inhalt (optional, unterstĂŒtzt \n-Escape)—
APNS_BUNDLE_IDiOS App Bundle Identifier (optional)—
APNS_SANDBOXAPNS Sandbox-Modus (optional, true fĂŒr Entwicklung/TestFlight)false
APNS_RELAY_SECRETPush-Relay-Geheimnis (optional, auf Relay-Host setzen)—
APNS_RELAY_URLPush-Relay-URL (optional, selbstgehostete Server zeigen auf Relay-Host)—
APNS_RELAY_KEYPush-Relay-Auth-SchlĂŒssel (optional, muss mit APNS_RELAY_SECRET des Relay-Hosts ĂŒbereinstimmen)—
TELEGRAM_BOT_TOKENTelegram Bot Token (optional)—
STICKER_PACKSBenutzerdefinierte Stickerpakete (optional, Name:Label)12 integrierte Standards
ADMIN_PATHAdmin-Panel URL-Pfad/admin
ADMIN_PASSWORDAdmin-Panel Passwort (in Produktion Àndern)admin123

FCM Private Key Zeilenumbruch-Behandlung

Das private_key-Feld in der Firebase-Dienstkonto-JSON-Datei enthĂ€lt einen RSA-PrivatschlĂŒssel im PEM-Format, der echte ZeilenumbrĂŒche (\n, ASCII 0x0A) zwischen jeder 64-Zeichen-Zeile erfordert. Viele Bereitstellungsplattformen (Zeabur, Vercel, Railway, Docker) speichern Umgebungsvariablen jedoch als einzeilige Strings und konvertieren \n in die wörtliche Zwei-Zeichen-Sequenz \ + n.

Dies ist die hĂ€ufigste Ursache fĂŒr FCM-Push-Benachrichtigungsfehler — der PEM-Parser schlĂ€gt stillschweigend fehl und es werden keine Push-Benachrichtigungen gesendet, ohne Fehlerprotokolle.

Der Server behandelt dies automatisch: fcm.rs normalisiert wörtliche \n-Sequenzen zurĂŒck zu echten ZeilenumbrĂŒchen vor dem Parsing. Beide Formate funktionieren:

  • Einzeilig (empfohlen fĂŒr Cloud-Plattformen): Den rohen private_key-Wert aus der JSON-Datei mit \n-Escapes einfĂŒgen:

    FCM_PRIVATE_KEY=-----BEGIN PRIVATE KEY-----\nMIIEvQ...\n-----END PRIVATE KEY-----\n
    
  • Mehrzeilig (fĂŒr .env-Dateien): Den vollstĂ€ndigen PEM-Inhalt in AnfĂŒhrungszeichen mit echten ZeilenumbrĂŒchen einschließen:

    FCM_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
    MIIEvQ...
    -----END PRIVATE KEY-----"
    
PlattformEmpfohlenes FormatHinweise
ZeaburEinzeilig (\n escaped)JSON-Wert direkt im Variables-Panel einfĂŒgen
Docker / docker-composeBeidesYAML | fĂŒr mehrzeilig; einzeilig in .env
Vercel / RailwayEinzeilig (\n escaped)Eingabefelder unterstĂŒtzen typischerweise keine echten ZeilenumbrĂŒche
Linux .env-DateiMehrzeilig (in AnfĂŒhrungszeichen)Sicherstellen, dass AnfĂŒhrungszeichen korrekt geschlossen sind

Fehlerbehebung: Wenn FCM-Variablen gesetzt sind, aber Android-Push nicht funktioniert, Serverprotokolle prĂŒfen:

  • [FCM] No access token available → Private Key Format-Fehler (Zeilenumbruch-Problem)
  • [FCM] ✅ Push sent to user xxx → FCM-Versand funktioniert, Problem ist clientseitig
  • Keine FCM-Protokolle → FCM_PROJECT_ID nicht gesetzt oder kein Token in der fcm_tokens-Tabelle

ntfy Push (Chinesische Android-GerÀte ohne Google-Dienste)

FĂŒr Android-GerĂ€te ohne Google Mobile Services (Huawei, Xiaomi, OPPO, vivo usw.) unterstĂŒtzt PaperPhonePlus Push-Benachrichtigungen ĂŒber ntfy.

Standard-Setup (Null-Konfiguration): Nutzt den öffentlichen ntfy.sh-Dienst. Keine zusÀtzliche Konfiguration erforderlich.

Optionale Konfiguration (fĂŒr selbstgehostete ntfy-Server):

NTFY_BASE_URL=https://your-ntfy-server.com
NTFY_TOKEN=your_optional_auth_token

Benutzer-Setup:

  1. ntfy App installieren (Google Play / F-Droid / Direktdownload)
  2. PaperPhonePlus-Einstellungen öffnen und die „ntfy Push"-Karte finden
  3. Den angezeigten Topic-Namen kopieren und in der ntfy App abonnieren
  4. Auf „Push registrieren" tippen, um die Registrierung abzuschließen

Sicherheitshinweis: ntfy-Benachrichtigungen enthalten Benachrichtigungstitel und Zusammenfassungen im Klartext (nicht den eigentlichen Nachrichteninhalt). FĂŒr höhere Sicherheit einen selbstgehosteten ntfy-Server verwenden.

APNS Push (Native iOS App)

APNS (Apple Push Notification Service) sendet Push-Benachrichtigungen an native iOS-Apps, die mit Capacitor erstellt wurden. Es gibt zwei Konfigurationsmöglichkeiten:

Option A: Direkte Konfiguration (Server des App-Entwicklers)

  1. Bei Apple Developer anmelden → Certificates, Identifiers & Profiles → Keys
  2. + klicken, um einen neuen Key zu erstellen → Apple Push Notifications service (APNs) aktivieren → Register
  3. .p8-Datei herunterladen (⚠ kann nur einmal heruntergeladen werden!) und die Key ID notieren
  4. Team ID von der Apple Developer Mitgliedschaftsseite notieren (10-stellig alphanumerisch)
  5. In server/.env einfĂŒgen:
APNS_TEAM_ID=AB12CD34EF
APNS_KEY_ID=LH4Z9YN3P7
APNS_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIGTAgEA...(.p8-Dateiinhalt)...\n-----END PRIVATE KEY-----"
APNS_BUNDLE_ID=com.yourcompany.paperphoneplus
APNS_SANDBOX=false

APNS_SANDBOX: Auf true fĂŒr Entwicklung/TestFlight-Builds, false fĂŒr App Store-Produktion setzen.

Option B: Über Push Relay (Selbstgehostete Server)

Wenn Sie die iOS-App eines anderen verwenden (z.B. aus dem App Store heruntergeladen), haben Sie keine Apple-Zugangsdaten des Entwicklers und können keine APNS-Pushes direkt senden. Verwenden Sie stattdessen den Push Relay.

Funktionsweise:

┌──────────────────────┐       ┌─────────────────────────┐       ┌─────────┐
│  Selbstgehosteter     │  HTTP  │  Server des Entwicklers  │  APNS  │  Apple  │
│  Server               │──────→│  (hat .p8 Key + Relay)   │──────→│  ──→ đŸ“± │
│  (keine Apple-Creds)  │       │                          │       └─────────┘
│  APNS_RELAY_URL=...   │       │  APNS_TEAM_ID=...        │
│  APNS_RELAY_KEY=...   │       │  APNS_RELAY_SECRET=...   │
└──────────────────────┘       └─────────────────────────┘

Schritt 1: App-Entwickler aktiviert den Relay-Endpunkt

Auf dem Server des App-Entwicklers (der bereits APNS-Zugangsdaten hat) ein Relay-Geheimnis setzen:

# Server des App-Entwicklers .env (hat bereits APNS_TEAM_ID usw.)
APNS_RELAY_SECRET=ein_langer_zufĂ€lliger_gemeinsamer_SchlĂŒssel

Dies aktiviert automatisch den Push-Relay-Endpunkt unter POST /api/push-relay/apns.

Schritt 2: Selbstgehosteter Benutzer konfiguriert den Relay

Selbstgehostete Server benötigen nur zwei Variablen — keine Apple-Zugangsdaten erforderlich:

# Selbstgehosteter Server .env
APNS_RELAY_URL=https://app-developer-server.com
APNS_RELAY_KEY=gemeinsamer_SchlĂŒssel_aus_Schritt_1

Ablauf:

  1. Selbstgehosteter Server empfĂ€ngt eine Offline-Nachricht → fragt lokale apns_tokens-Tabelle nach iOS-GerĂ€te-Tokens des Benutzers ab
  2. Sendet GerÀte-Tokens + Push-Titel/Inhalt per HTTP POST an den Relay
  3. Relay validiert den SchlĂŒssel und sendet dann mit eigenen APNS-Zugangsdaten an Apple
  4. Relay gibt eine Liste abgelaufener Tokens zurĂŒck; der selbstgehostete Server bereinigt automatisch seine lokale Datenbank

PrioritĂ€t: Lokale APNS-Zugangsdaten → Push Relay → Überspringen (still). Wenn beide konfiguriert sind, hat die lokale Direktverbindung Vorrang.

Sicherheitshinweis: Der Relay ĂŒbertrĂ€gt nur Push-Benachrichtigungstitel und Zusammenfassungen (z.B. „Jemand hat Ihnen eine Nachricht gesendet"), nicht den eigentlichen Nachrichteninhalt. GerĂ€te-Tokens können nicht zum Lesen von Benutzerdaten verwendet werden.

Push Relay (Alle KanÀle)

FĂŒr selbstgehostete Server-Betreiber, die die veröffentlichte App eines anderen verwenden (z.B. aus dem App Store/Google Play), haben Sie keine Push-Zugangsdaten des Entwicklers (Apple .p8 Key / Firebase-Dienstkonto / OneSignal API Key).

Das Push-Relay-System bietet Relay-FĂ€higkeit fĂŒr APNS, FCM und OneSignal KanĂ€le:

App-Entwickler aktiviert Relay-Endpunkte auf seinem Server:

# Server des App-Entwicklers .env
APNS_RELAY_SECRET=ein_langer_zufÀlliger_String
FCM_RELAY_SECRET=ein_langer_zufÀlliger_String
ONESIGNAL_RELAY_SECRET=ein_langer_zufÀlliger_String

Selbstgehostete Benutzer benötigen nur Relay-URL und SchlĂŒssel — keine Push-Service-Zugangsdaten erforderlich:

# Selbstgehosteter Server .env
# APNS (iOS native Push)
APNS_RELAY_URL=https://app-developer-server.com
APNS_RELAY_KEY=gemeinsamer_SchlĂŒssel

# FCM (Android native Push)
FCM_RELAY_URL=https://app-developer-server.com
FCM_RELAY_KEY=gemeinsamer_SchlĂŒssel

# OneSignal (Median.co-verpackte Apps)
ONESIGNAL_RELAY_URL=https://app-developer-server.com
ONESIGNAL_RELAY_KEY=gemeinsamer_SchlĂŒssel

PrioritĂ€t: Lokale Zugangsdaten → Push Relay → Überspringen (still). Wenn beide konfiguriert sind, hat die lokale Direktverbindung Vorrang.


Offizieller Push Relay

Selbstgehostete Server-Betreiber können den offiziellen Push Relay verwenden, um iOS/Android Push-Benachrichtigungen ohne Konfiguration von Push-Zugangsdaten zu aktivieren:

# 2026-05-18
APNS_RELAY_URL=https://619.chat
APNS_RELAY_KEY=EzmpqftbsENaRUO6BTABxLV96q7RuEDyokXJr1DWdDjL54cLg7yXVUQqydCQvxrX
FCM_RELAY_URL=https://619.chat
FCM_RELAY_KEY=EzmpqftbsENaRUO6BTABxLV96q7RuEDyokXJr1DWdDjL54cLg7yXVUQqydCQvxrX
ONESIGNAL_RELAY_URL=https://619.chat
ONESIGNAL_RELAY_KEY=EzmpqftbsENaRUO6BTABxLV96q7RuEDyokXJr1DWdDjL54cLg7yXVUQqydCQvxrX

Diese Zeilen zur .env-Datei Ihres selbstgehosteten Servers hinzufĂŒgen.


Lizenz

Dieses Projekt ist unter der GNU Affero General Public License v3.0 (AGPL-3.0) lizenziert.