From afb9b76208502e3ead44e0b499c1e2c2f865932a Mon Sep 17 00:00:00 2001 From: Nicholas Date: Wed, 22 Feb 2023 16:54:14 -0500 Subject: [PATCH] Bug fixes for the new registration flow. --- .../registration/VerifyAccountRepository.kt | 6 ++++++ .../fragments/BaseEnterSmsCodeFragment.java | 13 +++++++++++-- .../fragments/EnterPhoneNumberFragment.java | 15 ++++++++++++--- .../util/RegistrationNumberInputController.kt | 7 +++++-- .../viewmodel/BaseRegistrationViewModel.java | 13 ++++++++++++- .../viewmodel/RegistrationViewModel.java | 14 +++++++++++--- .../api/push/exceptions/IncorrectCodeException.kt | 3 +++ 7 files changed, 60 insertions(+), 11 deletions(-) create mode 100644 libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/exceptions/IncorrectCodeException.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/VerifyAccountRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/registration/VerifyAccountRepository.kt index ebf99f134..f3cfe36af 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/VerifyAccountRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/VerifyAccountRepository.kt @@ -182,6 +182,12 @@ class VerifyAccountRepository(private val context: Application) { }.subscribeOn(Schedulers.io()) } + fun getFcmToken(): Single { + return Single.fromCallable { + return@fromCallable FcmUtil.getToken(context).orElse("") + }.subscribeOn(Schedulers.io()) + } + interface KbsPinDataProducer { @Throws(IOException::class, KeyBackupSystemWrongPinException::class, KeyBackupSystemNoDataException::class) fun produceKbsPinData(): KbsPinData diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/BaseEnterSmsCodeFragment.java b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/BaseEnterSmsCodeFragment.java index 606e2a06e..fcd67f865 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/BaseEnterSmsCodeFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/fragments/BaseEnterSmsCodeFragment.java @@ -6,6 +6,7 @@ import android.widget.ScrollView; import android.widget.TextView; import android.widget.Toast; +import androidx.activity.OnBackPressedCallback; import androidx.annotation.CallSuper; import androidx.annotation.LayoutRes; import androidx.annotation.NonNull; @@ -124,6 +125,15 @@ public abstract class BaseEnterSmsCodeFragment { if (processor.verificationCodeRequestSuccess()) { + disposables.add(updateFcmTokenValue()); SafeNavigation.safeNavigate(navController, EnterPhoneNumberFragmentDirections.actionEnterVerificationCode()); } else if (processor.captchaRequired()) { Log.i(TAG, "Unable to request sms code due to captcha required"); @@ -301,6 +301,10 @@ public final class EnterPhoneNumberFragment extends LoggingFragment implements R disposables.add(request); } + private Disposable updateFcmTokenValue() { + return viewModel.updateFcmTokenValue().subscribe(); + } + private String formatMillisecondsToString(long milliseconds) { long totalSeconds = milliseconds / 1000; long HH = totalSeconds / 3600; @@ -350,7 +354,12 @@ public final class EnterPhoneNumberFragment extends LoggingFragment implements R .observeOn(AndroidSchedulers.mainThread()) .subscribe(processor -> { if (processor.hasResult() && processor.canSubmitProofImmediately()) { - SafeNavigation.safeNavigate(navController, EnterPhoneNumberFragmentDirections.actionEnterVerificationCode()); + try { + viewModel.restorePhoneNumberStateFromE164(sessionE164); + SafeNavigation.safeNavigate(navController, EnterPhoneNumberFragmentDirections.actionEnterVerificationCode()); + } catch (NumberParseException numberParseException) { + viewModel.resetSession(); + } } else { viewModel.resetSession(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/util/RegistrationNumberInputController.kt b/app/src/main/java/org/thoughtcrime/securesms/registration/util/RegistrationNumberInputController.kt index f6cccc54e..919182055 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/util/RegistrationNumberInputController.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/util/RegistrationNumberInputController.kt @@ -32,6 +32,7 @@ class RegistrationNumberInputController( .map { CountryPrefix(it, PhoneNumberUtil.getInstance().getRegionCodeForCountryCode(it)) } .sortedBy { it.digits } private val spinnerAdapter: ArrayAdapter = ArrayAdapter(context, R.layout.registration_country_code_dropdown_item, supportedCountryPrefixes) + private val countryCodeEntryListener = CountryCodeEntryListener() private var countryFormatter: AsYouTypeFormatter? = null private var isUpdating = true @@ -41,11 +42,13 @@ class RegistrationNumberInputController( spinnerView.threshold = 100 spinnerView.setAdapter(spinnerAdapter) - spinnerView.addTextChangedListener(CountryCodeEntryListener()) + spinnerView.addTextChangedListener(countryCodeEntryListener) } fun prepopulateCountryCode() { - spinnerView.setText(supportedCountryPrefixes[0].toString()) + if (spinnerView.editableText.isBlank()) { + spinnerView.setText(supportedCountryPrefixes[0].toString()) + } } private fun advanceToPhoneNumberInput() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/viewmodel/BaseRegistrationViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/registration/viewmodel/BaseRegistrationViewModel.java index 8e8a5bcf8..7644617bb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/viewmodel/BaseRegistrationViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/viewmodel/BaseRegistrationViewModel.java @@ -6,6 +6,10 @@ import androidx.lifecycle.LiveData; import androidx.lifecycle.SavedStateHandle; import androidx.lifecycle.ViewModel; +import com.google.i18n.phonenumbers.NumberParseException; +import com.google.i18n.phonenumbers.PhoneNumberUtil; +import com.google.i18n.phonenumbers.Phonenumber; + import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.pin.KbsRepository; import org.thoughtcrime.securesms.pin.TokenData; @@ -102,10 +106,17 @@ public abstract class BaseRegistrationViewModel extends ViewModel { return savedState.getLiveData(STATE_NUMBER); } + public void restorePhoneNumberStateFromE164(String e164) throws NumberParseException { + Phonenumber.PhoneNumber phoneNumber = PhoneNumberUtil.getInstance().parse(e164, null); + onCountrySelected(null, phoneNumber.getCountryCode()); + setNationalNumber(String.valueOf(phoneNumber.getNationalNumber())); + } + public void onCountrySelected(@Nullable String selectedCountryName, int countryCode) { setViewState(getNumber().toBuilder() .selectedCountryDisplayName(selectedCountryName) - .countryCode(countryCode).build()); + .countryCode(countryCode) + .build()); } public void setNationalNumber(String number) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/viewmodel/RegistrationViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/registration/viewmodel/RegistrationViewModel.java index 83b80c937..579878d0a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/viewmodel/RegistrationViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/viewmodel/RegistrationViewModel.java @@ -26,12 +26,12 @@ import org.thoughtcrime.securesms.registration.VerifyAccountRepository; import org.thoughtcrime.securesms.registration.VerifyResponse; import org.thoughtcrime.securesms.registration.VerifyResponseProcessor; import org.thoughtcrime.securesms.registration.VerifyResponseWithRegistrationLockProcessor; -import org.thoughtcrime.securesms.registration.VerifyResponseWithSuccessfulKbs; import org.thoughtcrime.securesms.registration.VerifyResponseWithoutKbs; import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.Util; import org.whispersystems.signalservice.api.KbsPinData; import org.whispersystems.signalservice.api.KeyBackupSystemNoDataException; +import org.whispersystems.signalservice.api.push.exceptions.IncorrectCodeException; import org.whispersystems.signalservice.internal.ServiceResponse; import org.whispersystems.signalservice.internal.push.RegistrationSessionMetadataResponse; @@ -123,13 +123,17 @@ public final class RegistrationViewModel extends BaseRegistrationViewModel { .map(RegistrationSessionProcessor.RegistrationSessionProcessorForVerification::new) .observeOn(AndroidSchedulers.mainThread()) .doOnSuccess(processor -> { - setCanSmsAtTime(processor.getNextCodeViaSmsAttempt()); - setCanCallAtTime(processor.getNextCodeViaCallAttempt()); + if (processor.hasResult()) { + setCanSmsAtTime(processor.getNextCodeViaSmsAttempt()); + setCanCallAtTime(processor.getNextCodeViaCallAttempt()); + } }) .observeOn(Schedulers.io()) .flatMap(processor -> { if (processor.isAlreadyVerified() || (processor.hasResult() && processor.isVerified())) { return verifyAccountRepository.registerAccount(sessionId, getRegistrationData(), null, null); + } else if (processor.getError() == null) { + return Single.just(ServiceResponse.forApplicationError(new IncorrectCodeException(), 403, null)); } else { return Single.just(ServiceResponse.coerceError(processor.getResponse())); } @@ -320,6 +324,10 @@ public final class RegistrationViewModel extends BaseRegistrationViewModel { .observeOn(AndroidSchedulers.mainThread()); } + public Single updateFcmTokenValue() { + return verifyAccountRepository.getFcmToken().observeOn(AndroidSchedulers.mainThread()).doOnSuccess(this::setFcmToken); + } + private void restoreFromStorageService() { SignalStore.onboarding().clearAll(); diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/exceptions/IncorrectCodeException.kt b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/exceptions/IncorrectCodeException.kt new file mode 100644 index 000000000..1772184dd --- /dev/null +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/exceptions/IncorrectCodeException.kt @@ -0,0 +1,3 @@ +package org.whispersystems.signalservice.api.push.exceptions + +class IncorrectCodeException : NonSuccessfulResponseCodeException(403)