From 87cbe305f08bebf5c82df851260bd452b1cf8281 Mon Sep 17 00:00:00 2001 From: Cody Henthorne Date: Fri, 25 Apr 2025 11:26:29 -0400 Subject: [PATCH] Support accounts without pins in AEP restore flows. --- .../securesms/PassphraseRequiredActivity.java | 2 +- .../app/account/AccountSettingsFragment.kt | 24 +++++++++---------- .../app/account/AccountSettingsState.kt | 4 ++-- .../app/account/AccountSettingsViewModel.kt | 2 +- .../app/changenumber/ChangeNumberViewModel.kt | 14 +++++------ .../securesms/jobs/RefreshAttributesJob.java | 6 ++--- .../securesms/jobs/RefreshOwnProfileJob.java | 4 ++-- .../jobs/RefreshSvrCredentialsJob.kt | 2 +- .../securesms/jobs/StorageSyncJob.kt | 4 ++-- .../securesms/keyvalue/AccountValues.kt | 1 + .../securesms/keyvalue/SvrValues.kt | 13 +--------- .../securesms/lock/v2/BaseSvrPinFragment.java | 2 +- .../securesms/lock/v2/SvrSplashFragment.java | 2 +- .../securesms/logsubmit/LogSectionPin.java | 2 +- .../megaphone/PinsForAllSchedule.java | 4 ++-- .../migrations/PinOptOutMigration.java | 2 +- .../securesms/pin/SvrRepository.kt | 8 +++---- .../registration/util/RegistrationUtil.java | 2 +- .../data/QuickRegistrationRepository.kt | 11 +++------ .../ui/RegistrationViewModel.kt | 6 ++--- .../ui/restore/RestoreViaQrViewModel.kt | 18 +++++++------- .../registration/util/RegistrationUtilTest.kt | 10 ++++---- .../protowire/RegistrationProvisioning.proto | 7 +++--- 23 files changed, 65 insertions(+), 85 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/PassphraseRequiredActivity.java b/app/src/main/java/org/thoughtcrime/securesms/PassphraseRequiredActivity.java index d979c19ae7..9c476ba208 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/PassphraseRequiredActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/PassphraseRequiredActivity.java @@ -195,7 +195,7 @@ public abstract class PassphraseRequiredActivity extends BaseActivity implements private boolean userMustCreateSignalPin() { return !SignalStore.registration().isRegistrationComplete() && - !SignalStore.svr().hasOptedInWithAccess() && + !SignalStore.svr().hasPin() && !SignalStore.svr().lastPinCreateFailed() && !SignalStore.svr().hasOptedOut(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsFragment.kt index 8ed2f32bb0..c28398f92c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsFragment.kt @@ -69,10 +69,10 @@ class AccountSettingsFragment : DSLSettingsFragment(R.string.AccountSettingsFrag @Suppress("DEPRECATION") clickPref( - title = DSLSettingsText.from(if (state.hasOptedInWithAccess) R.string.preferences_app_protection__change_your_pin else R.string.preferences_app_protection__create_a_pin), - isEnabled = state.isDeprecatedOrUnregistered(), + title = DSLSettingsText.from(if (state.hasPin || state.hasRestoredAep) R.string.preferences_app_protection__change_your_pin else R.string.preferences_app_protection__create_a_pin), + isEnabled = state.isNotDeprecatedOrUnregistered(), onClick = { - if (state.hasOptedInWithAccess) { + if (state.hasPin) { startActivityForResult(CreateSvrPinActivity.getIntentForPinChangeFromSettings(requireContext()), CreateSvrPinActivity.REQUEST_NEW_PIN) } else { startActivityForResult(CreateSvrPinActivity.getIntentForPinCreate(requireContext()), CreateSvrPinActivity.REQUEST_NEW_PIN) @@ -84,7 +84,7 @@ class AccountSettingsFragment : DSLSettingsFragment(R.string.AccountSettingsFrag title = DSLSettingsText.from(R.string.preferences_app_protection__pin_reminders), summary = DSLSettingsText.from(R.string.AccountSettingsFragment__youll_be_asked_less_frequently), isChecked = state.hasPin && state.pinRemindersEnabled, - isEnabled = state.hasPin && state.isDeprecatedOrUnregistered(), + isEnabled = state.hasPin && state.isNotDeprecatedOrUnregistered(), onClick = { setPinRemindersEnabled(!state.pinRemindersEnabled) } @@ -94,7 +94,7 @@ class AccountSettingsFragment : DSLSettingsFragment(R.string.AccountSettingsFrag title = DSLSettingsText.from(R.string.preferences_app_protection__registration_lock), summary = DSLSettingsText.from(R.string.AccountSettingsFragment__require_your_signal_pin), isChecked = state.registrationLockEnabled, - isEnabled = (state.hasOptedInWithAccess) && state.isDeprecatedOrUnregistered(), + isEnabled = state.hasPin && state.isNotDeprecatedOrUnregistered(), onClick = { setRegistrationLockEnabled(!state.registrationLockEnabled) } @@ -102,7 +102,7 @@ class AccountSettingsFragment : DSLSettingsFragment(R.string.AccountSettingsFrag clickPref( title = DSLSettingsText.from(R.string.preferences__advanced_pin_settings), - isEnabled = state.isDeprecatedOrUnregistered(), + isEnabled = state.isNotDeprecatedOrUnregistered(), onClick = { Navigation.findNavController(requireView()).safeNavigate(R.id.action_accountSettingsFragment_to_advancedPinSettingsActivity) } @@ -115,7 +115,7 @@ class AccountSettingsFragment : DSLSettingsFragment(R.string.AccountSettingsFrag if (SignalStore.account.isRegistered) { clickPref( title = DSLSettingsText.from(R.string.AccountSettingsFragment__change_phone_number), - isEnabled = state.isDeprecatedOrUnregistered(), + isEnabled = state.isNotDeprecatedOrUnregistered(), onClick = { Navigation.findNavController(requireView()).safeNavigate(R.id.action_accountSettingsFragment_to_changePhoneNumberFragment) } @@ -125,7 +125,7 @@ class AccountSettingsFragment : DSLSettingsFragment(R.string.AccountSettingsFrag clickPref( title = DSLSettingsText.from(R.string.preferences_chats__transfer_account), summary = DSLSettingsText.from(R.string.preferences_chats__transfer_account_to_a_new_android_device), - isEnabled = state.isDeprecatedOrUnregistered(), + isEnabled = state.isNotDeprecatedOrUnregistered(), onClick = { Navigation.findNavController(requireView()).safeNavigate(R.id.action_accountSettingsFragment_to_oldDeviceTransferActivity) } @@ -133,13 +133,13 @@ class AccountSettingsFragment : DSLSettingsFragment(R.string.AccountSettingsFrag clickPref( title = DSLSettingsText.from(R.string.AccountSettingsFragment__request_account_data), - isEnabled = state.isDeprecatedOrUnregistered(), + isEnabled = state.isNotDeprecatedOrUnregistered(), onClick = { Navigation.findNavController(requireView()).safeNavigate(R.id.action_accountSettingsFragment_to_exportAccountFragment) } ) - if (!state.isDeprecatedOrUnregistered()) { + if (!state.isNotDeprecatedOrUnregistered()) { if (state.clientDeprecated) { clickPref( title = DSLSettingsText.from(R.string.preferences_account_update_signal), @@ -174,8 +174,8 @@ class AccountSettingsFragment : DSLSettingsFragment(R.string.AccountSettingsFrag } clickPref( - title = DSLSettingsText.from(R.string.preferences__delete_account, ContextCompat.getColor(requireContext(), if (state.isDeprecatedOrUnregistered()) R.color.signal_alert_primary else R.color.signal_alert_primary_50)), - isEnabled = state.isDeprecatedOrUnregistered(), + title = DSLSettingsText.from(R.string.preferences__delete_account, ContextCompat.getColor(requireContext(), if (state.isNotDeprecatedOrUnregistered()) R.color.signal_alert_primary else R.color.signal_alert_primary_50)), + isEnabled = state.isNotDeprecatedOrUnregistered(), onClick = { Navigation.findNavController(requireView()).safeNavigate(R.id.action_accountSettingsFragment_to_deleteAccountFragment) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsState.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsState.kt index 713d743c0c..8a1b0349f0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsState.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsState.kt @@ -2,13 +2,13 @@ package org.thoughtcrime.securesms.components.settings.app.account data class AccountSettingsState( val hasPin: Boolean, - val hasOptedInWithAccess: Boolean, + val hasRestoredAep: Boolean, val pinRemindersEnabled: Boolean, val registrationLockEnabled: Boolean, val userUnregistered: Boolean, val clientDeprecated: Boolean ) { - fun isDeprecatedOrUnregistered(): Boolean { + fun isNotDeprecatedOrUnregistered(): Boolean { return !(userUnregistered || clientDeprecated) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsViewModel.kt index 94d470a6d2..0bd06cc0bf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsViewModel.kt @@ -19,7 +19,7 @@ class AccountSettingsViewModel : ViewModel() { private fun getCurrentState(): AccountSettingsState { return AccountSettingsState( hasPin = SignalStore.svr.hasPin() && !SignalStore.svr.hasOptedOut(), - hasOptedInWithAccess = SignalStore.svr.hasOptedInWithAccess(), + hasRestoredAep = SignalStore.account.restoredAccountEntropyPool, pinRemindersEnabled = SignalStore.pin.arePinRemindersEnabled() && SignalStore.svr.hasPin(), registrationLockEnabled = SignalStore.svr.isRegistrationLockEnabled, userUnregistered = TextSecurePreferences.isUnauthorizedReceived(AppDependencies.application), diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberViewModel.kt index e6bd0ac2a4..2eb6080ff2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/changenumber/ChangeNumberViewModel.kt @@ -409,16 +409,14 @@ class ChangeNumberViewModel : ViewModel() { private suspend fun changeNumberWithRecoveryPassword(): Boolean { Log.v(TAG, "changeNumberWithRecoveryPassword()") SignalStore.svr.recoveryPassword?.let { recoveryPassword -> - if (SignalStore.svr.hasOptedInWithAccess()) { - val result = repository.changeNumberWithRecoveryPassword(recoveryPassword = recoveryPassword, newE164 = number.e164Number) + val result = repository.changeNumberWithRecoveryPassword(recoveryPassword = recoveryPassword, newE164 = number.e164Number) - if (result is ChangeNumberResult.Success) { - handleSuccessfulChangedRemoteNumber(e164 = result.numberChangeResult.number, pni = ServiceId.PNI.parseOrThrow(result.numberChangeResult.pni), changeNumberOutcome = ChangeNumberOutcome.RecoveryPasswordWorked) - return true - } - - Log.d(TAG, "Encountered error while trying to change number with recovery password.", result.getCause()) + if (result is ChangeNumberResult.Success) { + handleSuccessfulChangedRemoteNumber(e164 = result.numberChangeResult.number, pni = ServiceId.PNI.parseOrThrow(result.numberChangeResult.pni), changeNumberOutcome = ChangeNumberOutcome.RecoveryPasswordWorked) + return true } + + Log.d(TAG, "Encountered error while trying to change number with recovery password.", result.getCause()) } return false } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshAttributesJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshAttributesJob.java index e2477eb42b..e009027409 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshAttributesJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshAttributesJob.java @@ -93,7 +93,7 @@ public class RefreshAttributesJob extends BaseJob { String registrationLockV2 = null; SvrValues svrValues = SignalStore.svr(); int pniRegistrationId = RegistrationRepository.getPniRegistrationId(); - String recoveryPassword = svrValues.hasPin() ? svrValues.getMasterKey().deriveRegistrationRecoveryPassword() : null; + String recoveryPassword = svrValues.getMasterKey().deriveRegistrationRecoveryPassword(); if (svrValues.isRegistrationLockEnabled()) { registrationLockV2 = svrValues.getRegistrationLockToken(); @@ -104,8 +104,8 @@ public class RefreshAttributesJob extends BaseJob { String deviceName = SignalStore.account().getDeviceName(); byte[] encryptedDeviceName = (deviceName == null) ? null : DeviceNameCipher.encryptDeviceName(deviceName.getBytes(StandardCharsets.UTF_8), SignalStore.account().getAciIdentityKey()); - AccountAttributes.Capabilities capabilities = AppCapabilities.getCapabilities(svrValues.hasOptedInWithAccess() && !svrValues.hasOptedOut()); - Log.i(TAG, "Calling setAccountAttributes() reglockV2? " + !TextUtils.isEmpty(registrationLockV2) + ", pin? " + svrValues.hasPin() + ", access? " + svrValues.hasOptedInWithAccess() + + AccountAttributes.Capabilities capabilities = AppCapabilities.getCapabilities(svrValues.hasPin() && !svrValues.hasOptedOut()); + Log.i(TAG, "Calling setAccountAttributes() reglockV2? " + !TextUtils.isEmpty(registrationLockV2) + ", pin? " + svrValues.hasPin() + ", restoredAEP? " + SignalStore.account().restoredAccountEntropyPool() + "\n Recovery password? " + !TextUtils.isEmpty(recoveryPassword) + "\n Phone number discoverable : " + phoneNumberDiscoverable + "\n Device Name : " + (encryptedDeviceName != null) + diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshOwnProfileJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshOwnProfileJob.java index 610644c7c6..c75faa3722 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshOwnProfileJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshOwnProfileJob.java @@ -107,8 +107,8 @@ public class RefreshOwnProfileJob extends BaseJob { return; } - if (SignalStore.svr().hasOptedInWithAccess() && !SignalStore.svr().hasOptedOut() && SignalStore.storageService().getLastSyncTime() == 0) { - Log.i(TAG, "Registered with PIN but haven't completed storage sync yet."); + if ((SignalStore.svr().hasPin() || SignalStore.account().restoredAccountEntropyPool()) && !SignalStore.svr().hasOptedOut() && SignalStore.storageService().getLastSyncTime() == 0) { + Log.i(TAG, "Registered with PIN or AEP but haven't completed storage sync yet."); return; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshSvrCredentialsJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshSvrCredentialsJob.kt index 5f8454a6fb..40175201a7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshSvrCredentialsJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshSvrCredentialsJob.kt @@ -24,7 +24,7 @@ class RefreshSvrCredentialsJob private constructor(parameters: Parameters) : Bas @JvmStatic fun enqueueIfNecessary() { - if (SignalStore.svr.hasOptedInWithAccess() && SignalStore.account.isRegistered) { + if (SignalStore.svr.hasPin() && SignalStore.account.isRegistered) { val lastTimestamp = SignalStore.svr.lastRefreshAuthTimestamp if (lastTimestamp + FREQUENCY.inWholeMilliseconds < System.currentTimeMillis() || lastTimestamp > System.currentTimeMillis()) { AppDependencies.jobManager.add(RefreshSvrCredentialsJob()) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.kt index a7b70a8b55..0fec4307cc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.kt @@ -165,8 +165,8 @@ class StorageSyncJob private constructor(parameters: Parameters, private var loc @Throws(IOException::class, RetryLaterException::class, UntrustedIdentityException::class) override fun onRun() { - if (!SignalStore.svr.hasOptedInWithAccess() && !SignalStore.svr.hasOptedOut()) { - Log.i(TAG, "Doesn't have a PIN. Skipping.") + if (!(SignalStore.svr.hasPin() || SignalStore.account.restoredAccountEntropyPool) && !SignalStore.svr.hasOptedOut()) { + Log.i(TAG, "Doesn't have access to storage service. Skipping.") return } diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/AccountValues.kt b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/AccountValues.kt index aff52b39de..33517d816d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/AccountValues.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/AccountValues.kt @@ -161,6 +161,7 @@ class AccountValues internal constructor(store: KeyValueStore, context: Context) } } + @get:JvmName("restoredAccountEntropyPool") @get:Synchronized val restoredAccountEntropyPool by booleanValue(KEY_RESTORED_ACCOUNT_ENTROPY_KEY, false) diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SvrValues.kt b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SvrValues.kt index d00f6e51c8..d6a663596b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SvrValues.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SvrValues.kt @@ -128,13 +128,7 @@ class SvrValues internal constructor(store: KeyValueStore) : SignalStoreValues(s @get:Synchronized val recoveryPassword: String? - get() { - return if (hasOptedInWithAccess()) { - masterKeyForInitialDataRestore?.deriveRegistrationRecoveryPassword() ?: masterKey.deriveRegistrationRecoveryPassword() - } else { - null - } - } + get() = masterKeyForInitialDataRestore?.deriveRegistrationRecoveryPassword() ?: masterKey.deriveRegistrationRecoveryPassword() @get:Synchronized val pin: String? by stringValue(PIN, null) @@ -142,11 +136,6 @@ class SvrValues internal constructor(store: KeyValueStore) : SignalStoreValues(s @get:Synchronized val localPinHash: String? by stringValue(LOCK_LOCAL_PIN_HASH, null) - @Synchronized - fun hasOptedInWithAccess(): Boolean { - return hasPin() || SignalStore.account.restoredAccountEntropyPool - } - @Synchronized fun hasPin(): Boolean { return localPinHash != null diff --git a/app/src/main/java/org/thoughtcrime/securesms/lock/v2/BaseSvrPinFragment.java b/app/src/main/java/org/thoughtcrime/securesms/lock/v2/BaseSvrPinFragment.java index 67a09d01a0..158df96247 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/lock/v2/BaseSvrPinFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/lock/v2/BaseSvrPinFragment.java @@ -101,7 +101,7 @@ public abstract class BaseSvrPinFragment @Override public void onPrepareOptionsMenu(@NonNull Menu menu) { if (SignalStore.svr().isRegistrationLockEnabled() || - SignalStore.svr().hasOptedInWithAccess() || + SignalStore.svr().hasPin() || SignalStore.svr().hasOptedOut()) { menu.clear(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/lock/v2/SvrSplashFragment.java b/app/src/main/java/org/thoughtcrime/securesms/lock/v2/SvrSplashFragment.java index 88b0317c3d..87a3038518 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/lock/v2/SvrSplashFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/lock/v2/SvrSplashFragment.java @@ -115,7 +115,7 @@ public final class SvrSplashFragment extends Fragment { private void onCreatePin() { SvrSplashFragmentDirections.ActionCreateKbsPin action = SvrSplashFragmentDirections.actionCreateKbsPin(); - action.setIsPinChange(SignalStore.svr().hasOptedInWithAccess()); + action.setIsPinChange(SignalStore.svr().hasPin()); SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), action); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionPin.java b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionPin.java index 1e297f94cd..2009ba1c98 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionPin.java +++ b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionPin.java @@ -20,7 +20,7 @@ public class LogSectionPin implements LogSection { .append("Next Reminder Interval: ").append(SignalStore.pin().getCurrentInterval()).append("\n") .append("Reglock: ").append(SignalStore.svr().isRegistrationLockEnabled()).append("\n") .append("Signal PIN: ").append(SignalStore.svr().hasPin()).append("\n") - .append("Restored via AEP: ").append(SignalStore.account().getRestoredAccountEntropyPool()).append("\n") + .append("Restored via AEP: ").append(SignalStore.account().restoredAccountEntropyPool()).append("\n") .append("Opted Out: ").append(SignalStore.svr().hasOptedOut()).append("\n") .append("Last Creation Failed: ").append(SignalStore.svr().lastPinCreateFailed()).append("\n") .append("Needs Account Restore: ").append(SignalStore.storageService().getNeedsAccountRestore()).append("\n") diff --git a/app/src/main/java/org/thoughtcrime/securesms/megaphone/PinsForAllSchedule.java b/app/src/main/java/org/thoughtcrime/securesms/megaphone/PinsForAllSchedule.java index f8e0836989..2b9a0dc2a7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/megaphone/PinsForAllSchedule.java +++ b/app/src/main/java/org/thoughtcrime/securesms/megaphone/PinsForAllSchedule.java @@ -45,7 +45,7 @@ class PinsForAllSchedule implements MegaphoneSchedule { return false; } - if (SignalStore.svr().hasOptedInWithAccess()) { + if (SignalStore.svr().hasPin()) { return false; } @@ -62,6 +62,6 @@ class PinsForAllSchedule implements MegaphoneSchedule { private static boolean pinCreationFailedDuringRegistration() { return SignalStore.registration().pinWasRequiredAtRegistration() && - !SignalStore.svr().hasOptedInWithAccess(); + !SignalStore.svr().hasPin(); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/PinOptOutMigration.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/PinOptOutMigration.java index ed3f9b3abc..4506ed0939 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/PinOptOutMigration.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/PinOptOutMigration.java @@ -37,7 +37,7 @@ public final class PinOptOutMigration extends MigrationJob { @Override void performMigration() { - if (SignalStore.svr().hasOptedOut() && SignalStore.svr().hasOptedInWithAccess()) { + if (SignalStore.svr().hasOptedOut() && SignalStore.svr().hasPin()) { Log.w(TAG, "Discovered a legacy opt-out user! Resetting the state."); SignalStore.svr().optOut(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/pin/SvrRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/pin/SvrRepository.kt index 4377813ee9..601169f230 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/pin/SvrRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/pin/SvrRepository.kt @@ -359,7 +359,7 @@ object SvrRepository { @Throws(IOException::class) fun enableRegistrationLockForUserWithPin() { operationLock.withLock { - check(SignalStore.svr.hasOptedInWithAccess() && !SignalStore.svr.hasOptedOut()) { "Must have a PIN to set a registration lock!" } + check(SignalStore.svr.hasPin() && !SignalStore.svr.hasOptedOut()) { "Must have a PIN to set a registration lock!" } Log.i(TAG, "[enableRegistrationLockForUserWithPin] Enabling registration lock.", true) NetworkResultUtil.toBasicLegacy(SignalNetwork.account.enableRegistrationLock(SignalStore.svr.masterKey.deriveRegistrationLock())) @@ -373,7 +373,7 @@ object SvrRepository { @Throws(IOException::class) fun disableRegistrationLockForUserWithPin() { operationLock.withLock { - check(SignalStore.svr.hasOptedInWithAccess() && !SignalStore.svr.hasOptedOut()) { "Must have a PIN to disable registration lock!" } + check(SignalStore.svr.hasPin() && !SignalStore.svr.hasOptedOut()) { "Must have a PIN to disable registration lock!" } Log.i(TAG, "[disableRegistrationLockForUserWithPin] Disabling registration lock.", true) NetworkResultUtil.toBasicLegacy(SignalNetwork.account.disableRegistrationLock()) @@ -403,7 +403,7 @@ object SvrRepository { false } - if (newToken && SignalStore.svr.hasOptedInWithAccess()) { + if (newToken && SignalStore.svr.hasPin()) { BackupManager(AppDependencies.application).dataChanged() } } catch (e: Throwable) { @@ -464,7 +464,7 @@ object SvrRepository { private val hasNoRegistrationLock: Boolean get() { return !SignalStore.svr.isRegistrationLockEnabled && - !SignalStore.svr.hasOptedInWithAccess() && + !SignalStore.svr.hasPin() && !SignalStore.svr.hasOptedOut() } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/util/RegistrationUtil.java b/app/src/main/java/org/thoughtcrime/securesms/registration/util/RegistrationUtil.java index e2a80777cb..fb91b1018f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/util/RegistrationUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/util/RegistrationUtil.java @@ -32,7 +32,7 @@ public final class RegistrationUtil { if (!SignalStore.registration().isRegistrationComplete() && SignalStore.account().isRegistered() && !Recipient.self().getProfileName().isEmpty() && - (SignalStore.svr().hasOptedInWithAccess() || SignalStore.svr().hasOptedOut()) && + (SignalStore.svr().hasPin() || SignalStore.svr().hasOptedOut()) && (!RemoteConfig.restoreAfterRegistration() || RestoreDecisionStateUtil.isTerminal(SignalStore.registration().getRestoreDecisionState()))) { Log.i(TAG, "Marking registration completed.", new Throwable()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/registrationv3/data/QuickRegistrationRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/registrationv3/data/QuickRegistrationRepository.kt index d4613b3a4e..9f9a03eb2a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registrationv3/data/QuickRegistrationRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/registrationv3/data/QuickRegistrationRepository.kt @@ -67,11 +67,6 @@ object QuickRegistrationRepository { return TransferAccountResult.FAILED } - val pin = SignalStore.svr.pin ?: run { - Log.w(TAG, "No pin") - return TransferAccountResult.FAILED - } - SignalNetwork .provisioning .sendReRegisterDeviceProvisioningMessage( @@ -81,15 +76,15 @@ object QuickRegistrationRepository { e164 = SignalStore.account.requireE164(), aci = SignalStore.account.requireAci().toByteString(), accountEntropyPool = SignalStore.account.accountEntropyPool.value, - pin = pin, + pin = SignalStore.svr.pin, platform = RegistrationProvisionMessage.Platform.ANDROID, - backupTimestampMs = SignalStore.backup.lastBackupTime.coerceAtLeast(0L), + backupTimestampMs = SignalStore.backup.lastBackupTime.coerceAtLeast(0L).takeIf { it > 0 }, tier = when (SignalStore.backup.backupTier) { MessageBackupTier.PAID -> RegistrationProvisionMessage.Tier.PAID MessageBackupTier.FREE -> RegistrationProvisionMessage.Tier.FREE null -> null }, - backupSizeBytes = SignalStore.backup.totalBackupSize, + backupSizeBytes = SignalStore.backup.totalBackupSize.takeIf { it > 0 }, restoreMethodToken = restoreMethodToken ) ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/registrationv3/ui/RegistrationViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/registrationv3/ui/RegistrationViewModel.kt index 3cce5a5dd1..9ac79e810c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registrationv3/ui/RegistrationViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/registrationv3/ui/RegistrationViewModel.kt @@ -894,12 +894,12 @@ class RegistrationViewModel : ViewModel() { Log.w(TAG, "Unable to start auth websocket", e) } - if (!remoteResult.storageCapable && SignalStore.registration.restoreDecisionState.isDecisionPending) { - Log.v(TAG, "Not storage capable and still pending restore decision, likely an account with no data to restore, skipping post register restore") + if (!remoteResult.storageCapable && !SignalStore.account.restoredAccountEntropyPool && SignalStore.registration.restoreDecisionState.isDecisionPending) { + Log.v(TAG, "Not storage capable or restored with AEP, and still pending restore decision, likely an account with no data to restore, skipping post register restore") SignalStore.registration.restoreDecisionState = RestoreDecisionState.NewAccount } - if (reglockEnabled || SignalStore.svr.hasOptedInWithAccess()) { + if (reglockEnabled || SignalStore.account.restoredAccountEntropyPool) { SignalStore.onboarding.clearAll() if (SignalStore.registration.restoreDecisionState.isTerminal) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/registrationv3/ui/restore/RestoreViaQrViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/registrationv3/ui/restore/RestoreViaQrViewModel.kt index 03427e4d99..a9d582ef01 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registrationv3/ui/restore/RestoreViaQrViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/registrationv3/ui/restore/RestoreViaQrViewModel.kt @@ -158,17 +158,15 @@ class RestoreViaQrViewModel : ViewModel() { Log.i(TAG, "Saving restore method token: ***${result.message.restoreMethodToken.takeLast(4)}") SignalStore.registration.restoreMethodToken = result.message.restoreMethodToken SignalStore.registration.isOtherDeviceAndroid = result.message.platform == RegistrationProvisionMessage.Platform.ANDROID - if (result.message.backupTimestampMs > 0) { - SignalStore.backup.backupTier = result.message.tier.let { - when (it) { - RegistrationProvisionMessage.Tier.FREE -> MessageBackupTier.FREE - RegistrationProvisionMessage.Tier.PAID -> MessageBackupTier.PAID - null -> null - } - } - SignalStore.backup.lastBackupTime = result.message.backupTimestampMs - SignalStore.backup.usedBackupMediaSpace = result.message.backupSizeBytes + + SignalStore.backup.lastBackupTime = result.message.backupTimestampMs ?: 0 + SignalStore.backup.usedBackupMediaSpace = result.message.backupSizeBytes ?: 0 + SignalStore.backup.backupTier = when (result.message.tier) { + RegistrationProvisionMessage.Tier.FREE -> MessageBackupTier.FREE + RegistrationProvisionMessage.Tier.PAID -> MessageBackupTier.PAID + null -> null } + store.update { it.copy(isRegistering = true, provisioningMessage = result.message, qrState = QrState.Scanned) } shutdown() } else { diff --git a/app/src/test/java/org/thoughtcrime/securesms/registration/util/RegistrationUtilTest.kt b/app/src/test/java/org/thoughtcrime/securesms/registration/util/RegistrationUtilTest.kt index 37e1f8fe81..c10801a1e4 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/registration/util/RegistrationUtilTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/registration/util/RegistrationUtilTest.kt @@ -66,7 +66,7 @@ class RegistrationUtilTest { every { signalStore.registration.isRegistrationComplete } returns false every { signalStore.account.isRegistered } returns true every { Recipient.self() } returns Recipient(profileName = ProfileName.fromParts("Dark", "Helmet")) - every { signalStore.svr.hasOptedInWithAccess() } returns true + every { signalStore.svr.hasPin() } returns true every { RemoteConfig.restoreAfterRegistration } returns false RegistrationUtil.maybeMarkRegistrationComplete() @@ -79,7 +79,7 @@ class RegistrationUtilTest { every { signalStore.registration.isRegistrationComplete } returns false every { signalStore.account.isRegistered } returns true every { Recipient.self() } returns Recipient(profileName = ProfileName.fromParts("Dark", "Helmet")) - every { signalStore.svr.hasOptedInWithAccess() } returns false + every { signalStore.svr.hasPin() } returns false every { signalStore.svr.hasOptedOut() } returns true every { RemoteConfig.restoreAfterRegistration } returns false @@ -93,7 +93,7 @@ class RegistrationUtilTest { every { signalStore.registration.isRegistrationComplete } returns false every { signalStore.account.isRegistered } returns true every { Recipient.self() } returns Recipient(profileName = ProfileName.fromParts("Dark", "Helmet")) - every { signalStore.svr.hasOptedInWithAccess() } returns true + every { signalStore.svr.hasPin() } returns true every { RemoteConfig.restoreAfterRegistration } returns true every { signalStore.registration.restoreDecisionState } returns RestoreDecisionState.Skipped @@ -115,12 +115,12 @@ class RegistrationUtilTest { RegistrationUtil.maybeMarkRegistrationComplete() every { Recipient.self() } returns Recipient(profileName = ProfileName.fromParts("Dark", "Helmet")) - every { signalStore.svr.hasOptedInWithAccess() } returns false + every { signalStore.svr.hasPin() } returns false every { signalStore.svr.hasOptedOut() } returns false RegistrationUtil.maybeMarkRegistrationComplete() - every { signalStore.svr.hasOptedInWithAccess() } returns true + every { signalStore.svr.hasPin() } returns true every { RemoteConfig.restoreAfterRegistration } returns true every { signalStore.registration.restoreDecisionState } returns RestoreDecisionState.Start diff --git a/libsignal-service/src/main/protowire/RegistrationProvisioning.proto b/libsignal-service/src/main/protowire/RegistrationProvisioning.proto index 4d7593f25f..1a8fd76095 100644 --- a/libsignal-service/src/main/protowire/RegistrationProvisioning.proto +++ b/libsignal-service/src/main/protowire/RegistrationProvisioning.proto @@ -22,11 +22,10 @@ message RegistrationProvisionMessage { string e164 = 1; bytes aci = 2; string accountEntropyPool = 3; - string pin = 4; + optional string pin = 4; Platform platform = 5; - uint64 backupTimestampMs = 6; + optional uint64 backupTimestampMs = 6; optional Tier tier = 7; - uint64 backupSizeBytes = 8; + optional uint64 backupSizeBytes = 8; string restoreMethodToken = 9; - reserved 10; // iOSDeviceTransferMessage }