fix: User Verification dialog #2283

This commit is contained in:
J-Jamet
2025-12-02 10:06:00 +01:00
parent 17d4c363ac
commit d28087d8d8
5 changed files with 28 additions and 9 deletions

View File

@@ -21,11 +21,13 @@ package com.kunzisoft.keepass.activities.dialogs
import android.app.Dialog import android.app.Dialog
import android.os.Bundle import android.os.Bundle
import android.text.InputFilter
import android.view.View import android.view.View
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.MasterCredential
import com.kunzisoft.keepass.utils.UriUtil.openUrl import com.kunzisoft.keepass.utils.UriUtil.openUrl
import com.kunzisoft.keepass.viewmodels.UserVerificationViewModel import com.kunzisoft.keepass.viewmodels.UserVerificationViewModel
@@ -39,12 +41,14 @@ class CheckDatabaseCredentialDialogFragment : DatabaseDialogFragment() {
val builder = AlertDialog.Builder(activity) val builder = AlertDialog.Builder(activity)
val inflater = activity.layoutInflater val inflater = activity.layoutInflater
val rootView = inflater.inflate(R.layout.fragment_check_database_credential, null) val rootView = inflater.inflate(R.layout.fragment_check_database_credential, null)
val editText = rootView.findViewById<TextView>(R.id.setup_check_password_edit_text)
editText.filters = arrayOf<InputFilter>(InputFilter.LengthFilter(
MasterCredential.CHECK_KEY_PASSWORD_LENGTH)
)
builder.setView(rootView) builder.setView(rootView)
.setPositiveButton(R.string.check) { _, _ -> .setPositiveButton(R.string.check) { _, _ ->
userVerificationViewModel.checkMainCredential( userVerificationViewModel.checkMainCredential(
rootView editText.text.toString()
.findViewById<TextView>(R.id.setup_check_password_edit_text)
.text.toString(),
) )
} }
.setNegativeButton(android.R.string.cancel) { _, _ -> .setNegativeButton(android.R.string.cancel) { _, _ ->

View File

@@ -103,6 +103,9 @@ class UserVerificationHelper {
} }
} }
/**
* Displays a dialog to verify the user
*/
fun FragmentActivity.checkUserVerification( fun FragmentActivity.checkUserVerification(
userVerificationViewModel: UserVerificationViewModel, userVerificationViewModel: UserVerificationViewModel,
dataToVerify: UserVerificationData dataToVerify: UserVerificationData
@@ -114,6 +117,9 @@ class UserVerificationHelper {
} }
} }
/**
* Displays a dialog for entering the device credential to be checked
*/
fun FragmentActivity.showUserVerificationDeviceCredential( fun FragmentActivity.showUserVerificationDeviceCredential(
userVerificationViewModel: UserVerificationViewModel, userVerificationViewModel: UserVerificationViewModel,
dataToVerify: UserVerificationData dataToVerify: UserVerificationData
@@ -162,14 +168,22 @@ class UserVerificationHelper {
) )
} }
/**
* Displays a dialog for entering the database credential to be checked
*/
fun FragmentActivity.showUserVerificationDatabaseCredential( fun FragmentActivity.showUserVerificationDatabaseCredential(
userVerificationViewModel: UserVerificationViewModel, userVerificationViewModel: UserVerificationViewModel,
dataToVerify: UserVerificationData dataToVerify: UserVerificationData
) { ) {
userVerificationViewModel.dataToVerify = dataToVerify userVerificationViewModel.dataToVerify = dataToVerify
CheckDatabaseCredentialDialogFragment val fragmentTag = "checkDatabaseCredentialDialog"
.getInstance() var fragment: CheckDatabaseCredentialDialogFragment? =
.show(this.supportFragmentManager, "checkDatabaseCredentialDialog") supportFragmentManager.findFragmentByTag(fragmentTag)
as? CheckDatabaseCredentialDialogFragment?
if (fragment == null) {
fragment = CheckDatabaseCredentialDialogFragment.getInstance()
fragment.show(this.supportFragmentManager, fragmentTag)
}
} }
} }
} }

View File

@@ -79,7 +79,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:focusable="true" android:focusable="true"
android:focusedByDefault="true" android:focusedByDefault="true"
android:maxLength="4"
android:inputType="textPassword" android:inputType="textPassword"
android:importantForAccessibility="no" android:importantForAccessibility="no"
android:importantForAutofill="no" android:importantForAutofill="no"

View File

@@ -777,7 +777,7 @@
<string name="error_passkey_credential_id">No passkey found with relying party %1$s and credentialIds %2$s</string> <string name="error_passkey_credential_id">No passkey found with relying party %1$s and credentialIds %2$s</string>
<string name="content_description_user_verification_information">User verification info</string> <string name="content_description_user_verification_information">User verification info</string>
<string name="user_verification_required_title">User Verification</string> <string name="user_verification_required_title">User Verification</string>
<string name="user_verification_required_description">User verification is required to use and edit passkeys</string> <string name="user_verification_required_description">Access to this data requires verification</string>
<string name="user_verification_database_credential">Enter the first four characters of your database password</string> <string name="user_verification_database_credential">Enter the first four characters of your database password</string>
<string name="first_chars">First chars</string> <string name="first_chars">First chars</string>
<string name="check">Check</string> <string name="check">Check</string>

View File

@@ -102,7 +102,7 @@ data class MasterCredential(
fun getCheckKey(password: String?): ByteArray { fun getCheckKey(password: String?): ByteArray {
return retrievePasswordKey( return retrievePasswordKey(
try { try {
password?.substring(0, 3) ?: "" password?.substring(0, CHECK_KEY_PASSWORD_LENGTH) ?: ""
} catch (_: Exception) { "" }, } catch (_: Exception) { "" },
Charsets.UTF_8 Charsets.UTF_8
) )
@@ -273,5 +273,7 @@ data class MasterCredential(
private const val XML_NODE_KEY_NAME = "Key" private const val XML_NODE_KEY_NAME = "Key"
private const val XML_NODE_DATA_NAME = "Data" private const val XML_NODE_DATA_NAME = "Data"
private const val XML_ATTRIBUTE_DATA_HASH = "Hash" private const val XML_ATTRIBUTE_DATA_HASH = "Hash"
const val CHECK_KEY_PASSWORD_LENGTH = 4
} }
} }