Path: blob/main/SignalServiceKit/Network/API/DeviceProvisioningService.swift
1 views
//
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Foundation
public struct DeviceProvisioningTokenId {
public let id: String
fileprivate init(id: String) {
self.id = id
}
}
public struct DeviceProvisioningCodeResponse: Decodable {
/// An opaque token to send to a new linked device that authorizes the
/// new device to link itself to the account that requested this token.
public var verificationCode: String
/// An opaque identifier for the generated token that the caller may use
/// to watch for a new device to complete the linking process.
var tokenIdentifier: String
public var tokenId: DeviceProvisioningTokenId { .init(id: tokenIdentifier) }
}
public protocol DeviceProvisioningService {
func requestDeviceProvisioningCode() async throws -> DeviceProvisioningCodeResponse
func provisionDevice(messageBody: Data, ephemeralDeviceId: String) async throws
}
public class DeviceProvisioningServiceImpl: DeviceProvisioningService {
private let networkManager: any NetworkManagerProtocol
public init(networkManager: any NetworkManagerProtocol) {
self.networkManager = networkManager
}
public func requestDeviceProvisioningCode() async throws -> DeviceProvisioningCodeResponse {
do {
let request = OWSRequestFactory.deviceProvisioningCode()
let httpResponse = try await networkManager.asyncRequest(request)
guard let httpResponseData = httpResponse.responseBodyData else {
throw OWSAssertionError("Missing responseBodyData.")
}
let response = try JSONDecoder().decode(DeviceProvisioningCodeResponse.self, from: httpResponseData)
guard response.verificationCode.nilIfEmpty != nil else {
throw OWSAssertionError("Empty verificationCode.")
}
return response
} catch {
throw DeviceLimitExceededError(error) ?? error
}
}
public func provisionDevice(messageBody: Data, ephemeralDeviceId: String) async throws {
let request = OWSRequestFactory.provisionDevice(
withMessageBody: messageBody,
ephemeralDeviceId: ephemeralDeviceId,
)
do {
_ = try await networkManager.asyncRequest(request)
} catch {
owsFailDebugUnlessNetworkFailure(error)
throw error
}
}
}