fix: Show toast error in passwordless mode

This commit is contained in:
J-Jamet
2025-11-24 20:35:54 +01:00
parent bc854c63f7
commit b64094ed20
4 changed files with 70 additions and 21 deletions

View File

@@ -73,6 +73,7 @@ import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.retrieveSea
import com.kunzisoft.keepass.credentialprovider.SpecialMode
import com.kunzisoft.keepass.credentialprovider.TypeMode
import com.kunzisoft.keepass.credentialprovider.magikeyboard.MagikeyboardService
import com.kunzisoft.keepass.credentialprovider.passkey.util.PasskeyHelper.buildPasskeyErrorAndSetResult
import com.kunzisoft.keepass.credentialprovider.passkey.util.PasskeyHelper.buildPasskeyResponseAndSetResult
import com.kunzisoft.keepass.database.ContextualDatabase
import com.kunzisoft.keepass.database.MainCredential
@@ -725,6 +726,8 @@ class GroupActivity : DatabaseLockActivity(),
// To get the form filling search as temp search
val searchInfo: SearchInfo? = intent.retrieveSearchInfo()
val autoSearch = intent.getBooleanExtra(AUTO_SEARCH_KEY, false)
// Directly return an error if credentialId is search because it's not found
errorIfNeededForPasskeySelection(searchInfo)
// Get search query
if (searchInfo != null && autoSearch) {
mAutoSearch = true
@@ -946,6 +949,21 @@ class GroupActivity : DatabaseLockActivity(),
onValidateSpecialMode()
}
private fun errorIfNeededForPasskeySelection(searchInfo: SearchInfo?) {
if (mTypeMode == TypeMode.PASSKEY && searchInfo?.credentialId != null) {
removeSearch()
// Build response with the entry selected
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
buildPasskeyErrorAndSetResult(
resources = resources,
relyingPartyId = searchInfo.relyingParty,
credentialId = searchInfo.credentialId
)
}
onValidateSpecialMode()
}
}
private fun entrySelectedForRegistration(
database: ContextualDatabase,
entry: Entry,

View File

@@ -112,10 +112,7 @@ class PasskeyProviderService : CredentialProviderService() {
}
} catch (e: Exception) {
Log.e(javaClass.simpleName, "onBeginGetCredentialRequest error", e)
when (e) {
is IOException -> toastError(e)
else -> {}
}
toastError(e)
callback.onError(GetCredentialUnknownException())
}
}
@@ -184,26 +181,36 @@ class PasskeyProviderService : CredentialProviderService() {
},
onItemNotFound = { _ ->
Log.w(TAG, "No passkey found in the database with this relying party : $relyingPartyId")
Log.d(TAG, "Add pending intent for passkey selection in opened database")
PasskeyLauncherActivity.getPendingIntent(
context = applicationContext,
specialMode = SpecialMode.SELECTION,
searchInfo = searchInfo
)?.let { pendingIntent ->
passkeyEntries.add(
PublicKeyCredentialEntry(
context = applicationContext,
username = getString(R.string.passkey_database_username),
displayName = getString(R.string.passkey_selection_description),
icon = defaultIcon,
pendingIntent = pendingIntent,
beginGetPublicKeyCredentialOption = option,
lastUsedTime = Instant.now(),
isAutoSelectAllowed = isAutoSelectAllowed
if (credentialId == null) {
Log.d(TAG, "Add pending intent for passkey selection in opened database")
PasskeyLauncherActivity.getPendingIntent(
context = applicationContext,
specialMode = SpecialMode.SELECTION,
searchInfo = searchInfo
)?.let { pendingIntent ->
passkeyEntries.add(
PublicKeyCredentialEntry(
context = applicationContext,
username = getString(R.string.passkey_database_username),
displayName = getString(R.string.passkey_selection_description),
icon = defaultIcon,
pendingIntent = pendingIntent,
beginGetPublicKeyCredentialOption = option,
lastUsedTime = Instant.now(),
isAutoSelectAllowed = isAutoSelectAllowed
)
)
}
callback(passkeyEntries)
} else {
throw IOException(
getString(
R.string.error_passkey_credential_id,
relyingPartyId,
credentialId
)
)
}
callback(passkeyEntries)
},
onDatabaseClosed = {
Log.d(TAG, "Add pending intent for passkey selection in closed database")

View File

@@ -22,6 +22,7 @@ package com.kunzisoft.keepass.credentialprovider.passkey.util
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.res.Resources
import android.os.Build
import android.os.Bundle
import android.security.keystore.KeyGenParameterSpec
@@ -200,6 +201,28 @@ object PasskeyHelper {
}
}
/**
* Build the Passkey error response
*/
fun Activity.buildPasskeyErrorAndSetResult(
resources: Resources,
relyingPartyId: String?,
credentialId: String?
) {
val error = resources.getString(
R.string.error_passkey_credential_id,
relyingPartyId,
credentialId
)
Log.e(javaClass.name, error)
Toast.makeText(
this,
error,
Toast.LENGTH_SHORT
).show()
setResult(Activity.RESULT_CANCELED)
}
/**
* Check the timestamp and authentication code transmitted via PendingIntent
*/