Convert change number back to WebSocket.

This commit is contained in:
Cody Henthorne
2025-04-23 10:10:53 -04:00
parent 901b4b469d
commit 8007045ca8
4 changed files with 24 additions and 46 deletions

View File

@@ -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

View File

@@ -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)
}

View File

@@ -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<VerifyAccountResponse> {
return NetworkResult.fromFetch {
pushServiceSocket.changeNumber(requestBody)
}
}
}

View File

@@ -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);