kopia lustrzana https://github.com/ryukoposting/Signal-Android
Bug fixes for the new registration flow.
rodzic
4f458a022f
commit
afb9b76208
|
@ -182,6 +182,12 @@ class VerifyAccountRepository(private val context: Application) {
|
||||||
}.subscribeOn(Schedulers.io())
|
}.subscribeOn(Schedulers.io())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getFcmToken(): Single<String> {
|
||||||
|
return Single.fromCallable {
|
||||||
|
return@fromCallable FcmUtil.getToken(context).orElse("")
|
||||||
|
}.subscribeOn(Schedulers.io())
|
||||||
|
}
|
||||||
|
|
||||||
interface KbsPinDataProducer {
|
interface KbsPinDataProducer {
|
||||||
@Throws(IOException::class, KeyBackupSystemWrongPinException::class, KeyBackupSystemNoDataException::class)
|
@Throws(IOException::class, KeyBackupSystemWrongPinException::class, KeyBackupSystemNoDataException::class)
|
||||||
fun produceKbsPinData(): KbsPinData
|
fun produceKbsPinData(): KbsPinData
|
||||||
|
|
|
@ -6,6 +6,7 @@ import android.widget.ScrollView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.activity.OnBackPressedCallback;
|
||||||
import androidx.annotation.CallSuper;
|
import androidx.annotation.CallSuper;
|
||||||
import androidx.annotation.LayoutRes;
|
import androidx.annotation.LayoutRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
@ -124,6 +125,15 @@ public abstract class BaseEnterSmsCodeFragment<ViewModel extends BaseRegistratio
|
||||||
new ContactSupportBottomSheetFragment(this::openTroubleshootingSteps, this::sendEmailToSupport).show(getChildFragmentManager(), "support_bottom_sheet");
|
new ContactSupportBottomSheetFragment(this::openTroubleshootingSteps, this::sendEmailToSupport).show(getChildFragmentManager(), "support_bottom_sheet");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) {
|
||||||
|
@Override
|
||||||
|
public void handleOnBackPressed() {
|
||||||
|
viewModel.resetSession();
|
||||||
|
this.remove();
|
||||||
|
requireActivity().getOnBackPressedDispatcher().onBackPressed();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract ViewModel getViewModel();
|
protected abstract ViewModel getViewModel();
|
||||||
|
@ -324,8 +334,7 @@ public abstract class BaseEnterSmsCodeFragment<ViewModel extends BaseRegistratio
|
||||||
} else if (processor.captchaRequired()) {
|
} else if (processor.captchaRequired()) {
|
||||||
navigateToCaptcha();
|
navigateToCaptcha();
|
||||||
} else if (processor.rateLimit()) {
|
} else if (processor.rateLimit()) {
|
||||||
long rateLimit = processor.getRateLimit();
|
handleRateLimited();
|
||||||
Toast.makeText(requireContext(), R.string.RegistrationActivity_rate_limited_to_service, Toast.LENGTH_LONG).show();
|
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "Unable to request phone code", processor.getError());
|
Log.w(TAG, "Unable to request phone code", processor.getError());
|
||||||
Toast.makeText(requireContext(), R.string.RegistrationActivity_unable_to_connect_to_service, Toast.LENGTH_LONG).show();
|
Toast.makeText(requireContext(), R.string.RegistrationActivity_unable_to_connect_to_service, Toast.LENGTH_LONG).show();
|
||||||
|
|
|
@ -156,8 +156,7 @@ public final class EnterPhoneNumberFragment extends LoggingFragment implements R
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleRegister(@NonNull Context context) {
|
private void handleRegister(@NonNull Context context) {
|
||||||
final EditText countryCodeEditText = countryCode.getEditText();
|
if (viewModel.getNumber().getCountryCode() == 0) {
|
||||||
if (countryCodeEditText == null || TextUtils.isEmpty(countryCodeEditText.getText())) {
|
|
||||||
showErrorDialog(context, getString(R.string.RegistrationActivity_you_must_specify_your_country_code));
|
showErrorDialog(context, getString(R.string.RegistrationActivity_you_must_specify_your_country_code));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -272,6 +271,7 @@ public final class EnterPhoneNumberFragment extends LoggingFragment implements R
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(processor -> {
|
.subscribe(processor -> {
|
||||||
if (processor.verificationCodeRequestSuccess()) {
|
if (processor.verificationCodeRequestSuccess()) {
|
||||||
|
disposables.add(updateFcmTokenValue());
|
||||||
SafeNavigation.safeNavigate(navController, EnterPhoneNumberFragmentDirections.actionEnterVerificationCode());
|
SafeNavigation.safeNavigate(navController, EnterPhoneNumberFragmentDirections.actionEnterVerificationCode());
|
||||||
} else if (processor.captchaRequired()) {
|
} else if (processor.captchaRequired()) {
|
||||||
Log.i(TAG, "Unable to request sms code due to captcha required");
|
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);
|
disposables.add(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Disposable updateFcmTokenValue() {
|
||||||
|
return viewModel.updateFcmTokenValue().subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
private String formatMillisecondsToString(long milliseconds) {
|
private String formatMillisecondsToString(long milliseconds) {
|
||||||
long totalSeconds = milliseconds / 1000;
|
long totalSeconds = milliseconds / 1000;
|
||||||
long HH = totalSeconds / 3600;
|
long HH = totalSeconds / 3600;
|
||||||
|
@ -350,7 +354,12 @@ public final class EnterPhoneNumberFragment extends LoggingFragment implements R
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(processor -> {
|
.subscribe(processor -> {
|
||||||
if (processor.hasResult() && processor.canSubmitProofImmediately()) {
|
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 {
|
} else {
|
||||||
viewModel.resetSession();
|
viewModel.resetSession();
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ class RegistrationNumberInputController(
|
||||||
.map { CountryPrefix(it, PhoneNumberUtil.getInstance().getRegionCodeForCountryCode(it)) }
|
.map { CountryPrefix(it, PhoneNumberUtil.getInstance().getRegionCodeForCountryCode(it)) }
|
||||||
.sortedBy { it.digits }
|
.sortedBy { it.digits }
|
||||||
private val spinnerAdapter: ArrayAdapter<CountryPrefix> = ArrayAdapter<CountryPrefix>(context, R.layout.registration_country_code_dropdown_item, supportedCountryPrefixes)
|
private val spinnerAdapter: ArrayAdapter<CountryPrefix> = ArrayAdapter<CountryPrefix>(context, R.layout.registration_country_code_dropdown_item, supportedCountryPrefixes)
|
||||||
|
private val countryCodeEntryListener = CountryCodeEntryListener()
|
||||||
|
|
||||||
private var countryFormatter: AsYouTypeFormatter? = null
|
private var countryFormatter: AsYouTypeFormatter? = null
|
||||||
private var isUpdating = true
|
private var isUpdating = true
|
||||||
|
@ -41,11 +42,13 @@ class RegistrationNumberInputController(
|
||||||
|
|
||||||
spinnerView.threshold = 100
|
spinnerView.threshold = 100
|
||||||
spinnerView.setAdapter(spinnerAdapter)
|
spinnerView.setAdapter(spinnerAdapter)
|
||||||
spinnerView.addTextChangedListener(CountryCodeEntryListener())
|
spinnerView.addTextChangedListener(countryCodeEntryListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun prepopulateCountryCode() {
|
fun prepopulateCountryCode() {
|
||||||
spinnerView.setText(supportedCountryPrefixes[0].toString())
|
if (spinnerView.editableText.isBlank()) {
|
||||||
|
spinnerView.setText(supportedCountryPrefixes[0].toString())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun advanceToPhoneNumberInput() {
|
private fun advanceToPhoneNumberInput() {
|
||||||
|
|
|
@ -6,6 +6,10 @@ import androidx.lifecycle.LiveData;
|
||||||
import androidx.lifecycle.SavedStateHandle;
|
import androidx.lifecycle.SavedStateHandle;
|
||||||
import androidx.lifecycle.ViewModel;
|
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.keyvalue.SignalStore;
|
||||||
import org.thoughtcrime.securesms.pin.KbsRepository;
|
import org.thoughtcrime.securesms.pin.KbsRepository;
|
||||||
import org.thoughtcrime.securesms.pin.TokenData;
|
import org.thoughtcrime.securesms.pin.TokenData;
|
||||||
|
@ -102,10 +106,17 @@ public abstract class BaseRegistrationViewModel extends ViewModel {
|
||||||
return savedState.getLiveData(STATE_NUMBER);
|
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) {
|
public void onCountrySelected(@Nullable String selectedCountryName, int countryCode) {
|
||||||
setViewState(getNumber().toBuilder()
|
setViewState(getNumber().toBuilder()
|
||||||
.selectedCountryDisplayName(selectedCountryName)
|
.selectedCountryDisplayName(selectedCountryName)
|
||||||
.countryCode(countryCode).build());
|
.countryCode(countryCode)
|
||||||
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNationalNumber(String number) {
|
public void setNationalNumber(String number) {
|
||||||
|
|
|
@ -26,12 +26,12 @@ import org.thoughtcrime.securesms.registration.VerifyAccountRepository;
|
||||||
import org.thoughtcrime.securesms.registration.VerifyResponse;
|
import org.thoughtcrime.securesms.registration.VerifyResponse;
|
||||||
import org.thoughtcrime.securesms.registration.VerifyResponseProcessor;
|
import org.thoughtcrime.securesms.registration.VerifyResponseProcessor;
|
||||||
import org.thoughtcrime.securesms.registration.VerifyResponseWithRegistrationLockProcessor;
|
import org.thoughtcrime.securesms.registration.VerifyResponseWithRegistrationLockProcessor;
|
||||||
import org.thoughtcrime.securesms.registration.VerifyResponseWithSuccessfulKbs;
|
|
||||||
import org.thoughtcrime.securesms.registration.VerifyResponseWithoutKbs;
|
import org.thoughtcrime.securesms.registration.VerifyResponseWithoutKbs;
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
import org.whispersystems.signalservice.api.KbsPinData;
|
import org.whispersystems.signalservice.api.KbsPinData;
|
||||||
import org.whispersystems.signalservice.api.KeyBackupSystemNoDataException;
|
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.ServiceResponse;
|
||||||
import org.whispersystems.signalservice.internal.push.RegistrationSessionMetadataResponse;
|
import org.whispersystems.signalservice.internal.push.RegistrationSessionMetadataResponse;
|
||||||
|
|
||||||
|
@ -123,13 +123,17 @@ public final class RegistrationViewModel extends BaseRegistrationViewModel {
|
||||||
.map(RegistrationSessionProcessor.RegistrationSessionProcessorForVerification::new)
|
.map(RegistrationSessionProcessor.RegistrationSessionProcessorForVerification::new)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.doOnSuccess(processor -> {
|
.doOnSuccess(processor -> {
|
||||||
setCanSmsAtTime(processor.getNextCodeViaSmsAttempt());
|
if (processor.hasResult()) {
|
||||||
setCanCallAtTime(processor.getNextCodeViaCallAttempt());
|
setCanSmsAtTime(processor.getNextCodeViaSmsAttempt());
|
||||||
|
setCanCallAtTime(processor.getNextCodeViaCallAttempt());
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.observeOn(Schedulers.io())
|
.observeOn(Schedulers.io())
|
||||||
.flatMap(processor -> {
|
.flatMap(processor -> {
|
||||||
if (processor.isAlreadyVerified() || (processor.hasResult() && processor.isVerified())) {
|
if (processor.isAlreadyVerified() || (processor.hasResult() && processor.isVerified())) {
|
||||||
return verifyAccountRepository.registerAccount(sessionId, getRegistrationData(), null, null);
|
return verifyAccountRepository.registerAccount(sessionId, getRegistrationData(), null, null);
|
||||||
|
} else if (processor.getError() == null) {
|
||||||
|
return Single.just(ServiceResponse.<VerifyResponse>forApplicationError(new IncorrectCodeException(), 403, null));
|
||||||
} else {
|
} else {
|
||||||
return Single.just(ServiceResponse.<VerifyResponse, RegistrationSessionMetadataResponse>coerceError(processor.getResponse()));
|
return Single.just(ServiceResponse.<VerifyResponse, RegistrationSessionMetadataResponse>coerceError(processor.getResponse()));
|
||||||
}
|
}
|
||||||
|
@ -320,6 +324,10 @@ public final class RegistrationViewModel extends BaseRegistrationViewModel {
|
||||||
.observeOn(AndroidSchedulers.mainThread());
|
.observeOn(AndroidSchedulers.mainThread());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Single<String> updateFcmTokenValue() {
|
||||||
|
return verifyAccountRepository.getFcmToken().observeOn(AndroidSchedulers.mainThread()).doOnSuccess(this::setFcmToken);
|
||||||
|
}
|
||||||
|
|
||||||
private void restoreFromStorageService() {
|
private void restoreFromStorageService() {
|
||||||
SignalStore.onboarding().clearAll();
|
SignalStore.onboarding().clearAll();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
package org.whispersystems.signalservice.api.push.exceptions
|
||||||
|
|
||||||
|
class IncorrectCodeException : NonSuccessfulResponseCodeException(403)
|
Ładowanie…
Reference in New Issue