From f39050a02015ede7dc02065f69d525c1f9ea65d0 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Wed, 4 Nov 2026 11:30:44 +0100 Subject: fix(app): cache only a typed autofill passphrase, close on a bad .gpg-id Autofill re-cached the passphrase it had just read from the cache, and cached an empty one for keys without a passphrase. Like the entry view, it now caches only what the user typed into the passphrase dialog. An unreadable .gpg-id left the transparent window up with a snackbar no one could see; the activity now finishes and fills nothing. Co-Authored-By: Claude Opus 5.5 --- .../ui/autofill/AutofillDecryptActivity.kt | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'app/src/main/java') diff --git a/app/src/main/java/app/passwordstore/ui/autofill/AutofillDecryptActivity.kt b/app/src/main/java/app/passwordstore/ui/autofill/AutofillDecryptActivity.kt index 17859cad..39bf8cff 100644 --- a/app/src/main/java/app/passwordstore/ui/autofill/AutofillDecryptActivity.kt +++ b/app/src/main/java/app/passwordstore/ui/autofill/AutofillDecryptActivity.kt @@ -154,7 +154,7 @@ class AutofillDecryptActivity : BasePGPActivity() { passphraseFor = null clearCache = clear lifecycleScope.launch(dispatcherProvider.main()) { - decryptWithPassphrase(identifiers, passphrase) + decryptWithPassphrase(identifiers, passphrase, typed = true) } }, onCancel = { finish() }, @@ -199,7 +199,11 @@ class AutofillDecryptActivity : BasePGPActivity() { val gpgIdentifiers = getPGPIdentifiers( getParentPath(filePath, PasswordRepository.getRepositoryDirectory().toString()) - ) ?: return + ) + ?: run { + finish() + return + } lifecycleScope.launch(dispatcherProvider.main()) { when (authResult) { // Internally handled by the prompt dialog @@ -240,8 +244,13 @@ class AutofillDecryptActivity : BasePGPActivity() { passphraseFor = identifiers } - private suspend fun decryptWithPassphrase(identifiers: List, password: String) { - val credentials = decryptCredential(File(filePath), password, identifiers) + /** Caches [password] only when the user [typed] it, as the entry view does. */ + private suspend fun decryptWithPassphrase( + identifiers: List, + password: String, + typed: Boolean = false, + ) { + val credentials = decryptCredential(File(filePath), password, identifiers, typed) if (credentials == null) { setResult(RESULT_CANCELED) } else { @@ -266,6 +275,7 @@ class AutofillDecryptActivity : BasePGPActivity() { file: File, password: String, identifiers: List, + typed: Boolean, ): Credentials? { runCatching { file.readBytes().inputStream() } .onFailure { e -> @@ -283,7 +293,9 @@ class AutofillDecryptActivity : BasePGPActivity() { .onSuccess { result -> return runCatching { runCatching { - if (cachesPassphrase(features.isEnabled(EnablePGPPassphraseCache), auth)) { + if ( + typed && cachesPassphrase(features.isEnabled(EnablePGPPassphraseCache), auth) + ) { passphraseCache.cachePassphrase(this, identifiers.first(), password) settings.edit { putBoolean(PreferenceKeys.CLEAR_PASSPHRASE_CACHE, clearCache) -- cgit v1.2.3