feat(apple): Disable the update checker for MDM and App store (#9167)

For App Store installed macOS clients, it doesn't make sense to run an
update checker, because the system is managing the updates, and will
notify the user if there's an update available for Firezone (the user
has configured the system to manage app updates).

Related: #7664 
Related: #4505
This commit is contained in:
Jamil
2025-05-16 02:27:57 -07:00
committed by GitHub
parent e599eb2f09
commit 9951e82727
3 changed files with 46 additions and 9 deletions

View File

@@ -13,6 +13,7 @@ public class Configuration: Codable {
public static let defaultAccountSlug = ""
public static let defaultConnectOnStart = true
public static let defaultDisableUpdateCheck = false
public struct Keys {
public static let authURL = "authURL"
@@ -23,6 +24,7 @@ public class Configuration: Codable {
public static let firezoneId = "firezoneId"
public static let hideAdminPortalMenuItem = "hideAdminPortalMenuItem"
public static let connectOnStart = "connectOnStart"
public static let disableUpdateCheck = "disableUpdateCheck"
}
public var authURL: String?
@@ -33,6 +35,7 @@ public class Configuration: Codable {
public var internetResourceEnabled: Bool?
public var hideAdminPortalMenuItem: Bool?
public var connectOnStart: Bool?
public var disableUpdateCheck: Bool?
private var overriddenKeys: Set<String> = []
@@ -52,6 +55,9 @@ public class Configuration: Codable {
setValue(forKey: Keys.connectOnStart, from: managedDict, and: userDict) { [weak self] in
self?.connectOnStart = $0
}
setValue(forKey: Keys.disableUpdateCheck, from: managedDict, and: userDict) { [weak self] in
self?.disableUpdateCheck = $0
}
}
func isOverridden(_ key: String) -> Bool {

View File

@@ -25,7 +25,7 @@ public final class MenuBar: NSObject, ObservableObject {
var lastShownOthers: [Resource] = []
var wasInternetResourceEnabled: Bool?
var cancellables: Set<AnyCancellable> = []
var updateChecker: UpdateChecker = UpdateChecker()
var updateChecker: UpdateChecker
var updateMenuDisplayed: Bool = false
var signedOutIcon: NSImage?
var signedInConnectedIcon: NSImage?
@@ -167,6 +167,7 @@ public final class MenuBar: NSObject, ObservableObject {
public init(store: Store) {
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
self.store = store
self.updateChecker = UpdateChecker(store: store)
self.signedOutIcon = NSImage(named: "MenuBarIconSignedOut")
self.signedInConnectedIcon = NSImage(named: "MenuBarIconSignedInConnected")
self.signedOutIconNotification = NSImage(named: "MenuBarIconSignedOutNotification")

View File

@@ -7,9 +7,11 @@
// Note: it should be easy to expand this module to iOS
#if os(macOS)
import Foundation
import Combine
import UserNotifications
import Cocoa
@MainActor
class UpdateChecker {
enum UpdateError: Error {
case invalidVersion(String)
@@ -26,10 +28,13 @@ class UpdateChecker {
private let notificationAdapter: NotificationAdapter = NotificationAdapter()
private let versionCheckUrl: URL
private let marketingVersion: SemanticVersion
private let store: Store
@MainActor @Published private(set) var updateAvailable: Bool = false
private var cancellables: Set<AnyCancellable> = []
init() {
@Published private(set) var updateAvailable: Bool = false
init(store: Store) {
guard let versionCheckUrl = URL(string: "https://www.firezone.dev/api/releases"),
let versionString = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String,
let marketingVersion = try? SemanticVersion(versionString)
@@ -40,20 +45,49 @@ class UpdateChecker {
self.versionCheckUrl = versionCheckUrl
self.marketingVersion = marketingVersion
startCheckingForUpdates()
self.store = store
store.$configuration
.receive(on: RunLoop.main)
.sink { [weak self] _ in
self?.handleConfigurationChange()
}
.store(in: &cancellables)
handleConfigurationChange()
}
private func handleConfigurationChange() {
let disabled = (
store.configuration?.disableUpdateCheck ?? Configuration.defaultDisableUpdateCheck
) || BundleHelper.isAppStore()
if disabled {
stopCheckingForUpdates()
} else {
startCheckingForUpdates()
}
}
private func startCheckingForUpdates() {
timer = Timer.scheduledTimer(
guard timer == nil else { return }
self.timer = Timer.scheduledTimer(
timeInterval: 6 * 60 * 60,
target: self,
selector: #selector(checkForUpdates),
userInfo: nil,
repeats: true
)
checkForUpdates()
}
private func stopCheckingForUpdates() {
timer?.invalidate()
self.timer = nil
}
deinit {
timer?.invalidate()
}
@@ -110,10 +144,6 @@ class UpdateChecker {
}
static func downloadURL() -> URL {
if BundleHelper.isAppStore() {
return URL(string: "https://apps.apple.com/app/firezone/id6443661826")!
}
return URL(string: "https://www.firezone.dev/dl/firezone-client-macos/latest")!
}
}