mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 18:18:55 +00:00
macOS: Don't sign out on rebooting the Mac (#2816)
Fixes #2809. Tested the case where the user: - while being signed in and connected in the Firezone app, logs out of macOS - logs in as another user In the above case, the app: - sees that there's a token reference stored in the tunnel, but is unable to access the token (the token is per user) - so the app signs the user out This PR is stacked on top of PR #2804.
This commit is contained in:
@@ -39,6 +39,7 @@ public struct TunnelShutdownEvent: Codable, CustomStringConvertible {
|
||||
}
|
||||
|
||||
public enum Action {
|
||||
case doNothing
|
||||
case signoutImmediately
|
||||
case retryThenSignout
|
||||
}
|
||||
@@ -50,8 +51,10 @@ public struct TunnelShutdownEvent: Codable, CustomStringConvertible {
|
||||
public var action: Action {
|
||||
switch reason {
|
||||
case .stopped(let reason):
|
||||
if reason == .userInitiated || reason == .userLogout || reason == .userSwitch {
|
||||
if reason == .userInitiated {
|
||||
return .signoutImmediately
|
||||
} else if reason == .userLogout || reason == .userSwitch {
|
||||
return .doNothing
|
||||
} else {
|
||||
return .retryThenSignout
|
||||
}
|
||||
|
||||
@@ -88,6 +88,9 @@ final class AuthStore: ObservableObject {
|
||||
.sink { [weak self] status in
|
||||
guard let self = self else { return }
|
||||
Task {
|
||||
if status == .disconnected {
|
||||
self.handleTunnelDisconnectionEvent()
|
||||
}
|
||||
if status == .connected {
|
||||
self.resetReconnectionAttemptsRemaining()
|
||||
}
|
||||
@@ -170,26 +173,40 @@ final class AuthStore: ObservableObject {
|
||||
do {
|
||||
try await tunnelStore.start()
|
||||
} catch {
|
||||
logger.error("\(#function): Error starting tunnel: \(String(describing: error))")
|
||||
if let tsEvent = TunnelShutdownEvent.loadFromDisk() {
|
||||
self.logger.log(
|
||||
"\(#function): Tunnel shutdown event: \(tsEvent, privacy: .public)"
|
||||
if case TunnelStoreError.startTunnelErrored(let startTunnelError) = error {
|
||||
logger.error(
|
||||
"\(#function): Starting tunnel errored: \(String(describing: startTunnelError))"
|
||||
)
|
||||
switch tsEvent.action {
|
||||
case .signoutImmediately:
|
||||
Task {
|
||||
await self.signOut()
|
||||
}
|
||||
case .retryThenSignout:
|
||||
self.retryStartTunnel()
|
||||
}
|
||||
handleTunnelDisconnectionEvent()
|
||||
} else {
|
||||
self.logger.log("\(#function): Tunnel shutdown event not found")
|
||||
logger.error("\(#function): Starting tunnel failed: \(String(describing: error))")
|
||||
// Disconnection event will be handled in the tunnel status change handler
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handleTunnelDisconnectionEvent() {
|
||||
logger.log("\(#function)")
|
||||
if let tsEvent = TunnelShutdownEvent.loadFromDisk() {
|
||||
self.logger.log(
|
||||
"\(#function): Tunnel shutdown event: \(tsEvent, privacy: .public)"
|
||||
)
|
||||
switch tsEvent.action {
|
||||
case .signoutImmediately:
|
||||
Task {
|
||||
await self.signOut()
|
||||
}
|
||||
case .retryThenSignout:
|
||||
self.retryStartTunnel()
|
||||
case .doNothing:
|
||||
break
|
||||
}
|
||||
} else {
|
||||
self.logger.log("\(#function): Tunnel shutdown event not found")
|
||||
}
|
||||
}
|
||||
|
||||
func retryStartTunnel() {
|
||||
// Try to reconnect, but don't try more than 3 times at a time.
|
||||
// If this gets called the third time, sign out.
|
||||
|
||||
@@ -15,6 +15,7 @@ enum TunnelStoreError: Error {
|
||||
case cannotSaveToTunnelWhenConnected
|
||||
case cannotSignOutWhenConnected
|
||||
case stopAlreadyBeingAttempted
|
||||
case startTunnelErrored(Error)
|
||||
}
|
||||
|
||||
public struct TunnelProviderKeys {
|
||||
@@ -173,7 +174,11 @@ final class TunnelStore: ObservableObject {
|
||||
try await tunnel.loadFromPreferences()
|
||||
|
||||
let session = castToSession(tunnel.connection)
|
||||
try session.startTunnel()
|
||||
do {
|
||||
try session.startTunnel()
|
||||
} catch {
|
||||
throw TunnelStoreError.startTunnelErrored(error)
|
||||
}
|
||||
try await withCheckedThrowingContinuation { continuation in
|
||||
self.startTunnelContinuation = continuation
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user