4S settings screen
This commit is contained in:
parent
25bbe9c3d6
commit
c57d41863f
|
@ -19,7 +19,11 @@ package im.vector.matrix.rx
|
|||
import androidx.paging.PagedList
|
||||
import im.vector.matrix.android.api.query.QueryStringValue
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME
|
||||
import im.vector.matrix.android.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME
|
||||
import im.vector.matrix.android.api.session.crypto.crosssigning.MXCrossSigningInfo
|
||||
import im.vector.matrix.android.api.session.crypto.crosssigning.SELF_SIGNING_KEY_SSSS_NAME
|
||||
import im.vector.matrix.android.api.session.crypto.crosssigning.USER_SIGNING_KEY_SSSS_NAME
|
||||
import im.vector.matrix.android.api.session.group.GroupSummaryQueryParams
|
||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||
import im.vector.matrix.android.api.session.identity.ThreePid
|
||||
|
@ -36,9 +40,11 @@ import im.vector.matrix.android.api.util.toOptional
|
|||
import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
|
||||
import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
|
||||
import im.vector.matrix.android.internal.crypto.store.PrivateKeysInfo
|
||||
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountData
|
||||
import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAccountDataEvent
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.functions.Function3
|
||||
|
||||
class RxSession(private val session: Session) {
|
||||
|
||||
|
@ -165,6 +171,50 @@ class RxSession(private val session: Session) {
|
|||
session.widgetService().getRoomWidgets(roomId, widgetId, widgetTypes, excludedTypes)
|
||||
}
|
||||
}
|
||||
|
||||
data class SecretsSynchronisationInfo(
|
||||
val isBackupSetup: Boolean = false,
|
||||
val isCrossSigningEnabled: Boolean = false,
|
||||
val isCrossSigningTrusted: Boolean = false,
|
||||
val allPrivateKeysKnown: Boolean = false,
|
||||
val megolmBackupAvailable: Boolean = false,
|
||||
val megolmSecretKnown: Boolean = false,
|
||||
val isMegolmKeyIn4S: Boolean = false
|
||||
)
|
||||
|
||||
fun liveSecretSynchronisationInfo(): Observable<SecretsSynchronisationInfo> {
|
||||
return Observable.combineLatest<List<UserAccountData>, Optional<MXCrossSigningInfo>, Optional<PrivateKeysInfo>, SecretsSynchronisationInfo>(
|
||||
liveAccountData(setOf(MASTER_KEY_SSSS_NAME, USER_SIGNING_KEY_SSSS_NAME, SELF_SIGNING_KEY_SSSS_NAME, KEYBACKUP_SECRET_SSSS_NAME)),
|
||||
liveCrossSigningInfo(session.myUserId),
|
||||
liveCrossSigningPrivateKeys(),
|
||||
Function3 { _, crossSigningInfo, pInfo ->
|
||||
// first check if 4S is already setup
|
||||
val is4SSetup = session.sharedSecretStorageService.isRecoverySetup()
|
||||
val isCrossSigningEnabled = crossSigningInfo.getOrNull() != null
|
||||
val isCrossSigningTrusted = crossSigningInfo.getOrNull()?.isTrusted() == true
|
||||
val allPrivateKeysKnown = pInfo.getOrNull()?.master != null
|
||||
&& pInfo.getOrNull()?.selfSigned != null
|
||||
&& pInfo.getOrNull()?.user != null
|
||||
|
||||
val keysBackupService = session.cryptoService().keysBackupService()
|
||||
val currentBackupVersion = keysBackupService.currentBackupVersion
|
||||
val megolmBackupAvailable = currentBackupVersion != null
|
||||
val savedBackupKey = keysBackupService.getKeyBackupRecoveryKeyInfo()
|
||||
|
||||
val megolmKeyKnown = savedBackupKey?.version == currentBackupVersion
|
||||
SecretsSynchronisationInfo(
|
||||
isBackupSetup = is4SSetup,
|
||||
isCrossSigningEnabled = isCrossSigningEnabled,
|
||||
isCrossSigningTrusted = isCrossSigningTrusted,
|
||||
allPrivateKeysKnown = allPrivateKeysKnown,
|
||||
megolmBackupAvailable = megolmBackupAvailable,
|
||||
megolmSecretKnown = megolmKeyKnown,
|
||||
isMegolmKeyIn4S = session.sharedSecretStorageService.isMegolmKeyInBackup()
|
||||
)
|
||||
}
|
||||
)
|
||||
.distinctUntilChanged()
|
||||
}
|
||||
}
|
||||
|
||||
fun Session.rx(): RxSession {
|
||||
|
|
|
@ -18,6 +18,7 @@ package im.vector.matrix.android.api.session.securestorage
|
|||
|
||||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.listeners.ProgressListener
|
||||
import im.vector.matrix.android.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME
|
||||
import im.vector.matrix.android.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME
|
||||
import im.vector.matrix.android.api.session.crypto.crosssigning.SELF_SIGNING_KEY_SSSS_NAME
|
||||
import im.vector.matrix.android.api.session.crypto.crosssigning.USER_SIGNING_KEY_SSSS_NAME
|
||||
|
@ -124,6 +125,13 @@ interface SharedSecretStorageService {
|
|||
) is IntegrityResult.Success
|
||||
}
|
||||
|
||||
fun isMegolmKeyInBackup(): Boolean {
|
||||
return checkShouldBeAbleToAccessSecrets(
|
||||
secretNames = listOf(KEYBACKUP_SECRET_SSSS_NAME),
|
||||
keyId = null
|
||||
) is IntegrityResult.Success
|
||||
}
|
||||
|
||||
fun checkShouldBeAbleToAccessSecrets(secretNames: List<String>, keyId: String?): IntegrityResult
|
||||
|
||||
fun requestSecret(name: String, myOtherDeviceId: String)
|
||||
|
|
|
@ -71,8 +71,8 @@ internal class OutgoingGossipingRequestManager @Inject constructor(
|
|||
delay(1500)
|
||||
cryptoStore.getOrAddOutgoingSecretShareRequest(secretName, recipients)?.let {
|
||||
// TODO check if there is already one that is being sent?
|
||||
if (it.state == OutgoingGossipingRequestState.SENDING || it.state == OutgoingGossipingRequestState.SENT) {
|
||||
Timber.v("## CRYPTO - GOSSIP sendSecretShareRequest() : we already request for that session: $it")
|
||||
if (it.state == OutgoingGossipingRequestState.SENDING /**|| it.state == OutgoingGossipingRequestState.SENT*/) {
|
||||
Timber.v("## CRYPTO - GOSSIP sendSecretShareRequest() : we are already sending for that session: $it")
|
||||
return@launch
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,8 @@ class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
|||
|
||||
@Parcelize
|
||||
data class Args(
|
||||
val initCrossSigningOnly: Boolean
|
||||
val initCrossSigningOnly: Boolean,
|
||||
val forceReset4S: Boolean
|
||||
) : Parcelable
|
||||
|
||||
override val showExpanded = true
|
||||
|
@ -180,10 +181,15 @@ class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
|||
|
||||
const val EXTRA_ARGS = "EXTRA_ARGS"
|
||||
|
||||
fun show(fragmentManager: FragmentManager, initCrossSigningOnly: Boolean) {
|
||||
fun show(fragmentManager: FragmentManager, initCrossSigningOnly: Boolean, forceReset4S: Boolean) {
|
||||
BootstrapBottomSheet().apply {
|
||||
isCancelable = false
|
||||
arguments = Bundle().apply { this.putParcelable(EXTRA_ARGS, Args(initCrossSigningOnly)) }
|
||||
arguments = Bundle().apply {
|
||||
this.putParcelable(EXTRA_ARGS, Args(
|
||||
initCrossSigningOnly,
|
||||
forceReset4S
|
||||
))
|
||||
}
|
||||
}.show(fragmentManager, "BootstrapBottomSheet")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -258,6 +258,30 @@ class BootstrapCrossSigningTask @Inject constructor(
|
|||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Timber.d("## BootstrapCrossSigningTask: Creating 4S - Existing megolm backup found")
|
||||
// ensure we store existing backup secret if we have it!
|
||||
val knownSecret = session.cryptoService().keysBackupService().getKeyBackupRecoveryKeyInfo()
|
||||
if (knownSecret != null && knownSecret.version == serverVersion.version) {
|
||||
// check it matches
|
||||
val isValid = awaitCallback<Boolean> {
|
||||
session.cryptoService().keysBackupService().isValidRecoveryKeyForCurrentVersion(knownSecret.recoveryKey, it)
|
||||
}
|
||||
if (isValid) {
|
||||
Timber.d("## BootstrapCrossSigningTask: Creating 4S - Megolm key valid and known")
|
||||
awaitCallback<Unit> {
|
||||
extractCurveKeyFromRecoveryKey(knownSecret.recoveryKey)?.toBase64NoPadding()?.let { secret ->
|
||||
ssssService.storeSecret(
|
||||
KEYBACKUP_SECRET_SSSS_NAME,
|
||||
secret,
|
||||
listOf(SharedSecretStorageService.KeyRef(keyInfo.keyId, keyInfo.keySpec)), it
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Timber.d("## BootstrapCrossSigningTask: Creating 4S - Megolm key is unknown by this session")
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (failure: Throwable) {
|
||||
Timber.e("## BootstrapCrossSigningTask: Failed to init keybackup")
|
||||
|
|
|
@ -58,6 +58,13 @@ class BootstrapSetupRecoveryKeyFragment @Inject constructor() : VectorBaseFragme
|
|||
bootstrapSetupSecureUseSecurityPassphrase.isVisible = false
|
||||
bootstrapSetupSecureUseSecurityPassphraseSeparator.isVisible = false
|
||||
} else {
|
||||
if (state.step.reset) {
|
||||
bootstrapSetupSecureText.text = getString(R.string.reset_secure_backup_title)
|
||||
bootstrapSetupWarningTextView.isVisible = true
|
||||
} else {
|
||||
bootstrapSetupSecureText.text = getString(R.string.bottom_sheet_setup_secure_backup_subtitle)
|
||||
bootstrapSetupWarningTextView.isVisible = false
|
||||
}
|
||||
// Choose between create a passphrase or use a recovery key
|
||||
bootstrapSetupSecureSubmit.isVisible = false
|
||||
bootstrapSetupSecureUseSecurityKey.isVisible = true
|
||||
|
|
|
@ -69,7 +69,11 @@ class BootstrapSharedViewModel @AssistedInject constructor(
|
|||
|
||||
init {
|
||||
|
||||
if (args.initCrossSigningOnly) {
|
||||
if (args.forceReset4S) {
|
||||
setState {
|
||||
copy(step = BootstrapStep.FirstForm(keyBackUpExist = false, reset = true))
|
||||
}
|
||||
} else if (args.initCrossSigningOnly) {
|
||||
// Go straight to account password
|
||||
setState {
|
||||
copy(step = BootstrapStep.AccountPassword(false))
|
||||
|
@ -554,7 +558,7 @@ class BootstrapSharedViewModel @AssistedInject constructor(
|
|||
override fun create(viewModelContext: ViewModelContext, state: BootstrapViewState): BootstrapSharedViewModel? {
|
||||
val fragment: BootstrapBottomSheet = (viewModelContext as FragmentViewModelContext).fragment()
|
||||
val args: BootstrapBottomSheet.Args = fragment.arguments?.getParcelable(BootstrapBottomSheet.EXTRA_ARGS)
|
||||
?: BootstrapBottomSheet.Args(initCrossSigningOnly = true)
|
||||
?: BootstrapBottomSheet.Args(initCrossSigningOnly = true, forceReset4S = false)
|
||||
return fragment.bootstrapViewModelFactory.create(state, args)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ sealed class BootstrapStep {
|
|||
object CheckingMigration : BootstrapStep()
|
||||
|
||||
// Use will be asked to choose between passphrase or recovery key, or to start process if a key backup exists
|
||||
data class FirstForm(val keyBackUpExist: Boolean) : BootstrapStep()
|
||||
data class FirstForm(val keyBackUpExist: Boolean, val reset: Boolean = false) : BootstrapStep()
|
||||
|
||||
data class SetupPassphrase(val isPasswordVisible: Boolean) : BootstrapStep()
|
||||
data class ConfirmPassphrase(val isPasswordVisible: Boolean) : BootstrapStep()
|
||||
|
|
|
@ -146,7 +146,7 @@ class VerificationRequestController @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
if (state.isMe && state.currentDeviceCanCrossSign) {
|
||||
if (state.isMe && state.currentDeviceCanCrossSign && !state.selfVerificationMode) {
|
||||
dividerItem {
|
||||
id("sep_notMe")
|
||||
}
|
||||
|
|
|
@ -145,7 +145,7 @@ class DefaultNavigator @Inject constructor(
|
|||
|
||||
override fun upgradeSessionSecurity(context: Context, initCrossSigningOnly: Boolean) {
|
||||
if (context is VectorBaseActivity) {
|
||||
BootstrapBottomSheet.show(context.supportFragmentManager, initCrossSigningOnly)
|
||||
BootstrapBottomSheet.show(context.supportFragmentManager, initCrossSigningOnly, false)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,7 +221,7 @@ class DefaultNavigator @Inject constructor(
|
|||
// if cross signing is enabled we should propose full 4S
|
||||
sessionHolder.getSafeActiveSession()?.let { session ->
|
||||
if (session.cryptoService().crossSigningService().canCrossSign() && context is VectorBaseActivity) {
|
||||
BootstrapBottomSheet.show(context.supportFragmentManager, false)
|
||||
BootstrapBottomSheet.show(context.supportFragmentManager, initCrossSigningOnly = false, forceReset4S = false)
|
||||
} else {
|
||||
context.startActivity(KeysBackupSetupActivity.intent(context, showManualExport))
|
||||
}
|
||||
|
|
|
@ -72,6 +72,9 @@ class VectorPreferences @Inject constructor(private val context: Context) {
|
|||
const val SETTINGS_ALLOW_INTEGRATIONS_KEY = "SETTINGS_ALLOW_INTEGRATIONS_KEY"
|
||||
const val SETTINGS_INTEGRATION_MANAGER_UI_URL_KEY = "SETTINGS_INTEGRATION_MANAGER_UI_URL_KEY"
|
||||
const val SETTINGS_SECURE_MESSAGE_RECOVERY_PREFERENCE_KEY = "SETTINGS_SECURE_MESSAGE_RECOVERY_PREFERENCE_KEY"
|
||||
const val SETTINGS_CRYPTOGRAPHY_MANAGE_4S_CATEGORY_KEY = "SETTINGS_CRYPTOGRAPHY_MANAGE_4S_CATEGORY_KEY"
|
||||
const val SETTINGS_SECURE_BACKUP_RECOVERY_PREFERENCE_KEY = "SETTINGS_SECURE_BACKUP_RECOVERY_PREFERENCE_KEY"
|
||||
// const val SETTINGS_SECURE_BACKUP_RESET_PREFERENCE_KEY = "SETTINGS_SECURE_BACKUP_RESET_PREFERENCE_KEY"
|
||||
|
||||
// user
|
||||
const val SETTINGS_PROFILE_PICTURE_PREFERENCE_KEY = "SETTINGS_PROFILE_PICTURE_PREFERENCE_KEY"
|
||||
|
|
|
@ -33,6 +33,8 @@ import im.vector.matrix.android.internal.crypto.crosssigning.isVerified
|
|||
import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult
|
||||
import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
|
||||
import im.vector.matrix.android.internal.crypto.model.rest.DevicesListResponse
|
||||
import im.vector.matrix.rx.RxSession
|
||||
import im.vector.matrix.rx.rx
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ActiveSessionHolder
|
||||
import im.vector.riotx.core.dialogs.ExportKeysDialog
|
||||
|
@ -41,12 +43,17 @@ import im.vector.riotx.core.intent.ExternalIntentData
|
|||
import im.vector.riotx.core.intent.analyseIntent
|
||||
import im.vector.riotx.core.intent.getFilenameFromUri
|
||||
import im.vector.riotx.core.platform.SimpleTextWatcher
|
||||
import im.vector.riotx.core.platform.VectorBaseActivity
|
||||
import im.vector.riotx.core.preference.VectorPreference
|
||||
import im.vector.riotx.core.preference.VectorPreferenceCategory
|
||||
import im.vector.riotx.core.utils.openFileSelection
|
||||
import im.vector.riotx.core.utils.toast
|
||||
import im.vector.riotx.features.crypto.keys.KeysExporter
|
||||
import im.vector.riotx.features.crypto.keys.KeysImporter
|
||||
import im.vector.riotx.features.crypto.keysbackup.settings.KeysBackupManageActivity
|
||||
import im.vector.riotx.features.crypto.recover.BootstrapBottomSheet
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import javax.inject.Inject
|
||||
|
||||
class VectorSettingsSecurityPrivacyFragment @Inject constructor(
|
||||
|
@ -56,6 +63,7 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
|
|||
|
||||
override var titleRes = R.string.settings_security_and_privacy
|
||||
override val preferenceXmlRes = R.xml.vector_settings_security_privacy
|
||||
private var disposables = emptyList<Disposable>().toMutableList()
|
||||
|
||||
// cryptography
|
||||
private val mCryptographyCategory by lazy {
|
||||
|
@ -92,6 +100,109 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
|
|||
// My device name may have been updated
|
||||
refreshMyDevice()
|
||||
refreshXSigningStatus()
|
||||
session.rx().liveSecretSynchronisationInfo()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe {
|
||||
refresh4SSection(it)
|
||||
refreshXSigningStatus()
|
||||
}.also {
|
||||
disposables.add(it)
|
||||
}
|
||||
}
|
||||
|
||||
private val secureBackupCategory by lazy {
|
||||
findPreference<VectorPreferenceCategory>(VectorPreferences.SETTINGS_CRYPTOGRAPHY_MANAGE_4S_CATEGORY_KEY)
|
||||
}
|
||||
private val secureBackupPreference by lazy {
|
||||
findPreference<VectorPreference>(VectorPreferences.SETTINGS_SECURE_BACKUP_RECOVERY_PREFERENCE_KEY)
|
||||
}
|
||||
// private val secureBackupResetPreference by lazy {
|
||||
// findPreference<VectorPreference>(VectorPreferences.SETTINGS_SECURE_BACKUP_RESET_PREFERENCE_KEY)
|
||||
// }
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
disposables.forEach {
|
||||
it.dispose()
|
||||
}
|
||||
disposables.clear()
|
||||
}
|
||||
|
||||
private fun refresh4SSection(state: RxSession.SecretsSynchronisationInfo) {
|
||||
secureBackupCategory?.isVisible = false
|
||||
|
||||
// it's a lot of if / else if / else
|
||||
// But it's not yet clear how to manage all cases
|
||||
if (!state.isCrossSigningEnabled) {
|
||||
// There is not cross signing, so we can remove the section
|
||||
} else {
|
||||
secureBackupCategory?.isVisible = true
|
||||
|
||||
if (!state.isBackupSetup) {
|
||||
if (state.isCrossSigningEnabled && state.allPrivateKeysKnown) {
|
||||
// You can setup recovery!
|
||||
secureBackupCategory?.isVisible = true
|
||||
secureBackupPreference?.isVisible = true
|
||||
secureBackupPreference?.title = getString(R.string.settings_secure_backup_setup)
|
||||
secureBackupPreference?.isEnabled = true
|
||||
secureBackupPreference?.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||
BootstrapBottomSheet.show(parentFragmentManager, initCrossSigningOnly = false, forceReset4S = false)
|
||||
true
|
||||
}
|
||||
} else {
|
||||
// just hide all, you can't setup from here
|
||||
// you should synchronize to get gossips
|
||||
secureBackupCategory?.isVisible = false
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// so here we know that 4S is setup
|
||||
if (state.isCrossSigningTrusted && state.allPrivateKeysKnown) {
|
||||
// Looks like we have all cross signing secrets and session is trusted
|
||||
// Let's see if there is a megolm backup
|
||||
if (!state.megolmBackupAvailable || state.megolmSecretKnown) {
|
||||
// Only option here is to create a new backup if you want?
|
||||
// aka reset
|
||||
secureBackupCategory?.isVisible = true
|
||||
secureBackupPreference?.isVisible = true
|
||||
secureBackupPreference?.title = getString(R.string.settings_secure_backup_reset)
|
||||
secureBackupPreference?.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||
BootstrapBottomSheet.show(parentFragmentManager, initCrossSigningOnly = false, forceReset4S = true)
|
||||
true
|
||||
}
|
||||
} else if (!state.megolmSecretKnown) {
|
||||
// megolm backup is available but we don't have key
|
||||
// you could try to synchronize to get missing megolm key ?
|
||||
secureBackupCategory?.isVisible = true
|
||||
secureBackupPreference?.isVisible = true
|
||||
secureBackupPreference?.title = getString(R.string.settings_secure_backup_enter_to_setup)
|
||||
secureBackupPreference?.isEnabled = true
|
||||
secureBackupPreference?.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||
(requireActivity() as? VectorBaseActivity)?.let {
|
||||
it.navigator.requestSelfSessionVerification(it)
|
||||
}
|
||||
true
|
||||
}
|
||||
} else {
|
||||
secureBackupCategory?.isVisible = false
|
||||
}
|
||||
return
|
||||
} else {
|
||||
// there is a backup, but this session is not trusted, or is missing some secrets
|
||||
// you should enter passphrase to get them or verify against another session
|
||||
secureBackupCategory?.isVisible = true
|
||||
secureBackupPreference?.isVisible = true
|
||||
secureBackupPreference?.title = getString(R.string.settings_secure_backup_enter_to_setup)
|
||||
secureBackupPreference?.isEnabled = true
|
||||
secureBackupPreference?.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||
(requireActivity() as? VectorBaseActivity)?.let {
|
||||
it.navigator.requestSelfSessionVerification(it)
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun bindPref() {
|
||||
|
@ -115,26 +226,43 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
|
|||
}
|
||||
|
||||
refreshXSigningStatus()
|
||||
|
||||
// secureBackupResetPreference?.let { pref ->
|
||||
// val destructiveColor = ContextCompat.getColor(requireContext(), R.color.riotx_destructive_accent)
|
||||
// pref.title = span {
|
||||
// text = getString(R.string.keys_backup_restore_setup_recovery_key)
|
||||
// textColor = destructiveColor
|
||||
// }
|
||||
// pref.icon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_delete)?.let {
|
||||
// ThemeUtils.tintDrawableWithColor(it, destructiveColor)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// Todo this should be refactored and use same state as 4S section
|
||||
private fun refreshXSigningStatus() {
|
||||
val crossSigningKeys = session.cryptoService().crossSigningService().getMyCrossSigningKeys()
|
||||
val xSigningIsEnableInAccount = crossSigningKeys != null
|
||||
val xSigningKeysAreTrusted = session.cryptoService().crossSigningService().checkUserTrust(session.myUserId).isVerified()
|
||||
val xSigningKeyCanSign = session.cryptoService().crossSigningService().canCrossSign()
|
||||
|
||||
if (xSigningKeyCanSign) {
|
||||
mCrossSigningStatePreference.setIcon(R.drawable.ic_shield_trusted)
|
||||
mCrossSigningStatePreference.summary = getString(R.string.encryption_information_dg_xsigning_complete)
|
||||
} else if (xSigningKeysAreTrusted) {
|
||||
mCrossSigningStatePreference.setIcon(R.drawable.ic_shield_custom)
|
||||
mCrossSigningStatePreference.summary = getString(R.string.encryption_information_dg_xsigning_trusted)
|
||||
} else if (xSigningIsEnableInAccount) {
|
||||
mCrossSigningStatePreference.setIcon(R.drawable.ic_shield_black)
|
||||
mCrossSigningStatePreference.summary = getString(R.string.encryption_information_dg_xsigning_not_trusted)
|
||||
} else {
|
||||
mCrossSigningStatePreference.setIcon(android.R.color.transparent)
|
||||
mCrossSigningStatePreference.summary = getString(R.string.encryption_information_dg_xsigning_disabled)
|
||||
when {
|
||||
xSigningKeyCanSign -> {
|
||||
mCrossSigningStatePreference.setIcon(R.drawable.ic_shield_trusted)
|
||||
mCrossSigningStatePreference.summary = getString(R.string.encryption_information_dg_xsigning_complete)
|
||||
}
|
||||
xSigningKeysAreTrusted -> {
|
||||
mCrossSigningStatePreference.setIcon(R.drawable.ic_shield_custom)
|
||||
mCrossSigningStatePreference.summary = getString(R.string.encryption_information_dg_xsigning_trusted)
|
||||
}
|
||||
xSigningIsEnableInAccount -> {
|
||||
mCrossSigningStatePreference.setIcon(R.drawable.ic_shield_black)
|
||||
mCrossSigningStatePreference.summary = getString(R.string.encryption_information_dg_xsigning_not_trusted)
|
||||
}
|
||||
else -> {
|
||||
mCrossSigningStatePreference.setIcon(android.R.color.transparent)
|
||||
mCrossSigningStatePreference.summary = getString(R.string.encryption_information_dg_xsigning_disabled)
|
||||
}
|
||||
}
|
||||
|
||||
mCrossSigningStatePreference.isVisible = true
|
||||
|
|
|
@ -121,7 +121,7 @@ class SignOutBottomSheetDialogFragment : VectorBaseBottomSheetDialogFragment(),
|
|||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
setupRecoveryButton.action = {
|
||||
BootstrapBottomSheet.show(parentFragmentManager, false)
|
||||
BootstrapBottomSheet.show(parentFragmentManager, initCrossSigningOnly = false, forceReset4S = false)
|
||||
}
|
||||
|
||||
exitAnywayButton.action = {
|
||||
|
|
|
@ -71,4 +71,18 @@
|
|||
android:layout_height="1dp"
|
||||
android:background="?attr/vctr_list_divider_color" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bootstrapSetupWarningTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/reset_secure_backup_warning"
|
||||
android:textColor="@color/riotx_destructive_accent"
|
||||
android:drawableStart="@drawable/ic_warning_small"
|
||||
android:drawablePadding="4dp"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -843,6 +843,15 @@
|
|||
<string name="settings_send_message_with_enter">Send message with enter</string>
|
||||
<string name="settings_send_message_with_enter_summary">Enter button of the soft keyboard will send message instead of adding a line break</string>
|
||||
|
||||
<string name="settings_secure_backup_section_title">Secure Backup</string>
|
||||
<string name="settings_secure_backup_manage">Manage</string>
|
||||
<string name="settings_secure_backup_setup">Set up Secure Backup</string>
|
||||
<string name="settings_secure_backup_reset">Reset Secure Backup</string>
|
||||
<string name="settings_secure_backup_enter_to_setup">Set up on this device</string>
|
||||
<string name="settings_secure_backup_section_info">Safeguard against losing access to encrypted messages & data by backing up encryption keys on your server.</string>
|
||||
<string name="reset_secure_backup_title">Generate a new Security Key or set a new Security Phrase for your existing backup.</string>
|
||||
<string name="reset_secure_backup_warning">This will replace your current Key or Phrase.</string>
|
||||
|
||||
<string name="settings_deactivate_account_section">Deactivate account</string>
|
||||
<string name="settings_deactivate_my_account">Deactivate my account</string>
|
||||
<string name="settings_discovery_category">Discovery</string>
|
||||
|
|
|
@ -48,6 +48,23 @@
|
|||
|
||||
</im.vector.riotx.core.preference.VectorPreferenceCategory>
|
||||
|
||||
<im.vector.riotx.core.preference.VectorPreferenceCategory
|
||||
android:key="SETTINGS_CRYPTOGRAPHY_MANAGE_4S_CATEGORY_KEY"
|
||||
android:title="@string/settings_secure_backup_section_title">
|
||||
|
||||
<im.vector.riotx.core.preference.VectorPreference
|
||||
android:key="SETTINGS_SECURE_BACKUP_RECOVERY_PREFERENCE_KEY"
|
||||
android:persistent="false"
|
||||
android:icon="@drawable/ic_secure_backup"
|
||||
android:title="@string/settings_secure_backup_setup" />
|
||||
|
||||
<im.vector.riotx.core.preference.VectorPreference
|
||||
android:focusable="false"
|
||||
android:persistent="false"
|
||||
android:summary="@string/settings_secure_backup_section_info" />
|
||||
</im.vector.riotx.core.preference.VectorPreferenceCategory>
|
||||
|
||||
|
||||
<im.vector.riotx.core.preference.VectorPreferenceCategory
|
||||
android:key="SETTINGS_CRYPTOGRAPHY_MANAGE_PREFERENCE_KEY"
|
||||
android:title="@string/settings_cryptography_manage_keys">
|
||||
|
|
Loading…
Reference in New Issue