diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS.xcodeproj/project.pbxproj b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS.xcodeproj/project.pbxproj index 1c455dd..c5c2bef 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS.xcodeproj/project.pbxproj +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS.xcodeproj/project.pbxproj @@ -16,6 +16,27 @@ 22488AA228E72C4E00FE29C3 /* KeychainStorageStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22488A9E28E72C4E00FE29C3 /* KeychainStorageStrategy.swift */; }; 22488AA328E72C4E00FE29C3 /* StoresWallet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22488A9F28E72C4E00FE29C3 /* StoresWallet.swift */; }; 22488AA628E72CF000FE29C3 /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 22488AA528E72CF000FE29C3 /* KeychainAccess */; }; + 225A836A28EACE6C00F66619 /* ConnectionModelType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225A834B28EACE6C00F66619 /* ConnectionModelType.swift */; }; + 225A836B28EACE6C00F66619 /* ConnectionModelError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225A834C28EACE6C00F66619 /* ConnectionModelError.swift */; }; + 225A836C28EACE6C00F66619 /* ConnectionNodeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225A834F28EACE6C00F66619 /* ConnectionNodeModel.swift */; }; + 225A837E28EACE6C00F66619 /* ConnectionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225A836628EACE6C00F66619 /* ConnectionModel.swift */; }; + 225A838028EACFD900F66619 /* Node.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225A837F28EACFD900F66619 /* Node.swift */; }; + 225A838828EAE01400F66619 /* SessionsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225A838228EAE01400F66619 /* SessionsService.swift */; }; + 225A838928EAE01400F66619 /* SessionServiceError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225A838328EAE01400F66619 /* SessionServiceError.swift */; }; + 225A838A28EAE01400F66619 /* SessionsServiceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225A838428EAE01400F66619 /* SessionsServiceType.swift */; }; + 225A838B28EAE01400F66619 /* SubscriptionsServiceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225A838628EAE01400F66619 /* SubscriptionsServiceType.swift */; }; + 225A838C28EAE01400F66619 /* SubscriptionsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225A838728EAE01400F66619 /* SubscriptionsService.swift */; }; + 225A839428EAE0A600F66619 /* StartSessionResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225A838F28EAE0A600F66619 /* StartSessionResponse.swift */; }; + 225A839528EAE0A600F66619 /* StartSessionRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225A839028EAE0A600F66619 /* StartSessionRequest.swift */; }; + 225A839628EAE0A600F66619 /* NodeSessionProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225A839128EAE0A600F66619 /* NodeSessionProvider.swift */; }; + 225A839728EAE0A600F66619 /* NodeSessionAPITarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225A839228EAE0A600F66619 /* NodeSessionAPITarget.swift */; }; + 225A839828EAE0A600F66619 /* NodeSessionProviderType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225A839328EAE0A600F66619 /* NodeSessionProviderType.swift */; }; + 225A839A28EAE42300F66619 /* StoresConnectInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225A839928EAE42300F66619 /* StoresConnectInfo.swift */; }; + 225A839D28EAE54400F66619 /* SecurityService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225A839C28EAE54400F66619 /* SecurityService.swift */; }; + 225A83A028EAE5D200F66619 /* SwiftKeychainWrapper in Frameworks */ = {isa = PBXBuildFile; productRef = 225A839F28EAE5D200F66619 /* SwiftKeychainWrapper */; }; + 225A83A228EB06BF00F66619 /* NodesProviderType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225A83A128EB06BF00F66619 /* NodesProviderType.swift */; }; + 225A83A328EB14B200F66619 /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22C3EF0028E6FD95007DB01B /* PacketTunnelProvider.swift */; }; + 225A83A628EC81E500F66619 /* WebSocketDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225A83A528EC81E500F66619 /* WebSocketDelegate.swift */; }; 22C3EE9028E4638E007DB01B /* WireGuardNetworkExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 22C3EE8728E4638E007DB01B /* WireGuardNetworkExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 22C3EE9728E463D6007DB01B /* WireGuardKit in Frameworks */ = {isa = PBXBuildFile; productRef = 22C3EE9628E463D6007DB01B /* WireGuardKit */; }; 22C3EE9A28E464A1007DB01B /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = 22C3EE9928E464A1007DB01B /* Alamofire */; }; @@ -54,7 +75,6 @@ 22C3EEF928E48F0B007DB01B /* DNSServerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22C3EEF828E48F0A007DB01B /* DNSServerType.swift */; }; 22C3EEFB28E48F95007DB01B /* NotificationToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22C3EEFA28E48F94007DB01B /* NotificationToken.swift */; }; 22C3EEFD28E6FC2C007DB01B /* WireGuardKit in Frameworks */ = {isa = PBXBuildFile; productRef = 22C3EE6928E460B2007DB01B /* WireGuardKit */; }; - 22C3EF0328E6FD95007DB01B /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22C3EF0028E6FD95007DB01B /* PacketTunnelProvider.swift */; }; 22C3EF0628E6FDDB007DB01B /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22C3EF0528E6FDDB007DB01B /* NetworkExtension.framework */; }; 22C3EF0728E6FDF8007DB01B /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22C3EF0528E6FDDB007DB01B /* NetworkExtension.framework */; }; 923C371428E5B898003CFC03 /* CommonContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 923C371328E5B898003CFC03 /* CommonContext.swift */; }; @@ -85,7 +105,6 @@ 92D6B44D28E438EF004CF9DF /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = 92D6B44C28E438EF004CF9DF /* Alamofire */; }; 92D6B44F28E45EA0004CF9DF /* NodesAPITarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92D6B44E28E45EA0004CF9DF /* NodesAPITarget.swift */; }; 92D6B45228E45F03004CF9DF /* NodesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92D6B45128E45F03004CF9DF /* NodesProvider.swift */; }; - 92D6B45428E45F15004CF9DF /* NodesProviderType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92D6B45328E45F15004CF9DF /* NodesProviderType.swift */; }; 92D6B45628E4609E004CF9DF /* APITarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92D6B45528E4609E004CF9DF /* APITarget.swift */; }; 92D6B45828E46118004CF9DF /* SOLARAPIProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92D6B45728E46118004CF9DF /* SOLARAPIProvider.swift */; }; 92D6B45A28E46283004CF9DF /* NetworkError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92D6B45928E46283004CF9DF /* NetworkError.swift */; }; @@ -158,6 +177,25 @@ 22488A9D28E72C4E00FE29C3 /* SettingsStorageStrategyType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsStorageStrategyType.swift; sourceTree = ""; }; 22488A9E28E72C4E00FE29C3 /* KeychainStorageStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeychainStorageStrategy.swift; sourceTree = ""; }; 22488A9F28E72C4E00FE29C3 /* StoresWallet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoresWallet.swift; sourceTree = ""; }; + 225A834B28EACE6C00F66619 /* ConnectionModelType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectionModelType.swift; sourceTree = ""; }; + 225A834C28EACE6C00F66619 /* ConnectionModelError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectionModelError.swift; sourceTree = ""; }; + 225A834F28EACE6C00F66619 /* ConnectionNodeModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectionNodeModel.swift; sourceTree = ""; }; + 225A836628EACE6C00F66619 /* ConnectionModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectionModel.swift; sourceTree = ""; }; + 225A837F28EACFD900F66619 /* Node.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Node.swift; sourceTree = ""; }; + 225A838228EAE01400F66619 /* SessionsService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SessionsService.swift; sourceTree = ""; }; + 225A838328EAE01400F66619 /* SessionServiceError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SessionServiceError.swift; sourceTree = ""; }; + 225A838428EAE01400F66619 /* SessionsServiceType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SessionsServiceType.swift; sourceTree = ""; }; + 225A838628EAE01400F66619 /* SubscriptionsServiceType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SubscriptionsServiceType.swift; sourceTree = ""; }; + 225A838728EAE01400F66619 /* SubscriptionsService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SubscriptionsService.swift; sourceTree = ""; }; + 225A838F28EAE0A600F66619 /* StartSessionResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StartSessionResponse.swift; sourceTree = ""; }; + 225A839028EAE0A600F66619 /* StartSessionRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StartSessionRequest.swift; sourceTree = ""; }; + 225A839128EAE0A600F66619 /* NodeSessionProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NodeSessionProvider.swift; sourceTree = ""; }; + 225A839228EAE0A600F66619 /* NodeSessionAPITarget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NodeSessionAPITarget.swift; sourceTree = ""; }; + 225A839328EAE0A600F66619 /* NodeSessionProviderType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NodeSessionProviderType.swift; sourceTree = ""; }; + 225A839928EAE42300F66619 /* StoresConnectInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoresConnectInfo.swift; sourceTree = ""; }; + 225A839C28EAE54400F66619 /* SecurityService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecurityService.swift; sourceTree = ""; }; + 225A83A128EB06BF00F66619 /* NodesProviderType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NodesProviderType.swift; sourceTree = ""; }; + 225A83A528EC81E500F66619 /* WebSocketDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebSocketDelegate.swift; sourceTree = ""; }; 22C3EE8728E4638E007DB01B /* WireGuardNetworkExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = WireGuardNetworkExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 22C3EE9B28E467E4007DB01B /* SOLARdVPNCommunityCoreiOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SOLARdVPNCommunityCoreiOS.entitlements; sourceTree = ""; }; 22C3EE9D28E4733C007DB01B /* Config.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Config.swift; sourceTree = ""; }; @@ -217,7 +255,6 @@ 92D6B44528E34D7C004CF9DF /* APIRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIRequest.swift; sourceTree = ""; }; 92D6B44E28E45EA0004CF9DF /* NodesAPITarget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodesAPITarget.swift; sourceTree = ""; }; 92D6B45128E45F03004CF9DF /* NodesProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodesProvider.swift; sourceTree = ""; }; - 92D6B45328E45F15004CF9DF /* NodesProviderType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodesProviderType.swift; sourceTree = ""; }; 92D6B45528E4609E004CF9DF /* APITarget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APITarget.swift; sourceTree = ""; }; 92D6B45728E46118004CF9DF /* SOLARAPIProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SOLARAPIProvider.swift; sourceTree = ""; }; 92D6B45928E46283004CF9DF /* NetworkError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkError.swift; sourceTree = ""; }; @@ -249,6 +286,7 @@ files = ( 22C3EEFD28E6FC2C007DB01B /* WireGuardKit in Frameworks */, 92D6B44D28E438EF004CF9DF /* Alamofire in Frameworks */, + 225A83A028EAE5D200F66619 /* SwiftKeychainWrapper in Frameworks */, 22488AA628E72CF000FE29C3 /* KeychainAccess in Frameworks */, 22C3EE9A28E464A1007DB01B /* Alamofire in Frameworks */, 22C3EEB128E473E5007DB01B /* SwiftyBeaver in Frameworks */, @@ -270,15 +308,6 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 22488A9428E727F200FE29C3 /* Routes */ = { - isa = PBXGroup; - children = ( - 22488A9228E726A900FE29C3 /* TunnelRouteCollection.swift */, - 22488A9528E7285500FE29C3 /* PostConnectionRequest.swift */, - ); - path = Routes; - sourceTree = ""; - }; 22488A9728E7297000FE29C3 /* Storage */ = { isa = PBXGroup; children = ( @@ -286,6 +315,7 @@ 22488A9B28E72C4E00FE29C3 /* StorageStrategy */, 22C3EEF328E48EBE007DB01B /* StoresDNSServers.swift */, 22488A9F28E72C4E00FE29C3 /* StoresWallet.swift */, + 225A839928EAE42300F66619 /* StoresConnectInfo.swift */, ); path = Storage; sourceTree = ""; @@ -308,6 +338,82 @@ path = StorageStrategy; sourceTree = ""; }; + 225A834628EACE6C00F66619 /* Connection */ = { + isa = PBXGroup; + children = ( + 225A834928EACE6C00F66619 /* Models */, + 225A834F28EACE6C00F66619 /* ConnectionNodeModel.swift */, + 225A836628EACE6C00F66619 /* ConnectionModel.swift */, + ); + path = Connection; + sourceTree = ""; + }; + 225A834928EACE6C00F66619 /* Models */ = { + isa = PBXGroup; + children = ( + 225A834B28EACE6C00F66619 /* ConnectionModelType.swift */, + 225A834C28EACE6C00F66619 /* ConnectionModelError.swift */, + ); + path = Models; + sourceTree = ""; + }; + 225A838128EAE01400F66619 /* SessionsService */ = { + isa = PBXGroup; + children = ( + 225A838228EAE01400F66619 /* SessionsService.swift */, + 225A838328EAE01400F66619 /* SessionServiceError.swift */, + 225A838428EAE01400F66619 /* SessionsServiceType.swift */, + ); + path = SessionsService; + sourceTree = ""; + }; + 225A838528EAE01400F66619 /* SubscriptionsService */ = { + isa = PBXGroup; + children = ( + 225A838628EAE01400F66619 /* SubscriptionsServiceType.swift */, + 225A838728EAE01400F66619 /* SubscriptionsService.swift */, + ); + path = SubscriptionsService; + sourceTree = ""; + }; + 225A838D28EAE0A600F66619 /* SessionProvider */ = { + isa = PBXGroup; + children = ( + 225A838E28EAE0A600F66619 /* Models */, + 225A839128EAE0A600F66619 /* NodeSessionProvider.swift */, + 225A839228EAE0A600F66619 /* NodeSessionAPITarget.swift */, + 225A839328EAE0A600F66619 /* NodeSessionProviderType.swift */, + ); + path = SessionProvider; + sourceTree = ""; + }; + 225A838E28EAE0A600F66619 /* Models */ = { + isa = PBXGroup; + children = ( + 225A838F28EAE0A600F66619 /* StartSessionResponse.swift */, + 225A839028EAE0A600F66619 /* StartSessionRequest.swift */, + ); + path = Models; + sourceTree = ""; + }; + 225A839B28EAE54400F66619 /* SecurityService */ = { + isa = PBXGroup; + children = ( + 225A839C28EAE54400F66619 /* SecurityService.swift */, + ); + path = SecurityService; + sourceTree = ""; + }; + 225A83A428EC297500F66619 /* Tunnel */ = { + isa = PBXGroup; + children = ( + 225A834628EACE6C00F66619 /* Connection */, + 22488A9228E726A900FE29C3 /* TunnelRouteCollection.swift */, + 22488A9528E7285500FE29C3 /* PostConnectionRequest.swift */, + ); + path = Tunnel; + sourceTree = ""; + }; 22C3EE9C28E4733C007DB01B /* Shared */ = { isa = PBXGroup; children = ( @@ -332,7 +438,6 @@ 22C3EEBB28E48B51007DB01B /* Tunnel */ = { isa = PBXGroup; children = ( - 22488A9428E727F200FE29C3 /* Routes */, 22C3EEBC28E48B51007DB01B /* Manager */, 22C3EEBF28E48B51007DB01B /* Model */, 22C3EEC528E48B51007DB01B /* Service */, @@ -435,6 +540,7 @@ 92D6B41328E1E133004CF9DF /* DVPNServer.swift */, 92D6B3FE28E19E20004CF9DF /* SceneDelegate.swift */, 92D6B40028E19E20004CF9DF /* ViewController.swift */, + 225A83A528EC81E500F66619 /* WebSocketDelegate.swift */, ); path = Root; sourceTree = ""; @@ -454,6 +560,7 @@ 92D6B46E28E47E2E004CF9DF /* NodesService.swift */, 923C372928EAFAA5003CFC03 /* NodesServiceError.swift */, 92D6B47028E47E71004CF9DF /* NodesServiceType.swift */, + 225A837F28EACFD900F66619 /* Node.swift */, ); path = NodesService; sourceTree = ""; @@ -471,6 +578,7 @@ isa = PBXGroup; children = ( 923C372428E72FF0003CFC03 /* Nodes */, + 225A83A428EC297500F66619 /* Tunnel */, ); path = RouteCollections; sourceTree = ""; @@ -569,6 +677,7 @@ 92D6B44A28E4360D004CF9DF /* Providers */ = { isa = PBXGroup; children = ( + 225A838D28EAE0A600F66619 /* SessionProvider */, 92D6B45028E45EF1004CF9DF /* NodesProvider */, ); path = Providers; @@ -580,7 +689,7 @@ 92D6B45B28E46350004CF9DF /* Models */, 92D6B44E28E45EA0004CF9DF /* NodesAPITarget.swift */, 92D6B45128E45F03004CF9DF /* NodesProvider.swift */, - 92D6B45328E45F15004CF9DF /* NodesProviderType.swift */, + 225A83A128EB06BF00F66619 /* NodesProviderType.swift */, ); path = NodesProvider; sourceTree = ""; @@ -625,9 +734,12 @@ 92D6B46D28E47DD2004CF9DF /* Services */ = { isa = PBXGroup; children = ( - 22488A9728E7297000FE29C3 /* Storage */, - 22C3EF0A28E6FEF0007DB01B /* NodesService */, 22C3EEF228E48EBE007DB01B /* DNSServers */, + 22C3EF0A28E6FEF0007DB01B /* NodesService */, + 225A839B28EAE54400F66619 /* SecurityService */, + 225A838128EAE01400F66619 /* SessionsService */, + 22488A9728E7297000FE29C3 /* Storage */, + 225A838528EAE01400F66619 /* SubscriptionsService */, 22C3EEBB28E48B51007DB01B /* Tunnel */, ); path = Services; @@ -721,6 +833,7 @@ 22C3EEB028E473E5007DB01B /* SwiftyBeaver */, 22C3EEF028E48E2F007DB01B /* SentinelWallet */, 22488AA528E72CF000FE29C3 /* KeychainAccess */, + 225A839F28EAE5D200F66619 /* SwiftKeychainWrapper */, ); productName = SolardVPNCommunityCoreiOS; productReference = 92D6B3F928E19E20004CF9DF /* SOLARdVPNCommunityCoreiOS.app */; @@ -788,6 +901,7 @@ 22C3EEAF28E473E5007DB01B /* XCRemoteSwiftPackageReference "SwiftyBeaver" */, 22C3EEEF28E48E2F007DB01B /* XCRemoteSwiftPackageReference "sentinel-wallet-sdk-ios" */, 22488AA428E72CF000FE29C3 /* XCRemoteSwiftPackageReference "KeychainAccess" */, + 225A839E28EAE5D200F66619 /* XCRemoteSwiftPackageReference "SwiftKeychainWrapper" */, ); productRefGroup = 92D6B3FA28E19E20004CF9DF /* Products */; projectDirPath = ""; @@ -838,6 +952,7 @@ 22C3EEB328E4748E007DB01B /* NETunnelProviderProtocol+Extension.swift in Sources */, 22C3EEB528E4748E007DB01B /* Keychain.swift in Sources */, 22C3EEB828E4748E007DB01B /* ConfigurationParseError.swift in Sources */, + 225A83A328EB14B200F66619 /* PacketTunnelProvider.swift in Sources */, 22C3EEB728E4748E007DB01B /* TunnelConfiguration+WireGuardConfig.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -849,10 +964,12 @@ 92D6B40128E19E20004CF9DF /* ViewController.swift in Sources */, 22C3EEED28E48D9A007DB01B /* SentinelNode+Ext.swift in Sources */, 923C372628EAE93E003CFC03 /* Encoder.swift in Sources */, + 225A838028EACFD900F66619 /* Node.swift in Sources */, 92D6B41828E2DC85004CF9DF /* NodesRouteCollection.swift in Sources */, 923C371428E5B898003CFC03 /* CommonContext.swift in Sources */, 92D6B3FD28E19E20004CF9DF /* AppDelegate.swift in Sources */, 923C371C28E5DA05003CFC03 /* OrderType.swift in Sources */, + 225A838C28EAE01400F66619 /* SubscriptionsService.swift in Sources */, 92D6B46F28E47E2E004CF9DF /* NodesService.swift in Sources */, 22C3EEA728E4733C007DB01B /* Config.swift in Sources */, 22C3EEE528E48D9A007DB01B /* NEVPNManager+Ext.swift in Sources */, @@ -860,18 +977,27 @@ 22C3EECA28E48B52007DB01B /* TunnelManager.swift in Sources */, 22C3EED028E48B52007DB01B /* TunnelModel.swift in Sources */, 22C3EECC28E48B52007DB01B /* TunnelChanges.swift in Sources */, + 225A837E28EACE6C00F66619 /* ConnectionModel.swift in Sources */, 22C3EEAB28E4733C007DB01B /* TunnelConfiguration+WireGuardConfig.swift in Sources */, 22C3EECB28E48B52007DB01B /* TunnelManagerType.swift in Sources */, + 225A838828EAE01400F66619 /* SessionsService.swift in Sources */, + 225A839A28EAE42300F66619 /* StoresConnectInfo.swift in Sources */, + 225A838A28EAE01400F66619 /* SessionsServiceType.swift in Sources */, 22488A9328E726AA00FE29C3 /* TunnelRouteCollection.swift in Sources */, 22488A9128E7043200FE29C3 /* String+ArrayConversion.swift in Sources */, - 22C3EF0328E6FD95007DB01B /* PacketTunnelProvider.swift in Sources */, 22488AA128E72C4E00FE29C3 /* SettingsStorageStrategyType.swift in Sources */, + 225A838928EAE01400F66619 /* SessionServiceError.swift in Sources */, 22C3EEF928E48F0B007DB01B /* DNSServerType.swift in Sources */, + 225A836A28EACE6C00F66619 /* ConnectionModelType.swift in Sources */, + 225A838B28EAE01400F66619 /* SubscriptionsServiceType.swift in Sources */, 22C3EEAD28E4733C007DB01B /* ConfigurationParseError.swift in Sources */, + 225A83A628EC81E500F66619 /* WebSocketDelegate.swift in Sources */, 22C3EED228E48B52007DB01B /* TunnelContainer.swift in Sources */, 22488A9A28E729E600FE29C3 /* GeneralSettingsStorage.swift in Sources */, 22C3EEFB28E48F95007DB01B /* NotificationToken.swift in Sources */, + 225A836B28EACE6C00F66619 /* ConnectionModelError.swift in Sources */, 22C3EED428E48B52007DB01B /* TunnelsService.swift in Sources */, + 225A839D28EAE54400F66619 /* SecurityService.swift in Sources */, 22C3EEE628E48D9A007DB01B /* TunnelConfiguration+Ext.swift in Sources */, 22C3EEE828E48D9A007DB01B /* Serializer.swift in Sources */, 22C3EEE728E48D9A007DB01B /* NEVPNStatus+Ext.swift in Sources */, @@ -896,6 +1022,7 @@ 22488AA328E72C4E00FE29C3 /* StoresWallet.swift in Sources */, 22C3EED128E48B52007DB01B /* TunnelStatus.swift in Sources */, 923C372A28EAFAA5003CFC03 /* NodesServiceError.swift in Sources */, + 225A836C28EACE6C00F66619 /* ConnectionNodeModel.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -906,19 +1033,24 @@ 92D6B44428E34A9B004CF9DF /* AnyEncodable.swift in Sources */, 92D6B44F28E45EA0004CF9DF /* NodesAPITarget.swift in Sources */, 92D6B45D28E4636B004CF9DF /* GetNodesRequest.swift in Sources */, + 225A839628EAE0A600F66619 /* NodeSessionProvider.swift in Sources */, + 225A839528EAE0A600F66619 /* StartSessionRequest.swift in Sources */, 92D6B46628E47311004CF9DF /* PageResponse.swift in Sources */, 92D6B46128E463EF004CF9DF /* NodeStatusType.swift in Sources */, - 92D6B45428E45F15004CF9DF /* NodesProviderType.swift in Sources */, 92D6B46328E47240004CF9DF /* Node.swift in Sources */, + 225A839828EAE0A600F66619 /* NodeSessionProviderType.swift in Sources */, 92D6B45F28E4639D004CF9DF /* OrderType.swift in Sources */, 92D6B45228E45F03004CF9DF /* NodesProvider.swift in Sources */, 923C372828EAF0E8003CFC03 /* Country.swift in Sources */, + 225A839428EAE0A600F66619 /* StartSessionResponse.swift in Sources */, 92D6B44628E34D7C004CF9DF /* APIRequest.swift in Sources */, 92D6B42828E32900004CF9DF /* SOLARAPI.docc in Sources */, 92D6B45A28E46283004CF9DF /* NetworkError.swift in Sources */, 923C372028E71D19003CFC03 /* PostNodesByAddressRequest.swift in Sources */, + 225A839728EAE0A600F66619 /* NodeSessionAPITarget.swift in Sources */, 92D6B46C28E47519004CF9DF /* Encodable+Ext.swift in Sources */, 92D6B45628E4609E004CF9DF /* APITarget.swift in Sources */, + 225A83A228EB06BF00F66619 /* NodesProviderType.swift in Sources */, 92D6B45828E46118004CF9DF /* SOLARAPIProvider.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1003,7 +1135,7 @@ INFOPLIST_FILE = WireGuardNetworkExtension/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = WireGuardNetworkExtension; INFOPLIST_KEY_NSHumanReadableCopyright = ""; - IPHONEOS_DEPLOYMENT_TARGET = 16.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1032,7 +1164,7 @@ INFOPLIST_FILE = WireGuardNetworkExtension/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = WireGuardNetworkExtension; INFOPLIST_KEY_NSHumanReadableCopyright = ""; - IPHONEOS_DEPLOYMENT_TARGET = 16.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1178,8 +1310,8 @@ INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UIMainStoryboardFile = Main; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1187,9 +1319,12 @@ MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = "ee.solarlabs.community-core.ios"; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = 1; }; name = Debug; }; @@ -1209,8 +1344,8 @@ INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UIMainStoryboardFile = Main; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1218,9 +1353,12 @@ MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = "ee.solarlabs.community-core.ios"; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = 1; }; name = Release; }; @@ -1345,6 +1483,14 @@ kind = branch; }; }; + 225A839E28EAE5D200F66619 /* XCRemoteSwiftPackageReference "SwiftKeychainWrapper" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/jrendel/SwiftKeychainWrapper"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 4.0.0; + }; + }; 22C3EE6828E460B2007DB01B /* XCRemoteSwiftPackageReference "wireguard-apple" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://git.zx2c4.com/wireguard-apple"; @@ -1401,6 +1547,11 @@ package = 22488AA428E72CF000FE29C3 /* XCRemoteSwiftPackageReference "KeychainAccess" */; productName = KeychainAccess; }; + 225A839F28EAE5D200F66619 /* SwiftKeychainWrapper */ = { + isa = XCSwiftPackageProductDependency; + package = 225A839E28EAE5D200F66619 /* XCRemoteSwiftPackageReference "SwiftKeychainWrapper" */; + productName = SwiftKeychainWrapper; + }; 22C3EE6928E460B2007DB01B /* WireGuardKit */ = { isa = XCSwiftPackageProductDependency; package = 22C3EE6828E460B2007DB01B /* XCRemoteSwiftPackageReference "wireguard-apple" */; diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Context/CommonContext.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Context/CommonContext.swift index ddad30b..791feeb 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Context/CommonContext.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Context/CommonContext.swift @@ -6,28 +6,110 @@ // import Foundation +import SentinelWallet import SOLARAPI protocol NoContext {} final class CommonContext { - // Providers - let nodesProvider: NodesProviderType + typealias Storage = StoresConnectInfo & StoresWallet & StoresDNSServers + let storage: Storage + // Providers + let nodesProvider: SOLARAPI.NodesProviderType + // Services + let securityService: SecurityService let nodesService: NodesServiceType + let walletService: WalletService + let subscriptionsService: SubscriptionsServiceType + let sessionsService: SessionsServiceType + + let tunnelManager: TunnelManagerType + init( - nodesProvider: NodesProviderType, - nodesService: NodesServiceType + storage: Storage, + nodesProvider: SOLARAPI.NodesProviderType, + securityService: SecurityService, + walletService: WalletService, + nodesService: NodesServiceType, + subscriptionsService: SubscriptionsServiceType, + sessionsService: SessionsServiceType, + tunnelManager: TunnelManagerType ) { + self.storage = storage self.nodesProvider = nodesProvider + self.securityService = securityService + self.walletService = walletService self.nodesService = nodesService + self.subscriptionsService = subscriptionsService + self.sessionsService = sessionsService + self.tunnelManager = tunnelManager } } -protocol HasNodesProvider { var nodesProvider: NodesProviderType { get } } +protocol HasWalletService { + var walletService: WalletService { get } + + func updateWalletContext() + func resetWalletContext() +} + +extension CommonContext: HasWalletService { + func updateWalletContext() { + let walletAddress = storage.walletAddress + guard !walletAddress.isEmpty else { return } + walletService.manage(address: walletAddress) + } + + func resetWalletContext() { + let mnemonics = securityService.generateMnemonics().components(separatedBy: " ") + switch securityService.restore(from: mnemonics) { + case .failure(let error): + fatalError("failed to generate wallet due to \(error), terminate") + case .success(let address): + saveMnemonicsIfNeeded(for: address, mnemonics: mnemonics) + storage.set(wallet: address) + updateWalletContext() + } + } + + private func saveMnemonicsIfNeeded(for account: String, mnemonics: [String]) { + guard !securityService.mnemonicsExists(for: account) else { return } + if !self.securityService.save(mnemonics: mnemonics, for: account) { + log.error("Failed to save mnemonics info") + } + } +} + +protocol HasSubscriptionsService { var subscriptionsService: SubscriptionsServiceType { get } } +extension CommonContext: HasSubscriptionsService {} + +protocol HasNodesProvider { var nodesProvider: SOLARAPI.NodesProviderType { get } } extension CommonContext: HasNodesProvider {} protocol HasNodesService { var nodesService: NodesServiceType { get } } extension CommonContext: HasNodesService {} + +protocol HasTunnelManager { var tunnelManager: TunnelManagerType { get } } +extension CommonContext: HasTunnelManager {} + +protocol HasSessionsService { var sessionsService: SessionsServiceType { get } } +extension CommonContext: HasSessionsService {} + +// MARK: - Storages + +protocol HasConnectionInfoStorage { var connectionInfoStorage: StoresConnectInfo { get } } +extension CommonContext: HasConnectionInfoStorage { + var connectionInfoStorage: StoresConnectInfo { + storage as StoresConnectInfo + } +} + +protocol HasWalletStorage { var walletStorage: StoresWallet { get } } +extension CommonContext: HasWalletStorage { + var walletStorage: StoresWallet { + storage as StoresWallet + } +} diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Context/ContextBuilder.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Context/ContextBuilder.swift index 96bf911..6061afe 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Context/ContextBuilder.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Context/ContextBuilder.swift @@ -6,18 +6,82 @@ // import Foundation +import SentinelWallet import SOLARAPI /// This class should configure all required services and inject them into a Context final class ContextBuilder { func buildContext() -> CommonContext { - let nodesProvider = NodesProvider(configuration: .init(baseURL: ClientConstants.backendURL)) + let generalSettingsStorage = GeneralSettingsStorage() + let nodesProvider = NodesProvider(configuration: .init(baseURL: ClientConstants.backendURL)) let nodesService = NodesService(nodesProvider: nodesProvider) + + let securityService = SecurityService() + let subscriptionsProvider = SubscriptionsProvider(configuration: ApplicationConfiguration.shared) + let sessionProvider = NodeSessionProvider() + let walletService = buildWalletService(storage: generalSettingsStorage, securityService: securityService) + + let sessionsService = SessionsService( + sessionProvider: sessionProvider, + subscriptionsProvider: subscriptionsProvider, + walletService: walletService + ) + let subscriptionsService = SubscriptionsService( + subscriptionsProvider: subscriptionsProvider, + walletService: walletService + ) + + let tunnelManager = TunnelManager(storage: generalSettingsStorage) return CommonContext( + storage: generalSettingsStorage, nodesProvider: nodesProvider, - nodesService: nodesService + securityService: securityService, + walletService: walletService, + nodesService: nodesService, + subscriptionsService: subscriptionsService, + sessionsService: sessionsService, + tunnelManager: tunnelManager ) } + + func buildWalletService( + storage: StoresWallet, + securityService: SecurityService + ) -> WalletService { + let walletAddress = storage.walletAddress + let grpc = ApplicationConfiguration.shared + guard !walletAddress.isEmpty else { + let mnemonic = securityService.generateMnemonics().components(separatedBy: " ") + switch securityService.restore(from: mnemonic) { + case .failure(let error): + fatalError("failed to generate wallet due to \(error), terminate") + case .success(let address): + saveMnemonicsIfNeeded(for: address, mnemonics: mnemonic, securityService: securityService) + storage.set(wallet: address) + return .init( + for: address, + configuration: grpc, + securityService: securityService + ) + } + } + return WalletService( + for: walletAddress, + configuration: grpc, + securityService: securityService + ) + } + + private func saveMnemonicsIfNeeded( + for account: String, + mnemonics: [String], + securityService: SecurityService + ) { + guard !securityService.mnemonicsExists(for: account) else { return } + if !securityService.save(mnemonics: mnemonics, for: account) { + log.error("Failed to save mnemonics info") + } + } } diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/Tunnel/Routes/PostConnectionRequest.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Tunnel/PostConnectionRequest.swift similarity index 100% rename from SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/Tunnel/Routes/PostConnectionRequest.swift rename to SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Tunnel/PostConnectionRequest.swift diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Tunnel/TunnelRouteCollection.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Tunnel/TunnelRouteCollection.swift new file mode 100644 index 0000000..8ff410b --- /dev/null +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Tunnel/TunnelRouteCollection.swift @@ -0,0 +1,102 @@ +// +// TunnelRouteCollection.swift +// SOLARdVPNCommunityCoreiOS +// +// Created by Lika Vorobeva on 30.09.2022. +// + +import Vapor +import Combine + +enum TunnelRouteEvent: String { + case alreadyConnected + case subscriptionCanceled +} + +class TunnelRouteCollection: RouteCollection { + private let model: ConnectionModel + private var cancellables = Set() + + // Connection Status + @Published private(set) var isConnected: Bool = false + private weak var delegate: WebSocketDelegate? + + init(model: ConnectionModel, delegate: WebSocketDelegate?) { + self.model = model + self.delegate = delegate + + subscribeToEvents() + model.setInitData() + } + + func boot(routes: RoutesBuilder) throws { + routes.post("connection", use: createNewSession) + routes.delete("connection", use: startDeactivationOfActiveTunnel) + } +} + +extension TunnelRouteCollection { +#warning("TODO add result") + func startDeactivationOfActiveTunnel(_ req: Request) async throws -> Bool { + model.disconnect() + + return true + } + +#warning("TODO add result & pass node") + func createNewSession(_ req: Request) async throws -> Bool { + if isConnected { + return true // && add status TunnelRouteEvent + } + model.connect() + return true + } +} + +// MARK: - Subscribe to events + +extension TunnelRouteCollection { + private func subscribeToEvents() { + model.eventPublisher + .receive(on: DispatchQueue.main) + .sink { [weak self] event in + guard let self = self else { return } + switch event { + case let .error(error): + self.send(error: error) + case let .warning(warning): + self.send(warning: warning) + case let .info(text): + self.send(info: text) + case let .updateTunnelActivity(isActive): + self.updateConnection(isConnected: isActive) + } + } + .store(in: &cancellables) + } +} + +// MARK: - Handle events + +extension TunnelRouteCollection { + private func send(error: Error) { +#warning("TODO: send json with error") + delegate?.send(event: error.localizedDescription) + } + + private func send(warning: Error) { +#warning("TODO: send json with warning") + delegate?.send(event: warning.localizedDescription) + } + + private func send(info: String) { +#warning("TODO: send json with info") + delegate?.send(event: info) + } + + private func updateConnection(isConnected: Bool) { +#warning("TODO: send json with isConnected") + self.isConnected = isConnected + delegate?.send(event: "isConnected \(isConnected)") + } +} diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/Tunnel/Routes/TunnelRouteCollection.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/Tunnel/Routes/TunnelRouteCollection.swift deleted file mode 100644 index 8380300..0000000 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/Tunnel/Routes/TunnelRouteCollection.swift +++ /dev/null @@ -1,29 +0,0 @@ -// -// TunnelRouteCollection.swift -// SOLARdVPNCommunityCoreiOS -// -// Created by Lika Vorobeva on 30.09.2022. -// - -import Vapor - -struct TunnelRouteCollection: RouteCollection { - let context: HasTunnelManager - - func boot(routes: RoutesBuilder) throws { - routes.post("connection", use: createNewSession) - routes.delete("connection", use: startDeactivationOfActiveTunnel) - } -} - -extension TunnelRouteCollection { - func startDeactivationOfActiveTunnel(_ req: Request) async throws -> Bool { - return !context.tunnelManager.startDeactivationOfActiveTunnel() - } - - func createNewSession(_ req: Request) async throws -> Bool { - let continentCode = req.query[String.self, at: PostConnectionRequest.CodingKeys.nodeAddress.rawValue] - - return true - } -}