chahinebrini 5fb441817f feat(magic): RE-hardening Quick Wins (ACL, #if DEBUG guards, rate-limit)
Härtung der öffentlich downloadbaren Magic-Apps gegen Reverse Engineering
(Assessment: docs/specs/magic-re-hardening.md):
- Windows: protection.json per ACL auf SYSTEM+Admins (DNS-Token nicht mehr von
  Standard-Usern lesbar) — setup.rs
- Mac: MacProfileInstaller.remove() + Debug-Supervision-Modi/Reset nur noch
  #if DEBUG (kein Removal-/Debug-Pfad im Release-Binary)
- Mac: staging-URL einmal als Konstante statt 4x Literal; interne Infra-Notizen
  aus String-Literalen raus
- Backend: Rate-Limit (10/IP/min) auf /api/magic/pair/redeem

NUR Backend-Teil deployt via Push; Mac/Win brauchen Xcode-/Cargo-Release-Build
(zied) + Smoke-Tests vor Release. MagicAPIClient.swift trägt etwas vorbestehenden
WIP mit (gleiche Magic-Client-Domäne).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 05:19:10 +02:00

58 lines
2.0 KiB
Swift

import SwiftUI
@main
struct RebreakMagicApp: App {
@State private var model = WizardModel()
var body: some Scene {
WindowGroup("Rebreak Magic") {
ContentView()
.environment(model)
.frame(minWidth: 720, idealWidth: 800, minHeight: 600, idealHeight: 720)
}
.windowResizability(.contentSize)
.windowStyle(.titleBar)
.commands {
CommandMenu("Account") {
Button("Abmelden") {
Task { await model.handleLogout() }
}
.keyboardShortcut("l", modifiers: [.command, .shift])
.disabled(model.authSession == nil)
}
#if DEBUG
CommandMenu("Aktionen") {
Menu("Debug Supervision Mode") {
Button(DebugSupervisionMode.none.title) {
model.supervisionMode = .none
}
Button(DebugSupervisionMode.forceSupervised.title) {
model.supervisionMode = .forceSupervised
}
Button(DebugSupervisionMode.forceUnsupervised.title) {
model.supervisionMode = .forceUnsupervised
}
}
Toggle("Profile + App entfernen", isOn: $model.resetAll)
Toggle("MDM Enrollment-Profil", isOn: $model.resetEnrollmentProfile)
.disabled(model.resetAll)
Toggle("Lock-Profil", isOn: $model.resetLockProfile)
.disabled(model.resetAll)
Toggle("ReBreak-App", isOn: $model.resetApp)
.disabled(model.resetAll)
Divider()
Button("Debug-Reset ausführen") {
model.startDebugReset()
}
.keyboardShortcut("r", modifiers: [.command, .shift, .option])
.disabled(model.device == nil || model.resetRunning)
}
#endif
}
}
}