mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
fix: Add User Verification for Entry Edition #2283
This commit is contained in:
@@ -41,6 +41,9 @@ import androidx.core.graphics.BlendModeColorFilterCompat
|
||||
import androidx.core.graphics.BlendModeCompat
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
@@ -53,6 +56,8 @@ import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper
|
||||
import com.kunzisoft.keepass.activities.legacy.DatabaseLockActivity
|
||||
import com.kunzisoft.keepass.adapters.TagsAdapter
|
||||
import com.kunzisoft.keepass.credentialprovider.SpecialMode
|
||||
import com.kunzisoft.keepass.credentialprovider.UserVerificationData
|
||||
import com.kunzisoft.keepass.credentialprovider.UserVerificationHelper.Companion.askUserVerification
|
||||
import com.kunzisoft.keepass.credentialprovider.magikeyboard.MagikeyboardService
|
||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||
import com.kunzisoft.keepass.database.element.Attachment
|
||||
@@ -79,6 +84,8 @@ import com.kunzisoft.keepass.view.hideByFading
|
||||
import com.kunzisoft.keepass.view.setTransparentNavigationBar
|
||||
import com.kunzisoft.keepass.view.showActionErrorIfNeeded
|
||||
import com.kunzisoft.keepass.viewmodels.EntryViewModel
|
||||
import com.kunzisoft.keepass.viewmodels.UserVerificationViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.EnumSet
|
||||
import java.util.UUID
|
||||
|
||||
@@ -100,14 +107,10 @@ class EntryActivity : DatabaseLockActivity() {
|
||||
private var loadingView: ProgressBar? = null
|
||||
|
||||
private val mEntryViewModel: EntryViewModel by viewModels()
|
||||
private val mUserVerificationViewModel: UserVerificationViewModel by viewModels()
|
||||
|
||||
private val mEntryActivityEducation = EntryActivityEducation(this)
|
||||
|
||||
private var mMainEntryId: NodeId<UUID>? = null
|
||||
private var mHistoryPosition: Int = -1
|
||||
private var mEntryIsHistory: Boolean = false
|
||||
private var mEntryLoaded = false
|
||||
|
||||
private var mAttachmentFileBinderManager: AttachmentFileBinderManager? = null
|
||||
private var mExternalFileHelper: ExternalFileHelper? = null
|
||||
private var mAttachmentSelected: Attachment? = null
|
||||
@@ -238,13 +241,9 @@ class EntryActivity : DatabaseLockActivity() {
|
||||
|
||||
mEntryViewModel.entryInfoHistory.observe(this) { entryInfoHistory ->
|
||||
if (entryInfoHistory != null) {
|
||||
this.mMainEntryId = entryInfoHistory.mainEntryId
|
||||
|
||||
// Manage history position
|
||||
val historyPosition = entryInfoHistory.historyPosition
|
||||
this.mHistoryPosition = historyPosition
|
||||
val entryIsHistory = historyPosition > -1
|
||||
this.mEntryIsHistory = entryIsHistory
|
||||
// Assign history dedicated view
|
||||
historyView?.visibility = if (entryIsHistory) View.VISIBLE else View.GONE
|
||||
// TODO History badge
|
||||
@@ -279,7 +278,6 @@ class EntryActivity : DatabaseLockActivity() {
|
||||
mForegroundColor = if (showEntryColors) entryInfo.foregroundColor else null
|
||||
|
||||
loadingView?.hideByFading()
|
||||
mEntryLoaded = true
|
||||
} else {
|
||||
finish()
|
||||
}
|
||||
@@ -322,6 +320,33 @@ class EntryActivity : DatabaseLockActivity() {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
lifecycleScope.launch {
|
||||
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
||||
mUserVerificationViewModel.uiState.collect { uIState ->
|
||||
when (uIState) {
|
||||
is UserVerificationViewModel.UIState.Loading -> {}
|
||||
is UserVerificationViewModel.UIState.OnUserVerificationCanceled -> {
|
||||
mUserVerificationViewModel.onUserVerificationReceived()
|
||||
}
|
||||
is UserVerificationViewModel.UIState.OnUserVerificationSucceeded -> {
|
||||
uIState.dataToVerify.database?.let { database ->
|
||||
uIState.dataToVerify.entryId?.let { entryId ->
|
||||
EntryEditActivity.launch(
|
||||
activity = this@EntryActivity,
|
||||
database = database,
|
||||
registrationType = EntryEditActivity.RegistrationType.UPDATE,
|
||||
nodeId = entryId,
|
||||
activityResultLauncher = mEntryActivityResultLauncher
|
||||
)
|
||||
}
|
||||
}
|
||||
mUserVerificationViewModel.onUserVerificationReceived()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun finishActivityIfReloadRequested(): Boolean {
|
||||
@@ -410,13 +435,13 @@ class EntryActivity : DatabaseLockActivity() {
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
super.onCreateOptionsMenu(menu)
|
||||
if (mEntryLoaded) {
|
||||
if (mEntryViewModel.entryLoaded) {
|
||||
val inflater = menuInflater
|
||||
|
||||
inflater.inflate(R.menu.entry, menu)
|
||||
inflater.inflate(R.menu.database, menu)
|
||||
|
||||
if (mEntryIsHistory && !mDatabaseReadOnly) {
|
||||
if (mEntryViewModel.entryIsHistory && !mDatabaseReadOnly) {
|
||||
inflater.inflate(R.menu.entry_history, menu)
|
||||
}
|
||||
|
||||
@@ -429,7 +454,7 @@ class EntryActivity : DatabaseLockActivity() {
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
|
||||
if (mEntryIsHistory || mDatabaseReadOnly) {
|
||||
if (mEntryViewModel.entryIsHistory || mDatabaseReadOnly) {
|
||||
menu?.findItem(R.id.menu_save_database)?.isVisible = false
|
||||
menu?.findItem(R.id.menu_merge_database)?.isVisible = false
|
||||
menu?.findItem(R.id.menu_edit)?.isVisible = false
|
||||
@@ -477,31 +502,27 @@ class EntryActivity : DatabaseLockActivity() {
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
R.id.menu_edit -> {
|
||||
mDatabase?.let { database ->
|
||||
mMainEntryId?.let { entryId ->
|
||||
EntryEditActivity.launch(
|
||||
activity = this,
|
||||
database = database,
|
||||
registrationType = EntryEditActivity.RegistrationType.UPDATE,
|
||||
nodeId = entryId,
|
||||
activityResultLauncher = mEntryActivityResultLauncher
|
||||
)
|
||||
}
|
||||
}
|
||||
askUserVerification(
|
||||
userVerificationViewModel = mUserVerificationViewModel,
|
||||
userVerificationCondition = true,
|
||||
dataToVerify = UserVerificationData(mDatabase, mEntryViewModel.mainEntryId)
|
||||
)
|
||||
return true
|
||||
}
|
||||
R.id.menu_restore_entry_history -> {
|
||||
mMainEntryId?.let { mainEntryId ->
|
||||
mEntryViewModel.mainEntryId?.let { mainEntryId ->
|
||||
restoreEntryHistory(
|
||||
mainEntryId,
|
||||
mHistoryPosition)
|
||||
mEntryViewModel.historyPosition
|
||||
)
|
||||
}
|
||||
}
|
||||
R.id.menu_delete_entry_history -> {
|
||||
mMainEntryId?.let { mainEntryId ->
|
||||
mEntryViewModel.mainEntryId?.let { mainEntryId ->
|
||||
deleteEntryHistory(
|
||||
mainEntryId,
|
||||
mHistoryPosition)
|
||||
mEntryViewModel.historyPosition
|
||||
)
|
||||
}
|
||||
}
|
||||
R.id.menu_save_database -> {
|
||||
@@ -521,7 +542,7 @@ class EntryActivity : DatabaseLockActivity() {
|
||||
override fun finish() {
|
||||
// Transit data in previous Activity after an update
|
||||
Intent().apply {
|
||||
putExtra(EntryEditActivity.ADD_OR_UPDATE_ENTRY_KEY, mMainEntryId)
|
||||
putExtra(EntryEditActivity.ADD_OR_UPDATE_ENTRY_KEY, mEntryViewModel.mainEntryId)
|
||||
setResult(RESULT_OK, this)
|
||||
}
|
||||
super.finish()
|
||||
|
||||
@@ -52,7 +52,9 @@ import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.drawerlayout.widget.DrawerLayout
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.datepicker.MaterialDatePicker
|
||||
import com.google.android.material.timepicker.MaterialTimePicker
|
||||
@@ -73,6 +75,8 @@ import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.removeModes
|
||||
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.retrieveSearchInfo
|
||||
import com.kunzisoft.keepass.credentialprovider.SpecialMode
|
||||
import com.kunzisoft.keepass.credentialprovider.TypeMode
|
||||
import com.kunzisoft.keepass.credentialprovider.UserVerificationData
|
||||
import com.kunzisoft.keepass.credentialprovider.UserVerificationHelper.Companion.askUserVerification
|
||||
import com.kunzisoft.keepass.credentialprovider.magikeyboard.MagikeyboardService
|
||||
import com.kunzisoft.keepass.credentialprovider.passkey.util.PasskeyHelper.buildPasskeyResponseAndSetResult
|
||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||
@@ -122,6 +126,7 @@ import com.kunzisoft.keepass.view.updateLockPaddingStart
|
||||
import com.kunzisoft.keepass.viewmodels.GroupEditViewModel
|
||||
import com.kunzisoft.keepass.viewmodels.GroupViewModel
|
||||
import com.kunzisoft.keepass.viewmodels.MainCredentialViewModel
|
||||
import com.kunzisoft.keepass.viewmodels.UserVerificationViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import org.joda.time.LocalDateTime
|
||||
import java.util.EnumSet
|
||||
@@ -158,6 +163,7 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
private val mGroupViewModel: GroupViewModel by viewModels()
|
||||
private val mGroupEditViewModel: GroupEditViewModel by viewModels()
|
||||
private val mMainCredentialViewModel: MainCredentialViewModel by viewModels()
|
||||
private val mUserVerificationViewModel: UserVerificationViewModel by viewModels()
|
||||
|
||||
private val mGroupActivityEducation = GroupActivityEducation(this)
|
||||
|
||||
@@ -565,6 +571,33 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lifecycleScope.launch {
|
||||
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
||||
mUserVerificationViewModel.uiState.collect { uIState ->
|
||||
when (uIState) {
|
||||
is UserVerificationViewModel.UIState.Loading -> {}
|
||||
is UserVerificationViewModel.UIState.OnUserVerificationCanceled -> {
|
||||
mUserVerificationViewModel.onUserVerificationReceived()
|
||||
}
|
||||
is UserVerificationViewModel.UIState.OnUserVerificationSucceeded -> {
|
||||
uIState.dataToVerify.database?.let { database ->
|
||||
uIState.dataToVerify.entryId?.let { entryId ->
|
||||
EntryEditActivity.launch(
|
||||
activity = this@GroupActivity,
|
||||
database = database,
|
||||
registrationType = EntryEditActivity.RegistrationType.UPDATE,
|
||||
nodeId = entryId,
|
||||
activityResultLauncher = mEntryActivityResultLauncher
|
||||
)
|
||||
}
|
||||
}
|
||||
mUserVerificationViewModel.onUserVerificationReceived()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun viewToInvalidateTimeout(): View? {
|
||||
@@ -1060,12 +1093,10 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
launchDialogForGroupUpdate(node as Group)
|
||||
}
|
||||
Type.ENTRY -> {
|
||||
EntryEditActivity.launch(
|
||||
activity = this@GroupActivity,
|
||||
database = database,
|
||||
registrationType = EntryEditActivity.RegistrationType.UPDATE,
|
||||
nodeId = (node as Entry).nodeId,
|
||||
activityResultLauncher = mEntryActivityResultLauncher
|
||||
askUserVerification(
|
||||
userVerificationViewModel = mUserVerificationViewModel,
|
||||
userVerificationCondition = true,
|
||||
dataToVerify = UserVerificationData(database,node.nodeId)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.kunzisoft.keepass.credentialprovider
|
||||
|
||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||
import com.kunzisoft.keepass.database.element.node.NodeId
|
||||
|
||||
data class UserVerificationData(
|
||||
val database: ContextualDatabase? = null,
|
||||
val entryId: NodeId<*>? = null
|
||||
)
|
||||
@@ -14,7 +14,6 @@ import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.activities.dialogs.MainCredentialDialogFragment
|
||||
import com.kunzisoft.keepass.activities.dialogs.MainCredentialDialogFragment.Companion.TAG_ASK_MAIN_CREDENTIAL
|
||||
import com.kunzisoft.keepass.credentialprovider.passkey.data.UserVerificationRequirement
|
||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||
import com.kunzisoft.keepass.utils.getEnumExtra
|
||||
import com.kunzisoft.keepass.utils.putEnumExtra
|
||||
import com.kunzisoft.keepass.view.toastError
|
||||
@@ -86,12 +85,13 @@ class UserVerificationHelper {
|
||||
* Ask for the database credential otherwise
|
||||
*/
|
||||
fun FragmentActivity.askUserVerification(
|
||||
database: ContextualDatabase?,
|
||||
userVerificationViewModel: UserVerificationViewModel
|
||||
userVerificationViewModel: UserVerificationViewModel,
|
||||
userVerificationCondition: Boolean,
|
||||
dataToVerify: UserVerificationData
|
||||
) {
|
||||
if (this.intent.getUserVerificationCondition()) {
|
||||
if (userVerificationCondition) {
|
||||
// Important to check the nullable database here
|
||||
database?.let {
|
||||
dataToVerify.database?.let {
|
||||
if (isAuthenticatorsAllowed()) {
|
||||
BiometricPrompt(
|
||||
this, ContextCompat.getMainExecutor(this),
|
||||
@@ -113,20 +113,20 @@ class UserVerificationHelper {
|
||||
toastError(SecurityException("Authentication error: $errString"))
|
||||
}
|
||||
}
|
||||
userVerificationViewModel.onUserVerificationFailed(database)
|
||||
userVerificationViewModel.onUserVerificationFailed(dataToVerify)
|
||||
}
|
||||
|
||||
override fun onAuthenticationSucceeded(
|
||||
result: BiometricPrompt.AuthenticationResult
|
||||
) {
|
||||
super.onAuthenticationSucceeded(result)
|
||||
userVerificationViewModel.onUserVerificationSucceeded(database)
|
||||
userVerificationViewModel.onUserVerificationSucceeded(dataToVerify)
|
||||
}
|
||||
|
||||
override fun onAuthenticationFailed() {
|
||||
super.onAuthenticationFailed()
|
||||
toastError(SecurityException(getString(R.string.device_unlock_not_recognized)))
|
||||
userVerificationViewModel.onUserVerificationFailed(database)
|
||||
userVerificationViewModel.onUserVerificationFailed(dataToVerify)
|
||||
}
|
||||
}).authenticate(
|
||||
BiometricPrompt.PromptInfo.Builder()
|
||||
@@ -141,7 +141,7 @@ class UserVerificationHelper {
|
||||
.findFragmentByTag(TAG_ASK_MAIN_CREDENTIAL) as? MainCredentialDialogFragment?
|
||||
if (mainCredentialDialogFragment == null) {
|
||||
mainCredentialDialogFragment = MainCredentialDialogFragment
|
||||
.getInstance(database.fileUri)
|
||||
.getInstance(dataToVerify.database.fileUri)
|
||||
mainCredentialDialogFragment.show(
|
||||
supportFragmentManager,
|
||||
TAG_ASK_MAIN_CREDENTIAL
|
||||
@@ -150,7 +150,7 @@ class UserVerificationHelper {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
userVerificationViewModel.onUserVerificationSucceeded(database)
|
||||
userVerificationViewModel.onUserVerificationSucceeded(dataToVerify)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,9 @@ import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.activity.viewModels
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.activities.FileDatabaseSelectActivity
|
||||
import com.kunzisoft.keepass.activities.GroupActivity
|
||||
@@ -43,6 +45,7 @@ import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.addTypeMode
|
||||
import com.kunzisoft.keepass.credentialprovider.EntrySelectionHelper.setActivityResult
|
||||
import com.kunzisoft.keepass.credentialprovider.SpecialMode
|
||||
import com.kunzisoft.keepass.credentialprovider.TypeMode
|
||||
import com.kunzisoft.keepass.credentialprovider.UserVerificationData
|
||||
import com.kunzisoft.keepass.credentialprovider.UserVerificationHelper.Companion.addUserVerification
|
||||
import com.kunzisoft.keepass.credentialprovider.UserVerificationHelper.Companion.askUserVerification
|
||||
import com.kunzisoft.keepass.credentialprovider.UserVerificationHelper.Companion.getUserVerificationCondition
|
||||
@@ -186,19 +189,23 @@ class PasskeyLauncherActivity : DatabaseLockActivity() {
|
||||
}
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
userVerificationViewModel.uiState.collect { uiState ->
|
||||
when (uiState) {
|
||||
is UserVerificationViewModel.UIState.Loading -> {}
|
||||
is UserVerificationViewModel.UIState.OnUserVerificationSucceeded -> {
|
||||
passkeyLauncherViewModel.launchActionIfNeeded(
|
||||
userVerified = true,
|
||||
intent = intent,
|
||||
specialMode = mSpecialMode,
|
||||
database = uiState.database
|
||||
)
|
||||
}
|
||||
is UserVerificationViewModel.UIState.OnUserVerificationCanceled -> {
|
||||
passkeyLauncherViewModel.cancelResult()
|
||||
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
||||
userVerificationViewModel.uiState.collect { uiState ->
|
||||
when (uiState) {
|
||||
is UserVerificationViewModel.UIState.Loading -> {}
|
||||
is UserVerificationViewModel.UIState.OnUserVerificationSucceeded -> {
|
||||
passkeyLauncherViewModel.launchActionIfNeeded(
|
||||
userVerified = true,
|
||||
intent = intent,
|
||||
specialMode = mSpecialMode,
|
||||
database = uiState.dataToVerify.database
|
||||
)
|
||||
userVerificationViewModel.onUserVerificationReceived()
|
||||
}
|
||||
is UserVerificationViewModel.UIState.OnUserVerificationCanceled -> {
|
||||
passkeyLauncherViewModel.cancelResult()
|
||||
userVerificationViewModel.onUserVerificationReceived()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -208,9 +215,11 @@ class PasskeyLauncherActivity : DatabaseLockActivity() {
|
||||
override fun onUnknownDatabaseRetrieved(database: ContextualDatabase?) {
|
||||
super.onUnknownDatabaseRetrieved(database)
|
||||
// To manage https://github.com/Kunzisoft/KeePassDX/issues/2283
|
||||
// When a database is opened
|
||||
askUserVerification(
|
||||
database = database,
|
||||
userVerificationViewModel = userVerificationViewModel
|
||||
userVerificationViewModel = userVerificationViewModel,
|
||||
userVerificationCondition = intent.getUserVerificationCondition(),
|
||||
dataToVerify = UserVerificationData(database)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -227,9 +236,13 @@ class PasskeyLauncherActivity : DatabaseLockActivity() {
|
||||
}
|
||||
ACTION_DATABASE_CHECK_CREDENTIAL_TASK -> {
|
||||
if (result.isSuccess) {
|
||||
userVerificationViewModel.onUserVerificationSucceeded(database)
|
||||
userVerificationViewModel.onUserVerificationSucceeded(
|
||||
UserVerificationData(database)
|
||||
)
|
||||
} else {
|
||||
userVerificationViewModel.onUserVerificationFailed(database)
|
||||
userVerificationViewModel.onUserVerificationFailed(
|
||||
UserVerificationData(database)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,8 +36,14 @@ import java.util.UUID
|
||||
|
||||
class EntryViewModel: ViewModel() {
|
||||
|
||||
private var mMainEntryId: NodeId<UUID>? = null
|
||||
private var mHistoryPosition: Int = -1
|
||||
var mainEntryId: NodeId<UUID>? = null
|
||||
private set
|
||||
var historyPosition: Int = -1
|
||||
private set
|
||||
var entryIsHistory: Boolean = false
|
||||
private set
|
||||
var entryLoaded = false
|
||||
private set
|
||||
|
||||
val entryInfoHistory : LiveData<EntryInfoHistory?> get() = _entryInfoHistory
|
||||
private val _entryInfoHistory = MutableLiveData<EntryInfoHistory?>()
|
||||
@@ -60,12 +66,12 @@ class EntryViewModel: ViewModel() {
|
||||
private val _historySelected = SingleLiveEvent<EntryHistory>()
|
||||
|
||||
fun loadDatabase(database: ContextualDatabase?) {
|
||||
loadEntry(database, mMainEntryId, mHistoryPosition)
|
||||
loadEntry(database, mainEntryId, historyPosition)
|
||||
}
|
||||
|
||||
fun loadEntry(database: ContextualDatabase?, mainEntryId: NodeId<UUID>?, historyPosition: Int = -1) {
|
||||
this.mMainEntryId = mainEntryId
|
||||
this.mHistoryPosition = historyPosition
|
||||
this.mainEntryId = mainEntryId
|
||||
this.historyPosition = historyPosition
|
||||
|
||||
if (database != null && mainEntryId != null) {
|
||||
IOActionTask(
|
||||
@@ -104,6 +110,12 @@ class EntryViewModel: ViewModel() {
|
||||
}
|
||||
},
|
||||
{ entryInfoHistory ->
|
||||
if (entryInfoHistory != null) {
|
||||
this.mainEntryId = entryInfoHistory.mainEntryId
|
||||
this.historyPosition = historyPosition
|
||||
this.entryIsHistory = historyPosition > -1
|
||||
this.entryLoaded = true
|
||||
}
|
||||
_entryInfoHistory.value = entryInfoHistory
|
||||
_entryHistory.value = entryInfoHistory?.entryHistory
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.kunzisoft.keepass.viewmodels
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||
import com.kunzisoft.keepass.credentialprovider.UserVerificationData
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
@@ -13,22 +13,22 @@ class UserVerificationViewModel: ViewModel() {
|
||||
private val mUiState = MutableStateFlow<UIState>(UIState.Loading)
|
||||
val uiState: StateFlow<UIState> = mUiState
|
||||
|
||||
fun onUserVerificationSucceeded(database: ContextualDatabase?) {
|
||||
mUiState.value = UIState.OnUserVerificationSucceeded(database)
|
||||
fun onUserVerificationSucceeded(dataToVerify: UserVerificationData) {
|
||||
mUiState.value = UIState.OnUserVerificationSucceeded(dataToVerify)
|
||||
}
|
||||
|
||||
fun onUserVerificationFailed(database: ContextualDatabase? = null) {
|
||||
mUiState.value = UIState.OnUserVerificationCanceled(database)
|
||||
fun onUserVerificationFailed(dataToVerify: UserVerificationData = UserVerificationData()) {
|
||||
mUiState.value = UIState.OnUserVerificationCanceled(dataToVerify)
|
||||
}
|
||||
|
||||
fun onUserVerificationReceived() {
|
||||
mUiState.value = UIState.Loading
|
||||
}
|
||||
|
||||
sealed class UIState {
|
||||
object Loading: UIState()
|
||||
data class OnUserVerificationSucceeded(
|
||||
val database: ContextualDatabase?
|
||||
): UIState()
|
||||
data class OnUserVerificationCanceled(
|
||||
val database: ContextualDatabase?
|
||||
): UIState()
|
||||
data class OnUserVerificationSucceeded(val dataToVerify: UserVerificationData): UIState()
|
||||
data class OnUserVerificationCanceled(val dataToVerify: UserVerificationData): UIState()
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user