mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-02 08:23:00 +01:00
Allow opting out of key transparency.
This commit is contained in:
committed by
Greyson Parrelli
parent
423b8c942c
commit
a11888ff71
@@ -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
|
||||
)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1418,7 +1418,7 @@ class ConversationFragment :
|
||||
}
|
||||
|
||||
private fun presentVerifyAutomaticallySheet() {
|
||||
if (RemoteConfig.keyTransparency && !SignalStore.uiHints.hasSeenVerifyAutomaticallySheet() && viewModel.recipientSnapshot?.isIndividual == true) {
|
||||
if (RemoteConfig.keyTransparency && SignalStore.settings.automaticVerificationEnabled && !SignalStore.uiHints.hasSeenVerifyAutomaticallySheet() && viewModel.recipientSnapshot?.isIndividual == true) {
|
||||
VerifyAutomaticallyEducationSheet.show(parentFragmentManager)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4048,6 +4048,14 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
.run()
|
||||
}
|
||||
|
||||
fun clearAllKeyTransparencyData() {
|
||||
writableDatabase
|
||||
.update(TABLE_NAME)
|
||||
.values(KEY_TRANSPARENCY_DATA to null)
|
||||
.where("$KEY_TRANSPARENCY_DATA IS NOT NULL")
|
||||
.run()
|
||||
}
|
||||
|
||||
/**
|
||||
* Will update the database with the content values you specified. It will make an intelligent
|
||||
* query such that this will only return true if a row was *actually* updated.
|
||||
|
||||
@@ -75,6 +75,7 @@ public final class SettingsValues extends SignalStoreValues {
|
||||
private static final String PASSPHRASE_TIMEOUT = "settings.passphrase.timeout";
|
||||
private static final String SCREEN_LOCK_ENABLED = "settings.screen.lock.enabled";
|
||||
private static final String SCREEN_LOCK_TIMEOUT = "settings.screen.lock.timeout";
|
||||
private static final String AUTOMATIC_VERIFICATION_ENABLED = "settings.automatic.verification.enabled";
|
||||
|
||||
public static final int BACKUP_DEFAULT_HOUR = 2;
|
||||
public static final int BACKUP_DEFAULT_MINUTE = 0;
|
||||
@@ -560,6 +561,14 @@ public final class SettingsValues extends SignalStoreValues {
|
||||
return getLong(SCREEN_LOCK_TIMEOUT, 0);
|
||||
}
|
||||
|
||||
public boolean getAutomaticVerificationEnabled() {
|
||||
return getBoolean(AUTOMATIC_VERIFICATION_ENABLED, true);
|
||||
}
|
||||
|
||||
public void setAutomaticVerificationEnabled(boolean enabled) {
|
||||
putBoolean(AUTOMATIC_VERIFICATION_ENABLED, enabled);
|
||||
}
|
||||
|
||||
private @Nullable Uri getUri(@NonNull String key) {
|
||||
String uri = getString(key, "");
|
||||
|
||||
|
||||
@@ -138,6 +138,7 @@ class AccountRecordProcessor(
|
||||
usernameLink = remote.proto.usernameLink
|
||||
notificationProfileManualOverride = remote.proto.notificationProfileManualOverride
|
||||
backupTier = local.proto.backupTier ?: remote.proto.backupTier
|
||||
automaticKeyVerificationDisabled = remote.proto.automaticKeyVerificationDisabled
|
||||
|
||||
safeSetPayments(payments?.enabled == true, payments?.entropy?.toByteArray())
|
||||
safeSetSubscriber(donationSubscriberId, donationSubscriberCurrencyCode)
|
||||
|
||||
@@ -195,6 +195,7 @@ object StorageSyncHelper {
|
||||
}
|
||||
|
||||
safeSetPayments(SignalStore.payments.mobileCoinPaymentsEnabled(), Optional.ofNullable(SignalStore.payments.paymentsEntropy).map { obj: Entropy -> obj.bytes }.orElse(null))
|
||||
automaticKeyVerificationDisabled = !SignalStore.settings.automaticVerificationEnabled
|
||||
}
|
||||
|
||||
return accountRecord.toSignalAccountRecord(StorageId.forAccount(storageId)).toSignalStorageRecord()
|
||||
@@ -258,6 +259,11 @@ object StorageSyncHelper {
|
||||
SignalStore.story.userHasSeenGroupStoryEducationSheet = update.new.proto.hasSeenGroupStoryEducationSheet
|
||||
SignalStore.uiHints.setHasCompletedUsernameOnboarding(update.new.proto.hasCompletedUsernameOnboarding)
|
||||
|
||||
if (SignalStore.settings.automaticVerificationEnabled && update.new.proto.automaticKeyVerificationDisabled) {
|
||||
SignalDatabase.recipients.clearAllKeyTransparencyData()
|
||||
}
|
||||
SignalStore.settings.automaticVerificationEnabled = !update.new.proto.automaticKeyVerificationDisabled
|
||||
|
||||
if (update.new.proto.storyViewReceiptsEnabled == OptionalBool.UNSET) {
|
||||
SignalStore.story.viewedReceiptsEnabled = update.new.proto.readReceipts
|
||||
} else {
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.thoughtcrime.securesms.components.ViewBinderDelegate
|
||||
import org.thoughtcrime.securesms.components.verify.SafetyNumberQrView.Companion.getSegments
|
||||
import org.thoughtcrime.securesms.crypto.IdentityKeyParcelable
|
||||
import org.thoughtcrime.securesms.databinding.VerifyDisplayFragmentBinding
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import org.thoughtcrime.securesms.util.RemoteConfig
|
||||
@@ -74,7 +75,7 @@ class VerifyDisplayFragment : Fragment() {
|
||||
|
||||
updateVerifyButton(requireArguments().getBoolean(VERIFIED_STATE, false), false)
|
||||
|
||||
binding.automaticVerification.visible = RemoteConfig.keyTransparency
|
||||
binding.automaticVerification.visible = RemoteConfig.keyTransparency && SignalStore.settings.automaticVerificationEnabled
|
||||
binding.safetyQrView.verifyButton.setOnClickListener { updateVerifyButton(!currentVerifiedState, true) }
|
||||
binding.toolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
|
||||
binding.toolbar.setTitle(R.string.AndroidManifest__verify_safety_number)
|
||||
|
||||
@@ -4247,6 +4247,10 @@
|
||||
<string name="preferences_compact">Compact</string>
|
||||
<!-- Dialog message body explaining that we have to restart the app in order to apply the user\'s new language setting. -->
|
||||
<string name="preferences_language_change_confirmation_message">The app will restart to apply the new language setting.</string>
|
||||
<!-- Preference title for automatic key verification -->
|
||||
<string name="preferences_automatic_key_verification">Automatic key verification</string>
|
||||
<!-- Preference summary for automatic key verification -->
|
||||
<string name="preferences_automatic_key_verification_body">When enabled, Signal will attempt to automatically verify the encryption of 1:1 chats.</string>
|
||||
|
||||
|
||||
<string name="configurable_single_select__customize_option">Customize option</string>
|
||||
|
||||
@@ -294,6 +294,8 @@ message AccountRecord {
|
||||
optional AvatarColor avatarColor = 42;
|
||||
BackupTierHistory backupTierHistory = 43;
|
||||
NotificationProfileManualOverride notificationProfileManualOverride = 44;
|
||||
bool notificationProfileSyncDisabled = 45;
|
||||
bool automaticKeyVerificationDisabled = 46;
|
||||
}
|
||||
|
||||
message StoryDistributionListRecord {
|
||||
|
||||
Reference in New Issue
Block a user