From 3db1af07f13b05ce2bf4e5ddcf0e78dadc5ddf78 Mon Sep 17 00:00:00 2001 From: Diego Rey Mendez Date: Thu, 30 May 2024 11:15:14 +0200 Subject: [PATCH] Fixes some VPN uninstallation issues (#2820) Task/Issue URL: https://app.asana.com/0/1206580121312550/1207431594119528/f ## Description Fixes some VPN uninstallation issues in v1.90.0. --- .../NetworkProtectionTunnelController.swift | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionTunnelController.swift b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionTunnelController.swift index 44394aa36f..8610b020c7 100644 --- a/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionTunnelController.swift +++ b/DuckDuckGo/NetworkProtection/AppTargets/BothAppTargets/NetworkProtectionTunnelController.swift @@ -37,6 +37,7 @@ import Subscription typealias NetworkProtectionStatusChangeHandler = (NetworkProtection.ConnectionStatus) -> Void typealias NetworkProtectionConfigChangeHandler = () -> Void +// swiftlint:disable:next type_body_length final class NetworkProtectionTunnelController: TunnelController, TunnelSessionProvider { // MARK: - Settings @@ -94,6 +95,13 @@ final class NetworkProtectionTunnelController: TunnelController, TunnelSessionPr /// private var internalManager: NETunnelProviderManager? + /// Simply clears the internal manager so the VPN manager is reloaded next time it's requested. + /// + @MainActor + private func clearInternalManager() { + internalManager = nil + } + /// The last known VPN status. /// /// Should not be used for checking the current status. @@ -178,6 +186,7 @@ final class NetworkProtectionTunnelController: TunnelController, TunnelSessionPr subscribeToSettingsChanges() subscribeToStatusChanges() + subscribeToConfigurationChanges() } // MARK: - Observing Status Changes @@ -209,6 +218,31 @@ final class NetworkProtectionTunnelController: TunnelController, TunnelSessionPr } } + // MARK: - Observing Configuation Changes + + private func subscribeToConfigurationChanges() { + notificationCenter.publisher(for: .NEVPNConfigurationChange) + .receive(on: DispatchQueue.main) + .sink { _ in + Task { @MainActor in + guard let manager = await self.manager else { + return + } + + do { + try await manager.loadFromPreferences() + + if manager.connection.status == .invalid { + self.clearInternalManager() + } + } catch { + self.clearInternalManager() + } + } + } + .store(in: &cancellables) + } + // MARK: - Subscriptions private func subscribeToSettingsChanges() { @@ -693,6 +727,14 @@ final class NetworkProtectionTunnelController: TunnelController, TunnelSessionPr func disableOnDemand(tunnelManager: NETunnelProviderManager) async throws { try await tunnelManager.loadFromPreferences() + guard tunnelManager.connection.status != .invalid else { + // An invalid connection status means the VPN isn't really configured + // so we don't want to save changed because that would re-create the VPN + // configuration. + clearInternalManager() + return + } + tunnelManager.isOnDemandEnabled = false try await tunnelManager.saveToPreferences()