02 - Authentifizierung & Autorisierung¶
Dokument: Auth-System Dokumentation Stand: 28.02.2026 Scope: Web3Auth, Wallet-Validierung, Session-Management Status: Audit-ready
1. Web3Auth-Integration¶
1.1 Konfiguration¶
| Parameter | Wert |
|---|---|
| Provider | Web3Auth Modal v10.13.2 |
| Netzwerk | Sapphire Devnet |
| Session-Dauer | 7 Tage (604.800 Sekunden) |
| Client-ID | NEXT_PUBLIC_WEB3AUTH_CLIENT_ID |
| Chain | Arbitrum Sepolia (0x66eee / 421614) |
| RPC Target | Alchemy (arb-sepolia) |
1.2 Login-Methoden nach Plattform¶
| Methode | Web (Desktop) | Web (Mobile) | Telegram Mobile | Telegram Desktop |
|---|---|---|---|---|
| Web3Auth Modal | Ja | Ja | Nein | Nein |
| Google OAuth | Popup | Popup | Redirect | Redirect |
| Apple OAuth | - | - | Redirect | Redirect |
| Email/Passwordless | - | - | Redirect | Redirect |
1.3 Plattform-Erkennung¶
const isTelegramWebView = !!window.Telegram?.WebApp?.initData;
const tgPlatform = window.Telegram?.WebApp?.platform;
const isTelegramMobile = ["android", "android_x", "ios"].includes(tgPlatform);
Konfiguration nach Plattform:
| Plattform | UX Mode | Redirect URL | Grund |
|---|---|---|---|
| Telegram Mobile | redirect |
Aktuelle Seiten-URL | Popups blockiert in Mobile WebView |
| Telegram Desktop | popup |
- | Popups funktionieren |
| Web/Browser | modal |
- | Full Web3Auth Modal mit Connector-Auswahl |
1.4 Connector-Konfiguration (Web)¶
| Connector | Sichtbar im Modal |
|---|---|
| AUTH (Web3Auth) | Ja |
| WALLET_CONNECT_V2 | Nein |
| METAMASK | Nein (außer Mobile) |
| COINBASE | Nein |
2. Login-Flows¶
2.1 Standard Web Login¶
User klickt Login
→ Web3Auth Modal öffnet sich
→ User wählt Provider
→ Web3Auth initialisiert Wallet
→ waitForProviderRPC() (max 5s, 500ms Polling)
→ loadUserDataWithRetry() (max 4 Versuche, exponentielles Backoff)
→ completeLogin()
→ Provider & isConnected setzen
→ Wallet-Adresse extrahieren
→ fetchStats() (POST /api/player/init)
→ checkOrCreateUserProfile()
2.2 Telegram Email Login¶
User gibt E-Mail ein
→ web3auth.connectTo(AUTH, { authConnection: "email_passwordless", loginHint: email })
→ Redirect zu Web3Auth
→ Rückkehr zur App
→ Session wiederhergestellt
→ completeLogin()
2.3 Telegram Social Login¶
User klickt Google/Apple
→ web3auth.connectTo(AUTH, { authConnection: "google" | "apple" })
→ Redirect (Mobile) oder Popup (Desktop)
→ Rückkehr zur App
→ completeLogin()
2.4 Session-Wiederherstellung¶
App startet
→ Web3Auth initModal()
→ web3auth.connected && web3auth.provider?
→ Ja: waitForProviderRPC() (RPC bereit?)
→ Ja: loadUserDataWithRetry() (max 2 Versuche)
→ Erfolg: completeLogin()
→ Fehler: Session löschen
→ Nein (RPC-Timeout): Session löschen
→ Nein: isReady=true, warte auf Login
2.5 Telegram Mobile Visibility Handler¶
Spezialbehandlung für Telegram Mobile OAuth-Redirects:
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "visible" && !isConnected) {
// Prüfe ob Session in SharedStorage gespeichert wurde
// Falls ja: loadUserData() + completeLogin()
}
});
3. Wallet-Validierung¶
3.1 Konsistenzprüfung (Firefox-Fix)¶
Problem: Firefox/Web3Auth-Bug kann bei Session-Wiederherstellung eine andere Wallet-Adresse laden.
Lösung: lib/walletValidation.ts
| Funktion | Beschreibung |
|---|---|
saveVerifiedWallet(address) |
Speichert Wallet nach Login in localStorage |
getVerifiedWallet() |
Ruft gespeicherte Adresse ab |
clearVerifiedWallet() |
Löscht bei Logout |
validateWalletConsistency(currentAddress) |
Vergleicht aktuelle vs. gespeicherte Adresse |
Storage Key: chainbets_verified_wallet
Validierungslogik:
| Szenario | Ergebnis | Aktion |
|---|---|---|
| Kein gespeichertes Wallet (Erst-Login) | valid: true |
Wallet speichern, weiter |
| Wallet stimmt überein | valid: true |
Weiter |
| Wallet stimmt NICHT überein | valid: false |
Logout, Wallet löschen, Fehler anzeigen |
3.2 Implementierung im Web3AuthProvider¶
const validation = validateWalletConsistency(addr);
if (!validation.valid) {
// Fehler loggen
// walletError setzen
// Logout erzwingen
// clearVerifiedWallet()
return false;
}
if (!validation.savedAddress) {
saveVerifiedWallet(addr);
}
4. Benutzerprofil-System¶
4.1 Profil-Erstellung¶
| Schritt | Beschreibung |
|---|---|
| Login | checkOrCreateUserProfile() wird aufgerufen |
| GET /api/user/profile | Prüft ob User existiert |
| User existiert | Profil laden, ggf. Web3Auth-Daten aktualisieren |
| User existiert nicht (404) | Neuen User via POST erstellen |
| Vollständigkeit prüfen | Modal anzeigen wenn unvollständig |
4.2 Pflichtfelder¶
| Feld | Pflicht | Nach Eingabe gesperrt |
|---|---|---|
| firstName | Ja | Ja |
| lastName | Ja | Ja |
| Ja | Ja | |
| dateOfBirth | Ja | Ja |
| addressCountry (Nationalität) | Ja | Ja |
Profil-Vollständigkeit: Alle 5 Felder müssen ausgefüllt sein, sonst wird ProfileIncompleteModal angezeigt.
4.3 Profilvervollständigungs-Bonus¶
Bei erstmaliger Eingabe aller Pflichtfelder werden 10 Bonus-Tips gutgeschrieben.
4.4 KYC-Status-Tracking¶
| Status | Beschreibung |
|---|---|
none |
Keine Verifizierung |
pending |
Verifizierung läuft |
verified |
Verifiziert |
rejected |
Abgelehnt |
4.5 Responsible Gaming¶
| Feature | Beschreibung |
|---|---|
| Tägliches Limit | dailyLimitUsdt |
| Wöchentliches Limit | weeklyLimitUsdt |
| Monatliches Limit | monthlyLimitUsdt |
| Self-Exclusion | selfExclusionUntil (24h - 365 Tage, nicht verkürzbar) |
| Altersverifizierung | 18+ Pflicht (Geburtsdatum geprüft) |
5. Signaturbasierte Authentifizierung¶
5.1 EIP-712 Typed Data Signaturen¶
Verwendet für Transaktionsautorisierung (kein Passwort nötig):
BuyPermit:
{
buyer: address,
poolId: uint256,
tipsHash: bytes32,
deadline: uint256,
nonce: uint256,
maxGasCostUsdt: uint256
}
ClaimPermit:
{
claimer: address,
totalWinnerAmount: uint256,
totalAffiliateAmount: uint256,
maxGasCostUsdt: uint256,
deadline: uint256,
nonce: uint256,
claimsHash: bytes32
}
5.2 EIP-191 Message Signing¶
Verwendet für Claim-Payload-Zugriff:
Message: "Claim payload request\nAddress: {address}\nChainId: {chainId}\nTimestamp: {timestamp}"
Headers: x-claim-address, x-claim-signature, x-claim-timestamp
Replay-Schutz: Timestamp ± 5 Minuten
6. Affiliate-Ref-Tracking¶
6.1 Flow¶
1. User erhält Link: chainbets.win/?ref=0x...
2. App erkennt ?ref= Parameter
3. Ref wird in localStorage gespeichert ("chainbets_ref")
4. ?ref= wird aus URL entfernt (verhindert OAuth-Redirect-Probleme)
5. Bei Login: ref wird an POST /api/player/init gesendet
6. Backend bindet Affiliate (nur beim Erst-Login)
7. localStorage-Eintrag wird gelöscht
6.2 Telegram-Affiliate¶
1. Telegram Bot: /start refCode
2. Mini App: ?startapp=refCode
3. TelegramProvider extrahiert startParam
4. Speichert als "chainbets_ref" in localStorage
5. Gleicher Login-Flow wie Web
7. Logout¶
web3auth.logout()
→ clearVerifiedWallet()
→ Alle State-Variablen zurücksetzen
→ window.location.href = "/" (Hard Redirect)
→ Web3Auth-Instanz wird NICHT zerstört (Singleton, wiederverwendbar)
Weiterführende Dokumente: - 11 - Telegram Integration - 13 - KYC & Compliance - 10 - Sicherheit