Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions Sources/HelperManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ final class HelperManager: ObservableObject {
// binary. For updates we must always go through the legacy path which does
// the actual file copy. Only use SMAppService for first-time installs.
let helperPath = "/Library/PrivilegedHelperTools/\(kHelperToolMachServiceName)"
let plistPath = "/Library/LaunchDaemons/\(kHelperToolMachServiceName).plist"
if FileManager.default.fileExists(atPath: helperPath) {
print("🔐 Helper exists on disk, using legacy path for update...")
return installHelperLegacy()
Expand All @@ -268,12 +269,22 @@ final class HelperManager: ObservableObject {
let service = SMAppService.daemon(plistName: "\(kHelperToolMachServiceName).plist")
try await service.register()

installationError = nil
print("✅ Helper registered successfully via SMAppService")

// SMAppService.register() can report success without actually placing the
// binary/plist on disk (observed with enterprise security tools like Zscaler).
// Verify both files exist before trusting the registration.
if !FileManager.default.fileExists(atPath: helperPath) ||
!FileManager.default.fileExists(atPath: plistPath) {
print("⚠️ SMAppService reported success but helper files missing on disk, falling back to legacy install...")
return installHelperLegacy()
}

installationError = nil
Comment thread
coderabbitai[bot] marked this conversation as resolved.
return true
} catch {
print("⚠️ SMAppService failed: \(error.localizedDescription)")
print("🔐 Falling back to legacy SMJobBless...")
print("🔐 Falling back to legacy install...")
return installHelperLegacy()
}
}
Expand Down
Loading