@@ -4,28 +4,20 @@ import KeychainAccess
4
4
import NetworkExtension
5
5
import SwiftUI
6
6
7
- protocol Session : ObservableObject {
8
- var hasSession : Bool { get }
9
- var baseAccessURL : URL ? { get }
10
- var sessionToken : String ? { get }
11
-
12
- func store( baseAccessURL: URL , sessionToken: String )
13
- func clear( )
14
- func tunnelProviderProtocol( ) -> NETunnelProviderProtocol ?
15
- }
16
-
17
- class SecureSession : ObservableObject , Session {
7
+ class AppState : ObservableObject {
18
8
let appId = Bundle . main. bundleIdentifier!
19
9
20
10
// Stored in UserDefaults
21
11
@Published private( set) var hasSession : Bool {
22
12
didSet {
13
+ guard persistent else { return }
23
14
UserDefaults . standard. set ( hasSession, forKey: Keys . hasSession)
24
15
}
25
16
}
26
17
27
18
@Published private( set) var baseAccessURL : URL ? {
28
19
didSet {
20
+ guard persistent else { return }
29
21
UserDefaults . standard. set ( baseAccessURL, forKey: Keys . baseAccessURL)
30
22
}
31
23
}
@@ -37,6 +29,27 @@ class SecureSession: ObservableObject, Session {
37
29
}
38
30
}
39
31
32
+ @Published var useLiteralHeaders : Bool = UserDefaults . standard. bool ( forKey: Keys . useLiteralHeaders) {
33
+ didSet {
34
+ guard persistent else { return }
35
+ UserDefaults . standard. set ( useLiteralHeaders, forKey: Keys . useLiteralHeaders)
36
+ }
37
+ }
38
+
39
+ @Published var literalHeaders : [ LiteralHeader ] {
40
+ didSet {
41
+ guard persistent else { return }
42
+ try ? UserDefaults . standard. set ( JSONEncoder ( ) . encode ( literalHeaders) , forKey: Keys . literalHeaders)
43
+ }
44
+ }
45
+
46
+ @Published var stopVPNOnQuit : Bool = UserDefaults . standard. bool ( forKey: Keys . stopVPNOnQuit) {
47
+ didSet {
48
+ guard persistent else { return }
49
+ UserDefaults . standard. set ( stopVPNOnQuit, forKey: Keys . stopVPNOnQuit)
50
+ }
51
+ }
52
+
40
53
func tunnelProviderProtocol( ) -> NETunnelProviderProtocol ? {
41
54
if !hasSession { return nil }
42
55
let proto = NETunnelProviderProtocol ( )
@@ -49,37 +62,50 @@ class SecureSession: ObservableObject, Session {
49
62
}
50
63
51
64
private let keychain : Keychain
65
+ private let persistent : Bool
52
66
53
67
let onChange : ( ( NETunnelProviderProtocol ? ) -> Void ) ?
54
68
55
- public init ( onChange: ( ( NETunnelProviderProtocol ? ) -> Void ) ? = nil ) {
69
+ public init ( onChange: ( ( NETunnelProviderProtocol ? ) -> Void ) ? = nil ,
70
+ persistent: Bool = true )
71
+ {
72
+ self . persistent = persistent
56
73
self . onChange = onChange
57
74
keychain = Keychain ( service: Bundle . main. bundleIdentifier!)
58
- _hasSession = Published ( initialValue: UserDefaults . standard. bool ( forKey: Keys . hasSession) )
59
- _baseAccessURL = Published ( initialValue: UserDefaults . standard. url ( forKey: Keys . baseAccessURL) )
75
+ _hasSession = Published ( initialValue: persistent ? UserDefaults . standard. bool ( forKey: Keys . hasSession) : false )
76
+ _baseAccessURL = Published (
77
+ initialValue: persistent ? UserDefaults . standard. url ( forKey: Keys . baseAccessURL) : nil
78
+ )
79
+ _literalHeaders = Published (
80
+ initialValue: persistent ? UserDefaults . standard. data (
81
+ forKey: Keys . literalHeaders
82
+ ) . flatMap { try ? JSONDecoder ( ) . decode ( [ LiteralHeader ] . self, from: $0) } ?? [ ] : [ ]
83
+ )
60
84
if hasSession {
61
85
_sessionToken = Published ( initialValue: keychainGet ( for: Keys . sessionToken) )
62
86
}
63
87
}
64
88
65
- public func store ( baseAccessURL: URL , sessionToken: String ) {
89
+ public func login ( baseAccessURL: URL , sessionToken: String ) {
66
90
hasSession = true
67
91
self . baseAccessURL = baseAccessURL
68
92
self . sessionToken = sessionToken
69
93
if let onChange { onChange ( tunnelProviderProtocol ( ) ) }
70
94
}
71
95
72
- public func clear ( ) {
96
+ public func clearSession ( ) {
73
97
hasSession = false
74
98
sessionToken = nil
75
99
if let onChange { onChange ( tunnelProviderProtocol ( ) ) }
76
100
}
77
101
78
102
private func keychainGet( for key: String ) -> String ? {
79
- try ? keychain. getString ( key)
103
+ guard persistent else { return nil }
104
+ return try ? keychain. getString ( key)
80
105
}
81
106
82
107
private func keychainSet( _ value: String ? , for key: String ) {
108
+ guard persistent else { return }
83
109
if let value {
84
110
try ? keychain. set ( value, key: key)
85
111
} else {
@@ -91,31 +117,7 @@ class SecureSession: ObservableObject, Session {
91
117
static let hasSession = " hasSession "
92
118
static let baseAccessURL = " baseAccessURL "
93
119
static let sessionToken = " sessionToken "
94
- }
95
- }
96
-
97
- class Settings : ObservableObject {
98
- private let store : UserDefaults
99
- @AppStorage ( Keys . useLiteralHeaders) var useLiteralHeaders = false
100
120
101
- @Published var literalHeaders : [ LiteralHeader ] {
102
- didSet {
103
- try ? store. set ( JSONEncoder ( ) . encode ( literalHeaders) , forKey: Keys . literalHeaders)
104
- }
105
- }
106
-
107
- @AppStorage ( Keys . stopVPNOnQuit) var stopVPNOnQuit = true
108
-
109
- init ( store: UserDefaults = . standard) {
110
- self . store = store
111
- _literalHeaders = Published (
112
- initialValue: store. data (
113
- forKey: Keys . literalHeaders
114
- ) . flatMap { try ? JSONDecoder ( ) . decode ( [ LiteralHeader ] . self, from: $0) } ?? [ ]
115
- )
116
- }
117
-
118
- enum Keys {
119
121
static let useLiteralHeaders = " UseLiteralHeaders "
120
122
static let literalHeaders = " LiteralHeaders "
121
123
static let stopVPNOnQuit = " StopVPNOnQuit "
0 commit comments