- 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)
7.1 KiB
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 viaprofilescommand
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.swiftviamodel.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(viamodel.showingManageBindings) - Bei Erfolg: "Weiter → iPhone-Setup" button
- ✅ Integration in
ContentView.swiftswitch-case - ✅
WizardModel.swifterweitert:- Initial-Step:
.macRegistrationstatt.welcome reset()setzt auchmagicRegistration = nilundregistrationError = nil
- Initial-Step:
4. Menu-Erweiterung
- ✅ Neues Command-Menu "Account" mit "Abmelden" (⌘⇧L)
- ✅
handleLogout()in WizardModel ruftAuthService.signOut()+ reset
5. Workflow-Integration
Neuer Flow:
- App startet →
authStateaus Keychain laden - Wenn kein Auth →
LoginView - Nach Login →
.macRegistration(Mac registrieren + Profil installieren) - Nach Mac-Setup →
.welcome(iPhone-Detection wie bisher) - Rest unverändert: preflight → supervise → enroll → configure → done
📂 Neue Files
- ✅
Sources/Views/MacRegistrationView.swift(218 Zeilen)
📝 Geänderte Files
-
Sources/Models/WizardStep.swift- Neuer Case
.macRegistration = 0 .welcomewurde von rawValue 0 → 1 (alle anderen +1)- Titel: "Mac registrieren"
- Neuer Case
-
Sources/Models/WizardModel.swift- Initial-Step:
var step: WizardStep = .macRegistration reset()erweitert: setztmagicRegistration = nil,registrationError = nil- Syntax-Fix: entfernte orphaned code-fragments
- Initial-Step:
-
Sources/Views/ContentView.swift- Switch-Case erweitert:
case .macRegistration: MacRegistrationView()
- Switch-Case erweitert:
-
Sources/Views/LoginView.swift- macOS-Kompatibilität:
.textInputAutocapitalization(.never)entfernt (iOS-only)
- macOS-Kompatibilität:
-
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-DashboardbackendBaseUrl— staging:https://staging.rebreak.org, prod:https://api.rebreak.orgmdmServer,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' expressionbeiMainActor.run(expected, korrekt)
📋 Login-Flow-Ablauf
-
App-Start
WizardModel.init()lädtauthSession = AuthService.shared.currentSession()- Falls
authSession == nil→showingLogin = true
-
LoginView
- User gibt Email + Passwort ein
AuthService.signIn()→ Supabase/auth/v1/token- Bei Erfolg: Session in Keychain speichern
model.handleLogin(session)setztshowingLogin = false
-
MacRegistrationView (neuer Step)
- Liest Mac-Info via
MacDeviceDetector.detect() - Button "Mac registrieren" →
model.registerMac()- API:
POST /api/magic/registermit{ deviceId, hostname, model, osVersion } - Response:
{ dnsToken, profileUrl, existing }
- API:
- 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
- Liest Mac-Info via
-
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.jsonempfohlen
🚧 Bekannte Limitations / TODOs
-
Profile-Installation benötigt User-Interaktion
profiles installauf macOS öffnet evtl. System-Settings-Dialog- User muss Profil manuell bestätigen (macOS-Security-Policy)
- TODO: Anleitung in UI zeigen falls Installation fehlschlägt
-
Keine Profile-Signierung
- Unsigned Profiles triggern macOS-Warnung
- TODO: Apple-Developer-Cert für Profil-Signierung (Phase 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
-
Keine Tests
- Unit-Tests für AuthService, MagicAPIClient kommen in Phase 3
-
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)
- Config erstellen:
cp config.example.json ~/.config/rebreak-magic/config.json+ Werte eintragen - Supabase-Projekt: URL + Anon-Key aus Supabase-Dashboard
- Test-Account: User in Supabase anlegen (via Supabase-Dashboard oder Backend-Signup)
- App starten: Xcode → Run, Login-Flow testen
- Mac-Registrierung testen: Device-Limit-Check (max 3 Devices)
- Profil prüfen:
profiles show -type configuration→ sollteorg.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