diff --git a/Signal/Registration/RegistrationCoordinatorImpl+Service.swift b/Signal/Registration/RegistrationCoordinatorImpl+Service.swift index f93bfc1266..2ecf09f211 100644 --- a/Signal/Registration/RegistrationCoordinatorImpl+Service.swift +++ b/Signal/Registration/RegistrationCoordinatorImpl+Service.swift @@ -20,12 +20,12 @@ extension RegistrationCoordinatorImpl { e164: E164, candidateCredentials: [SVR2AuthCredential], signalService: OWSSignalServiceProtocol, - ) -> Guarantee { + ) async -> SVR2AuthCheckResponse { let request = RegistrationRequestFactory.svr2AuthCredentialCheckRequest( e164: e164, credentials: candidateCredentials ) - return makeRequest( + return await makeRequest( request, signalService: signalService, handler: self.handleSVR2AuthCheckResponse(statusCode:retryAfterHeader:bodyData:), @@ -69,7 +69,7 @@ extension RegistrationCoordinatorImpl { apnRegistrationId: RegistrationRequestFactory.ApnRegistrationId?, prekeyBundles: RegistrationPreKeyUploadBundles, signalService: OWSSignalServiceProtocol, - ) -> Guarantee { + ) async -> AccountResponse { let request = RegistrationRequestFactory.createAccountRequest( verificationMethod: method, e164: e164, @@ -79,7 +79,7 @@ extension RegistrationCoordinatorImpl { apnRegistrationId: apnRegistrationId, prekeyBundles: prekeyBundles ) - return makeRequest( + return await makeRequest( request, signalService: signalService, handler: { @@ -178,14 +178,14 @@ extension RegistrationCoordinatorImpl { authPassword: String, pniChangeNumberParameters: PniDistribution.Parameters, signalService: OWSSignalServiceProtocol, - ) -> Guarantee { + ) async -> AccountResponse { let request = RegistrationRequestFactory.changeNumberRequest( verificationMethod: method, e164: e164, reglockToken: reglockToken, pniChangeNumberParameters: pniChangeNumberParameters ) - return makeRequest( + return await makeRequest( request, signalService: signalService, handler: { @@ -363,32 +363,28 @@ extension RegistrationCoordinatorImpl { private static func makeRequest( _ request: TSRequest, signalService: OWSSignalServiceProtocol, - handler: @escaping (_ statusCode: Int, _ retryAfterHeader: String?, _ bodyData: Data?) -> ResponseType, + handler: (_ statusCode: Int, _ retryAfterHeader: String?, _ bodyData: Data?) -> ResponseType, fallbackError: ResponseType, networkFailureError: ResponseType - ) -> Guarantee { - return signalService.urlSessionForMainSignalService().promiseForTSRequest(request) - .map(on: DispatchQueue.global()) { (response: HTTPResponse) -> ResponseType in - return handler( - response.responseStatusCode, - response.headers[Constants.retryAfterHeader], - response.responseBodyData - ) - } - .recover(on: DispatchQueue.global()) { (error: Error) -> Guarantee in - if error.isNetworkFailureOrTimeout { - return .value(networkFailureError) - } - guard let error = error as? OWSHTTPError else { - return .value(fallbackError) - } - let response = handler( - error.responseStatusCode, - error.responseHeaders?[Constants.retryAfterHeader], - error.httpResponseData - ) - return .value(response) - } + ) async -> ResponseType { + do { + let response = try await signalService.urlSessionForMainSignalService().performRequest(request) + return handler( + response.responseStatusCode, + response.headers[Constants.retryAfterHeader], + response.responseBodyData + ) + } catch where error.isNetworkFailureOrTimeout { + return networkFailureError + } catch let error as OWSHTTPError { + return handler( + error.responseStatusCode, + error.responseHeaders?[Constants.retryAfterHeader], + error.httpResponseData + ) + } catch { + return fallbackError + } } enum Constants { diff --git a/Signal/Registration/RegistrationCoordinatorImpl.swift b/Signal/Registration/RegistrationCoordinatorImpl.swift index 9a226f3584..ed5e6837ee 100644 --- a/Signal/Registration/RegistrationCoordinatorImpl.swift +++ b/Signal/Registration/RegistrationCoordinatorImpl.swift @@ -2128,58 +2128,58 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator { // credential candidates to check, enter it now. return .value(.phoneNumberEntry(phoneNumberEntryState())) } - return makeSVR2AuthCredentialCheckRequest( - svr2AuthCredentialCandidates: svr2AuthCredentialCandidates, - e164: e164 - ) - } - - private func makeSVR2AuthCredentialCheckRequest( - svr2AuthCredentialCandidates: [SVR2AuthCredential], - e164: E164, - retriesLeft: Int = Constants.networkErrorRetries - ) -> Guarantee { - return Service.makeSVR2AuthCheckRequest( - e164: e164, - candidateCredentials: svr2AuthCredentialCandidates, - signalService: deps.signalService, - ).then(on: DispatchQueue.main) { [weak self] response in - guard let self else { - return unretainedSelfError() - } - return self.handleSVR2AuthCredentialCheckResponse( - response, + return Guarantee.wrapAsync { + return await self.makeSVR2AuthCredentialCheckRequest( svr2AuthCredentialCandidates: svr2AuthCredentialCandidates, - e164: e164, - retriesLeft: retriesLeft + e164: e164 ) } } + @MainActor + private func makeSVR2AuthCredentialCheckRequest( + svr2AuthCredentialCandidates: [SVR2AuthCredential], + e164: E164, + retriesLeft: Int = Constants.networkErrorRetries + ) async -> RegistrationStep { + let response = await Service.makeSVR2AuthCheckRequest( + e164: e164, + candidateCredentials: svr2AuthCredentialCandidates, + signalService: deps.signalService, + ) + return await self.handleSVR2AuthCredentialCheckResponse( + response, + svr2AuthCredentialCandidates: svr2AuthCredentialCandidates, + e164: e164, + retriesLeft: retriesLeft + ) + } + + @MainActor private func handleSVR2AuthCredentialCheckResponse( _ response: Service.SVR2AuthCheckResponse, svr2AuthCredentialCandidates: [SVR2AuthCredential], e164: E164, retriesLeft: Int - ) -> Guarantee { + ) async -> RegistrationStep { var matchedCredential: SVR2AuthCredential? var credentialsToDelete = [SVR2AuthCredential]() switch response { case .networkError: if retriesLeft > 0 { - return makeSVR2AuthCredentialCheckRequest( + return await makeSVR2AuthCredentialCheckRequest( svr2AuthCredentialCandidates: svr2AuthCredentialCandidates, e164: e164, retriesLeft: retriesLeft - 1 ) } self.inMemoryState.svr2AuthCredentialCandidates = nil - return self.nextStep() + return await self.nextStep().awaitable() case .genericError: // If we failed to verify, wipe the candidates so we don't try again // and keep going. self.inMemoryState.svr2AuthCredentialCandidates = nil - return self.nextStep() + return await self.nextStep().awaitable() case .success(let response): for candidate in svr2AuthCredentialCandidates { let result: RegistrationServiceResponses.SVR2AuthCheckResponse.Result? = response.result(for: candidate) @@ -2203,7 +2203,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator { self.db.write { tx in self.deps.svrAuthCredentialStore.deleteInvalidCredentials(credentialsToDelete, tx) } - return self.nextStep() + return await self.nextStep().awaitable() } // MARK: - RegistrationSession Pathway @@ -4216,47 +4216,48 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator { guard let prekeyBundles else { return .value(.showErrorSheet(.genericError)) } - return Service - .makeCreateAccountRequest( + let shouldSkipDeviceTransfer = self.shouldSkipDeviceTransfer() + let signalService = self.deps.signalService + return Guarantee.wrapAsync { @MainActor [weak self] () -> RegistrationStep in + let accountResponse = await Service.makeCreateAccountRequest( method, e164: e164, authPassword: authPassword, accountAttributes: accountAttributes, - skipDeviceTransfer: self.shouldSkipDeviceTransfer(), + skipDeviceTransfer: shouldSkipDeviceTransfer, apnRegistrationId: apnRegistrationId, prekeyBundles: prekeyBundles, - signalService: self.deps.signalService, + signalService: signalService, ) - .then(on: DispatchQueue.main) { [weak self] (accountResponse: AccountResponse) -> Guarantee in - guard let self else { - return unretainedSelfError() - } - let isPrekeyUploadSuccess: Bool - switch accountResponse { - case .success: - isPrekeyUploadSuccess = true - case - .retryAfter, - .rejectedVerificationMethod, - .reglockFailure, - .networkError, - .genericError, - .deviceTransferPossible: - isPrekeyUploadSuccess = false - } - return self.deps.preKeyManager - .finalizeRegistrationPreKeys( - prekeyBundles, - uploadDidSucceed: isPrekeyUploadSuccess - ).recover(on: SyncScheduler()) { error in - // Finalizing is best effort. - Logger.error("Unable to finalize prekeys, ignoring and continuing") - return .value(()) - } - .then(on: DispatchQueue.main) { () -> Guarantee in - return responseHandler(accountResponse) - } + guard let self else { + return unretainedSelfErrorStep() } + let isPrekeyUploadSuccess: Bool + switch accountResponse { + case .success: + isPrekeyUploadSuccess = true + case + .retryAfter, + .rejectedVerificationMethod, + .reglockFailure, + .networkError, + .genericError, + .deviceTransferPossible: + isPrekeyUploadSuccess = false + } + return await self.deps.preKeyManager + .finalizeRegistrationPreKeys( + prekeyBundles, + uploadDidSucceed: isPrekeyUploadSuccess + ).recover(on: SyncScheduler()) { error in + // Finalizing is best effort. + Logger.error("Unable to finalize prekeys, ignoring and continuing") + return .value(()) + } + .then(on: DispatchQueue.main) { () -> Guarantee in + return responseHandler(accountResponse) + }.awaitable() + } } } @@ -4339,16 +4340,16 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator { case .v1, .none: reglockToken = nil } - return Service - .makeChangeNumberRequest( + return Guarantee.wrapAsync { + return .serviceResponse(await Service.makeChangeNumberRequest( verificationMethod, e164: e164, reglockToken: reglockToken, authPassword: changeNumberState.oldAuthToken, pniChangeNumberParameters: pniParams, signalService: strongSelf.deps.signalService, - ) - .map(on: SyncScheduler()) { .serviceResponse($0) } + )) + } } }