mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
feat: Custom settings and privileged
This commit is contained in:
@@ -159,20 +159,22 @@
|
|||||||
android:label="@string/about" />
|
android:label="@string/about" />
|
||||||
<activity
|
<activity
|
||||||
android:name="com.kunzisoft.keepass.settings.SettingsActivity" />
|
android:name="com.kunzisoft.keepass.settings.SettingsActivity" />
|
||||||
<activity
|
|
||||||
android:name="com.kunzisoft.keepass.credentialprovider.activity.AutofillLauncherActivity"
|
|
||||||
android:theme="@style/Theme.Transparent"
|
|
||||||
android:configChanges="keyboardHidden"
|
|
||||||
android:excludeFromRecents="true"/>
|
|
||||||
<activity
|
<activity
|
||||||
android:name="com.kunzisoft.keepass.settings.DeviceUnlockSettingsActivity" />
|
android:name="com.kunzisoft.keepass.settings.DeviceUnlockSettingsActivity" />
|
||||||
<activity
|
<activity
|
||||||
android:name="com.kunzisoft.keepass.settings.AutofillSettingsActivity" />
|
android:name="com.kunzisoft.keepass.settings.AutofillSettingsActivity" />
|
||||||
|
<activity
|
||||||
|
android:name="com.kunzisoft.keepass.settings.PasskeysSettingsActivity" />
|
||||||
<activity
|
<activity
|
||||||
android:name="com.kunzisoft.keepass.settings.AppearanceSettingsActivity" />
|
android:name="com.kunzisoft.keepass.settings.AppearanceSettingsActivity" />
|
||||||
<activity
|
<activity
|
||||||
android:name="com.kunzisoft.keepass.hardware.HardwareKeyActivity"
|
android:name="com.kunzisoft.keepass.hardware.HardwareKeyActivity"
|
||||||
android:theme="@style/Theme.Transparent" />
|
android:theme="@style/Theme.Transparent" />
|
||||||
|
<activity
|
||||||
|
android:name="com.kunzisoft.keepass.credentialprovider.activity.AutofillLauncherActivity"
|
||||||
|
android:theme="@style/Theme.Transparent"
|
||||||
|
android:configChanges="keyboardHidden"
|
||||||
|
android:excludeFromRecents="true"/>
|
||||||
<activity
|
<activity
|
||||||
android:name="com.kunzisoft.keepass.credentialprovider.activity.EntrySelectionLauncherActivity"
|
android:name="com.kunzisoft.keepass.credentialprovider.activity.EntrySelectionLauncherActivity"
|
||||||
android:theme="@style/Theme.Transparent"
|
android:theme="@style/Theme.Transparent"
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
package com.kunzisoft.keepass.activities
|
package com.kunzisoft.keepass.activities
|
||||||
|
|
||||||
import android.content.pm.PackageManager.NameNotFoundException
|
import android.content.pm.PackageManager.NameNotFoundException
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.method.LinkMovementMethod
|
import android.text.method.LinkMovementMethod
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@@ -32,7 +31,7 @@ import androidx.core.text.HtmlCompat
|
|||||||
import com.kunzisoft.keepass.BuildConfig
|
import com.kunzisoft.keepass.BuildConfig
|
||||||
import com.kunzisoft.keepass.R
|
import com.kunzisoft.keepass.R
|
||||||
import com.kunzisoft.keepass.activities.stylish.StylishActivity
|
import com.kunzisoft.keepass.activities.stylish.StylishActivity
|
||||||
import com.kunzisoft.keepass.utils.UriUtil.isContributingUser
|
import com.kunzisoft.keepass.utils.AppUtil.isContributingUser
|
||||||
import com.kunzisoft.keepass.utils.getPackageInfoCompat
|
import com.kunzisoft.keepass.utils.getPackageInfoCompat
|
||||||
import org.joda.time.DateTime
|
import org.joda.time.DateTime
|
||||||
|
|
||||||
|
|||||||
@@ -44,14 +44,14 @@ import androidx.recyclerview.widget.SimpleItemAnimator
|
|||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import com.kunzisoft.keepass.R
|
import com.kunzisoft.keepass.R
|
||||||
import com.kunzisoft.keepass.activities.dialogs.SetMainCredentialDialogFragment
|
import com.kunzisoft.keepass.activities.dialogs.SetMainCredentialDialogFragment
|
||||||
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper
|
|
||||||
import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper
|
import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper
|
||||||
import com.kunzisoft.keepass.credentialprovider.SpecialMode
|
|
||||||
import com.kunzisoft.keepass.activities.helpers.setOpenDocumentClickListener
|
import com.kunzisoft.keepass.activities.helpers.setOpenDocumentClickListener
|
||||||
import com.kunzisoft.keepass.activities.legacy.DatabaseModeActivity
|
import com.kunzisoft.keepass.activities.legacy.DatabaseModeActivity
|
||||||
import com.kunzisoft.keepass.adapters.FileDatabaseHistoryAdapter
|
import com.kunzisoft.keepass.adapters.FileDatabaseHistoryAdapter
|
||||||
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
|
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
|
||||||
|
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper
|
||||||
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.buildActivityResultLauncher
|
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.buildActivityResultLauncher
|
||||||
|
import com.kunzisoft.keepass.credentialprovider.SpecialMode
|
||||||
import com.kunzisoft.keepass.credentialprovider.TypeMode
|
import com.kunzisoft.keepass.credentialprovider.TypeMode
|
||||||
import com.kunzisoft.keepass.credentialprovider.autofill.AutofillComponent
|
import com.kunzisoft.keepass.credentialprovider.autofill.AutofillComponent
|
||||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||||
@@ -66,10 +66,10 @@ import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.
|
|||||||
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.DATABASE_URI_KEY
|
import com.kunzisoft.keepass.services.DatabaseTaskNotificationService.Companion.DATABASE_URI_KEY
|
||||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||||
import com.kunzisoft.keepass.tasks.ActionRunnable
|
import com.kunzisoft.keepass.tasks.ActionRunnable
|
||||||
|
import com.kunzisoft.keepass.utils.AppUtil.isContributingUser
|
||||||
import com.kunzisoft.keepass.utils.DexUtil
|
import com.kunzisoft.keepass.utils.DexUtil
|
||||||
import com.kunzisoft.keepass.utils.MagikeyboardUtil
|
import com.kunzisoft.keepass.utils.MagikeyboardUtil
|
||||||
import com.kunzisoft.keepass.utils.MenuUtil
|
import com.kunzisoft.keepass.utils.MenuUtil
|
||||||
import com.kunzisoft.keepass.utils.UriUtil.isContributingUser
|
|
||||||
import com.kunzisoft.keepass.utils.UriUtil.openUrl
|
import com.kunzisoft.keepass.utils.UriUtil.openUrl
|
||||||
import com.kunzisoft.keepass.utils.getParcelableCompat
|
import com.kunzisoft.keepass.utils.getParcelableCompat
|
||||||
import com.kunzisoft.keepass.view.asError
|
import com.kunzisoft.keepass.view.asError
|
||||||
|
|||||||
@@ -29,7 +29,11 @@ import android.view.MotionEvent
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.inputmethod.EditorInfo
|
import android.view.inputmethod.EditorInfo
|
||||||
import android.widget.*
|
import android.widget.AdapterView
|
||||||
|
import android.widget.ArrayAdapter
|
||||||
|
import android.widget.EditText
|
||||||
|
import android.widget.Spinner
|
||||||
|
import android.widget.TextView
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import com.google.android.material.textfield.TextInputLayout
|
import com.google.android.material.textfield.TextInputLayout
|
||||||
import com.kunzisoft.keepass.R
|
import com.kunzisoft.keepass.R
|
||||||
@@ -40,15 +44,15 @@ import com.kunzisoft.keepass.otp.OtpElement.Companion.MAX_OTP_DIGITS
|
|||||||
import com.kunzisoft.keepass.otp.OtpElement.Companion.MAX_TOTP_PERIOD
|
import com.kunzisoft.keepass.otp.OtpElement.Companion.MAX_TOTP_PERIOD
|
||||||
import com.kunzisoft.keepass.otp.OtpElement.Companion.MIN_HOTP_COUNTER
|
import com.kunzisoft.keepass.otp.OtpElement.Companion.MIN_HOTP_COUNTER
|
||||||
import com.kunzisoft.keepass.otp.OtpElement.Companion.MIN_OTP_DIGITS
|
import com.kunzisoft.keepass.otp.OtpElement.Companion.MIN_OTP_DIGITS
|
||||||
import com.kunzisoft.keepass.otp.OtpElement.Companion.MIN_TOTP_PERIOD
|
|
||||||
import com.kunzisoft.keepass.otp.OtpElement.Companion.MIN_OTP_SECRET
|
import com.kunzisoft.keepass.otp.OtpElement.Companion.MIN_OTP_SECRET
|
||||||
|
import com.kunzisoft.keepass.otp.OtpElement.Companion.MIN_TOTP_PERIOD
|
||||||
import com.kunzisoft.keepass.otp.OtpTokenType
|
import com.kunzisoft.keepass.otp.OtpTokenType
|
||||||
import com.kunzisoft.keepass.otp.OtpType
|
import com.kunzisoft.keepass.otp.OtpType
|
||||||
import com.kunzisoft.keepass.otp.TokenCalculator
|
import com.kunzisoft.keepass.otp.TokenCalculator
|
||||||
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.openUrl
|
||||||
import com.kunzisoft.keepass.utils.getParcelableCompat
|
import com.kunzisoft.keepass.utils.getParcelableCompat
|
||||||
import java.util.*
|
import java.util.Locale
|
||||||
|
|
||||||
class SetOTPDialogFragment : DatabaseDialogFragment() {
|
class SetOTPDialogFragment : DatabaseDialogFragment() {
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ import com.kunzisoft.keepass.database.ContextualDatabase
|
|||||||
import com.kunzisoft.keepass.database.helper.SearchHelper
|
import com.kunzisoft.keepass.database.helper.SearchHelper
|
||||||
import com.kunzisoft.keepass.model.RegisterInfo
|
import com.kunzisoft.keepass.model.RegisterInfo
|
||||||
import com.kunzisoft.keepass.model.SearchInfo
|
import com.kunzisoft.keepass.model.SearchInfo
|
||||||
import com.kunzisoft.keepass.utils.WebDomain
|
import com.kunzisoft.keepass.utils.AppUtil
|
||||||
import com.kunzisoft.keepass.utils.getParcelableCompat
|
import com.kunzisoft.keepass.utils.getParcelableCompat
|
||||||
import com.kunzisoft.keepass.utils.getParcelableExtraCompat
|
import com.kunzisoft.keepass.utils.getParcelableExtraCompat
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ class AutofillLauncherActivity : DatabaseModeActivity() {
|
|||||||
}
|
}
|
||||||
// Build search param
|
// Build search param
|
||||||
bundle.getParcelableCompat<SearchInfo>(KEY_SEARCH_INFO)?.let { searchInfo ->
|
bundle.getParcelableCompat<SearchInfo>(KEY_SEARCH_INFO)?.let { searchInfo ->
|
||||||
WebDomain.getConcreteWebDomain(
|
AppUtil.getConcreteWebDomain(
|
||||||
this,
|
this,
|
||||||
searchInfo.webDomain
|
searchInfo.webDomain
|
||||||
) { concreteWebDomain ->
|
) { concreteWebDomain ->
|
||||||
@@ -109,7 +109,7 @@ class AutofillLauncherActivity : DatabaseModeActivity() {
|
|||||||
KEY_REGISTER_INFO
|
KEY_REGISTER_INFO
|
||||||
)
|
)
|
||||||
val searchInfo = SearchInfo(registerInfo?.searchInfo)
|
val searchInfo = SearchInfo(registerInfo?.searchInfo)
|
||||||
WebDomain.getConcreteWebDomain(this, searchInfo.webDomain) { concreteWebDomain ->
|
AppUtil.getConcreteWebDomain(this, searchInfo.webDomain) { concreteWebDomain ->
|
||||||
searchInfo.webDomain = concreteWebDomain
|
searchInfo.webDomain = concreteWebDomain
|
||||||
launchRegistration(database, searchInfo, registerInfo)
|
launchRegistration(database, searchInfo, registerInfo)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ import com.kunzisoft.keepass.database.ContextualDatabase
|
|||||||
import com.kunzisoft.keepass.database.helper.SearchHelper
|
import com.kunzisoft.keepass.database.helper.SearchHelper
|
||||||
import com.kunzisoft.keepass.model.SearchInfo
|
import com.kunzisoft.keepass.model.SearchInfo
|
||||||
import com.kunzisoft.keepass.otp.OtpEntryFields
|
import com.kunzisoft.keepass.otp.OtpEntryFields
|
||||||
|
import com.kunzisoft.keepass.utils.AppUtil
|
||||||
import com.kunzisoft.keepass.utils.KeyboardUtil.isKeyboardActivatedInSettings
|
import com.kunzisoft.keepass.utils.KeyboardUtil.isKeyboardActivatedInSettings
|
||||||
import com.kunzisoft.keepass.utils.WebDomain
|
|
||||||
import com.kunzisoft.keepass.utils.getParcelableCompat
|
import com.kunzisoft.keepass.utils.getParcelableCompat
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -109,7 +109,7 @@ class EntrySelectionLauncherActivity : DatabaseModeActivity() {
|
|||||||
this.otpString = otpString
|
this.otpString = otpString
|
||||||
}
|
}
|
||||||
|
|
||||||
WebDomain.getConcreteWebDomain(this, searchInfo.webDomain) { concreteWebDomain ->
|
AppUtil.getConcreteWebDomain(this, searchInfo.webDomain) { concreteWebDomain ->
|
||||||
searchInfo.webDomain = concreteWebDomain
|
searchInfo.webDomain = concreteWebDomain
|
||||||
launch(database, searchInfo)
|
launch(database, searchInfo)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ import com.kunzisoft.keepass.model.RegisterInfo
|
|||||||
import com.kunzisoft.keepass.model.SearchInfo
|
import com.kunzisoft.keepass.model.SearchInfo
|
||||||
import com.kunzisoft.keepass.settings.AutofillSettingsActivity
|
import com.kunzisoft.keepass.settings.AutofillSettingsActivity
|
||||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||||
import com.kunzisoft.keepass.utils.WebDomain
|
import com.kunzisoft.keepass.utils.AppUtil
|
||||||
import org.joda.time.DateTime
|
import org.joda.time.DateTime
|
||||||
|
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ class KeeAutofillService : AutofillService() {
|
|||||||
webDomain = parseResult.webDomain
|
webDomain = parseResult.webDomain
|
||||||
webScheme = parseResult.webScheme
|
webScheme = parseResult.webScheme
|
||||||
}
|
}
|
||||||
WebDomain.getConcreteWebDomain(this, searchInfo.webDomain) { webDomainWithoutSubDomain ->
|
AppUtil.getConcreteWebDomain(this, searchInfo.webDomain) { webDomainWithoutSubDomain ->
|
||||||
searchInfo.webDomain = webDomainWithoutSubDomain
|
searchInfo.webDomain = webDomainWithoutSubDomain
|
||||||
val inlineSuggestionsRequest = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
|
val inlineSuggestionsRequest = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
|
||||||
&& autofillInlineSuggestionsEnabled) {
|
&& autofillInlineSuggestionsEnabled) {
|
||||||
|
|||||||
@@ -328,19 +328,54 @@ object PasskeyHelper {
|
|||||||
return request.credentialOptions[0] as GetPublicKeyCredentialOption
|
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,
|
callingAppInfo: CallingAppInfo,
|
||||||
assets: AssetManager,
|
assets: AssetManager,
|
||||||
fileName: String): String? {
|
fileName: String
|
||||||
|
): String? {
|
||||||
val privilegedAllowList = assets.open(fileName).bufferedReader().use {
|
val privilegedAllowList = assets.open(fileName).bufferedReader().use {
|
||||||
it.readText()
|
it.readText()
|
||||||
}
|
}
|
||||||
return callingAppInfo.getOrigin(privilegedAllowList)?.removeSuffix("/")
|
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,
|
* 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 [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
|
* 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) {
|
withContext(Dispatchers.IO) {
|
||||||
|
|
||||||
// For trusted browsers like Chrome and Firefox
|
// For trusted browsers like Chrome and Firefox
|
||||||
// Check the community apps first
|
val callOrigin = getOriginFromPrivilegedAllowLists(callingAppInfo, assets)
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Build the default Android origin
|
||||||
val androidOrigin = AndroidOrigin(
|
val androidOrigin = AndroidOrigin(
|
||||||
packageName = callingAppInfo.packageName,
|
packageName = callingAppInfo.packageName,
|
||||||
fingerprint = callingAppInfo.signingInfo.getApplicationFingerprints()
|
fingerprint = callingAppInfo.signingInfo.getApplicationFingerprints()
|
||||||
)
|
)
|
||||||
|
|
||||||
// Check if the webDomain is validated for the
|
// Check if the webDomain is validated by the system
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
if (callOrigin != null && providedClientDataHash != null) {
|
if (callOrigin != null && providedClientDataHash != null) {
|
||||||
// Origin already defined by the system
|
// Origin already defined by the system
|
||||||
@@ -624,4 +642,7 @@ object PasskeyHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private const val BACKUP_ELIGIBILITY = true
|
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"
|
||||||
}
|
}
|
||||||
@@ -14,7 +14,7 @@ import androidx.appcompat.app.AlertDialog
|
|||||||
import com.kunzisoft.keepass.R
|
import com.kunzisoft.keepass.R
|
||||||
import com.kunzisoft.keepass.activities.legacy.DatabaseModeActivity
|
import com.kunzisoft.keepass.activities.legacy.DatabaseModeActivity
|
||||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
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,
|
* Special activity to deal with hardware key drivers,
|
||||||
|
|||||||
@@ -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<Intent>? = 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<ActivityResult> { 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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -21,7 +21,6 @@ package com.kunzisoft.keepass.settings
|
|||||||
|
|
||||||
import android.content.ActivityNotFoundException
|
import android.content.ActivityNotFoundException
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
@@ -30,6 +29,7 @@ import android.view.autofill.AutofillManager
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.core.net.toUri
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
@@ -47,7 +47,7 @@ import com.kunzisoft.keepass.icons.IconPackChooser
|
|||||||
import com.kunzisoft.keepass.services.ClipboardEntryNotificationService
|
import com.kunzisoft.keepass.services.ClipboardEntryNotificationService
|
||||||
import com.kunzisoft.keepass.settings.preference.IconPackListPreference
|
import com.kunzisoft.keepass.settings.preference.IconPackListPreference
|
||||||
import com.kunzisoft.keepass.settings.preferencedialogfragment.DurationDialogFragmentCompat
|
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.openUrl
|
||||||
import com.kunzisoft.keepass.utils.UriUtil.releaseAllUnnecessaryPermissionUris
|
import com.kunzisoft.keepass.utils.UriUtil.releaseAllUnnecessaryPermissionUris
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
|
|||||||
|
|
||||||
activity?.let { activity ->
|
activity?.let { activity ->
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
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 ->
|
activity.getSystemService(AutofillManager::class.java)?.let { autofillManager ->
|
||||||
if (autofillManager.hasEnabledAutofillServices())
|
if (autofillManager.hasEnabledAutofillServices())
|
||||||
autoFillEnablePreference?.isChecked = autofillManager.hasEnabledAutofillServices()
|
autoFillEnablePreference?.isChecked = autofillManager.hasEnabledAutofillServices()
|
||||||
@@ -161,7 +161,7 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
|
|||||||
val intent =
|
val intent =
|
||||||
Intent(Settings.ACTION_REQUEST_SET_AUTOFILL_SERVICE)
|
Intent(Settings.ACTION_REQUEST_SET_AUTOFILL_SERVICE)
|
||||||
intent.data =
|
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")
|
Log.d(javaClass.name, "Autofill enable service: intent=$intent")
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
} else {
|
} else {
|
||||||
@@ -171,7 +171,7 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
findPreference<Preference>(getString(R.string.autofill_key))?.isVisible = false
|
findPreference<Preference>(getString(R.string.credential_provider_key))?.isVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,6 +202,11 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
findPreference<Preference>(getString(R.string.settings_passkeys_key))?.setOnPreferenceClickListener {
|
||||||
|
startActivity(Intent(context, PasskeysSettingsActivity::class.java))
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
findPreference<Preference>(getString(R.string.clipboard_notifications_key))?.setOnPreferenceChangeListener { _, newValue ->
|
findPreference<Preference>(getString(R.string.clipboard_notifications_key))?.setOnPreferenceChangeListener { _, newValue ->
|
||||||
if (!(newValue as Boolean)) {
|
if (!(newValue as Boolean)) {
|
||||||
ClipboardEntryNotificationService.removeNotification(context)
|
ClipboardEntryNotificationService.removeNotification(context)
|
||||||
@@ -530,7 +535,7 @@ class NestedAppSettingsFragment : NestedSettingsFragment() {
|
|||||||
super.onResume()
|
super.onResume()
|
||||||
activity?.let { activity ->
|
activity?.let { activity ->
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
findPreference<TwoStatePreference?>(getString(R.string.settings_autofill_enable_key))?.let { autoFillEnablePreference ->
|
findPreference<TwoStatePreference?>(getString(R.string.settings_credential_provider_enable_key))?.let { autoFillEnablePreference ->
|
||||||
val autofillManager = activity.getSystemService(AutofillManager::class.java)
|
val autofillManager = activity.getSystemService(AutofillManager::class.java)
|
||||||
autoFillEnablePreference.isChecked = autofillManager != null
|
autoFillEnablePreference.isChecked = autofillManager != null
|
||||||
&& autofillManager.hasEnabledAutofillServices()
|
&& autofillManager.hasEnabledAutofillServices()
|
||||||
|
|||||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -35,8 +35,8 @@ import com.kunzisoft.keepass.database.search.SearchParameters
|
|||||||
import com.kunzisoft.keepass.education.Education
|
import com.kunzisoft.keepass.education.Education
|
||||||
import com.kunzisoft.keepass.password.PassphraseGenerator
|
import com.kunzisoft.keepass.password.PassphraseGenerator
|
||||||
import com.kunzisoft.keepass.timeout.TimeoutHelper
|
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.KeyboardUtil.isKeyboardActivatedInSettings
|
||||||
import com.kunzisoft.keepass.utils.UriUtil.isContributingUser
|
|
||||||
import java.util.Properties
|
import java.util.Properties
|
||||||
|
|
||||||
object PreferencesUtil {
|
object PreferencesUtil {
|
||||||
@@ -821,7 +821,7 @@ object PreferencesUtil {
|
|||||||
context.getString(R.string.clipboard_notifications_key) -> editor.putBoolean(name, value.toBoolean())
|
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.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.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_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_notification_entry_clear_close_key) -> editor.putBoolean(name, value.toBoolean())
|
||||||
context.getString(R.string.keyboard_entry_timeout_key) -> editor.putString(name, value.toLong().toString())
|
context.getString(R.string.keyboard_entry_timeout_key) -> editor.putString(name, value.toLong().toString())
|
||||||
|
|||||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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<AndroidOrigin>()
|
||||||
|
private var mListBrowsers: List<AndroidOrigin> = 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<RecyclerView>(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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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<T>()
|
||||||
|
: RecyclerView.Adapter<ListSelectionItemAdapter.SelectionViewHolder>() {
|
||||||
|
|
||||||
|
private val itemList: MutableList<T> = ArrayList()
|
||||||
|
var selectedItem: T? = null
|
||||||
|
private set
|
||||||
|
|
||||||
|
var itemSelectedCallback: ItemSelectedCallback<T>? = 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<T>) {
|
||||||
|
this.itemList.clear()
|
||||||
|
this.itemList.addAll(items)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ItemSelectedCallback<T> {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
147
app/src/main/java/com/kunzisoft/keepass/utils/AppUtil.kt
Normal file
147
app/src/main/java/com/kunzisoft/keepass/utils/AppUtil.kt
Normal file
@@ -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<AndroidOrigin> {
|
||||||
|
val packageManager = context.packageManager
|
||||||
|
val browserList = mutableListOf<AndroidOrigin>()
|
||||||
|
|
||||||
|
// 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<ResolveInfo> = 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<String>()
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,7 +28,7 @@ import android.view.MenuItem
|
|||||||
import com.kunzisoft.keepass.R
|
import com.kunzisoft.keepass.R
|
||||||
import com.kunzisoft.keepass.activities.AboutActivity
|
import com.kunzisoft.keepass.activities.AboutActivity
|
||||||
import com.kunzisoft.keepass.settings.SettingsActivity
|
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
|
import com.kunzisoft.keepass.utils.UriUtil.openUrl
|
||||||
|
|
||||||
object MenuUtil {
|
object MenuUtil {
|
||||||
@@ -40,9 +40,6 @@ object MenuUtil {
|
|||||||
menu.findItem(R.id.menu_contribute)?.isVisible = false
|
menu.findItem(R.id.menu_contribute)?.isVisible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @param checkLock Check the time lock before launch settings in LockingActivity
|
|
||||||
*/
|
|
||||||
fun onDefaultMenuOptionsItemSelected(activity: Activity,
|
fun onDefaultMenuOptionsItemSelected(activity: Activity,
|
||||||
item: MenuItem,
|
item: MenuItem,
|
||||||
timeoutEnable: Boolean = false) {
|
timeoutEnable: Boolean = false) {
|
||||||
|
|||||||
@@ -200,64 +200,5 @@ object UriUtil {
|
|||||||
this.openUrl(this.getString(resId))
|
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"
|
private const val TAG = "UriUtil"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -20,7 +20,6 @@
|
|||||||
package com.kunzisoft.keepass.view
|
package com.kunzisoft.keepass.view
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build
|
|
||||||
import android.text.InputFilter
|
import android.text.InputFilter
|
||||||
import android.text.util.Linkify
|
import android.text.util.Linkify
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
@@ -37,7 +36,7 @@ import androidx.core.view.ViewCompat
|
|||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import com.kunzisoft.keepass.R
|
import com.kunzisoft.keepass.R
|
||||||
import com.kunzisoft.keepass.model.AppOriginEntryField.APPLICATION_ID_FIELD_NAME
|
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,
|
open class TextFieldView @JvmOverloads constructor(context: Context,
|
||||||
|
|||||||
35
app/src/main/res/layout/pref_dialog_list_item.xml
Normal file
35
app/src/main/res/layout/pref_dialog_list_item.xml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright 2019 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 <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/pref_dialog_list_container"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:minHeight="@dimen/selectable_min_height"
|
||||||
|
style="@style/KeepassDXStyle.Selectable.Item"
|
||||||
|
android:layout_margin="8dp">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/pref_dialog_list_text"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
style="@style/KeepassDXStyle.Title.Entry"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
</LinearLayout>
|
||||||
@@ -167,7 +167,7 @@
|
|||||||
<string name="general">عام</string>
|
<string name="general">عام</string>
|
||||||
<string name="autofill">الملء التلقائي</string>
|
<string name="autofill">الملء التلقائي</string>
|
||||||
<string name="autofill_sign_in_prompt">سجل باستخدام KeePassDX</string>
|
<string name="autofill_sign_in_prompt">سجل باستخدام KeePassDX</string>
|
||||||
<string name="set_autofill_service_title">تعيين خدمة الملأ التلقائي الافتراضية</string>
|
<string name="set_credential_provider_service_title">تعيين خدمة الملأ التلقائي الافتراضية</string>
|
||||||
<string name="password_size_title">حجم كلمة السر المولدة</string>
|
<string name="password_size_title">حجم كلمة السر المولدة</string>
|
||||||
<string name="password_size_summary">تعيين الحجم الافتراضي لكلمات السر المولدة</string>
|
<string name="password_size_summary">تعيين الحجم الافتراضي لكلمات السر المولدة</string>
|
||||||
<string name="list_password_generator_options_title">محارف كلمة السر</string>
|
<string name="list_password_generator_options_title">محارف كلمة السر</string>
|
||||||
|
|||||||
@@ -518,7 +518,7 @@
|
|||||||
<string name="device_unlock_prompt_not_initialized">Cihaz kilid açma istəyini başlatmaq mümkün deyil.</string>
|
<string name="device_unlock_prompt_not_initialized">Cihaz kilid açma istəyini başlatmaq mümkün deyil.</string>
|
||||||
<string name="autofill_explanation_summary">Digər tətbiqlərdə formları (anket) daha sürətli doldurmaq üçün avtomatik doldurma funksiyasını aktiv edin</string>
|
<string name="autofill_explanation_summary">Digər tətbiqlərdə formları (anket) daha sürətli doldurmaq üçün avtomatik doldurma funksiyasını aktiv edin</string>
|
||||||
<string name="autofill_select_entry">Şifrə seç .…</string>
|
<string name="autofill_select_entry">Şifrə seç .…</string>
|
||||||
<string name="set_autofill_service_title">Standart avtomatik doldurma xidmətini təyin edin</string>
|
<string name="set_credential_provider_service_title">Standart avtomatik doldurma xidmətini təyin edin</string>
|
||||||
<string name="autofill_preference_title">Avtomatik doldurmanın parametrləri</string>
|
<string name="autofill_preference_title">Avtomatik doldurmanın parametrləri</string>
|
||||||
<string name="password_size_title">Yaradılan şifrə həcmi</string>
|
<string name="password_size_title">Yaradılan şifrə həcmi</string>
|
||||||
<string name="password_size_summary">Yaradılan şifrələrin standart həcmini təyin edər</string>
|
<string name="password_size_summary">Yaradılan şifrələrin standart həcmini təyin edər</string>
|
||||||
|
|||||||
@@ -288,7 +288,7 @@
|
|||||||
<string name="read_only">Само за четене</string>
|
<string name="read_only">Само за четене</string>
|
||||||
<string name="contains_duplicate_uuid">Хранилището съдържа повтарящ се идентификатор.</string>
|
<string name="contains_duplicate_uuid">Хранилището съдържа повтарящ се идентификатор.</string>
|
||||||
<string name="biometric">Биометричен ключ</string>
|
<string name="biometric">Биометричен ключ</string>
|
||||||
<string name="set_autofill_service_title">Задаване на подразбирана услуга за автоматично попълване</string>
|
<string name="set_credential_provider_service_title">Задаване на подразбирана услуга за автоматично попълване</string>
|
||||||
<string name="password_size_title">Дължина на създаваните пароли</string>
|
<string name="password_size_title">Дължина на създаваните пароли</string>
|
||||||
<string name="lock_database_back_root_title">Заключване при „Назад“</string>
|
<string name="lock_database_back_root_title">Заключване при „Назад“</string>
|
||||||
<string name="content">Съдържание</string>
|
<string name="content">Съдържание</string>
|
||||||
|
|||||||
@@ -410,7 +410,7 @@
|
|||||||
<string name="waiting_challenge_response">Esperant la resposta de desafiament…</string>
|
<string name="waiting_challenge_response">Esperant la resposta de desafiament…</string>
|
||||||
<string name="bank_name">Nom del banc</string>
|
<string name="bank_name">Nom del banc</string>
|
||||||
<string name="wireless">Wi-Fi</string>
|
<string name="wireless">Wi-Fi</string>
|
||||||
<string name="set_autofill_service_title">Estableix el servei d\'emplenament automàtic predeterminat</string>
|
<string name="set_credential_provider_service_title">Estableix el servei d\'emplenament automàtic predeterminat</string>
|
||||||
<string name="compression">Compressió</string>
|
<string name="compression">Compressió</string>
|
||||||
<string name="id_card">Targeta d\'identificació</string>
|
<string name="id_card">Targeta d\'identificació</string>
|
||||||
<string name="error_hardware_key_unsupported">Clau física no suportada.</string>
|
<string name="error_hardware_key_unsupported">Clau física no suportada.</string>
|
||||||
|
|||||||
@@ -181,7 +181,7 @@
|
|||||||
<string name="autofill">Samovyplnění</string>
|
<string name="autofill">Samovyplnění</string>
|
||||||
<string name="autofill_service_name">KeePassDX samovyplnění formulářů</string>
|
<string name="autofill_service_name">KeePassDX samovyplnění formulářů</string>
|
||||||
<string name="autofill_sign_in_prompt">Přihlásit se s KeePassDX</string>
|
<string name="autofill_sign_in_prompt">Přihlásit se s KeePassDX</string>
|
||||||
<string name="set_autofill_service_title">Nastavit výchozí službu samovyplnění</string>
|
<string name="set_credential_provider_service_title">Nastavit výchozí službu samovyplnění</string>
|
||||||
<string name="autofill_explanation_summary">Zapnout samovyplnění formulářů za účelem rychlého vyplnění v ostatních aplikacích</string>
|
<string name="autofill_explanation_summary">Zapnout samovyplnění formulářů za účelem rychlého vyplnění v ostatních aplikacích</string>
|
||||||
<string name="password_size_title">Délka generovaného hesla</string>
|
<string name="password_size_title">Délka generovaného hesla</string>
|
||||||
<string name="password_size_summary">Nastavení výchozí délky generovaných hesel</string>
|
<string name="password_size_summary">Nastavení výchozí délky generovaných hesel</string>
|
||||||
|
|||||||
@@ -180,7 +180,7 @@
|
|||||||
<string name="autofill">Autoudfyld</string>
|
<string name="autofill">Autoudfyld</string>
|
||||||
<string name="autofill_service_name">KeePassDX formularudfyldning</string>
|
<string name="autofill_service_name">KeePassDX formularudfyldning</string>
|
||||||
<string name="autofill_sign_in_prompt">Log ind med KeePassDX</string>
|
<string name="autofill_sign_in_prompt">Log ind med KeePassDX</string>
|
||||||
<string name="set_autofill_service_title">Indstil standard autoudfyldningstjeneste</string>
|
<string name="set_credential_provider_service_title">Indstil standard autoudfyldningstjeneste</string>
|
||||||
<string name="autofill_explanation_summary">Aktiver autofyldning for hurtigt at udfylde formularer i andre apps</string>
|
<string name="autofill_explanation_summary">Aktiver autofyldning for hurtigt at udfylde formularer i andre apps</string>
|
||||||
<string name="password_size_title">Genereret adgangskodelængde</string>
|
<string name="password_size_title">Genereret adgangskodelængde</string>
|
||||||
<string name="password_size_summary">Angiver standardlængden for genererede adgangskoder</string>
|
<string name="password_size_summary">Angiver standardlængden for genererede adgangskoder</string>
|
||||||
|
|||||||
@@ -197,7 +197,7 @@
|
|||||||
<string name="autofill">Automatisches Ausfüllen</string>
|
<string name="autofill">Automatisches Ausfüllen</string>
|
||||||
<string name="autofill_service_name">KeePassDX Auto-Formularausfüllung</string>
|
<string name="autofill_service_name">KeePassDX Auto-Formularausfüllung</string>
|
||||||
<string name="autofill_sign_in_prompt">Mit KeePassDX anmelden</string>
|
<string name="autofill_sign_in_prompt">Mit KeePassDX anmelden</string>
|
||||||
<string name="set_autofill_service_title">Standard-Autofill-Service festlegen</string>
|
<string name="set_credential_provider_service_title">Standard-Autofill-Service festlegen</string>
|
||||||
<string name="autofill_explanation_summary">Automatisches Ausfüllen aktivieren, um Formulare in anderen Apps schnell auszufüllen</string>
|
<string name="autofill_explanation_summary">Automatisches Ausfüllen aktivieren, um Formulare in anderen Apps schnell auszufüllen</string>
|
||||||
<string name="autofill_select_entry">Eintrag auswählen …</string>
|
<string name="autofill_select_entry">Eintrag auswählen …</string>
|
||||||
<string name="clipboard">Zwischenablage</string>
|
<string name="clipboard">Zwischenablage</string>
|
||||||
|
|||||||
@@ -169,7 +169,7 @@
|
|||||||
<string name="autofill">Αυτόματη συμπλήρωση</string>
|
<string name="autofill">Αυτόματη συμπλήρωση</string>
|
||||||
<string name="autofill_service_name">Μορφή KeePassDX αυτόματης συμπλήρωσης</string>
|
<string name="autofill_service_name">Μορφή KeePassDX αυτόματης συμπλήρωσης</string>
|
||||||
<string name="autofill_sign_in_prompt">Συνδεθείτε με το KeePassDX</string>
|
<string name="autofill_sign_in_prompt">Συνδεθείτε με το KeePassDX</string>
|
||||||
<string name="set_autofill_service_title">Ορίστε την προεπιλεγμένη υπηρεσία αυτόματης συμπλήρωσης</string>
|
<string name="set_credential_provider_service_title">Ορίστε την προεπιλεγμένη υπηρεσία αυτόματης συμπλήρωσης</string>
|
||||||
<string name="password_size_title">Παραγόμενο μέγεθος κωδικού πρόσβασης</string>
|
<string name="password_size_title">Παραγόμενο μέγεθος κωδικού πρόσβασης</string>
|
||||||
<string name="password_size_summary">Ορίστε το προεπιλεγμένο μέγεθος των παραγόμενων κωδικών πρόσβασης</string>
|
<string name="password_size_summary">Ορίστε το προεπιλεγμένο μέγεθος των παραγόμενων κωδικών πρόσβασης</string>
|
||||||
<string name="list_password_generator_options_title">Χαρακτήρες Κωδικού Πρόσβασης</string>
|
<string name="list_password_generator_options_title">Χαρακτήρες Κωδικού Πρόσβασης</string>
|
||||||
|
|||||||
@@ -172,7 +172,7 @@
|
|||||||
<string name="autofill">Autocompletado</string>
|
<string name="autofill">Autocompletado</string>
|
||||||
<string name="autofill_service_name">Autocompletado de formularios de KeePassDX</string>
|
<string name="autofill_service_name">Autocompletado de formularios de KeePassDX</string>
|
||||||
<string name="autofill_sign_in_prompt">Iniciar sesión con KeePassDX</string>
|
<string name="autofill_sign_in_prompt">Iniciar sesión con KeePassDX</string>
|
||||||
<string name="set_autofill_service_title">Establecer servicio de autocompletado por defecto</string>
|
<string name="set_credential_provider_service_title">Establecer servicio de autocompletado por defecto</string>
|
||||||
<string name="password_size_title">Tamaño de la contraseña generada</string>
|
<string name="password_size_title">Tamaño de la contraseña generada</string>
|
||||||
<string name="password_size_summary">Establece el tamaño predeterminado de las contraseñas generadas</string>
|
<string name="password_size_summary">Establece el tamaño predeterminado de las contraseñas generadas</string>
|
||||||
<string name="list_password_generator_options_title">Caracteres de contraseña</string>
|
<string name="list_password_generator_options_title">Caracteres de contraseña</string>
|
||||||
|
|||||||
@@ -474,7 +474,7 @@
|
|||||||
<string name="autofill_service_name">KeePassDXi automaattäite teenus</string>
|
<string name="autofill_service_name">KeePassDXi automaattäite teenus</string>
|
||||||
<string name="autofill_explanation_summary">Täitmaks andmevorme teistes rakenduses, luba automaattäite teenus</string>
|
<string name="autofill_explanation_summary">Täitmaks andmevorme teistes rakenduses, luba automaattäite teenus</string>
|
||||||
<string name="autofill_select_entry">Vali kirje…</string>
|
<string name="autofill_select_entry">Vali kirje…</string>
|
||||||
<string name="set_autofill_service_title">Vali vaikimisi kasutatav automaattäite teenus</string>
|
<string name="set_credential_provider_service_title">Vali vaikimisi kasutatav automaattäite teenus</string>
|
||||||
<string name="autofill_preference_title">Automaattäite teenuse seadistused</string>
|
<string name="autofill_preference_title">Automaattäite teenuse seadistused</string>
|
||||||
<string name="database_opened">Andmebaas on avatud</string>
|
<string name="database_opened">Andmebaas on avatud</string>
|
||||||
<string name="clipboard">Lõikelaud</string>
|
<string name="clipboard">Lõikelaud</string>
|
||||||
|
|||||||
@@ -575,7 +575,7 @@
|
|||||||
<string name="warning_database_revoked">Fitxategirako atzipena baliogabetu du fitxategi kudeatzaileak, itxi datu-basea eta berriro ireki ezazu bere lokalizaziotik.</string>
|
<string name="warning_database_revoked">Fitxategirako atzipena baliogabetu du fitxategi kudeatzaileak, itxi datu-basea eta berriro ireki ezazu bere lokalizaziotik.</string>
|
||||||
<string name="device_unlock_prompt_store_credential_title">Gailuaren desblokeorako esteka</string>
|
<string name="device_unlock_prompt_store_credential_title">Gailuaren desblokeorako esteka</string>
|
||||||
<string name="device_unlock_prompt_not_initialized">Ezin izan da hasieratu gailuaren desblokeatze menua.</string>
|
<string name="device_unlock_prompt_not_initialized">Ezin izan da hasieratu gailuaren desblokeatze menua.</string>
|
||||||
<string name="set_autofill_service_title">Lehenetsi betetze automatiko zerbitzua</string>
|
<string name="set_credential_provider_service_title">Lehenetsi betetze automatiko zerbitzua</string>
|
||||||
<string name="content">Edukia</string>
|
<string name="content">Edukia</string>
|
||||||
<string name="education_device_unlock_title">Datu-basearen desblokeatze automatikoa</string>
|
<string name="education_device_unlock_title">Datu-basearen desblokeatze automatikoa</string>
|
||||||
<string name="screenshot_mode_banner_text">Pantaila-argazki modua</string>
|
<string name="screenshot_mode_banner_text">Pantaila-argazki modua</string>
|
||||||
|
|||||||
@@ -237,7 +237,7 @@
|
|||||||
<string name="kdf_explanation">Pääavain muunnetaan käyttäen satunnaista suolattua avaimen johtamisfunktiota, jotta salausalgoritmin avain voidaan generoida.</string>
|
<string name="kdf_explanation">Pääavain muunnetaan käyttäen satunnaista suolattua avaimen johtamisfunktiota, jotta salausalgoritmin avain voidaan generoida.</string>
|
||||||
<string name="encryption_explanation">Salasanatietokannan salausalgoritmi, jota käytetään kaikelle datalle.</string>
|
<string name="encryption_explanation">Salasanatietokannan salausalgoritmi, jota käytetään kaikelle datalle.</string>
|
||||||
<string name="password_size_title">Generoidun salasanan pituus</string>
|
<string name="password_size_title">Generoidun salasanan pituus</string>
|
||||||
<string name="set_autofill_service_title">Aseta oletus automaattiselle täytölle</string>
|
<string name="set_credential_provider_service_title">Aseta oletus automaattiselle täytölle</string>
|
||||||
<string name="autofill_sign_in_prompt">Kirjaudu sisään KeePassDX:llä</string>
|
<string name="autofill_sign_in_prompt">Kirjaudu sisään KeePassDX:llä</string>
|
||||||
<string name="autofill_service_name">KeePassDX:n automaattinen täyttö</string>
|
<string name="autofill_service_name">KeePassDX:n automaattinen täyttö</string>
|
||||||
<string name="autofill">Automaattinen täyttö</string>
|
<string name="autofill">Automaattinen täyttö</string>
|
||||||
|
|||||||
@@ -165,7 +165,7 @@
|
|||||||
<string name="autofill">Remplissage automatique</string>
|
<string name="autofill">Remplissage automatique</string>
|
||||||
<string name="autofill_service_name">Remplissage automatique des formulaires KeePassDX</string>
|
<string name="autofill_service_name">Remplissage automatique des formulaires KeePassDX</string>
|
||||||
<string name="autofill_sign_in_prompt">Se connecter avec KeePassDX</string>
|
<string name="autofill_sign_in_prompt">Se connecter avec KeePassDX</string>
|
||||||
<string name="set_autofill_service_title">Définir le service de remplissage automatique par défaut</string>
|
<string name="set_credential_provider_service_title">Définir le service de remplissage automatique par défaut</string>
|
||||||
<string name="autofill_explanation_summary">Activer le remplissage automatique pour remplir rapidement des formulaires dans d’autres applications</string>
|
<string name="autofill_explanation_summary">Activer le remplissage automatique pour remplir rapidement des formulaires dans d’autres applications</string>
|
||||||
<string name="autofill_select_entry">Sélectionner une entrée…</string>
|
<string name="autofill_select_entry">Sélectionner une entrée…</string>
|
||||||
<string name="password_size_title">Taille du mot de passe généré</string>
|
<string name="password_size_title">Taille du mot de passe généré</string>
|
||||||
|
|||||||
@@ -373,7 +373,7 @@
|
|||||||
<string name="biometric">Biométrico</string>
|
<string name="biometric">Biométrico</string>
|
||||||
<string name="autofill_explanation_summary">Habilite o servizo para autocompletar rapidamente os formularios de outras aplicacións</string>
|
<string name="autofill_explanation_summary">Habilite o servizo para autocompletar rapidamente os formularios de outras aplicacións</string>
|
||||||
<string name="clipboard_notifications_title">Notificacións do portapapeis</string>
|
<string name="clipboard_notifications_title">Notificacións do portapapeis</string>
|
||||||
<string name="set_autofill_service_title">Estabelecer o servizo de autocompletado predefinido</string>
|
<string name="set_credential_provider_service_title">Estabelecer o servizo de autocompletado predefinido</string>
|
||||||
<string name="lock_database_back_root_summary">Bloquear a base de datos cando o usuario faga click no botón de volver á pantalla principal</string>
|
<string name="lock_database_back_root_summary">Bloquear a base de datos cando o usuario faga click no botón de volver á pantalla principal</string>
|
||||||
<string name="lock_database_show_button_title">Mostrar botón de bloqueo</string>
|
<string name="lock_database_show_button_title">Mostrar botón de bloqueo</string>
|
||||||
<string name="clipboard_notifications_summary">Mostrar notificacións do portapapeis ao visualizar unha entrada</string>
|
<string name="clipboard_notifications_summary">Mostrar notificacións do portapapeis ao visualizar unha entrada</string>
|
||||||
|
|||||||
@@ -178,7 +178,7 @@
|
|||||||
<string name="general">Opće</string>
|
<string name="general">Opće</string>
|
||||||
<string name="autofill">Automatsko ispunjavanje</string>
|
<string name="autofill">Automatsko ispunjavanje</string>
|
||||||
<string name="autofill_service_name">Automatsko ispunjavanje KeePassDX obrasca</string>
|
<string name="autofill_service_name">Automatsko ispunjavanje KeePassDX obrasca</string>
|
||||||
<string name="set_autofill_service_title">Postavi standardnu uslugu automatskog ispunjavanja</string>
|
<string name="set_credential_provider_service_title">Postavi standardnu uslugu automatskog ispunjavanja</string>
|
||||||
<string name="list_password_generator_options_title">Znakovi lozinke</string>
|
<string name="list_password_generator_options_title">Znakovi lozinke</string>
|
||||||
<string name="list_password_generator_options_summary">Postavi dozvoljene znakove za generiranje lozinke</string>
|
<string name="list_password_generator_options_summary">Postavi dozvoljene znakove za generiranje lozinke</string>
|
||||||
<string name="database_opened">Baza podataka otvorena</string>
|
<string name="database_opened">Baza podataka otvorena</string>
|
||||||
|
|||||||
@@ -185,7 +185,7 @@
|
|||||||
<string name="autofill">Automatikus kitöltés</string>
|
<string name="autofill">Automatikus kitöltés</string>
|
||||||
<string name="autofill_service_name">KeePassDX űrlapkitöltés</string>
|
<string name="autofill_service_name">KeePassDX űrlapkitöltés</string>
|
||||||
<string name="autofill_sign_in_prompt">Bejelentkezés a KeePassDX-szel</string>
|
<string name="autofill_sign_in_prompt">Bejelentkezés a KeePassDX-szel</string>
|
||||||
<string name="set_autofill_service_title">Alapértelmezett automatikus kitöltési szolgáltatás beállítása</string>
|
<string name="set_credential_provider_service_title">Alapértelmezett automatikus kitöltési szolgáltatás beállítása</string>
|
||||||
<string name="autofill_explanation_summary">Automatikus kitöltés engedélyezése az űrlapok gyors kitöltéséhez más alkalmazásokban</string>
|
<string name="autofill_explanation_summary">Automatikus kitöltés engedélyezése az űrlapok gyors kitöltéséhez más alkalmazásokban</string>
|
||||||
<string name="password_size_title">Előállított jelszó mérete</string>
|
<string name="password_size_title">Előállított jelszó mérete</string>
|
||||||
<string name="password_size_summary">Beállítja az előállított jelszavak alapértelmezett méretét</string>
|
<string name="password_size_summary">Beállítja az előállított jelszavak alapértelmezett méretét</string>
|
||||||
|
|||||||
@@ -423,7 +423,7 @@
|
|||||||
<string name="credential_before_click_device_unlock_button">Ketik kata sandi, lalu klik tombol ini.</string>
|
<string name="credential_before_click_device_unlock_button">Ketik kata sandi, lalu klik tombol ini.</string>
|
||||||
<string name="autofill_service_name">Isi formulir KeePassDX otomatis</string>
|
<string name="autofill_service_name">Isi formulir KeePassDX otomatis</string>
|
||||||
<string name="autofill_preference_title">Pengaturan isi otomatis</string>
|
<string name="autofill_preference_title">Pengaturan isi otomatis</string>
|
||||||
<string name="set_autofill_service_title">Setel layanan isi otomatis secara default</string>
|
<string name="set_credential_provider_service_title">Setel layanan isi otomatis secara default</string>
|
||||||
<string name="autofill_explanation_summary">Aktifkan pengisian otomatis untuk mengisi formulir dengan cepat di aplikasi lain</string>
|
<string name="autofill_explanation_summary">Aktifkan pengisian otomatis untuk mengisi formulir dengan cepat di aplikasi lain</string>
|
||||||
<string name="autofill_sign_in_prompt">Masuk dengan KeePassDX</string>
|
<string name="autofill_sign_in_prompt">Masuk dengan KeePassDX</string>
|
||||||
<string name="autofill">Isi otomatis</string>
|
<string name="autofill">Isi otomatis</string>
|
||||||
|
|||||||
@@ -180,7 +180,7 @@
|
|||||||
<string name="autofill">Autocompletamento</string>
|
<string name="autofill">Autocompletamento</string>
|
||||||
<string name="autofill_service_name">Autocompletamento di KeePassDX</string>
|
<string name="autofill_service_name">Autocompletamento di KeePassDX</string>
|
||||||
<string name="autofill_sign_in_prompt">Accedi con KeePassDX</string>
|
<string name="autofill_sign_in_prompt">Accedi con KeePassDX</string>
|
||||||
<string name="set_autofill_service_title">Servizio predefinito di autocompletamento</string>
|
<string name="set_credential_provider_service_title">Servizio predefinito di autocompletamento</string>
|
||||||
<string name="autofill_explanation_summary">Attiva l\'autocompletamento per riempire velocemente i campi in altre app</string>
|
<string name="autofill_explanation_summary">Attiva l\'autocompletamento per riempire velocemente i campi in altre app</string>
|
||||||
<string name="password_size_title">Dimensione password generata</string>
|
<string name="password_size_title">Dimensione password generata</string>
|
||||||
<string name="password_size_summary">Imposta la dimensione predefinita delle password generate</string>
|
<string name="password_size_summary">Imposta la dimensione predefinita delle password generate</string>
|
||||||
|
|||||||
@@ -414,7 +414,7 @@
|
|||||||
<string name="autofill_sign_in_prompt">התחבר עם KeePassDX</string>
|
<string name="autofill_sign_in_prompt">התחבר עם KeePassDX</string>
|
||||||
<string name="general">כללי</string>
|
<string name="general">כללי</string>
|
||||||
<string name="autofill_explanation_summary">הפעל מילוי אוטומטי כדי למלא במהירות טפסים ביישומים אחרים</string>
|
<string name="autofill_explanation_summary">הפעל מילוי אוטומטי כדי למלא במהירות טפסים ביישומים אחרים</string>
|
||||||
<string name="set_autofill_service_title">הגדר שירות מילוי אוטומטי ברירת מחדל</string>
|
<string name="set_credential_provider_service_title">הגדר שירות מילוי אוטומטי ברירת מחדל</string>
|
||||||
<string name="password_size_title">גודל סיסמה שנוצרה</string>
|
<string name="password_size_title">גודל סיסמה שנוצרה</string>
|
||||||
<string name="password_size_summary">מגדיר גודל ברירת המחדל של הסיסמאות שנוצרו</string>
|
<string name="password_size_summary">מגדיר גודל ברירת המחדל של הסיסמאות שנוצרו</string>
|
||||||
<string name="list_password_generator_options_title">תווי סיסמה</string>
|
<string name="list_password_generator_options_title">תווי סיסמה</string>
|
||||||
|
|||||||
@@ -276,7 +276,7 @@
|
|||||||
<string name="autofill_service_name">KeePassDX フォーム自動入力</string>
|
<string name="autofill_service_name">KeePassDX フォーム自動入力</string>
|
||||||
<string name="autofill_sign_in_prompt">KeePassDX でログイン</string>
|
<string name="autofill_sign_in_prompt">KeePassDX でログイン</string>
|
||||||
<string name="autofill_explanation_summary">自動入力を有効にして、他のアプリ内のフォームにすばやく入力します</string>
|
<string name="autofill_explanation_summary">自動入力を有効にして、他のアプリ内のフォームにすばやく入力します</string>
|
||||||
<string name="set_autofill_service_title">デフォルトの自動入力サービスに設定</string>
|
<string name="set_credential_provider_service_title">デフォルトの自動入力サービスに設定</string>
|
||||||
<string name="autofill_preference_title">自動入力の設定</string>
|
<string name="autofill_preference_title">自動入力の設定</string>
|
||||||
<string name="password_size_title">生成されるパスワードの長さ</string>
|
<string name="password_size_title">生成されるパスワードの長さ</string>
|
||||||
<string name="password_size_summary">生成されるパスワードの長さのデフォルト値を設定します</string>
|
<string name="password_size_summary">生成されるパスワードの長さのデフォルト値を設定します</string>
|
||||||
|
|||||||
@@ -385,7 +385,7 @@
|
|||||||
<string name="autofill_sign_in_prompt">KeePassDX로 로그인</string>
|
<string name="autofill_sign_in_prompt">KeePassDX로 로그인</string>
|
||||||
<string name="password_size_title">생성된 비밀번호 크기</string>
|
<string name="password_size_title">생성된 비밀번호 크기</string>
|
||||||
<string name="autofill_preference_title">자동 완성 설정</string>
|
<string name="autofill_preference_title">자동 완성 설정</string>
|
||||||
<string name="set_autofill_service_title">기본 자동완성 서비스 설정</string>
|
<string name="set_credential_provider_service_title">기본 자동완성 서비스 설정</string>
|
||||||
<string name="lock_database_screen_off_title">화면 꺼짐 시 잠금</string>
|
<string name="lock_database_screen_off_title">화면 꺼짐 시 잠금</string>
|
||||||
<string name="device_unlock_explanation_summary">기기 잠금 방식을 사용하여 데이터베이스를 더 쉽게 여세요</string>
|
<string name="device_unlock_explanation_summary">기기 잠금 방식을 사용하여 데이터베이스를 더 쉽게 여세요</string>
|
||||||
<string name="biometric_unlock_enable_title">생체 인식 잠금 해제</string>
|
<string name="biometric_unlock_enable_title">생체 인식 잠금 해제</string>
|
||||||
|
|||||||
@@ -361,7 +361,7 @@
|
|||||||
<string name="warning_keyfile_integrity">Failo \"hash\" reikšmė nėra garantuota, nes \"Android\" gali keisti jo duomenis. Norėdami užtikrinti teisingą vientisumą, pakeiskite failo plėtinį į .bin.</string>
|
<string name="warning_keyfile_integrity">Failo \"hash\" reikšmė nėra garantuota, nes \"Android\" gali keisti jo duomenis. Norėdami užtikrinti teisingą vientisumą, pakeiskite failo plėtinį į .bin.</string>
|
||||||
<string name="configure_biometric">Biometriniai duomenys ar prietaiso įgaliojimai neįrašomi.</string>
|
<string name="configure_biometric">Biometriniai duomenys ar prietaiso įgaliojimai neįrašomi.</string>
|
||||||
<string name="autofill_preference_title">Automatinio pildymo nustatymai</string>
|
<string name="autofill_preference_title">Automatinio pildymo nustatymai</string>
|
||||||
<string name="set_autofill_service_title">Nustatyti numatytąją automatinio pildymo paslaugą</string>
|
<string name="set_credential_provider_service_title">Nustatyti numatytąją automatinio pildymo paslaugą</string>
|
||||||
<string name="lock_database_screen_off_title">Ekrano užraktas</string>
|
<string name="lock_database_screen_off_title">Ekrano užraktas</string>
|
||||||
<string name="biometric_unlock_enable_title">Biometrinis atrakinimas</string>
|
<string name="biometric_unlock_enable_title">Biometrinis atrakinimas</string>
|
||||||
<string name="show_uuid_title">Rodyti UUID</string>
|
<string name="show_uuid_title">Rodyti UUID</string>
|
||||||
|
|||||||
@@ -339,7 +339,7 @@
|
|||||||
<string name="clipboard_explanation_summary">നിങ്ങളുടെ ഉപകരണത്തിന്റെ ക്ലിപ്പ്ബോർഡ് ഉപയോഗിച്ച് എൻട്രി ഫീൽഡുകൾ പകർത്തുക</string>
|
<string name="clipboard_explanation_summary">നിങ്ങളുടെ ഉപകരണത്തിന്റെ ക്ലിപ്പ്ബോർഡ് ഉപയോഗിച്ച് എൻട്രി ഫീൽഡുകൾ പകർത്തുക</string>
|
||||||
<string name="list_password_generator_options_title">പാസ്വേഡ് പ്രതീകങ്ങൾ</string>
|
<string name="list_password_generator_options_title">പാസ്വേഡ് പ്രതീകങ്ങൾ</string>
|
||||||
<string name="password_size_summary">സൃഷ്ടിച്ച പാസ്വേഡുകളുടെ സ്ഥിരസ്ഥിതി വലുപ്പം സജ്ജമാക്കുക</string>
|
<string name="password_size_summary">സൃഷ്ടിച്ച പാസ്വേഡുകളുടെ സ്ഥിരസ്ഥിതി വലുപ്പം സജ്ജമാക്കുക</string>
|
||||||
<string name="set_autofill_service_title">സ്ഥിരസ്ഥിതി ഓട്ടോഫിൽ സേവനം സജ്ജമാക്കുക</string>
|
<string name="set_credential_provider_service_title">സ്ഥിരസ്ഥിതി ഓട്ടോഫിൽ സേവനം സജ്ജമാക്കുക</string>
|
||||||
<string name="autofill_explanation_summary">മറ്റ് അപ്ലിക്കേഷനുകളിൽ ഫോമുകൾ വേഗത്തിൽ പൂരിപ്പിക്കുന്നതിന് ഓട്ടോഫില്ലിംഗ് പ്രവർത്തനക്ഷമമാക്കുക</string>
|
<string name="autofill_explanation_summary">മറ്റ് അപ്ലിക്കേഷനുകളിൽ ഫോമുകൾ വേഗത്തിൽ പൂരിപ്പിക്കുന്നതിന് ഓട്ടോഫില്ലിംഗ് പ്രവർത്തനക്ഷമമാക്കുക</string>
|
||||||
<string name="keystore_not_accessible">കീസ്റ്റോർ ശരിയായി സമാരംഭിച്ചിട്ടില്ല.</string>
|
<string name="keystore_not_accessible">കീസ്റ്റോർ ശരിയായി സമാരംഭിച്ചിട്ടില്ല.</string>
|
||||||
<string name="sort_recycle_bin_bottom">റീസൈക്കിൾ ബിൻ ചുവടെയുണ്ട്</string>
|
<string name="sort_recycle_bin_bottom">റീസൈക്കിൾ ബിൻ ചുവടെയുണ്ട്</string>
|
||||||
|
|||||||
@@ -175,7 +175,7 @@
|
|||||||
<string name="autofill">Autofyll</string>
|
<string name="autofill">Autofyll</string>
|
||||||
<string name="autofill_service_name">KeePassDX autofyll-tjeneste</string>
|
<string name="autofill_service_name">KeePassDX autofyll-tjeneste</string>
|
||||||
<string name="autofill_sign_in_prompt">Logg inn med KeePassDX</string>
|
<string name="autofill_sign_in_prompt">Logg inn med KeePassDX</string>
|
||||||
<string name="set_autofill_service_title">Sett forvalgt autofyll-tjeneste</string>
|
<string name="set_credential_provider_service_title">Sett forvalgt autofyll-tjeneste</string>
|
||||||
<string name="autofill_explanation_summary">Skru på tjenesten for å fylle ut skjema fra andre programmer</string>
|
<string name="autofill_explanation_summary">Skru på tjenesten for å fylle ut skjema fra andre programmer</string>
|
||||||
<string name="password_size_title">Passordsstørrelse</string>
|
<string name="password_size_title">Passordsstørrelse</string>
|
||||||
<string name="password_size_summary">Sett forvalgt størrelse for generert passord</string>
|
<string name="password_size_summary">Sett forvalgt størrelse for generert passord</string>
|
||||||
|
|||||||
@@ -187,7 +187,7 @@
|
|||||||
<string name="autofill">Automatisch aanvullen</string>
|
<string name="autofill">Automatisch aanvullen</string>
|
||||||
<string name="autofill_service_name">KeePassDX dienst automatisch aanvullen</string>
|
<string name="autofill_service_name">KeePassDX dienst automatisch aanvullen</string>
|
||||||
<string name="autofill_sign_in_prompt">Inloggen met KeePassDX</string>
|
<string name="autofill_sign_in_prompt">Inloggen met KeePassDX</string>
|
||||||
<string name="set_autofill_service_title">Dienst automatisch aanvullen</string>
|
<string name="set_credential_provider_service_title">Dienst automatisch aanvullen</string>
|
||||||
<string name="autofill_explanation_summary">Schakel de dienst in om formulieren in andere apps in te vullen</string>
|
<string name="autofill_explanation_summary">Schakel de dienst in om formulieren in andere apps in te vullen</string>
|
||||||
<string name="password_size_title">Gegenereerde wachtwoordlengte</string>
|
<string name="password_size_title">Gegenereerde wachtwoordlengte</string>
|
||||||
<string name="password_size_summary">Stel de standaardlengte van gegenereerde wachtwoorden in</string>
|
<string name="password_size_summary">Stel de standaardlengte van gegenereerde wachtwoorden in</string>
|
||||||
|
|||||||
@@ -266,7 +266,7 @@
|
|||||||
<string name="lock_database_back_root_title">ਲਾਕ ਕਰਨ ਲਈ \'ਪਿੱਛੇ\' ਨੂੰ ਦਬਾਓ</string>
|
<string name="lock_database_back_root_title">ਲਾਕ ਕਰਨ ਲਈ \'ਪਿੱਛੇ\' ਨੂੰ ਦਬਾਓ</string>
|
||||||
<string name="lock_database_screen_off_summary">ਜਦੋਂ ਸਕਰੀਨ ਬੰਦ ਹੋ ਜਾਵੇ ਤਾਂ ਡਾਟਾਬੇਸ ਨੂੰ ਲਾਕ ਕਰੋ</string>
|
<string name="lock_database_screen_off_summary">ਜਦੋਂ ਸਕਰੀਨ ਬੰਦ ਹੋ ਜਾਵੇ ਤਾਂ ਡਾਟਾਬੇਸ ਨੂੰ ਲਾਕ ਕਰੋ</string>
|
||||||
<string name="clipboard_notifications_title">ਕਲਿੱਪਬੋਰਡ ਨੋਟੀਫਿਕੇਸ਼ਨ</string>
|
<string name="clipboard_notifications_title">ਕਲਿੱਪਬੋਰਡ ਨੋਟੀਫਿਕੇਸ਼ਨ</string>
|
||||||
<string name="set_autofill_service_title">ਮੂਲ ਆਪੇ-ਭਰਨ ਸੇਵਾ ਵਜੋਂ ਸੈੱਟ ਕਰੋ</string>
|
<string name="set_credential_provider_service_title">ਮੂਲ ਆਪੇ-ਭਰਨ ਸੇਵਾ ਵਜੋਂ ਸੈੱਟ ਕਰੋ</string>
|
||||||
<string name="configure_biometric">ਕੋਈ ਬਾਇਓਮੈਟਰਿਕ ਜਾਂ ਡਿਵਾਈਸ ਸਨਦ ਦਾਖਲ ਨਹੀਂ ਕੀਤੀ ਹੈ।</string>
|
<string name="configure_biometric">ਕੋਈ ਬਾਇਓਮੈਟਰਿਕ ਜਾਂ ਡਿਵਾਈਸ ਸਨਦ ਦਾਖਲ ਨਹੀਂ ਕੀਤੀ ਹੈ।</string>
|
||||||
<string name="warning_sure_remove_data">ਇਹ ਡਾਟਾ ਕਿਵੇਂ ਵੀ ਹਟਾਉਣਾ ਹੈ\?</string>
|
<string name="warning_sure_remove_data">ਇਹ ਡਾਟਾ ਕਿਵੇਂ ਵੀ ਹਟਾਉਣਾ ਹੈ\?</string>
|
||||||
<string name="warning_sure_add_file">ਕਿਵੇਂ ਵੀ ਫ਼ਾਇਲ ਜੋੜਨੀ ਹੈ\?</string>
|
<string name="warning_sure_add_file">ਕਿਵੇਂ ਵੀ ਫ਼ਾਇਲ ਜੋੜਨੀ ਹੈ\?</string>
|
||||||
|
|||||||
@@ -182,7 +182,7 @@
|
|||||||
<string name="autofill">Wypełnij automatycznie</string>
|
<string name="autofill">Wypełnij automatycznie</string>
|
||||||
<string name="autofill_service_name">Autouzupełnianie formularzy KeePassDX</string>
|
<string name="autofill_service_name">Autouzupełnianie formularzy KeePassDX</string>
|
||||||
<string name="autofill_sign_in_prompt">Zaloguj się za pomocą KeePassDX</string>
|
<string name="autofill_sign_in_prompt">Zaloguj się za pomocą KeePassDX</string>
|
||||||
<string name="set_autofill_service_title">Ustaw domyślną usługę autouzupełniania</string>
|
<string name="set_credential_provider_service_title">Ustaw domyślną usługę autouzupełniania</string>
|
||||||
<string name="autofill_explanation_summary">Włącz autouzupełnianie, aby móc szybko wypełniać formularze w innych aplikacjach</string>
|
<string name="autofill_explanation_summary">Włącz autouzupełnianie, aby móc szybko wypełniać formularze w innych aplikacjach</string>
|
||||||
<string name="password_size_title">Wygenerowany rozmiar hasła</string>
|
<string name="password_size_title">Wygenerowany rozmiar hasła</string>
|
||||||
<string name="password_size_summary">Ustawia domyślny rozmiar wygenerowanych haseł</string>
|
<string name="password_size_summary">Ustawia domyślny rozmiar wygenerowanych haseł</string>
|
||||||
|
|||||||
@@ -180,7 +180,7 @@
|
|||||||
<string name="autofill">Preenchimento automático</string>
|
<string name="autofill">Preenchimento automático</string>
|
||||||
<string name="autofill_service_name">Preenchimento automático do KeePassDX</string>
|
<string name="autofill_service_name">Preenchimento automático do KeePassDX</string>
|
||||||
<string name="autofill_sign_in_prompt">Entre com o KeePassDX</string>
|
<string name="autofill_sign_in_prompt">Entre com o KeePassDX</string>
|
||||||
<string name="set_autofill_service_title">Definir serviço padrão de preenchimento automático</string>
|
<string name="set_credential_provider_service_title">Definir serviço padrão de preenchimento automático</string>
|
||||||
<string name="autofill_explanation_summary">Habilite o serviço para rapidamente preencher formulários em outros aplicativos</string>
|
<string name="autofill_explanation_summary">Habilite o serviço para rapidamente preencher formulários em outros aplicativos</string>
|
||||||
<string name="password_size_title">Comprimento da senha gerada</string>
|
<string name="password_size_title">Comprimento da senha gerada</string>
|
||||||
<string name="password_size_summary">Define o tamanho padrão para senhas geradas</string>
|
<string name="password_size_summary">Define o tamanho padrão para senhas geradas</string>
|
||||||
|
|||||||
@@ -179,7 +179,7 @@
|
|||||||
<string name="autofill">Preenchimento automático</string>
|
<string name="autofill">Preenchimento automático</string>
|
||||||
<string name="autofill_service_name">Serviço de preenchimento automático do KeePassDX</string>
|
<string name="autofill_service_name">Serviço de preenchimento automático do KeePassDX</string>
|
||||||
<string name="autofill_sign_in_prompt">Iniciar sessão com KeePassDX</string>
|
<string name="autofill_sign_in_prompt">Iniciar sessão com KeePassDX</string>
|
||||||
<string name="set_autofill_service_title">Definir como serviço de preenchimento automático predefinido</string>
|
<string name="set_credential_provider_service_title">Definir como serviço de preenchimento automático predefinido</string>
|
||||||
<string name="autofill_explanation_summary">Ative o serviço de preencher automático para preencher formulários noutras aplicações</string>
|
<string name="autofill_explanation_summary">Ative o serviço de preencher automático para preencher formulários noutras aplicações</string>
|
||||||
<string name="password_size_title">Tamanho da palavra-passe gerada</string>
|
<string name="password_size_title">Tamanho da palavra-passe gerada</string>
|
||||||
<string name="edit_entry">Editar entrada</string>
|
<string name="edit_entry">Editar entrada</string>
|
||||||
|
|||||||
@@ -91,7 +91,7 @@
|
|||||||
<string name="list_password_generator_options_title">Caracteres das palavras-passe</string>
|
<string name="list_password_generator_options_title">Caracteres das palavras-passe</string>
|
||||||
<string name="password_size_summary">Define o tamanho predefinido para as palavras-passe geradas</string>
|
<string name="password_size_summary">Define o tamanho predefinido para as palavras-passe geradas</string>
|
||||||
<string name="password_size_title">Tamanho da palavra-passe gerada</string>
|
<string name="password_size_title">Tamanho da palavra-passe gerada</string>
|
||||||
<string name="set_autofill_service_title">Definir como serviço de preenchimento automático predefinido</string>
|
<string name="set_credential_provider_service_title">Definir como serviço de preenchimento automático predefinido</string>
|
||||||
<string name="autofill_sign_in_prompt">Iniciar sessão com KeePassDX</string>
|
<string name="autofill_sign_in_prompt">Iniciar sessão com KeePassDX</string>
|
||||||
<string name="autofill_service_name">Serviço de preenchimento automático do KeePassDX</string>
|
<string name="autofill_service_name">Serviço de preenchimento automático do KeePassDX</string>
|
||||||
<string name="autofill">Preenchimento automático</string>
|
<string name="autofill">Preenchimento automático</string>
|
||||||
|
|||||||
@@ -240,7 +240,7 @@
|
|||||||
<string name="autofill_service_name">Completarea automată cu KeePassDX</string>
|
<string name="autofill_service_name">Completarea automată cu KeePassDX</string>
|
||||||
<string name="autofill_sign_in_prompt">Conectați-vă cu KeePassDX</string>
|
<string name="autofill_sign_in_prompt">Conectați-vă cu KeePassDX</string>
|
||||||
<string name="autofill_explanation_summary">Activați completarea automată pentru a completa rapid formulare în alte aplicații</string>
|
<string name="autofill_explanation_summary">Activați completarea automată pentru a completa rapid formulare în alte aplicații</string>
|
||||||
<string name="set_autofill_service_title">Setați serviciul implicit de autocompletare</string>
|
<string name="set_credential_provider_service_title">Setați serviciul implicit de autocompletare</string>
|
||||||
<string name="password_size_title">Dimensiunea parolei generate</string>
|
<string name="password_size_title">Dimensiunea parolei generate</string>
|
||||||
<string name="password_size_summary">Setează dimensiunea implicită a parolelor generate</string>
|
<string name="password_size_summary">Setează dimensiunea implicită a parolelor generate</string>
|
||||||
<string name="list_password_generator_options_title">Caractere parolă</string>
|
<string name="list_password_generator_options_title">Caractere parolă</string>
|
||||||
|
|||||||
@@ -184,7 +184,7 @@
|
|||||||
<string name="autofill_service_name">Служба автозаполнения KeePassDX</string>
|
<string name="autofill_service_name">Служба автозаполнения KeePassDX</string>
|
||||||
<string name="autofill_sign_in_prompt">Войти с помощью KeePassDX</string>
|
<string name="autofill_sign_in_prompt">Войти с помощью KeePassDX</string>
|
||||||
<string name="autofill_explanation_summary">Включите службу для быстрого заполнения форм в других приложениях</string>
|
<string name="autofill_explanation_summary">Включите службу для быстрого заполнения форм в других приложениях</string>
|
||||||
<string name="set_autofill_service_title">Использовать службу автозаполнения</string>
|
<string name="set_credential_provider_service_title">Использовать службу автозаполнения</string>
|
||||||
<string name="password_size_title">Длина создаваемого пароля</string>
|
<string name="password_size_title">Длина создаваемого пароля</string>
|
||||||
<string name="password_size_summary">Настройка длины создаваемых паролей по умолчанию</string>
|
<string name="password_size_summary">Настройка длины создаваемых паролей по умолчанию</string>
|
||||||
<string name="list_password_generator_options_title">Символы пароля</string>
|
<string name="list_password_generator_options_title">Символы пароля</string>
|
||||||
|
|||||||
@@ -595,7 +595,7 @@
|
|||||||
<string name="properties">Vlastnosti</string>
|
<string name="properties">Vlastnosti</string>
|
||||||
<string name="menu_appearance_settings">Vzhľad</string>
|
<string name="menu_appearance_settings">Vzhľad</string>
|
||||||
<string name="autofill_explanation_summary">Povoľte automatické dopĺňanie na rýchle vyplnenie formulárov v iných aplikáciách</string>
|
<string name="autofill_explanation_summary">Povoľte automatické dopĺňanie na rýchle vyplnenie formulárov v iných aplikáciách</string>
|
||||||
<string name="set_autofill_service_title">Nastavte predvolenú službu automatického dopĺňania</string>
|
<string name="set_credential_provider_service_title">Nastavte predvolenú službu automatického dopĺňania</string>
|
||||||
<string name="list_password_generator_options_summary">Nastavte povolené znaky generátora hesiel</string>
|
<string name="list_password_generator_options_summary">Nastavte povolené znaky generátora hesiel</string>
|
||||||
<string name="biometric_unlock_enable_summary">Umožňuje vám skenovať biometrické údaje a otvoriť databázu</string>
|
<string name="biometric_unlock_enable_summary">Umožňuje vám skenovať biometrické údaje a otvoriť databázu</string>
|
||||||
<string name="max_history_items_title">Maximálny počet</string>
|
<string name="max_history_items_title">Maximálny počet</string>
|
||||||
|
|||||||
@@ -570,7 +570,7 @@
|
|||||||
<string name="style_brightness_summary">Përzgjidhni tema të çelëta ose të errëta</string>
|
<string name="style_brightness_summary">Përzgjidhni tema të çelëta ose të errëta</string>
|
||||||
<string name="icon_pack_choose_summary">Paketë ikonash të përdorura te aplikacioni</string>
|
<string name="icon_pack_choose_summary">Paketë ikonash të përdorura te aplikacioni</string>
|
||||||
<string name="hide_expired_entries_summary">Zërat e skaduar nuk shfaqen</string>
|
<string name="hide_expired_entries_summary">Zërat e skaduar nuk shfaqen</string>
|
||||||
<string name="set_autofill_service_title">Caktoni shërbim parazgjedhje vetëplotësimesh</string>
|
<string name="set_credential_provider_service_title">Caktoni shërbim parazgjedhje vetëplotësimesh</string>
|
||||||
<string name="autofill_explanation_summary">Aktivizoni vetëplotësimet, për të plotësuar shpejt formularë në aplikacione të tjerë</string>
|
<string name="autofill_explanation_summary">Aktivizoni vetëplotësimet, për të plotësuar shpejt formularë në aplikacione të tjerë</string>
|
||||||
<string name="autofill_preference_title">Rregullime vetëplotësimi</string>
|
<string name="autofill_preference_title">Rregullime vetëplotësimi</string>
|
||||||
<string name="password_size_summary">Cakton madhësinë parazgjedhje për fjalëkalimet e prodhuar</string>
|
<string name="password_size_summary">Cakton madhësinë parazgjedhje për fjalëkalimet e prodhuar</string>
|
||||||
|
|||||||
@@ -189,7 +189,7 @@
|
|||||||
<string name="autofill">Autofyll</string>
|
<string name="autofill">Autofyll</string>
|
||||||
<string name="autofill_service_name">KeePassDX autofyll formulär</string>
|
<string name="autofill_service_name">KeePassDX autofyll formulär</string>
|
||||||
<string name="autofill_sign_in_prompt">Logga in med KeePassDX</string>
|
<string name="autofill_sign_in_prompt">Logga in med KeePassDX</string>
|
||||||
<string name="set_autofill_service_title">Välj standardtjänst för autofyll</string>
|
<string name="set_credential_provider_service_title">Välj standardtjänst för autofyll</string>
|
||||||
<string name="password_size_title">Längd på genererat lösenord</string>
|
<string name="password_size_title">Längd på genererat lösenord</string>
|
||||||
<string name="password_size_summary">Anger standardlängden för de genererade lösenorden</string>
|
<string name="password_size_summary">Anger standardlängden för de genererade lösenorden</string>
|
||||||
<string name="list_password_generator_options_title">Lösenordstecken</string>
|
<string name="list_password_generator_options_title">Lösenordstecken</string>
|
||||||
|
|||||||
@@ -73,7 +73,7 @@
|
|||||||
<string name="biometric_security_update_required">பயோமெட்ரிக் பாதுகாப்பு புதுப்பிப்பு தேவை.</string>
|
<string name="biometric_security_update_required">பயோமெட்ரிக் பாதுகாப்பு புதுப்பிப்பு தேவை.</string>
|
||||||
<string name="keystore_not_accessible">கீச்டோர் சரியாக துவக்கப்படவில்லை.</string>
|
<string name="keystore_not_accessible">கீச்டோர் சரியாக துவக்கப்படவில்லை.</string>
|
||||||
<string name="menu_appearance_settings">தோற்றம்</string>
|
<string name="menu_appearance_settings">தோற்றம்</string>
|
||||||
<string name="set_autofill_service_title">இயல்புநிலை ஆட்டோஃபில் சேவையை அமைக்கவும்</string>
|
<string name="set_credential_provider_service_title">இயல்புநிலை ஆட்டோஃபில் சேவையை அமைக்கவும்</string>
|
||||||
<string name="autofill_preference_title">ஆட்டோஃபில் அமைப்புகள்</string>
|
<string name="autofill_preference_title">ஆட்டோஃபில் அமைப்புகள்</string>
|
||||||
<string name="lock_database_screen_off_title">திரை பூட்டு</string>
|
<string name="lock_database_screen_off_title">திரை பூட்டு</string>
|
||||||
<string name="content">உள்ளடக்கம்</string>
|
<string name="content">உள்ளடக்கம்</string>
|
||||||
|
|||||||
@@ -529,7 +529,7 @@
|
|||||||
<string name="database_history">ประวัติ</string>
|
<string name="database_history">ประวัติ</string>
|
||||||
<string name="import_app_properties_summary">เลือกไฟล์ที่จะนําเข้าการตั้งค่าของแอป</string>
|
<string name="import_app_properties_summary">เลือกไฟล์ที่จะนําเข้าการตั้งค่าของแอป</string>
|
||||||
<string name="success_import_app_properties">นำเข้าการตั้งค่าแอปแล้ว</string>
|
<string name="success_import_app_properties">นำเข้าการตั้งค่าแอปแล้ว</string>
|
||||||
<string name="set_autofill_service_title">ตั่งค่าเป็นบริการกรอกข้อมูลอัตโนมัติเรื่มต้น</string>
|
<string name="set_credential_provider_service_title">ตั่งค่าเป็นบริการกรอกข้อมูลอัตโนมัติเรื่มต้น</string>
|
||||||
<string name="error_export_app_properties">เกิดข้อผิดพลาดระหว่างการส่งออกการตั้งค่าของแอป</string>
|
<string name="error_export_app_properties">เกิดข้อผิดพลาดระหว่างการส่งออกการตั้งค่าของแอป</string>
|
||||||
<string name="menu_appearance_settings">ลักษณะ</string>
|
<string name="menu_appearance_settings">ลักษณะ</string>
|
||||||
<string name="biometric">ไบโอเมตริก</string>
|
<string name="biometric">ไบโอเมตริก</string>
|
||||||
|
|||||||
@@ -176,7 +176,7 @@
|
|||||||
<string name="autofill">Otomatik Doldurma</string>
|
<string name="autofill">Otomatik Doldurma</string>
|
||||||
<string name="autofill_service_name">KeePassDX formu otomatik doldurma</string>
|
<string name="autofill_service_name">KeePassDX formu otomatik doldurma</string>
|
||||||
<string name="autofill_sign_in_prompt">KeePassDX ile giriş yap</string>
|
<string name="autofill_sign_in_prompt">KeePassDX ile giriş yap</string>
|
||||||
<string name="set_autofill_service_title">Öntanımlı otomatik doldurma hizmetini ayarla</string>
|
<string name="set_credential_provider_service_title">Öntanımlı otomatik doldurma hizmetini ayarla</string>
|
||||||
<string name="autofill_explanation_summary">Diğer uygulamalardaki formları hızlı doldurmak için otomatik doldurmayı etkinleştirin</string>
|
<string name="autofill_explanation_summary">Diğer uygulamalardaki formları hızlı doldurmak için otomatik doldurmayı etkinleştirin</string>
|
||||||
<string name="password_size_title">Oluşturulan parola boyutu</string>
|
<string name="password_size_title">Oluşturulan parola boyutu</string>
|
||||||
<string name="password_size_summary">Oluşturulan parolaların öntanımlı boyutunu ayarlar</string>
|
<string name="password_size_summary">Oluşturulan parolaların öntanımlı boyutunu ayarlar</string>
|
||||||
|
|||||||
@@ -394,7 +394,7 @@
|
|||||||
<string name="password_size_summary">Встановити типову довжину створюваних паролів</string>
|
<string name="password_size_summary">Встановити типову довжину створюваних паролів</string>
|
||||||
<string name="password_size_title">Довжина створюваного пароля</string>
|
<string name="password_size_title">Довжина створюваного пароля</string>
|
||||||
<string name="autofill_preference_title">Налаштування автозаповнення</string>
|
<string name="autofill_preference_title">Налаштування автозаповнення</string>
|
||||||
<string name="set_autofill_service_title">Встановити типовою службою автозаповнення</string>
|
<string name="set_credential_provider_service_title">Встановити типовою службою автозаповнення</string>
|
||||||
<string name="autofill_explanation_summary">Увімкнути автозаповнення для швидкого заповнення форм в інших застосунках</string>
|
<string name="autofill_explanation_summary">Увімкнути автозаповнення для швидкого заповнення форм в інших застосунках</string>
|
||||||
<string name="autofill_sign_in_prompt">Увійти за допомогою KeePassDX</string>
|
<string name="autofill_sign_in_prompt">Увійти за допомогою KeePassDX</string>
|
||||||
<string name="autofill_service_name">Автозаповнення форм KeePassDX</string>
|
<string name="autofill_service_name">Автозаповнення форм KeePassDX</string>
|
||||||
|
|||||||
@@ -415,7 +415,7 @@
|
|||||||
<string name="autofill_sign_in_prompt">Đăng nhập bằng KeePassDX</string>
|
<string name="autofill_sign_in_prompt">Đăng nhập bằng KeePassDX</string>
|
||||||
<string name="autofill_explanation_summary">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</string>
|
<string name="autofill_explanation_summary">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</string>
|
||||||
<string name="autofill_select_entry">Chọn mục…</string>
|
<string name="autofill_select_entry">Chọn mục…</string>
|
||||||
<string name="set_autofill_service_title">Đặt dịch vụ tự động điền mặc định</string>
|
<string name="set_credential_provider_service_title">Đặt dịch vụ tự động điền mặc định</string>
|
||||||
<string name="autofill_preference_title">Thiết đặt tự động điền</string>
|
<string name="autofill_preference_title">Thiết đặt tự động điền</string>
|
||||||
<string name="password_size_title">Kích thước mật khẩu đã tạo</string>
|
<string name="password_size_title">Kích thước mật khẩu đã tạo</string>
|
||||||
<string name="password_size_summary">Đặt kích thước mặc định của mật khẩu được tạo</string>
|
<string name="password_size_summary">Đặt kích thước mặc định của mật khẩu được tạo</string>
|
||||||
|
|||||||
@@ -206,7 +206,7 @@
|
|||||||
<string name="build_label">构建 %1$s</string>
|
<string name="build_label">构建 %1$s</string>
|
||||||
<string name="encrypted_value_stored">加密密码已保存</string>
|
<string name="encrypted_value_stored">加密密码已保存</string>
|
||||||
<string name="unavailable">不可用</string>
|
<string name="unavailable">不可用</string>
|
||||||
<string name="set_autofill_service_title">设为默认自动填充服务</string>
|
<string name="set_credential_provider_service_title">设为默认自动填充服务</string>
|
||||||
<string name="autofill_explanation_summary">启用自动填充功能,以快速填写其他应用中的表单</string>
|
<string name="autofill_explanation_summary">启用自动填充功能,以快速填写其他应用中的表单</string>
|
||||||
<string name="password_size_title">密码生成长度</string>
|
<string name="password_size_title">密码生成长度</string>
|
||||||
<string name="password_size_summary">设置生成密码的默认长度</string>
|
<string name="password_size_summary">设置生成密码的默认长度</string>
|
||||||
|
|||||||
@@ -501,7 +501,7 @@
|
|||||||
<string name="select_entry">選擇條目</string>
|
<string name="select_entry">選擇條目</string>
|
||||||
<string name="select_to_copy">複製%1$s到剪貼簿</string>
|
<string name="select_to_copy">複製%1$s到剪貼簿</string>
|
||||||
<string name="selection_mode">選擇模式</string>
|
<string name="selection_mode">選擇模式</string>
|
||||||
<string name="set_autofill_service_title">設置為預設的填充服務</string>
|
<string name="set_credential_provider_service_title">設置為預設的填充服務</string>
|
||||||
<string name="settings">設定</string>
|
<string name="settings">設定</string>
|
||||||
<string name="settings_database_force_changing_master_key_next_time_summary">下次強制更改主密鑰(一次)</string>
|
<string name="settings_database_force_changing_master_key_next_time_summary">下次強制更改主密鑰(一次)</string>
|
||||||
<string name="settings_database_force_changing_master_key_next_time_title">下次強制更換</string>
|
<string name="settings_database_force_changing_master_key_next_time_title">下次強制更換</string>
|
||||||
|
|||||||
@@ -126,11 +126,14 @@
|
|||||||
<bool name="clear_clipboard_notification_default" translatable="false">false</bool>
|
<bool name="clear_clipboard_notification_default" translatable="false">false</bool>
|
||||||
<string name="clipboard_timeout_key" translatable="false">clip_timeout_key</string>
|
<string name="clipboard_timeout_key" translatable="false">clip_timeout_key</string>
|
||||||
<string name="clipboard_timeout_default" translatable="false">20000</string>
|
<string name="clipboard_timeout_default" translatable="false">20000</string>
|
||||||
<string name="autofill_key" translatable="false">autofill_key</string>
|
<string name="credential_provider_key" translatable="false">credential_provider_key</string>
|
||||||
|
<string name="settings_credential_provider_enable_key" translatable="false">settings_credential_provider_enable_key</string>
|
||||||
|
<bool name="settings_credential_provider_enable_default" translatable="false">false</bool>
|
||||||
<string name="autofill_explanation_key" translatable="false">autofill_explanation_key</string>
|
<string name="autofill_explanation_key" translatable="false">autofill_explanation_key</string>
|
||||||
<string name="settings_autofill_enable_key" translatable="false">settings_autofill_enable_key</string>
|
|
||||||
<bool name="settings_autofill_enable_default" translatable="false">false</bool>
|
|
||||||
<string name="settings_autofill_key" translatable="false">settings_autofill_key</string>
|
<string name="settings_autofill_key" translatable="false">settings_autofill_key</string>
|
||||||
|
<string name="passkeys_explanation_key" translatable="false">passkeys_explanation_key</string>
|
||||||
|
<string name="settings_passkeys_key" translatable="false">settings_passkeys_key</string>
|
||||||
|
<string name="passkeys_privileged_apps_key" translatable="false">passkeys_privileged_apps_key</string>
|
||||||
<string name="keyboard_notification_entry_key" translatable="false">keyboard_notification_entry_key</string>
|
<string name="keyboard_notification_entry_key" translatable="false">keyboard_notification_entry_key</string>
|
||||||
<bool name="keyboard_notification_entry_default" translatable="false">true</bool>
|
<bool name="keyboard_notification_entry_default" translatable="false">true</bool>
|
||||||
<string name="keyboard_notification_entry_clear_close_key" translatable="false">keyboard_notification_entry_clear_close_key</string>
|
<string name="keyboard_notification_entry_clear_close_key" translatable="false">keyboard_notification_entry_clear_close_key</string>
|
||||||
|
|||||||
@@ -417,12 +417,19 @@
|
|||||||
<string name="biometric">Biometric</string>
|
<string name="biometric">Biometric</string>
|
||||||
<string name="device_credential">Device credential</string>
|
<string name="device_credential">Device credential</string>
|
||||||
<string name="general">General</string>
|
<string name="general">General</string>
|
||||||
|
<string name="credential_provider">Credential provider</string>
|
||||||
|
<string name="set_credential_provider_service_title">Credential provider service</string>
|
||||||
|
<string name="passkeys">Passkeys</string>
|
||||||
|
<string name="passkeys_explanation_summary">Configure Passkeys for fast and secure passwordless login</string>
|
||||||
|
<string name="passkeys_preference_title">Passkeys settings</string>
|
||||||
|
<string name="passkeys_privileged_apps_title">Privileged apps</string>
|
||||||
|
<string name="passkeys_privileged_apps_summary">Add a browser to the list of privileged apps</string>
|
||||||
|
<string name="passkeys_privileged_apps_explanation">Select an app to add to the list of privileged apps</string>
|
||||||
<string name="autofill">Autofill</string>
|
<string name="autofill">Autofill</string>
|
||||||
<string name="autofill_service_name">KeePassDX form autofilling</string>
|
<string name="autofill_service_name">KeePassDX form autofilling</string>
|
||||||
<string name="autofill_sign_in_prompt">Sign in with KeePassDX</string>
|
<string name="autofill_sign_in_prompt">Sign in with KeePassDX</string>
|
||||||
<string name="autofill_explanation_summary">Enable autofilling to quickly fill out forms in other apps</string>
|
<string name="autofill_explanation_summary">Configure autofilling to quickly fill out forms in other apps</string>
|
||||||
<string name="autofill_select_entry">Select entry…</string>
|
<string name="autofill_select_entry">Select entry…</string>
|
||||||
<string name="set_autofill_service_title">Set default autofill service</string>
|
|
||||||
<string name="autofill_preference_title">Autofill settings</string>
|
<string name="autofill_preference_title">Autofill settings</string>
|
||||||
<string name="password_size_title">Generated password size</string>
|
<string name="password_size_title">Generated password size</string>
|
||||||
<string name="password_size_summary">Sets default size of the generated passwords</string>
|
<string name="password_size_summary">Sets default size of the generated passwords</string>
|
||||||
|
|||||||
@@ -34,16 +34,23 @@
|
|||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:key="@string/autofill_key"
|
android:key="@string/credential_provider_key"
|
||||||
android:title="@string/autofill">
|
android:title="@string/credential_provider">
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
android:key="@string/settings_credential_provider_enable_key"
|
||||||
|
android:title="@string/set_credential_provider_service_title"
|
||||||
|
android:defaultValue="@bool/settings_credential_provider_enable_default"/>
|
||||||
|
<Preference
|
||||||
|
android:key="@string/passkeys_explanation_key"
|
||||||
|
android:icon="@drawable/prefs_info_24dp"
|
||||||
|
android:summary="@string/passkeys_explanation_summary"/>
|
||||||
|
<Preference
|
||||||
|
android:key="@string/settings_passkeys_key"
|
||||||
|
android:title="@string/passkeys_preference_title" />
|
||||||
<Preference
|
<Preference
|
||||||
android:key="@string/autofill_explanation_key"
|
android:key="@string/autofill_explanation_key"
|
||||||
android:icon="@drawable/prefs_info_24dp"
|
android:icon="@drawable/prefs_info_24dp"
|
||||||
android:summary="@string/autofill_explanation_summary"/>
|
android:summary="@string/autofill_explanation_summary"/>
|
||||||
<SwitchPreferenceCompat
|
|
||||||
android:key="@string/settings_autofill_enable_key"
|
|
||||||
android:title="@string/set_autofill_service_title"
|
|
||||||
android:defaultValue="@bool/settings_autofill_enable_default"/>
|
|
||||||
<Preference
|
<Preference
|
||||||
android:key="@string/settings_autofill_key"
|
android:key="@string/settings_autofill_key"
|
||||||
android:title="@string/autofill_preference_title" />
|
android:title="@string/autofill_preference_title" />
|
||||||
|
|||||||
53
app/src/main/res/xml/preferences_passkeys.xml
Normal file
53
app/src/main/res/xml/preferences_passkeys.xml
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright 2020 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 <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<PreferenceCategory
|
||||||
|
android:title="@string/general">
|
||||||
|
<com.kunzisoft.keepass.settings.preference.DialogListExplanationPreference
|
||||||
|
android:key="@string/passkeys_privileged_apps_key"
|
||||||
|
android:title="@string/passkeys_privileged_apps_title"
|
||||||
|
android:summary="@string/passkeys_privileged_apps_summary"/>
|
||||||
|
<!--
|
||||||
|
// TODO Backup state #2135
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
android:key="@string/passkeys_backup_state_key"
|
||||||
|
android:title="@string/passkeys_backup_state_title"
|
||||||
|
android:summary="@string/passkeys_backup_state_summary"
|
||||||
|
android:defaultValue="@bool/passkeys_backup_state_default"/>
|
||||||
|
-->
|
||||||
|
</PreferenceCategory>
|
||||||
|
<!--
|
||||||
|
// TODO Passkeys default group #2123
|
||||||
|
<PreferenceCategory
|
||||||
|
android:title="@string/save">
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
android:key="@string/passkeys_default_group_creation_key"
|
||||||
|
android:persistent="false"
|
||||||
|
android:title="@string/passkeys_default_group_creation_title"
|
||||||
|
android:summary="@string/passkeys_default_group_creation_summary"
|
||||||
|
android:enabled="false"/>
|
||||||
|
<com.kunzisoft.keepass.settings.preference.DialogListExplanationPreference
|
||||||
|
android:key="@string/passkeys_group_creation_key"
|
||||||
|
android:persistent="false"
|
||||||
|
android:title="@string/passkeys_default_group_creation_title"
|
||||||
|
android:enabled="false"/>
|
||||||
|
</PreferenceCategory>
|
||||||
|
-->
|
||||||
|
</PreferenceScreen>
|
||||||
@@ -119,6 +119,10 @@ data class AndroidOrigin(
|
|||||||
}
|
}
|
||||||
return "android:apk-key-hash:${fingerprintToUrlSafeBase64(fingerprint)}"
|
return "android:apk-key-hash:${fingerprintToUrlSafeBase64(fingerprint)}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "$packageName (${fingerprint})"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
@@ -134,6 +138,10 @@ data class WebOrigin(
|
|||||||
return "${origin}/.well-known/assetlinks.json"
|
return "${origin}/.well-known/assetlinks.json"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return origin
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val RELYING_PARTY_DEFAULT_PROTOCOL = "https"
|
const val RELYING_PARTY_DEFAULT_PROTOCOL = "https"
|
||||||
fun fromRelyingParty(relyingParty: String): WebOrigin = WebOrigin(
|
fun fromRelyingParty(relyingParty: String): WebOrigin = WebOrigin(
|
||||||
|
|||||||
Reference in New Issue
Block a user