mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-09-19 16:24:41 +01:00
Add screen lock protection to delete account flow.
This commit is contained in:
+18
-2
@@ -78,7 +78,13 @@ class AccountSettingsFragment : ComposeFragment() {
|
||||
onAuthenticationFailed = { viewModel.onEvent(AccountSettingsEvent.AuthenticationFailed) }
|
||||
)
|
||||
|
||||
CollectActions(viewModel.actions) { action -> handleAction(action, removalBiometrics, signalLoginBiometrics) }
|
||||
val deleteAccountBiometrics = rememberBiometricsAuthentication(
|
||||
promptTitle = stringResource(AppSettingsR.string.AccountSettingsFragment__unlock_to_confirm_its_you),
|
||||
educationSheetMessage = stringResource(AppSettingsR.string.AccountSettingsFragment__to_delete_your_account_confirm_its_you),
|
||||
onAuthenticationFailed = { viewModel.onEvent(AccountSettingsEvent.AuthenticationFailed) }
|
||||
)
|
||||
|
||||
CollectActions(viewModel.actions) { action -> handleAction(action, removalBiometrics, signalLoginBiometrics, deleteAccountBiometrics) }
|
||||
|
||||
AccountSettingsScreen(
|
||||
state = state,
|
||||
@@ -86,7 +92,12 @@ class AccountSettingsFragment : ComposeFragment() {
|
||||
)
|
||||
}
|
||||
|
||||
private fun handleAction(action: AccountSettingsAction, removalBiometrics: BiometricsAuthentication, signalLoginBiometrics: BiometricsAuthentication) {
|
||||
private fun handleAction(
|
||||
action: AccountSettingsAction,
|
||||
removalBiometrics: BiometricsAuthentication,
|
||||
signalLoginBiometrics: BiometricsAuthentication,
|
||||
deleteAccountBiometrics: BiometricsAuthentication
|
||||
) {
|
||||
when (action) {
|
||||
AccountSettingsAction.NavigateBack -> requireActivity().onBackPressedDispatcher.onBackPressed()
|
||||
AccountSettingsAction.LaunchCreatePinFlow -> pinFlowLauncher.launch(CreateSvrPinActivity.getIntentForPinCreate(requireContext()))
|
||||
@@ -118,6 +129,11 @@ class AccountSettingsFragment : ComposeFragment() {
|
||||
AccountSettingsAction.NavigateToChangePhoneNumber -> findNavController().safeNavigate(R.id.action_accountSettingsFragment_to_changePhoneNumberFragment)
|
||||
AccountSettingsAction.NavigateToDeviceTransfer -> findNavController().safeNavigate(R.id.action_accountSettingsFragment_to_oldDeviceTransferActivity)
|
||||
AccountSettingsAction.NavigateToExportAccountData -> findNavController().safeNavigate(R.id.action_accountSettingsFragment_to_exportAccountFragment)
|
||||
AccountSettingsAction.AuthenticateToDeleteAccount -> {
|
||||
deleteAccountBiometrics.withBiometricsAuthentication {
|
||||
viewModel.onEvent(AccountSettingsEvent.DeleteAccountAuthenticated)
|
||||
}
|
||||
}
|
||||
AccountSettingsAction.NavigateToDeleteAccount -> findNavController().safeNavigate(R.id.action_accountSettingsFragment_to_deleteAccountFragment)
|
||||
AccountSettingsAction.OpenPlayStore -> PlayStoreUtil.openPlayStoreOrOurApkDownloadPage(requireContext())
|
||||
AccountSettingsAction.LaunchReRegistration -> startActivity(RegistrationActivity.newIntentForReRegistration(requireContext()))
|
||||
|
||||
+3
@@ -138,6 +138,9 @@ class AccountSettingsViewModel(
|
||||
_actions.send(AccountSettingsAction.ShowDataWipeFailed)
|
||||
}
|
||||
AccountSettingsEvent.DeleteAccountClicked -> {
|
||||
_actions.send(AccountSettingsAction.AuthenticateToDeleteAccount)
|
||||
}
|
||||
AccountSettingsEvent.DeleteAccountAuthenticated -> {
|
||||
_actions.send(AccountSettingsAction.NavigateToDeleteAccount)
|
||||
}
|
||||
AccountSettingsEvent.DialogDismissed -> {
|
||||
|
||||
+20
@@ -591,6 +591,26 @@ class AccountSettingsViewModelTest {
|
||||
assertThat(actions.last()).isEqualTo(AccountSettingsAction.NavigateToSignalLoginDetails)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `DeleteAccountClicked asks for the screen lock first`() = runTest(testDispatcher) {
|
||||
val viewModel = createViewModel()
|
||||
val actions = collectActions(viewModel.actions)
|
||||
|
||||
viewModel.onEvent(AccountSettingsEvent.DeleteAccountClicked)
|
||||
|
||||
assertThat(actions.last()).isEqualTo(AccountSettingsAction.AuthenticateToDeleteAccount)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `DeleteAccountAuthenticated opens the delete account screen`() = runTest(testDispatcher) {
|
||||
val viewModel = createViewModel()
|
||||
val actions = collectActions(viewModel.actions)
|
||||
|
||||
viewModel.onEvent(AccountSettingsEvent.DeleteAccountAuthenticated)
|
||||
|
||||
assertThat(actions.last()).isEqualTo(AccountSettingsAction.NavigateToDeleteAccount)
|
||||
}
|
||||
|
||||
private fun methods(vararg methods: TwoFactorMethod) = AccountSettingsRepository.TwoFactorMethodsResult.Success(methods.toList())
|
||||
|
||||
private fun createViewModel(): AccountSettingsViewModel = AccountSettingsViewModel(repository)
|
||||
|
||||
+3
@@ -72,6 +72,9 @@ sealed interface AccountSettingsAction {
|
||||
/** Open registration so the user can re-register. */
|
||||
data object LaunchReRegistration : AccountSettingsAction
|
||||
|
||||
/** Ask the user to get past their screen lock before we send them into the delete account flow. */
|
||||
data object AuthenticateToDeleteAccount : AccountSettingsAction
|
||||
|
||||
/** Open the delete account flow. */
|
||||
data object NavigateToDeleteAccount : AccountSettingsAction
|
||||
|
||||
|
||||
+4
-1
@@ -96,9 +96,12 @@ sealed interface AccountSettingsEvent {
|
||||
/** The fragment reported that clearing application data failed. */
|
||||
data object DataWipeFailed : AccountSettingsEvent
|
||||
|
||||
/** The user tapped the delete account row. */
|
||||
/** The user tapped the delete account row, which asks for the screen lock first. */
|
||||
data object DeleteAccountClicked : AccountSettingsEvent
|
||||
|
||||
/** The user got past their screen lock, so we can send them into the delete account flow. */
|
||||
data object DeleteAccountAuthenticated : AccountSettingsEvent
|
||||
|
||||
/** Dismisses whatever is in [AccountSettingsState.dialog]. */
|
||||
data object DialogDismissed : AccountSettingsEvent
|
||||
}
|
||||
|
||||
@@ -80,6 +80,10 @@
|
||||
<string name="AccountSettingsFragment__unlock_to_view_signal_login">Unlock to view Signal Login</string>
|
||||
<!-- Title of the sheet explaining that the device screen lock is needed before the Signal Login details can be viewed -->
|
||||
<string name="AccountSettingsFragment__to_view_your_signal_login_confirm_its_you">To view your Signal Login, confirm it\'s you</string>
|
||||
<!-- Title of the device screen lock prompt shown before the delete account flow can be opened -->
|
||||
<string name="AccountSettingsFragment__unlock_to_confirm_its_you">Unlock to confirm it\'s you</string>
|
||||
<!-- Title of the sheet explaining that the device screen lock is needed before the delete account flow can be opened -->
|
||||
<string name="AccountSettingsFragment__to_delete_your_account_confirm_its_you">To delete your account, confirm it\'s you</string>
|
||||
<!-- Toast shown when the device screen lock wasn\'t confirmed, so nothing happened -->
|
||||
<string name="AccountSettingsFragment__authentication_required">Authentication required</string>
|
||||
<!-- Title of the dialog shown when the account already has as many authenticator apps as it\'s allowed -->
|
||||
|
||||
Reference in New Issue
Block a user