aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/src/main/java/app/passwordstore/ui/entry/EntryDestination.kt20
-rw-r--r--app/src/main/java/app/passwordstore/ui/entry/EntryViewModel.kt6
2 files changed, 18 insertions, 8 deletions
diff --git a/app/src/main/java/app/passwordstore/ui/entry/EntryDestination.kt b/app/src/main/java/app/passwordstore/ui/entry/EntryDestination.kt
index a54b517d..5c16b5a3 100644
--- a/app/src/main/java/app/passwordstore/ui/entry/EntryDestination.kt
+++ b/app/src/main/java/app/passwordstore/ui/entry/EntryDestination.kt
@@ -25,6 +25,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.key
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
@@ -104,6 +105,9 @@ fun EntryDestination(
}
}
+ // ponytail: after process death during key import or the editor, the unlock flow can start
+ // twice or a prompt can be left over the list; rare, no secret exposed. Fix by tracking
+ // whether the flow already started if it shows up.
val keyImport =
rememberLauncherForActivityResult(StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) unlock() else onClose()
@@ -173,13 +177,15 @@ fun EntryDestination(
)
EntryPrompt.Passphrase,
EntryPrompt.WrongPassphrase ->
- PassphraseDialog(
- wrong = viewModel.prompt == EntryPrompt.WrongPassphrase,
- cacheEnabled = viewModel.cacheEnabled,
- clearCache = viewModel.clearCache,
- onSubmit = { passphrase, clear -> viewModel.submit(passphrase, clear, activity) },
- onCancel = viewModel::cancel,
- )
+ key(viewModel.retries) {
+ PassphraseDialog(
+ wrong = viewModel.prompt == EntryPrompt.WrongPassphrase,
+ cacheEnabled = viewModel.cacheEnabled,
+ clearCache = viewModel.clearCache,
+ onSubmit = { passphrase, clear -> viewModel.submit(passphrase, clear, activity) },
+ onCancel = viewModel::cancel,
+ )
+ }
}
}
}
diff --git a/app/src/main/java/app/passwordstore/ui/entry/EntryViewModel.kt b/app/src/main/java/app/passwordstore/ui/entry/EntryViewModel.kt
index 38d3b9d9..5714f2a6 100644
--- a/app/src/main/java/app/passwordstore/ui/entry/EntryViewModel.kt
+++ b/app/src/main/java/app/passwordstore/ui/entry/EntryViewModel.kt
@@ -86,7 +86,10 @@ constructor(
private var started = false
private var copyOnDecrypt = false
- private var retries = 0
+ /** Failed-or-asked passphrase prompts so far; keys the dialog so each attempt starts fresh. */
+ var retries = 0
+ private set
+
private var auth: BiometricResult = BiometricResult.CanceledByUser
private var ids: List<PGPIdentifier> = emptyList()
private var file: File? = null
@@ -115,6 +118,7 @@ constructor(
}
fun submit(passphrase: String, clearCache: Boolean, context: Context) {
+ if (prompt == EntryPrompt.None) return
prompt = EntryPrompt.None
this.clearCache = clearCache
val app = context.applicationContext