aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoopesh Chander <roop@roopc.net>2019-10-31 15:05:58 +0530
committerRoopesh Chander <roop@roopc.net>2019-11-03 15:51:51 +0530
commit9b087ed5c6cbd27210bc16ff47eade6190eeca71 (patch)
tree8f66f1521760c2ad3b501003e587237995fb57b8
parentTunnelsManager: Workaround for macOS Catalina deleting tunnels arbitrarily (diff)
downloadwireguard-apple-rc/catalinaworkaround.tar.xz
wireguard-apple-rc/catalinaworkaround.zip
TunnelsManager: Workaround for macOS Catalina: Show confirmation alertrc/catalinaworkaround
When reinstating from zero tunnels, macOS will show the VPN prompt (“WireGuard” Would Like to Add VPN Configurations). Before that prompt, we show a confirmation alert to make it clear to the user what the VPN prompt is for. The text of this prompt is not localized because this is expected to be a temporary workaround.
-rw-r--r--WireGuard/WireGuard/Tunnel/TunnelsManager.swift31
-rw-r--r--WireGuard/WireGuard/UI/macOS/AppDelegate.swift27
2 files changed, 57 insertions, 1 deletions
diff --git a/WireGuard/WireGuard/Tunnel/TunnelsManager.swift b/WireGuard/WireGuard/Tunnel/TunnelsManager.swift
index ba14a3b9..a4172793 100644
--- a/WireGuard/WireGuard/Tunnel/TunnelsManager.swift
+++ b/WireGuard/WireGuard/Tunnel/TunnelsManager.swift
@@ -662,6 +662,11 @@ extension NETunnelProviderManager {
#if os(macOS)
@available(macOS 10.15, *)
+protocol CatalinaWorkaroundUIDelegate: class {
+ func shouldReinstateAllTunnelsDeletedOutsideApp(completion: @escaping (Bool) -> Void)
+}
+
+@available(macOS 10.15, *)
class CatalinaWorkaround {
// In macOS Catalina, for some users, the tunnels get deleted arbitrarily
@@ -672,6 +677,7 @@ class CatalinaWorkaround {
// in the keychain.
unowned let tunnelsManager: TunnelsManager
+ weak var uiDelegate: CatalinaWorkaroundUIDelegate?
private var configChangeSubscriber: Any?
struct ReinstationData {
@@ -701,7 +707,16 @@ class CatalinaWorkaround {
func reinstateTunnelsDeletedOutsideApp() {
let rd = reinstationDataForTunnelsDeletedOutsideApp()
- reinstateTunnels(ArraySlice(rd), completionHandler: nil)
+ guard !rd.isEmpty else { return }
+ if self.tunnelsManager.tunnels.isEmpty {
+ uiDelegate?.shouldReinstateAllTunnelsDeletedOutsideApp { [weak self] shouldReinstate in
+ if shouldReinstate {
+ self?.reinstateTunnels(ArraySlice(rd), completionHandler: nil)
+ }
+ }
+ } else {
+ reinstateTunnels(ArraySlice(rd), completionHandler: nil)
+ }
}
private func reinstateTunnels(_ rdArray: ArraySlice<ReinstationData>, completionHandler: (() -> Void)?) {
@@ -752,6 +767,20 @@ class CatalinaWorkaround {
#if os(macOS)
@available(macOS 10.15, *)
extension TunnelsManager {
+ var catalinaWorkaroundUIDelegate: CatalinaWorkaroundUIDelegate? {
+ get {
+ return (self.catalinaWorkaround as? CatalinaWorkaround)?.uiDelegate
+ }
+ set(value) {
+ if let cw = (self.catalinaWorkaround as? CatalinaWorkaround) {
+ cw.uiDelegate = value
+ DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) { [weak cw] in
+ cw?.reinstateTunnelsDeletedOutsideApp()
+ }
+ }
+ }
+ }
+
fileprivate func reinstateTunnel(reinstationData: CatalinaWorkaround.ReinstationData, completionHandler: @escaping (Bool) -> Void) {
let tunnelName = reinstationData.tunnelConfiguration.name ?? ""
if tunnelName.isEmpty {
diff --git a/WireGuard/WireGuard/UI/macOS/AppDelegate.swift b/WireGuard/WireGuard/UI/macOS/AppDelegate.swift
index cb240230..c66ffa1b 100644
--- a/WireGuard/WireGuard/UI/macOS/AppDelegate.swift
+++ b/WireGuard/WireGuard/UI/macOS/AppDelegate.swift
@@ -58,6 +58,10 @@ class AppDelegate: NSObject, NSApplicationDelegate {
self.tunnelsTracker = tunnelsTracker
self.statusItemController = statusItemController
+ if #available(macOS 10.15, *) {
+ tunnelsManager.catalinaWorkaroundUIDelegate = self
+ }
+
if !isLaunchedAtLogin {
self.showManageTunnelsWindow(completion: nil)
}
@@ -249,3 +253,26 @@ func registerLoginItem(shouldLaunchAtLogin: Bool) -> Bool {
let helperBundleId = "\(appId).login-item-helper"
return SMLoginItemSetEnabled(helperBundleId as CFString, shouldLaunchAtLogin)
}
+
+@available(macOS 10.15, *)
+extension AppDelegate: CatalinaWorkaroundUIDelegate {
+ func shouldReinstateAllTunnelsDeletedOutsideApp(completion: @escaping (Bool) -> Void) {
+ let alert = NSAlert()
+ alert.messageText = "Restoring all tunnels"
+ alert.informativeText = "All tunnels have been deleted outside the app. Do you want to restore all the tunnels?"
+
+ alert.addButton(withTitle: "Restore All")
+ alert.addButton(withTitle: "Cancel")
+
+ NSApp.activate(ignoringOtherApps: true)
+ if let manageWindow = manageTunnelsWindowObject {
+ manageWindow.orderFront(self)
+ alert.beginSheetModal(for: manageWindow) { response in
+ completion(response == .alertFirstButtonReturn)
+ }
+ } else {
+ let response = alert.runModal()
+ completion(response == .alertFirstButtonReturn)
+ }
+ }
+}