Skip to content

Commit a906e98

Browse files
chore: reconfigure VPN on reinstall (#84)
1 parent 3a520d5 commit a906e98

File tree

5 files changed

+20
-11
lines changed

5 files changed

+20
-11
lines changed

Coder Desktop/Coder Desktop/Coder_DesktopApp.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,10 @@ class AppDelegate: NSObject, NSApplicationDelegate {
5050
object: nil
5151
)
5252
Task {
53-
// If there's no NE config, then the user needs to sign in.
54-
// However, they might have a session from a previous install, so we
55-
// need to clear it.
53+
// If there's no NE config, but the user is logged in, such as
54+
// from a previous install, then we need to reconfigure.
5655
if await !vpn.loadNetworkExtensionConfig() {
57-
state.clearSession()
56+
state.reconfigure()
5857
}
5958
}
6059
}

Coder Desktop/Coder Desktop/MenuBarIconController.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ class MenuBarController {
1313

1414
init(menuBarExtra: FluidMenuBarExtra) {
1515
self.menuBarExtra = menuBarExtra
16+
// Off by default, as `vpnDidUpdate` isn't called until the VPN is configured
17+
menuBarExtra.setOpacity(offOpacity)
1618
}
1719

1820
func vpnDidUpdate(_ connection: NETunnelProviderSession) {

Coder Desktop/Coder Desktop/State.swift

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ class AppState: ObservableObject {
3232

3333
@Published var useLiteralHeaders: Bool = UserDefaults.standard.bool(forKey: Keys.useLiteralHeaders) {
3434
didSet {
35-
if let onChange { onChange(tunnelProviderProtocol()) }
35+
reconfigure()
3636
guard persistent else { return }
3737
UserDefaults.standard.set(useLiteralHeaders, forKey: Keys.useLiteralHeaders)
3838
}
3939
}
4040

4141
@Published var literalHeaders: [LiteralHeader] {
4242
didSet {
43-
if let onChange { onChange(tunnelProviderProtocol()) }
43+
reconfigure()
4444
guard persistent else { return }
4545
try? UserDefaults.standard.set(JSONEncoder().encode(literalHeaders), forKey: Keys.literalHeaders)
4646
}
@@ -70,9 +70,13 @@ class AppState: ObservableObject {
7070
private let keychain: Keychain
7171
private let persistent: Bool
7272

73-
// This closure must be called when any property used to configure the VPN changes
7473
let onChange: ((NETunnelProviderProtocol?) -> Void)?
7574

75+
// reconfigure must be called when any property used to configure the VPN changes
76+
public func reconfigure() {
77+
if let onChange { onChange(tunnelProviderProtocol()) }
78+
}
79+
7680
public init(onChange: ((NETunnelProviderProtocol?) -> Void)? = nil,
7781
persistent: Bool = true)
7882
{
@@ -97,13 +101,13 @@ class AppState: ObservableObject {
97101
hasSession = true
98102
self.baseAccessURL = baseAccessURL
99103
self.sessionToken = sessionToken
100-
if let onChange { onChange(tunnelProviderProtocol()) }
104+
reconfigure()
101105
}
102106

103107
public func clearSession() {
104108
hasSession = false
105109
sessionToken = nil
106-
if let onChange { onChange(tunnelProviderProtocol()) }
110+
reconfigure()
107111
}
108112

109113
private func keychainGet(for key: String) -> String? {

Coder Desktop/Coder Desktop/Views/LoginForm.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ struct LoginForm: View {
3838
.animation(.easeInOut, value: currentPage)
3939
.onAppear {
4040
baseAccessURL = state.baseAccessURL?.absoluteString ?? baseAccessURL
41-
sessionToken = ""
41+
sessionToken = state.sessionToken ?? sessionToken
4242
}
4343
.alert("Error", isPresented: Binding(
4444
get: { loginError != nil },
@@ -122,7 +122,7 @@ struct LoginForm: View {
122122
).disabled(true)
123123
}
124124
Section {
125-
SecureField("Session Token", text: $sessionToken, prompt: Text("●●●●●●●●"))
125+
SecureField("Session Token", text: $sessionToken)
126126
.autocorrectionDisabled()
127127
.privacySensitive()
128128
.focused($focusedField, equals: .sessionToken)

Coder Desktop/VPN/Manager.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ actor Manager {
3030
let sessionConfig = URLSessionConfiguration.default
3131
// The tunnel might be asked to start before the network interfaces have woken up from sleep
3232
sessionConfig.waitsForConnectivity = true
33+
// URLSession's waiting for connectivity sometimes hangs even when
34+
// the network is up so this is deliberately short (15s) to avoid a
35+
// poor UX where it appears stuck.
36+
sessionConfig.timeoutIntervalForResource = 15
3337
try await download(src: dylibPath, dest: dest, urlSession: URLSession(configuration: sessionConfig))
3438
} catch {
3539
throw .download(error)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy