diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberRepository.kt index 2048288178..f9ab356b63 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberRepository.kt @@ -46,11 +46,11 @@ import org.whispersystems.signalservice.api.push.ServiceIdType import org.whispersystems.signalservice.api.push.SignalServiceAddress import org.whispersystems.signalservice.api.push.SignedPreKeyEntity import org.whispersystems.signalservice.internal.push.KyberPreKeyEntity +import org.whispersystems.signalservice.internal.push.MismatchedDevices import org.whispersystems.signalservice.internal.push.OutgoingPushMessage import org.whispersystems.signalservice.internal.push.SyncMessage import org.whispersystems.signalservice.internal.push.VerifyAccountResponse import org.whispersystems.signalservice.internal.push.WhoAmIResponse -import org.whispersystems.signalservice.internal.push.exceptions.MismatchedDevicesException import java.io.IOException import java.security.MessageDigest import java.security.SecureRandom @@ -267,12 +267,14 @@ class ChangeNumberRepository( SignalStore.misc.setPendingChangeNumberMetadata(metadata) withContext(Dispatchers.IO) { - result = accountManager.registrationApi.changeNumber(request) + result = SignalNetwork.account.changeNumber(request) } - val possibleError = result.getCause() as? MismatchedDevicesException - if (possibleError != null) { - messageSender.handleChangeNumberMismatchDevices(possibleError.mismatchedDevices) + if (result is NetworkResult.StatusCodeError && result.code == 409) { + val mismatchedDevices: MismatchedDevices? = result.parseJsonBody() + if (mismatchedDevices != null) { + messageSender.handleChangeNumberMismatchDevices(mismatchedDevices) + } attempts++ } else { completed = true diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberResult.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberResult.kt index 65aaee7e62..1ae6dba84f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberResult.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberResult.kt @@ -9,13 +9,10 @@ import org.thoughtcrime.securesms.pin.SvrWrongPinException import org.thoughtcrime.securesms.registration.data.network.RegistrationResult import org.whispersystems.signalservice.api.NetworkResult import org.whispersystems.signalservice.api.SvrNoDataException -import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException -import org.whispersystems.signalservice.api.push.exceptions.IncorrectRegistrationRecoveryPasswordException -import org.whispersystems.signalservice.api.push.exceptions.MalformedRequestException -import org.whispersystems.signalservice.api.push.exceptions.RateLimitException +import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException import org.whispersystems.signalservice.api.svr.Svr3Credentials import org.whispersystems.signalservice.internal.push.AuthCredentials -import org.whispersystems.signalservice.internal.push.LockedException +import org.whispersystems.signalservice.internal.push.PushServiceSocket.RegistrationLockFailure import org.whispersystems.signalservice.internal.push.VerifyAccountResponse /** @@ -29,27 +26,29 @@ sealed class ChangeNumberResult(cause: Throwable?) : RegistrationResult(cause) { is NetworkResult.ApplicationError -> UnknownError(networkResult.throwable) is NetworkResult.NetworkError -> UnknownError(networkResult.exception) is NetworkResult.StatusCodeError -> { - when (val cause = networkResult.exception) { - is IncorrectRegistrationRecoveryPasswordException -> IncorrectRecoveryPassword(cause) - is AuthorizationFailedException -> AuthorizationFailed(cause) - is MalformedRequestException -> MalformedRequest(cause) - is RateLimitException -> createRateLimitProcessor(cause) - is LockedException -> RegistrationLocked(cause = cause, timeRemaining = cause.timeRemaining, svr2Credentials = cause.svr2Credentials, svr3Credentials = cause.svr3Credentials) - else -> { - if (networkResult.code == 422) { - ValidationError(cause) + when (networkResult.code) { + 403 -> IncorrectRecoveryPassword(networkResult.exception) + 401 -> AuthorizationFailed(networkResult.exception) + 400 -> MalformedRequest(networkResult.exception) + 429 -> createRateLimitProcessor(networkResult.exception, networkResult.header("retry-after")?.toLongOrNull()) + 423 -> { + val registrationLockFailure: RegistrationLockFailure? = networkResult.parseJsonBody() + if (registrationLockFailure != null) { + RegistrationLocked(cause = networkResult.exception, timeRemaining = registrationLockFailure.timeRemaining, svr2Credentials = registrationLockFailure.svr2Credentials, svr3Credentials = registrationLockFailure.svr3Credentials) } else { - UnknownError(cause) + UnknownError(networkResult.exception) } } + 422 -> ValidationError(networkResult.exception) + else -> UnknownError(networkResult.exception) } } } } - private fun createRateLimitProcessor(exception: RateLimitException): ChangeNumberResult { - return if (exception.retryAfterMilliseconds.isPresent) { - RateLimited(exception, exception.retryAfterMilliseconds.get()) + private fun createRateLimitProcessor(exception: NonSuccessfulResponseCodeException, retryAfter: Long?): ChangeNumberResult { + return if (retryAfter != null) { + RateLimited(exception, retryAfter) } else { AttemptsExhausted(exception) } diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/registration/RegistrationApi.kt b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/registration/RegistrationApi.kt index 26b42f9566..eafb34e22b 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/registration/RegistrationApi.kt +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/registration/RegistrationApi.kt @@ -7,7 +7,6 @@ package org.whispersystems.signalservice.api.registration import org.whispersystems.signalservice.api.NetworkResult import org.whispersystems.signalservice.api.account.AccountAttributes -import org.whispersystems.signalservice.api.account.ChangePhoneNumberRequest import org.whispersystems.signalservice.api.account.PreKeyCollection import org.whispersystems.signalservice.api.provisioning.RestoreMethod import org.whispersystems.signalservice.internal.push.BackupV2AuthCheckResponse @@ -134,15 +133,4 @@ class RegistrationApi( pushServiceSocket.setRestoreMethodChosen(token, RestoreMethodBody(method = method)) } } - - /** - * Changes the phone number that an account is associated with. - * - * `PUT /v2/accounts/number` - */ - fun changeNumber(requestBody: ChangePhoneNumberRequest): NetworkResult { - return NetworkResult.fromFetch { - pushServiceSocket.changeNumber(requestBody) - } - } } diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java index db8fe937cd..9b3606f51d 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java @@ -25,7 +25,6 @@ import org.signal.storageservice.protos.groups.GroupResponse; import org.signal.storageservice.protos.groups.Member; import org.whispersystems.signalservice.api.NetworkResult; import org.whispersystems.signalservice.api.account.AccountAttributes; -import org.whispersystems.signalservice.api.account.ChangePhoneNumberRequest; import org.whispersystems.signalservice.api.account.PreKeyCollection; import org.whispersystems.signalservice.api.crypto.SealedSenderAccess; import org.whispersystems.signalservice.api.groupsv2.GroupsV2AuthorizationString; @@ -328,16 +327,6 @@ public class PushServiceSocket { return JsonUtil.fromJson(response, VerifyAccountResponse.class); } - - public VerifyAccountResponse changeNumber(@Nonnull ChangePhoneNumberRequest changePhoneNumberRequest) - throws IOException - { - String requestBody = JsonUtil.toJson(changePhoneNumberRequest); - String responseBody = makeServiceRequest("/v2/accounts/number", "PUT", requestBody); - - return JsonUtil.fromJson(responseBody, VerifyAccountResponse.class); - } - public void setRestoreMethodChosen(@Nonnull String token, @Nonnull RestoreMethodBody request) throws IOException { String body = JsonUtil.toJson(request); makeServiceRequest(String.format(Locale.US, SET_RESTORE_METHOD_PATH, urlEncode(token)), "PUT", body, NO_HEADERS, UNOPINIONATED_HANDLER, SealedSenderAccess.NONE);