diff --git a/app/src/main/java/com/kunzisoft/keepass/credentialprovider/UserVerificationHelper.kt b/app/src/main/java/com/kunzisoft/keepass/credentialprovider/UserVerificationHelper.kt
index 8ee640a7e..06593ce15 100644
--- a/app/src/main/java/com/kunzisoft/keepass/credentialprovider/UserVerificationHelper.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/credentialprovider/UserVerificationHelper.kt
@@ -15,6 +15,7 @@ import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.dialogs.CheckDatabaseCredentialDialogFragment
import com.kunzisoft.keepass.credentialprovider.passkey.data.UserVerificationRequirement
import com.kunzisoft.keepass.model.EntryInfo
+import com.kunzisoft.keepass.settings.PreferencesUtil.isUserVerificationDeviceCredential
import com.kunzisoft.keepass.utils.getEnumExtra
import com.kunzisoft.keepass.utils.putEnumExtra
import com.kunzisoft.keepass.view.toastError
@@ -96,11 +97,7 @@ class UserVerificationHelper {
userVerificationViewModel: UserVerificationViewModel,
dataToVerify: UserVerificationData
) {
- if (context?.isAuthenticatorsAllowed() == true) {
- activity?.showUserVerificationDeviceCredential(userVerificationViewModel, dataToVerify)
- } else {
- activity?.showUserVerificationDatabaseCredential(userVerificationViewModel, dataToVerify)
- }
+ activity?.checkUserVerification(userVerificationViewModel, dataToVerify)
}
/**
@@ -110,7 +107,7 @@ class UserVerificationHelper {
userVerificationViewModel: UserVerificationViewModel,
dataToVerify: UserVerificationData
) {
- if (isAuthenticatorsAllowed()) {
+ if (isAuthenticatorsAllowed() && isUserVerificationDeviceCredential(this)) {
showUserVerificationDeviceCredential(userVerificationViewModel, dataToVerify)
} else {
showUserVerificationDatabaseCredential(userVerificationViewModel, dataToVerify)
diff --git a/app/src/main/java/com/kunzisoft/keepass/credentialprovider/activity/PasskeyLauncherActivity.kt b/app/src/main/java/com/kunzisoft/keepass/credentialprovider/activity/PasskeyLauncherActivity.kt
index 61ed1e82e..f27e86091 100644
--- a/app/src/main/java/com/kunzisoft/keepass/credentialprovider/activity/PasskeyLauncherActivity.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/credentialprovider/activity/PasskeyLauncherActivity.kt
@@ -60,7 +60,7 @@ import com.kunzisoft.keepass.database.ContextualDatabase
import com.kunzisoft.keepass.model.AppOrigin
import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_UPDATE_ENTRY_TASK
-import com.kunzisoft.keepass.settings.PreferencesUtil.isPasskeyUserVerificationPreferred
+import com.kunzisoft.keepass.settings.PreferencesUtil.isUserVerificationPreferred
import com.kunzisoft.keepass.tasks.ActionRunnable
import com.kunzisoft.keepass.utils.AppUtil.randomRequestCode
import com.kunzisoft.keepass.view.toastError
@@ -202,7 +202,7 @@ class PasskeyLauncherActivity : DatabaseLockActivity() {
super.onUnknownDatabaseRetrieved(database)
// To manage https://github.com/Kunzisoft/KeePassDX/issues/2283
val userVerificationNeeded = intent.isUserVerificationNeeded(
- userVerificationPreferred = isPasskeyUserVerificationPreferred(this)
+ userVerificationPreferred = isUserVerificationPreferred(this)
) && intent.getUserVerifiedWithAuth().not()
if (userVerificationNeeded) {
checkUserVerification(
diff --git a/app/src/main/java/com/kunzisoft/keepass/settings/NestedAppSettingsFragment.kt b/app/src/main/java/com/kunzisoft/keepass/settings/NestedAppSettingsFragment.kt
index fca226a01..7e0df5669 100644
--- a/app/src/main/java/com/kunzisoft/keepass/settings/NestedAppSettingsFragment.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/settings/NestedAppSettingsFragment.kt
@@ -302,7 +302,7 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
biometricUnlockEnablePreference.isChecked = false
warningMessage(activity, keystoreWarning = true, deleteKeys = true) {
biometricUnlockEnablePreference.isChecked = true
- deviceCredentialUnlockEnablePreference?.isChecked = false
+ deviceCredentialUnlockEnablePreference.isChecked = false
}
} else {
biometricUnlockEnablePreference.isChecked = false
@@ -349,7 +349,7 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
deviceCredentialUnlockEnablePreference.isChecked = false
warningMessage(activity, keystoreWarning = true, deleteKeys = true) {
deviceCredentialUnlockEnablePreference.isChecked = true
- biometricUnlockEnablePreference?.isChecked = false
+ biometricUnlockEnablePreference.isChecked = false
}
} else {
deviceCredentialUnlockEnablePreference.isChecked = false
@@ -523,27 +523,23 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
}
override fun onDisplayPreferenceDialog(preference: Preference) {
-
- var otherDialogFragment = false
-
var dialogFragment: DialogFragment? = null
- // Main Preferences
+
when (preference.key) {
getString(R.string.app_timeout_key),
getString(R.string.clipboard_timeout_key),
getString(R.string.temp_device_unlock_timeout_key) -> {
dialogFragment = DurationDialogFragmentCompat.newInstance(preference.key)
}
- else -> otherDialogFragment = true
+ else -> {}
}
if (dialogFragment != null) {
@Suppress("DEPRECATION")
dialogFragment.setTargetFragment(this, 0)
dialogFragment.show(parentFragmentManager, TAG_PREF_FRAGMENT)
- }
- // Could not be handled here. Try with the super method.
- else if (otherDialogFragment) {
+ } else {
+ // Could not be handled here. Try with the super method.
super.onDisplayPreferenceDialog(preference)
}
}
diff --git a/app/src/main/java/com/kunzisoft/keepass/settings/NestedSettingsFragment.kt b/app/src/main/java/com/kunzisoft/keepass/settings/NestedSettingsFragment.kt
index 0e6d020e0..a1dc7d82b 100644
--- a/app/src/main/java/com/kunzisoft/keepass/settings/NestedSettingsFragment.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/settings/NestedSettingsFragment.kt
@@ -30,11 +30,17 @@ import com.kunzisoft.keepass.activities.dialogs.UnderDevelopmentFeatureDialogFra
abstract class NestedSettingsFragment : PreferenceFragmentCompat() {
enum class Screen {
- APPLICATION, FORM_FILLING, DEVICE_UNLOCK, APPEARANCE, DATABASE, DATABASE_SECURITY, DATABASE_MASTER_KEY
+ APPLICATION,
+ FORM_FILLING,
+ DEVICE_UNLOCK,
+ APPEARANCE,
+ DATABASE,
+ DATABASE_SECURITY,
+ DATABASE_MASTER_KEY
}
fun getScreen(): Screen {
- return Screen.values()[requireArguments().getInt(TAG_KEY)]
+ return Screen.entries[requireArguments().getInt(TAG_KEY)]
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
@@ -50,8 +56,7 @@ abstract class NestedSettingsFragment : PreferenceFragmentCompat() {
preferenceInDev.setOnPreferenceClickListener { preference ->
try { // don't check if we can
(preference as TwoStatePreference).isChecked = false
- } catch (ignored: Exception) {
- }
+ } catch (_: Exception) {}
UnderDevelopmentFeatureDialogFragment().show(parentFragmentManager, "underDevFeatureDialog")
false
}
diff --git a/app/src/main/java/com/kunzisoft/keepass/settings/PreferencesUtil.kt b/app/src/main/java/com/kunzisoft/keepass/settings/PreferencesUtil.kt
index ea19872ea..99df926b2 100644
--- a/app/src/main/java/com/kunzisoft/keepass/settings/PreferencesUtil.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/settings/PreferencesUtil.kt
@@ -690,10 +690,16 @@ object PreferencesUtil {
context.resources.getBoolean(R.bool.passkeys_close_database_default))
}
- fun isPasskeyUserVerificationPreferred(context: Context): Boolean {
+ fun isUserVerificationDeviceCredential(context: Context): Boolean {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
- return prefs.getBoolean(context.getString(R.string.passkeys_user_verification_preferred_key),
- context.resources.getBoolean(R.bool.passkeys_user_verification_preferred_default))
+ return prefs.getBoolean(context.getString(R.string.user_verification_device_credential_key),
+ context.resources.getBoolean(R.bool.user_verification_device_credential_default))
+ }
+
+ fun isUserVerificationPreferred(context: Context): Boolean {
+ val prefs = PreferenceManager.getDefaultSharedPreferences(context)
+ return prefs.getBoolean(context.getString(R.string.user_verification_preferred_key),
+ context.resources.getBoolean(R.bool.user_verification_preferred_default))
}
fun isPasskeyBackupEligibilityEnable(context: Context): Boolean {
diff --git a/app/src/main/res/drawable/prefs_user_verification_24dp.xml b/app/src/main/res/drawable/prefs_user_verification_24dp.xml
new file mode 100644
index 000000000..f51cf2607
--- /dev/null
+++ b/app/src/main/res/drawable/prefs_user_verification_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml
index 00da027fd..7d95a353b 100644
--- a/app/src/main/res/values/donottranslate.xml
+++ b/app/src/main/res/values/donottranslate.xml
@@ -69,6 +69,8 @@
false
delete_entered_password_key
true
+ user_verification_device_credential_key
+ true
enable_auto_save_database_key
true
enable_keep_screen_on_key
@@ -77,8 +79,6 @@
false
auto_focus_search_key
false
- subdomain_search_key
- false
app_timeout_key
lock_database_screen_off_key
true
@@ -140,12 +140,14 @@
passkeys_privileged_apps_key
passkeys_auto_select_key
true
- passkeys_user_verification_preferred_key
- false
passkeys_backup_eligibility_key
true
passkeys_backup_state_key
true
+ user_verification_preferred_key
+ false
+ subdomain_search_key
+ false
keyboard_notification_entry_key
true
keyboard_notification_entry_clear_close_key
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 0e5a60584..f97b6fae0 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -434,8 +434,6 @@
Add app signature to passkey entry?
Auto select
Auto select if only one entry and the database is open, only if the requesting app is compatible
- Preferred User Verification
- Perform a user verification to access sensitive data when the relying party requests \"preferred\".
Backup Eligibility
Determine at creation time whether the public key credential source is allowed to be backed up
Backup State
@@ -446,6 +444,10 @@
Configure autofilling to quickly fill out forms in other apps
Select entry…
Autofill settings
+ Device credential
+ Use the device credential as user verification if available
+ Preferred User Verification
+ Perform a user verification when the relying party requests \"preferred\"
Generated password size
Sets default size of the generated passwords
Password characters
diff --git a/app/src/main/res/xml/preferences_application.xml b/app/src/main/res/xml/preferences_application.xml
index 47338bff7..251a4d00e 100644
--- a/app/src/main/res/xml/preferences_application.xml
+++ b/app/src/main/res/xml/preferences_application.xml
@@ -32,6 +32,11 @@
android:title="@string/delete_entered_password_title"
android:summary="@string/delete_entered_password_summary"
android:defaultValue="@bool/delete_entered_password_default"/>
+
+ android:key="@string/credential_provider_key"
+ android:title="@string/credential_provider">
+ android:key="@string/settings_credential_provider_enable_key"
+ android:title="@string/set_credential_provider_service_title"
+ android:defaultValue="@bool/settings_credential_provider_enable_default"/>
+
+
+
+
+
+ android:title="@string/general">
-
-
-
-
+ android:key="@string/subdomain_search_key"
+ android:title="@string/subdomain_search_title"
+ android:summary="@string/subdomain_search_summary"
+ android:defaultValue="@bool/subdomain_search_default"/>
-
+
diff --git a/art/ic_user_verification.svg b/art/ic_user_verification.svg
new file mode 100644
index 000000000..752cca889
--- /dev/null
+++ b/art/ic_user_verification.svg
@@ -0,0 +1,45 @@
+
+
+
+