mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-08-05 12:55:11 +01:00
Add relink support and fix sad paths in all link flows.
Co-authored-by: Greyson Parrelli <greyson@signal.org>
This commit is contained in:
@@ -13,9 +13,11 @@ import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.signal.core.util.AppForegroundObserver;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.signal.core.util.tracing.Tracer;
|
||||
import org.signal.devicetransfer.TransferStatus;
|
||||
import org.signal.registration.RegistrationRoute;
|
||||
import org.thoughtcrime.securesms.components.settings.app.changenumber.ChangeNumberLockActivity;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies;
|
||||
@@ -30,11 +32,10 @@ import org.thoughtcrime.securesms.profiles.edit.CreateProfileActivity;
|
||||
import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.registration.ui.RegistrationActivity;
|
||||
import org.thoughtcrime.securesms.util.Environment;
|
||||
import org.thoughtcrime.securesms.restore.RestoreActivity;
|
||||
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||
import org.signal.core.util.AppForegroundObserver;
|
||||
import org.thoughtcrime.securesms.util.AppStartup;
|
||||
import org.thoughtcrime.securesms.util.Environment;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
||||
import java.util.Locale;
|
||||
@@ -57,6 +58,7 @@ public abstract class PassphraseRequiredActivity extends BaseActivity implements
|
||||
private static final int STATE_TRANSFER_LOCKED = 9;
|
||||
private static final int STATE_CHANGE_NUMBER_LOCK = 10;
|
||||
private static final int STATE_TRANSFER_OR_RESTORE = 11;
|
||||
private static final int STATE_RESUME_LINKING_REG = 12;
|
||||
|
||||
private SignalServiceNetworkAccess networkAccess;
|
||||
private BroadcastReceiver clearKeyReceiver;
|
||||
@@ -155,6 +157,7 @@ public abstract class PassphraseRequiredActivity extends BaseActivity implements
|
||||
case STATE_TRANSFER_LOCKED: return getOldDeviceTransferLockedIntent();
|
||||
case STATE_CHANGE_NUMBER_LOCK: return getChangeNumberLockIntent();
|
||||
case STATE_TRANSFER_OR_RESTORE: return getTransferOrRestoreIntent();
|
||||
case STATE_RESUME_LINKING_REG: return getResumeLinkedRegistrationIntent();
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
@@ -168,6 +171,8 @@ public abstract class PassphraseRequiredActivity extends BaseActivity implements
|
||||
return STATE_UI_BLOCKING_UPGRADE;
|
||||
} else if (!TextSecurePreferences.hasPromptedPushRegistration(this)) {
|
||||
return STATE_WELCOME_PUSH_SCREEN;
|
||||
} else if (shouldResumeLinkingRegistration()) {
|
||||
return STATE_RESUME_LINKING_REG;
|
||||
} else if (userCanTransferOrRestore()) {
|
||||
return STATE_TRANSFER_OR_RESTORE;
|
||||
} else if (SignalStore.storageService().getNeedsAccountRestore()) {
|
||||
@@ -192,6 +197,14 @@ public abstract class PassphraseRequiredActivity extends BaseActivity implements
|
||||
RestoreDecisionStateUtil.isDecisionPending(SignalStore.registration().getRestoreDecisionState());
|
||||
}
|
||||
|
||||
private boolean shouldResumeLinkingRegistration() {
|
||||
return Environment.USE_NEW_REGISTRATION &&
|
||||
SignalStore.account().isRegistered() &&
|
||||
!SignalStore.account().isPrimaryDevice() &&
|
||||
!SignalStore.registration().isRegistrationComplete() &&
|
||||
RestoreDecisionStateUtil.isDecisionPending(SignalStore.registration().getRestoreDecisionState());
|
||||
}
|
||||
|
||||
private boolean userMustCreateSignalPin() {
|
||||
return !SignalStore.registration().isRegistrationComplete() &&
|
||||
!SignalStore.svr().hasPin() &&
|
||||
@@ -246,6 +259,10 @@ public abstract class PassphraseRequiredActivity extends BaseActivity implements
|
||||
return getRoutedIntent(intent, MainActivity.clearTop(this));
|
||||
}
|
||||
|
||||
private Intent getResumeLinkedRegistrationIntent() {
|
||||
return org.signal.registration.RegistrationActivity.createIntent(this, MainActivity.clearTop(this), RegistrationRoute.MessageSync.INSTANCE);
|
||||
}
|
||||
|
||||
private Intent getCreateProfileNameIntent() {
|
||||
Intent intent = CreateProfileActivity.getIntentForUserProfile(this);
|
||||
return getRoutedIntent(intent, getIntent());
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.thoughtcrime.securesms.messages.IncomingMessageObserver;
|
||||
import org.thoughtcrime.securesms.net.SignalNetwork;
|
||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
import org.signal.core.util.PlayServicesUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.signalservice.api.NetworkResultUtil;
|
||||
import org.signal.network.exceptions.NonSuccessfulResponseCodeException;
|
||||
|
||||
@@ -72,6 +73,11 @@ public class FcmRefreshJob extends BaseJob {
|
||||
|
||||
@Override
|
||||
public void onRun() throws Exception {
|
||||
if (TextSecurePreferences.isUnauthorizedReceived(context)) {
|
||||
Log.i(TAG, "No longer authorized. Ignoring.");
|
||||
return;
|
||||
}
|
||||
|
||||
Log.i(TAG, "Reregistering FCM...");
|
||||
|
||||
boolean playServicesMissing = PlayServicesUtil.getPlayServicesStatus(context) == PlayServicesUtil.PlayServicesStatus.MISSING ;
|
||||
|
||||
@@ -91,6 +91,11 @@ public class RefreshAttributesJob extends BaseJob {
|
||||
return;
|
||||
}
|
||||
|
||||
if (TextSecurePreferences.isUnauthorizedReceived(context)) {
|
||||
Log.i(TAG, "No longer authorized. Ignoring.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!forced && hasRefreshedThisAppCycle) {
|
||||
Log.d(TAG, "Already refreshed this app cycle. Skipping.");
|
||||
return;
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.thoughtcrime.securesms.jobmanager.Job
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.pin.SvrRepository
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
import java.io.IOException
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.days
|
||||
@@ -24,7 +25,7 @@ class RefreshSvrCredentialsJob private constructor(parameters: Parameters) : Bas
|
||||
|
||||
@JvmStatic
|
||||
fun enqueueIfNecessary() {
|
||||
if (SignalStore.svr.hasPin() && SignalStore.account.isRegistered) {
|
||||
if (SignalStore.svr.hasPin() && SignalStore.account.isRegistered && !TextSecurePreferences.isUnauthorizedReceived(AppDependencies.application)) {
|
||||
val lastTimestamp = SignalStore.svr.lastRefreshAuthTimestamp
|
||||
if (lastTimestamp + FREQUENCY.inWholeMilliseconds < System.currentTimeMillis() || lastTimestamp > System.currentTimeMillis()) {
|
||||
AppDependencies.jobManager.add(RefreshSvrCredentialsJob())
|
||||
@@ -55,6 +56,11 @@ class RefreshSvrCredentialsJob private constructor(parameters: Parameters) : Bas
|
||||
return
|
||||
}
|
||||
|
||||
if (TextSecurePreferences.isUnauthorizedReceived(context)) {
|
||||
Log.i(TAG, "No longer authorized. Ignoring.")
|
||||
return
|
||||
}
|
||||
|
||||
SvrRepository.refreshAndStoreAuthorization()
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.net.SignalNetwork
|
||||
import org.thoughtcrime.securesms.util.RemoteConfig
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
import org.whispersystems.signalservice.api.websocket.SignalWebSocket
|
||||
import kotlin.time.Duration.Companion.days
|
||||
|
||||
@@ -44,6 +45,11 @@ class RemoteConfigRefreshJob private constructor(parameters: Parameters) : Job(p
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
if (TextSecurePreferences.isUnauthorizedReceived(context)) {
|
||||
Log.i(TAG, "No longer authorized. Ignoring.")
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
return when (val result = SignalNetwork.remoteConfig.getRemoteConfig(SignalStore.remoteConfig.eTag)) {
|
||||
is NetworkResult.Success -> {
|
||||
RemoteConfig.update(result.result.config)
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.thoughtcrime.securesms.keyvalue.CertificateType;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.net.SignalNetwork;
|
||||
import org.thoughtcrime.securesms.util.ExceptionHelper;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.signalservice.api.NetworkResultUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -56,6 +57,11 @@ public final class RotateCertificateJob extends BaseJob {
|
||||
return;
|
||||
}
|
||||
|
||||
if (TextSecurePreferences.isUnauthorizedReceived(context)) {
|
||||
Log.i(TAG, "No longer authorized. Ignoring.");
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (RotateCertificateJob.class) {
|
||||
Collection<CertificateType> certificateTypes = SignalStore.phoneNumberPrivacy()
|
||||
.getAllCertificateTypes();
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.thoughtcrime.securesms.storage.StorageSyncValidations
|
||||
import org.thoughtcrime.securesms.storage.StoryDistributionListRecordProcessor
|
||||
import org.thoughtcrime.securesms.transport.RetryLaterException
|
||||
import org.thoughtcrime.securesms.util.RemoteConfig
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.RequestMessage
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage
|
||||
@@ -185,6 +186,11 @@ class StorageSyncJob private constructor(parameters: Parameters, private var loc
|
||||
return
|
||||
}
|
||||
|
||||
if (TextSecurePreferences.isUnauthorizedReceived(context)) {
|
||||
Log.i(TAG, "No longer authorized. Ignoring.")
|
||||
return
|
||||
}
|
||||
|
||||
if (!Recipient.self().hasE164 || !Recipient.self().hasServiceId) {
|
||||
Log.w(TAG, "Missing E164 or ACI!")
|
||||
return
|
||||
|
||||
+8
-3
@@ -12,6 +12,7 @@ import androidx.activity.viewModels
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.navigation.ActivityNavigator
|
||||
import org.signal.registration.RegistrationRoute
|
||||
import org.thoughtcrime.securesms.BaseActivity
|
||||
import org.thoughtcrime.securesms.MainActivity
|
||||
import org.thoughtcrime.securesms.R
|
||||
@@ -84,7 +85,7 @@ class RegistrationActivity : BaseActivity() {
|
||||
@JvmStatic
|
||||
fun newIntentForNewRegistration(context: Context, originalIntent: Intent): Intent {
|
||||
return if (Environment.USE_NEW_REGISTRATION) {
|
||||
org.signal.registration.RegistrationActivity.createIntent(context, MainActivity.clearTop(context))
|
||||
org.signal.registration.RegistrationActivity.createIntent(context, nextIntent = MainActivity.clearTop(context))
|
||||
} else {
|
||||
Intent(context, RegistrationActivity::class.java).apply {
|
||||
putExtra(RE_REGISTRATION_EXTRA, false)
|
||||
@@ -96,7 +97,7 @@ class RegistrationActivity : BaseActivity() {
|
||||
@JvmStatic
|
||||
fun newIntentForReRegistration(context: Context): Intent {
|
||||
return if (Environment.USE_NEW_REGISTRATION) {
|
||||
org.signal.registration.RegistrationActivity.createIntent(context, MainActivity.clearTop(context))
|
||||
org.signal.registration.RegistrationActivity.createIntent(context, nextIntent = MainActivity.clearTop(context))
|
||||
} else {
|
||||
Intent(context, RegistrationActivity::class.java).apply {
|
||||
putExtra(RE_REGISTRATION_EXTRA, true)
|
||||
@@ -107,7 +108,11 @@ class RegistrationActivity : BaseActivity() {
|
||||
@JvmStatic
|
||||
fun newIntentForReLinkDevice(context: Context): Intent {
|
||||
return if (Environment.USE_NEW_REGISTRATION) {
|
||||
org.signal.registration.RegistrationActivity.createIntent(context, MainActivity.clearTop(context))
|
||||
org.signal.registration.RegistrationActivity.createIntent(
|
||||
context = context,
|
||||
nextIntent = MainActivity.clearTop(context),
|
||||
startDestination = RegistrationRoute.LinkAccount(showCreateAccount = false)
|
||||
)
|
||||
} else {
|
||||
Intent(context, RegistrationActivity::class.java)
|
||||
}
|
||||
|
||||
+1
-1
@@ -87,7 +87,7 @@ class RegisterLinkDeviceQrViewModel : ViewModel() {
|
||||
}
|
||||
|
||||
return ProvisioningSocket.start<ProvisionMessage>(
|
||||
mode = ProvisioningSocket.Mode.LINK,
|
||||
mode = ProvisioningSocket.Mode.Link(linkAndSyncCapable = true),
|
||||
identityKeyPair = IdentityKeyPair.generate(),
|
||||
configuration = AppDependencies.signalServiceNetworkAccess.getConfiguration(),
|
||||
handler = { id, t ->
|
||||
|
||||
+1
-1
@@ -122,7 +122,7 @@ class RestoreViaQrViewModel : ViewModel() {
|
||||
}
|
||||
|
||||
return ProvisioningSocket.start<RegistrationProvisionMessage>(
|
||||
mode = ProvisioningSocket.Mode.REREG,
|
||||
mode = ProvisioningSocket.Mode.Rereg,
|
||||
identityKeyPair = IdentityKeyPair.generate(),
|
||||
configuration = AppDependencies.signalServiceNetworkAccess.getConfiguration(),
|
||||
handler = { id, t ->
|
||||
|
||||
+3
-3
@@ -771,7 +771,7 @@ class AppRegistrationNetworkController(
|
||||
|
||||
fun startSocket() {
|
||||
val handle = ProvisioningSocket.start<RegistrationProvisionMessage>(
|
||||
mode = ProvisioningSocket.Mode.REREG,
|
||||
mode = ProvisioningSocket.Mode.Rereg,
|
||||
identityKeyPair = IdentityKeyPair.generate(),
|
||||
configuration = configuration,
|
||||
handler = { id, t ->
|
||||
@@ -848,13 +848,13 @@ class AppRegistrationNetworkController(
|
||||
}
|
||||
}
|
||||
|
||||
override fun startLinkDeviceProvisioning(): Flow<LinkDeviceProvisioningEvent> = callbackFlow {
|
||||
override fun startLinkDeviceProvisioning(allowLinkAndSync: Boolean): Flow<LinkDeviceProvisioningEvent> = callbackFlow {
|
||||
val socketHandles = mutableListOf<Closeable>()
|
||||
val configuration = AppDependencies.signalServiceNetworkAccess.getConfiguration()
|
||||
|
||||
fun startSocket() {
|
||||
val handle = ProvisioningSocket.start<ProvisionMessage>(
|
||||
mode = ProvisioningSocket.Mode.LINK,
|
||||
mode = ProvisioningSocket.Mode.Link(linkAndSyncCapable = allowLinkAndSync),
|
||||
identityKeyPair = IdentityKeyPair.generate(),
|
||||
configuration = configuration,
|
||||
handler = { id, t ->
|
||||
|
||||
+1
-1
@@ -91,7 +91,7 @@ class AppRegistrationStorageController(private val context: Context) : StorageCo
|
||||
val pni = SignalStore.account.pni ?: return@withContext null
|
||||
val e164 = SignalStore.account.e164 ?: return@withContext null
|
||||
val servicePassword = SignalStore.account.servicePassword ?: return@withContext null
|
||||
val aep = SignalStore.account.accountEntropyPool ?: return@withContext null
|
||||
val aep = SignalStore.account.accountEntropyPool
|
||||
|
||||
val aciIdentityKeyPair = SignalStore.account.aciIdentityKey
|
||||
val pniIdentityKeyPair = SignalStore.account.pniIdentityKey
|
||||
|
||||
Reference in New Issue
Block a user