fix(magic-mac): macOS 26 profile install via NSWorkspace + de-dup register card
Zwei Bugs:
1) 'profiles install -path' wurde mit macOS 15+ entfernt
('profiles tool no longer supports installs. Use System Settings
Profiles to add configuration profiles.'). Auf macOS 26 (Tahoe)
ist das Hard-Removal.
-> Switch zu NSWorkspace.shared.open(profileURL): \u00f6ffnet die
.mobileconfig in System Settings -> Profile-Pane. User best\u00e4tigt
manuell + gibt Admin-PW. Einziger Weg ohne MDM-Enrollment.
-> success-Text passt: 'Bitte in System Settings Installieren
klicken'.
2) Doppelte 'Mac registriert'-Karte: successMessage-Card UND
strukturierte Registration-Status-Card beide sichtbar nach
register. Auto-Profile-Install nach Register war eh totes
Verhalten (DNS jetzt optional).
-> successMessage wird nicht mehr in handleRegistration gesetzt,
nur noch in handleProfileInstall. Eine Karte.
This commit is contained in:
parent
18c3a49404
commit
87d6395ed2
@ -1,4 +1,5 @@
|
||||
import Foundation
|
||||
import AppKit
|
||||
|
||||
/// Service für Mac-DNS-Profile-Download + Installation.
|
||||
enum MacProfileInstaller {
|
||||
@ -20,8 +21,12 @@ enum MacProfileInstaller {
|
||||
}
|
||||
}
|
||||
|
||||
/// Lädt Mac-DNS-Profile von Backend und installiert via `profiles install`.
|
||||
/// Profile-File wird nach Installation gelöscht (enthält sensiblen Token).
|
||||
/// Lädt Mac-DNS-Profile von Backend und öffnet es in System Settings → Profiles.
|
||||
/// Ab macOS 15+ ist `profiles install` für Configuration Profiles entfernt
|
||||
/// ("profiles tool no longer supports installs. Use System Settings
|
||||
/// Profiles to add configuration profiles."). Einzig zulässiger Weg ohne
|
||||
/// MDM-Enrollment: NSWorkspace öffnet die .mobileconfig → Profiles-Pane
|
||||
/// erscheint → User muss manuell „Installieren" klicken + Admin-PW geben.
|
||||
static func downloadAndInstall(registration: MagicRegistration) async throws {
|
||||
// 1. Download profile
|
||||
let profileURL: URL
|
||||
@ -31,19 +36,20 @@ enum MacProfileInstaller {
|
||||
throw InstallerError.downloadFailed(error.localizedDescription)
|
||||
}
|
||||
|
||||
// 2. Install via `profiles` command (macOS-only)
|
||||
let result = try await ProcessRunner.run(
|
||||
"/usr/bin/profiles",
|
||||
arguments: ["install", "-path", profileURL.path]
|
||||
)
|
||||
|
||||
// 3. Clean up downloaded file
|
||||
try? FileManager.default.removeItem(at: profileURL)
|
||||
|
||||
if result.exitCode != 0 {
|
||||
let errorMsg = result.stderr.isEmpty ? result.stdout : result.stderr
|
||||
throw InstallerError.installFailed(errorMsg)
|
||||
// 2. Open in System Settings → Profiles (user must confirm in UI)
|
||||
let opened = await MainActor.run {
|
||||
NSWorkspace.shared.open(profileURL)
|
||||
}
|
||||
|
||||
if !opened {
|
||||
try? FileManager.default.removeItem(at: profileURL)
|
||||
throw InstallerError.installFailed(
|
||||
"System Settings konnte das Profil nicht öffnen. Datei liegt unter: \(profileURL.path)"
|
||||
)
|
||||
}
|
||||
|
||||
// NICHT löschen — System Settings braucht die Datei evtl. noch.
|
||||
// OS räumt /tmp selbst auf.
|
||||
}
|
||||
|
||||
/// Prüft ob ReBreak-DNS-Profile bereits installiert ist.
|
||||
|
||||
@ -196,13 +196,10 @@ struct MacRegistrationView: View {
|
||||
try await model.registerMac()
|
||||
|
||||
await MainActor.run {
|
||||
successMessage = "Mac erfolgreich registriert ✓"
|
||||
isRegistering = false
|
||||
}
|
||||
|
||||
// Auto-trigger profile install
|
||||
try await Task.sleep(nanoseconds: 500_000_000) // 0.5s delay
|
||||
await handleProfileInstall()
|
||||
// KEIN Auto-Profile-Install mehr — DNS-Schutz ist optional.
|
||||
// User entscheidet selbst via Button.
|
||||
|
||||
} catch {
|
||||
await MainActor.run {
|
||||
@ -226,14 +223,15 @@ struct MacRegistrationView: View {
|
||||
do {
|
||||
try await MacProfileInstaller.downloadAndInstall(registration: registration)
|
||||
|
||||
// Re-check profile status
|
||||
await checkProfileStatus()
|
||||
|
||||
await MainActor.run {
|
||||
isInstallingProfile = false
|
||||
successMessage = "DNS-Filter-Profil installiert ✓"
|
||||
successMessage = "System Settings → Profile geöffnet. Bitte dort „Installieren" klicken und Admin-Passwort eingeben."
|
||||
}
|
||||
|
||||
// Re-check profile status nach kurzer Wartezeit (User muss in UI bestätigen)
|
||||
try? await Task.sleep(nanoseconds: 3_000_000_000)
|
||||
await checkProfileStatus()
|
||||
|
||||
} catch {
|
||||
await MainActor.run {
|
||||
isInstallingProfile = false
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user