chahinebrini 77edd67cbe fix(magic): explicit imports + staging defaults + sheet height
- backend/api/magic/register: explicit import of MAGIC_DEVICE_LIMIT
  and createAdGuardClient (Nitro auto-import was missing them
  → ReferenceError → HTTP 500 on /api/magic/register)
- mac-app: default backendBaseUrl falls back to staging.rebreak.org
  (app.rebreak.org serves wrong TLS cert)
- native MagicSheet: fallback download/dmg URLs point to staging
- native settings: Magic sheet capped at detents=[0.85] so AppHeader
  stays visible
- bundles all in-flight Magic feature work (pair create/redeem,
  device endpoints, schema, adguard utils, mac-app, locales)
2026-06-03 08:25:02 +02:00

7.1 KiB

ReBreak Magic Mac-App — Phase 2: Backend-Auth-Integration

Implementierte Features

1. Auth-Stack (bereits implementiert)

  • AuthService.swift — Supabase-Login + Keychain-Persistence
  • KeychainStore — in AuthService integriert (Service: org.rebreak.magic)
  • MagicAPIClient.swift — Backend-API-Client für /api/magic/*
  • MacDeviceDetector.swift — IOPlatformUUID + hwModel via IOKit/sysctl
  • MacProfileInstaller.swift — Profile-Download + Installation via profiles command

2. Login-UI (bereits implementiert)

  • LoginView.swift — Email/Passwort-Login
  • Error-Handling für InvalidCredentials
  • Link zu "Noch kein Account? rebreak.org/signup"
  • Integration in ContentView.swift via model.showingLogin

3. Mac-Registration-Flow (NEU implementiert)

  • Neuer WizardStep .macRegistration (rawValue 0, vor .welcome)
  • MacRegistrationView.swift — UI für Mac-Device-Registrierung:
    • Zeigt Mac-Info (hostname, model, deviceId via IOPlatformUUID)
    • Button "Mac registrieren" → ruft model.registerMac()
    • Auto-Download + Installation des DNS-Filter-Profils
    • Limit-Reached-Handling → öffnet ManageBindingsView (via model.showingManageBindings)
    • Bei Erfolg: "Weiter → iPhone-Setup" button
  • Integration in ContentView.swift switch-case
  • WizardModel.swift erweitert:
    • Initial-Step: .macRegistration statt .welcome
    • reset() setzt auch magicRegistration = nil und registrationError = nil

4. Menu-Erweiterung

  • Neues Command-Menu "Account" mit "Abmelden" (⌘⇧L)
  • handleLogout() in WizardModel ruft AuthService.signOut() + reset

5. Workflow-Integration

Neuer Flow:

  1. App startet → authState aus Keychain laden
  2. Wenn kein Auth → LoginView
  3. Nach Login → .macRegistration (Mac registrieren + Profil installieren)
  4. Nach Mac-Setup → .welcome (iPhone-Detection wie bisher)
  5. Rest unverändert: preflight → supervise → enroll → configure → done

📂 Neue Files

  • Sources/Views/MacRegistrationView.swift (218 Zeilen)

📝 Geänderte Files

  1. Sources/Models/WizardStep.swift

    • Neuer Case .macRegistration = 0
    • .welcome wurde von rawValue 0 → 1 (alle anderen +1)
    • Titel: "Mac registrieren"
  2. Sources/Models/WizardModel.swift

    • Initial-Step: var step: WizardStep = .macRegistration
    • reset() erweitert: setzt magicRegistration = nil, registrationError = nil
    • Syntax-Fix: entfernte orphaned code-fragments
  3. Sources/Views/ContentView.swift

    • Switch-Case erweitert: case .macRegistration: MacRegistrationView()
  4. Sources/Views/LoginView.swift

    • macOS-Kompatibilität: .textInputAutocapitalization(.never) entfernt (iOS-only)
  5. Sources/RebreakMagicApp.swift

    • Neues Command-Menu "Account" mit "Abmelden"

⚙️ Config-Anforderungen

User muss ~/.config/rebreak-magic/config.json erstellen (siehe config.example.json):

{
  "supabaseUrl": "https://your-project.supabase.co",
  "supabaseAnonKey": "your-supabase-anon-key",
  "backendBaseUrl": "https://staging.rebreak.org",
  "mdmServer": "https://mdm.rebreak.org",
  "mdmUser": "admin",
  "mdmApiKey": "your-nanomdm-api-key"
}

Benötigte Werte:

  • supabaseUrl + supabaseAnonKey — von Supabase-Dashboard
  • backendBaseUrl — staging: https://staging.rebreak.org, prod: https://api.rebreak.org
  • mdmServer, mdmUser, mdmApiKey — für iPhone-MDM-Commands (nur wenn iPhone-Setup durchgeführt wird)

🏗 Build-Status

BUILD SUCCEEDED

cd apps/rebreak-magic-mac
xcodegen generate
xcodebuild -project RebreakMagic.xcodeproj -scheme RebreakMagic -configuration Debug build

Warnings (harmlos):

  • no 'async' operations occur within 'await' expression bei MainActor.run (expected, korrekt)

📋 Login-Flow-Ablauf

  1. App-Start

    • WizardModel.init() lädt authSession = AuthService.shared.currentSession()
    • Falls authSession == nilshowingLogin = true
  2. LoginView

    • User gibt Email + Passwort ein
    • AuthService.signIn() → Supabase /auth/v1/token
    • Bei Erfolg: Session in Keychain speichern
    • model.handleLogin(session) setzt showingLogin = false
  3. MacRegistrationView (neuer Step)

    • Liest Mac-Info via MacDeviceDetector.detect()
    • Button "Mac registrieren" → model.registerMac()
      • API: POST /api/magic/register mit { deviceId, hostname, model, osVersion }
      • Response: { dnsToken, profileUrl, existing }
    • Auto-Download: MagicAPIClient.downloadProfile(token) → tmp-File
    • Auto-Install: MacProfileInstaller.downloadAndInstall()profiles install -path <url>
    • Bei Limit-Reached (409): öffnet ManageBindingsView (Sheet)
    • Bei Erfolg: "Weiter → iPhone-Setup" → model.advance() zu .welcome
  4. Rest des Wizards (unverändert)

    • .welcome — iPhone-Detection
    • etc.

🔒 Security-Hinweise

  • Keychain-Service: org.rebreak.magic (Account: User-Email)
  • JWT-Tokens: Access + Refresh-Token in Keychain
  • Token-Refresh: Auto-Refresh bei Expiry via AuthService.refreshSessionIfNeeded()
  • Config-File: chmod 600 auf ~/.config/rebreak-magic/config.json empfohlen

🚧 Bekannte Limitations / TODOs

  1. Profile-Installation benötigt User-Interaktion

    • profiles install auf macOS öffnet evtl. System-Settings-Dialog
    • User muss Profil manuell bestätigen (macOS-Security-Policy)
    • TODO: Anleitung in UI zeigen falls Installation fehlschlägt
  2. Keine Profile-Signierung

    • Unsigned Profiles triggern macOS-Warnung
    • TODO: Apple-Developer-Cert für Profil-Signierung (Phase 3)
  3. Device-ID-Persistence

    • IOPlatformUUID ist Hardware-UUID, bleibt stabil
    • Bei Mac-Hardware-Reset ändert sich UUID → neues Device im Backend
    • Akzeptabel für jetzt
  4. Keine Tests

    • Unit-Tests für AuthService, MagicAPIClient kommen in Phase 3
  5. Offline-Handling

    • Bei Netzwerkfehler: Error-Message, aber kein Retry-Button
    • User muss App neu starten oder "Erneut registrieren" clicken

📊 Code-Statistik

  • Neue Files: 1 (MacRegistrationView.swift, 218 LOC)
  • Geänderte Files: 5 (WizardStep, WizardModel, ContentView, LoginView, RebreakMagicApp)
  • Bestehende Services (nicht geändert): AuthService, MagicAPIClient, MacDeviceDetector, MacProfileInstaller, ManageBindingsView

🎯 Nächste Schritte (optional für User)

  1. Config erstellen: cp config.example.json ~/.config/rebreak-magic/config.json + Werte eintragen
  2. Supabase-Projekt: URL + Anon-Key aus Supabase-Dashboard
  3. Test-Account: User in Supabase anlegen (via Supabase-Dashboard oder Backend-Signup)
  4. App starten: Xcode → Run, Login-Flow testen
  5. Mac-Registrierung testen: Device-Limit-Check (max 3 Devices)
  6. Profil prüfen: profiles show -type configuration → sollte org.rebreak.protection.profile.* enthalten

Bonus-Feature (bereits implementiert)

  • ManageBindingsView — zeigt eigene Magic-Bindings + Release-Button
  • Erreichbar via Sheet wenn Limit-Reached
  • 24h-Cooldown-Handling für Release-Requests