diff --git a/app/src/main/assets/fido2_privileged_google.json b/app/src/free/assets/passkeys_privileged_apps_google.json
similarity index 100%
rename from app/src/main/assets/fido2_privileged_google.json
rename to app/src/free/assets/passkeys_privileged_apps_google.json
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d9adc5a52..5a952e707 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -159,20 +159,22 @@
android:label="@string/about" />
-
+
+
(KEY_SEARCH_INFO)?.let { searchInfo ->
- WebDomain.getConcreteWebDomain(
+ AppUtil.getConcreteWebDomain(
this,
searchInfo.webDomain
) { concreteWebDomain ->
@@ -109,7 +109,7 @@ class AutofillLauncherActivity : DatabaseModeActivity() {
KEY_REGISTER_INFO
)
val searchInfo = SearchInfo(registerInfo?.searchInfo)
- WebDomain.getConcreteWebDomain(this, searchInfo.webDomain) { concreteWebDomain ->
+ AppUtil.getConcreteWebDomain(this, searchInfo.webDomain) { concreteWebDomain ->
searchInfo.webDomain = concreteWebDomain
launchRegistration(database, searchInfo, registerInfo)
}
diff --git a/app/src/main/java/com/kunzisoft/keepass/credentialprovider/activity/EntrySelectionLauncherActivity.kt b/app/src/main/java/com/kunzisoft/keepass/credentialprovider/activity/EntrySelectionLauncherActivity.kt
index 2c1bdb4f5..e3b2f4dad 100644
--- a/app/src/main/java/com/kunzisoft/keepass/credentialprovider/activity/EntrySelectionLauncherActivity.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/credentialprovider/activity/EntrySelectionLauncherActivity.kt
@@ -33,8 +33,8 @@ import com.kunzisoft.keepass.database.ContextualDatabase
import com.kunzisoft.keepass.database.helper.SearchHelper
import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.otp.OtpEntryFields
+import com.kunzisoft.keepass.utils.AppUtil
import com.kunzisoft.keepass.utils.KeyboardUtil.isKeyboardActivatedInSettings
-import com.kunzisoft.keepass.utils.WebDomain
import com.kunzisoft.keepass.utils.getParcelableCompat
/**
@@ -109,7 +109,7 @@ class EntrySelectionLauncherActivity : DatabaseModeActivity() {
this.otpString = otpString
}
- WebDomain.getConcreteWebDomain(this, searchInfo.webDomain) { concreteWebDomain ->
+ AppUtil.getConcreteWebDomain(this, searchInfo.webDomain) { concreteWebDomain ->
searchInfo.webDomain = concreteWebDomain
launch(database, searchInfo)
}
diff --git a/app/src/main/java/com/kunzisoft/keepass/credentialprovider/autofill/KeeAutofillService.kt b/app/src/main/java/com/kunzisoft/keepass/credentialprovider/autofill/KeeAutofillService.kt
index 9d832e3e1..6c3a3aeea 100644
--- a/app/src/main/java/com/kunzisoft/keepass/credentialprovider/autofill/KeeAutofillService.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/credentialprovider/autofill/KeeAutofillService.kt
@@ -53,7 +53,7 @@ import com.kunzisoft.keepass.model.RegisterInfo
import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.settings.AutofillSettingsActivity
import com.kunzisoft.keepass.settings.PreferencesUtil
-import com.kunzisoft.keepass.utils.WebDomain
+import com.kunzisoft.keepass.utils.AppUtil
import org.joda.time.DateTime
@@ -120,7 +120,7 @@ class KeeAutofillService : AutofillService() {
webDomain = parseResult.webDomain
webScheme = parseResult.webScheme
}
- WebDomain.getConcreteWebDomain(this, searchInfo.webDomain) { webDomainWithoutSubDomain ->
+ AppUtil.getConcreteWebDomain(this, searchInfo.webDomain) { webDomainWithoutSubDomain ->
searchInfo.webDomain = webDomainWithoutSubDomain
val inlineSuggestionsRequest = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
&& autofillInlineSuggestionsEnabled) {
diff --git a/app/src/main/java/com/kunzisoft/keepass/credentialprovider/passkey/util/PasskeyHelper.kt b/app/src/main/java/com/kunzisoft/keepass/credentialprovider/passkey/util/PasskeyHelper.kt
index 2590adc5b..5b5ccb657 100644
--- a/app/src/main/java/com/kunzisoft/keepass/credentialprovider/passkey/util/PasskeyHelper.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/credentialprovider/passkey/util/PasskeyHelper.kt
@@ -328,19 +328,54 @@ object PasskeyHelper {
return request.credentialOptions[0] as GetPublicKeyCredentialOption
}
- private fun getOriginFromPrivilegedAllowList(
+ /**
+ * Get the origin from a privileged allow list,
+ * [fileName] is the name of the file in assets containing the origin list as JSON
+ */
+ private fun getOriginFromPrivilegedAllowListFile(
callingAppInfo: CallingAppInfo,
assets: AssetManager,
- fileName: String): String? {
+ fileName: String
+ ): String? {
val privilegedAllowList = assets.open(fileName).bufferedReader().use {
it.readText()
}
return callingAppInfo.getOrigin(privilegedAllowList)?.removeSuffix("/")
}
+ /**
+ * Get the origin from the predefined privileged allow lists
+ */
+ private fun getOriginFromPrivilegedAllowLists(
+ callingAppInfo: CallingAppInfo,
+ assets: AssetManager
+ ): String? {
+ return try {
+ // TODO add the manual privileged apps
+ // Check the community apps first
+ getOriginFromPrivilegedAllowListFile(
+ callingAppInfo = callingAppInfo,
+ assets = assets,
+ fileName = FILE_NAME_PRIVILEGED_APPS_COMMUNITY
+ )
+ } catch (e: Exception) {
+ // Then the Google list if allowed
+ if (BuildConfig.CLOSED_STORE) {
+ // http://www.gstatic.com/gpm-passkeys-privileged-apps/apps.json
+ getOriginFromPrivilegedAllowListFile(
+ callingAppInfo = callingAppInfo,
+ assets = assets,
+ fileName = FILE_NAME_PRIVILEGED_APPS_GOOGLE
+ )
+ } else {
+ throw e
+ }
+ }
+ }
+
/**
* Utility method to retrieve the origin asynchronously,
- * checks for the presence of the application in the privilege list of the fido2_privileged_google.json file,
+ * checks for the presence of the application in the privilege list of the passkeys_privileged_apps_google.json file,
* call [onOriginRetrieved] if the origin is already calculated by the system and in the privileged list, return the clientDataHash
* call [onOriginNotRetrieved] if the origin is not retrieved from the system, return a new Android Origin
*/
@@ -357,32 +392,15 @@ object PasskeyHelper {
withContext(Dispatchers.IO) {
// For trusted browsers like Chrome and Firefox
- // Check the community apps first
- val callOrigin = try {
- getOriginFromPrivilegedAllowList(
- callingAppInfo,
- assets,
- "fido2_privileged_community.json"
- )
- } catch (e: Exception) {
- // Then the Google list if allowed
- if (BuildConfig.CLOSED_STORE) {
- getOriginFromPrivilegedAllowList(
- callingAppInfo,
- assets,
- "fido2_privileged_google.json"
- )
- } else {
- throw e
- }
- }
+ val callOrigin = getOriginFromPrivilegedAllowLists(callingAppInfo, assets)
+ // Build the default Android origin
val androidOrigin = AndroidOrigin(
packageName = callingAppInfo.packageName,
fingerprint = callingAppInfo.signingInfo.getApplicationFingerprints()
)
- // Check if the webDomain is validated for the
+ // Check if the webDomain is validated by the system
withContext(Dispatchers.Main) {
if (callOrigin != null && providedClientDataHash != null) {
// Origin already defined by the system
@@ -624,4 +642,7 @@ object PasskeyHelper {
}
private const val BACKUP_ELIGIBILITY = true
+
+ private const val FILE_NAME_PRIVILEGED_APPS_COMMUNITY = "passkeys_privileged_apps_community.json"
+ private const val FILE_NAME_PRIVILEGED_APPS_GOOGLE = "passkeys_privileged_apps_google.json"
}
\ No newline at end of file
diff --git a/app/src/main/java/com/kunzisoft/keepass/hardware/HardwareKeyActivity.kt b/app/src/main/java/com/kunzisoft/keepass/hardware/HardwareKeyActivity.kt
index 77d802025..cd746d88c 100644
--- a/app/src/main/java/com/kunzisoft/keepass/hardware/HardwareKeyActivity.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/hardware/HardwareKeyActivity.kt
@@ -14,7 +14,7 @@ import androidx.appcompat.app.AlertDialog
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.legacy.DatabaseModeActivity
import com.kunzisoft.keepass.database.ContextualDatabase
-import com.kunzisoft.keepass.utils.UriUtil.openExternalApp
+import com.kunzisoft.keepass.utils.AppUtil.openExternalApp
/**
* Special activity to deal with hardware key drivers,
diff --git a/app/src/main/java/com/kunzisoft/keepass/hardware/HardwareKeyResponseHelper.kt b/app/src/main/java/com/kunzisoft/keepass/hardware/HardwareKeyResponseHelper.kt
deleted file mode 100644
index 5f00e2138..000000000
--- a/app/src/main/java/com/kunzisoft/keepass/hardware/HardwareKeyResponseHelper.kt
+++ /dev/null
@@ -1,144 +0,0 @@
-package com.kunzisoft.keepass.hardware
-
-import android.app.Activity
-import android.content.Intent
-import android.os.Bundle
-import android.util.Log
-import androidx.activity.result.ActivityResult
-import androidx.activity.result.ActivityResultCallback
-import androidx.activity.result.ActivityResultLauncher
-import androidx.activity.result.contract.ActivityResultContracts
-import androidx.appcompat.app.AlertDialog
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.FragmentActivity
-import androidx.lifecycle.lifecycleScope
-import com.kunzisoft.keepass.R
-import com.kunzisoft.keepass.utils.UriUtil.openExternalApp
-import kotlinx.coroutines.launch
-
-class HardwareKeyResponseHelper {
-
- private var activity: FragmentActivity? = null
- private var fragment: Fragment? = null
-
- private var getChallengeResponseResultLauncher: ActivityResultLauncher? = null
-
- constructor(context: FragmentActivity) {
- this.activity = context
- this.fragment = null
- }
-
- constructor(context: Fragment) {
- this.activity = context.activity
- this.fragment = context
- }
-
- fun buildHardwareKeyResponse(onChallengeResponded: (challengeResponse: ByteArray?,
- extra: Bundle?) -> Unit) {
- val resultCallback = ActivityResultCallback { result ->
- if (result.resultCode == Activity.RESULT_OK) {
- val challengeResponse: ByteArray? = result.data?.getByteArrayExtra(HARDWARE_KEY_RESPONSE_KEY)
- Log.d(TAG, "Response form challenge")
- onChallengeResponded.invoke(challengeResponse,
- result.data?.getBundleExtra(EXTRA_BUNDLE_KEY))
- } else {
- Log.e(TAG, "Response from challenge error")
- onChallengeResponded.invoke(null,
- result.data?.getBundleExtra(EXTRA_BUNDLE_KEY))
- }
- }
-
- getChallengeResponseResultLauncher = if (fragment != null) {
- fragment?.registerForActivityResult(
- ActivityResultContracts.StartActivityForResult(),
- resultCallback
- )
- } else {
- activity?.registerForActivityResult(
- ActivityResultContracts.StartActivityForResult(),
- resultCallback
- )
- }
- }
-
- fun launchChallengeForResponse(hardwareKey: HardwareKey, seed: ByteArray?) {
- when (hardwareKey) {
- /*
- HardwareKey.FIDO2_SECRET -> {
- // TODO FIDO2 under development
- throw Exception("FIDO2 not implemented")
- }
- */
- HardwareKey.CHALLENGE_RESPONSE_YUBIKEY -> {
- // Transform the seed before sending
- var challenge: ByteArray? = null
- if (seed != null) {
- challenge = ByteArray(64)
- seed.copyInto(challenge, 0, 0, 32)
- challenge.fill(32, 32, 64)
- }
- // Send to the driver
- getChallengeResponseResultLauncher!!.launch(
- Intent(YUBIKEY_CHALLENGE_RESPONSE_INTENT).apply {
- putExtra(HARDWARE_KEY_CHALLENGE_KEY, challenge)
- }
- )
- Log.d(TAG, "Challenge sent")
- }
- }
- }
-
- companion object {
- private val TAG = HardwareKeyResponseHelper::class.java.simpleName
-
- private const val YUBIKEY_CHALLENGE_RESPONSE_INTENT = "android.yubikey.intent.action.CHALLENGE_RESPONSE"
- private const val HARDWARE_KEY_CHALLENGE_KEY = "challenge"
- private const val HARDWARE_KEY_RESPONSE_KEY = "response"
- private const val EXTRA_BUNDLE_KEY = "EXTRA_BUNDLE_KEY"
-
- fun isHardwareKeyAvailable(
- activity: FragmentActivity,
- hardwareKey: HardwareKey,
- showDialog: Boolean = true
- ): Boolean {
- return when (hardwareKey) {
- /*
- HardwareKey.FIDO2_SECRET -> {
- // TODO FIDO2 under development
- if (showDialog)
- UnderDevelopmentFeatureDialogFragment()
- .show(activity.supportFragmentManager, "underDevFeatureDialog")
- false
- }
- */
- HardwareKey.CHALLENGE_RESPONSE_YUBIKEY -> {
- // Check available intent
- val yubikeyDriverAvailable =
- Intent(YUBIKEY_CHALLENGE_RESPONSE_INTENT)
- .resolveActivity(activity.packageManager) != null
- if (showDialog && !yubikeyDriverAvailable)
- showHardwareKeyDriverNeeded(activity, hardwareKey)
- yubikeyDriverAvailable
- }
- }
- }
-
- private fun showHardwareKeyDriverNeeded(
- activity: FragmentActivity,
- hardwareKey: HardwareKey
- ) {
- activity.lifecycleScope.launch {
- val builder = AlertDialog.Builder(activity)
- builder
- .setMessage(
- activity.getString(R.string.error_driver_required, hardwareKey.toString())
- )
- .setPositiveButton(R.string.download) { _, _ ->
- activity.openExternalApp(activity.getString(R.string.key_driver_app_id))
- }
- .setNegativeButton(android.R.string.cancel) { _, _ -> }
- builder.create().show()
- }
- }
- }
-}
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 e22a6d042..e12b9c2e3 100644
--- a/app/src/main/java/com/kunzisoft/keepass/settings/NestedAppSettingsFragment.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/settings/NestedAppSettingsFragment.kt
@@ -21,7 +21,6 @@ package com.kunzisoft.keepass.settings
import android.content.ActivityNotFoundException
import android.content.Intent
-import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Settings
@@ -30,6 +29,7 @@ import android.view.autofill.AutofillManager
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AlertDialog
+import androidx.core.net.toUri
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentActivity
import androidx.preference.ListPreference
@@ -47,7 +47,7 @@ import com.kunzisoft.keepass.icons.IconPackChooser
import com.kunzisoft.keepass.services.ClipboardEntryNotificationService
import com.kunzisoft.keepass.settings.preference.IconPackListPreference
import com.kunzisoft.keepass.settings.preferencedialogfragment.DurationDialogFragmentCompat
-import com.kunzisoft.keepass.utils.UriUtil.isContributingUser
+import com.kunzisoft.keepass.utils.AppUtil.isContributingUser
import com.kunzisoft.keepass.utils.UriUtil.openUrl
import com.kunzisoft.keepass.utils.UriUtil.releaseAllUnnecessaryPermissionUris
@@ -119,7 +119,7 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
activity?.let { activity ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- val autoFillEnablePreference: TwoStatePreference? = findPreference(getString(R.string.settings_autofill_enable_key))
+ val autoFillEnablePreference: TwoStatePreference? = findPreference(getString(R.string.settings_credential_provider_enable_key))
activity.getSystemService(AutofillManager::class.java)?.let { autofillManager ->
if (autofillManager.hasEnabledAutofillServices())
autoFillEnablePreference?.isChecked = autofillManager.hasEnabledAutofillServices()
@@ -161,7 +161,7 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
val intent =
Intent(Settings.ACTION_REQUEST_SET_AUTOFILL_SERVICE)
intent.data =
- Uri.parse("package:com.kunzisoft.keepass.autofill.KeeAutofillService")
+ "package:com.kunzisoft.keepass.autofill.KeeAutofillService".toUri()
Log.d(javaClass.name, "Autofill enable service: intent=$intent")
startActivity(intent)
} else {
@@ -171,7 +171,7 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
}
}
} else {
- findPreference(getString(R.string.autofill_key))?.isVisible = false
+ findPreference(getString(R.string.credential_provider_key))?.isVisible = false
}
}
@@ -202,6 +202,11 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
false
}
+ findPreference(getString(R.string.settings_passkeys_key))?.setOnPreferenceClickListener {
+ startActivity(Intent(context, PasskeysSettingsActivity::class.java))
+ false
+ }
+
findPreference(getString(R.string.clipboard_notifications_key))?.setOnPreferenceChangeListener { _, newValue ->
if (!(newValue as Boolean)) {
ClipboardEntryNotificationService.removeNotification(context)
@@ -530,7 +535,7 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
super.onResume()
activity?.let { activity ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- findPreference(getString(R.string.settings_autofill_enable_key))?.let { autoFillEnablePreference ->
+ findPreference(getString(R.string.settings_credential_provider_enable_key))?.let { autoFillEnablePreference ->
val autofillManager = activity.getSystemService(AutofillManager::class.java)
autoFillEnablePreference.isChecked = autofillManager != null
&& autofillManager.hasEnabledAutofillServices()
diff --git a/app/src/main/java/com/kunzisoft/keepass/settings/PasskeysSettingsActivity.kt b/app/src/main/java/com/kunzisoft/keepass/settings/PasskeysSettingsActivity.kt
new file mode 100644
index 000000000..e7e05bfa1
--- /dev/null
+++ b/app/src/main/java/com/kunzisoft/keepass/settings/PasskeysSettingsActivity.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2025 Jeremy Jamet / Kunzisoft.
+ *
+ * This file is part of KeePassDX.
+ *
+ * KeePassDX is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * KeePassDX is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with KeePassDX. If not, see .
+ *
+ */
+package com.kunzisoft.keepass.settings
+
+import androidx.preference.PreferenceFragmentCompat
+import com.kunzisoft.keepass.R
+
+class PasskeysSettingsActivity : ExternalSettingsActivity() {
+
+ override fun retrieveTitle(): Int {
+ return R.string.passkeys_preference_title
+ }
+
+ override fun retrievePreferenceFragment(): PreferenceFragmentCompat {
+ return PasskeysSettingsFragment()
+ }
+}
diff --git a/app/src/main/java/com/kunzisoft/keepass/settings/PasskeysSettingsFragment.kt b/app/src/main/java/com/kunzisoft/keepass/settings/PasskeysSettingsFragment.kt
new file mode 100644
index 000000000..7c0dd89b2
--- /dev/null
+++ b/app/src/main/java/com/kunzisoft/keepass/settings/PasskeysSettingsFragment.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2025 Jeremy Jamet / Kunzisoft.
+ *
+ * This file is part of KeePassDX.
+ *
+ * KeePassDX is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * KeePassDX is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with KeePassDX. If not, see .
+ *
+ */
+package com.kunzisoft.keepass.settings
+
+import android.os.Build
+import android.os.Bundle
+import androidx.fragment.app.DialogFragment
+import androidx.preference.Preference
+import androidx.preference.PreferenceFragmentCompat
+import com.kunzisoft.keepass.R
+import com.kunzisoft.keepass.settings.preferencedialogfragment.PasskeysPrivilegedAppsPreferenceDialogFragmentCompat
+
+class PasskeysSettingsFragment : PreferenceFragmentCompat() {
+
+ override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
+ // Load the preferences from an XML resource
+ setPreferencesFromResource(R.xml.preferences_passkeys, rootKey)
+ }
+
+ override fun onDisplayPreferenceDialog(preference: Preference) {
+ var otherDialogFragment = false
+
+ var dialogFragment: DialogFragment? = null
+
+ when (preference.key) {
+ getString(R.string.passkeys_privileged_apps_key) -> {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+ dialogFragment = PasskeysPrivilegedAppsPreferenceDialogFragmentCompat.newInstance(preference.key)
+ }
+ }
+ else -> otherDialogFragment = true
+ }
+
+ if (dialogFragment != null) {
+ dialogFragment.setTargetFragment(this, 0)
+ dialogFragment.show(parentFragmentManager, TAG_PASSKEYS_PREF_FRAGMENT)
+ } else if (otherDialogFragment) {
+ super.onDisplayPreferenceDialog(preference)
+ }
+ }
+
+ companion object {
+
+ private const val TAG_PASSKEYS_PREF_FRAGMENT = "TAG_PASSKEYS_PREF_FRAGMENT"
+ }
+}
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 9bc6ae1c6..e88e7e069 100644
--- a/app/src/main/java/com/kunzisoft/keepass/settings/PreferencesUtil.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/settings/PreferencesUtil.kt
@@ -35,8 +35,8 @@ import com.kunzisoft.keepass.database.search.SearchParameters
import com.kunzisoft.keepass.education.Education
import com.kunzisoft.keepass.password.PassphraseGenerator
import com.kunzisoft.keepass.timeout.TimeoutHelper
+import com.kunzisoft.keepass.utils.AppUtil.isContributingUser
import com.kunzisoft.keepass.utils.KeyboardUtil.isKeyboardActivatedInSettings
-import com.kunzisoft.keepass.utils.UriUtil.isContributingUser
import java.util.Properties
object PreferencesUtil {
@@ -821,7 +821,7 @@ object PreferencesUtil {
context.getString(R.string.clipboard_notifications_key) -> editor.putBoolean(name, value.toBoolean())
context.getString(R.string.clear_clipboard_notification_key) -> editor.putBoolean(name, value.toBoolean())
context.getString(R.string.clipboard_timeout_key) -> editor.putString(name, value.toLong().toString())
- context.getString(R.string.settings_autofill_enable_key) -> editor.putBoolean(name, value.toBoolean())
+ context.getString(R.string.settings_credential_provider_enable_key) -> editor.putBoolean(name, value.toBoolean())
context.getString(R.string.keyboard_notification_entry_key) -> editor.putBoolean(name, value.toBoolean())
context.getString(R.string.keyboard_notification_entry_clear_close_key) -> editor.putBoolean(name, value.toBoolean())
context.getString(R.string.keyboard_entry_timeout_key) -> editor.putString(name, value.toLong().toString())
diff --git a/app/src/main/java/com/kunzisoft/keepass/settings/preferencedialogfragment/PasskeysPrivilegedAppsPreferenceDialogFragmentCompat.kt b/app/src/main/java/com/kunzisoft/keepass/settings/preferencedialogfragment/PasskeysPrivilegedAppsPreferenceDialogFragmentCompat.kt
new file mode 100644
index 000000000..f331580a0
--- /dev/null
+++ b/app/src/main/java/com/kunzisoft/keepass/settings/preferencedialogfragment/PasskeysPrivilegedAppsPreferenceDialogFragmentCompat.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2025 Jeremy Jamet / Kunzisoft.
+ *
+ * This file is part of KeePassDX.
+ *
+ * KeePassDX is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * KeePassDX is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with KeePassDX. If not, see .
+ *
+ */
+package com.kunzisoft.keepass.settings.preferencedialogfragment
+
+import android.os.Build
+import android.os.Bundle
+import android.view.View
+import androidx.annotation.RequiresApi
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.kunzisoft.keepass.R
+import com.kunzisoft.keepass.model.AndroidOrigin
+import com.kunzisoft.keepass.settings.preferencedialogfragment.adapter.ListSelectionItemAdapter
+import com.kunzisoft.keepass.utils.AppUtil.getInstalledBrowsersWithSignatures
+
+@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+class PasskeysPrivilegedAppsPreferenceDialogFragmentCompat
+ : InputPreferenceDialogFragmentCompat() {
+ private var mAdapter = ListSelectionItemAdapter()
+ private var mListBrowsers: List = mutableListOf()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ mListBrowsers = getInstalledBrowsersWithSignatures(requireContext())
+ // TODO filter with current privileged apps
+ }
+
+ override fun onBindDialogView(view: View) {
+ super.onBindDialogView(view)
+ view.findViewById(R.id.pref_dialog_list).apply {
+ layoutManager = LinearLayoutManager(context)
+ adapter = mAdapter.apply {
+ setItems(mListBrowsers)
+ }
+ }
+ }
+
+ override fun onDialogClosed(positiveResult: Boolean) {
+ if (positiveResult) {
+ // TODO Save selected item in JSON
+ mAdapter.selectedItem
+ }
+ }
+
+ companion object {
+
+ fun newInstance(key: String): PasskeysPrivilegedAppsPreferenceDialogFragmentCompat {
+ val fragment = PasskeysPrivilegedAppsPreferenceDialogFragmentCompat()
+ val bundle = Bundle(1)
+ bundle.putString(ARG_KEY, key)
+ fragment.arguments = bundle
+
+ return fragment
+ }
+ }
+}
diff --git a/app/src/main/java/com/kunzisoft/keepass/settings/preferencedialogfragment/adapter/ListSelectionItemAdapter.kt b/app/src/main/java/com/kunzisoft/keepass/settings/preferencedialogfragment/adapter/ListSelectionItemAdapter.kt
new file mode 100644
index 000000000..d691df561
--- /dev/null
+++ b/app/src/main/java/com/kunzisoft/keepass/settings/preferencedialogfragment/adapter/ListSelectionItemAdapter.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2025 Jeremy Jamet / Kunzisoft.
+ *
+ * This file is part of KeePassDX.
+ *
+ * KeePassDX is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * KeePassDX is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with KeePassDX. If not, see .
+ *
+ */
+package com.kunzisoft.keepass.settings.preferencedialogfragment.adapter
+
+import android.annotation.SuppressLint
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import com.kunzisoft.keepass.R
+
+class ListSelectionItemAdapter()
+ : RecyclerView.Adapter() {
+
+ private val itemList: MutableList = ArrayList()
+ var selectedItem: T? = null
+ private set
+
+ var itemSelectedCallback: ItemSelectedCallback? = null
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SelectionViewHolder {
+ return SelectionViewHolder(LayoutInflater.from(parent.context)
+ .inflate(R.layout.pref_dialog_list_item, parent, false))
+ }
+
+ @SuppressLint("SetTextI18n", "NotifyDataSetChanged")
+ override fun onBindViewHolder(holder: SelectionViewHolder, position: Int) {
+ val item = itemList[position]
+
+ holder.container.apply {
+ isSelected = item == selectedItem
+ }
+ holder.textView.apply {
+ text = item.toString()
+ setOnClickListener {
+ selectedItem = if (item == selectedItem) null else item
+ itemSelectedCallback?.onItemSelected(item)
+ notifyDataSetChanged()
+ }
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return itemList.size
+ }
+
+ fun setItems(items: List) {
+ this.itemList.clear()
+ this.itemList.addAll(items)
+ }
+
+ interface ItemSelectedCallback {
+ fun onItemSelected(item: T)
+ }
+
+ class SelectionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ var textView: TextView = itemView.findViewById(R.id.pref_dialog_list_text)
+ var container: ViewGroup = itemView.findViewById(R.id.pref_dialog_list_container)
+ }
+}
diff --git a/app/src/main/java/com/kunzisoft/keepass/utils/AppUtil.kt b/app/src/main/java/com/kunzisoft/keepass/utils/AppUtil.kt
new file mode 100644
index 000000000..138dacfba
--- /dev/null
+++ b/app/src/main/java/com/kunzisoft/keepass/utils/AppUtil.kt
@@ -0,0 +1,147 @@
+package com.kunzisoft.keepass.utils
+
+import android.content.Context
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.content.pm.ResolveInfo
+import android.os.Build
+import android.util.Log
+import androidx.annotation.RequiresApi
+import androidx.core.net.toUri
+import com.kunzisoft.encrypt.Signature.getApplicationFingerprints
+import com.kunzisoft.keepass.BuildConfig
+import com.kunzisoft.keepass.R
+import com.kunzisoft.keepass.education.Education
+import com.kunzisoft.keepass.model.AndroidOrigin
+import com.kunzisoft.keepass.model.SearchInfo
+import com.kunzisoft.keepass.settings.PreferencesUtil
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import mozilla.components.lib.publicsuffixlist.PublicSuffixList
+
+object AppUtil {
+
+ fun Context.isExternalAppInstalled(packageName: String, showError: Boolean = true): Boolean {
+ try {
+ this.applicationContext.packageManager.getPackageInfoCompat(
+ packageName,
+ PackageManager.GET_ACTIVITIES
+ )
+ Education.setEducationScreenReclickedPerformed(this)
+ return true
+ } catch (e: Exception) {
+ if (showError)
+ Log.e(AppUtil::class.simpleName, "App not accessible", e)
+ }
+ return false
+ }
+
+ fun Context.openExternalApp(packageName: String, sourcesURL: String? = null) {
+ var launchIntent: Intent? = null
+ try {
+ launchIntent = this.packageManager.getLaunchIntentForPackage(packageName)?.apply {
+ addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ }
+ } catch (ignored: Exception) { }
+ try {
+ if (launchIntent == null) {
+ this.startActivity(
+ Intent(Intent.ACTION_VIEW)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ .setData(
+ if (sourcesURL != null
+ && !BuildConfig.CLOSED_STORE
+ ) {
+ sourcesURL
+ } else {
+ this.getString(
+ if (BuildConfig.CLOSED_STORE)
+ R.string.play_store_url
+ else
+ R.string.f_droid_url,
+ packageName
+ )
+ }.toUri()
+ )
+ )
+ } else {
+ this.startActivity(launchIntent)
+ }
+ } catch (e: Exception) {
+ Log.e(AppUtil::class.simpleName, "App cannot be open", e)
+ }
+ }
+
+ fun Context.isContributingUser(): Boolean {
+ return (Education.isEducationScreenReclickedPerformed(this)
+ || isExternalAppInstalled(this.getString(R.string.keepro_app_id), false)
+ )
+ }
+
+ /**
+ * Get the concrete web domain AKA without sub domain if needed
+ */
+ fun getConcreteWebDomain(context: Context,
+ webDomain: String?,
+ concreteWebDomain: (String?) -> Unit) {
+ CoroutineScope(Dispatchers.Main).launch {
+ if (webDomain != null) {
+ // Warning, web domain can contains IP, don't crop in this case
+ if (PreferencesUtil.searchSubdomains(context)
+ || Regex(SearchInfo.WEB_IP_REGEX).matches(webDomain)) {
+ concreteWebDomain.invoke(webDomain)
+ } else {
+ val publicSuffixList = PublicSuffixList(context)
+ concreteWebDomain.invoke(publicSuffixList
+ .getPublicSuffixPlusOne(webDomain).await())
+ }
+ } else {
+ concreteWebDomain.invoke(null)
+ }
+ }
+ }
+
+ @RequiresApi(Build.VERSION_CODES.P)
+ fun getInstalledBrowsersWithSignatures(context: Context): List {
+ val packageManager = context.packageManager
+ val browserList = mutableListOf()
+
+ // Create a generic web intent
+ val intent = Intent(Intent.ACTION_VIEW)
+ intent.data = "http://www.example.com".toUri() // Dummy URL
+
+ // Query for apps that can handle this intent
+ val resolveInfoList: List = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ packageManager.queryIntentActivities(
+ intent,
+ PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_ALL.toLong())
+ )
+ } else {
+ @Suppress("DEPRECATION")
+ packageManager.queryIntentActivities(intent, PackageManager.MATCH_ALL)
+ }
+
+ val processedPackageNames = mutableSetOf()
+
+ for (resolveInfo in resolveInfoList) {
+ val packageName = resolveInfo.activityInfo.packageName
+ if (packageName != null && !processedPackageNames.contains(packageName)) {
+ try {
+ val packageInfo = packageManager.getPackageInfo(
+ packageName,
+ PackageManager.GET_SIGNING_CERTIFICATES
+ )
+ val signatureFingerprints = packageInfo.signingInfo.getApplicationFingerprints()
+ signatureFingerprints?.let {
+ browserList.add(AndroidOrigin(packageName, signatureFingerprints))
+ processedPackageNames.add(packageName)
+ }
+ } catch (e: Exception) {
+ Log.e(AppUtil::class.simpleName, "Error processing package: $packageName", e)
+ }
+ }
+ }
+ return browserList.distinctBy { it.packageName } // Ensure uniqueness just in case
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/kunzisoft/keepass/utils/MenuUtil.kt b/app/src/main/java/com/kunzisoft/keepass/utils/MenuUtil.kt
index cf0cd289b..6df1c4561 100644
--- a/app/src/main/java/com/kunzisoft/keepass/utils/MenuUtil.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/utils/MenuUtil.kt
@@ -28,7 +28,7 @@ import android.view.MenuItem
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.AboutActivity
import com.kunzisoft.keepass.settings.SettingsActivity
-import com.kunzisoft.keepass.utils.UriUtil.isContributingUser
+import com.kunzisoft.keepass.utils.AppUtil.isContributingUser
import com.kunzisoft.keepass.utils.UriUtil.openUrl
object MenuUtil {
@@ -40,9 +40,6 @@ object MenuUtil {
menu.findItem(R.id.menu_contribute)?.isVisible = false
}
- /*
- * @param checkLock Check the time lock before launch settings in LockingActivity
- */
fun onDefaultMenuOptionsItemSelected(activity: Activity,
item: MenuItem,
timeoutEnable: Boolean = false) {
diff --git a/app/src/main/java/com/kunzisoft/keepass/utils/UriUtil.kt b/app/src/main/java/com/kunzisoft/keepass/utils/UriUtil.kt
index c53a29e7d..83a06d6ee 100644
--- a/app/src/main/java/com/kunzisoft/keepass/utils/UriUtil.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/utils/UriUtil.kt
@@ -200,64 +200,5 @@ object UriUtil {
this.openUrl(this.getString(resId))
}
- fun Context.isContributingUser(): Boolean {
- return (Education.isEducationScreenReclickedPerformed(this)
- || isExternalAppInstalled(this.getString(R.string.keepro_app_id), false)
- )
- }
-
- fun Context.isExternalAppInstalled(packageName: String, showError: Boolean = true): Boolean {
- try {
- this.applicationContext.packageManager.getPackageInfoCompat(
- packageName,
- PackageManager.GET_ACTIVITIES
- )
- Education.setEducationScreenReclickedPerformed(this)
- return true
- } catch (e: Exception) {
- if (showError)
- Log.e(TAG, "App not accessible", e)
- }
- return false
- }
-
- fun Context.openExternalApp(packageName: String, sourcesURL: String? = null) {
- var launchIntent: Intent? = null
- try {
- launchIntent = this.packageManager.getLaunchIntentForPackage(packageName)?.apply {
- addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- }
- } catch (ignored: Exception) { }
- try {
- if (launchIntent == null) {
- this.startActivity(
- Intent(Intent.ACTION_VIEW)
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- .setData(
- Uri.parse(
- if (sourcesURL != null
- && !BuildConfig.CLOSED_STORE
- ) {
- sourcesURL
- } else {
- this.getString(
- if (BuildConfig.CLOSED_STORE)
- R.string.play_store_url
- else
- R.string.f_droid_url,
- packageName
- )
- }
- )
- )
- )
- } else {
- this.startActivity(launchIntent)
- }
- } catch (e: Exception) {
- Log.e(TAG, "App cannot be open", e)
- }
- }
-
private const val TAG = "UriUtil"
}
diff --git a/app/src/main/java/com/kunzisoft/keepass/utils/WebDomain.kt b/app/src/main/java/com/kunzisoft/keepass/utils/WebDomain.kt
deleted file mode 100644
index 429405ee0..000000000
--- a/app/src/main/java/com/kunzisoft/keepass/utils/WebDomain.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.kunzisoft.keepass.utils
-
-import android.content.Context
-import com.kunzisoft.keepass.model.SearchInfo
-import com.kunzisoft.keepass.settings.PreferencesUtil
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import mozilla.components.lib.publicsuffixlist.PublicSuffixList
-
-object WebDomain {
-
- /**
- * Get the concrete web domain AKA without sub domain if needed
- */
- fun getConcreteWebDomain(context: Context,
- webDomain: String?,
- concreteWebDomain: (String?) -> Unit) {
- CoroutineScope(Dispatchers.Main).launch {
- if (webDomain != null) {
- // Warning, web domain can contains IP, don't crop in this case
- if (PreferencesUtil.searchSubdomains(context)
- || Regex(SearchInfo.WEB_IP_REGEX).matches(webDomain)) {
- concreteWebDomain.invoke(webDomain)
- } else {
- val publicSuffixList = PublicSuffixList(context)
- concreteWebDomain.invoke(publicSuffixList
- .getPublicSuffixPlusOne(webDomain).await())
- }
- } else {
- concreteWebDomain.invoke(null)
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/kunzisoft/keepass/view/TextFieldView.kt b/app/src/main/java/com/kunzisoft/keepass/view/TextFieldView.kt
index fb53a360a..89f45b5d4 100644
--- a/app/src/main/java/com/kunzisoft/keepass/view/TextFieldView.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/view/TextFieldView.kt
@@ -20,7 +20,6 @@
package com.kunzisoft.keepass.view
import android.content.Context
-import android.os.Build
import android.text.InputFilter
import android.text.util.Linkify
import android.util.AttributeSet
@@ -37,7 +36,7 @@ import androidx.core.view.ViewCompat
import androidx.core.view.isVisible
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.model.AppOriginEntryField.APPLICATION_ID_FIELD_NAME
-import com.kunzisoft.keepass.utils.UriUtil.openExternalApp
+import com.kunzisoft.keepass.utils.AppUtil.openExternalApp
open class TextFieldView @JvmOverloads constructor(context: Context,
diff --git a/app/src/main/res/layout/pref_dialog_list_item.xml b/app/src/main/res/layout/pref_dialog_list_item.xml
new file mode 100644
index 000000000..9c985da2c
--- /dev/null
+++ b/app/src/main/res/layout/pref_dialog_list_item.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index 494875b23..ae794372f 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -167,7 +167,7 @@
عام
الملء التلقائي
سجل باستخدام KeePassDX
- تعيين خدمة الملأ التلقائي الافتراضية
+ تعيين خدمة الملأ التلقائي الافتراضية
حجم كلمة السر المولدة
تعيين الحجم الافتراضي لكلمات السر المولدة
محارف كلمة السر
diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml
index 6ee009306..54954133a 100644
--- a/app/src/main/res/values-az/strings.xml
+++ b/app/src/main/res/values-az/strings.xml
@@ -518,7 +518,7 @@
Cihaz kilid açma istəyini başlatmaq mümkün deyil.
Digər tətbiqlərdə formları (anket) daha sürətli doldurmaq üçün avtomatik doldurma funksiyasını aktiv edin
Şifrə seç .…
- Standart avtomatik doldurma xidmətini təyin edin
+ Standart avtomatik doldurma xidmətini təyin edin
Avtomatik doldurmanın parametrləri
Yaradılan şifrə həcmi
Yaradılan şifrələrin standart həcmini təyin edər
diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml
index 2091a718a..c05eb24f5 100644
--- a/app/src/main/res/values-bg/strings.xml
+++ b/app/src/main/res/values-bg/strings.xml
@@ -288,7 +288,7 @@
Само за четене
Хранилището съдържа повтарящ се идентификатор.
Биометричен ключ
- Задаване на подразбирана услуга за автоматично попълване
+ Задаване на подразбирана услуга за автоматично попълване
Дължина на създаваните пароли
Заключване при „Назад“
Съдържание
diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml
index 3a9c202d5..6d02fdb10 100644
--- a/app/src/main/res/values-ca/strings.xml
+++ b/app/src/main/res/values-ca/strings.xml
@@ -410,7 +410,7 @@
Esperant la resposta de desafiament…
Nom del banc
Wi-Fi
- Estableix el servei d\'emplenament automàtic predeterminat
+ Estableix el servei d\'emplenament automàtic predeterminat
Compressió
Targeta d\'identificació
Clau física no suportada.
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index bf764789e..5d391ddb4 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -181,7 +181,7 @@
Samovyplnění
KeePassDX samovyplnění formulářů
Přihlásit se s KeePassDX
- Nastavit výchozí službu samovyplnění
+ Nastavit výchozí službu samovyplnění
Zapnout samovyplnění formulářů za účelem rychlého vyplnění v ostatních aplikacích
Délka generovaného hesla
Nastavení výchozí délky generovaných hesel
diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml
index 64fbac849..a75170aaf 100644
--- a/app/src/main/res/values-da/strings.xml
+++ b/app/src/main/res/values-da/strings.xml
@@ -180,7 +180,7 @@
Autoudfyld
KeePassDX formularudfyldning
Log ind med KeePassDX
- Indstil standard autoudfyldningstjeneste
+ Indstil standard autoudfyldningstjeneste
Aktiver autofyldning for hurtigt at udfylde formularer i andre apps
Genereret adgangskodelængde
Angiver standardlængden for genererede adgangskoder
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index b98393928..706244c77 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -197,7 +197,7 @@
Automatisches Ausfüllen
KeePassDX Auto-Formularausfüllung
Mit KeePassDX anmelden
- Standard-Autofill-Service festlegen
+ Standard-Autofill-Service festlegen
Automatisches Ausfüllen aktivieren, um Formulare in anderen Apps schnell auszufüllen
Eintrag auswählen …
Zwischenablage
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index f585bfe61..adc838d22 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -169,7 +169,7 @@
Αυτόματη συμπλήρωση
Μορφή KeePassDX αυτόματης συμπλήρωσης
Συνδεθείτε με το KeePassDX
- Ορίστε την προεπιλεγμένη υπηρεσία αυτόματης συμπλήρωσης
+ Ορίστε την προεπιλεγμένη υπηρεσία αυτόματης συμπλήρωσης
Παραγόμενο μέγεθος κωδικού πρόσβασης
Ορίστε το προεπιλεγμένο μέγεθος των παραγόμενων κωδικών πρόσβασης
Χαρακτήρες Κωδικού Πρόσβασης
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 992ccb923..dd351eb32 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -172,7 +172,7 @@
Autocompletado
Autocompletado de formularios de KeePassDX
Iniciar sesión con KeePassDX
- Establecer servicio de autocompletado por defecto
+ Establecer servicio de autocompletado por defecto
Tamaño de la contraseña generada
Establece el tamaño predeterminado de las contraseñas generadas
Caracteres de contraseña
diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml
index bc89cded7..56a97585a 100644
--- a/app/src/main/res/values-et/strings.xml
+++ b/app/src/main/res/values-et/strings.xml
@@ -474,7 +474,7 @@
KeePassDXi automaattäite teenus
Täitmaks andmevorme teistes rakenduses, luba automaattäite teenus
Vali kirje…
- Vali vaikimisi kasutatav automaattäite teenus
+ Vali vaikimisi kasutatav automaattäite teenus
Automaattäite teenuse seadistused
Andmebaas on avatud
Lõikelaud
diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml
index 2cad4c545..1b55116ff 100644
--- a/app/src/main/res/values-eu/strings.xml
+++ b/app/src/main/res/values-eu/strings.xml
@@ -575,7 +575,7 @@
Fitxategirako atzipena baliogabetu du fitxategi kudeatzaileak, itxi datu-basea eta berriro ireki ezazu bere lokalizaziotik.
Gailuaren desblokeorako esteka
Ezin izan da hasieratu gailuaren desblokeatze menua.
- Lehenetsi betetze automatiko zerbitzua
+ Lehenetsi betetze automatiko zerbitzua
Edukia
Datu-basearen desblokeatze automatikoa
Pantaila-argazki modua
diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml
index 5d3ebf87a..9e6177ce9 100644
--- a/app/src/main/res/values-fi/strings.xml
+++ b/app/src/main/res/values-fi/strings.xml
@@ -237,7 +237,7 @@
Pääavain muunnetaan käyttäen satunnaista suolattua avaimen johtamisfunktiota, jotta salausalgoritmin avain voidaan generoida.
Salasanatietokannan salausalgoritmi, jota käytetään kaikelle datalle.
Generoidun salasanan pituus
- Aseta oletus automaattiselle täytölle
+ Aseta oletus automaattiselle täytölle
Kirjaudu sisään KeePassDX:llä
KeePassDX:n automaattinen täyttö
Automaattinen täyttö
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 4d0aefe9c..1ba157de4 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -165,7 +165,7 @@
Remplissage automatique
Remplissage automatique des formulaires KeePassDX
Se connecter avec KeePassDX
- Définir le service de remplissage automatique par défaut
+ Définir le service de remplissage automatique par défaut
Activer le remplissage automatique pour remplir rapidement des formulaires dans d’autres applications
Sélectionner une entrée…
Taille du mot de passe généré
diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml
index 9802a2569..050b5958c 100644
--- a/app/src/main/res/values-gl/strings.xml
+++ b/app/src/main/res/values-gl/strings.xml
@@ -373,7 +373,7 @@
Biométrico
Habilite o servizo para autocompletar rapidamente os formularios de outras aplicacións
Notificacións do portapapeis
- Estabelecer o servizo de autocompletado predefinido
+ Estabelecer o servizo de autocompletado predefinido
Bloquear a base de datos cando o usuario faga click no botón de volver á pantalla principal
Mostrar botón de bloqueo
Mostrar notificacións do portapapeis ao visualizar unha entrada
diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml
index 5d537d245..375310bc0 100644
--- a/app/src/main/res/values-hr/strings.xml
+++ b/app/src/main/res/values-hr/strings.xml
@@ -178,7 +178,7 @@
Opće
Automatsko ispunjavanje
Automatsko ispunjavanje KeePassDX obrasca
- Postavi standardnu uslugu automatskog ispunjavanja
+ Postavi standardnu uslugu automatskog ispunjavanja
Znakovi lozinke
Postavi dozvoljene znakove za generiranje lozinke
Baza podataka otvorena
diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml
index d51d2a978..d18ff373f 100644
--- a/app/src/main/res/values-hu/strings.xml
+++ b/app/src/main/res/values-hu/strings.xml
@@ -185,7 +185,7 @@
Automatikus kitöltés
KeePassDX űrlapkitöltés
Bejelentkezés a KeePassDX-szel
- Alapértelmezett automatikus kitöltési szolgáltatás beállítása
+ Alapértelmezett automatikus kitöltési szolgáltatás beállítása
Automatikus kitöltés engedélyezése az űrlapok gyors kitöltéséhez más alkalmazásokban
Előállított jelszó mérete
Beállítja az előállított jelszavak alapértelmezett méretét
diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml
index e4f226d30..009d79cda 100644
--- a/app/src/main/res/values-in/strings.xml
+++ b/app/src/main/res/values-in/strings.xml
@@ -423,7 +423,7 @@
Ketik kata sandi, lalu klik tombol ini.
Isi formulir KeePassDX otomatis
Pengaturan isi otomatis
- Setel layanan isi otomatis secara default
+ Setel layanan isi otomatis secara default
Aktifkan pengisian otomatis untuk mengisi formulir dengan cepat di aplikasi lain
Masuk dengan KeePassDX
Isi otomatis
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 37ef2ad12..c1c474aa6 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -180,7 +180,7 @@
Autocompletamento
Autocompletamento di KeePassDX
Accedi con KeePassDX
- Servizio predefinito di autocompletamento
+ Servizio predefinito di autocompletamento
Attiva l\'autocompletamento per riempire velocemente i campi in altre app
Dimensione password generata
Imposta la dimensione predefinita delle password generate
diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml
index aef987119..b25c54740 100644
--- a/app/src/main/res/values-iw/strings.xml
+++ b/app/src/main/res/values-iw/strings.xml
@@ -414,7 +414,7 @@
התחבר עם KeePassDX
כללי
הפעל מילוי אוטומטי כדי למלא במהירות טפסים ביישומים אחרים
- הגדר שירות מילוי אוטומטי ברירת מחדל
+ הגדר שירות מילוי אוטומטי ברירת מחדל
גודל סיסמה שנוצרה
מגדיר גודל ברירת המחדל של הסיסמאות שנוצרו
תווי סיסמה
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index 768ea7262..7dc4018e6 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -276,7 +276,7 @@
KeePassDX フォーム自動入力
KeePassDX でログイン
自動入力を有効にして、他のアプリ内のフォームにすばやく入力します
- デフォルトの自動入力サービスに設定
+ デフォルトの自動入力サービスに設定
自動入力の設定
生成されるパスワードの長さ
生成されるパスワードの長さのデフォルト値を設定します
diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml
index 37e4720d3..7c2afffce 100644
--- a/app/src/main/res/values-ko/strings.xml
+++ b/app/src/main/res/values-ko/strings.xml
@@ -385,7 +385,7 @@
KeePassDX로 로그인
생성된 비밀번호 크기
자동 완성 설정
- 기본 자동완성 서비스 설정
+ 기본 자동완성 서비스 설정
화면 꺼짐 시 잠금
기기 잠금 방식을 사용하여 데이터베이스를 더 쉽게 여세요
생체 인식 잠금 해제
diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml
index 7ca277d4b..d4463caa8 100644
--- a/app/src/main/res/values-lt/strings.xml
+++ b/app/src/main/res/values-lt/strings.xml
@@ -361,7 +361,7 @@
Failo \"hash\" reikšmė nėra garantuota, nes \"Android\" gali keisti jo duomenis. Norėdami užtikrinti teisingą vientisumą, pakeiskite failo plėtinį į .bin.
Biometriniai duomenys ar prietaiso įgaliojimai neįrašomi.
Automatinio pildymo nustatymai
- Nustatyti numatytąją automatinio pildymo paslaugą
+ Nustatyti numatytąją automatinio pildymo paslaugą
Ekrano užraktas
Biometrinis atrakinimas
Rodyti UUID
diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml
index 1a4cb99ac..2b5dddeb3 100644
--- a/app/src/main/res/values-ml/strings.xml
+++ b/app/src/main/res/values-ml/strings.xml
@@ -339,7 +339,7 @@
നിങ്ങളുടെ ഉപകരണത്തിന്റെ ക്ലിപ്പ്ബോർഡ് ഉപയോഗിച്ച് എൻട്രി ഫീൽഡുകൾ പകർത്തുക
പാസ്വേഡ് പ്രതീകങ്ങൾ
സൃഷ്ടിച്ച പാസ്വേഡുകളുടെ സ്ഥിരസ്ഥിതി വലുപ്പം സജ്ജമാക്കുക
- സ്ഥിരസ്ഥിതി ഓട്ടോഫിൽ സേവനം സജ്ജമാക്കുക
+ സ്ഥിരസ്ഥിതി ഓട്ടോഫിൽ സേവനം സജ്ജമാക്കുക
മറ്റ് അപ്ലിക്കേഷനുകളിൽ ഫോമുകൾ വേഗത്തിൽ പൂരിപ്പിക്കുന്നതിന് ഓട്ടോഫില്ലിംഗ് പ്രവർത്തനക്ഷമമാക്കുക
കീസ്റ്റോർ ശരിയായി സമാരംഭിച്ചിട്ടില്ല.
റീസൈക്കിൾ ബിൻ ചുവടെയുണ്ട്
diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml
index 24233be04..37b01496e 100644
--- a/app/src/main/res/values-nb/strings.xml
+++ b/app/src/main/res/values-nb/strings.xml
@@ -175,7 +175,7 @@
Autofyll
KeePassDX autofyll-tjeneste
Logg inn med KeePassDX
- Sett forvalgt autofyll-tjeneste
+ Sett forvalgt autofyll-tjeneste
Skru på tjenesten for å fylle ut skjema fra andre programmer
Passordsstørrelse
Sett forvalgt størrelse for generert passord
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index b4e7cbb1f..5763a2b7b 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -187,7 +187,7 @@
Automatisch aanvullen
KeePassDX dienst automatisch aanvullen
Inloggen met KeePassDX
- Dienst automatisch aanvullen
+ Dienst automatisch aanvullen
Schakel de dienst in om formulieren in andere apps in te vullen
Gegenereerde wachtwoordlengte
Stel de standaardlengte van gegenereerde wachtwoorden in
diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml
index 6a2079916..724314917 100644
--- a/app/src/main/res/values-pa/strings.xml
+++ b/app/src/main/res/values-pa/strings.xml
@@ -266,7 +266,7 @@
ਲਾਕ ਕਰਨ ਲਈ \'ਪਿੱਛੇ\' ਨੂੰ ਦਬਾਓ
ਜਦੋਂ ਸਕਰੀਨ ਬੰਦ ਹੋ ਜਾਵੇ ਤਾਂ ਡਾਟਾਬੇਸ ਨੂੰ ਲਾਕ ਕਰੋ
ਕਲਿੱਪਬੋਰਡ ਨੋਟੀਫਿਕੇਸ਼ਨ
- ਮੂਲ ਆਪੇ-ਭਰਨ ਸੇਵਾ ਵਜੋਂ ਸੈੱਟ ਕਰੋ
+ ਮੂਲ ਆਪੇ-ਭਰਨ ਸੇਵਾ ਵਜੋਂ ਸੈੱਟ ਕਰੋ
ਕੋਈ ਬਾਇਓਮੈਟਰਿਕ ਜਾਂ ਡਿਵਾਈਸ ਸਨਦ ਦਾਖਲ ਨਹੀਂ ਕੀਤੀ ਹੈ।
ਇਹ ਡਾਟਾ ਕਿਵੇਂ ਵੀ ਹਟਾਉਣਾ ਹੈ\?
ਕਿਵੇਂ ਵੀ ਫ਼ਾਇਲ ਜੋੜਨੀ ਹੈ\?
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 0764caae3..5e26487d6 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -182,7 +182,7 @@
Wypełnij automatycznie
Autouzupełnianie formularzy KeePassDX
Zaloguj się za pomocą KeePassDX
- Ustaw domyślną usługę autouzupełniania
+ Ustaw domyślną usługę autouzupełniania
Włącz autouzupełnianie, aby móc szybko wypełniać formularze w innych aplikacjach
Wygenerowany rozmiar hasła
Ustawia domyślny rozmiar wygenerowanych haseł
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 92d234c07..4880478dd 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -180,7 +180,7 @@
Preenchimento automático
Preenchimento automático do KeePassDX
Entre com o KeePassDX
- Definir serviço padrão de preenchimento automático
+ Definir serviço padrão de preenchimento automático
Habilite o serviço para rapidamente preencher formulários em outros aplicativos
Comprimento da senha gerada
Define o tamanho padrão para senhas geradas
diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml
index 11ebb1a23..ba2fcb56f 100644
--- a/app/src/main/res/values-pt-rPT/strings.xml
+++ b/app/src/main/res/values-pt-rPT/strings.xml
@@ -179,7 +179,7 @@
Preenchimento automático
Serviço de preenchimento automático do KeePassDX
Iniciar sessão com KeePassDX
- Definir como serviço de preenchimento automático predefinido
+ Definir como serviço de preenchimento automático predefinido
Ative o serviço de preencher automático para preencher formulários noutras aplicações
Tamanho da palavra-passe gerada
Editar entrada
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index 8016ca296..1e36fbc1d 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -91,7 +91,7 @@
Caracteres das palavras-passe
Define o tamanho predefinido para as palavras-passe geradas
Tamanho da palavra-passe gerada
- Definir como serviço de preenchimento automático predefinido
+ Definir como serviço de preenchimento automático predefinido
Iniciar sessão com KeePassDX
Serviço de preenchimento automático do KeePassDX
Preenchimento automático
diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml
index 623deb078..7b558df3c 100644
--- a/app/src/main/res/values-ro/strings.xml
+++ b/app/src/main/res/values-ro/strings.xml
@@ -240,7 +240,7 @@
Completarea automată cu KeePassDX
Conectați-vă cu KeePassDX
Activați completarea automată pentru a completa rapid formulare în alte aplicații
- Setați serviciul implicit de autocompletare
+ Setați serviciul implicit de autocompletare
Dimensiunea parolei generate
Setează dimensiunea implicită a parolelor generate
Caractere parolă
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 23b40a62f..18b1c019f 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -184,7 +184,7 @@
Служба автозаполнения KeePassDX
Войти с помощью KeePassDX
Включите службу для быстрого заполнения форм в других приложениях
- Использовать службу автозаполнения
+ Использовать службу автозаполнения
Длина создаваемого пароля
Настройка длины создаваемых паролей по умолчанию
Символы пароля
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index 4decad49c..2ad2c9e40 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -595,7 +595,7 @@
Vlastnosti
Vzhľad
Povoľte automatické dopĺňanie na rýchle vyplnenie formulárov v iných aplikáciách
- Nastavte predvolenú službu automatického dopĺňania
+ Nastavte predvolenú službu automatického dopĺňania
Nastavte povolené znaky generátora hesiel
Umožňuje vám skenovať biometrické údaje a otvoriť databázu
Maximálny počet
diff --git a/app/src/main/res/values-sq/strings.xml b/app/src/main/res/values-sq/strings.xml
index 6d56c71c0..0e38282f2 100644
--- a/app/src/main/res/values-sq/strings.xml
+++ b/app/src/main/res/values-sq/strings.xml
@@ -570,7 +570,7 @@
Përzgjidhni tema të çelëta ose të errëta
Paketë ikonash të përdorura te aplikacioni
Zërat e skaduar nuk shfaqen
- Caktoni shërbim parazgjedhje vetëplotësimesh
+ Caktoni shërbim parazgjedhje vetëplotësimesh
Aktivizoni vetëplotësimet, për të plotësuar shpejt formularë në aplikacione të tjerë
Rregullime vetëplotësimi
Cakton madhësinë parazgjedhje për fjalëkalimet e prodhuar
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
index 666254906..bf7358e52 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -189,7 +189,7 @@
Autofyll
KeePassDX autofyll formulär
Logga in med KeePassDX
- Välj standardtjänst för autofyll
+ Välj standardtjänst för autofyll
Längd på genererat lösenord
Anger standardlängden för de genererade lösenorden
Lösenordstecken
diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml
index 946f50536..8fab75106 100644
--- a/app/src/main/res/values-ta/strings.xml
+++ b/app/src/main/res/values-ta/strings.xml
@@ -73,7 +73,7 @@
பயோமெட்ரிக் பாதுகாப்பு புதுப்பிப்பு தேவை.
கீச்டோர் சரியாக துவக்கப்படவில்லை.
தோற்றம்
- இயல்புநிலை ஆட்டோஃபில் சேவையை அமைக்கவும்
+ இயல்புநிலை ஆட்டோஃபில் சேவையை அமைக்கவும்
ஆட்டோஃபில் அமைப்புகள்
திரை பூட்டு
உள்ளடக்கம்
diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml
index 9f2cdfbc8..fe3af812d 100644
--- a/app/src/main/res/values-th/strings.xml
+++ b/app/src/main/res/values-th/strings.xml
@@ -529,7 +529,7 @@
ประวัติ
เลือกไฟล์ที่จะนําเข้าการตั้งค่าของแอป
นำเข้าการตั้งค่าแอปแล้ว
- ตั่งค่าเป็นบริการกรอกข้อมูลอัตโนมัติเรื่มต้น
+ ตั่งค่าเป็นบริการกรอกข้อมูลอัตโนมัติเรื่มต้น
เกิดข้อผิดพลาดระหว่างการส่งออกการตั้งค่าของแอป
ลักษณะ
ไบโอเมตริก
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index 28b5aa6b8..a72ca8fa2 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -176,7 +176,7 @@
Otomatik Doldurma
KeePassDX formu otomatik doldurma
KeePassDX ile giriş yap
- Öntanımlı otomatik doldurma hizmetini ayarla
+ Öntanımlı otomatik doldurma hizmetini ayarla
Diğer uygulamalardaki formları hızlı doldurmak için otomatik doldurmayı etkinleştirin
Oluşturulan parola boyutu
Oluşturulan parolaların öntanımlı boyutunu ayarlar
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index 7e2dca9e4..cde78726a 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -394,7 +394,7 @@
Встановити типову довжину створюваних паролів
Довжина створюваного пароля
Налаштування автозаповнення
- Встановити типовою службою автозаповнення
+ Встановити типовою службою автозаповнення
Увімкнути автозаповнення для швидкого заповнення форм в інших застосунках
Увійти за допомогою KeePassDX
Автозаповнення форм KeePassDX
diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml
index 19f93744c..e02cfdb36 100644
--- a/app/src/main/res/values-vi/strings.xml
+++ b/app/src/main/res/values-vi/strings.xml
@@ -415,7 +415,7 @@
Đăng nhập bằng KeePassDX
Bật tính năng tự động điền để nhanh chóng điền vào biểu mẫu trong các ứng dụng khác
Chọn mục…
- Đặt dịch vụ tự động điền mặc định
+ Đặt dịch vụ tự động điền mặc định
Thiết đặt tự động điền
Kích thước mật khẩu đã tạo
Đặt kích thước mặc định của mật khẩu được tạo
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index d6d8858b9..f23dda7c1 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -206,7 +206,7 @@
构建 %1$s
加密密码已保存
不可用
- 设为默认自动填充服务
+ 设为默认自动填充服务
启用自动填充功能,以快速填写其他应用中的表单
密码生成长度
设置生成密码的默认长度
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 3ea1a9310..99116662b 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -501,7 +501,7 @@
選擇條目
複製%1$s到剪貼簿
選擇模式
- 設置為預設的填充服務
+ 設置為預設的填充服務
設定
下次強制更改主密鑰(一次)
下次強制更換
diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml
index f563e16ad..2581f11bf 100644
--- a/app/src/main/res/values/donottranslate.xml
+++ b/app/src/main/res/values/donottranslate.xml
@@ -126,11 +126,14 @@
false
clip_timeout_key
20000
- autofill_key
+ credential_provider_key
+ settings_credential_provider_enable_key
+ false
autofill_explanation_key
- settings_autofill_enable_key
- false
settings_autofill_key
+ passkeys_explanation_key
+ settings_passkeys_key
+ passkeys_privileged_apps_key
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 d52376bfc..4420503ab 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -417,12 +417,19 @@
Biometric
Device credential
General
+ Credential provider
+ Credential provider service
+ Passkeys
+ Configure Passkeys for fast and secure passwordless login
+ Passkeys settings
+ Privileged apps
+ Add a browser to the list of privileged apps
+ Select an app to add to the list of privileged apps
Autofill
KeePassDX form autofilling
Sign in with KeePassDX
- Enable autofilling to quickly fill out forms in other apps
+ Configure autofilling to quickly fill out forms in other apps
Select entry…
- Set default autofill service
Autofill settings
Generated password size
Sets default size of the generated passwords
diff --git a/app/src/main/res/xml/preferences_form_filling.xml b/app/src/main/res/xml/preferences_form_filling.xml
index ae166bd50..3510b0655 100644
--- a/app/src/main/res/xml/preferences_form_filling.xml
+++ b/app/src/main/res/xml/preferences_form_filling.xml
@@ -34,16 +34,23 @@
+ android:key="@string/credential_provider_key"
+ android:title="@string/credential_provider">
+
+
+
-
diff --git a/app/src/main/res/xml/preferences_passkeys.xml b/app/src/main/res/xml/preferences_passkeys.xml
new file mode 100644
index 000000000..397a4afb2
--- /dev/null
+++ b/app/src/main/res/xml/preferences_passkeys.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/database/src/main/java/com/kunzisoft/keepass/model/AppOrigin.kt b/database/src/main/java/com/kunzisoft/keepass/model/AppOrigin.kt
index d4d75f501..31208a90d 100644
--- a/database/src/main/java/com/kunzisoft/keepass/model/AppOrigin.kt
+++ b/database/src/main/java/com/kunzisoft/keepass/model/AppOrigin.kt
@@ -119,6 +119,10 @@ data class AndroidOrigin(
}
return "android:apk-key-hash:${fingerprintToUrlSafeBase64(fingerprint)}"
}
+
+ override fun toString(): String {
+ return "$packageName (${fingerprint})"
+ }
}
@Parcelize
@@ -134,6 +138,10 @@ data class WebOrigin(
return "${origin}/.well-known/assetlinks.json"
}
+ override fun toString(): String {
+ return origin
+ }
+
companion object {
const val RELYING_PARTY_DEFAULT_PROTOCOL = "https"
fun fromRelyingParty(relyingParty: String): WebOrigin = WebOrigin(