diff --git a/app/src/main/java/app/passwordstore/ui/settings/PGPSettings.kt b/app/src/main/java/app/passwordstore/ui/settings/PGPSettings.kt index c21036ed9..ecf5e8d5e 100644 --- a/app/src/main/java/app/passwordstore/ui/settings/PGPSettings.kt +++ b/app/src/main/java/app/passwordstore/ui/settings/PGPSettings.kt @@ -17,7 +17,6 @@ import app.passwordstore.util.extensions.sharedPrefs import app.passwordstore.util.features.Feature import app.passwordstore.util.settings.PreferenceKeys import de.Maxr1998.modernpreferences.PreferenceScreen -import de.Maxr1998.modernpreferences.helpers.onCheckedChange import de.Maxr1998.modernpreferences.helpers.onClick import de.Maxr1998.modernpreferences.helpers.pref import de.Maxr1998.modernpreferences.helpers.switch @@ -47,27 +46,40 @@ class PGPSettings( titleRes = R.string.pref_passphrase_cache_title summaryRes = R.string.pref_passphrase_cache_summary defaultValue = false - onCheckedChange { checked -> - if (checked) { + onClick { + activity.sharedPrefs.edit { if (BiometricAuthenticator.canAuthenticate(activity)) { - BiometricAuthenticator.authenticate( - activity, - R.string.pref_passphrase_cache_authenticate_enable, - ) { - if (!(it is BiometricAuthenticator.Result.Success)) - activity.sharedPrefs.edit { - putBoolean(Feature.EnablePGPPassphraseCache.configKey, false) + var promptTitle = R.string.pref_passphrase_cache_authenticate_disable + if (checked) promptTitle = R.string.pref_passphrase_cache_authenticate_enable + BiometricAuthenticator.authenticate(activity, promptTitle) { result -> + when (result) { + is BiometricAuthenticator.Result.Success -> { + /* Any successful change of this setting clears the passphrase + * cache for safety */ + activity.lifecycleScope.launch { + passphraseCache.clearAllCachedPassphrases(activity) + } + putBoolean(Feature.EnablePGPPassphraseCache.configKey, checked) + if (!checked) + activity.sharedPrefs.edit { remove(PreferenceKeys.CLEAR_PASSPHRASE_CACHE) } } + is BiometricAuthenticator.Result.Retry -> {} + else -> { + /* revert back to previous state in case of error or cancellation */ + checked = !checked + putBoolean(Feature.EnablePGPPassphraseCache.configKey, checked) + } + } } - } else - activity.sharedPrefs.edit { - putBoolean(Feature.EnablePGPPassphraseCache.configKey, false) - } - } else { - activity.sharedPrefs.edit { remove(PreferenceKeys.CLEAR_PASSPHRASE_CACHE) } - activity.lifecycleScope.launch { passphraseCache.clearAllCachedPassphrases(activity) } + } else { + /* we may get here if device lock has been disabled while PGP settings + * screen was left open */ + checked = false + enabled = false + putBoolean(Feature.EnablePGPPassphraseCache.configKey, false) + } } - true + false } } switch(PreferenceKeys.CLEAR_PASSPHRASE_CACHE) { @@ -81,26 +93,35 @@ class PGPSettings( * authentication, otherwise the app crashes. Thus, the bad user could still bypass cache * clearing by dismissing the auhentication dialog. To prevent this, we enforce cache * clearing to stay enabled in case of any authentication failure. */ - onCheckedChange { checked -> + onClick { if (!checked) { - if (BiometricAuthenticator.canAuthenticate(activity)) { + if ( + BiometricAuthenticator.canAuthenticate(activity) && + activity.sharedPrefs.getBoolean(Feature.EnablePGPPassphraseCache.configKey, false) + ) { BiometricAuthenticator.authenticate( activity, R.string.pref_passphrase_cache_auto_clear_authenticate_disable, - ) { - if (it is BiometricAuthenticator.Result.Success) { - activity.lifecycleScope.launch { - passphraseCache.clearAllCachedPassphrases(activity) + ) { result -> + when (result) { + is BiometricAuthenticator.Result.Success -> { + activity.lifecycleScope.launch { + passphraseCache.clearAllCachedPassphrases(activity) + } + } + is BiometricAuthenticator.Result.Retry -> {} + else -> { + activity.sharedPrefs.edit { remove(PreferenceKeys.CLEAR_PASSPHRASE_CACHE) } + checked = !checked } - } else { - activity.sharedPrefs.edit { remove(PreferenceKeys.CLEAR_PASSPHRASE_CACHE) } } } } else { activity.sharedPrefs.edit { remove(PreferenceKeys.CLEAR_PASSPHRASE_CACHE) } + checked = !checked } } - true + false } } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a971006ed..5c2a7b930 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -138,6 +138,7 @@ Enable passphrase caching WARNING: this feature is functional but very experimental. Requires an active screen lock. Authenticate to enable cache + Authenticate to disable cache Authenticate to disable cache clearing Automatically clear passphrase cache Clears the passphrase cache when the screen is turned off