mirror of
https://github.com/ninxsoft/Mist.git
synced 2025-05-20 02:05:39 -04:00
Improve error messaging when installing the Privileged Helper Tool (#103)
* Improve error messaging when installing the Privileged Helper Tool * Squash those linter warnings * Fix typo
This commit is contained in:
parent
29238d1959
commit
c5aea7eddc
5 changed files with 83 additions and 35 deletions
|
@ -10,7 +10,7 @@ import Foundation
|
||||||
/// Helper struct to update a Property List key-pair value.
|
/// Helper struct to update a Property List key-pair value.
|
||||||
struct PropertyListUpdater {
|
struct PropertyListUpdater {
|
||||||
|
|
||||||
/// Edit a key-pair value in a Property List.
|
/// Update a key-pair value in a Property List.
|
||||||
///
|
///
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - url: The URL of the property list to be updated.
|
/// - url: The URL of the property list to be updated.
|
||||||
|
|
|
@ -10,4 +10,5 @@ import SwiftUI
|
||||||
enum FirmwareAlertType: String {
|
enum FirmwareAlertType: String {
|
||||||
case compatibility = "Compatiblity"
|
case compatibility = "Compatiblity"
|
||||||
case helperTool = "Helper Tool"
|
case helperTool = "Helper Tool"
|
||||||
|
case error = "Error"
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,4 +10,5 @@ enum InstallerAlertType: String {
|
||||||
case helperTool = "Helper Tool"
|
case helperTool = "Helper Tool"
|
||||||
case fullDiskAccess = "Full Disk Access"
|
case fullDiskAccess = "Full Disk Access"
|
||||||
case cacheDirectory = "Cache Directory"
|
case cacheDirectory = "Cache Directory"
|
||||||
|
case error = "Error"
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ struct ListRowFirmware: View {
|
||||||
@State private var showAlert: Bool = false
|
@State private var showAlert: Bool = false
|
||||||
@State private var showSavePanel: Bool = false
|
@State private var showSavePanel: Bool = false
|
||||||
@State private var downloading: Bool = false
|
@State private var downloading: Bool = false
|
||||||
|
@State private var error: Error?
|
||||||
private let length: CGFloat = 48
|
private let length: CGFloat = 48
|
||||||
private let spacing: CGFloat = 5
|
private let spacing: CGFloat = 5
|
||||||
private let padding: CGFloat = 3
|
private let padding: CGFloat = 3
|
||||||
|
@ -34,6 +35,14 @@ struct ListRowFirmware: View {
|
||||||
|
|
||||||
return "This macOS Firmware download cannot be used to restore macOS on this \(architecture.description) Mac.\n\nAre you sure you want to continue?"
|
return "This macOS Firmware download cannot be used to restore macOS on this \(architecture.description) Mac.\n\nAre you sure you want to continue?"
|
||||||
}
|
}
|
||||||
|
private var errorMessage: String {
|
||||||
|
|
||||||
|
if let error: BlessError = error as? BlessError {
|
||||||
|
return error.description
|
||||||
|
}
|
||||||
|
|
||||||
|
return error?.localizedDescription ?? ""
|
||||||
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
HStack {
|
HStack {
|
||||||
|
@ -68,10 +77,16 @@ struct ListRowFirmware: View {
|
||||||
case .helperTool:
|
case .helperTool:
|
||||||
return Alert(
|
return Alert(
|
||||||
title: Text("Privileged Helper Tool not installed!"),
|
title: Text("Privileged Helper Tool not installed!"),
|
||||||
message: Text("The Mist Privileged Helper Tool is required to perform Administrator tasks when downloading macOS Firmwares"),
|
message: Text("The Mist Privileged Helper Tool is required to perform Administrator tasks when downloading macOS Firmwares."),
|
||||||
primaryButton: .default(Text("Install...")) { installPrivilegedHelperTool() },
|
primaryButton: .default(Text("Install...")) { Task { installPrivilegedHelperTool() } },
|
||||||
secondaryButton: .default(Text("Cancel"))
|
secondaryButton: .default(Text("Cancel"))
|
||||||
)
|
)
|
||||||
|
case .error:
|
||||||
|
return Alert(
|
||||||
|
title: Text("An error has occured!"),
|
||||||
|
message: Text(errorMessage),
|
||||||
|
dismissButton: .default(Text("OK"))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onChange(of: showSavePanel) { boolean in
|
.onChange(of: showSavePanel) { boolean in
|
||||||
|
@ -132,7 +147,13 @@ struct ListRowFirmware: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func installPrivilegedHelperTool() {
|
private func installPrivilegedHelperTool() {
|
||||||
try? PrivilegedHelperManager.shared.authorizeAndBless()
|
do {
|
||||||
|
try PrivilegedHelperManager.shared.authorizeAndBless()
|
||||||
|
} catch {
|
||||||
|
self.error = error
|
||||||
|
alertType = .error
|
||||||
|
showAlert = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ struct ListRowInstaller: View {
|
||||||
@State private var showOpenPanel: Bool = false
|
@State private var showOpenPanel: Bool = false
|
||||||
@State private var exports: [InstallerExportType] = []
|
@State private var exports: [InstallerExportType] = []
|
||||||
@State private var volume: InstallerVolume?
|
@State private var volume: InstallerVolume?
|
||||||
|
@State private var error: Error?
|
||||||
private let length: CGFloat = 48
|
private let length: CGFloat = 48
|
||||||
private let spacing: CGFloat = 5
|
private let spacing: CGFloat = 5
|
||||||
private let padding: CGFloat = 3
|
private let padding: CGFloat = 3
|
||||||
|
@ -62,6 +63,14 @@ struct ListRowInstaller: View {
|
||||||
private var cacheDirectoryMessage: String {
|
private var cacheDirectoryMessage: String {
|
||||||
"The cache directory has incorrect ownership and/or permissions, which will cause issues caching macOS Installers.\n\nRepair the cache directory ownership and/or permissions and try again."
|
"The cache directory has incorrect ownership and/or permissions, which will cause issues caching macOS Installers.\n\nRepair the cache directory ownership and/or permissions and try again."
|
||||||
}
|
}
|
||||||
|
private var errorMessage: String {
|
||||||
|
|
||||||
|
if let error: BlessError = error as? BlessError {
|
||||||
|
return error.description
|
||||||
|
}
|
||||||
|
|
||||||
|
return error?.localizedDescription ?? ""
|
||||||
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
HStack {
|
HStack {
|
||||||
|
@ -97,36 +106,7 @@ struct ListRowInstaller: View {
|
||||||
.clipShape(Capsule())
|
.clipShape(Capsule())
|
||||||
}
|
}
|
||||||
.alert(isPresented: $showAlert) {
|
.alert(isPresented: $showAlert) {
|
||||||
switch alertType {
|
alert(for: alertType)
|
||||||
case .compatibility:
|
|
||||||
return Alert(
|
|
||||||
title: Text("macOS Installer not compatible!"),
|
|
||||||
message: Text(compatibilityMessage),
|
|
||||||
primaryButton: .default(Text("Cancel")),
|
|
||||||
secondaryButton: .default(Text("Continue")) { Task { validate() } }
|
|
||||||
)
|
|
||||||
case .helperTool:
|
|
||||||
return Alert(
|
|
||||||
title: Text("Privileged Helper Tool not installed!"),
|
|
||||||
message: Text("The Mist Privileged Helper Tool is required to perform Administrator tasks when creating macOS Installers."),
|
|
||||||
primaryButton: .default(Text("Install...")) { installPrivilegedHelperTool() },
|
|
||||||
secondaryButton: .default(Text("Cancel"))
|
|
||||||
)
|
|
||||||
case .fullDiskAccess:
|
|
||||||
return Alert(
|
|
||||||
title: Text("Full Disk Access required!"),
|
|
||||||
message: Text("Mist requires Full Disk Access to perform Administrator tasks when creating macOS Installers."),
|
|
||||||
primaryButton: .default(Text("Allow...")) { openFullDiskAccessPreferences() },
|
|
||||||
secondaryButton: .default(Text("Cancel"))
|
|
||||||
)
|
|
||||||
case .cacheDirectory:
|
|
||||||
return Alert(
|
|
||||||
title: Text("Cache directory settings incorrect!"),
|
|
||||||
message: Text(cacheDirectoryMessage),
|
|
||||||
primaryButton: .default(Text("Repair...")) { Task { try await repairCacheDirectoryOwnershipAndPermissions() } },
|
|
||||||
secondaryButton: .default(Text("Cancel"))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.onChange(of: showOpenPanel) { boolean in
|
.onChange(of: showOpenPanel) { boolean in
|
||||||
|
|
||||||
|
@ -309,7 +289,13 @@ struct ListRowInstaller: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func installPrivilegedHelperTool() {
|
private func installPrivilegedHelperTool() {
|
||||||
try? PrivilegedHelperManager.shared.authorizeAndBless()
|
do {
|
||||||
|
try PrivilegedHelperManager.shared.authorizeAndBless()
|
||||||
|
} catch {
|
||||||
|
self.error = error
|
||||||
|
alertType = .error
|
||||||
|
showAlert = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func openFullDiskAccessPreferences() {
|
private func openFullDiskAccessPreferences() {
|
||||||
|
@ -326,6 +312,45 @@ struct ListRowInstaller: View {
|
||||||
let ownerAccountName: String = NSUserName()
|
let ownerAccountName: String = NSUserName()
|
||||||
try await FileAttributesUpdater.update(url: url, ownerAccountName: ownerAccountName)
|
try await FileAttributesUpdater.update(url: url, ownerAccountName: ownerAccountName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func alert(for alertType: InstallerAlertType) -> Alert {
|
||||||
|
switch alertType {
|
||||||
|
case .compatibility:
|
||||||
|
return Alert(
|
||||||
|
title: Text("macOS Installer not compatible!"),
|
||||||
|
message: Text(compatibilityMessage),
|
||||||
|
primaryButton: .default(Text("Cancel")),
|
||||||
|
secondaryButton: .default(Text("Continue")) { Task { validate() } }
|
||||||
|
)
|
||||||
|
case .helperTool:
|
||||||
|
return Alert(
|
||||||
|
title: Text("Privileged Helper Tool not installed!"),
|
||||||
|
message: Text("The Mist Privileged Helper Tool is required to perform Administrator tasks when creating macOS Installers."),
|
||||||
|
primaryButton: .default(Text("Install...")) { Task { installPrivilegedHelperTool() } },
|
||||||
|
secondaryButton: .default(Text("Cancel"))
|
||||||
|
)
|
||||||
|
case .fullDiskAccess:
|
||||||
|
return Alert(
|
||||||
|
title: Text("Full Disk Access required!"),
|
||||||
|
message: Text("Mist requires Full Disk Access to perform Administrator tasks when creating macOS Installers."),
|
||||||
|
primaryButton: .default(Text("Allow...")) { openFullDiskAccessPreferences() },
|
||||||
|
secondaryButton: .default(Text("Cancel"))
|
||||||
|
)
|
||||||
|
case .cacheDirectory:
|
||||||
|
return Alert(
|
||||||
|
title: Text("Cache directory settings incorrect!"),
|
||||||
|
message: Text(cacheDirectoryMessage),
|
||||||
|
primaryButton: .default(Text("Repair...")) { Task { try await repairCacheDirectoryOwnershipAndPermissions() } },
|
||||||
|
secondaryButton: .default(Text("Cancel"))
|
||||||
|
)
|
||||||
|
case .error:
|
||||||
|
return Alert(
|
||||||
|
title: Text("An error has occured!"),
|
||||||
|
message: Text(errorMessage),
|
||||||
|
dismissButton: .default(Text("OK"))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ListRowInstaller_Previews: PreviewProvider {
|
struct ListRowInstaller_Previews: PreviewProvider {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue