Allow opting out of key transparency.

This commit is contained in:
Michelle Tang
2026-01-30 13:48:01 -05:00
committed by Greyson Parrelli
parent 423b8c942c
commit a11888ff71
11 changed files with 98 additions and 5 deletions

View File

@@ -45,6 +45,7 @@ import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.compose.ComposeFragment
import org.thoughtcrime.securesms.compose.rememberStatusBarColorNestedScrollModifier
import org.thoughtcrime.securesms.util.CommunicationActions
import org.thoughtcrime.securesms.util.RemoteConfig
import org.thoughtcrime.securesms.util.viewModel
/**
@@ -152,6 +153,17 @@ class AdvancedPrivacySettingsFragment : ComposeFragment() {
getString(R.string.AdvancedPrivacySettingsFragment__sealed_sender_link)
)
}
override fun onAllowAutomaticVerificationChanged(enabled: Boolean) {
viewModel.setAllowAutomaticVerification(enabled)
}
override fun onAutomaticVerificationLearnMoreClick() {
CommunicationActions.openBrowserLink(
requireContext(),
getString(R.string.verify_display_fragment__link)
)
}
}
}
@@ -163,6 +175,8 @@ private interface AdvancedPrivacySettingsCallbacks {
fun onShowStatusIconForSealedSenderChanged(enabled: Boolean) = Unit
fun onAllowSealedSenderFromAnyoneChanged(enabled: Boolean) = Unit
fun onSealedSenderLearnMoreClick() = Unit
fun onAutomaticVerificationLearnMoreClick() = Unit
fun onAllowAutomaticVerificationChanged(enabled: Boolean) = Unit
object Empty : AdvancedPrivacySettingsCallbacks
}
@@ -284,6 +298,33 @@ private fun AdvancedPrivacySettingsScreen(
text = sealedSenderSummary
)
}
if (RemoteConfig.keyTransparency) {
item {
Dividers.Default()
}
item {
val label = buildAnnotatedString {
append(stringResource(R.string.preferences_automatic_key_verification_body))
append(" ")
withLink(
LinkAnnotation.Clickable("learn-more", linkInteractionListener = {
callbacks.onAutomaticVerificationLearnMoreClick()
})
) {
append(stringResource(R.string.LearnMoreTextView_learn_more))
}
}
Rows.ToggleRow(
checked = state.allowAutomaticKeyVerification,
text = AnnotatedString(stringResource(R.string.preferences_automatic_key_verification)),
label = label,
onCheckChanged = callbacks::onAllowAutomaticVerificationChanged
)
}
}
}
}
}
@@ -300,7 +341,8 @@ private fun AdvancedPrivacySettingsScreenPreview() {
censorshipCircumventionEnabled = false,
showSealedSenderStatusIcon = false,
allowSealedSenderFromAnyone = false,
showProgressSpinner = false
showProgressSpinner = false,
allowAutomaticKeyVerification = false
),
callbacks = AdvancedPrivacySettingsCallbacks.Empty
)

View File

@@ -7,7 +7,8 @@ data class AdvancedPrivacySettingsState(
val censorshipCircumventionEnabled: Boolean,
val showSealedSenderStatusIcon: Boolean,
val allowSealedSenderFromAnyone: Boolean,
val showProgressSpinner: Boolean
val showProgressSpinner: Boolean,
val allowAutomaticKeyVerification: Boolean
)
enum class CensorshipCircumventionState(val available: Boolean) {

View File

@@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.components.settings.app.privacy.advanced
import android.content.SharedPreferences
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.disposables.CompositeDisposable
import kotlinx.coroutines.flow.MutableSharedFlow
@@ -9,12 +10,17 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import org.signal.core.util.concurrent.SignalDispatchers
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint
import org.thoughtcrime.securesms.jobs.RefreshAttributesJob
import org.thoughtcrime.securesms.jobs.RefreshOwnProfileJob
import org.thoughtcrime.securesms.keyvalue.SettingsValues
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.storage.StorageSyncHelper
import org.thoughtcrime.securesms.util.SignalE164Util
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState
@@ -63,6 +69,18 @@ class AdvancedPrivacySettingsViewModel(
refresh()
}
fun setAllowAutomaticVerification(enabled: Boolean) {
SignalStore.settings.automaticVerificationEnabled = enabled
refresh()
viewModelScope.launch(SignalDispatchers.IO) {
if (!enabled) {
SignalDatabase.recipients.clearAllKeyTransparencyData()
}
SignalDatabase.recipients.markNeedsSync(Recipient.self().id)
StorageSyncHelper.scheduleSyncForDataChange()
}
}
fun refresh() {
store.update { getState().copy(showProgressSpinner = it.showProgressSpinner) }
}
@@ -85,7 +103,8 @@ class AdvancedPrivacySettingsViewModel(
allowSealedSenderFromAnyone = TextSecurePreferences.isUniversalUnidentifiedAccess(
AppDependencies.application
),
false
showProgressSpinner = false,
allowAutomaticKeyVerification = SignalStore.settings.automaticVerificationEnabled
)
}