summaryrefslogtreecommitdiffhomepage
path: root/ios
diff options
context:
space:
mode:
authorBug Magnet <marco.nikic@mullvad.net>2025-04-28 09:50:16 +0200
committerBug Magnet <marco.nikic@mullvad.net>2025-04-28 09:50:16 +0200
commit30f142dd2ab096eeb80354690b754a452ba471cd (patch)
treeefc5ff711f46d7a25fe1f37d4d11f1d635fe5bf2 /ios
parent045a5c33f140945072e42553939adcf7bace52c1 (diff)
parent96444846bf5b741483c371a763cb1e9c6a1e7b8d (diff)
downloadmullvadvpn-30f142dd2ab096eeb80354690b754a452ba471cd.tar.xz
mullvadvpn-30f142dd2ab096eeb80354690b754a452ba471cd.zip
Merge branch 'use-mullvad-api-to-implement-a-devicehandling-ios-1103'
Diffstat (limited to 'ios')
-rw-r--r--ios/MullvadMockData/MullvadREST/DevicesProxy+Stubs.swift2
-rw-r--r--ios/MullvadREST/ApiHandlers/RESTDevicesProxy.swift38
-rw-r--r--ios/MullvadREST/ApiHandlers/RESTProxyFactory.swift18
-rw-r--r--ios/MullvadREST/MullvadAPI/APIHandlers/MullvadDeviceProxy.swift147
-rw-r--r--ios/MullvadREST/MullvadAPI/APIRequest/APIRequest.swift45
-rw-r--r--ios/MullvadREST/MullvadAPI/MullvadApiRequestFactory.swift44
-rw-r--r--ios/MullvadRustRuntime/include/mullvad_rust_runtime.h113
-rw-r--r--ios/MullvadTypes/RESTTypes.swift40
-rw-r--r--ios/MullvadVPN.xcodeproj/project.pbxproj4
-rw-r--r--ios/MullvadVPN/TunnelManager/SetAccountOperation.swift2
10 files changed, 406 insertions, 47 deletions
diff --git a/ios/MullvadMockData/MullvadREST/DevicesProxy+Stubs.swift b/ios/MullvadMockData/MullvadREST/DevicesProxy+Stubs.swift
index 6748805b2c..acf3d6369a 100644
--- a/ios/MullvadMockData/MullvadREST/DevicesProxy+Stubs.swift
+++ b/ios/MullvadMockData/MullvadREST/DevicesProxy+Stubs.swift
@@ -41,7 +41,7 @@ struct DevicesProxyStub: DeviceHandling {
func createDevice(
accountNumber: String,
- request: REST.CreateDeviceRequest,
+ request: CreateDeviceRequest,
retryStrategy: REST.RetryStrategy,
completion: @escaping ProxyCompletionHandler<Device>
) -> Cancellable {
diff --git a/ios/MullvadREST/ApiHandlers/RESTDevicesProxy.swift b/ios/MullvadREST/ApiHandlers/RESTDevicesProxy.swift
index 20dd0d0539..5a6d369ef3 100644
--- a/ios/MullvadREST/ApiHandlers/RESTDevicesProxy.swift
+++ b/ios/MullvadREST/ApiHandlers/RESTDevicesProxy.swift
@@ -26,7 +26,7 @@ public protocol DeviceHandling: Sendable {
func createDevice(
accountNumber: String,
- request: REST.CreateDeviceRequest,
+ request: CreateDeviceRequest,
retryStrategy: REST.RetryStrategy,
completion: @escaping @Sendable ProxyCompletionHandler<Device>
) -> Cancellable
@@ -309,40 +309,4 @@ extension REST {
return executor.execute(retryStrategy: retryStrategy, completionHandler: completion)
}
}
-
- public struct CreateDeviceRequest: Encodable, Sendable {
- let publicKey: PublicKey
- let hijackDNS: Bool
-
- public init(publicKey: PublicKey, hijackDNS: Bool) {
- self.publicKey = publicKey
- self.hijackDNS = hijackDNS
- }
-
- private enum CodingKeys: String, CodingKey {
- case hijackDNS = "hijackDns"
- case publicKey = "pubkey"
- }
-
- public func encode(to encoder: Encoder) throws {
- var container = encoder.container(keyedBy: CodingKeys.self)
-
- try container.encode(publicKey.base64Key, forKey: .publicKey)
- try container.encode(hijackDNS, forKey: .hijackDNS)
- }
- }
-
- private struct RotateDeviceKeyRequest: Encodable, Sendable {
- let publicKey: PublicKey
-
- private enum CodingKeys: String, CodingKey {
- case publicKey = "pubkey"
- }
-
- func encode(to encoder: Encoder) throws {
- var container = encoder.container(keyedBy: CodingKeys.self)
-
- try container.encode(publicKey.base64Key, forKey: .publicKey)
- }
- }
}
diff --git a/ios/MullvadREST/ApiHandlers/RESTProxyFactory.swift b/ios/MullvadREST/ApiHandlers/RESTProxyFactory.swift
index ff3751c5bd..4d6f5eaa02 100644
--- a/ios/MullvadREST/ApiHandlers/RESTProxyFactory.swift
+++ b/ios/MullvadREST/ApiHandlers/RESTProxyFactory.swift
@@ -71,11 +71,29 @@ extension REST {
}
public func createAccountsProxy() -> RESTAccountHandling {
+ #if DEBUG
+ MullvadAccountProxy(
+ transportProvider: configuration.apiTransportProvider,
+ dispatchQueue: DispatchQueue(label: "MullvadAccountProxy.dispatchQueue"),
+ responseDecoder: Coding.makeJSONDecoder()
+ )
+
+ #else
REST.AccountsProxy(configuration: configuration)
+ #endif
}
public func createDevicesProxy() -> DeviceHandling {
+ #if DEBUG
+ MullvadDeviceProxy(
+ transportProvider: configuration.apiTransportProvider,
+ dispatchQueue: DispatchQueue(label: "MullvadDeviceProxy.dispatchQueue"),
+ responseDecoder: Coding.makeJSONDecoder()
+ )
+
+ #else
REST.DevicesProxy(configuration: configuration)
+ #endif
}
}
}
diff --git a/ios/MullvadREST/MullvadAPI/APIHandlers/MullvadDeviceProxy.swift b/ios/MullvadREST/MullvadAPI/APIHandlers/MullvadDeviceProxy.swift
new file mode 100644
index 0000000000..f2bdb027cf
--- /dev/null
+++ b/ios/MullvadREST/MullvadAPI/APIHandlers/MullvadDeviceProxy.swift
@@ -0,0 +1,147 @@
+//
+// MullvadDeviceProxy.swift
+// MullvadVPN
+//
+// Created by Mojgan on 2025-04-02.
+// Copyright © 2025 Mullvad VPN AB. All rights reserved.
+//
+import MullvadRustRuntime
+import MullvadTypes
+import Operations
+import WireGuardKitTypes
+
+extension REST {
+ final class MullvadDeviceProxy: DeviceHandling, @unchecked Sendable {
+ let transportProvider: APITransportProviderProtocol
+ let dispatchQueue: DispatchQueue
+ let operationQueue = AsyncOperationQueue()
+ let responseDecoder: JSONDecoder
+
+ public init(
+ transportProvider: APITransportProviderProtocol,
+ dispatchQueue: DispatchQueue,
+ responseDecoder: JSONDecoder
+ ) {
+ self.transportProvider = transportProvider
+ self.dispatchQueue = dispatchQueue
+ self.responseDecoder = responseDecoder
+ }
+
+ func getDevice(
+ accountNumber: String,
+ identifier: String,
+ retryStrategy: REST.RetryStrategy,
+ completion: @escaping ProxyCompletionHandler<Device>
+ ) -> Cancellable {
+ let responseHandler = rustResponseHandler(
+ decoding: Device.self,
+ with: responseDecoder
+ )
+
+ return createNetworkOperation(
+ request: .getDevice(retryStrategy, accountNumber: accountNumber, identifier: identifier),
+ responseHandler: responseHandler,
+ completionHandler: completion
+ )
+ }
+
+ func getDevices(
+ accountNumber: String,
+ retryStrategy: REST.RetryStrategy,
+ completion: @escaping ProxyCompletionHandler<[Device]>
+ ) -> Cancellable {
+ let responseHandler = rustResponseHandler(
+ decoding: [Device].self,
+ with: responseDecoder
+ )
+
+ return createNetworkOperation(
+ request: .getDevices(retryStrategy, accountNumber: accountNumber),
+ responseHandler: responseHandler,
+ completionHandler: completion
+ )
+ }
+
+ func createDevice(
+ accountNumber: String,
+ request: CreateDeviceRequest,
+ retryStrategy: REST.RetryStrategy,
+ completion: @escaping ProxyCompletionHandler<Device>
+ ) -> Cancellable {
+ let responseHandler = rustResponseHandler(
+ decoding: Device.self,
+ with: responseDecoder
+ )
+
+ return createNetworkOperation(
+ request: .createDevice(retryStrategy, accountNumber: accountNumber, request: request),
+ responseHandler: responseHandler,
+ completionHandler: completion
+ )
+ }
+
+ func deleteDevice(
+ accountNumber: String,
+ identifier: String,
+ retryStrategy: REST.RetryStrategy,
+ completion: @escaping ProxyCompletionHandler<Bool>
+ ) -> Cancellable {
+ let responseHandler = rustEmptyResponseHandler()
+
+ return createNetworkOperation(
+ request: .deleteDevice(retryStrategy, accountNumber: accountNumber, identifier: identifier),
+ responseHandler: responseHandler
+ ) { result in
+ if case let .failure(err) = result {
+ completion(.failure(err))
+ } else {
+ completion(.success(true))
+ }
+ }
+ }
+
+ func rotateDeviceKey(
+ accountNumber: String,
+ identifier: String,
+ publicKey: PublicKey,
+ retryStrategy: REST.RetryStrategy,
+ completion: @escaping ProxyCompletionHandler<Device>
+ ) -> Cancellable {
+ let responseHandler = rustResponseHandler(
+ decoding: Device.self,
+ with: responseDecoder
+ )
+
+ return createNetworkOperation(
+ request: .rotateDeviceKey(
+ retryStrategy,
+ accountNumber: accountNumber,
+ identifier: identifier,
+ publicKey: publicKey
+ ),
+ responseHandler: responseHandler,
+ completionHandler: completion
+ )
+ }
+
+ private func createNetworkOperation<Success: Any>(
+ request: APIRequest,
+ responseHandler: RustResponseHandler<Success>,
+ completionHandler: @escaping @Sendable ProxyCompletionHandler<Success>
+ ) -> MullvadApiNetworkOperation<Success> {
+ let networkOperation = MullvadApiNetworkOperation(
+ name: request.name,
+ dispatchQueue: dispatchQueue,
+ request: request,
+ transportProvider: transportProvider,
+ responseDecoder: responseDecoder,
+ responseHandler: responseHandler,
+ completionHandler: completionHandler
+ )
+
+ operationQueue.addOperation(networkOperation)
+
+ return networkOperation
+ }
+ }
+}
diff --git a/ios/MullvadREST/MullvadAPI/APIRequest/APIRequest.swift b/ios/MullvadREST/MullvadAPI/APIRequest/APIRequest.swift
index 92b6bb89b1..ab1087fe5e 100644
--- a/ios/MullvadREST/MullvadAPI/APIRequest/APIRequest.swift
+++ b/ios/MullvadREST/MullvadAPI/APIRequest/APIRequest.swift
@@ -6,16 +6,31 @@
// Copyright © 2025 Mullvad VPN AB. All rights reserved.
//
import MullvadTypes
+@preconcurrency import WireGuardKitTypes
public enum APIRequest: Codable, Sendable {
+ // Api Proxy
case getAddressList(_ retryStrategy: REST.RetryStrategy)
case getRelayList(_ retryStrategy: REST.RetryStrategy, etag: String?)
case sendProblemReport(_ retryStrategy: REST.RetryStrategy, problemReportRequest: ProblemReportRequest)
+ // Account Proxy
case createAccount(_ retryStrategy: REST.RetryStrategy)
case getAccount(_ retryStrategy: REST.RetryStrategy, accountNumber: String)
case deleteAccount(_ retryStrategy: REST.RetryStrategy, accountNumber: String)
+ // Device Proxy
+ case getDevice(_ retryStrategy: REST.RetryStrategy, accountNumber: String, identifier: String)
+ case getDevices(_ retryStrategy: REST.RetryStrategy, accountNumber: String)
+ case createDevice(_ retryStrategy: REST.RetryStrategy, accountNumber: String, request: CreateDeviceRequest)
+ case deleteDevice(_ retryStrategy: REST.RetryStrategy, accountNumber: String, identifier: String)
+ case rotateDeviceKey(
+ _ retryStrategy: REST.RetryStrategy,
+ accountNumber: String,
+ identifier: String,
+ publicKey: PublicKey
+ )
+
var name: String {
switch self {
case .getAddressList:
@@ -30,19 +45,33 @@ public enum APIRequest: Codable, Sendable {
"get-account"
case .deleteAccount:
"delete-account"
+ case .getDevice:
+ "get-device"
+ case .getDevices:
+ "get-devices"
+ case .deleteDevice:
+ "delete-device"
+ case .rotateDeviceKey:
+ "rotate-device-key"
+ case .createDevice:
+ "create-device"
}
}
var retryStrategy: REST.RetryStrategy {
switch self {
- case
- let .getAddressList(strategy),
- let .getRelayList(strategy, _),
- let .sendProblemReport(strategy, _),
- let .createAccount(strategy),
- let .getAccount(strategy, _),
- let .deleteAccount(strategy, _):
- strategy
+ case let .getAddressList(strategy),
+ let .getRelayList(strategy, _),
+ let .sendProblemReport(strategy, _),
+ let .createAccount(strategy),
+ let .getAccount(strategy, _),
+ let .deleteAccount(strategy, _),
+ let .createDevice(strategy, _, _),
+ let .getDevice(strategy, _, _),
+ let .getDevices(strategy, _),
+ let .deleteDevice(strategy, _, _),
+ let .rotateDeviceKey(strategy, _, _, _):
+ return strategy
}
}
}
diff --git a/ios/MullvadREST/MullvadAPI/MullvadApiRequestFactory.swift b/ios/MullvadREST/MullvadAPI/MullvadApiRequestFactory.swift
index 0b3271c80b..3f29468d9b 100644
--- a/ios/MullvadREST/MullvadAPI/MullvadApiRequestFactory.swift
+++ b/ios/MullvadREST/MullvadAPI/MullvadApiRequestFactory.swift
@@ -67,6 +67,50 @@ public struct MullvadApiRequestFactory: Sendable {
retryStrategy.toRustStrategy(),
accountNumber
))
+
+ // Device Proxy
+ case let .getDevice(retryStrategy, accountNumber: accountNumber, identifier):
+ return MullvadApiCancellable(handle: mullvad_ios_get_device(
+ apiContext.context,
+ rawCompletionPointer,
+ retryStrategy.toRustStrategy(),
+ accountNumber,
+ identifier
+ ))
+
+ case let .getDevices(retryStrategy, accountNumber):
+ return MullvadApiCancellable(handle: mullvad_ios_get_devices(
+ apiContext.context,
+ rawCompletionPointer,
+ retryStrategy.toRustStrategy(),
+ accountNumber
+ ))
+
+ case let .deleteDevice(retryStrategy, accountNumber, identifier):
+ return MullvadApiCancellable(handle: mullvad_ios_delete_device(
+ apiContext.context,
+ rawCompletionPointer,
+ retryStrategy.toRustStrategy(),
+ accountNumber,
+ identifier
+ ))
+ case let .rotateDeviceKey(retryStrategy, accountNumber, identifier, publicKey):
+ return MullvadApiCancellable(handle: mullvad_ios_rotate_device_key(
+ apiContext.context,
+ rawCompletionPointer,
+ retryStrategy.toRustStrategy(),
+ accountNumber,
+ identifier,
+ publicKey.rawValue.map { $0 }
+ ))
+ case let .createDevice(retryStrategy, accountNumber, request):
+ return MullvadApiCancellable(handle: mullvad_ios_create_device(
+ apiContext.context,
+ rawCompletionPointer,
+ retryStrategy.toRustStrategy(),
+ accountNumber,
+ request.publicKey.rawValue.map { $0 }
+ ))
}
}
}
diff --git a/ios/MullvadRustRuntime/include/mullvad_rust_runtime.h b/ios/MullvadRustRuntime/include/mullvad_rust_runtime.h
index 6300b04902..b4f4a65e2f 100644
--- a/ios/MullvadRustRuntime/include/mullvad_rust_runtime.h
+++ b/ios/MullvadRustRuntime/include/mullvad_rust_runtime.h
@@ -361,6 +361,119 @@ extern void mullvad_api_completion_finish(struct SwiftMullvadApiResponse respons
struct CompletionCookie completion_cookie);
/**
+ * Get device info via the Mullvad API client.
+ *
+ * # Safety
+ *
+ * `api_context` must be pointing to a valid instance of `SwiftApiContext`. A `SwiftApiContext` is created
+ * by calling `mullvad_ios_init_new`.
+ *
+ * This function takes ownership of `completion_cookie`, which must be pointing to a valid instance of Swift
+ * object `MullvadApiCompletion`. The pointer will be freed by calling `mullvad_ios_completion_finish`
+ * when completion finishes (in completion.finish).
+ *
+ * the `account_number` must be a pointer to a null terminated string.
+ * the `identifier` must be a pointer to a null terminated string.
+ *
+ * This function is not safe to call multiple times with the same `CompletionCookie`.
+ */
+struct SwiftCancelHandle mullvad_ios_get_device(struct SwiftApiContext api_context,
+ void *completion_cookie,
+ struct SwiftRetryStrategy retry_strategy,
+ const char *account_number,
+ const char *identifier);
+
+/**
+ * Get devices info via the Mullvad API client.
+ *
+ * # Safety
+ *
+ * `api_context` must be pointing to a valid instance of `SwiftApiContext`. A `SwiftApiContext` is created
+ * by calling `mullvad_api_init_new`.
+ *
+ * This function takes ownership of `completion_cookie`, which must be pointing to a valid instance of Swift
+ * object `MullvadApiCompletion`. The pointer will be freed by calling `mullvad_api_completion_finish`
+ * when completion finishes (in completion.finish).
+ *
+ * the `account_number` must be a pointer to a null terminated string.
+ *
+ * This function is not safe to call multiple times with the same `CompletionCookie`.
+ */
+struct SwiftCancelHandle mullvad_ios_get_devices(struct SwiftApiContext api_context,
+ void *completion_cookie,
+ struct SwiftRetryStrategy retry_strategy,
+ const char *account_number);
+
+/**
+ * create device via the Mullvad API client.
+ *
+ * # Safety
+ *
+ * `api_context` must be pointing to a valid instance of `SwiftApiContext`. A `SwiftApiContext` is created
+ * by calling `mullvad_api_init_new`.
+ *
+ * This function takes ownership of `completion_cookie`, which must be pointing to a valid instance of Swift
+ * object `MullvadApiCompletion`. The pointer will be freed by calling `mullvad_api_completion_finish`
+ * when completion finishes (in completion.finish).
+ *
+ * the `account_number` must be a pointer to a null terminated string.
+ * the `identifier` must be a pointer to a null terminated string.
+ * the `public_key` pointer must be a valid pointer to 32 unsigned bytes.
+ * This function is not safe to call multiple times with the same `CompletionCookie`.
+ */
+struct SwiftCancelHandle mullvad_ios_create_device(struct SwiftApiContext api_context,
+ void *completion_cookie,
+ struct SwiftRetryStrategy retry_strategy,
+ const char *account_number,
+ const uint8_t *public_key);
+
+/**
+ * delete device via the Mullvad API client.
+ *
+ * # Safety
+ *
+ * `api_context` must be pointing to a valid instance of `SwiftApiContext`. A `SwiftApiContext` is created
+ * by calling `mullvad_api_init_new`.
+ *
+ * This function takes ownership of `completion_cookie`, which must be pointing to a valid instance of Swift
+ * object `MullvadApiCompletion`. The pointer will be freed by calling `mullvad_api_completion_finish`
+ * when completion finishes (in completion.finish).
+ *
+ * the `account_number` must be a pointer to a null terminated string.
+ * the `identifier` must be a pointer to a null terminated string.
+ * This function is not safe to call multiple times with the same `CompletionCookie`.
+ */
+struct SwiftCancelHandle mullvad_ios_delete_device(struct SwiftApiContext api_context,
+ void *completion_cookie,
+ struct SwiftRetryStrategy retry_strategy,
+ const char *account_number,
+ const char *identifier);
+
+/**
+ * rotate device key via the Mullvad API client.
+ *
+ * # Safety
+ *
+ * `api_context` must be pointing to a valid instance of `SwiftApiContext`. A `SwiftApiContext` is created
+ * by calling `mullvad_api_init_new`.
+ *
+ * This function takes ownership of `completion_cookie`, which must be pointing to a valid instance of Swift
+ * object `MullvadApiCompletion`. The pointer will be freed by calling `mullvad_api_completion_finish`
+ * when completion finishes (in completion.finish).
+ *
+ * the `account_number` must be a pointer to a null terminated string.
+ * the `identifier` must be a pointer to a null terminated string.
+ * the `public_key` pointer must be a valid pointer to 32 unsigned bytes.
+ * This function is not safe to call multiple times with the same `CompletionCookie`.
+ */
+struct SwiftCancelHandle mullvad_ios_rotate_device_key(struct SwiftApiContext api_context,
+ void *completion_cookie,
+ struct SwiftRetryStrategy retry_strategy,
+ const char *account_number,
+ const char *identifier,
+ const uint8_t *public_key);
+
+/**
* Converts parameters into a boxed `Shadowsocks` configuration that is safe
* to send across the FFI boundary
*
diff --git a/ios/MullvadTypes/RESTTypes.swift b/ios/MullvadTypes/RESTTypes.swift
index 6ba5c08297..dee960ca27 100644
--- a/ios/MullvadTypes/RESTTypes.swift
+++ b/ios/MullvadTypes/RESTTypes.swift
@@ -69,3 +69,43 @@ public struct ProblemReportRequest: Codable, Sendable {
self.metadata = metadata
}
}
+
+public struct CreateDeviceRequest: Codable, Sendable {
+ public let publicKey: PublicKey
+ public let hijackDNS: Bool
+
+ public init(publicKey: PublicKey, hijackDNS: Bool) {
+ self.publicKey = publicKey
+ self.hijackDNS = hijackDNS
+ }
+
+ private enum CodingKeys: String, CodingKey {
+ case hijackDNS = "hijackDns"
+ case publicKey = "pubkey"
+ }
+
+ public func encode(to encoder: Encoder) throws {
+ var container = encoder.container(keyedBy: CodingKeys.self)
+
+ try container.encode(publicKey.base64Key, forKey: .publicKey)
+ try container.encode(hijackDNS, forKey: .hijackDNS)
+ }
+}
+
+public struct RotateDeviceKeyRequest: Codable, Sendable {
+ let publicKey: PublicKey
+
+ public init(publicKey: PublicKey) {
+ self.publicKey = publicKey
+ }
+
+ private enum CodingKeys: String, CodingKey {
+ case publicKey = "pubkey"
+ }
+
+ public func encode(to encoder: Encoder) throws {
+ var container = encoder.container(keyedBy: CodingKeys.self)
+
+ try container.encode(publicKey.base64Key, forKey: .publicKey)
+ }
+}
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj
index 26406d4230..9d291a7ae5 100644
--- a/ios/MullvadVPN.xcodeproj/project.pbxproj
+++ b/ios/MullvadVPN.xcodeproj/project.pbxproj
@@ -1026,6 +1026,7 @@
F0A086902C22D6A700BF83E7 /* TunnelSettingsStrategyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0A0868F2C22D6A700BF83E7 /* TunnelSettingsStrategyTests.swift */; };
F0A7EBB22CEF6C79005BB671 /* ConsolidatedApplicationLogTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0A7EBB12CEF6C79005BB671 /* ConsolidatedApplicationLogTests.swift */; };
F0A7EBB62CF092CC005BB671 /* ApplicationConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58BFA5CB22A7CE1F00A6173D /* ApplicationConfiguration.swift */; };
+ F0A89CB32D9D6C2100580C27 /* MullvadDeviceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0A89CB22D9D6C1400580C27 /* MullvadDeviceProxy.swift */; };
F0A89CB52D9D864B00580C27 /* RustProblemReportRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0EEFB9E2D8D60E1007FE4B3 /* RustProblemReportRequest.swift */; };
F0A89CB72D9D923300580C27 /* String+UnsafePointer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0A89CB62D9D922300580C27 /* String+UnsafePointer.swift */; };
F0ACE30D2BE4E478006D5333 /* MullvadMockData.h in Headers */ = {isa = PBXBuildFile; fileRef = F0ACE30A2BE4E478006D5333 /* MullvadMockData.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -2454,6 +2455,7 @@
F0A0868F2C22D6A700BF83E7 /* TunnelSettingsStrategyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelSettingsStrategyTests.swift; sourceTree = "<group>"; };
F0A163882C47B46300592300 /* SingleHopEphemeralPeerExchangerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleHopEphemeralPeerExchangerTests.swift; sourceTree = "<group>"; };
F0A7EBB12CEF6C79005BB671 /* ConsolidatedApplicationLogTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConsolidatedApplicationLogTests.swift; sourceTree = "<group>"; };
+ F0A89CB22D9D6C1400580C27 /* MullvadDeviceProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MullvadDeviceProxy.swift; sourceTree = "<group>"; };
F0A89CB62D9D922300580C27 /* String+UnsafePointer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+UnsafePointer.swift"; sourceTree = "<group>"; };
F0ACE3082BE4E478006D5333 /* MullvadMockData.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MullvadMockData.framework; sourceTree = BUILT_PRODUCTS_DIR; };
F0ACE30A2BE4E478006D5333 /* MullvadMockData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MullvadMockData.h; sourceTree = "<group>"; };
@@ -4223,6 +4225,7 @@
children = (
7AB73F6D2D9AAD0400DA5E1D /* MullvadAccountProxy.swift */,
7A2C0E8B2D8B13E8003D8048 /* MullvadAPIProxy.swift */,
+ F0A89CB22D9D6C1400580C27 /* MullvadDeviceProxy.swift */,
);
path = APIHandlers;
sourceTree = "<group>";
@@ -5854,6 +5857,7 @@
A9D99B9A2A1F7C3200DE27D3 /* RESTTransport.swift in Sources */,
A90763BB2B2857D50045ADF0 /* Socks5AddressType.swift in Sources */,
7A99D36F2D56070400891FF7 /* MullvadApiRequestFactory.swift in Sources */,
+ F0A89CB32D9D6C2100580C27 /* MullvadDeviceProxy.swift in Sources */,
F0F3161B2BF358590078DBCF /* NoRelaysSatisfyingConstraintsError.swift in Sources */,
06799AE028F98E4800ACD94E /* RESTCoding.swift in Sources */,
A90763B72B2857D50045ADF0 /* Socks5DataStreamHandler.swift in Sources */,
diff --git a/ios/MullvadVPN/TunnelManager/SetAccountOperation.swift b/ios/MullvadVPN/TunnelManager/SetAccountOperation.swift
index 07467a5ca8..c018078989 100644
--- a/ios/MullvadVPN/TunnelManager/SetAccountOperation.swift
+++ b/ios/MullvadVPN/TunnelManager/SetAccountOperation.swift
@@ -392,7 +392,7 @@ class SetAccountOperation: ResultOperation<StoredAccountData?>, @unchecked Senda
completion: @escaping @Sendable (Result<NewDevice, Error>) -> Void
) {
let privateKey = PrivateKey()
- let request = REST.CreateDeviceRequest(publicKey: privateKey.publicKey, hijackDNS: false)
+ let request = CreateDeviceRequest(publicKey: privateKey.publicKey, hijackDNS: false)
logger.debug("Create device...")