From 8df7797f6d958a5d39625455e05cdbf9295d650e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 9 Jun 2020 22:48:01 +0200 Subject: [PATCH] Remove BootstrapStep.SetupPassphrase and BootstrapStep.ConfirmPassphrase --- .../im/vector/riotx/core/di/FragmentModule.kt | 12 -- .../crypto/recover/BootstrapActions.kt | 4 - .../crypto/recover/BootstrapBottomSheet.kt | 10 -- .../BootstrapConfirmPassphraseFragment.kt | 118 ---------------- .../recover/BootstrapCrossSigningTask.kt | 26 +--- .../BootstrapEnterPassphraseFragment.kt | 126 ----------------- .../recover/BootstrapMigrateBackupFragment.kt | 6 +- .../recover/BootstrapSharedViewModel.kt | 133 +++--------------- .../features/crypto/recover/BootstrapStep.kt | 38 +++-- 9 files changed, 47 insertions(+), 426 deletions(-) delete mode 100644 vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapConfirmPassphraseFragment.kt delete mode 100644 vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapEnterPassphraseFragment.kt diff --git a/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt index 0b7731ee70..6214677020 100644 --- a/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/riotx/core/di/FragmentModule.kt @@ -28,8 +28,6 @@ import im.vector.riotx.features.crypto.quads.SharedSecuredStorageKeyFragment import im.vector.riotx.features.crypto.quads.SharedSecuredStoragePassphraseFragment import im.vector.riotx.features.crypto.recover.BootstrapAccountPasswordFragment import im.vector.riotx.features.crypto.recover.BootstrapConclusionFragment -import im.vector.riotx.features.crypto.recover.BootstrapConfirmPassphraseFragment -import im.vector.riotx.features.crypto.recover.BootstrapEnterPassphraseFragment import im.vector.riotx.features.crypto.recover.BootstrapMigrateBackupFragment import im.vector.riotx.features.crypto.recover.BootstrapSaveRecoveryKeyFragment import im.vector.riotx.features.crypto.recover.BootstrapWaitingFragment @@ -453,16 +451,6 @@ interface FragmentModule { @FragmentKey(GossipingEventsPaperTrailFragment::class) fun bindGossipingEventsPaperTrailFragment(fragment: GossipingEventsPaperTrailFragment): Fragment - @Binds - @IntoMap - @FragmentKey(BootstrapEnterPassphraseFragment::class) - fun bindBootstrapEnterPassphraseFragment(fragment: BootstrapEnterPassphraseFragment): Fragment - - @Binds - @IntoMap - @FragmentKey(BootstrapConfirmPassphraseFragment::class) - fun bindBootstrapConfirmPassphraseFragment(fragment: BootstrapConfirmPassphraseFragment): Fragment - @Binds @IntoMap @FragmentKey(BootstrapWaitingFragment::class) diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapActions.kt b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapActions.kt index 9e4f3ea527..b1e94e551c 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapActions.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapActions.kt @@ -24,15 +24,11 @@ sealed class BootstrapActions : VectorViewModelAction { // Navigation object GoBack : BootstrapActions() - data class GoToConfirmPassphrase(val passphrase: String) : BootstrapActions() object GoToCompleted : BootstrapActions() object GoToEnterAccountPassword : BootstrapActions() - data class DoInitialize(val passphrase: String) : BootstrapActions() object DoInitializeGeneratedKey : BootstrapActions() object TogglePasswordVisibility : BootstrapActions() - data class UpdateCandidatePassphrase(val pass: String) : BootstrapActions() - data class UpdateConfirmCandidatePassphrase(val pass: String) : BootstrapActions() data class ReAuth(val pass: String) : BootstrapActions() object RecoveryKeySaved : BootstrapActions() object Completed : BootstrapActions() diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapBottomSheet.kt b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapBottomSheet.kt index d1138c20c7..15edf53a0d 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapBottomSheet.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapBottomSheet.kt @@ -127,16 +127,6 @@ class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment() { bootstrapTitleText.text = getString(R.string.upgrade_security) showFragment(BootstrapWaitingFragment::class, Bundle()) } - is BootstrapStep.SetupPassphrase -> { - bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_message_password)) - bootstrapTitleText.text = getString(R.string.set_recovery_passphrase, getString(R.string.recovery_passphrase)) - showFragment(BootstrapEnterPassphraseFragment::class, Bundle()) - } - is BootstrapStep.ConfirmPassphrase -> { - bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_message_password)) - bootstrapTitleText.text = getString(R.string.confirm_recovery_passphrase, getString(R.string.recovery_passphrase)) - showFragment(BootstrapConfirmPassphraseFragment::class, Bundle()) - } is BootstrapStep.AccountPassword -> { bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_user)) bootstrapTitleText.text = getString(R.string.account_password) diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapConfirmPassphraseFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapConfirmPassphraseFragment.kt deleted file mode 100644 index ebb6416317..0000000000 --- a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapConfirmPassphraseFragment.kt +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2020 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package im.vector.riotx.features.crypto.recover - -import android.os.Bundle -import android.view.View -import android.view.inputmethod.EditorInfo -import androidx.core.text.toSpannable -import androidx.core.view.isGone -import com.airbnb.mvrx.parentFragmentViewModel -import com.airbnb.mvrx.withState -import com.jakewharton.rxbinding3.widget.editorActionEvents -import com.jakewharton.rxbinding3.widget.textChanges -import im.vector.riotx.R -import im.vector.riotx.core.extensions.hideKeyboard -import im.vector.riotx.core.extensions.showPassword -import im.vector.riotx.core.platform.VectorBaseFragment -import im.vector.riotx.core.resources.ColorProvider -import im.vector.riotx.core.utils.colorizeMatchingText -import io.reactivex.android.schedulers.AndroidSchedulers -import kotlinx.android.synthetic.main.fragment_bootstrap_enter_passphrase.* -import java.util.concurrent.TimeUnit -import javax.inject.Inject - -class BootstrapConfirmPassphraseFragment @Inject constructor( - private val colorProvider: ColorProvider -) : VectorBaseFragment() { - - override fun getLayoutResId() = R.layout.fragment_bootstrap_enter_passphrase - - val sharedViewModel: BootstrapSharedViewModel by parentFragmentViewModel() - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - ssss_passphrase_security_progress.isGone = true - - val recPassPhrase = getString(R.string.recovery_passphrase) - bootstrapDescriptionText.text = getString(R.string.bootstrap_info_confirm_text, recPassPhrase) - .toSpannable() - .colorizeMatchingText(recPassPhrase, colorProvider.getColorFromAttribute(android.R.attr.textColorLink)) - - ssss_passphrase_enter_edittext.hint = getString(R.string.passphrase_confirm_passphrase) - - withState(sharedViewModel) { - // set initial value (useful when coming back) - ssss_passphrase_enter_edittext.setText(it.passphraseRepeat ?: "") - ssss_passphrase_enter_edittext.requestFocus() - } - - ssss_passphrase_enter_edittext.editorActionEvents() - .throttleFirst(300, TimeUnit.MILLISECONDS) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { - if (it.actionId == EditorInfo.IME_ACTION_DONE) { - submit() - } - } - .disposeOnDestroyView() - - ssss_passphrase_enter_edittext.textChanges() - .subscribe { - ssss_passphrase_enter_til.error = null - sharedViewModel.handle(BootstrapActions.UpdateConfirmCandidatePassphrase(it?.toString() ?: "")) - } - .disposeOnDestroyView() - - sharedViewModel.observeViewEvents { - // when (it) { -// is SharedSecureStorageViewEvent.InlineError -> { -// ssss_passphrase_enter_til.error = it.message -// } -// } - } - - ssss_view_show_password.debouncedClicks { sharedViewModel.handle(BootstrapActions.TogglePasswordVisibility) } - bootstrapSubmit.debouncedClicks { submit() } - } - - private fun submit() = withState(sharedViewModel) { state -> - if (state.step !is BootstrapStep.ConfirmPassphrase) { - return@withState - } - val passphrase = ssss_passphrase_enter_edittext.text?.toString() - when { - passphrase.isNullOrBlank() -> - ssss_passphrase_enter_til.error = getString(R.string.passphrase_empty_error_message) - passphrase != state.passphrase -> - ssss_passphrase_enter_til.error = getString(R.string.passphrase_passphrase_does_not_match) - else -> { - view?.hideKeyboard() - sharedViewModel.handle(BootstrapActions.DoInitialize(passphrase)) - } - } - } - - override fun invalidate() = withState(sharedViewModel) { state -> - if (state.step is BootstrapStep.ConfirmPassphrase) { - val isPasswordVisible = state.step.isPasswordVisible - ssss_passphrase_enter_edittext.showPassword(isPasswordVisible, updateCursor = false) - ssss_view_show_password.setImageResource(if (isPasswordVisible) R.drawable.ic_eye_closed_black else R.drawable.ic_eye_black) - } - } -} diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapCrossSigningTask.kt b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapCrossSigningTask.kt index c5dc24bf0a..bcb1f6fefd 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapCrossSigningTask.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapCrossSigningTask.kt @@ -68,7 +68,6 @@ interface BootstrapProgressListener { data class Params( val userPasswordAuth: UserPasswordAuth? = null, val progressListener: BootstrapProgressListener? = null, - val passphrase: String?, val keySpec: SsssKeySpec? = null ) @@ -105,24 +104,13 @@ class BootstrapCrossSigningTask @Inject constructor( ) try { keyInfo = awaitCallback { - params.passphrase?.let { passphrase -> - ssssService.generateKeyWithPassphrase( - UUID.randomUUID().toString(), - "ssss_key", - passphrase, - EmptyKeySigner(), - null, - it - ) - } ?: kotlin.run { - ssssService.generateKey( - UUID.randomUUID().toString(), - params.keySpec, - "ssss_key", - EmptyKeySigner(), - it - ) - } + ssssService.generateKey( + UUID.randomUUID().toString(), + params.keySpec, + "ssss_key", + EmptyKeySigner(), + it + ) } } catch (failure: Failure) { return BootstrapResult.FailedToCreateSSSSKey(failure) diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapEnterPassphraseFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapEnterPassphraseFragment.kt deleted file mode 100644 index 982f72c14e..0000000000 --- a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapEnterPassphraseFragment.kt +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2020 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package im.vector.riotx.features.crypto.recover - -import android.os.Bundle -import android.view.View -import android.view.inputmethod.EditorInfo -import androidx.core.text.toSpannable -import com.airbnb.mvrx.parentFragmentViewModel -import com.airbnb.mvrx.withState -import com.jakewharton.rxbinding3.widget.editorActionEvents -import com.jakewharton.rxbinding3.widget.textChanges -import im.vector.riotx.R -import im.vector.riotx.core.extensions.showPassword -import im.vector.riotx.core.platform.VectorBaseFragment -import im.vector.riotx.core.resources.ColorProvider -import im.vector.riotx.core.utils.colorizeMatchingText -import im.vector.riotx.features.settings.VectorLocale -import io.reactivex.android.schedulers.AndroidSchedulers -import kotlinx.android.synthetic.main.fragment_bootstrap_enter_passphrase.* -import java.util.concurrent.TimeUnit -import javax.inject.Inject - -class BootstrapEnterPassphraseFragment @Inject constructor( - private val colorProvider: ColorProvider -) : VectorBaseFragment() { - - override fun getLayoutResId() = R.layout.fragment_bootstrap_enter_passphrase - - val sharedViewModel: BootstrapSharedViewModel by parentFragmentViewModel() - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - val recPassPhrase = getString(R.string.recovery_passphrase) - bootstrapDescriptionText.text = getString(R.string.bootstrap_info_text, recPassPhrase) - .toSpannable() - .colorizeMatchingText(recPassPhrase, colorProvider.getColorFromAttribute(android.R.attr.textColorLink)) - - ssss_passphrase_enter_edittext.hint = getString(R.string.passphrase_enter_passphrase) - withState(sharedViewModel) { - // set initial value (useful when coming back) - ssss_passphrase_enter_edittext.setText(it.passphrase ?: "") - } - ssss_passphrase_enter_edittext.editorActionEvents() - .throttleFirst(300, TimeUnit.MILLISECONDS) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { - if (it.actionId == EditorInfo.IME_ACTION_DONE) { - submit() - } - } - .disposeOnDestroyView() - - ssss_passphrase_enter_edittext.textChanges() - .subscribe { - // ssss_passphrase_enter_til.error = null - sharedViewModel.handle(BootstrapActions.UpdateCandidatePassphrase(it?.toString() ?: "")) -// ssss_passphrase_submit.isEnabled = it.isNotBlank() - } - .disposeOnDestroyView() - - sharedViewModel.observeViewEvents { - // when (it) { -// is SharedSecureStorageViewEvent.InlineError -> { -// ssss_passphrase_enter_til.error = it.message -// } -// } - } - - ssss_view_show_password.debouncedClicks { sharedViewModel.handle(BootstrapActions.TogglePasswordVisibility) } - bootstrapSubmit.debouncedClicks { submit() } - } - - private fun submit() = withState(sharedViewModel) { state -> - if (state.step !is BootstrapStep.SetupPassphrase) { - return@withState - } - val score = state.passphraseStrength.invoke()?.score - val passphrase = ssss_passphrase_enter_edittext.text?.toString() - if (passphrase.isNullOrBlank()) { - ssss_passphrase_enter_til.error = getString(R.string.passphrase_empty_error_message) - } else if (score != 4) { - ssss_passphrase_enter_til.error = getString(R.string.passphrase_passphrase_too_weak) - } else { - sharedViewModel.handle(BootstrapActions.GoToConfirmPassphrase(passphrase)) - } - } - - override fun invalidate() = withState(sharedViewModel) { state -> - if (state.step is BootstrapStep.SetupPassphrase) { - val isPasswordVisible = state.step.isPasswordVisible - ssss_passphrase_enter_edittext.showPassword(isPasswordVisible, updateCursor = false) - ssss_view_show_password.setImageResource(if (isPasswordVisible) R.drawable.ic_eye_closed_black else R.drawable.ic_eye_black) - - state.passphraseStrength.invoke()?.let { strength -> - val score = strength.score - ssss_passphrase_security_progress.strength = score - if (score in 1..3) { - val hint = - strength.feedback?.getWarning(VectorLocale.applicationLocale)?.takeIf { it.isNotBlank() } - ?: strength.feedback?.getSuggestions(VectorLocale.applicationLocale)?.firstOrNull() - if (hint != null && hint != ssss_passphrase_enter_til.error.toString()) { - ssss_passphrase_enter_til.error = hint - } - } else { - ssss_passphrase_enter_til.error = null - } - } - } - } -} diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapMigrateBackupFragment.kt b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapMigrateBackupFragment.kt index 0b8e201edd..ee583e0381 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapMigrateBackupFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapMigrateBackupFragment.kt @@ -51,15 +51,11 @@ class BootstrapMigrateBackupFragment @Inject constructor( override fun getLayoutResId() = R.layout.fragment_bootstrap_migrate_backup - val sharedViewModel: BootstrapSharedViewModel by parentFragmentViewModel() + private val sharedViewModel: BootstrapSharedViewModel by parentFragmentViewModel() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - withState(sharedViewModel) { - // set initial value (useful when coming back) - bootstrapMigrateEditText.setText(it.passphrase ?: "") - } bootstrapMigrateEditText.editorActionEvents() .throttleFirst(300, TimeUnit.MILLISECONDS) .observeOn(AndroidSchedulers.mainThread()) diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapSharedViewModel.kt b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapSharedViewModel.kt index 78e5cc1fb3..b887df90ca 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapSharedViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapSharedViewModel.kt @@ -26,8 +26,6 @@ import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.Success import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.ViewModelContext -import com.nulabinc.zxcvbn.Strength -import com.nulabinc.zxcvbn.Zxcvbn import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject import im.vector.matrix.android.api.failure.Failure @@ -49,13 +47,9 @@ import kotlinx.coroutines.launch import java.io.OutputStream data class BootstrapViewState( - val step: BootstrapStep = BootstrapStep.SetupPassphrase(false), - val passphrase: String? = null, + val step: BootstrapStep = BootstrapStep.AccountPassword(false), val migrationRecoveryKey: String? = null, - val passphraseRepeat: String? = null, val crossSigningInitialization: Async = Uninitialized, - val passphraseStrength: Async = Uninitialized, - val passphraseConfirmMatch: Async = Uninitialized, val recoveryKeyCreationInfo: SsssKeyCreationInfo? = null, val initializationWaitingViewData: WaitingViewData? = null, val recoverySaveFileProcess: Async = Uninitialized @@ -71,8 +65,6 @@ class BootstrapSharedViewModel @AssistedInject constructor( private val reAuthHelper: ReAuthHelper ) : VectorViewModel(initialState) { - private val zxcvbn = Zxcvbn() - @AssistedInject.Factory interface Factory { fun create(initialState: BootstrapViewState, args: BootstrapBottomSheet.Args): BootstrapSharedViewModel @@ -84,7 +76,7 @@ class BootstrapSharedViewModel @AssistedInject constructor( // need to check if user have an existing keybackup if (args.isNewAccount) { setState { - copy(step = BootstrapStep.SetupPassphrase(false)) + copy(step = BootstrapStep.AccountPassword(false)) } } else { setState { @@ -99,7 +91,7 @@ class BootstrapSharedViewModel @AssistedInject constructor( if (version == null) { // we just resume plain bootstrap setState { - copy(step = BootstrapStep.SetupPassphrase(false)) + copy(step = BootstrapStep.AccountPassword(false)) } } else { // we need to get existing backup passphrase/key and convert to SSSS @@ -128,19 +120,9 @@ class BootstrapSharedViewModel @AssistedInject constructor( override fun handle(action: BootstrapActions) = withState { state -> when (action) { - is BootstrapActions.GoBack -> queryBack() - BootstrapActions.TogglePasswordVisibility -> { + is BootstrapActions.GoBack -> queryBack() + BootstrapActions.TogglePasswordVisibility -> { when (state.step) { - is BootstrapStep.SetupPassphrase -> { - setState { - copy(step = state.step.copy(isPasswordVisible = !state.step.isPasswordVisible)) - } - } - is BootstrapStep.ConfirmPassphrase -> { - setState { - copy(step = state.step.copy(isPasswordVisible = !state.step.isPasswordVisible)) - } - } is BootstrapStep.AccountPassword -> { setState { copy(step = state.step.copy(isPasswordVisible = !state.step.isPasswordVisible)) @@ -155,119 +137,64 @@ class BootstrapSharedViewModel @AssistedInject constructor( } } } - - is BootstrapActions.UpdateCandidatePassphrase -> { - val strength = zxcvbn.measure(action.pass) - setState { - copy( - passphrase = action.pass, - passphraseStrength = Success(strength) - ) - } - } - is BootstrapActions.GoToConfirmPassphrase -> { - setState { - copy( - passphrase = action.passphrase, - step = BootstrapStep.ConfirmPassphrase( - isPasswordVisible = (state.step as? BootstrapStep.SetupPassphrase)?.isPasswordVisible ?: false - ) - ) - } - } - is BootstrapActions.UpdateConfirmCandidatePassphrase -> { - setState { - copy( - passphraseRepeat = action.pass - ) - } - } - is BootstrapActions.DoInitialize -> { - if (state.passphrase == state.passphraseRepeat) { - val userPassword = reAuthHelper.data - if (userPassword == null) { - setState { - copy( - step = BootstrapStep.AccountPassword(false) - ) - } - } else { - startInitializeFlow(userPassword) - } - } else { - setState { - copy( - passphraseConfirmMatch = Fail(Throwable(stringProvider.getString(R.string.passphrase_passphrase_does_not_match))) - ) - } - } - } - is BootstrapActions.DoInitializeGeneratedKey -> { + is BootstrapActions.DoInitializeGeneratedKey -> { val userPassword = reAuthHelper.data if (userPassword == null) { setState { copy( - passphrase = null, - passphraseRepeat = null, step = BootstrapStep.AccountPassword(false) ) } } else { - setState { - copy( - passphrase = null, - passphraseRepeat = null - ) - } startInitializeFlow(userPassword) } } - BootstrapActions.RecoveryKeySaved -> { + BootstrapActions.RecoveryKeySaved -> { _viewEvents.post(BootstrapViewEvents.RecoveryKeySaved) setState { copy(step = BootstrapStep.SaveRecoveryKey(true)) } } - BootstrapActions.Completed -> { + BootstrapActions.Completed -> { _viewEvents.post(BootstrapViewEvents.Dismiss) } - BootstrapActions.GoToCompleted -> { + BootstrapActions.GoToCompleted -> { setState { copy(step = BootstrapStep.DoneSuccess) } } - BootstrapActions.SaveReqQueryStarted -> { + BootstrapActions.SaveReqQueryStarted -> { setState { copy(recoverySaveFileProcess = Loading()) } } - is BootstrapActions.SaveKeyToUri -> { + is BootstrapActions.SaveKeyToUri -> { saveRecoveryKeyToUri(action.os) } - BootstrapActions.SaveReqFailed -> { + BootstrapActions.SaveReqFailed -> { setState { copy(recoverySaveFileProcess = Uninitialized) } } - BootstrapActions.GoToEnterAccountPassword -> { + BootstrapActions.GoToEnterAccountPassword -> { setState { copy(step = BootstrapStep.AccountPassword(false)) } } - BootstrapActions.HandleForgotBackupPassphrase -> { + BootstrapActions.HandleForgotBackupPassphrase -> { if (state.step is BootstrapStep.GetBackupSecretPassForMigration) { setState { copy(step = BootstrapStep.GetBackupSecretPassForMigration(state.step.isPasswordVisible, true)) } } else return@withState } - is BootstrapActions.ReAuth -> { + is BootstrapActions.ReAuth -> { startInitializeFlow(action.pass) } - is BootstrapActions.DoMigrateWithPassphrase -> { + is BootstrapActions.DoMigrateWithPassphrase -> { startMigrationFlow(state.step, action.passphrase, null) } - is BootstrapActions.DoMigrateWithRecoveryKey -> { + is BootstrapActions.DoMigrateWithRecoveryKey -> { startMigrationFlow(state.step, null, action.recoveryKey) } }.exhaustive @@ -316,8 +243,6 @@ class BootstrapSharedViewModel @AssistedInject constructor( if (it is BackupToQuadSMigrationTask.Result.Success) { setState { copy( - passphrase = passphrase, - passphraseRepeat = passphrase, migrationRecoveryKey = recoveryKey ) } @@ -365,6 +290,7 @@ class BootstrapSharedViewModel @AssistedInject constructor( } withState { state -> + val previousStep = state.step viewModelScope.launch(Dispatchers.IO) { val userPasswordAuth = userPassword?.let { UserPasswordAuth( @@ -379,7 +305,6 @@ class BootstrapSharedViewModel @AssistedInject constructor( Params( userPasswordAuth = userPasswordAuth, progressListener = progressListener, - passphrase = state.passphrase, keySpec = state.migrationRecoveryKey?.let { extractCurveKeyFromRecoveryKey(it)?.let { RawBytesKeySpec(it) } } ) ) { bootstrapResult -> @@ -423,7 +348,7 @@ class BootstrapSharedViewModel @AssistedInject constructor( _viewEvents.post(BootstrapViewEvents.ModalError(bootstrapResult.error ?: stringProvider.getString(R.string.matrix_error))) setState { copy( - step = BootstrapStep.ConfirmPassphrase(false) + step = previousStep ) } } @@ -459,25 +384,12 @@ class BootstrapSharedViewModel @AssistedInject constructor( // do we let you cancel from here? _viewEvents.post(BootstrapViewEvents.SkipBootstrap()) } - is BootstrapStep.SetupPassphrase -> { - // do we let you cancel from here? - _viewEvents.post(BootstrapViewEvents.SkipBootstrap()) - } - is BootstrapStep.ConfirmPassphrase -> { - setState { - copy( - step = BootstrapStep.SetupPassphrase( - isPasswordVisible = (state.step as? BootstrapStep.ConfirmPassphrase)?.isPasswordVisible ?: false - ) - ) - } - } is BootstrapStep.AccountPassword -> { - _viewEvents.post(BootstrapViewEvents.SkipBootstrap(state.passphrase != null)) + _viewEvents.post(BootstrapViewEvents.SkipBootstrap(false)) } BootstrapStep.Initializing -> { // do we let you cancel from here? - _viewEvents.post(BootstrapViewEvents.SkipBootstrap(state.passphrase != null)) + _viewEvents.post(BootstrapViewEvents.SkipBootstrap(false)) } is BootstrapStep.SaveRecoveryKey, BootstrapStep.DoneSuccess -> { @@ -490,7 +402,8 @@ class BootstrapSharedViewModel @AssistedInject constructor( // Companion, view model assisted creation // ====================================== - companion object : MvRxViewModelFactory { + companion object + : MvRxViewModelFactory { override fun create(viewModelContext: ViewModelContext, state: BootstrapViewState): BootstrapSharedViewModel? { val fragment: BootstrapBottomSheet = (viewModelContext as FragmentViewModelContext).fragment() diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapStep.kt b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapStep.kt index 2c649ae99c..1855a3b063 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapStep.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/recover/BootstrapStep.kt @@ -30,29 +30,25 @@ package im.vector.riotx.features.crypto.recover * └───────────────────────────────────┘ │ * │ │ * │ │ - * Existing ├─────────No ───────┐ │ - * ┌────Keybackup───────┘ KeyBackup │ │ - * │ │ │ - * │ ▼ ▼ - * ▼ ┌────────────────────────────────────┐ - * ┌─────────────────────────────────────────┐ │ BootstrapStep.SetupPassphrase │◀─┐ - * │BootstrapStep.GetBackupSecretForMigration│ └────────────────────────────────────┘ │ - * └─────────────────────────────────────────┘ │ │ - * │ │ ┌Back - * │ ▼ │ - * │ ┌────────────────────────────────────┤ - * │ │ BootstrapStep.ConfirmPassphrase │──┐ - * │ └────────────────────────────────────┘ │ - * │ │ │ - * │ is password needed? │ - * │ │ │ - * │ ▼ │ + * Existing ├─────────No ──────────────────┐ + * ┌────Keybackup───────┘ KeyBackup │ + * │ │ + * │ │ + * ▼ │ + * ┌─────────────────────────────────────────┐ │ + * │BootstrapStep.GetBackupSecretForMigration│ │ + * └─────────────────────────────────────────┘ │ + * │ │ + * │ │ + * │ is password needed? ─────────────┐ + * │ │ │ + * │ ▼ │ * │ ┌────────────────────────────────────┐ │ * │ │ BootstrapStep.AccountPassword │ │ * │ └────────────────────────────────────┘ │ - * │ │ │ - * │ │ │ - * │ ┌──────────────────┘ password not needed (in + * │ │ │ + * │ │ │ + * │ ┌──────────────┘ password not needed (in * │ │ memory) * │ │ │ * │ ▼ │ @@ -77,8 +73,6 @@ package im.vector.riotx.features.crypto.recover */ sealed class BootstrapStep { - data class SetupPassphrase(val isPasswordVisible: Boolean) : BootstrapStep() - data class ConfirmPassphrase(val isPasswordVisible: Boolean) : BootstrapStep() data class AccountPassword(val isPasswordVisible: Boolean, val failure: String? = null) : BootstrapStep() object CheckingMigration : BootstrapStep()