From 7e269c6b8cf2e67c697d610f85a47d52b1d27672 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Tue, 4 Jun 2024 15:59:23 +0100 Subject: [PATCH] android, desktop: enter app logic (#4288) Co-authored-by: Avently <7953703+avently@users.noreply.github.com> --- .../chat/simplex/common/platform/Core.kt | 4 ++ .../views/database/DatabaseEncryptionView.kt | 43 +++++++++++-------- .../onboarding/SetupDatabasePassphrase.kt | 12 +++++- 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Core.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Core.kt index 85179d66c7..d6b8901042 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Core.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Core.kt @@ -1,6 +1,7 @@ package chat.simplex.common.platform import chat.simplex.common.model.* +import chat.simplex.common.model.ChatController.appPrefs import chat.simplex.common.model.ChatModel.controller import chat.simplex.common.model.ChatModel.currentUser import chat.simplex.common.views.helpers.* @@ -57,6 +58,9 @@ suspend fun initChatController(useKey: String? = null, confirmMigrations: Migrat try { if (chatModel.ctrlInitInProgress.value) return chatModel.ctrlInitInProgress.value = true + if (!appPrefs.storeDBPassphrase.get() && !appPrefs.initialRandomDBPassphrase.get()) { + ksDatabasePassword.remove() + } val dbKey = useKey ?: DatabaseUtils.useDatabaseKey() val confirm = confirmMigrations ?: if (appPreferences.developerTools.get() && appPreferences.confirmDBUpgrades.get()) MigrationConfirmation.Error else MigrationConfirmation.YesUp var migrated: Array = chatMigrateInit(dbAbsolutePrefixPath, dbKey, MigrationConfirmation.Error.value) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseEncryptionView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseEncryptionView.kt index ca14b19adf..a2aeac21a2 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseEncryptionView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseEncryptionView.kt @@ -27,6 +27,7 @@ import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.unit.* import chat.simplex.common.model.* +import chat.simplex.common.model.ChatController.appPrefs import chat.simplex.common.platform.* import chat.simplex.common.ui.theme.* import chat.simplex.common.views.helpers.* @@ -40,9 +41,8 @@ import kotlin.math.log2 @Composable fun DatabaseEncryptionView(m: ChatModel, migration: Boolean) { val progressIndicator = remember { mutableStateOf(false) } - val prefs = m.controller.appPrefs - val useKeychain = remember { mutableStateOf(prefs.storeDBPassphrase.get()) } - val initialRandomDBPassphrase = remember { mutableStateOf(prefs.initialRandomDBPassphrase.get()) } + val useKeychain = remember { mutableStateOf(appPrefs.storeDBPassphrase.get()) } + val initialRandomDBPassphrase = remember { mutableStateOf(appPrefs.initialRandomDBPassphrase.get()) } val storedKey = remember { val key = DatabaseUtils.ksDatabasePassword.get(); mutableStateOf(key != null && key != "") } // Do not do rememberSaveable on current key to prevent saving it on disk in clear text val currentKey = remember { mutableStateOf(if (initialRandomDBPassphrase.value) DatabaseUtils.ksDatabasePassword.get() ?: "" else "") } @@ -54,7 +54,6 @@ fun DatabaseEncryptionView(m: ChatModel, migration: Boolean) { ) { DatabaseEncryptionLayout( useKeychain, - prefs, m.chatDbEncrypted.value, currentKey, newKey, @@ -65,7 +64,16 @@ fun DatabaseEncryptionView(m: ChatModel, migration: Boolean) { migration, onConfirmEncrypt = { withLongRunningApi { - encryptDatabase(currentKey, newKey, confirmNewKey, initialRandomDBPassphrase, useKeychain, storedKey, progressIndicator, migration) + encryptDatabase( + currentKey = currentKey, + newKey = newKey, + confirmNewKey = confirmNewKey, + initialRandomDBPassphrase = initialRandomDBPassphrase, + useKeychain = useKeychain, + storedKey = storedKey, + progressIndicator = progressIndicator, + migration = migration + ) } } ) @@ -89,7 +97,6 @@ fun DatabaseEncryptionView(m: ChatModel, migration: Boolean) { @Composable fun DatabaseEncryptionLayout( useKeychain: MutableState, - prefs: AppPreferences, chatDbEncrypted: Boolean?, currentKey: MutableState, newKey: MutableState, @@ -119,14 +126,14 @@ fun DatabaseEncryptionLayout( enabled = (!initialRandomDBPassphrase.value && !progressIndicator.value) || migration ) { checked -> if (checked) { - setUseKeychain(true, useKeychain, prefs, migration) + setUseKeychain(true, useKeychain, migration) } else if (storedKey.value && !migration) { // Don't show in migration process since it will remove the key after successful encryption removePassphraseAlert { - removePassphraseFromKeyChain(useKeychain, prefs, storedKey, false) + removePassphraseFromKeyChain(useKeychain, storedKey, false) } } else { - setUseKeychain(false, useKeychain, prefs, migration) + setUseKeychain(false, useKeychain, migration) } } @@ -272,17 +279,17 @@ fun resetFormAfterEncryption( m.controller.appPrefs.initialRandomDBPassphrase.set(false) } -fun setUseKeychain(value: Boolean, useKeychain: MutableState, prefs: AppPreferences, migration: Boolean) { +fun setUseKeychain(value: Boolean, useKeychain: MutableState, migration: Boolean) { useKeychain.value = value // Postpone it when migrating to the end of encryption process if (!migration) { - prefs.storeDBPassphrase.set(value) + appPrefs.storeDBPassphrase.set(value) } } -private fun removePassphraseFromKeyChain(useKeychain: MutableState, prefs: AppPreferences, storedKey: MutableState, migration: Boolean) { +private fun removePassphraseFromKeyChain(useKeychain: MutableState, storedKey: MutableState, migration: Boolean) { DatabaseUtils.ksDatabasePassword.remove() - setUseKeychain(false, useKeychain, prefs, migration) + setUseKeychain(false, useKeychain, migration) storedKey.value = false } @@ -415,15 +422,14 @@ suspend fun encryptDatabase( migration: Boolean, ): Boolean { val m = ChatModel - val prefs = ChatController.appPrefs progressIndicator.value = true return try { - prefs.encryptionStartedAt.set(Clock.System.now()) + appPrefs.encryptionStartedAt.set(Clock.System.now()) if (!m.chatDbChanged.value) { m.controller.apiSaveAppSettings(AppSettings.current.prepareForExport()) } val error = m.controller.apiStorageEncryption(currentKey.value, newKey.value) - prefs.encryptionStartedAt.set(null) + appPrefs.encryptionStartedAt.set(null) val sqliteError = ((error?.chatError as? ChatError.ChatErrorDatabase)?.databaseError as? DatabaseError.ErrorExport)?.sqliteError when { sqliteError is SQLiteError.ErrorNotADatabase -> { @@ -451,8 +457,8 @@ suspend fun encryptDatabase( resetFormAfterEncryption(m, initialRandomDBPassphrase, currentKey, newKey, confirmNewKey, storedKey, useKeychain.value) if (useKeychain.value) { DatabaseUtils.ksDatabasePassword.set(new) - } else if (migration) { - removePassphraseFromKeyChain(useKeychain, prefs, storedKey, true) + } else { + removePassphraseFromKeyChain(useKeychain, storedKey, migration) } operationEnded(m, progressIndicator) { AlertManager.shared.showAlertMsg(generalGetString(MR.strings.database_encrypted)) @@ -523,7 +529,6 @@ fun PreviewDatabaseEncryptionLayout() { SimpleXTheme { DatabaseEncryptionLayout( useKeychain = remember { mutableStateOf(true) }, - prefs = AppPreferences(), chatDbEncrypted = true, currentKey = remember { mutableStateOf("") }, newKey = remember { mutableStateOf("") }, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/SetupDatabasePassphrase.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/SetupDatabasePassphrase.kt index 65bd89b11b..a96cfa5a03 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/SetupDatabasePassphrase.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/SetupDatabasePassphrase.kt @@ -31,7 +31,6 @@ import kotlinx.coroutines.delay fun SetupDatabasePassphrase(m: ChatModel) { val progressIndicator = remember { mutableStateOf(false) } val prefs = m.controller.appPrefs - val saveInPreferences = remember { mutableStateOf(prefs.storeDBPassphrase.get()) } val initialRandomDBPassphrase = remember { mutableStateOf(prefs.initialRandomDBPassphrase.get()) } // Do not do rememberSaveable on current key to prevent saving it on disk in clear text val currentKey = remember { mutableStateOf(if (initialRandomDBPassphrase.value) DatabaseUtils.ksDatabasePassword.get() ?: "" else "") } @@ -58,7 +57,16 @@ fun SetupDatabasePassphrase(m: ChatModel) { prefs.storeDBPassphrase.set(false) val newKeyValue = newKey.value - val success = encryptDatabase(currentKey, newKey, confirmNewKey, mutableStateOf(true), saveInPreferences, mutableStateOf(true), progressIndicator, false) + val success = encryptDatabase( + currentKey = currentKey, + newKey = newKey, + confirmNewKey = confirmNewKey, + initialRandomDBPassphrase = mutableStateOf(true), + useKeychain = mutableStateOf(false), + storedKey = mutableStateOf(true), + progressIndicator = progressIndicator, + migration = false + ) if (success) { startChat(newKeyValue) nextStep()