Add VPN check before heartbeat

This commit is contained in:
Jackson Coxson 2025-03-29 13:35:02 -06:00
parent 40a48852fa
commit 6b71ed5f06
No known key found for this signature in database
GPG key ID: 5EAEF578E866A64B

View file

@ -6,6 +6,7 @@
//
import SwiftUI
import Network
import em_proxy
import UniformTypeIdentifiers
@ -44,26 +45,41 @@ struct HeartbeatApp: App {
.onAppear {
startProxy() { result, error in
if result {
if FileManager.default.fileExists(atPath: URL.documentsDirectory.appendingPathComponent("pairingFile.plist").path) {
Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { timer in
if pubHeartBeat {
isLoading = false
timer.invalidate()
} else {
if let error {
if error == InvalidHostID.rawValue {
isPairing = true
checkVPNConnection() { result, vpn_error in
if result {
if FileManager.default.fileExists(atPath: URL.documentsDirectory.appendingPathComponent("pairingFile.plist").path) {
Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { timer in
if pubHeartBeat {
isLoading = false
timer.invalidate()
} else {
startHeartbeatInBackground()
if let error {
if error == InvalidHostID.rawValue {
isPairing = true
} else {
startHeartbeatInBackground()
}
self.error = nil
}
}
self.error = nil
}
startHeartbeatInBackground()
} else {
isLoading = false
}
} else if let vpn_error {
showAlert(title: "Error", message: "EM Proxy failed to connect: \(vpn_error)", showOk: true) { _ in
// Add code here to exit the application
exit(0) // This will terminate the app immediately
// Or for a more graceful exit in iOS:
// UIApplication.shared.perform(#selector(NSXPCConnection.suspend))
// DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
// exit(0)
// }
}
}
startHeartbeatInBackground()
} else {
isLoading = false
}
} else if let error {
showAlert(title: "Error", message: "EM Proxy Failed to start \(error)", showOk: true) { cool in
@ -137,6 +153,63 @@ struct HeartbeatApp: App {
}
}
}
private func checkVPNConnection(callback: @escaping (Bool, String?) -> Void) {
let host = NWEndpoint.Host("10.7.0.1")
let port = NWEndpoint.Port(rawValue: 62078)!
let connection = NWConnection(host: host, port: port, using: .tcp)
// Create a variable to hold the timeout work item
var timeoutWorkItem: DispatchWorkItem?
timeoutWorkItem = DispatchWorkItem { [weak connection] in
if connection?.state != .ready {
connection?.cancel()
DispatchQueue.main.async {
// Only call back if we haven't already
if timeoutWorkItem?.isCancelled == false {
callback(false, "[TIMEOUT] Wireguard is not connected. Try closing this app, turn Wireguard off and back on.")
}
}
}
}
connection.stateUpdateHandler = { [weak connection] state in
switch state {
case .ready:
// Connection succeeded - cancel the timeout
timeoutWorkItem?.cancel()
connection?.cancel()
DispatchQueue.main.async {
callback(true, nil)
}
case .failed(let error):
// Connection failed - cancel the timeout
timeoutWorkItem?.cancel()
connection?.cancel()
DispatchQueue.main.async {
if error == NWError.posix(.ETIMEDOUT) {
callback(false, "Wireguard is not connected. Try closing the app, turn it off and back on.")
} else if error == NWError.posix(.ECONNREFUSED) {
callback(false, "Wifi is not connected. StikJIT won't work on cellular data.")
} else {
callback(false, "em proxy check error: \(error.localizedDescription)")
}
}
default:
break
}
}
// Start the connection
connection.start(queue: .global())
// Schedule the timeout
if let workItem = timeoutWorkItem {
DispatchQueue.global().asyncAfter(deadline: .now() + 10, execute: workItem)
}
}
}
var pubHeartBeat = false