aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-11-04 20:07:05 +0100
committerDanilo M. <danix@danix.xyz>2026-11-04 20:07:05 +0100
commit756754ac6f95deec3b3efea05a4a01a3a7a59550 (patch)
tree5b67c8bf64d8e71d15e6461dca043d8bc125a04d
parentd06f64a75c78991da0b74319c83d794117a8126c (diff)
downloadHardenedPass-756754ac6f95deec3b3efea05a4a01a3a7a59550.tar.gz
HardenedPass-756754ac6f95deec3b3efea05a4a01a3a7a59550.zip
fix(app): show an invalid .gpg-id as a snackbar in the entry view and editor
getPGPIdentifiers showed its own Toast, while the entry view and the editor report every other error with a snackbar. It now passes the message to its caller: the entry view and editor show a snackbar, autofill keeps the Toast because its window finishes right after. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
-rw-r--r--TODO.md2
-rw-r--r--app/src/main/java/app/passwordstore/ui/autofill/AutofillDecryptActivity.kt7
-rw-r--r--app/src/main/java/app/passwordstore/ui/crypto/CryptoExtensions.kt12
-rw-r--r--app/src/main/java/app/passwordstore/ui/editor/EditorDestination.kt2
-rw-r--r--app/src/main/java/app/passwordstore/ui/entry/EntryDestination.kt5
5 files changed, 15 insertions, 13 deletions
diff --git a/TODO.md b/TODO.md
index 1fa43fb5..132aef17 100644
--- a/TODO.md
+++ b/TODO.md
@@ -16,5 +16,3 @@ Open work after 0.2.0. Remove an item in the commit that finishes it.
does not work (fill and generate do). First check that it sends save requests.
- A stale cached passphrase (the key's passphrase changed) makes every autofill fail until the
cache is cleared; the entry view asks for the passphrase instead. Do the same in autofill.
-- A bad `.gpg-id` shows a Toast in the entry view and editor, where their other errors use a
- snackbar. Return the reason from `getPGPIdentifiers` and let each caller show it.
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 3f0fb5ef..f6d5df0f 100644
--- a/app/src/main/java/app/passwordstore/ui/autofill/AutofillDecryptActivity.kt
+++ b/app/src/main/java/app/passwordstore/ui/autofill/AutofillDecryptActivity.kt
@@ -13,6 +13,7 @@ import android.os.Build
import android.os.Bundle
import android.view.WindowManager
import android.view.autofill.AutofillManager
+import android.widget.Toast
import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
import androidx.appcompat.app.AppCompatActivity
@@ -211,7 +212,11 @@ class AutofillDecryptActivity : AppCompatActivity() {
val gpgIdentifiers =
getPGPIdentifiers(
getParentPath(filePath, PasswordRepository.getRepositoryDirectory().toString())
- )
+ ) {
+ // A toast on the application context, not a snackbar: this window finishes right after,
+ // and the toast must outlive it.
+ Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show()
+ }
?: run {
finish()
return
diff --git a/app/src/main/java/app/passwordstore/ui/crypto/CryptoExtensions.kt b/app/src/main/java/app/passwordstore/ui/crypto/CryptoExtensions.kt
index fbaa534f..67343a2e 100644
--- a/app/src/main/java/app/passwordstore/ui/crypto/CryptoExtensions.kt
+++ b/app/src/main/java/app/passwordstore/ui/crypto/CryptoExtensions.kt
@@ -6,11 +6,9 @@
package app.passwordstore.ui.crypto
import android.content.ClipData
-import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.PersistableBundle
-import android.widget.Toast
import androidx.annotation.StringRes
import androidx.fragment.app.FragmentActivity
import app.passwordstore.R
@@ -95,10 +93,10 @@ fun FragmentActivity.copyPasswordToClipboard(password: String?) {
/**
* Get a list of available [PGPIdentifier]s for the current password repository. This method throws
* when no identifiers were able to be parsed. If this method returns null, an invalid identifier
- * was encountered and reported with a toast: further execution must stop to let the user correct
- * the problem.
+ * was encountered and its message passed to [onInvalid]: further execution must stop to let the
+ * user correct the problem.
*/
-fun Context.getPGPIdentifiers(subDir: String): List<PGPIdentifier>? {
+fun getPGPIdentifiers(subDir: String, onInvalid: (message: Int) -> Unit): List<PGPIdentifier>? {
val repoRoot = PasswordRepository.getRepositoryDirectory()
val gpgIdentifierFile =
File(repoRoot, subDir).findTillRoot(".gpg-id", repoRoot)
@@ -119,9 +117,7 @@ fun Context.getPGPIdentifiers(subDir: String): List<PGPIdentifier>? {
val message =
if (line.removePrefix("0x").matches("[a-fA-F0-9]{8}".toRegex())) R.string.short_gpg_id
else R.string.invalid_gpg_id
- // A toast on the application context, not a snackbar: the autofill decryption
- // finishes its window right after, and the toast must outlive it.
- Toast.makeText(applicationContext, message, Toast.LENGTH_LONG).show()
+ onInvalid(message)
return null
}
}
diff --git a/app/src/main/java/app/passwordstore/ui/editor/EditorDestination.kt b/app/src/main/java/app/passwordstore/ui/editor/EditorDestination.kt
index 6d9f9c9f..b5a961d3 100644
--- a/app/src/main/java/app/passwordstore/ui/editor/EditorDestination.kt
+++ b/app/src/main/java/app/passwordstore/ui/editor/EditorDestination.kt
@@ -121,7 +121,7 @@ fun EditorDestination(
if (problem != null) return say(problem)
// Recipients from the nearest .gpg-id, as pass does; null: an invalid ID, already reported.
val ids =
- activity.getPGPIdentifiers(target.parentFile?.relativeTo(root)?.path.orEmpty()) ?: return
+ getPGPIdentifiers(target.parentFile?.relativeTo(root)?.path.orEmpty(), ::say) ?: return
activity.lifecycleScope.launch {
val result = viewModel.save(ids, target, original, activity, copy)
if (result is SaveResult.Failed) failure = activity.getString(result.message, result.arg)
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 02b112f4..c414d4d9 100644
--- a/app/src/main/java/app/passwordstore/ui/entry/EntryDestination.kt
+++ b/app/src/main/java/app/passwordstore/ui/entry/EntryDestination.kt
@@ -53,6 +53,7 @@ import app.passwordstore.ui.setup.SetupStart
import app.passwordstore.util.auth.BiometricAuthenticator
import app.passwordstore.util.auth.BiometricAuthenticator.Result as BiometricResult
import app.passwordstore.util.extensions.sharedPrefs
+import app.passwordstore.util.extensions.snackbar
import app.passwordstore.util.settings.PreferenceKeys
import java.io.File
@@ -79,7 +80,9 @@ fun EntryDestination(
fun unlock() {
val ids =
- activity.getPGPIdentifiers(getParentPath(file.absolutePath, root.absolutePath)) ?: return
+ getPGPIdentifiers(getParentPath(file.absolutePath, root.absolutePath)) {
+ activity.snackbar(message = activity.getString(it))
+ } ?: return
if (viewModel.cacheEnabled && BiometricAuthenticator.canAuthenticate(activity)) {
BiometricAuthenticator.authenticate(
activity,