diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsFragment.kt
index e2cc328c31..59f699f862 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsFragment.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsFragment.kt
@@ -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()))
diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsViewModel.kt
index 2c846fa09d..ea5f6c5a3f 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsViewModel.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsViewModel.kt
@@ -138,6 +138,9 @@ class AccountSettingsViewModel(
_actions.send(AccountSettingsAction.ShowDataWipeFailed)
}
AccountSettingsEvent.DeleteAccountClicked -> {
+ _actions.send(AccountSettingsAction.AuthenticateToDeleteAccount)
+ }
+ AccountSettingsEvent.DeleteAccountAuthenticated -> {
_actions.send(AccountSettingsAction.NavigateToDeleteAccount)
}
AccountSettingsEvent.DialogDismissed -> {
diff --git a/app/src/test/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsViewModelTest.kt b/app/src/test/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsViewModelTest.kt
index 309b727f3e..5863f985bf 100644
--- a/app/src/test/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsViewModelTest.kt
+++ b/app/src/test/java/org/thoughtcrime/securesms/components/settings/app/account/AccountSettingsViewModelTest.kt
@@ -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)
diff --git a/feature/app-settings/src/main/java/org/signal/appsettings/account/AccountSettingsAction.kt b/feature/app-settings/src/main/java/org/signal/appsettings/account/AccountSettingsAction.kt
index 8195654e74..7a0f419aca 100644
--- a/feature/app-settings/src/main/java/org/signal/appsettings/account/AccountSettingsAction.kt
+++ b/feature/app-settings/src/main/java/org/signal/appsettings/account/AccountSettingsAction.kt
@@ -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
diff --git a/feature/app-settings/src/main/java/org/signal/appsettings/account/AccountSettingsEvent.kt b/feature/app-settings/src/main/java/org/signal/appsettings/account/AccountSettingsEvent.kt
index 8b8d96d8a6..c903344010 100644
--- a/feature/app-settings/src/main/java/org/signal/appsettings/account/AccountSettingsEvent.kt
+++ b/feature/app-settings/src/main/java/org/signal/appsettings/account/AccountSettingsEvent.kt
@@ -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
}
diff --git a/feature/app-settings/src/main/res/values/strings.xml b/feature/app-settings/src/main/res/values/strings.xml
index d4cdce166e..931625014d 100644
--- a/feature/app-settings/src/main/res/values/strings.xml
+++ b/feature/app-settings/src/main/res/values/strings.xml
@@ -80,6 +80,10 @@
Unlock to view Signal Login
To view your Signal Login, confirm it\'s you
+
+ Unlock to confirm it\'s you
+
+ To delete your account, confirm it\'s you
Authentication required