Skip to content

Commit a5305cd

Browse files
committed
Merge branch 'main' into colin/xpc
2 parents 11a79a9 + 06b4c16 commit a5305cd

24 files changed

+673
-170
lines changed

Coder Desktop/Coder Desktop.xcodeproj/project.pbxproj

Lines changed: 153 additions & 36 deletions
Large diffs are not rendered by default.

Coder Desktop/Coder Desktop.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"originHash" : "ec40e522ec1a2416e8e8f5cbe97424ab3e4a614e6ef453c10ea28e84e88b6771",
2+
"originHash" : "c41f63aa01c78f450e2232efbefcd30874995ad120db77fa5942062d6f813891",
33
"pins" : [
44
{
55
"identity" : "fluid-menu-bar-extra",
@@ -18,6 +18,15 @@
1818
"revision" : "e0c7eebc5a4465a3c4680764f26b7a61f567cdaf"
1919
}
2020
},
21+
{
22+
"identity" : "launchatlogin-modern",
23+
"kind" : "remoteSourceControl",
24+
"location" : "https://github.com/sindresorhus/LaunchAtLogin-modern",
25+
"state" : {
26+
"revision" : "a04ec1c363be3627734f6dad757d82f5d4fa8fcc",
27+
"version" : "1.1.0"
28+
}
29+
},
2130
{
2231
"identity" : "mocker",
2332
"kind" : "remoteSourceControl",
@@ -41,8 +50,8 @@
4150
"kind" : "remoteSourceControl",
4251
"location" : "https://github.com/SimplyDanny/SwiftLintPlugins",
4352
"state" : {
44-
"revision" : "f9731bef175c3eea3a0ca960f1be78fcc2bc7853",
45-
"version" : "0.57.1"
53+
"revision" : "fac0c3d3ac69b15ea5382275dbbd5e583a2e05fa",
54+
"version" : "0.58.0"
4655
}
4756
},
4857
{

Coder Desktop/Coder Desktop/About.swift

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,7 @@ enum About {
3232

3333
@MainActor
3434
static func open() {
35-
#if compiler(>=5.9) && canImport(AppKit)
36-
if #available(macOS 14, *) {
37-
NSApp.activate()
38-
} else {
39-
NSApp.activate(ignoringOtherApps: true)
40-
}
41-
#else
42-
NSApp.activate(ignoringOtherApps: true)
43-
#endif
35+
appActivate()
4436
NSApp.orderFrontStandardAboutPanel(options: [
4537
.credits: credits,
4638
])

Coder Desktop/Coder Desktop/Coder_DesktopApp.swift

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,39 @@ struct DesktopApp: App {
1111
EmptyView()
1212
}
1313
Window("Sign In", id: Windows.login.rawValue) {
14-
LoginForm<PreviewSession>()
15-
}.environmentObject(appDelegate.session)
16-
.windowResizability(.contentSize)
14+
LoginForm<SecureSession>()
15+
.environmentObject(appDelegate.session)
16+
.environmentObject(appDelegate.settings)
17+
}
18+
.windowResizability(.contentSize)
19+
SwiftUI.Settings {
20+
SettingsView<CoderVPNService>()
21+
.environmentObject(appDelegate.vpn)
22+
.environmentObject(appDelegate.settings)
23+
}
24+
.windowResizability(.contentSize)
1725
}
1826
}
1927

2028
@MainActor
2129
class AppDelegate: NSObject, NSApplicationDelegate {
2230
private var menuBarExtra: FluidMenuBarExtra?
2331
let vpn: CoderVPNService
24-
let session: PreviewSession
32+
let session: SecureSession
33+
let settings: Settings
2534

2635
override init() {
2736
vpn = CoderVPNService()
28-
// TODO: Replace with real implementations
29-
session = PreviewSession()
37+
settings = Settings()
38+
session = SecureSession(onChange: vpn.configureTunnelProviderProtocol)
3039
}
3140

3241
func applicationDidFinishLaunching(_: Notification) {
3342
menuBarExtra = FluidMenuBarExtra(title: "Coder Desktop", image: "MenuBarIcon") {
34-
VPNMenu<CoderVPNService, PreviewSession>().frame(width: 256)
43+
VPNMenu<CoderVPNService, SecureSession>().frame(width: 256)
3544
.environmentObject(self.vpn)
3645
.environmentObject(self.session)
46+
.environmentObject(self.settings)
3747
}
3848
}
3949

@@ -49,3 +59,8 @@ class AppDelegate: NSObject, NSApplicationDelegate {
4959
false
5060
}
5161
}
62+
63+
@MainActor
64+
func appActivate() {
65+
NSApp.activate()
66+
}

Coder Desktop/Coder Desktop/NetworkExtension.swift

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@ import os
33

44
enum NetworkExtensionState: Equatable {
55
case unconfigured
6-
case disbled
6+
case disabled
77
case enabled
88
case failed(String)
99

1010
var description: String {
1111
switch self {
1212
case .unconfigured:
13-
return "Not logged in to Coder"
13+
return "NetworkExtension not configured, try logging in again"
1414
case .enabled:
1515
return "NetworkExtension tunnel enabled"
16-
case .disbled:
16+
case .disabled:
1717
return "NetworkExtension tunnel disabled"
1818
case let .failed(error):
1919
return "NetworkExtension config failed: \(error)"
@@ -24,6 +24,16 @@ enum NetworkExtensionState: Equatable {
2424
/// An actor that handles configuring, enabling, and disabling the VPN tunnel via the
2525
/// NetworkExtension APIs.
2626
extension CoderVPNService {
27+
// Updates the UI if a previous configuration exists
28+
func loadNetworkExtension() async {
29+
do {
30+
try await getTunnelManager()
31+
neState = .disabled
32+
} catch {
33+
neState = .unconfigured
34+
}
35+
}
36+
2737
func configureNetworkExtension(proto: NETunnelProviderProtocol) async {
2838
// removing the old tunnels, rather than reconfiguring ensures that configuration changes
2939
// are picked up.
@@ -47,6 +57,7 @@ extension CoderVPNService {
4757
logger.error("save tunnel failed: \(error)")
4858
neState = .failed(error.localizedDescription)
4959
}
60+
neState = .disabled
5061
}
5162

5263
func removeNetworkExtension() async throws(VPNServiceError) {
@@ -91,9 +102,10 @@ extension CoderVPNService {
91102
return
92103
}
93104
logger.debug("saved tunnel with enabled=false")
94-
neState = .disbled
105+
neState = .disabled
95106
}
96107

108+
@discardableResult
97109
private func getTunnelManager() async throws(VPNServiceError) -> NETunnelProviderManager {
98110
var tunnels: [NETunnelProviderManager] = []
99111
do {

Coder Desktop/Coder Desktop/Session.swift renamed to Coder Desktop/Coder Desktop/State.swift

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import CoderSDK
12
import Foundation
23
import KeychainAccess
34
import NetworkExtension
5+
import SwiftUI
46

57
protocol Session: ObservableObject {
68
var hasSession: Bool { get }
@@ -89,3 +91,47 @@ class SecureSession: ObservableObject, Session {
8991
static let sessionToken = "sessionToken"
9092
}
9193
}
94+
95+
class Settings: ObservableObject {
96+
private let store: UserDefaults
97+
@AppStorage(Keys.useLiteralHeaders) var useLiteralHeaders = false
98+
99+
@Published var literalHeaders: [LiteralHeader] {
100+
didSet {
101+
try? store.set(JSONEncoder().encode(literalHeaders), forKey: Keys.literalHeaders)
102+
}
103+
}
104+
105+
init(store: UserDefaults = .standard) {
106+
self.store = store
107+
_literalHeaders = Published(
108+
initialValue: store.data(
109+
forKey: Keys.literalHeaders
110+
).flatMap { try? JSONDecoder().decode([LiteralHeader].self, from: $0) } ?? []
111+
)
112+
}
113+
114+
enum Keys {
115+
static let useLiteralHeaders = "UseLiteralHeaders"
116+
static let literalHeaders = "LiteralHeaders"
117+
}
118+
}
119+
120+
struct LiteralHeader: Hashable, Identifiable, Equatable, Codable {
121+
var header: String
122+
var value: String
123+
var id: String {
124+
"\(header):\(value)"
125+
}
126+
127+
init(header: String, value: String) {
128+
self.header = header
129+
self.value = value
130+
}
131+
}
132+
133+
extension LiteralHeader {
134+
func toSDKHeader() -> HTTPHeader {
135+
return .init(header: header, value: value)
136+
}
137+
}

Coder Desktop/Coder Desktop/VPNService.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ final class CoderVPNService: NSObject, VPNService {
5252
guard sysExtnState == .installed else {
5353
return .failed(.systemExtensionError(sysExtnState))
5454
}
55-
guard neState == .enabled || neState == .disbled else {
55+
guard neState == .enabled || neState == .disabled else {
5656
return .failed(.networkExtensionError(neState))
5757
}
5858
return tunnelState
@@ -72,6 +72,9 @@ final class CoderVPNService: NSObject, VPNService {
7272

7373
super.init()
7474
installSystemExtension()
75+
Task {
76+
await loadNetworkExtension()
77+
}
7578
}
7679

7780
var startTask: Task<Void, Never>?

0 commit comments

Comments
 (0)