From 8bbc90ae26c354602d47d0e5b1d59610ae87965b Mon Sep 17 00:00:00 2001 From: MohamadJaara Date: Thu, 16 Nov 2023 19:50:22 +0100 Subject: [PATCH 1/3] refactor: remove user scoped shared pref and store all feature flags in the metadata user DB table --- .../logic/di/PlatformUserStorageProvider.kt | 11 +- .../logic/di/PlatformUserStorageProvider.kt | 12 +- .../logic/configuration/E2EISettings.kt | 2 +- .../configuration/UserConfigRepository.kt | 206 +++---- .../data/featureConfig/FeatureConfigMapper.kt | 2 +- .../logic/data/message/SelfDeletionMapper.kt | 2 +- .../kalium/logic/di/UserStorageProvider.kt | 8 +- .../kalium/logic/feature/UserSessionScope.kt | 123 +++-- .../AppLockTeamFeatureConfigObserver.kt | 4 +- .../MarkTeamAppLockStatusAsNotifiedUseCase.kt | 4 +- .../feature/auth/ClearUserDataUseCase.kt | 8 +- .../logic/feature/backup/BackupScope.kt | 10 +- .../usecase/IsEligibleToStartCallUseCase.kt | 2 +- .../feature/conversation/ConversationScope.kt | 10 +- ...rUserSecurityClassificationLabelUseCase.kt | 2 +- .../handler/AppLockConfigHandler.kt | 2 +- .../handler/ClassifiedDomainsConfigHandler.kt | 4 +- .../handler/ConferenceCallingConfigHandler.kt | 4 +- .../handler/E2EIConfigHandler.kt | 4 +- .../handler/FileSharingConfigHandler.kt | 4 +- .../handler/GuestRoomConfigHandler.kt | 4 +- ...ondFactorPasswordChallengeConfigHandler.kt | 4 +- .../user/IsFileSharingEnabledUseCase.kt | 6 +- .../logic/feature/user/IsMLSEnabledUseCase.kt | 4 +- .../user/ObserveE2EIRequiredUseCase.kt | 6 +- .../user/ObserveFileSharingStatusUseCase.kt | 4 +- ...GuestLinkFeatureFlagAsNotChangedUseCase.kt | 4 +- .../receiver/UserPropertiesEventReceiver.kt | 4 +- .../kalium/logic/sync/slow/SlowSyncManager.kt | 2 +- .../SyncFeatureConfigsUseCaseTest.kt | 2 +- .../kmmSettings/UserPrefBuilder.kt | 49 -- .../kmmSettings/UserPrefBuilder.kt | 48 -- .../LastRetrievedNotificationEventStorage.kt | 52 -- .../persistence/config/UserConfigStorage.kt | 501 ------------------ .../kalium/persistence/dao/MetadataDAO.kt | 4 + .../kalium/persistence/dao/MetadataDAOImpl.kt | 53 +- .../persistence/dao/config/MLSConfigDAO.kt | 91 ++++ .../persistence/dao/config/UserConfigDAO.kt | 350 ++++++++++++ .../dao/config/model/AppLockConfigEntity.kt} | 25 +- .../config/model/ClassifiedDomainsEntity.kt | 27 + .../config/model/E2EISettingsEntity.kt} | 18 +- .../model/IsFileSharingEnabledEntity.kt | 27 + .../model/IsGuestRoomLinkEnabledEntity.kt | 27 + .../dao/config/model/MLSMigrationEntity.kt | 28 + .../config/model/SelfDeletionTimerEntity.kt | 38 ++ .../TeamSettingsSelfDeletionStatusEntity.kt | 27 + .../persistence/dao/unread/UserConfigDAO.kt | 92 ---- .../persistence/db/UserDatabaseBuilder.kt | 9 +- .../persistence/config/UserConfigDAOTest.kt | 163 +++++- .../config/UserConfigStorageTest.kt | 207 -------- .../kmmSettings/UserPrefBuilder.kt | 49 -- 51 files changed, 1091 insertions(+), 1258 deletions(-) delete mode 100644 persistence/src/androidMain/kotlin/com/wire/kalium/persistence/kmmSettings/UserPrefBuilder.kt delete mode 100644 persistence/src/appleMain/kotlin/com/wire/kalium/persistence/kmmSettings/UserPrefBuilder.kt delete mode 100644 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/client/LastRetrievedNotificationEventStorage.kt delete mode 100644 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/config/UserConfigStorage.kt create mode 100644 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/MLSConfigDAO.kt create mode 100644 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/UserConfigDAO.kt rename persistence/src/{jsMain/kotlin/com/wire/kalium/persistence/kmmSettings/UserPrefBuilder.kt => commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/AppLockConfigEntity.kt} (57%) create mode 100644 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/ClassifiedDomainsEntity.kt rename persistence/src/commonMain/kotlin/com/wire/kalium/persistence/{kmmSettings/UserPrefBuilder.kt => dao/config/model/E2EISettingsEntity.kt} (65%) create mode 100644 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/IsFileSharingEnabledEntity.kt create mode 100644 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/IsGuestRoomLinkEnabledEntity.kt create mode 100644 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/MLSMigrationEntity.kt create mode 100644 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/SelfDeletionTimerEntity.kt create mode 100644 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/TeamSettingsSelfDeletionStatusEntity.kt delete mode 100644 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/unread/UserConfigDAO.kt delete mode 100644 persistence/src/commonTest/kotlin/com/wire/kalium/persistence/config/UserConfigStorageTest.kt delete mode 100644 persistence/src/jvmMain/kotlin/com/wire/kalium/persistence/kmmSettings/UserPrefBuilder.kt diff --git a/logic/src/androidMain/kotlin/com/wire/kalium/logic/di/PlatformUserStorageProvider.kt b/logic/src/androidMain/kotlin/com/wire/kalium/logic/di/PlatformUserStorageProvider.kt index e9aa64227f6..f80b01da659 100644 --- a/logic/src/androidMain/kotlin/com/wire/kalium/logic/di/PlatformUserStorageProvider.kt +++ b/logic/src/androidMain/kotlin/com/wire/kalium/logic/di/PlatformUserStorageProvider.kt @@ -21,14 +21,17 @@ package com.wire.kalium.logic.di import com.wire.kalium.logic.data.id.toDao import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.persistence.db.PlatformDatabaseData +import com.wire.kalium.persistence.db.UserDatabaseBuilder import com.wire.kalium.persistence.db.userDatabaseBuilder -import com.wire.kalium.persistence.kmmSettings.UserPrefBuilder import com.wire.kalium.util.KaliumDispatcherImpl internal actual class PlatformUserStorageProvider : UserStorageProvider() { - override fun create(userId: UserId, shouldEncryptData: Boolean, platformProperties: PlatformUserStorageProperties): UserStorage { + override fun create( + userId: UserId, + shouldEncryptData: Boolean, + platformProperties: PlatformUserStorageProperties + ): UserDatabaseBuilder { val userIdEntity = userId.toDao() - val pref = UserPrefBuilder(userIdEntity, platformProperties.applicationContext, shouldEncryptData) val databasePassphrase = if (shouldEncryptData) { platformProperties.securityHelper.userDBSecret(userId) @@ -42,6 +45,6 @@ internal actual class PlatformUserStorageProvider : UserStorageProvider() { dispatcher = KaliumDispatcherImpl.io, enableWAL = true ) - return UserStorage(database, pref) + return database } } diff --git a/logic/src/appleMain/kotlin/com/wire/kalium/logic/di/PlatformUserStorageProvider.kt b/logic/src/appleMain/kotlin/com/wire/kalium/logic/di/PlatformUserStorageProvider.kt index e6d12280507..b34e2594596 100644 --- a/logic/src/appleMain/kotlin/com/wire/kalium/logic/di/PlatformUserStorageProvider.kt +++ b/logic/src/appleMain/kotlin/com/wire/kalium/logic/di/PlatformUserStorageProvider.kt @@ -22,13 +22,17 @@ import com.wire.kalium.logic.data.id.toDao import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.persistence.db.userDatabaseBuilder import com.wire.kalium.persistence.db.PlatformDatabaseData -import com.wire.kalium.persistence.kmmSettings.UserPrefBuilder +import com.wire.kalium.persistence.db.UserDatabaseBuilder import com.wire.kalium.util.KaliumDispatcherImpl internal actual class PlatformUserStorageProvider actual constructor() : UserStorageProvider() { - override fun create(userId: UserId, shouldEncryptData: Boolean, platformProperties: PlatformUserStorageProperties): UserStorage { + override fun create( + userId: UserId, + shouldEncryptData: Boolean, + platformProperties: PlatformUserStorageProperties + ): UserDatabaseBuilder { val userIdEntity = userId.toDao() - val pref = UserPrefBuilder(userIdEntity, platformProperties.rootPath, shouldEncryptData) + val database = userDatabaseBuilder( PlatformDatabaseData(platformProperties.rootStoragePath), userIdEntity, @@ -36,6 +40,6 @@ internal actual class PlatformUserStorageProvider actual constructor() : UserSto KaliumDispatcherImpl.io, true ) - return UserStorage(database, pref) + return database } } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/E2EISettings.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/E2EISettings.kt index 1416c937e5b..6fdfed6701a 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/E2EISettings.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/E2EISettings.kt @@ -17,7 +17,7 @@ */ package com.wire.kalium.logic.configuration -import com.wire.kalium.persistence.config.E2EISettingsEntity +import com.wire.kalium.persistence.dao.config.model.E2EISettingsEntity import kotlinx.datetime.Instant data class E2EISettings( diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/UserConfigRepository.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/UserConfigRepository.kt index f4413d1ea8b..2d1767e8bbd 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/UserConfigRepository.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/UserConfigRepository.kt @@ -37,10 +37,10 @@ import com.wire.kalium.logic.functional.map import com.wire.kalium.logic.functional.mapRight import com.wire.kalium.logic.wrapFlowStorageRequest import com.wire.kalium.logic.wrapStorageRequest -import com.wire.kalium.persistence.config.IsFileSharingEnabledEntity -import com.wire.kalium.persistence.config.TeamSettingsSelfDeletionStatusEntity -import com.wire.kalium.persistence.config.UserConfigStorage -import com.wire.kalium.persistence.dao.unread.UserConfigDAO +import com.wire.kalium.persistence.dao.config.MLSConfigDAO +import com.wire.kalium.persistence.dao.config.model.TeamSettingsSelfDeletionStatusEntity +import com.wire.kalium.persistence.dao.config.UserConfigDAO +import com.wire.kalium.persistence.dao.config.model.IsFileSharingEnabledEntity import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map import kotlinx.datetime.Instant @@ -49,50 +49,50 @@ import kotlin.time.Duration.Companion.seconds @Suppress("TooManyFunctions") interface UserConfigRepository { - fun setAppLockStatus( + suspend fun setAppLockStatus( isAppLocked: Boolean, timeout: Int, isStatusChanged: Boolean? ): Either - fun isTeamAppLockEnabled(): Either - fun observeAppLockConfig(): Flow> - fun setTeamAppLockAsNotified(): Either - fun setFileSharingStatus( + suspend fun isTeamAppLockEnabled(): Either + suspend fun observeAppLockConfig(): Flow> + suspend fun setTeamAppLockAsNotified(): Either + suspend fun setFileSharingStatus( status: Boolean, isStatusChanged: Boolean? ): Either - fun setFileSharingAsNotified(): Either - fun isFileSharingEnabled(): Either - fun isFileSharingEnabledFlow(): Flow> - fun setClassifiedDomainsStatus( + suspend fun setFileSharingAsNotified(): Either + suspend fun isFileSharingEnabled(): Either + suspend fun isFileSharingEnabledFlow(): Flow> + suspend fun setClassifiedDomainsStatus( enabled: Boolean, domains: List ): Either - fun getClassifiedDomainsStatus(): Flow> - fun isMLSEnabled(): Either - fun setMLSEnabled(enabled: Boolean): Either - fun getE2EISettings(): Either - fun observeE2EISettings(): Flow> - fun setE2EISettings(setting: E2EISettings): Either - fun snoozeE2EINotification(duration: Duration): Either - fun setDefaultProtocol(protocol: SupportedProtocol): Either - fun getDefaultProtocol(): Either + suspend fun getClassifiedDomainsStatus(): Flow> + suspend fun isMLSEnabled(): Either + suspend fun setMLSEnabled(enabled: Boolean): Either + suspend fun getE2EISettings(): Either + suspend fun observeE2EISettings(): Flow> + suspend fun setE2EISettings(setting: E2EISettings): Either + suspend fun snoozeE2EINotification(duration: Duration): Either + suspend fun setDefaultProtocol(protocol: SupportedProtocol): Either + suspend fun getDefaultProtocol(): Either suspend fun setSupportedProtocols(protocols: Set): Either suspend fun getSupportedProtocols(): Either> - fun setConferenceCallingEnabled(enabled: Boolean): Either - fun isConferenceCallingEnabled(): Either - fun setSecondFactorPasswordChallengeStatus(isRequired: Boolean): Either - fun isSecondFactorPasswordChallengeRequired(): Either - fun isReadReceiptsEnabled(): Flow> - fun setReadReceiptsStatus(enabled: Boolean): Either - fun isTypingIndicatorEnabled(): Flow> - fun setTypingIndicatorStatus(enabled: Boolean): Either - fun setGuestRoomStatus(status: Boolean, isStatusChanged: Boolean?): Either - fun getGuestRoomLinkStatus(): Either - fun observeGuestRoomLinkFeatureFlag(): Flow> + suspend fun setConferenceCallingEnabled(enabled: Boolean): Either + suspend fun isConferenceCallingEnabled(): Either + suspend fun setSecondFactorPasswordChallengeStatus(isRequired: Boolean): Either + suspend fun isSecondFactorPasswordChallengeRequired(): Either + suspend fun isReadReceiptsEnabled(): Flow> + suspend fun setReadReceiptsStatus(enabled: Boolean): Either + suspend fun isTypingIndicatorEnabled(): Flow> + suspend fun setTypingIndicatorStatus(enabled: Boolean): Either + suspend fun setGuestRoomStatus(status: Boolean, isStatusChanged: Boolean?): Either + suspend fun getGuestRoomLinkStatus(): Either + suspend fun observeGuestRoomLinkFeatureFlag(): Flow> suspend fun setScreenshotCensoringConfig(enabled: Boolean): Either suspend fun observeScreenshotCensoringConfig(): Flow> @@ -103,44 +103,44 @@ interface UserConfigRepository { suspend fun markTeamSettingsSelfDeletingMessagesStatusAsNotified(): Either suspend fun observeTeamSettingsSelfDeletingStatus(): Flow> - fun observeE2EINotificationTime(): Flow> - fun setE2EINotificationTime(instant: Instant): Either + suspend fun observeE2EINotificationTime(): Flow> + suspend fun setE2EINotificationTime(instant: Instant): Either suspend fun getMigrationConfiguration(): Either suspend fun setMigrationConfiguration(configuration: MLSMigrationModel): Either } @Suppress("TooManyFunctions") class UserConfigDataSource( - private val userConfigStorage: UserConfigStorage, private val userConfigDAO: UserConfigDAO, + private val mlsConfigDAO: MLSConfigDAO, private val kaliumConfigs: KaliumConfigs ) : UserConfigRepository { - override fun setFileSharingStatus( + override suspend fun setFileSharingStatus( status: Boolean, isStatusChanged: Boolean? ): Either = - wrapStorageRequest { userConfigStorage.persistFileSharingStatus(status, isStatusChanged) } + wrapStorageRequest { userConfigDAO.persistFileSharingStatus(status, isStatusChanged) } - override fun setFileSharingAsNotified(): Either = wrapStorageRequest { - userConfigStorage.setFileSharingAsNotified() + override suspend fun setFileSharingAsNotified(): Either = wrapStorageRequest { + userConfigDAO.setFileSharingAsNotified() } - override fun isFileSharingEnabled(): Either { - val serverSideConfig = wrapStorageRequest { userConfigStorage.isFileSharingEnabled() } + override suspend fun isFileSharingEnabled(): Either { + val serverSideConfig = wrapStorageRequest { userConfigDAO.isFileSharingEnabled() } val buildConfig = kaliumConfigs.fileRestrictionState return deriveFileSharingStatus(serverSideConfig, buildConfig) } - override fun isFileSharingEnabledFlow(): Flow> = - userConfigStorage.isFileSharingEnabledFlow() + override suspend fun isFileSharingEnabledFlow(): Flow> = + userConfigDAO.isFileSharingEnabledFlow() .wrapStorageRequest() .map { val buildConfig = kaliumConfigs.fileRestrictionState deriveFileSharingStatus(it, buildConfig) } - private fun deriveFileSharingStatus( + private suspend fun deriveFileSharingStatus( serverSideConfig: Either, buildConfig: BuildFileRestrictionState ): Either = when { @@ -170,58 +170,58 @@ class UserConfigDataSource( else -> error("Unknown file restriction state: buildConfig: $buildConfig , serverConfig: $serverSideConfig") } - override fun setClassifiedDomainsStatus(enabled: Boolean, domains: List) = - wrapStorageRequest { userConfigStorage.persistClassifiedDomainsStatus(enabled, domains) } + override suspend fun setClassifiedDomainsStatus(enabled: Boolean, domains: List) = + wrapStorageRequest { userConfigDAO.persistClassifiedDomainsStatus(enabled, domains) } - override fun getClassifiedDomainsStatus(): Flow> = - userConfigStorage.isClassifiedDomainsEnabledFlow().wrapStorageRequest().map { + override suspend fun getClassifiedDomainsStatus(): Flow> = + userConfigDAO.isClassifiedDomainsEnabledFlow().wrapStorageRequest().map { it.map { classifiedDomain -> ClassifiedDomainsStatus(classifiedDomain.status, classifiedDomain.trustedDomains) } } - override fun isMLSEnabled(): Either = - wrapStorageRequest { userConfigStorage.isMLSEnabled() } + override suspend fun isMLSEnabled(): Either = + wrapStorageRequest { mlsConfigDAO.isMLSEnabled() } - override fun setMLSEnabled(enabled: Boolean): Either = - wrapStorageRequest { userConfigStorage.enableMLS(enabled) } + override suspend fun setMLSEnabled(enabled: Boolean): Either = + wrapStorageRequest { mlsConfigDAO.enableMLS(enabled) } - override fun getE2EISettings(): Either = - wrapStorageRequest { userConfigStorage.getE2EISettings() } + override suspend fun getE2EISettings(): Either = + wrapStorageRequest { mlsConfigDAO.getE2EISettings() } .map { E2EISettings.fromEntity(it) } - override fun observeE2EISettings(): Flow> = - userConfigStorage.e2EISettingsFlow() + override suspend fun observeE2EISettings(): Flow> = + mlsConfigDAO.e2EISettingsFlow() .wrapStorageRequest() .mapRight { E2EISettings.fromEntity(it) } - override fun setE2EISettings(setting: E2EISettings): Either = - wrapStorageRequest { userConfigStorage.setE2EISettings(setting.toEntity()) } + override suspend fun setE2EISettings(setting: E2EISettings): Either = + wrapStorageRequest { mlsConfigDAO.setE2EISettings(setting.toEntity()) } - override fun observeE2EINotificationTime(): Flow> = - userConfigStorage.e2EINotificationTimeFlow() + override suspend fun observeE2EINotificationTime(): Flow> = + mlsConfigDAO.e2EINotificationTimeFlow() .wrapStorageRequest() .mapRight { Instant.fromEpochMilliseconds(it) } - override fun setE2EINotificationTime(instant: Instant): Either = - wrapStorageRequest { userConfigStorage.setE2EINotificationTime(instant.toEpochMilliseconds()) } + override suspend fun setE2EINotificationTime(instant: Instant): Either = + wrapStorageRequest { mlsConfigDAO.setE2EINotificationTime(instant.toEpochMilliseconds()) } - override fun snoozeE2EINotification(duration: Duration): Either = + override suspend fun snoozeE2EINotification(duration: Duration): Either = wrapStorageRequest { getE2EINotificationTimeOrNull()?.let { current -> val notifyUserAfterMs = current.plus(duration.inWholeMilliseconds) - userConfigStorage.setE2EINotificationTime(notifyUserAfterMs) + mlsConfigDAO.setE2EINotificationTime(notifyUserAfterMs) } } - private fun getE2EINotificationTimeOrNull() = - wrapStorageRequest { userConfigStorage.getE2EINotificationTime() }.getOrNull() + private suspend fun getE2EINotificationTimeOrNull() = + wrapStorageRequest { mlsConfigDAO.getE2EINotificationTime() }.getOrNull() - override fun setDefaultProtocol(protocol: SupportedProtocol): Either = - wrapStorageRequest { userConfigStorage.persistDefaultProtocol(protocol.toDao()) } + override suspend fun setDefaultProtocol(protocol: SupportedProtocol): Either = + wrapStorageRequest { userConfigDAO.persistDefaultProtocol(protocol.toDao()) } - override fun getDefaultProtocol(): Either = - wrapStorageRequest { userConfigStorage.defaultProtocol().toModel() } + override suspend fun getDefaultProtocol(): Either = + wrapStorageRequest { userConfigDAO.defaultProtocol().toModel() } override suspend fun setSupportedProtocols(protocols: Set): Either = wrapStorageRequest { userConfigDAO.setSupportedProtocols(protocols.toDao()) } @@ -229,57 +229,57 @@ class UserConfigDataSource( override suspend fun getSupportedProtocols(): Either> = wrapStorageRequest { userConfigDAO.getSupportedProtocols()?.toModel() } - override fun setConferenceCallingEnabled(enabled: Boolean): Either = + override suspend fun setConferenceCallingEnabled(enabled: Boolean): Either = wrapStorageRequest { - userConfigStorage.persistConferenceCalling(enabled) + userConfigDAO.persistConferenceCalling(enabled) } - override fun isConferenceCallingEnabled(): Either = + override suspend fun isConferenceCallingEnabled(): Either = wrapStorageRequest { - userConfigStorage.isConferenceCallingEnabled() + userConfigDAO.isConferenceCallingEnabled() } - override fun setSecondFactorPasswordChallengeStatus(isRequired: Boolean): Either = + override suspend fun setSecondFactorPasswordChallengeStatus(isRequired: Boolean): Either = wrapStorageRequest { - userConfigStorage.persistSecondFactorPasswordChallengeStatus(isRequired) + userConfigDAO.persistSecondFactorPasswordChallengeStatus(isRequired) } - override fun isSecondFactorPasswordChallengeRequired(): Either = + override suspend fun isSecondFactorPasswordChallengeRequired(): Either = wrapStorageRequest { - userConfigStorage.isSecondFactorPasswordChallengeRequired() + userConfigDAO.isSecondFactorPasswordChallengeRequired() } - override fun isReadReceiptsEnabled(): Flow> = - userConfigStorage.areReadReceiptsEnabled().wrapStorageRequest() + override suspend fun isReadReceiptsEnabled(): Flow> = + userConfigDAO.areReadReceiptsEnabled().wrapStorageRequest() - override fun setReadReceiptsStatus(enabled: Boolean): Either = + override suspend fun setReadReceiptsStatus(enabled: Boolean): Either = wrapStorageRequest { - userConfigStorage.persistReadReceipts(enabled) + userConfigDAO.persistReadReceipts(enabled) } - override fun isTypingIndicatorEnabled(): Flow> = - userConfigStorage.isTypingIndicatorEnabled().wrapStorageRequest() + override suspend fun isTypingIndicatorEnabled(): Flow> = + userConfigDAO.isTypingIndicatorEnabled().wrapStorageRequest() - override fun setTypingIndicatorStatus(enabled: Boolean): Either = + override suspend fun setTypingIndicatorStatus(enabled: Boolean): Either = wrapStorageRequest { - userConfigStorage.persistTypingIndicator(enabled) + userConfigDAO.persistTypingIndicator(enabled) } - override fun setGuestRoomStatus( + override suspend fun setGuestRoomStatus( status: Boolean, isStatusChanged: Boolean? ): Either = wrapStorageRequest { - userConfigStorage.persistGuestRoomLinkFeatureFlag(status, isStatusChanged) + userConfigDAO.persistGuestRoomLinkFeatureFlag(status, isStatusChanged) } - override fun getGuestRoomLinkStatus(): Either = - wrapStorageRequest { userConfigStorage.isGuestRoomLinkEnabled() }.map { + override suspend fun getGuestRoomLinkStatus(): Either = + wrapStorageRequest { userConfigDAO.isGuestRoomLinkEnabled() }.map { with(it) { GuestRoomLinkStatus(status, isStatusChanged) } } - override fun observeGuestRoomLinkFeatureFlag(): Flow> = - userConfigStorage.isGuestRoomLinkEnabledFlow() + override suspend fun observeGuestRoomLinkFeatureFlag(): Flow> = + userConfigDAO.isGuestRoomLinkEnabledFlow() .wrapStorageRequest() .map { it.map { isGuestRoomLinkEnabledEntity -> @@ -328,27 +328,27 @@ class UserConfigDataSource( } override suspend fun setScreenshotCensoringConfig(enabled: Boolean): Either = - wrapStorageRequest { userConfigStorage.persistScreenshotCensoring(enabled) } + wrapStorageRequest { userConfigDAO.persistScreenshotCensoring(enabled) } override suspend fun observeScreenshotCensoringConfig(): Flow> = - userConfigStorage.isScreenshotCensoringEnabledFlow().wrapStorageRequest() + userConfigDAO.isScreenshotCensoringEnabledFlow().wrapStorageRequest() - override fun setAppLockStatus( + override suspend fun setAppLockStatus( isAppLocked: Boolean, timeout: Int, isStatusChanged: Boolean? ): Either = wrapStorageRequest { - userConfigStorage.persistAppLockStatus( + userConfigDAO.persistAppLockStatus( isAppLocked, timeout, isStatusChanged ) } - override fun observeAppLockConfig(): Flow> = + override suspend fun observeAppLockConfig(): Flow> = wrapFlowStorageRequest { - userConfigStorage.appLockFlow().map { + userConfigDAO.appLockFlow().map { it?.let { config -> AppLockTeamConfig( isEnabled = config.enforceAppLock, @@ -359,8 +359,8 @@ class UserConfigDataSource( } } - override fun isTeamAppLockEnabled(): Either { - val serverSideConfig = wrapStorageRequest { userConfigStorage.appLockStatus() } + override suspend fun isTeamAppLockEnabled(): Either { + val serverSideConfig = wrapStorageRequest { userConfigDAO.appLockStatus() } return serverSideConfig.map { AppLockTeamConfig( isEnabled = it.enforceAppLock, @@ -370,8 +370,8 @@ class UserConfigDataSource( } } - override fun setTeamAppLockAsNotified(): Either = wrapStorageRequest { - userConfigStorage.setTeamAppLockAsNotified() + override suspend fun setTeamAppLockAsNotified(): Either = wrapStorageRequest { + userConfigDAO.setTeamAppLockAsNotified() } override suspend fun getMigrationConfiguration(): Either = diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/featureConfig/FeatureConfigMapper.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/featureConfig/FeatureConfigMapper.kt index e103b97fe45..3d219ca2977 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/featureConfig/FeatureConfigMapper.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/featureConfig/FeatureConfigMapper.kt @@ -25,7 +25,7 @@ import com.wire.kalium.network.api.base.authenticated.featureConfigs.FeatureConf import com.wire.kalium.network.api.base.authenticated.featureConfigs.FeatureConfigResponse import com.wire.kalium.network.api.base.authenticated.featureConfigs.FeatureFlagStatusDTO import com.wire.kalium.network.api.base.authenticated.featureConfigs.MLSMigrationConfigDTO -import com.wire.kalium.persistence.config.MLSMigrationEntity +import com.wire.kalium.persistence.dao.config.model.MLSMigrationEntity interface FeatureConfigMapper { fun fromDTO(featureConfigResponse: FeatureConfigResponse): FeatureConfigModel diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/SelfDeletionMapper.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/SelfDeletionMapper.kt index 41c8525ce65..bfef9f75a01 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/SelfDeletionMapper.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/SelfDeletionMapper.kt @@ -17,7 +17,7 @@ */ package com.wire.kalium.logic.data.message -import com.wire.kalium.persistence.config.SelfDeletionTimerEntity +import com.wire.kalium.persistence.dao.config.model.SelfDeletionTimerEntity internal object SelfDeletionMapper { // TODO rename and refactor fun TeamSelfDeleteTimer.toSelfDeletionTimerEntity(): SelfDeletionTimerEntity = when (this) { diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/di/UserStorageProvider.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/di/UserStorageProvider.kt index e34b13cad5e..e58177026ee 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/di/UserStorageProvider.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/di/UserStorageProvider.kt @@ -22,16 +22,14 @@ import co.touchlab.stately.collections.ConcurrentMutableMap import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.util.safeComputeIfAbsent import com.wire.kalium.persistence.db.UserDatabaseBuilder -import com.wire.kalium.persistence.kmmSettings.UserPrefBuilder -data class UserStorage(val database: UserDatabaseBuilder, val preferences: UserPrefBuilder) abstract class UserStorageProvider { - private val inMemoryUserStorage: ConcurrentMutableMap = ConcurrentMutableMap() + private val inMemoryUserStorage: ConcurrentMutableMap = ConcurrentMutableMap() fun getOrCreate( userId: UserId, platformUserStorageProperties: PlatformUserStorageProperties, shouldEncryptData: Boolean = true - ): UserStorage = inMemoryUserStorage.safeComputeIfAbsent(userId) { + ): UserDatabaseBuilder = inMemoryUserStorage.safeComputeIfAbsent(userId) { create(userId, shouldEncryptData, platformUserStorageProperties) } @@ -39,7 +37,7 @@ abstract class UserStorageProvider { userId: UserId, shouldEncryptData: Boolean, platformProperties: PlatformUserStorageProperties - ): UserStorage + ): UserDatabaseBuilder fun clearInMemoryUserStorage(userId: UserId) = inMemoryUserStorage.remove(userId) } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt index e80d7854e82..4190055449f 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt @@ -414,13 +414,13 @@ class UserSessionScope internal constructor( dataStoragePaths: DataStoragePaths, private val kaliumConfigs: KaliumConfigs, private val userSessionScopeProvider: UserSessionScopeProvider, - userStorageProvider: UserStorageProvider, + databaseProvider: UserStorageProvider, private val clientConfig: ClientConfig, platformUserStorageProperties: PlatformUserStorageProperties, networkStateObserver: NetworkStateObserver ) : CoroutineScope { - private val userStorage = userStorageProvider.getOrCreate( + private val database = databaseProvider.getOrCreate( userId, platformUserStorageProperties, kaliumConfigs.shouldEncryptData ) @@ -542,8 +542,8 @@ class UserSessionScope internal constructor( private val userConfigRepository: UserConfigRepository get() = UserConfigDataSource( - userStorage.preferences.userConfigStorage, - userStorage.database.userConfigDAO, + database.userConfigDAO, + database.mlsConfigDAO, kaliumConfigs ) @@ -588,7 +588,7 @@ class UserSessionScope internal constructor( keyPackageRepository, mlsClientProvider, authenticatedNetworkContainer.mlsMessageApi, - userStorage.database.conversationDAO, + database.conversationDAO, authenticatedNetworkContainer.clientApi, syncManager, mlsPublicKeysRepository, @@ -627,13 +627,13 @@ class UserSessionScope internal constructor( userId, mlsClientProvider, selfTeamId, - userStorage.database.conversationDAO, - userStorage.database.memberDAO, + database.conversationDAO, + database.memberDAO, authenticatedNetworkContainer.conversationApi, - userStorage.database.messageDAO, - userStorage.database.clientDAO, + database.messageDAO, + database.clientDAO, authenticatedNetworkContainer.clientApi, - userStorage.database.conversationMetaDataDAO + database.conversationMetaDataDAO ) private val conversationGroupRepository: ConversationGroupRepository @@ -643,7 +643,7 @@ class UserSessionScope internal constructor( memberJoinHandler, memberLeaveHandler, conversationMessageTimerEventHandler, - userStorage.database.conversationDAO, + database.conversationDAO, authenticatedNetworkContainer.conversationApi, newConversationMembersRepository, lazy { conversations.newGroupConversationSystemMessagesCreator }, @@ -653,7 +653,7 @@ class UserSessionScope internal constructor( private val newConversationMembersRepository: NewConversationMembersRepository get() = NewConversationMembersRepositoryImpl( - userStorage.database.memberDAO, + database.memberDAO, lazy { conversations.newGroupConversationSystemMessagesCreator } ) @@ -661,20 +661,20 @@ class UserSessionScope internal constructor( get() = MessageDataSource( messageApi = authenticatedNetworkContainer.messageApi, mlsMessageApi = authenticatedNetworkContainer.mlsMessageApi, - messageDAO = userStorage.database.messageDAO, + messageDAO = database.messageDAO, selfUserId = userId ) private val messageMetadataRepository: MessageMetadataRepository - get() = MessageMetadataSource(messageMetaDataDAO = userStorage.database.messageMetaDataDAO) + get() = MessageMetadataSource(messageMetaDataDAO = database.messageMetaDataDAO) private val compositeMessageRepository: CompositeMessageRepository - get() = CompositeMessageDataSource(compositeMessageDAO = userStorage.database.compositeMessageDAO) + get() = CompositeMessageDataSource(compositeMessageDAO = database.compositeMessageDAO) private val userRepository: UserRepository = UserDataSource( - userStorage.database.userDAO, - userStorage.database.metadataDAO, - userStorage.database.clientDAO, + database.userDAO, + database.metadataDAO, + database.clientDAO, authenticatedNetworkContainer.selfApi, authenticatedNetworkContainer.userDetailsApi, authenticatedNetworkContainer.teamsApi, @@ -685,51 +685,51 @@ class UserSessionScope internal constructor( private val accountRepository: AccountRepository get() = AccountRepositoryImpl( - userDAO = userStorage.database.userDAO, + userDAO = database.userDAO, selfUserId = userId, selfApi = authenticatedNetworkContainer.selfApi ) internal val pushTokenRepository: PushTokenRepository - get() = PushTokenDataSource(userStorage.database.metadataDAO) + get() = PushTokenDataSource(database.metadataDAO) private val teamRepository: TeamRepository get() = TeamDataSource( - userStorage.database.userDAO, - userStorage.database.teamDAO, + database.userDAO, + database.teamDAO, authenticatedNetworkContainer.teamsApi, authenticatedNetworkContainer.userDetailsApi, userId, - userStorage.database.serviceDAO + database.serviceDAO ) private val serviceRepository: ServiceRepository get() = ServiceDataSource( - serviceDAO = userStorage.database.serviceDAO + serviceDAO = database.serviceDAO ) private val connectionRepository: ConnectionRepository get() = ConnectionDataSource( - userStorage.database.conversationDAO, - userStorage.database.memberDAO, - userStorage.database.connectionDAO, + database.conversationDAO, + database.memberDAO, + database.connectionDAO, authenticatedNetworkContainer.connectionApi, - userStorage.database.userDAO, + database.userDAO, conversationRepository ) private val userSearchApiWrapper: UserSearchApiWrapper = UserSearchApiWrapperImpl( authenticatedNetworkContainer.userSearchApi, - userStorage.database.conversationDAO, - userStorage.database.memberDAO, - userStorage.database.userDAO, - userStorage.database.metadataDAO + database.conversationDAO, + database.memberDAO, + database.userDAO, + database.metadataDAO ) private val publicUserRepository: SearchUserRepository get() = SearchUserRepositoryImpl( - userStorage.database.userDAO, - userStorage.database.metadataDAO, + database.userDAO, + database.metadataDAO, authenticatedNetworkContainer.userDetailsApi, authenticatedNetworkContainer.teamsApi, userSearchApiWrapper @@ -741,7 +741,7 @@ class UserSessionScope internal constructor( clientIdProvider, userRepository, kaliumFileSystem, - userStorage, + database, persistMigratedMessage, restartSlowSyncProcessForRecoveryUseCase, globalPreferences, @@ -760,7 +760,7 @@ class UserSessionScope internal constructor( CallDataSource( callApi = authenticatedNetworkContainer.callApi, qualifiedIdMapper = qualifiedIdMapper, - callDAO = userStorage.database.callDAO, + callDAO = database.callDAO, conversationRepository = conversationRepository, mlsConversationRepository = mlsConversationRepository, subconversationRepository = subconversationRepository, @@ -782,14 +782,14 @@ class UserSessionScope internal constructor( ) private val clientRegistrationStorage: ClientRegistrationStorage - get() = ClientRegistrationStorageImpl(userStorage.database.metadataDAO) + get() = ClientRegistrationStorageImpl(database.metadataDAO) internal val clientRepository: ClientRepository get() = ClientDataSource( clientRemoteRepository, clientRegistrationStorage, - userStorage.database.clientDAO, - userStorage.database.newClientDAO, + database.clientDAO, + database.newClientDAO, userId, authenticatedNetworkContainer.clientApi, ) @@ -800,7 +800,7 @@ class UserSessionScope internal constructor( private val assetRepository: AssetRepository get() = AssetDataSource( assetApi = authenticatedNetworkContainer.assetApi, - assetDao = userStorage.database.assetDAO, + assetDao = database.assetDAO, kaliumFileSystem = kaliumFileSystem ) @@ -808,7 +808,7 @@ class UserSessionScope internal constructor( InMemoryIncrementalSyncRepository() } - private val slowSyncRepository: SlowSyncRepository by lazy { SlowSyncRepositoryImpl(userStorage.database.metadataDAO) } + private val slowSyncRepository: SlowSyncRepository by lazy { SlowSyncRepositoryImpl(database.metadataDAO) } private val eventGatherer: EventGatherer get() = EventGathererImpl(eventRepository, incrementalSyncRepository) @@ -1026,13 +1026,13 @@ class UserSessionScope internal constructor( private val apiMigrationManager get() = ApiMigrationManager( sessionManager.serverConfig().metaData.commonApiVersion.version, - userStorage.database.metadataDAO, + database.metadataDAO, apiMigrations ) private val eventRepository: EventRepository get() = EventDataSource( - authenticatedNetworkContainer.notificationApi, userStorage.database.metadataDAO, clientIdProvider, userId + authenticatedNetworkContainer.notificationApi, database.metadataDAO, clientIdProvider, userId ) private val mlsMigrator: MLSMigrator @@ -1138,8 +1138,8 @@ class UserSessionScope internal constructor( UpdateConversationClientsForCurrentCallUseCaseImpl(callRepository, conversationClientsInCallUpdater) } - private val reactionRepository = ReactionRepositoryImpl(userId, userStorage.database.reactionDAO) - private val receiptRepository = ReceiptRepositoryImpl(userStorage.database.receiptDAO) + private val reactionRepository = ReactionRepositoryImpl(userId, database.reactionDAO) + private val receiptRepository = ReceiptRepositoryImpl(database.receiptDAO) private val persistReaction: PersistReactionUseCase get() = PersistReactionUseCaseImpl( reactionRepository @@ -1241,7 +1241,7 @@ class UserSessionScope internal constructor( ) private val memberLeaveHandler: MemberLeaveEventHandler get() = MemberLeaveEventHandlerImpl( - userStorage.database.memberDAO, userRepository, persistMessage, updateConversationClientsForCurrentCall + database.memberDAO, userRepository, persistMessage, updateConversationClientsForCurrentCall ) private val memberChangeHandler: MemberChangeEventHandler get() = MemberChangeEventHandlerImpl( @@ -1253,29 +1253,29 @@ class UserSessionScope internal constructor( ) private val renamedConversationHandler: RenamedConversationEventHandler get() = RenamedConversationEventHandlerImpl( - userStorage.database.conversationDAO, persistMessage + database.conversationDAO, persistMessage ) private val receiptModeUpdateEventHandler: ReceiptModeUpdateEventHandler get() = ReceiptModeUpdateEventHandlerImpl( - conversationDAO = userStorage.database.conversationDAO, + conversationDAO = database.conversationDAO, persistMessage = persistMessage ) private val conversationMessageTimerEventHandler: ConversationMessageTimerEventHandler get() = ConversationMessageTimerEventHandlerImpl( - conversationDAO = userStorage.database.conversationDAO, + conversationDAO = database.conversationDAO, persistMessage = persistMessage ) private val conversationCodeUpdateHandler: CodeUpdatedHandler get() = CodeUpdateHandlerImpl( - conversationDAO = userStorage.database.conversationDAO + conversationDAO = database.conversationDAO ) private val conversationCodeDeletedHandler: CodeDeletedHandler get() = CodeDeletedHandlerImpl( - conversationDAO = userStorage.database.conversationDAO + conversationDAO = database.conversationDAO ) private val typingIndicatorHandler: TypingIndicatorHandler @@ -1325,7 +1325,7 @@ class UserSessionScope internal constructor( private val federationEventReceiver: FederationEventReceiver get() = FederationEventReceiverImpl( conversationRepository, connectionRepository, userRepository, - userStorage.database.memberDAO, persistMessage, userId + database.memberDAO, persistMessage, userId ) private val teamEventReceiver: TeamEventReceiver @@ -1379,9 +1379,9 @@ class UserSessionScope internal constructor( authenticatedNetworkContainer.preKeyApi, proteusClientProvider, clientIdProvider, - userStorage.database.prekeyDAO, - userStorage.database.clientDAO, - userStorage.database.metadataDAO, + database.prekeyDAO, + database.clientDAO, + database.metadataDAO, ) private val proteusPreKeyRefiller: ProteusPreKeyRefiller @@ -1402,7 +1402,7 @@ class UserSessionScope internal constructor( private val logoutRepository: LogoutRepository = LogoutDataSource( authenticatedNetworkContainer.logoutApi, - userStorage.database.metadataDAO + database.metadataDAO ) val observeSyncState: ObserveSyncStateUseCase @@ -1424,7 +1424,7 @@ class UserSessionScope internal constructor( val persistMigratedMessage: PersistMigratedMessagesUseCase get() = PersistMigratedMessagesUseCaseImpl( userId, - userStorage.database.migrationDAO, + database.migrationDAO, protoContentMapper = protoContentMapper ) @@ -1478,16 +1478,15 @@ class UserSessionScope internal constructor( messages.sendConfirmation, renamedConversationHandler, qualifiedIdMapper, - team.isSelfATeamMember, globalScope.serverConfigRepository, - userStorage, + database, userPropertyRepository, oneOnOneResolver, this ) } - val migration get() = MigrationScope(userId, userStorage.database) + val migration get() = MigrationScope(userId, database) val debug: DebugScope get() = DebugScope( messageRepository, @@ -1550,7 +1549,7 @@ class UserSessionScope internal constructor( globalScope.sessionRepository, globalScope.serverConfigRepository, userId, - userStorage.database.metadataDAO, + database.metadataDAO, userPropertyRepository, messages.messageSender, clientIdProvider, @@ -1559,7 +1558,7 @@ class UserSessionScope internal constructor( team.isSelfATeamMember, updateSupportedProtocols ) - private val clearUserData: ClearUserDataUseCase get() = ClearUserDataUseCaseImpl(userStorage) + private val clearUserData: ClearUserDataUseCase get() = ClearUserDataUseCaseImpl(database) val validateAssetMimeType: ValidateAssetMimeTypeUseCase get() = ValidateAssetMimeTypeUseCaseImpl() val logout: LogoutUseCase diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/applock/AppLockTeamFeatureConfigObserver.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/applock/AppLockTeamFeatureConfigObserver.kt index 4064f67b1c7..9cf62e401f0 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/applock/AppLockTeamFeatureConfigObserver.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/applock/AppLockTeamFeatureConfigObserver.kt @@ -30,14 +30,14 @@ import kotlin.time.Duration.Companion.seconds * observe app lock feature flag of the team */ interface AppLockTeamFeatureConfigObserver { - operator fun invoke(): Flow + suspend operator fun invoke(): Flow } class AppLockTeamFeatureConfigObserverImpl( private val userConfigRepository: UserConfigRepository, private val kaliumConfigs: KaliumConfigs ) : AppLockTeamFeatureConfigObserver { - override fun invoke(): Flow { + override suspend fun invoke(): Flow { if (kaliumConfigs.teamAppLock) { return flowOf( AppLockTeamConfig( diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/applock/MarkTeamAppLockStatusAsNotifiedUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/applock/MarkTeamAppLockStatusAsNotifiedUseCase.kt index 026e8587b66..12761f4ab9b 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/applock/MarkTeamAppLockStatusAsNotifiedUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/applock/MarkTeamAppLockStatusAsNotifiedUseCase.kt @@ -25,13 +25,13 @@ import com.wire.kalium.logic.configuration.UserConfigRepository * e.g. after showing a dialog, or a toast etc. */ interface MarkTeamAppLockStatusAsNotifiedUseCase { - operator fun invoke() + suspend operator fun invoke() } class MarkTeamAppLockStatusAsNotifiedUseCaseImpl internal constructor( private val userConfigRepository: UserConfigRepository ) : MarkTeamAppLockStatusAsNotifiedUseCase { - override operator fun invoke() { + override suspend operator fun invoke() { userConfigRepository.setTeamAppLockAsNotified() } } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/auth/ClearUserDataUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/auth/ClearUserDataUseCase.kt index 76719036ee9..fc8e6b1b9db 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/auth/ClearUserDataUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/auth/ClearUserDataUseCase.kt @@ -18,7 +18,7 @@ package com.wire.kalium.logic.feature.auth -import com.wire.kalium.logic.di.UserStorage +import com.wire.kalium.persistence.db.UserDatabaseBuilder /** * Clears the user data from the local storage, except for the client id @@ -28,7 +28,7 @@ interface ClearUserDataUseCase { } internal class ClearUserDataUseCaseImpl internal constructor( - private val userStorage: UserStorage + private val database: UserDatabaseBuilder ) : ClearUserDataUseCase { override suspend operator fun invoke() { @@ -36,8 +36,6 @@ internal class ClearUserDataUseCaseImpl internal constructor( } private fun clearUserStorage() { - userStorage.database.nuke() - // exclude clientId clear from this step - userStorage.preferences.clear() + database.nuke() } } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/backup/BackupScope.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/backup/BackupScope.kt index 8f262a0fd5e..0a3e65d1769 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/backup/BackupScope.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/backup/BackupScope.kt @@ -22,11 +22,11 @@ package com.wire.kalium.logic.feature.backup import com.wire.kalium.logic.data.asset.KaliumFileSystem import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.data.user.UserRepository -import com.wire.kalium.logic.di.UserStorage import com.wire.kalium.logic.data.id.CurrentClientIdProvider import com.wire.kalium.logic.feature.message.PersistMigratedMessagesUseCase import com.wire.kalium.logic.sync.slow.RestartSlowSyncProcessForRecoveryUseCase import com.wire.kalium.logic.util.SecurityHelperImpl +import com.wire.kalium.persistence.db.UserDatabaseBuilder import com.wire.kalium.persistence.kmmSettings.GlobalPrefProvider @Suppress("LongParameterList") @@ -35,7 +35,7 @@ class BackupScope internal constructor( private val clientIdProvider: CurrentClientIdProvider, private val userRepository: UserRepository, private val kaliumFileSystem: KaliumFileSystem, - private val userStorage: UserStorage, + private val database: UserDatabaseBuilder, private val persistMigratedMessages: PersistMigratedMessagesUseCase, private val restartSlowSyncProcessForRecovery: RestartSlowSyncProcessForRecoveryUseCase, val globalPreferences: GlobalPrefProvider, @@ -46,7 +46,7 @@ class BackupScope internal constructor( clientIdProvider, userRepository, kaliumFileSystem, - userStorage.database.databaseExporter, + database.databaseExporter, securityHelper = SecurityHelperImpl(globalPreferences.passphraseStorage) ) @@ -59,12 +59,12 @@ class BackupScope internal constructor( userId, persistMigratedMessages, restartSlowSyncProcessForRecovery, - userStorage.database.migrationDAO + database.migrationDAO ) val restore: RestoreBackupUseCase get() = RestoreBackupUseCaseImpl( - userStorage.database.databaseImporter, + database.databaseImporter, kaliumFileSystem, userId, userRepository, diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/IsEligibleToStartCallUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/IsEligibleToStartCallUseCase.kt index c3b68714b42..fc5f6189e75 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/IsEligibleToStartCallUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/call/usecase/IsEligibleToStartCallUseCase.kt @@ -60,7 +60,7 @@ internal class IsEligibleToStartCallUseCaseImpl( else -> ConferenceCallingResult.Disabled.Unavailable } - private fun isConferenceCallingEnabled(): Boolean = userConfigRepository + private suspend fun isConferenceCallingEnabled(): Boolean = userConfigRepository .isConferenceCallingEnabled() .fold({ DEFAULT_CONFERENCE_CALLING_ENABLED_VALUE diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/ConversationScope.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/ConversationScope.kt index 105fd62efff..d4ccfd6eaaf 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/ConversationScope.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/ConversationScope.kt @@ -40,7 +40,6 @@ import com.wire.kalium.logic.data.properties.UserPropertyRepository import com.wire.kalium.logic.data.team.TeamRepository import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.data.user.UserRepository -import com.wire.kalium.logic.di.UserStorage import com.wire.kalium.logic.feature.connection.MarkConnectionRequestAsNotifiedUseCase import com.wire.kalium.logic.feature.connection.MarkConnectionRequestAsNotifiedUseCaseImpl import com.wire.kalium.logic.feature.connection.ObserveConnectionListUseCase @@ -64,10 +63,10 @@ import com.wire.kalium.logic.feature.team.DeleteTeamConversationUseCase import com.wire.kalium.logic.feature.team.DeleteTeamConversationUseCaseImpl import com.wire.kalium.logic.feature.team.GetSelfTeamUseCase import com.wire.kalium.logic.feature.team.GetSelfTeamUseCaseImpl -import com.wire.kalium.logic.feature.user.IsSelfATeamMemberUseCase import com.wire.kalium.logic.sync.SyncManager import com.wire.kalium.logic.sync.receiver.conversation.RenamedConversationEventHandler import com.wire.kalium.logic.sync.receiver.handler.CodeUpdateHandlerImpl +import com.wire.kalium.persistence.db.UserDatabaseBuilder import kotlinx.coroutines.CoroutineScope @Suppress("LongParameterList") @@ -89,10 +88,9 @@ class ConversationScope internal constructor( private val sendConfirmation: SendConfirmationUseCase, private val renamedConversationHandler: RenamedConversationEventHandler, private val qualifiedIdMapper: QualifiedIdMapper, - private val isSelfATeamMember: IsSelfATeamMemberUseCase, private val serverConfigRepository: ServerConfigRepository, - private val userStorage: UserStorage, - private val userPropertyRepository: UserPropertyRepository, + private val database: UserDatabaseBuilder, + userPropertyRepository: UserPropertyRepository, private val oneOnOneResolver: OneOnOneResolver, private val scope: CoroutineScope ) { @@ -248,7 +246,7 @@ class ConversationScope internal constructor( val generateGuestRoomLink: GenerateGuestRoomLinkUseCase get() = GenerateGuestRoomLinkUseCaseImpl( conversationGroupRepository, - CodeUpdateHandlerImpl(userStorage.database.conversationDAO) + CodeUpdateHandlerImpl(database.conversationDAO) ) val revokeGuestRoomLink: RevokeGuestRoomLinkUseCase diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/ObserveOtherUserSecurityClassificationLabelUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/ObserveOtherUserSecurityClassificationLabelUseCase.kt index f98af641371..4f970c07af8 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/ObserveOtherUserSecurityClassificationLabelUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/ObserveOtherUserSecurityClassificationLabelUseCase.kt @@ -57,7 +57,7 @@ internal class ObserveOtherUserSecurityClassificationLabelUseCaseImpl( } } - private fun getClassifiedDomainsStatus(): Flow?> = userConfigRepository.getClassifiedDomainsStatus() + private suspend fun getClassifiedDomainsStatus(): Flow?> = userConfigRepository.getClassifiedDomainsStatus() .mapToRightOr(null) .map { classifiedDomainsStatus -> if (classifiedDomainsStatus == null || !classifiedDomainsStatus.isClassifiedDomainsEnabled) { diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/AppLockConfigHandler.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/AppLockConfigHandler.kt index 35977292da4..eb6055b0bb9 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/AppLockConfigHandler.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/AppLockConfigHandler.kt @@ -29,7 +29,7 @@ import kotlin.time.Duration.Companion.seconds class AppLockConfigHandler( private val userConfigRepository: UserConfigRepository ) { - fun handle(appLockConfig: AppLockModel): Either { + suspend fun handle(appLockConfig: AppLockModel): Either { val isStatusChanged = userConfigRepository.isTeamAppLockEnabled().nullableFold( { diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/ClassifiedDomainsConfigHandler.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/ClassifiedDomainsConfigHandler.kt index 0f43653d019..ad9035a1158 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/ClassifiedDomainsConfigHandler.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/ClassifiedDomainsConfigHandler.kt @@ -23,10 +23,10 @@ import com.wire.kalium.logic.data.featureConfig.ClassifiedDomainsModel import com.wire.kalium.logic.data.featureConfig.Status import com.wire.kalium.logic.functional.Either -class ClassifiedDomainsConfigHandler( +internal class ClassifiedDomainsConfigHandler( private val userConfigRepository: UserConfigRepository ) { - fun handle(classifiedDomainsConfig: ClassifiedDomainsModel): Either { + suspend fun handle(classifiedDomainsConfig: ClassifiedDomainsModel): Either { val classifiedDomainsEnabled = classifiedDomainsConfig.status == Status.ENABLED return userConfigRepository.setClassifiedDomainsStatus(classifiedDomainsEnabled, classifiedDomainsConfig.config.domains) } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/ConferenceCallingConfigHandler.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/ConferenceCallingConfigHandler.kt index df3a5198f99..26496d45904 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/ConferenceCallingConfigHandler.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/ConferenceCallingConfigHandler.kt @@ -23,10 +23,10 @@ import com.wire.kalium.logic.data.featureConfig.ConferenceCallingModel import com.wire.kalium.logic.data.featureConfig.Status import com.wire.kalium.logic.functional.Either -class ConferenceCallingConfigHandler( +internal class ConferenceCallingConfigHandler internal constructor( private val userConfigRepository: UserConfigRepository ) { - fun handle(conferenceCallingConfig: ConferenceCallingModel): Either { + suspend fun handle(conferenceCallingConfig: ConferenceCallingModel): Either { val conferenceCallingEnabled = conferenceCallingConfig.status == Status.ENABLED return userConfigRepository.setConferenceCallingEnabled(conferenceCallingEnabled) } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/E2EIConfigHandler.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/E2EIConfigHandler.kt index 52b9d35970b..d948106aaa0 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/E2EIConfigHandler.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/E2EIConfigHandler.kt @@ -28,10 +28,10 @@ import kotlinx.datetime.Instant import kotlin.time.DurationUnit import kotlin.time.toDuration -class E2EIConfigHandler( +internal class E2EIConfigHandler internal constructor( private val userConfigRepository: UserConfigRepository, ) { - fun handle(e2eiConfig: E2EIModel): Either { + suspend fun handle(e2eiConfig: E2EIModel): Either { val gracePeriodEndMs = e2eiConfig.config.verificationExpirationNS.toDuration(DurationUnit.NANOSECONDS).inWholeMilliseconds userConfigRepository.setE2EISettings( E2EISettings( diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/FileSharingConfigHandler.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/FileSharingConfigHandler.kt index bd04e6633da..1e488d54bcf 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/FileSharingConfigHandler.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/FileSharingConfigHandler.kt @@ -24,10 +24,10 @@ import com.wire.kalium.logic.data.featureConfig.ConfigsStatusModel import com.wire.kalium.logic.data.featureConfig.Status import com.wire.kalium.logic.functional.Either -class FileSharingConfigHandler( +internal class FileSharingConfigHandler internal constructor( private val userConfigRepository: UserConfigRepository, ) { - fun handle(fileSharingConfig: ConfigsStatusModel): Either { + suspend fun handle(fileSharingConfig: ConfigsStatusModel): Either { val newStatus: Boolean = fileSharingConfig.status == Status.ENABLED val currentStatus = userConfigRepository.isFileSharingEnabled() val isStatusChanged: Boolean = when (currentStatus) { diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/GuestRoomConfigHandler.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/GuestRoomConfigHandler.kt index 15a83abd25d..8b04ace6fd4 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/GuestRoomConfigHandler.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/GuestRoomConfigHandler.kt @@ -25,11 +25,11 @@ import com.wire.kalium.logic.featureFlags.KaliumConfigs import com.wire.kalium.logic.functional.Either import com.wire.kalium.logic.functional.fold -class GuestRoomConfigHandler( +internal class GuestRoomConfigHandler internal constructor( private val userConfigRepository: UserConfigRepository, private val kaliumConfigs: KaliumConfigs ) { - fun handle(guestRoomConfig: ConfigsStatusModel): Either = + suspend fun handle(guestRoomConfig: ConfigsStatusModel): Either = if (!kaliumConfigs.guestRoomLink) { userConfigRepository.setGuestRoomStatus(false, null) } else { diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/SecondFactorPasswordChallengeConfigHandler.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/SecondFactorPasswordChallengeConfigHandler.kt index 4558f8c0d0b..e683b9e9faf 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/SecondFactorPasswordChallengeConfigHandler.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/SecondFactorPasswordChallengeConfigHandler.kt @@ -23,10 +23,10 @@ import com.wire.kalium.logic.data.featureConfig.ConfigsStatusModel import com.wire.kalium.logic.data.featureConfig.Status import com.wire.kalium.logic.functional.Either -class SecondFactorPasswordChallengeConfigHandler( +internal class SecondFactorPasswordChallengeConfigHandler internal constructor( private val userConfigRepository: UserConfigRepository ) { - fun handle(secondFactorPasswordChallengeConfig: ConfigsStatusModel): Either { + suspend fun handle(secondFactorPasswordChallengeConfig: ConfigsStatusModel): Either { val isRequired = secondFactorPasswordChallengeConfig.status == Status.ENABLED return userConfigRepository.setSecondFactorPasswordChallengeStatus(isRequired) } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/IsFileSharingEnabledUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/IsFileSharingEnabledUseCase.kt index afad437a015..c37dfbce8ae 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/IsFileSharingEnabledUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/IsFileSharingEnabledUseCase.kt @@ -28,14 +28,14 @@ import com.wire.kalium.logic.functional.fold */ interface IsFileSharingEnabledUseCase { - operator fun invoke(): FileSharingStatus + suspend operator fun invoke(): FileSharingStatus } -internal class IsFileSharingEnabledUseCaseImpl( +internal class IsFileSharingEnabledUseCaseImpl internal constructor( private val userConfigRepository: UserConfigRepository ) : IsFileSharingEnabledUseCase { - override operator fun invoke(): FileSharingStatus = + override suspend operator fun invoke(): FileSharingStatus = userConfigRepository.isFileSharingEnabled() .fold({ FileSharingStatus(FileSharingStatus.Value.Disabled, false) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/IsMLSEnabledUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/IsMLSEnabledUseCase.kt index bd74f25983a..43106567b38 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/IsMLSEnabledUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/IsMLSEnabledUseCase.kt @@ -29,7 +29,7 @@ interface IsMLSEnabledUseCase { /** * @return true if MLS is enabled, false otherwise. */ - operator fun invoke(): Boolean + suspend operator fun invoke(): Boolean } internal class IsMLSEnabledUseCaseImpl( @@ -37,7 +37,7 @@ internal class IsMLSEnabledUseCaseImpl( private val userConfigRepository: UserConfigRepository ) : IsMLSEnabledUseCase { - override operator fun invoke(): Boolean = + override suspend operator fun invoke(): Boolean = userConfigRepository.isMLSEnabled().fold({ false }, { diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/ObserveE2EIRequiredUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/ObserveE2EIRequiredUseCase.kt index 0dc2e1e260a..8b237f53f33 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/ObserveE2EIRequiredUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/ObserveE2EIRequiredUseCase.kt @@ -44,7 +44,7 @@ interface ObserveE2EIRequiredUseCase { /** * @return [Flow] of [E2EIRequiredResult] */ - operator fun invoke(): Flow + suspend operator fun invoke(): Flow } internal class ObserveE2EIRequiredUseCaseImpl( @@ -54,7 +54,7 @@ internal class ObserveE2EIRequiredUseCaseImpl( ) : ObserveE2EIRequiredUseCase { @OptIn(ExperimentalCoroutinesApi::class) - override fun invoke(): Flow { + override suspend fun invoke(): Flow { if (!featureSupport.isMLSSupported) return flowOf(E2EIRequiredResult.NotRequired) return userConfigRepository @@ -79,7 +79,7 @@ internal class ObserveE2EIRequiredUseCaseImpl( .flowOn(dispatcher) } - private fun observeE2EISettings() = userConfigRepository.observeE2EISettings().onlyRight().flowOn(dispatcher) + private suspend fun observeE2EISettings() = userConfigRepository.observeE2EISettings().onlyRight().flowOn(dispatcher) private fun observeCurrentE2EICertificate(): Flow { // TODO get current client E2EI certificate data here diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/ObserveFileSharingStatusUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/ObserveFileSharingStatusUseCase.kt index fcc6b01d404..d2dc05783e6 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/ObserveFileSharingStatusUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/ObserveFileSharingStatusUseCase.kt @@ -32,12 +32,12 @@ import kotlinx.coroutines.flow.map */ interface ObserveFileSharingStatusUseCase { - operator fun invoke(): Flow + suspend operator fun invoke(): Flow } internal class ObserveFileSharingStatusUseCaseImpl(private val userConfigRepository: UserConfigRepository) : ObserveFileSharingStatusUseCase { - override operator fun invoke(): Flow = + override suspend operator fun invoke(): Flow = userConfigRepository.isFileSharingEnabledFlow().map { fileSharingStatusFlow -> fileSharingStatusFlow.fold({ when (it) { diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/guestroomlink/MarkGuestLinkFeatureFlagAsNotChangedUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/guestroomlink/MarkGuestLinkFeatureFlagAsNotChangedUseCase.kt index 044b44f9ae7..d1ab9e3e711 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/guestroomlink/MarkGuestLinkFeatureFlagAsNotChangedUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/guestroomlink/MarkGuestLinkFeatureFlagAsNotChangedUseCase.kt @@ -25,13 +25,13 @@ import com.wire.kalium.logic.functional.onSuccess * Mark Guest Link Feature Flag state as not changed */ interface MarkGuestLinkFeatureFlagAsNotChangedUseCase { - operator fun invoke() + suspend operator fun invoke() } class MarkGuestLinkFeatureFlagAsNotChangedUseCaseImpl internal constructor( private val userConfigRepository: UserConfigRepository ) : MarkGuestLinkFeatureFlagAsNotChangedUseCase { - override operator fun invoke() { + override suspend operator fun invoke() { userConfigRepository.getGuestRoomLinkStatus().onSuccess { it.isStatusChanged?.let { isEnabled -> userConfigRepository.setGuestRoomStatus(isEnabled, false) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/UserPropertiesEventReceiver.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/UserPropertiesEventReceiver.kt index 12a7801efc8..59b98f36879 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/UserPropertiesEventReceiver.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/UserPropertiesEventReceiver.kt @@ -45,7 +45,7 @@ internal class UserPropertiesEventReceiverImpl internal constructor( } } - private fun handleReadReceiptMode( + private suspend fun handleReadReceiptMode( event: Event.UserProperty.ReadReceiptModeSet ): Either = userConfigRepository @@ -66,7 +66,7 @@ internal class UserPropertiesEventReceiverImpl internal constructor( ) } - private fun handleTypingIndicatorMode( + private suspend fun handleTypingIndicatorMode( event: Event.UserProperty.TypingIndicatorModeSet ): Either = userConfigRepository diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/slow/SlowSyncManager.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/slow/SlowSyncManager.kt index dc03f90eb95..baba61f5961 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/slow/SlowSyncManager.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/slow/SlowSyncManager.kt @@ -192,7 +192,7 @@ internal class SlowSyncManager( * Useful when a new step is added to Slow Sync, or when we fix some bug in Slow Sync, * and we'd like to get all users to take advantage of the fix. */ - const val CURRENT_VERSION = 7 + const val CURRENT_VERSION = 8 val MIN_RETRY_DELAY = 1.seconds val MAX_RETRY_DELAY = 10.minutes diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/featureConfig/SyncFeatureConfigsUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/featureConfig/SyncFeatureConfigsUseCaseTest.kt index 7eae5a2597a..6a871f22e70 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/featureConfig/SyncFeatureConfigsUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/featureConfig/SyncFeatureConfigsUseCaseTest.kt @@ -53,7 +53,7 @@ import com.wire.kalium.logic.test_util.TestNetworkException import com.wire.kalium.logic.util.shouldSucceed import com.wire.kalium.persistence.config.inMemoryUserConfigStorage import com.wire.kalium.persistence.dao.SupportedProtocolEntity -import com.wire.kalium.persistence.dao.unread.UserConfigDAO +import com.wire.kalium.persistence.dao.config.UserConfigDAO import io.mockative.Mock import io.mockative.any import io.mockative.classOf diff --git a/persistence/src/androidMain/kotlin/com/wire/kalium/persistence/kmmSettings/UserPrefBuilder.kt b/persistence/src/androidMain/kotlin/com/wire/kalium/persistence/kmmSettings/UserPrefBuilder.kt deleted file mode 100644 index bb0c6c2c2da..00000000000 --- a/persistence/src/androidMain/kotlin/com/wire/kalium/persistence/kmmSettings/UserPrefBuilder.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Wire - * Copyright (C) 2023 Wire Swiss GmbH - * - * This program 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. - * - * This program 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 this program. If not, see http://www.gnu.org/licenses/. - */ - -package com.wire.kalium.persistence.kmmSettings - -import android.content.Context -import com.wire.kalium.persistence.client.LastRetrievedNotificationEventStorage -import com.wire.kalium.persistence.client.LastRetrievedNotificationEventStorageImpl -import com.wire.kalium.persistence.config.UserConfigStorage -import com.wire.kalium.persistence.config.UserConfigStorageImpl -import com.wire.kalium.persistence.dao.UserIDEntity - -actual class UserPrefBuilder( - userId: UserIDEntity, - context: Context, - shouldEncryptData: Boolean = true -) { - private val encryptedSettingsHolder = - KaliumPreferencesSettings( - EncryptedSettingsBuilder.build( - SettingOptions.UserSettings(shouldEncryptData = shouldEncryptData, userIDEntity = userId), - EncryptedSettingsPlatformParam(context) - ) - ) - - actual val lastRetrievedNotificationEventStorage: LastRetrievedNotificationEventStorage - get() = LastRetrievedNotificationEventStorageImpl(encryptedSettingsHolder) - - actual val userConfigStorage: UserConfigStorage = UserConfigStorageImpl(encryptedSettingsHolder) - - actual fun clear() { - encryptedSettingsHolder.nuke() - } -} diff --git a/persistence/src/appleMain/kotlin/com/wire/kalium/persistence/kmmSettings/UserPrefBuilder.kt b/persistence/src/appleMain/kotlin/com/wire/kalium/persistence/kmmSettings/UserPrefBuilder.kt deleted file mode 100644 index 1405bba7641..00000000000 --- a/persistence/src/appleMain/kotlin/com/wire/kalium/persistence/kmmSettings/UserPrefBuilder.kt +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Wire - * Copyright (C) 2023 Wire Swiss GmbH - * - * This program 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. - * - * This program 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 this program. If not, see http://www.gnu.org/licenses/. - */ - -package com.wire.kalium.persistence.kmmSettings - -import com.wire.kalium.persistence.client.LastRetrievedNotificationEventStorage -import com.wire.kalium.persistence.client.LastRetrievedNotificationEventStorageImpl -import com.wire.kalium.persistence.config.UserConfigStorage -import com.wire.kalium.persistence.config.UserConfigStorageImpl -import com.wire.kalium.persistence.dao.UserIDEntity - -actual class UserPrefBuilder( - userId: UserIDEntity, - rootPath: String, - shouldEncryptData: Boolean = true -) { - - private val kaliumPreferences = - KaliumPreferencesSettings( - EncryptedSettingsBuilder.build(SettingOptions.UserSettings(shouldEncryptData, userId), EncryptedSettingsPlatformParam(rootPath)) - ) - - actual val lastRetrievedNotificationEventStorage: LastRetrievedNotificationEventStorage - get() = LastRetrievedNotificationEventStorageImpl(kaliumPreferences) - - actual fun clear() { - kaliumPreferences.nuke() - } - - actual val userConfigStorage: UserConfigStorage = - UserConfigStorageImpl(kaliumPreferences) - -} diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/client/LastRetrievedNotificationEventStorage.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/client/LastRetrievedNotificationEventStorage.kt deleted file mode 100644 index 20c14711e21..00000000000 --- a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/client/LastRetrievedNotificationEventStorage.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Wire - * Copyright (C) 2023 Wire Swiss GmbH - * - * This program 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. - * - * This program 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 this program. If not, see http://www.gnu.org/licenses/. - */ - -package com.wire.kalium.persistence.client - -import com.wire.kalium.persistence.kmmSettings.KaliumPreferences - -interface LastRetrievedNotificationEventStorage { - /** - * to save the id of the last event retrieved from the notifications stream - */ - fun saveEvent(eventId: String) - - /** - * get the id of the last saved event if one exists - */ - fun getLastEventId(): String? -} - -internal class LastRetrievedNotificationEventStorageImpl internal constructor( - private val kaliumPreferences: KaliumPreferences -) : LastRetrievedNotificationEventStorage { - - override fun saveEvent(eventId: String) { - kaliumPreferences.putString( - LAST_NOTIFICATION_STREAM_EVENT_ID, - eventId - ) - } - - override fun getLastEventId(): String? = - kaliumPreferences.getString(LAST_NOTIFICATION_STREAM_EVENT_ID) - - private companion object { - const val LAST_NOTIFICATION_STREAM_EVENT_ID = "last_notification_stream_event_id" - } -} diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/config/UserConfigStorage.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/config/UserConfigStorage.kt deleted file mode 100644 index 6bc36aa42e7..00000000000 --- a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/config/UserConfigStorage.kt +++ /dev/null @@ -1,501 +0,0 @@ -/* - * Wire - * Copyright (C) 2023 Wire Swiss GmbH - * - * This program 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. - * - * This program 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 this program. If not, see http://www.gnu.org/licenses/. - */ - -package com.wire.kalium.persistence.config - -import com.wire.kalium.persistence.dao.SupportedProtocolEntity -import com.wire.kalium.persistence.kmmSettings.KaliumPreferences -import com.wire.kalium.util.time.Second -import kotlinx.coroutines.channels.BufferOverflow -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.onStart -import kotlinx.datetime.Instant -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import kotlin.time.Duration - -@Suppress("TooManyFunctions") -interface UserConfigStorage { - - /** - * save flag from the user settings to enforce and disable App Lock - */ - fun persistAppLockStatus( - isEnforced: Boolean, - inactivityTimeoutSecs: Second, - isStatusChanged: Boolean? - ) - - /** - * get the saved flag to know if App Lock is enforced or not - */ - fun appLockStatus(): AppLockConfigEntity? - - /** - * returns a Flow of the saved App Lock status - */ - fun appLockFlow(): Flow - - fun setTeamAppLockAsNotified() - - /** - * Save flag from the file sharing api, and if the status changes - */ - fun persistFileSharingStatus(status: Boolean, isStatusChanged: Boolean?) - - /** - * Get the saved flag that been saved to know if the file sharing is enabled or not with the flag - * to know if there was a status change - */ - fun isFileSharingEnabled(): IsFileSharingEnabledEntity? - - /** - * Returns the Flow of file sharing status - */ - fun isFileSharingEnabledFlow(): Flow - - fun setFileSharingAsNotified() - - /** - * Returns a Flow containing the status and list of classified domains - */ - fun isClassifiedDomainsEnabledFlow(): Flow - - /** - *Save the flag and list of trusted domains - */ - fun persistClassifiedDomainsStatus(status: Boolean, classifiedDomains: List) - - /** - * Saves the flag that indicates whether a 2FA challenge is - * required for some operations such as: - * Login, Create Account, Register Client, etc. - * @see isSecondFactorPasswordChallengeRequired - */ - fun persistSecondFactorPasswordChallengeStatus(isRequired: Boolean) - - /** - * Checks if the 2FA challenge is - * required for some operations such as: - * Login, Create Account, Register Client, etc. - * @see persistSecondFactorPasswordChallengeStatus - */ - fun isSecondFactorPasswordChallengeRequired(): Boolean - - /** - * Save default protocol to use - */ - fun persistDefaultProtocol(protocol: SupportedProtocolEntity) - - /** - * Gets default protocol to use. Defaults to PROTEUS if not default protocol has been saved. - */ - fun defaultProtocol(): SupportedProtocolEntity - - /** - * Save flag from the user settings to enable and disable MLS - */ - fun enableMLS(enabled: Boolean) - - /** - * Get the saved flag to know if MLS enabled or not - */ - fun isMLSEnabled(): Boolean - - /** - * Save MLSE2EISetting - */ - fun setE2EISettings(settingEntity: E2EISettingsEntity) - - /** - * Get MLSE2EISetting - */ - fun getE2EISettings(): E2EISettingsEntity? - - /** - * Get Flow of the saved MLSE2EISetting - */ - fun e2EISettingsFlow(): Flow - - /** - * Save flag from user settings to enable or disable Conference Calling - */ - fun persistConferenceCalling(enabled: Boolean) - - /** - * Get the saved flag to know if Conference Calling is enabled or not - */ - fun isConferenceCallingEnabled(): Boolean - - /** - * Get the saved flag to know whether user's Read Receipts are currently enabled or not - */ - fun areReadReceiptsEnabled(): Flow - - /** - * Persist the flag to indicate if user's Read Receipts are enabled or not. - */ - fun persistReadReceipts(enabled: Boolean) - - /** - * Get the saved global flag to know whether user's typing indicator is currently enabled or not. - */ - fun isTypingIndicatorEnabled(): Flow - - /** - * Persist the flag to indicate whether user's typing indicator global flag is enabled or not. - */ - fun persistTypingIndicator(enabled: Boolean) - - fun persistGuestRoomLinkFeatureFlag(status: Boolean, isStatusChanged: Boolean?) - fun isGuestRoomLinkEnabled(): IsGuestRoomLinkEnabledEntity? - fun isGuestRoomLinkEnabledFlow(): Flow - fun isScreenshotCensoringEnabledFlow(): Flow - fun persistScreenshotCensoring(enabled: Boolean) - fun setE2EINotificationTime(timeStamp: Long) - fun getE2EINotificationTime(): Long? - fun e2EINotificationTimeFlow(): Flow -} - -@Serializable -data class IsFileSharingEnabledEntity( - @SerialName("status") val status: Boolean, - @SerialName("isStatusChanged") val isStatusChanged: Boolean? -) - -@Serializable -data class ClassifiedDomainsEntity( - @SerialName("status") val status: Boolean, - @SerialName("trustedDomains") val trustedDomains: List, -) - -@Serializable -data class IsGuestRoomLinkEnabledEntity( - @SerialName("status") val status: Boolean, - @SerialName("isStatusChanged") val isStatusChanged: Boolean? -) - -@Serializable -data class TeamSettingsSelfDeletionStatusEntity( - @SerialName("selfDeletionTimer") val selfDeletionTimerEntity: SelfDeletionTimerEntity, - @SerialName("isStatusChanged") val isStatusChanged: Boolean? -) - -@Serializable -data class E2EISettingsEntity( - @SerialName("status") val status: Boolean, - @SerialName("discoverUrl") val discoverUrl: String, - @SerialName("gracePeriodEndMs") val gracePeriodEndMs: Long?, -) - -@Serializable -data class AppLockConfigEntity( - @SerialName("inactivityTimeoutSecs") val inactivityTimeoutSecs: Second, - @SerialName("enforceAppLock") val enforceAppLock: Boolean, - @SerialName("isStatusChanged") val isStatusChanged: Boolean? -) - -@Serializable -sealed class SelfDeletionTimerEntity { - - @Serializable - @SerialName("disabled") - data object Disabled : SelfDeletionTimerEntity() - - @Serializable - @SerialName("enabled") - data object Enabled : SelfDeletionTimerEntity() - - @Serializable - @SerialName("enforced") - data class Enforced(val enforcedDuration: Duration) : SelfDeletionTimerEntity() -} - -@Serializable -data class MLSMigrationEntity( - @Serializable val status: Boolean, - @Serializable val startTime: Instant?, - @Serializable val endTime: Instant?, -) - -@Suppress("TooManyFunctions") -class UserConfigStorageImpl( - private val kaliumPreferences: KaliumPreferences -) : UserConfigStorage { - - private val areReadReceiptsEnabledFlow = - MutableSharedFlow(extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) - - private val isTypingIndicatorEnabledFlow = - MutableSharedFlow(extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) - - private val isFileSharingEnabledFlow = - MutableSharedFlow(extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) - - private val isClassifiedDomainsEnabledFlow = - MutableSharedFlow(extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) - - private val isGuestRoomLinkEnabledFlow = - MutableSharedFlow(extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) - - private val e2EIFlow = - MutableSharedFlow(extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) - - private val e2EINotificationFlow = - MutableSharedFlow(extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) - - private val isScreenshotCensoringEnabledFlow = - MutableSharedFlow(extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) - - private val appLockFlow = - MutableSharedFlow(extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) - - override fun persistAppLockStatus( - isEnforced: Boolean, - inactivityTimeoutSecs: Second, - isStatusChanged: Boolean? - ) { - kaliumPreferences.putSerializable( - APP_LOCK, - AppLockConfigEntity(inactivityTimeoutSecs, isEnforced, isStatusChanged), - AppLockConfigEntity.serializer(), - ).also { - appLockFlow.tryEmit(Unit) - } - } - - override fun setTeamAppLockAsNotified() { - val newValue = - kaliumPreferences.getSerializable(APP_LOCK, AppLockConfigEntity.serializer())?.copy(isStatusChanged = false) - ?: return - kaliumPreferences.putSerializable( - APP_LOCK, - newValue, - AppLockConfigEntity.serializer() - ).also { - appLockFlow.tryEmit(Unit) - } - } - - override fun appLockStatus(): AppLockConfigEntity? = - kaliumPreferences.getSerializable(APP_LOCK, AppLockConfigEntity.serializer()) - - override fun appLockFlow(): Flow = appLockFlow.map { - appLockStatus() - }.onStart { - emit(appLockStatus()) - } - - override fun persistFileSharingStatus( - status: Boolean, - isStatusChanged: Boolean? - ) { - kaliumPreferences.putSerializable( - FILE_SHARING, - IsFileSharingEnabledEntity(status, isStatusChanged), - IsFileSharingEnabledEntity.serializer() - ).also { - isFileSharingEnabledFlow.tryEmit(Unit) - } - } - - override fun isFileSharingEnabled(): IsFileSharingEnabledEntity? = - kaliumPreferences.getSerializable(FILE_SHARING, IsFileSharingEnabledEntity.serializer()) - - override fun isFileSharingEnabledFlow(): Flow = isFileSharingEnabledFlow - .map { isFileSharingEnabled() } - .onStart { emit(isFileSharingEnabled()) } - .distinctUntilChanged() - - override fun setFileSharingAsNotified() { - val newValue = - kaliumPreferences.getSerializable(FILE_SHARING, IsFileSharingEnabledEntity.serializer())?.copy(isStatusChanged = false) - ?: return - kaliumPreferences.putSerializable( - FILE_SHARING, - newValue, - IsFileSharingEnabledEntity.serializer() - ).also { - isFileSharingEnabledFlow.tryEmit(Unit) - } - } - - override fun isClassifiedDomainsEnabledFlow(): Flow { - return isClassifiedDomainsEnabledFlow - .map { - kaliumPreferences.getSerializable(ENABLE_CLASSIFIED_DOMAINS, ClassifiedDomainsEntity.serializer())!! - }.onStart { - emit( - kaliumPreferences.getSerializable( - ENABLE_CLASSIFIED_DOMAINS, - ClassifiedDomainsEntity.serializer() - )!! - ) - }.distinctUntilChanged() - } - - override fun persistClassifiedDomainsStatus(status: Boolean, classifiedDomains: List) { - kaliumPreferences.putSerializable( - ENABLE_CLASSIFIED_DOMAINS, - ClassifiedDomainsEntity(status, classifiedDomains), - ClassifiedDomainsEntity.serializer() - ).also { - isClassifiedDomainsEnabledFlow.tryEmit(Unit) - } - } - - override fun persistSecondFactorPasswordChallengeStatus(isRequired: Boolean) { - kaliumPreferences.putBoolean(REQUIRE_SECOND_FACTOR_PASSWORD_CHALLENGE, isRequired) - } - - override fun isSecondFactorPasswordChallengeRequired(): Boolean = - kaliumPreferences.getBoolean(REQUIRE_SECOND_FACTOR_PASSWORD_CHALLENGE, false) - - override fun persistDefaultProtocol(protocol: SupportedProtocolEntity) { - kaliumPreferences.putString(DEFAULT_PROTOCOL, protocol.name) - } - - override fun defaultProtocol(): SupportedProtocolEntity = - kaliumPreferences.getString(DEFAULT_PROTOCOL)?.let { SupportedProtocolEntity.valueOf(it) } - ?: SupportedProtocolEntity.PROTEUS - - override fun enableMLS(enabled: Boolean) { - kaliumPreferences.putBoolean(ENABLE_MLS, enabled) - } - - override fun isMLSEnabled(): Boolean = kaliumPreferences.getBoolean(ENABLE_MLS, false) - - override fun setE2EISettings(settingEntity: E2EISettingsEntity) { - kaliumPreferences.putSerializable( - E2EI_SETTINGS, - settingEntity, - E2EISettingsEntity.serializer() - ).also { - e2EIFlow.tryEmit(Unit) - } - } - - override fun getE2EISettings(): E2EISettingsEntity? { - return kaliumPreferences.getSerializable(E2EI_SETTINGS, E2EISettingsEntity.serializer()) - } - - override fun e2EISettingsFlow(): Flow = e2EIFlow - .map { getE2EISettings() } - .onStart { emit(getE2EISettings()) } - .distinctUntilChanged() - - override fun setE2EINotificationTime(timeStamp: Long) { - kaliumPreferences.putLong( - E2EI_NOTIFICATION_TIME, - timeStamp - ).also { - e2EIFlow.tryEmit(Unit) - } - } - - override fun getE2EINotificationTime(): Long? { - return kaliumPreferences.getLong(E2EI_NOTIFICATION_TIME) - } - - override fun e2EINotificationTimeFlow(): Flow = e2EINotificationFlow - .map { getE2EINotificationTime() } - .onStart { emit(getE2EINotificationTime()) } - .distinctUntilChanged() - - override fun persistConferenceCalling(enabled: Boolean) { - kaliumPreferences.putBoolean(ENABLE_CONFERENCE_CALLING, enabled) - } - - override fun isConferenceCallingEnabled(): Boolean = - kaliumPreferences.getBoolean(ENABLE_CONFERENCE_CALLING, DEFAULT_CONFERENCE_CALLING_ENABLED_VALUE) - - override fun areReadReceiptsEnabled(): Flow = areReadReceiptsEnabledFlow - .map { kaliumPreferences.getBoolean(ENABLE_READ_RECEIPTS, true) } - .onStart { emit(kaliumPreferences.getBoolean(ENABLE_READ_RECEIPTS, true)) } - .distinctUntilChanged() - - override fun persistReadReceipts(enabled: Boolean) { - kaliumPreferences.putBoolean(ENABLE_READ_RECEIPTS, enabled).also { - areReadReceiptsEnabledFlow.tryEmit(Unit) - } - } - - override fun isTypingIndicatorEnabled(): Flow = isTypingIndicatorEnabledFlow - .map { kaliumPreferences.getBoolean(ENABLE_TYPING_INDICATOR, true) } - .onStart { emit(kaliumPreferences.getBoolean(ENABLE_TYPING_INDICATOR, true)) } - .distinctUntilChanged() - - override fun persistTypingIndicator(enabled: Boolean) { - kaliumPreferences.putBoolean(ENABLE_TYPING_INDICATOR, enabled).also { - isTypingIndicatorEnabledFlow.tryEmit(Unit) - } - } - - override fun persistGuestRoomLinkFeatureFlag( - status: Boolean, - isStatusChanged: Boolean? - ) { - kaliumPreferences.putSerializable( - GUEST_ROOM_LINK, - IsGuestRoomLinkEnabledEntity(status, isStatusChanged), - IsGuestRoomLinkEnabledEntity.serializer() - ).also { - isGuestRoomLinkEnabledFlow.tryEmit(Unit) - } - } - - override fun isGuestRoomLinkEnabled(): IsGuestRoomLinkEnabledEntity? = - kaliumPreferences.getSerializable(GUEST_ROOM_LINK, IsGuestRoomLinkEnabledEntity.serializer()) - - override fun isGuestRoomLinkEnabledFlow(): Flow = - isGuestRoomLinkEnabledFlow - .map { isGuestRoomLinkEnabled() } - .onStart { emit(isGuestRoomLinkEnabled()) } - .distinctUntilChanged() - - override fun isScreenshotCensoringEnabledFlow(): Flow = isScreenshotCensoringEnabledFlow - .map { kaliumPreferences.getBoolean(ENABLE_SCREENSHOT_CENSORING, false) } - .onStart { emit(kaliumPreferences.getBoolean(ENABLE_SCREENSHOT_CENSORING, false)) } - .distinctUntilChanged() - - override fun persistScreenshotCensoring(enabled: Boolean) { - kaliumPreferences.putBoolean(ENABLE_SCREENSHOT_CENSORING, enabled).also { - isScreenshotCensoringEnabledFlow.tryEmit(Unit) - } - } - - private companion object { - const val FILE_SHARING = "file_sharing" - const val GUEST_ROOM_LINK = "guest_room_link" - const val ENABLE_CLASSIFIED_DOMAINS = "enable_classified_domains" - const val ENABLE_MLS = "enable_mls" - const val E2EI_SETTINGS = "end_to_end_identity_settings" - const val E2EI_NOTIFICATION_TIME = "end_to_end_identity_notification_time" - const val ENABLE_CONFERENCE_CALLING = "enable_conference_calling" - const val ENABLE_READ_RECEIPTS = "enable_read_receipts" - const val DEFAULT_CONFERENCE_CALLING_ENABLED_VALUE = false - const val REQUIRE_SECOND_FACTOR_PASSWORD_CHALLENGE = "require_second_factor_password_challenge" - const val ENABLE_SCREENSHOT_CENSORING = "enable_screenshot_censoring" - const val ENABLE_TYPING_INDICATOR = "enable_typing_indicator" - const val APP_LOCK = "app_lock" - const val DEFAULT_PROTOCOL = "default_protocol" - } -} diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/MetadataDAO.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/MetadataDAO.kt index 7a37aaab2b8..e8fb0ee3216 100644 --- a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/MetadataDAO.kt +++ b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/MetadataDAO.kt @@ -26,6 +26,10 @@ interface MetadataDAO { suspend fun deleteValue(key: String) suspend fun valueByKeyFlow(key: String): Flow suspend fun valueByKey(key: String): String? + suspend fun insertBooleanValue(key: String, value: Boolean) + suspend fun modifySerriedValue(key: String, newValueBlock: (oldValue: T) -> T, kSerializer: KSerializer) + suspend fun getBooleanValue(key: String): Boolean? + suspend fun observeBooleanValue(key: String, defaultValue: Boolean): Flow suspend fun clear(keysToKeep: List?) suspend fun putSerializable(key: String, value: T, kSerializer: KSerializer) suspend fun getSerializable(key: String, kSerializer: KSerializer): T? diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/MetadataDAOImpl.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/MetadataDAOImpl.kt index ec4d9e436cd..078b5a53551 100644 --- a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/MetadataDAOImpl.kt +++ b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/MetadataDAOImpl.kt @@ -33,7 +33,8 @@ import kotlinx.coroutines.withContext import kotlinx.serialization.KSerializer import kotlin.coroutines.CoroutineContext -class MetadataDAOImpl internal constructor( +@Suppress("TooManyFunctions") +internal class MetadataDAOImpl internal constructor( private val metadataQueries: MetadataQueries, private val metadataCache: Cache>, private val databaseScope: CoroutineScope, @@ -60,6 +61,41 @@ class MetadataDAOImpl internal constructor( metadataQueries.selectValueByKey(key).executeAsOneOrNull() } + override suspend fun insertBooleanValue(key: String, value: Boolean) = withContext(queriesContext) { + metadataQueries.insertValue(key, booleanToString(value)) + } + + override suspend fun modifySerriedValue(key: String, newValueBlock: (oldValue: T) -> T, kSerializer: KSerializer) = + withContext(queriesContext) { + metadataQueries.transaction { + val oldValue = metadataQueries.selectValueByKey(key).executeAsOneOrNull()?.let { + JsonSerializer().decodeFromString(kSerializer, it) + } ?: return@transaction + + val newValue = newValueBlock(oldValue).let { + JsonSerializer().encodeToString(kSerializer, it) + } + + metadataQueries.insertValue(key = key, stringValue = newValue) + } + } + + override suspend fun getBooleanValue(key: String): Boolean? = withContext(queriesContext) { + metadataQueries.selectValueByKey(key).executeAsOneOrNull()?.let { + stringToBoolean(it) + } + } + + override suspend fun observeBooleanValue(key: String, defaultValue: Boolean): Flow = withContext(queriesContext) { + metadataQueries.selectValueByKey(key) + .asFlow() + .mapToOneOrNull() + .map { value -> value?.let { stringToBoolean(it) } ?: defaultValue } + .distinctUntilChanged() + .shareIn(databaseScope, SharingStarted.Lazily, 1) + + } + override suspend fun clear(keysToKeep: List?) = withContext(queriesContext) { if (keysToKeep == null) { metadataQueries.deleteAll() @@ -92,4 +128,19 @@ class MetadataDAOImpl internal constructor( .distinctUntilChanged() .shareIn(databaseScope, SharingStarted.Lazily, 1) } + + private fun stringToBoolean(value: String): Boolean? { + return when (value) { + "true" -> true + "false" -> false + else -> null + } + } + + private fun booleanToString(value: Boolean): String { + return when (value) { + true -> "true" + false -> "false" + } + } } diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/MLSConfigDAO.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/MLSConfigDAO.kt new file mode 100644 index 00000000000..2e0676ede81 --- /dev/null +++ b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/MLSConfigDAO.kt @@ -0,0 +1,91 @@ +/* + * Wire + * Copyright (C) 2023 Wire Swiss GmbH + * + * This program 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. + * + * This program 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 this program. If not, see http://www.gnu.org/licenses/. + */ +package com.wire.kalium.persistence.dao.config + +import com.wire.kalium.persistence.dao.MetadataDAO +import com.wire.kalium.persistence.dao.config.model.E2EISettingsEntity +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +interface MLSConfigDAO { + /** + * Save flag from the user settings to enable and disable MLS + */ + suspend fun enableMLS(enabled: Boolean) + + /** + * Get the saved flag to know if MLS enabled or not + */ + suspend fun isMLSEnabled(): Boolean + + /** + * Save MLSE2EISetting + */ + suspend fun setE2EISettings(settingEntity: E2EISettingsEntity) + + /** + * Get MLSE2EISetting + */ + suspend fun getE2EISettings(): E2EISettingsEntity? + + /** + * Get Flow of the saved MLSE2EISetting + */ + suspend fun e2EISettingsFlow(): Flow + + suspend fun setE2EINotificationTime(timeStamp: Long) + suspend fun getE2EINotificationTime(): Long? + suspend fun e2EINotificationTimeFlow(): Flow +} + +internal class MLSConfigDAOImpl internal constructor( + private val metadataDAO: MetadataDAO +) : MLSConfigDAO { + + override suspend fun enableMLS(enabled: Boolean) = + metadataDAO.insertBooleanValue(ENABLE_MLS, enabled) + + override suspend fun isMLSEnabled(): Boolean = + metadataDAO.getBooleanValue(ENABLE_MLS) ?: false + + override suspend fun setE2EISettings(settingEntity: E2EISettingsEntity) { + metadataDAO.putSerializable(E2EI_SETTINGS, settingEntity, E2EISettingsEntity.serializer()) + } + + override suspend fun getE2EISettings(): E2EISettingsEntity? = + metadataDAO.getSerializable(E2EI_SETTINGS, E2EISettingsEntity.serializer()) + + override suspend fun e2EISettingsFlow(): Flow = + metadataDAO.observeSerializable(E2EI_SETTINGS, E2EISettingsEntity.serializer()) + + override suspend fun setE2EINotificationTime(timeStamp: Long) { + metadataDAO.insertValue(timeStamp.toString(), E2EI_NOTIFICATION_TIME) + } + + override suspend fun getE2EINotificationTime(): Long? = + metadataDAO.valueByKey(E2EI_NOTIFICATION_TIME)?.toLongOrNull() + + override suspend fun e2EINotificationTimeFlow(): Flow = + metadataDAO.valueByKeyFlow(E2EI_NOTIFICATION_TIME).map { it?.toLongOrNull() } + + private companion object { + const val ENABLE_MLS = "enable_mls" + const val E2EI_SETTINGS = "end_to_end_identity_settings" + const val E2EI_NOTIFICATION_TIME = "end_to_end_identity_notification_time" + } +} diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/UserConfigDAO.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/UserConfigDAO.kt new file mode 100644 index 00000000000..611cb2df071 --- /dev/null +++ b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/UserConfigDAO.kt @@ -0,0 +1,350 @@ +/* + * Wire + * Copyright (C) 2023 Wire Swiss GmbH + * + * This program 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. + * + * This program 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 this program. If not, see http://www.gnu.org/licenses/. + */ +package com.wire.kalium.persistence.dao.config + +import com.wire.kalium.persistence.dao.config.model.MLSMigrationEntity +import com.wire.kalium.persistence.dao.config.model.TeamSettingsSelfDeletionStatusEntity +import com.wire.kalium.persistence.dao.MetadataDAO +import com.wire.kalium.persistence.dao.SupportedProtocolEntity +import com.wire.kalium.persistence.dao.config.model.AppLockConfigEntity +import com.wire.kalium.persistence.dao.config.model.ClassifiedDomainsEntity +import com.wire.kalium.persistence.dao.config.model.IsFileSharingEnabledEntity +import com.wire.kalium.persistence.dao.config.model.IsGuestRoomLinkEnabledEntity +import com.wire.kalium.util.time.Second +import kotlinx.coroutines.flow.Flow +import kotlinx.serialization.builtins.SetSerializer + +@Suppress("TooManyFunctions") +interface UserConfigDAO { + + suspend fun getTeamSettingsSelfDeletionStatus(): TeamSettingsSelfDeletionStatusEntity? + suspend fun setTeamSettingsSelfDeletionStatus( + teamSettingsSelfDeletionStatusEntity: TeamSettingsSelfDeletionStatusEntity + ) + + suspend fun markTeamSettingsSelfDeletingMessagesStatusAsNotified() + suspend fun observeTeamSettingsSelfDeletingStatus(): Flow + + suspend fun getMigrationConfiguration(): MLSMigrationEntity? + suspend fun setMigrationConfiguration(configuration: MLSMigrationEntity) + + suspend fun getSupportedProtocols(): Set? + suspend fun setSupportedProtocols(protocols: Set) + + /** + * save flag from the user settings to enforce and disable App Lock + */ + suspend fun persistAppLockStatus( + isEnforced: Boolean, + inactivityTimeoutSecs: Second, + isStatusChanged: Boolean? + ) + + /** + * get the saved flag to know if App Lock is enforced or not + */ + suspend fun appLockStatus(): AppLockConfigEntity? + + /** + * returns a Flow of the saved App Lock status + */ + suspend fun appLockFlow(): Flow + + suspend fun setTeamAppLockAsNotified() + + /** + * Save flag from the file sharing api, and if the status changes + */ + suspend fun persistFileSharingStatus(status: Boolean, isStatusChanged: Boolean?) + + /** + * Get the saved flag that been saved to know if the file sharing is enabled or not with the flag + * to know if there was a status change + */ + suspend fun isFileSharingEnabled(): IsFileSharingEnabledEntity? + + /** + * Returns the Flow of file sharing status + */ + suspend fun isFileSharingEnabledFlow(): Flow + + suspend fun setFileSharingAsNotified() + + /** + * Returns a Flow containing the status and list of classified domains + */ + suspend fun isClassifiedDomainsEnabledFlow(): Flow + + /** + *Save the flag and list of trusted domains + */ + suspend fun persistClassifiedDomainsStatus(status: Boolean, classifiedDomains: List) + + /** + * Saves the flag that indicates whether a 2FA challenge is + * required for some operations such as: + * Login, Create Account, Register Client, etc. + * @see isSecondFactorPasswordChallengeRequired + */ + suspend fun persistSecondFactorPasswordChallengeStatus(isRequired: Boolean) + + /** + * Checks if the 2FA challenge is + * required for some operations such as: + * Login, Create Account, Register Client, etc. + * @see persistSecondFactorPasswordChallengeStatus + */ + suspend fun isSecondFactorPasswordChallengeRequired(): Boolean + + /** + * Save default protocol to use + */ + suspend fun persistDefaultProtocol(protocol: SupportedProtocolEntity) + + /** + * Gets default protocol to use. Defaults to PROTEUS if not default protocol has been saved. + */ + suspend fun defaultProtocol(): SupportedProtocolEntity + + /** + * Save flag from user settings to enable or disable Conference Calling + */ + suspend fun persistConferenceCalling(enabled: Boolean) + + /** + * Get the saved flag to know if Conference Calling is enabled or not + */ + suspend fun isConferenceCallingEnabled(): Boolean + + /** + * Get the saved flag to know whether user's Read Receipts are currently enabled or not + */ + suspend fun areReadReceiptsEnabled(): Flow + + /** + * Persist the flag to indicate if user's Read Receipts are enabled or not. + */ + suspend fun persistReadReceipts(enabled: Boolean) + + /** + * Get the saved global flag to know whether user's typing indicator is currently enabled or not. + */ + suspend fun isTypingIndicatorEnabled(): Flow + + /** + * Persist the flag to indicate whether user's typing indicator global flag is enabled or not. + */ + suspend fun persistTypingIndicator(enabled: Boolean) + + suspend fun persistGuestRoomLinkFeatureFlag(status: Boolean, isStatusChanged: Boolean?) + suspend fun isGuestRoomLinkEnabled(): IsGuestRoomLinkEnabledEntity? + suspend fun isGuestRoomLinkEnabledFlow(): Flow + suspend fun isScreenshotCensoringEnabledFlow(): Flow + suspend fun persistScreenshotCensoring(enabled: Boolean) +} + +@Suppress("TooManyFunctions") +internal class UserConfigDAOImpl internal constructor( + private val metadataDAO: MetadataDAO +) : UserConfigDAO { + + override suspend fun getTeamSettingsSelfDeletionStatus(): TeamSettingsSelfDeletionStatusEntity? = + metadataDAO.getSerializable(SELF_DELETING_MESSAGES_KEY, TeamSettingsSelfDeletionStatusEntity.serializer()) + + override suspend fun setTeamSettingsSelfDeletionStatus( + teamSettingsSelfDeletionStatusEntity: TeamSettingsSelfDeletionStatusEntity + ) { + metadataDAO.putSerializable( + key = SELF_DELETING_MESSAGES_KEY, + value = teamSettingsSelfDeletionStatusEntity, + TeamSettingsSelfDeletionStatusEntity.serializer() + ) + } + + override suspend fun markTeamSettingsSelfDeletingMessagesStatusAsNotified() { + metadataDAO.getSerializable(SELF_DELETING_MESSAGES_KEY, TeamSettingsSelfDeletionStatusEntity.serializer()) + ?.copy(isStatusChanged = false)?.let { newValue -> + metadataDAO.putSerializable( + SELF_DELETING_MESSAGES_KEY, + newValue, + TeamSettingsSelfDeletionStatusEntity.serializer() + ) + } + } + + override suspend fun observeTeamSettingsSelfDeletingStatus(): Flow = + metadataDAO.observeSerializable(SELF_DELETING_MESSAGES_KEY, TeamSettingsSelfDeletionStatusEntity.serializer()) + + override suspend fun getMigrationConfiguration(): MLSMigrationEntity? = + metadataDAO.getSerializable(MLS_MIGRATION_KEY, MLSMigrationEntity.serializer()) + + override suspend fun setMigrationConfiguration(configuration: MLSMigrationEntity) = + metadataDAO.putSerializable(MLS_MIGRATION_KEY, configuration, MLSMigrationEntity.serializer()) + + override suspend fun getSupportedProtocols(): Set? = + metadataDAO.getSerializable(SUPPORTED_PROTOCOLS_KEY, SetSerializer(SupportedProtocolEntity.serializer())) + + override suspend fun setSupportedProtocols(protocols: Set) = + metadataDAO.putSerializable(SUPPORTED_PROTOCOLS_KEY, protocols, SetSerializer(SupportedProtocolEntity.serializer())) + + override suspend fun persistAppLockStatus(isEnforced: Boolean, inactivityTimeoutSecs: Second, isStatusChanged: Boolean?) { + metadataDAO.putSerializable( + APP_LOCK, + AppLockConfigEntity(inactivityTimeoutSecs, isEnforced, isStatusChanged), + AppLockConfigEntity.serializer() + ) + } + + override suspend fun appLockStatus(): AppLockConfigEntity? = metadataDAO.getSerializable( + APP_LOCK, + AppLockConfigEntity.serializer() + ) + + override suspend fun appLockFlow(): Flow = metadataDAO.observeSerializable( + APP_LOCK, + AppLockConfigEntity.serializer() + ) + + override suspend fun setTeamAppLockAsNotified() { + metadataDAO.modifySerriedValue( + APP_LOCK, + { it.copy(isStatusChanged = false) }, + AppLockConfigEntity.serializer() + ) + } + + override suspend fun persistFileSharingStatus(status: Boolean, isStatusChanged: Boolean?) { + metadataDAO.putSerializable( + FILE_SHARING, + IsFileSharingEnabledEntity(status, isStatusChanged), + IsFileSharingEnabledEntity.serializer() + ) + } + + override suspend fun isFileSharingEnabled(): IsFileSharingEnabledEntity? = metadataDAO.getSerializable( + FILE_SHARING, + IsFileSharingEnabledEntity.serializer() + ) + + override suspend fun isFileSharingEnabledFlow(): Flow = metadataDAO.observeSerializable( + FILE_SHARING, + IsFileSharingEnabledEntity.serializer() + ) + + override suspend fun setFileSharingAsNotified() { + metadataDAO.modifySerriedValue( + FILE_SHARING, + { it.copy(isStatusChanged = false) }, + IsFileSharingEnabledEntity.serializer() + ) + } + + override suspend fun isClassifiedDomainsEnabledFlow(): Flow = metadataDAO.observeSerializable( + ENABLE_CLASSIFIED_DOMAINS, + ClassifiedDomainsEntity.serializer() + ) + + override suspend fun persistClassifiedDomainsStatus(status: Boolean, classifiedDomains: List) { + metadataDAO.putSerializable( + ENABLE_CLASSIFIED_DOMAINS, + ClassifiedDomainsEntity(status, classifiedDomains), + ClassifiedDomainsEntity.serializer() + ) + } + + override suspend fun persistSecondFactorPasswordChallengeStatus(isRequired: Boolean) { + metadataDAO.insertBooleanValue(REQUIRE_SECOND_FACTOR_PASSWORD_CHALLENGE, isRequired) + } + + override suspend fun isSecondFactorPasswordChallengeRequired(): Boolean = metadataDAO.getBooleanValue( + REQUIRE_SECOND_FACTOR_PASSWORD_CHALLENGE + ) ?: false + + override suspend fun persistDefaultProtocol(protocol: SupportedProtocolEntity) { + metadataDAO.putSerializable(DEFAULT_PROTOCOL, protocol, SupportedProtocolEntity.serializer()) + } + + override suspend fun defaultProtocol(): SupportedProtocolEntity = metadataDAO.getSerializable( + DEFAULT_PROTOCOL, + SupportedProtocolEntity.serializer() + ) ?: SupportedProtocolEntity.PROTEUS + + override suspend fun persistConferenceCalling(enabled: Boolean) { + metadataDAO.insertBooleanValue(ENABLE_CONFERENCE_CALLING, enabled) + } + + override suspend fun isConferenceCallingEnabled(): Boolean = metadataDAO.getBooleanValue( + ENABLE_CONFERENCE_CALLING + ) ?: DEFAULT_CONFERENCE_CALLING_ENABLED_VALUE + + override suspend fun areReadReceiptsEnabled(): Flow = metadataDAO.observeBooleanValue( + ENABLE_READ_RECEIPTS, + DEFAULT_CONFERENCE_CALLING_ENABLED_VALUE + ) + + override suspend fun persistReadReceipts(enabled: Boolean) { + metadataDAO.insertBooleanValue(ENABLE_READ_RECEIPTS, enabled) + } + + override suspend fun isTypingIndicatorEnabled(): Flow = + metadataDAO.observeBooleanValue(ENABLE_TYPING_INDICATOR, true) + + override suspend fun persistTypingIndicator(enabled: Boolean) { + metadataDAO.insertBooleanValue(ENABLE_TYPING_INDICATOR, enabled) + } + + override suspend fun persistGuestRoomLinkFeatureFlag(status: Boolean, isStatusChanged: Boolean?) { + metadataDAO.putSerializable( + GUEST_ROOM_LINK, + IsGuestRoomLinkEnabledEntity(status, isStatusChanged), + IsGuestRoomLinkEnabledEntity.serializer() + ) + } + + override suspend fun isGuestRoomLinkEnabled(): IsGuestRoomLinkEnabledEntity? = + metadataDAO.getSerializable(GUEST_ROOM_LINK, IsGuestRoomLinkEnabledEntity.serializer()) + + override suspend fun isGuestRoomLinkEnabledFlow(): Flow = metadataDAO.observeSerializable( + GUEST_ROOM_LINK, + IsGuestRoomLinkEnabledEntity.serializer() + ) + + override suspend fun isScreenshotCensoringEnabledFlow(): Flow = + metadataDAO.observeBooleanValue(ENABLE_SCREENSHOT_CENSORING, false) + + override suspend fun persistScreenshotCensoring(enabled: Boolean) { + metadataDAO.insertBooleanValue(ENABLE_SCREENSHOT_CENSORING, enabled) + } + + private companion object { + const val SELF_DELETING_MESSAGES_KEY = "SELF_DELETING_MESSAGES" + const val MLS_MIGRATION_KEY = "MLS_MIGRATION" + const val SUPPORTED_PROTOCOLS_KEY = "SUPPORTED_PROTOCOLS" + const val FILE_SHARING = "file_sharing" + const val GUEST_ROOM_LINK = "guest_room_link" + const val ENABLE_CLASSIFIED_DOMAINS = "enable_classified_domains" + const val ENABLE_CONFERENCE_CALLING = "enable_conference_calling" + const val ENABLE_READ_RECEIPTS = "enable_read_receipts" + const val DEFAULT_CONFERENCE_CALLING_ENABLED_VALUE = false + const val REQUIRE_SECOND_FACTOR_PASSWORD_CHALLENGE = "require_second_factor_password_challenge" + const val ENABLE_SCREENSHOT_CENSORING = "enable_screenshot_censoring" + const val ENABLE_TYPING_INDICATOR = "enable_typing_indicator" + const val APP_LOCK = "app_lock" + const val DEFAULT_PROTOCOL = "default_protocol" + } +} diff --git a/persistence/src/jsMain/kotlin/com/wire/kalium/persistence/kmmSettings/UserPrefBuilder.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/AppLockConfigEntity.kt similarity index 57% rename from persistence/src/jsMain/kotlin/com/wire/kalium/persistence/kmmSettings/UserPrefBuilder.kt rename to persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/AppLockConfigEntity.kt index afa0f7617c0..d98d2b35616 100644 --- a/persistence/src/jsMain/kotlin/com/wire/kalium/persistence/kmmSettings/UserPrefBuilder.kt +++ b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/AppLockConfigEntity.kt @@ -15,20 +15,15 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ +package com.wire.kalium.persistence.dao.config.model -package com.wire.kalium.persistence.kmmSettings +import com.wire.kalium.util.time.Second +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable -import com.wire.kalium.persistence.client.LastRetrievedNotificationEventStorage -import com.wire.kalium.persistence.config.UserConfigStorage - -actual class UserPrefBuilder { - actual val lastRetrievedNotificationEventStorage: LastRetrievedNotificationEventStorage - get() = TODO("Not yet implemented") - - actual fun clear() { - TODO("Not yet implemented") - } - - actual val userConfigStorage: UserConfigStorage - get() = TODO("Not yet implemented") -} +@Serializable +data class AppLockConfigEntity( + @SerialName("inactivityTimeoutSecs") val inactivityTimeoutSecs: Second, + @SerialName("enforceAppLock") val enforceAppLock: Boolean, + @SerialName("isStatusChanged") val isStatusChanged: Boolean? +) diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/ClassifiedDomainsEntity.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/ClassifiedDomainsEntity.kt new file mode 100644 index 00000000000..36d6e12e275 --- /dev/null +++ b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/ClassifiedDomainsEntity.kt @@ -0,0 +1,27 @@ +/* + * Wire + * Copyright (C) 2023 Wire Swiss GmbH + * + * This program 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. + * + * This program 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 this program. If not, see http://www.gnu.org/licenses/. + */ +package com.wire.kalium.persistence.dao.config.model + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class ClassifiedDomainsEntity( + @SerialName("status") val status: Boolean, + @SerialName("trustedDomains") val trustedDomains: List, +) diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/kmmSettings/UserPrefBuilder.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/E2EISettingsEntity.kt similarity index 65% rename from persistence/src/commonMain/kotlin/com/wire/kalium/persistence/kmmSettings/UserPrefBuilder.kt rename to persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/E2EISettingsEntity.kt index 5937b261312..1aafaf6e4ea 100644 --- a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/kmmSettings/UserPrefBuilder.kt +++ b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/E2EISettingsEntity.kt @@ -15,14 +15,14 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ +package com.wire.kalium.persistence.dao.config.model -package com.wire.kalium.persistence.kmmSettings +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable -import com.wire.kalium.persistence.client.LastRetrievedNotificationEventStorage -import com.wire.kalium.persistence.config.UserConfigStorage - -expect class UserPrefBuilder { - val lastRetrievedNotificationEventStorage: LastRetrievedNotificationEventStorage - val userConfigStorage: UserConfigStorage - fun clear() -} +@Serializable +data class E2EISettingsEntity( + @SerialName("status") val status: Boolean, + @SerialName("discoverUrl") val discoverUrl: String, + @SerialName("gracePeriodEndMs") val gracePeriodEndMs: Long?, +) diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/IsFileSharingEnabledEntity.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/IsFileSharingEnabledEntity.kt new file mode 100644 index 00000000000..cd27cccffda --- /dev/null +++ b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/IsFileSharingEnabledEntity.kt @@ -0,0 +1,27 @@ +/* + * Wire + * Copyright (C) 2023 Wire Swiss GmbH + * + * This program 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. + * + * This program 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 this program. If not, see http://www.gnu.org/licenses/. + */ +package com.wire.kalium.persistence.dao.config.model + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class IsFileSharingEnabledEntity( + @SerialName("status") val status: Boolean, + @SerialName("isStatusChanged") val isStatusChanged: Boolean? +) diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/IsGuestRoomLinkEnabledEntity.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/IsGuestRoomLinkEnabledEntity.kt new file mode 100644 index 00000000000..ec135df94b0 --- /dev/null +++ b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/IsGuestRoomLinkEnabledEntity.kt @@ -0,0 +1,27 @@ +/* + * Wire + * Copyright (C) 2023 Wire Swiss GmbH + * + * This program 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. + * + * This program 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 this program. If not, see http://www.gnu.org/licenses/. + */ +package com.wire.kalium.persistence.dao.config.model + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class IsGuestRoomLinkEnabledEntity( + @SerialName("status") val status: Boolean, + @SerialName("isStatusChanged") val isStatusChanged: Boolean? +) diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/MLSMigrationEntity.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/MLSMigrationEntity.kt new file mode 100644 index 00000000000..8bd39c1e8a2 --- /dev/null +++ b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/MLSMigrationEntity.kt @@ -0,0 +1,28 @@ +/* + * Wire + * Copyright (C) 2023 Wire Swiss GmbH + * + * This program 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. + * + * This program 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 this program. If not, see http://www.gnu.org/licenses/. + */ +package com.wire.kalium.persistence.dao.config.model + +import kotlinx.datetime.Instant +import kotlinx.serialization.Serializable + +@Serializable +data class MLSMigrationEntity( + @Serializable val status: Boolean, + @Serializable val startTime: Instant?, + @Serializable val endTime: Instant?, +) diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/SelfDeletionTimerEntity.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/SelfDeletionTimerEntity.kt new file mode 100644 index 00000000000..4bf4e75bb02 --- /dev/null +++ b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/SelfDeletionTimerEntity.kt @@ -0,0 +1,38 @@ +/* + * Wire + * Copyright (C) 2023 Wire Swiss GmbH + * + * This program 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. + * + * This program 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 this program. If not, see http://www.gnu.org/licenses/. + */ +package com.wire.kalium.persistence.dao.config.model + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlin.time.Duration + +@Serializable +sealed class SelfDeletionTimerEntity { + + @Serializable + @SerialName("disabled") + data object Disabled : SelfDeletionTimerEntity() + + @Serializable + @SerialName("enabled") + data object Enabled : SelfDeletionTimerEntity() + + @Serializable + @SerialName("enforced") + data class Enforced(val enforcedDuration: Duration) : SelfDeletionTimerEntity() +} diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/TeamSettingsSelfDeletionStatusEntity.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/TeamSettingsSelfDeletionStatusEntity.kt new file mode 100644 index 00000000000..277973ecf95 --- /dev/null +++ b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/config/model/TeamSettingsSelfDeletionStatusEntity.kt @@ -0,0 +1,27 @@ +/* + * Wire + * Copyright (C) 2023 Wire Swiss GmbH + * + * This program 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. + * + * This program 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 this program. If not, see http://www.gnu.org/licenses/. + */ +package com.wire.kalium.persistence.dao.config.model + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class TeamSettingsSelfDeletionStatusEntity( + @SerialName("selfDeletionTimer") val selfDeletionTimerEntity: SelfDeletionTimerEntity, + @SerialName("isStatusChanged") val isStatusChanged: Boolean? +) diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/unread/UserConfigDAO.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/unread/UserConfigDAO.kt deleted file mode 100644 index e39e7149c83..00000000000 --- a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/unread/UserConfigDAO.kt +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Wire - * Copyright (C) 2023 Wire Swiss GmbH - * - * This program 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. - * - * This program 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 this program. If not, see http://www.gnu.org/licenses/. - */ -package com.wire.kalium.persistence.dao.unread - -import com.wire.kalium.persistence.config.MLSMigrationEntity -import com.wire.kalium.persistence.config.TeamSettingsSelfDeletionStatusEntity -import com.wire.kalium.persistence.dao.MetadataDAO -import com.wire.kalium.persistence.dao.SupportedProtocolEntity -import kotlinx.coroutines.flow.Flow -import kotlinx.serialization.builtins.SetSerializer - -interface UserConfigDAO { - - suspend fun getTeamSettingsSelfDeletionStatus(): TeamSettingsSelfDeletionStatusEntity? - suspend fun setTeamSettingsSelfDeletionStatus( - teamSettingsSelfDeletionStatusEntity: TeamSettingsSelfDeletionStatusEntity - ) - - suspend fun markTeamSettingsSelfDeletingMessagesStatusAsNotified() - suspend fun observeTeamSettingsSelfDeletingStatus(): Flow - - suspend fun getMigrationConfiguration(): MLSMigrationEntity? - suspend fun setMigrationConfiguration(configuration: MLSMigrationEntity) - - suspend fun getSupportedProtocols(): Set? - suspend fun setSupportedProtocols(protocols: Set) -} - -internal class UserConfigDAOImpl internal constructor( - private val metadataDAO: MetadataDAO -) : UserConfigDAO { - - override suspend fun getTeamSettingsSelfDeletionStatus(): TeamSettingsSelfDeletionStatusEntity? = - metadataDAO.getSerializable(SELF_DELETING_MESSAGES_KEY, TeamSettingsSelfDeletionStatusEntity.serializer()) - - override suspend fun setTeamSettingsSelfDeletionStatus( - teamSettingsSelfDeletionStatusEntity: TeamSettingsSelfDeletionStatusEntity - ) { - metadataDAO.putSerializable( - key = SELF_DELETING_MESSAGES_KEY, - value = teamSettingsSelfDeletionStatusEntity, - TeamSettingsSelfDeletionStatusEntity.serializer() - ) - } - - override suspend fun markTeamSettingsSelfDeletingMessagesStatusAsNotified() { - metadataDAO.getSerializable(SELF_DELETING_MESSAGES_KEY, TeamSettingsSelfDeletionStatusEntity.serializer()) - ?.copy(isStatusChanged = false)?.let { newValue -> - metadataDAO.putSerializable( - SELF_DELETING_MESSAGES_KEY, - newValue, - TeamSettingsSelfDeletionStatusEntity.serializer() - ) - } - } - - override suspend fun observeTeamSettingsSelfDeletingStatus(): Flow = - metadataDAO.observeSerializable(SELF_DELETING_MESSAGES_KEY, TeamSettingsSelfDeletionStatusEntity.serializer()) - - override suspend fun getMigrationConfiguration(): MLSMigrationEntity? = - metadataDAO.getSerializable(MLS_MIGRATION_KEY, MLSMigrationEntity.serializer()) - - override suspend fun setMigrationConfiguration(configuration: MLSMigrationEntity) = - metadataDAO.putSerializable(MLS_MIGRATION_KEY, configuration, MLSMigrationEntity.serializer()) - - override suspend fun getSupportedProtocols(): Set? = - metadataDAO.getSerializable(SUPPORTED_PROTOCOLS_KEY, SetSerializer(SupportedProtocolEntity.serializer())) - - override suspend fun setSupportedProtocols(protocols: Set) = - metadataDAO.putSerializable(SUPPORTED_PROTOCOLS_KEY, protocols, SetSerializer(SupportedProtocolEntity.serializer())) - - private companion object { - private const val SELF_DELETING_MESSAGES_KEY = "SELF_DELETING_MESSAGES" - private const val MLS_MIGRATION_KEY = "MLS_MIGRATION" - private const val SUPPORTED_PROTOCOLS_KEY = "SUPPORTED_PROTOCOLS" - } -} diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/db/UserDatabaseBuilder.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/db/UserDatabaseBuilder.kt index 4bbff76933e..5cc2978debf 100644 --- a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/db/UserDatabaseBuilder.kt +++ b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/db/UserDatabaseBuilder.kt @@ -49,6 +49,8 @@ import com.wire.kalium.persistence.dao.call.CallDAO import com.wire.kalium.persistence.dao.call.CallDAOImpl import com.wire.kalium.persistence.dao.client.ClientDAO import com.wire.kalium.persistence.dao.client.ClientDAOImpl +import com.wire.kalium.persistence.dao.config.MLSConfigDAO +import com.wire.kalium.persistence.dao.config.MLSConfigDAOImpl import com.wire.kalium.persistence.dao.conversation.ConversationDAO import com.wire.kalium.persistence.dao.conversation.ConversationDAOImpl import com.wire.kalium.persistence.dao.conversation.ConversationMetaDataDAO @@ -67,8 +69,8 @@ import com.wire.kalium.persistence.dao.reaction.ReactionDAO import com.wire.kalium.persistence.dao.reaction.ReactionDAOImpl import com.wire.kalium.persistence.dao.receipt.ReceiptDAO import com.wire.kalium.persistence.dao.receipt.ReceiptDAOImpl -import com.wire.kalium.persistence.dao.unread.UserConfigDAO -import com.wire.kalium.persistence.dao.unread.UserConfigDAOImpl +import com.wire.kalium.persistence.dao.config.UserConfigDAO +import com.wire.kalium.persistence.dao.config.UserConfigDAOImpl import com.wire.kalium.util.KaliumDispatcherImpl import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope @@ -172,6 +174,9 @@ class UserDatabaseBuilder internal constructor( val userConfigDAO: UserConfigDAO get() = UserConfigDAOImpl(metadataDAO) + val mlsConfigDAO: MLSConfigDAO + get() = MLSConfigDAOImpl(metadataDAO) + val connectionDAO: ConnectionDAO get() = ConnectionDAOImpl(database.connectionsQueries, database.conversationsQueries, queriesContext) diff --git a/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/config/UserConfigDAOTest.kt b/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/config/UserConfigDAOTest.kt index 2bcdcff975d..74abbfa7972 100644 --- a/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/config/UserConfigDAOTest.kt +++ b/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/config/UserConfigDAOTest.kt @@ -19,10 +19,17 @@ package com.wire.kalium.persistence.config import app.cash.turbine.test import com.wire.kalium.persistence.BaseDatabaseTest +import com.wire.kalium.persistence.dao.SupportedProtocolEntity import com.wire.kalium.persistence.dao.UserIDEntity -import com.wire.kalium.persistence.dao.unread.UserConfigDAO +import com.wire.kalium.persistence.dao.config.UserConfigDAO +import com.wire.kalium.persistence.dao.config.model.AppLockConfigEntity +import com.wire.kalium.persistence.dao.config.model.ClassifiedDomainsEntity +import com.wire.kalium.persistence.dao.config.model.IsFileSharingEnabledEntity +import com.wire.kalium.persistence.dao.config.model.SelfDeletionTimerEntity +import com.wire.kalium.persistence.dao.config.model.TeamSettingsSelfDeletionStatusEntity import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.setMain import kotlin.test.BeforeTest @@ -123,4 +130,158 @@ class UserConfigDAOTest : BaseDatabaseTest() { assertEquals(thirdExpectedValue, thirdValue) } } + + @Test + fun givenAFileSharingStatusValue_whenCAllPersistItSaveAnd_thenCanRestoreTheValueLocally() = runTest { + userConfigDAO.persistFileSharingStatus(true, null) + assertEquals(IsFileSharingEnabledEntity(true, null), userConfigDAO.isFileSharingEnabled()) + + userConfigDAO.persistFileSharingStatus(false, null) + assertEquals(IsFileSharingEnabledEntity(false, null), userConfigDAO.isFileSharingEnabled()) + } + + @Test + fun givenAClassifiedDomainsStatusValue_whenCAllPersistItSaveAndThenCanRestoreTheValueLocally() = runTest { + userConfigDAO.persistClassifiedDomainsStatus(true, listOf("bella.com", "anta.wire")) + assertEquals( + ClassifiedDomainsEntity(true, listOf("bella.com", "anta.wire")), + userConfigDAO.isClassifiedDomainsEnabledFlow().first() + ) + } + + @Test + fun givenAConferenceCallingStatusValue_whenPersistingIt_saveAndThenRestoreTheValueLocally() = runTest { + userConfigDAO.persistConferenceCalling(true) + assertEquals( + true, + userConfigDAO.isConferenceCallingEnabled() + ) + } + + @Test + fun givenAReadReceiptsSetValue_whenPersistingIt_saveAndThenRestoreTheValueLocally() = runTest { + userConfigDAO.persistReadReceipts(true) + assertTrue(userConfigDAO.areReadReceiptsEnabled().first()) + } + + @Test + fun whenMarkingFileSharingAsNotified_thenIsChangedIsSetToFalse() = runTest { + userConfigDAO.persistFileSharingStatus(true, true) + userConfigDAO.setFileSharingAsNotified() + assertEquals(IsFileSharingEnabledEntity(true, false), userConfigDAO.isFileSharingEnabled()) + } + + @Test + fun givenPasswordChallengeRequirementIsNotSet_whenGettingItsValue_thenItShouldBeFalseByDefault() = runTest { + assertFalse { + userConfigDAO.isSecondFactorPasswordChallengeRequired() + } + } + + @Test + fun givenPasswordChallengeRequirementIsSetToFalse_whenGettingItsValue_thenItShouldBeFalse() = runTest { + userConfigDAO.persistSecondFactorPasswordChallengeStatus(false) + assertFalse { + userConfigDAO.isSecondFactorPasswordChallengeRequired() + } + } + + @Test + fun givenPasswordChallengeRequirementIsSetToTrue_whenGettingItsValue_thenItShouldBeTrue() = runTest { + userConfigDAO.persistSecondFactorPasswordChallengeStatus(true) + assertTrue { + userConfigDAO.isSecondFactorPasswordChallengeRequired() + } + } + + @Test + fun givenGuestRoomLinkStatusIsSetToFalse_whenGettingItsValue_thenItShouldBeFalse() = runTest { + userConfigDAO.persistGuestRoomLinkFeatureFlag(status = false, isStatusChanged = false) + userConfigDAO.isGuestRoomLinkEnabled()?.status?.let { + assertFalse { it } + } + } + + @Test + fun givenGuestRoomLinkStatusIsSetToTrue_whenGettingItsValue_thenItShouldBeTrue() = runTest { + userConfigDAO.persistGuestRoomLinkFeatureFlag(status = true, isStatusChanged = false) + userConfigDAO.isGuestRoomLinkEnabled()?.status?.let { + assertTrue { it } + } + } + + @Test + fun givenScreenshotCensoringConfigIsSetToFalse_whenGettingItsValue_thenItShouldBeFalse() = runTest { + userConfigDAO.persistScreenshotCensoring(enabled = false) + assertEquals(false, userConfigDAO.isScreenshotCensoringEnabledFlow().first()) + } + + @Test + fun givenScreenshotCensoringConfigIsSetToTrue_whenGettingItsValue_thenItShouldBeTrue() = runTest { + userConfigDAO.persistScreenshotCensoring(enabled = true) + assertEquals(true, userConfigDAO.isScreenshotCensoringEnabledFlow().first()) + } + + @Test + fun givenAppLockConfig_whenStoring_thenItCanBeRead() = runTest { + val expected = AppLockConfigEntity( + enforceAppLock = true, + inactivityTimeoutSecs = 60, + isStatusChanged = false + ) + userConfigDAO.persistAppLockStatus( + expected.enforceAppLock, + expected.inactivityTimeoutSecs, + expected.isStatusChanged + ) + assertEquals(expected, userConfigDAO.appLockStatus()) + } + + @Test + fun givenNewAppLockValueStored_whenObservingFlow_thenNewValueIsEmitted() = runTest { + userConfigDAO.appLockFlow().test { + + awaitItem().also { + assertNull(it) + } + val expected1 = AppLockConfigEntity( + enforceAppLock = true, + inactivityTimeoutSecs = 60, + isStatusChanged = true + ) + userConfigDAO.persistAppLockStatus( + expected1.enforceAppLock, + expected1.inactivityTimeoutSecs, + expected1.isStatusChanged + ) + awaitItem().also { + assertEquals(expected1, it) + } + + val expected2 = AppLockConfigEntity( + enforceAppLock = false, + inactivityTimeoutSecs = 60, + isStatusChanged = false + ) + userConfigDAO.persistAppLockStatus( + expected2.enforceAppLock, + expected2.inactivityTimeoutSecs, + expected2.isStatusChanged + ) + awaitItem().also { + assertEquals(expected2, it) + } + } + } + + @Test + fun givenDefaultProtocolIsNotSet_whenGettingItsValue_thenItShouldBeProteus() = runTest { + assertEquals(SupportedProtocolEntity.PROTEUS, userConfigDAO.defaultProtocol()) + } + + @Test + fun givenDefaultProtocolIsSetToMls_whenGettingItsValue_thenItShouldBeMls() = runTest { + userConfigDAO.persistDefaultProtocol(SupportedProtocolEntity.MLS) + assertEquals(SupportedProtocolEntity.MLS, userConfigDAO.defaultProtocol()) + } } diff --git a/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/config/UserConfigStorageTest.kt b/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/config/UserConfigStorageTest.kt deleted file mode 100644 index 72145af3d72..00000000000 --- a/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/config/UserConfigStorageTest.kt +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Wire - * Copyright (C) 2023 Wire Swiss GmbH - * - * This program 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. - * - * This program 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 this program. If not, see http://www.gnu.org/licenses/. - */ - -package com.wire.kalium.persistence.config - -import app.cash.turbine.test -import com.russhwolf.settings.MapSettings -import com.russhwolf.settings.Settings -import com.wire.kalium.persistence.dao.SupportedProtocolEntity -import com.wire.kalium.persistence.kmmSettings.KaliumPreferences -import com.wire.kalium.persistence.kmmSettings.KaliumPreferencesSettings -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.flow.first -import kotlinx.coroutines.test.runTest -import kotlin.test.AfterTest -import kotlin.test.BeforeTest -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertFalse -import kotlin.test.assertNull -import kotlin.test.assertTrue - -class UserConfigStorageTest { - private val settings: Settings = MapSettings() - - private val kaliumPreferences: KaliumPreferences = KaliumPreferencesSettings(settings) - private lateinit var userConfigStorage: UserConfigStorage - - @BeforeTest - fun setUp() { - userConfigStorage = UserConfigStorageImpl(kaliumPreferences) - } - - @AfterTest - fun clear() { - settings.clear() - } - - @Test - fun givenAFileSharingStatusValue_whenCAllPersistItSaveAnd_thenCanRestoreTheValueLocally() = runTest { - userConfigStorage.persistFileSharingStatus(true, null) - assertEquals(IsFileSharingEnabledEntity(true, null), userConfigStorage.isFileSharingEnabled()) - - userConfigStorage.persistFileSharingStatus(false, null) - assertEquals(IsFileSharingEnabledEntity(false, null), userConfigStorage.isFileSharingEnabled()) - } - - @Test - fun givenAClassifiedDomainsStatusValue_whenCAllPersistItSaveAndThenCanRestoreTheValueLocally() = runTest { - userConfigStorage.persistClassifiedDomainsStatus(true, listOf("bella.com", "anta.wire")) - assertEquals( - ClassifiedDomainsEntity(true, listOf("bella.com", "anta.wire")), - userConfigStorage.isClassifiedDomainsEnabledFlow().first() - ) - } - - @Test - fun givenAConferenceCallingStatusValue_whenPersistingIt_saveAndThenRestoreTheValueLocally() = runTest { - userConfigStorage.persistConferenceCalling(true) - assertEquals( - true, - userConfigStorage.isConferenceCallingEnabled() - ) - } - - @Test - fun givenAReadReceiptsSetValue_whenPersistingIt_saveAndThenRestoreTheValueLocally() = runTest { - userConfigStorage.persistReadReceipts(true) - assertTrue(userConfigStorage.areReadReceiptsEnabled().first()) - } - - @Test - fun whenMarkingFileSharingAsNotified_thenIsChangedIsSetToFalse() = runTest { - userConfigStorage.persistFileSharingStatus(true, true) - userConfigStorage.setFileSharingAsNotified() - assertEquals(IsFileSharingEnabledEntity(true, false), userConfigStorage.isFileSharingEnabled()) - } - - @Test - fun givenPasswordChallengeRequirementIsNotSet_whenGettingItsValue_thenItShouldBeFalseByDefault() = runTest { - assertFalse { - userConfigStorage.isSecondFactorPasswordChallengeRequired() - } - } - - @Test - fun givenPasswordChallengeRequirementIsSetToFalse_whenGettingItsValue_thenItShouldBeFalse() = runTest { - userConfigStorage.persistSecondFactorPasswordChallengeStatus(false) - assertFalse { - userConfigStorage.isSecondFactorPasswordChallengeRequired() - } - } - - @Test - fun givenPasswordChallengeRequirementIsSetToTrue_whenGettingItsValue_thenItShouldBeTrue() = runTest { - userConfigStorage.persistSecondFactorPasswordChallengeStatus(true) - assertTrue { - userConfigStorage.isSecondFactorPasswordChallengeRequired() - } - } - - @Test - fun givenGuestRoomLinkStatusIsSetToFalse_whenGettingItsValue_thenItShouldBeFalse() { - userConfigStorage.persistGuestRoomLinkFeatureFlag(status = false, isStatusChanged = false) - userConfigStorage.isGuestRoomLinkEnabled()?.status?.let { - assertFalse { it } - } - } - - @Test - fun givenGuestRoomLinkStatusIsSetToTrue_whenGettingItsValue_thenItShouldBeTrue() { - userConfigStorage.persistGuestRoomLinkFeatureFlag(status = true, isStatusChanged = false) - userConfigStorage.isGuestRoomLinkEnabled()?.status?.let { - assertTrue { it } - } - } - - @Test - fun givenScreenshotCensoringConfigIsSetToFalse_whenGettingItsValue_thenItShouldBeFalse() = runTest { - userConfigStorage.persistScreenshotCensoring(enabled = false) - assertEquals(false, userConfigStorage.isScreenshotCensoringEnabledFlow().first()) - } - - @Test - fun givenScreenshotCensoringConfigIsSetToTrue_whenGettingItsValue_thenItShouldBeTrue() = runTest { - userConfigStorage.persistScreenshotCensoring(enabled = true) - assertEquals(true, userConfigStorage.isScreenshotCensoringEnabledFlow().first()) - } - - @Test - fun givenAppLockConfig_whenStoring_thenItCanBeRead() = runTest { - val expected = AppLockConfigEntity( - enforceAppLock = true, - inactivityTimeoutSecs = 60, - isStatusChanged = false - ) - userConfigStorage.persistAppLockStatus( - expected.enforceAppLock, - expected.inactivityTimeoutSecs, - expected.isStatusChanged - ) - assertEquals(expected, userConfigStorage.appLockStatus()) - } - - @Test - fun givenNewAppLockValueStored_whenObservingFlow_thenNewValueIsEmitted() = runTest { - userConfigStorage.appLockFlow().test { - - awaitItem().also { - assertNull(it) - } - val expected1 = AppLockConfigEntity( - enforceAppLock = true, - inactivityTimeoutSecs = 60, - isStatusChanged = true - ) - userConfigStorage.persistAppLockStatus( - expected1.enforceAppLock, - expected1.inactivityTimeoutSecs, - expected1.isStatusChanged - ) - awaitItem().also { - assertEquals(expected1, it) - } - - val expected2 = AppLockConfigEntity( - enforceAppLock = false, - inactivityTimeoutSecs = 60, - isStatusChanged = false - ) - userConfigStorage.persistAppLockStatus( - expected2.enforceAppLock, - expected2.inactivityTimeoutSecs, - expected2.isStatusChanged - ) - awaitItem().also { - assertEquals(expected2, it) - } - } - } - - @Test - fun givenDefaultProtocolIsNotSet_whenGettingItsValue_thenItShouldBeProteus() { - assertEquals(SupportedProtocolEntity.PROTEUS, userConfigStorage.defaultProtocol()) - } - - @Test - fun givenDefaultProtocolIsSetToMls_whenGettingItsValue_thenItShouldBeMls() { - userConfigStorage.persistDefaultProtocol(SupportedProtocolEntity.MLS) - assertEquals(SupportedProtocolEntity.MLS, userConfigStorage.defaultProtocol()) - } -} diff --git a/persistence/src/jvmMain/kotlin/com/wire/kalium/persistence/kmmSettings/UserPrefBuilder.kt b/persistence/src/jvmMain/kotlin/com/wire/kalium/persistence/kmmSettings/UserPrefBuilder.kt deleted file mode 100644 index 3210dd3ca01..00000000000 --- a/persistence/src/jvmMain/kotlin/com/wire/kalium/persistence/kmmSettings/UserPrefBuilder.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Wire - * Copyright (C) 2023 Wire Swiss GmbH - * - * This program 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. - * - * This program 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 this program. If not, see http://www.gnu.org/licenses/. - */ - -package com.wire.kalium.persistence.kmmSettings - -import com.wire.kalium.persistence.client.LastRetrievedNotificationEventStorage -import com.wire.kalium.persistence.client.LastRetrievedNotificationEventStorageImpl -import com.wire.kalium.persistence.config.UserConfigStorage -import com.wire.kalium.persistence.config.UserConfigStorageImpl -import com.wire.kalium.persistence.dao.UserIDEntity - -actual class UserPrefBuilder( - userId: UserIDEntity, - rootPath: String, - shouldEncryptData: Boolean = true -) { - - private val kaliumPref = - KaliumPreferencesSettings( - EncryptedSettingsBuilder.build( - SettingOptions.UserSettings(shouldEncryptData, userId), - EncryptedSettingsPlatformParam(rootPath) - ) - ) - - actual val lastRetrievedNotificationEventStorage: LastRetrievedNotificationEventStorage - get() = LastRetrievedNotificationEventStorageImpl(kaliumPref) - actual val userConfigStorage: UserConfigStorage = UserConfigStorageImpl(kaliumPref) - - actual fun clear() { - kaliumPref.nuke() - } - -} From 24b1a0a1f52df25a0ed479e8ec2b9e23668d68a5 Mon Sep 17 00:00:00 2001 From: MohamadJaara Date: Thu, 16 Nov 2023 20:03:36 +0100 Subject: [PATCH 2/3] fix cli --- .../wire/kalium/logic/di/PlatformUserStorageProvider.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/logic/src/jvmMain/kotlin/com/wire/kalium/logic/di/PlatformUserStorageProvider.kt b/logic/src/jvmMain/kotlin/com/wire/kalium/logic/di/PlatformUserStorageProvider.kt index f7b439b1f4d..3af42993b07 100644 --- a/logic/src/jvmMain/kotlin/com/wire/kalium/logic/di/PlatformUserStorageProvider.kt +++ b/logic/src/jvmMain/kotlin/com/wire/kalium/logic/di/PlatformUserStorageProvider.kt @@ -21,9 +21,9 @@ package com.wire.kalium.logic.di import com.wire.kalium.logic.data.id.toDao import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.persistence.db.PlatformDatabaseData +import com.wire.kalium.persistence.db.UserDatabaseBuilder import com.wire.kalium.persistence.db.inMemoryDatabase import com.wire.kalium.persistence.db.userDatabaseBuilder -import com.wire.kalium.persistence.kmmSettings.UserPrefBuilder import com.wire.kalium.util.KaliumDispatcherImpl internal actual class PlatformUserStorageProvider : UserStorageProvider() { @@ -31,9 +31,8 @@ internal actual class PlatformUserStorageProvider : UserStorageProvider() { userId: UserId, shouldEncryptData: Boolean, platformProperties: PlatformUserStorageProperties - ): UserStorage { + ): UserDatabaseBuilder { val userIdEntity = userId.toDao() - val pref = UserPrefBuilder(userIdEntity, platformProperties.rootPath, shouldEncryptData) val databaseInfo = platformProperties.databaseInfo val database = when (databaseInfo) { @@ -51,6 +50,6 @@ internal actual class PlatformUserStorageProvider : UserStorageProvider() { inMemoryDatabase(userIdEntity, KaliumDispatcherImpl.io) } } - return UserStorage(database, pref) + return database } } From 567af5225809802fabf93818075aada0d0af5aea Mon Sep 17 00:00:00 2001 From: MohamadJaara Date: Fri, 17 Nov 2023 11:42:43 +0100 Subject: [PATCH 3/3] fix test --- .../properties/UserPropertyRepositoryTest.kt | 8 +-- .../AppLockTeamFeatureConfigObserverTest.kt | 10 ++-- ...kTeamAppLockStatusAsNotifiedUseCaseTest.kt | 7 ++- .../IsEligibleToStartCallUseCaseTest.kt | 10 ++-- .../client/ObserveE2EIRequiredUseCaseTest.kt | 7 +-- ...rSecurityClassificationLabelUseCaseTest.kt | 4 +- ...eSecurityClassificationLabelUseCaseTest.kt | 4 +- .../SyncFeatureConfigsUseCaseTest.kt | 59 ++++++++++--------- .../handler/AppLockConfigHandlerTest.kt | 29 ++++----- .../IsFileSharingEnabledUseCaseTest.kt | 8 +-- ...tLinkFeatureFlagAsNotChangedUseCaseTest.kt | 19 +++--- ...erveGuestRoomLinkFeatureFlagUseCaseTest.kt | 4 +- .../FeatureConfigEventReceiverTest.kt | 12 ++-- .../UserPropertiesEventReceiverTest.kt | 4 +- .../message/ApplicationMessageHandlerTest.kt | 2 +- .../UserConfigRepositoryArrangement.kt | 5 +- .../receiver/asset/AssetMessageHandlerTest.kt | 3 +- .../config/TestUserConfigStorage.kt | 25 -------- 18 files changed, 97 insertions(+), 123 deletions(-) delete mode 100644 persistence-test/src/commonMain/kotlin/com/wire/kalium/persistence/config/TestUserConfigStorage.kt diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/properties/UserPropertyRepositoryTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/properties/UserPropertyRepositoryTest.kt index 7ded78b5b54..8179502ed04 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/properties/UserPropertyRepositoryTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/properties/UserPropertyRepositoryTest.kt @@ -32,13 +32,11 @@ import io.mockative.given import io.mockative.mock import io.mockative.once import io.mockative.verify -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import kotlin.test.Test import kotlin.test.assertFalse -@OptIn(ExperimentalCoroutinesApi::class) class UserPropertyRepositoryTest { @Test @@ -93,7 +91,7 @@ class UserPropertyRepositoryTest { assertFalse(result) verify(arrangement.userConfigRepository) - .function(arrangement.userConfigRepository::isReadReceiptsEnabled) + .suspendFunction(arrangement.userConfigRepository::isReadReceiptsEnabled) .wasInvoked(exactly = once) } @@ -123,14 +121,14 @@ class UserPropertyRepositoryTest { fun withUpdateReadReceiptsLocallySuccess() = apply { given(userConfigRepository) - .function(userConfigRepository::setReadReceiptsStatus) + .suspendFunction(userConfigRepository::setReadReceiptsStatus) .whenInvokedWith(any()) .thenReturn(Either.Right(Unit)) } fun withNullReadReceiptsStatus() = apply { given(userConfigRepository) - .function(userConfigRepository::isReadReceiptsEnabled) + .suspendFunction(userConfigRepository::isReadReceiptsEnabled) .whenInvoked() .thenReturn(flowOf(Either.Left(StorageFailure.DataNotFound))) } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/applock/AppLockTeamFeatureConfigObserverTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/applock/AppLockTeamFeatureConfigObserverTest.kt index fb23b82b17f..66de81de67c 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/applock/AppLockTeamFeatureConfigObserverTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/applock/AppLockTeamFeatureConfigObserverTest.kt @@ -53,7 +53,7 @@ class AppLockTeamFeatureConfigObserverTest { val result = observer.invoke() verify(arrangement.userConfigRepository) - .function(arrangement.userConfigRepository::observeAppLockConfig) + .suspendFunction(arrangement.userConfigRepository::observeAppLockConfig) .wasNotInvoked() assertEquals(expectedAppLockValue, result.first()) } @@ -73,7 +73,7 @@ class AppLockTeamFeatureConfigObserverTest { val result = observer.invoke() verify(arrangement.userConfigRepository) - .function(arrangement.userConfigRepository::observeAppLockConfig) + .suspendFunction(arrangement.userConfigRepository::observeAppLockConfig) .wasInvoked(exactly = once) assertEquals(expectedAppLockValue, result.first()) } @@ -93,7 +93,7 @@ class AppLockTeamFeatureConfigObserverTest { val result = observer.invoke() verify(arrangement.userConfigRepository) - .function(arrangement.userConfigRepository::observeAppLockConfig) + .suspendFunction(arrangement.userConfigRepository::observeAppLockConfig) .wasInvoked(exactly = once) assertEquals(expectedAppLockValue, result.first()) } @@ -108,14 +108,14 @@ class AppLockTeamFeatureConfigObserverTest { fun withFailure(): Arrangement = apply { given(userConfigRepository) - .function(userConfigRepository::observeAppLockConfig) + .suspendFunction(userConfigRepository::observeAppLockConfig) .whenInvoked() .thenReturn(flowOf(Either.Left(StorageFailure.DataNotFound))) } fun withSuccess(): Arrangement = apply { given(userConfigRepository) - .function(userConfigRepository::observeAppLockConfig) + .suspendFunction(userConfigRepository::observeAppLockConfig) .whenInvoked() .thenReturn(flowOf(Either.Right(appLockTeamConfig))) } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/applock/MarkTeamAppLockStatusAsNotifiedUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/applock/MarkTeamAppLockStatusAsNotifiedUseCaseTest.kt index 934a334833b..7f3e46c427d 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/applock/MarkTeamAppLockStatusAsNotifiedUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/applock/MarkTeamAppLockStatusAsNotifiedUseCaseTest.kt @@ -25,12 +25,13 @@ import io.mockative.given import io.mockative.mock import io.mockative.once import io.mockative.verify +import kotlinx.coroutines.test.runTest import kotlin.test.Test class MarkTeamAppLockStatusAsNotifiedUseCaseTest { @Test - fun givenAppLockStatusChanged_whenMarkingAsNotified_thenSetAppLockAsNotified() { + fun givenAppLockStatusChanged_whenMarkingAsNotified_thenSetAppLockAsNotified() = runTest { val (arrangement, useCase) = Arrangement() .withSuccess() .arrange() @@ -38,7 +39,7 @@ class MarkTeamAppLockStatusAsNotifiedUseCaseTest { useCase.invoke() verify(arrangement.userConfigRepository) - .function(arrangement.userConfigRepository::setTeamAppLockAsNotified) + .suspendFunction(arrangement.userConfigRepository::setTeamAppLockAsNotified) .wasInvoked(once) } @@ -53,7 +54,7 @@ class MarkTeamAppLockStatusAsNotifiedUseCaseTest { fun withSuccess() = apply { given(userConfigRepository) - .function(userConfigRepository::setTeamAppLockAsNotified) + .suspendFunction(userConfigRepository::setTeamAppLockAsNotified) .whenInvoked() .thenReturn(Either.Right(Unit)) } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/IsEligibleToStartCallUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/IsEligibleToStartCallUseCaseTest.kt index ca44d2f17c9..f63b8fa99d2 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/IsEligibleToStartCallUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/IsEligibleToStartCallUseCaseTest.kt @@ -60,7 +60,7 @@ class IsEligibleToStartCallUseCaseTest { .thenReturn(null) given(userConfigRepository) - .function(userConfigRepository::isConferenceCallingEnabled) + .suspendFunction(userConfigRepository::isConferenceCallingEnabled) .whenInvoked() .thenReturn(Either.Left(StorageFailure.Generic(Throwable("error")))) @@ -83,7 +83,7 @@ class IsEligibleToStartCallUseCaseTest { .thenReturn(null) given(userConfigRepository) - .function(userConfigRepository::isConferenceCallingEnabled) + .suspendFunction(userConfigRepository::isConferenceCallingEnabled) .whenInvoked() .thenReturn(Either.Left(StorageFailure.Generic(Throwable("error")))) @@ -107,7 +107,7 @@ class IsEligibleToStartCallUseCaseTest { .thenReturn(establishedCallConversationId) given(userConfigRepository) - .function(userConfigRepository::isConferenceCallingEnabled) + .suspendFunction(userConfigRepository::isConferenceCallingEnabled) .whenInvoked() .thenReturn(Either.Left(StorageFailure.Generic(Throwable("error")))) @@ -131,7 +131,7 @@ class IsEligibleToStartCallUseCaseTest { .thenReturn(establishedCallConversationId) given(userConfigRepository) - .function(userConfigRepository::isConferenceCallingEnabled) + .suspendFunction(userConfigRepository::isConferenceCallingEnabled) .whenInvoked() .thenReturn(Either.Right(true)) @@ -155,7 +155,7 @@ class IsEligibleToStartCallUseCaseTest { .thenReturn(conversationId) given(userConfigRepository) - .function(userConfigRepository::isConferenceCallingEnabled) + .suspendFunction(userConfigRepository::isConferenceCallingEnabled) .whenInvoked() .thenReturn(Either.Right(true)) diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/client/ObserveE2EIRequiredUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/client/ObserveE2EIRequiredUseCaseTest.kt index 7feda0ad1a1..25b35fefdbf 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/client/ObserveE2EIRequiredUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/client/ObserveE2EIRequiredUseCaseTest.kt @@ -28,7 +28,6 @@ import com.wire.kalium.logic.functional.Either import com.wire.kalium.logic.test_util.TestKaliumDispatcher import com.wire.kalium.util.DateTimeUtil import io.mockative.Mock -import io.mockative.any import io.mockative.given import io.mockative.mock import io.mockative.verify @@ -183,7 +182,7 @@ class ObserveE2EIRequiredUseCaseTest { } verify(arrangement.userConfigRepository) - .function(arrangement.userConfigRepository::observeE2EINotificationTime) + .suspendFunction(arrangement.userConfigRepository::observeE2EINotificationTime) .wasNotInvoked() } @@ -199,14 +198,14 @@ class ObserveE2EIRequiredUseCaseTest { fun withMLSE2EISetting(setting: E2EISettings) = apply { given(userConfigRepository) - .function(userConfigRepository::observeE2EISettings) + .suspendFunction(userConfigRepository::observeE2EISettings) .whenInvoked() .then { flowOf(Either.Right(setting)) } } fun withE2EINotificationTime(instant: Instant?) = apply { given(userConfigRepository) - .function(userConfigRepository::observeE2EINotificationTime) + .suspendFunction(userConfigRepository::observeE2EINotificationTime) .whenInvoked() .then { flowOf(Either.Right(instant)) } } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/ObserveOtherUserSecurityClassificationLabelUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/ObserveOtherUserSecurityClassificationLabelUseCaseTest.kt index 6fbd985975b..c216ce66f81 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/ObserveOtherUserSecurityClassificationLabelUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/ObserveOtherUserSecurityClassificationLabelUseCaseTest.kt @@ -93,14 +93,14 @@ class ObserveOtherUserSecurityClassificationLabelUseCaseTest { fun withGettingClassifiedDomainsDisabled() = apply { given(userConfigRepository) - .function(userConfigRepository::getClassifiedDomainsStatus) + .suspendFunction(userConfigRepository::getClassifiedDomainsStatus) .whenInvoked() .thenReturn(flowOf(Either.Left(StorageFailure.DataNotFound))) } fun withGettingClassifiedDomains() = apply { given(userConfigRepository) - .function(userConfigRepository::getClassifiedDomainsStatus) + .suspendFunction(userConfigRepository::getClassifiedDomainsStatus) .whenInvoked() .thenReturn(flowOf(Either.Right(ClassifiedDomainsStatus(true, listOf("wire.com", "bella.com"))))) } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/ObserveSecurityClassificationLabelUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/ObserveSecurityClassificationLabelUseCaseTest.kt index 2a5b610681b..671ab9babfe 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/ObserveSecurityClassificationLabelUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/ObserveSecurityClassificationLabelUseCaseTest.kt @@ -156,14 +156,14 @@ class ObserveSecurityClassificationLabelUseCaseTest { fun withGettingClassifiedDomainsDisabled() = apply { given(userConfigRepository) - .function(userConfigRepository::getClassifiedDomainsStatus) + .suspendFunction(userConfigRepository::getClassifiedDomainsStatus) .whenInvoked() .thenReturn(emptyFlow()) } fun withGettingClassifiedDomains(domains: List) = apply { given(userConfigRepository) - .function(userConfigRepository::getClassifiedDomainsStatus) + .suspendFunction(userConfigRepository::getClassifiedDomainsStatus) .whenInvoked() .thenReturn(flowOf(Either.Right(ClassifiedDomainsStatus(true, domains)))) } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/featureConfig/SyncFeatureConfigsUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/featureConfig/SyncFeatureConfigsUseCaseTest.kt index 6a871f22e70..361a27499a6 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/featureConfig/SyncFeatureConfigsUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/featureConfig/SyncFeatureConfigsUseCaseTest.kt @@ -19,19 +19,20 @@ package com.wire.kalium.logic.feature.featureConfig import com.wire.kalium.logic.NetworkFailure import com.wire.kalium.logic.configuration.FileSharingStatus -import com.wire.kalium.logic.configuration.GuestRoomLinkStatus import com.wire.kalium.logic.configuration.UserConfigDataSource import com.wire.kalium.logic.configuration.UserConfigRepository import com.wire.kalium.logic.data.featureConfig.ConferenceCallingModel import com.wire.kalium.logic.data.featureConfig.ConfigsStatusModel +import com.wire.kalium.logic.data.featureConfig.E2EIConfigModel +import com.wire.kalium.logic.data.featureConfig.E2EIModel import com.wire.kalium.logic.data.featureConfig.FeatureConfigModel import com.wire.kalium.logic.data.featureConfig.FeatureConfigRepository import com.wire.kalium.logic.data.featureConfig.FeatureConfigTest -import com.wire.kalium.logic.data.featureConfig.E2EIConfigModel -import com.wire.kalium.logic.data.featureConfig.E2EIModel import com.wire.kalium.logic.data.featureConfig.SelfDeletingMessagesConfigModel import com.wire.kalium.logic.data.featureConfig.SelfDeletingMessagesModel import com.wire.kalium.logic.data.featureConfig.Status +import com.wire.kalium.logic.data.message.SelfDeletionMapper.toTeamSelfDeleteTimer +import com.wire.kalium.logic.data.message.TeamSelfDeleteTimer import com.wire.kalium.logic.feature.featureConfig.handler.AppLockConfigHandler import com.wire.kalium.logic.feature.featureConfig.handler.ClassifiedDomainsConfigHandler import com.wire.kalium.logic.feature.featureConfig.handler.ConferenceCallingConfigHandler @@ -42,8 +43,6 @@ import com.wire.kalium.logic.feature.featureConfig.handler.MLSConfigHandler import com.wire.kalium.logic.feature.featureConfig.handler.MLSMigrationConfigHandler import com.wire.kalium.logic.feature.featureConfig.handler.SecondFactorPasswordChallengeConfigHandler import com.wire.kalium.logic.feature.featureConfig.handler.SelfDeletingMessagesConfigHandler -import com.wire.kalium.logic.data.message.SelfDeletionMapper.toTeamSelfDeleteTimer -import com.wire.kalium.logic.data.message.TeamSelfDeleteTimer import com.wire.kalium.logic.feature.user.UpdateSupportedProtocolsAndResolveOneOnOnesUseCase import com.wire.kalium.logic.featureFlags.BuildFileRestrictionState import com.wire.kalium.logic.featureFlags.KaliumConfigs @@ -51,9 +50,11 @@ import com.wire.kalium.logic.framework.TestUser import com.wire.kalium.logic.functional.Either import com.wire.kalium.logic.test_util.TestNetworkException import com.wire.kalium.logic.util.shouldSucceed -import com.wire.kalium.persistence.config.inMemoryUserConfigStorage import com.wire.kalium.persistence.dao.SupportedProtocolEntity +import com.wire.kalium.persistence.dao.config.MLSConfigDAO import com.wire.kalium.persistence.dao.config.UserConfigDAO +import com.wire.kalium.persistence.dao.config.model.IsFileSharingEnabledEntity +import com.wire.kalium.persistence.dao.config.model.IsGuestRoomLinkEnabledEntity import io.mockative.Mock import io.mockative.any import io.mockative.classOf @@ -281,8 +282,8 @@ class SyncFeatureConfigsUseCaseTest { FeatureConfigTest.newModel(guestRoomLink = ConfigsStatusModel(Status.ENABLED)) ) .withGuestRoomLinkEnabledReturning( - GuestRoomLinkStatus( - isGuestRoomLinkEnabled = true, + IsGuestRoomLinkEnabledEntity( + status = true, isStatusChanged = false ) ) @@ -304,8 +305,8 @@ class SyncFeatureConfigsUseCaseTest { FeatureConfigTest.newModel(guestRoomLink = ConfigsStatusModel(Status.DISABLED)) ) .withGuestRoomLinkEnabledReturning( - GuestRoomLinkStatus( - isGuestRoomLinkEnabled = false, + IsGuestRoomLinkEnabledEntity( + status = false, isStatusChanged = false ) ) @@ -327,8 +328,8 @@ class SyncFeatureConfigsUseCaseTest { FeatureConfigTest.newModel(guestRoomLink = ConfigsStatusModel(Status.DISABLED)) ) .withGuestRoomLinkEnabledReturning( - GuestRoomLinkStatus( - isGuestRoomLinkEnabled = true, + IsGuestRoomLinkEnabledEntity( + status = true, isStatusChanged = false ) ) @@ -351,8 +352,8 @@ class SyncFeatureConfigsUseCaseTest { FeatureConfigTest.newModel(guestRoomLink = ConfigsStatusModel(Status.ENABLED)) ) .withGuestRoomLinkEnabledReturning( - GuestRoomLinkStatus( - isGuestRoomLinkEnabled = false, + IsGuestRoomLinkEnabledEntity( + status = false, isStatusChanged = false ) ) @@ -627,16 +628,17 @@ class SyncFeatureConfigsUseCaseTest { private class Arrangement { - private val inMemoryStorage = inMemoryUserConfigStorage() - var kaliumConfigs = KaliumConfigs() @Mock val userConfigDAO: UserConfigDAO = mock(UserConfigDAO::class) + @Mock + val mlsConfigDAO: MLSConfigDAO = mock(MLSConfigDAO::class) + var userConfigRepository: UserConfigRepository = UserConfigDataSource( - inMemoryStorage, userConfigDAO, + mlsConfigDAO, kaliumConfigs ) private set @@ -656,8 +658,8 @@ class SyncFeatureConfigsUseCaseTest { // isStatusChanged = false // ) withGuestRoomLinkEnabledReturning( - GuestRoomLinkStatus( - isGuestRoomLinkEnabled = true, + IsGuestRoomLinkEnabledEntity( + status = true, isStatusChanged = false ) ) @@ -668,8 +670,8 @@ class SyncFeatureConfigsUseCaseTest { ) = apply { kaliumConfigs = kaliumConfigs.copy(fileRestrictionState = state) userConfigRepository = UserConfigDataSource( - inMemoryStorage, userConfigDAO, + mlsConfigDAO, kaliumConfigs ) } @@ -688,16 +690,17 @@ class SyncFeatureConfigsUseCaseTest { status: Boolean, isStatusChanged: Boolean? ) = apply { - userConfigRepository.setFileSharingStatus( - status, isStatusChanged - ) + given(userConfigDAO) + .suspendFunction(userConfigDAO::isFileSharingEnabled) + .whenInvoked() + .then { IsFileSharingEnabledEntity(status, isStatusChanged) } } - fun withGuestRoomLinkEnabledReturning(guestRoomLinkStatus: GuestRoomLinkStatus) = apply { - inMemoryStorage.persistGuestRoomLinkFeatureFlag( - guestRoomLinkStatus.isGuestRoomLinkEnabled ?: false, - guestRoomLinkStatus.isStatusChanged - ) + fun withGuestRoomLinkEnabledReturning(guestRoomLinkStatus: IsGuestRoomLinkEnabledEntity) = apply { + given(userConfigDAO) + .suspendFunction(userConfigDAO::isGuestRoomLinkEnabled) + .whenInvoked() + .then { guestRoomLinkStatus } } fun withGetTeamSettingsSelfDeletionStatusSuccessful() = apply { diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/AppLockConfigHandlerTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/AppLockConfigHandlerTest.kt index 5b98a583877..5e04c2cf458 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/AppLockConfigHandlerTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/featureConfig/handler/AppLockConfigHandlerTest.kt @@ -30,13 +30,14 @@ import io.mockative.given import io.mockative.mock import io.mockative.once import io.mockative.verify +import kotlinx.coroutines.test.runTest import kotlin.test.Test import kotlin.time.Duration.Companion.seconds class AppLockConfigHandlerTest { @Test - fun givenConfigRepositoryReturnsFailureWithStatusDisabled_whenHandlingTheEvent_ThenSetAppLockWithStatusChangedFalse() { + fun givenConfigRepositoryReturnsFailureWithStatusDisabled_whenHandlingTheEvent_ThenSetAppLockWithStatusChangedFalse() = runTest { val appLockModel = AppLockModel(Status.DISABLED, 20) val (arrangement, appLockConfigHandler) = Arrangement() .withUserConfigRepositoryFailure() @@ -45,7 +46,7 @@ class AppLockConfigHandlerTest { appLockConfigHandler.handle(appLockModel) verify(arrangement.userConfigRepository) - .function(arrangement.userConfigRepository::isTeamAppLockEnabled) + .suspendFunction(arrangement.userConfigRepository::isTeamAppLockEnabled) .wasInvoked(exactly = once) verify(arrangement.userConfigRepository) @@ -59,7 +60,7 @@ class AppLockConfigHandlerTest { } @Test - fun givenConfigRepositoryReturnsFailureWithStatusEnabled_whenHandlingTheEvent_ThenSetAppLockWithStatusChangedTrue() { + fun givenConfigRepositoryReturnsFailureWithStatusEnabled_whenHandlingTheEvent_ThenSetAppLockWithStatusChangedTrue() = runTest { val appLockModel = AppLockModel(Status.ENABLED, 20) val (arrangement, appLockConfigHandler) = Arrangement() .withUserConfigRepositoryFailure() @@ -68,7 +69,7 @@ class AppLockConfigHandlerTest { appLockConfigHandler.handle(appLockModel) verify(arrangement.userConfigRepository) - .function(arrangement.userConfigRepository::isTeamAppLockEnabled) + .suspendFunction(arrangement.userConfigRepository::isTeamAppLockEnabled) .wasInvoked(exactly = once) verify(arrangement.userConfigRepository) @@ -82,7 +83,7 @@ class AppLockConfigHandlerTest { } @Test - fun givenNewStatusSameAsCurrent_whenHandlingTheEvent_ThenSetAppLockWithStatusChangedFalse() { + fun givenNewStatusSameAsCurrent_whenHandlingTheEvent_ThenSetAppLockWithStatusChangedFalse() = runTest { val appLockModel = AppLockModel(Status.ENABLED, 44) val (arrangement, appLockConfigHandler) = Arrangement() .withAppLocked() @@ -91,7 +92,7 @@ class AppLockConfigHandlerTest { appLockConfigHandler.handle(appLockModel) verify(arrangement.userConfigRepository) - .function(arrangement.userConfigRepository::isTeamAppLockEnabled) + .suspendFunction(arrangement.userConfigRepository::isTeamAppLockEnabled) .wasInvoked(exactly = once) verify(arrangement.userConfigRepository) @@ -105,7 +106,7 @@ class AppLockConfigHandlerTest { } @Test - fun givenStatusEnabledAndTimeoutDifferentFromCurrent_whenHandlingTheEvent_ThenSetAppLockWithStatusChangedTrue() { + fun givenStatusEnabledAndTimeoutDifferentFromCurrent_whenHandlingTheEvent_ThenSetAppLockWithStatusChangedTrue() = runTest { val appLockModel = AppLockModel(Status.ENABLED, 20) val (arrangement, appLockConfigHandler) = Arrangement() .withAppLocked() @@ -114,7 +115,7 @@ class AppLockConfigHandlerTest { appLockConfigHandler.handle(appLockModel) verify(arrangement.userConfigRepository) - .function(arrangement.userConfigRepository::isTeamAppLockEnabled) + .suspendFunction(arrangement.userConfigRepository::isTeamAppLockEnabled) .wasInvoked(exactly = once) verify(arrangement.userConfigRepository) @@ -128,7 +129,7 @@ class AppLockConfigHandlerTest { } @Test - fun givenNewStatusDifferentThenCurrent_whenHandlingTheEvent_ThenSetAppLockWithStatusChangedTrue() { + fun givenNewStatusDifferentThenCurrent_whenHandlingTheEvent_ThenSetAppLockWithStatusChangedTrue() = runTest { val appLockModel = AppLockModel(Status.ENABLED, 20) val (arrangement, appLockConfigHandler) = Arrangement() .withAppNotLocked() @@ -137,7 +138,7 @@ class AppLockConfigHandlerTest { appLockConfigHandler.handle(appLockModel) verify(arrangement.userConfigRepository) - .function(arrangement.userConfigRepository::isTeamAppLockEnabled) + .suspendFunction(arrangement.userConfigRepository::isTeamAppLockEnabled) .wasInvoked(exactly = once) verify(arrangement.userConfigRepository) @@ -163,28 +164,28 @@ class AppLockConfigHandlerTest { init { given(userConfigRepository) - .function(userConfigRepository::setAppLockStatus) + .suspendFunction(userConfigRepository::setAppLockStatus) .whenInvokedWith(any()) .thenReturn(Either.Right(Unit)) } fun withUserConfigRepositoryFailure() = apply { given(userConfigRepository) - .function(userConfigRepository::isTeamAppLockEnabled) + .suspendFunction(userConfigRepository::isTeamAppLockEnabled) .whenInvoked() .thenReturn(Either.Left(StorageFailure.DataNotFound)) } fun withAppLocked() = apply { given(userConfigRepository) - .function(userConfigRepository::isTeamAppLockEnabled) + .suspendFunction(userConfigRepository::isTeamAppLockEnabled) .whenInvoked() .thenReturn(Either.Right(appLockTeamConfigEnabled)) } fun withAppNotLocked() = apply { given(userConfigRepository) - .function(userConfigRepository::isTeamAppLockEnabled) + .suspendFunction(userConfigRepository::isTeamAppLockEnabled) .whenInvoked() .thenReturn(Either.Right(appLockTeamConfigDisabled)) } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/session/IsFileSharingEnabledUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/session/IsFileSharingEnabledUseCaseTest.kt index e8f149b2005..f09bab24a2b 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/session/IsFileSharingEnabledUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/session/IsFileSharingEnabledUseCaseTest.kt @@ -48,7 +48,7 @@ class IsFileSharingEnabledUseCaseTest { val actual = isFileSharingEnabledUseCase.invoke() assertEquals(expectedValue, actual) - verify(arrangement.userConfigRepository).invocation { isFileSharingEnabled() } + verify(arrangement.userConfigRepository).coroutine { isFileSharingEnabled() } .wasInvoked(exactly = once) } @@ -64,7 +64,7 @@ class IsFileSharingEnabledUseCaseTest { isFileSharingEnabledUseCase.invoke() verify(arrangement.userConfigRepository) - .function(arrangement.userConfigRepository::isFileSharingEnabled) + .suspendFunction(arrangement.userConfigRepository::isFileSharingEnabled) .wasInvoked(exactly = once) } @@ -76,7 +76,7 @@ class IsFileSharingEnabledUseCaseTest { fun withSuccessfulResponse(expectedValue: FileSharingStatus): Arrangement { given(userConfigRepository) - .function(userConfigRepository::isFileSharingEnabled) + .suspendFunction(userConfigRepository::isFileSharingEnabled) .whenInvoked() .thenReturn(Either.Right(expectedValue)) @@ -85,7 +85,7 @@ class IsFileSharingEnabledUseCaseTest { fun withIsFileSharingEnabledErrorResponse(storageFailure: StorageFailure): Arrangement { given(userConfigRepository) - .function(userConfigRepository::isFileSharingEnabled) + .suspendFunction(userConfigRepository::isFileSharingEnabled) .whenInvoked() .thenReturn(Either.Left(storageFailure)) return this diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/guestroomlink/MarkGuestLinkFeatureFlagAsNotChangedUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/guestroomlink/MarkGuestLinkFeatureFlagAsNotChangedUseCaseTest.kt index 84147d74d1b..8235d0caaa2 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/guestroomlink/MarkGuestLinkFeatureFlagAsNotChangedUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/guestroomlink/MarkGuestLinkFeatureFlagAsNotChangedUseCaseTest.kt @@ -29,6 +29,7 @@ import io.mockative.given import io.mockative.mock import io.mockative.once import io.mockative.verify +import kotlinx.coroutines.test.runTest import kotlin.test.BeforeTest import kotlin.test.Test @@ -45,30 +46,30 @@ class MarkGuestLinkFeatureFlagAsNotChangedUseCaseTest { } @Test - fun givenRepositoryReturnsFailure_whenInvokingUseCase_thenDoNotUpdateGuestStatus() { - given(userConfigRepository).invocation { getGuestRoomLinkStatus() } + fun givenRepositoryReturnsFailure_whenInvokingUseCase_thenDoNotUpdateGuestStatus() = runTest { + given(userConfigRepository).coroutine { getGuestRoomLinkStatus() } .thenReturn(Either.Left(StorageFailure.DataNotFound)) markGuestLinkFeatureFlagAsNotChanged() - verify(userConfigRepository).function(userConfigRepository::getGuestRoomLinkStatus) + verify(userConfigRepository).suspendFunction(userConfigRepository::getGuestRoomLinkStatus) .wasInvoked(exactly = once) - verify(userConfigRepository).function(userConfigRepository::setGuestRoomStatus).with(any(), eq(false)).wasNotInvoked() + verify(userConfigRepository).suspendFunction(userConfigRepository::setGuestRoomStatus).with(any(), eq(false)).wasNotInvoked() } @Test - fun givenRepositoryReturnsSuccess_whenInvokingUseCase_thenUpdateGuestStatus() { - given(userConfigRepository).invocation { getGuestRoomLinkStatus() } + fun givenRepositoryReturnsSuccess_whenInvokingUseCase_thenUpdateGuestStatus() = runTest { + given(userConfigRepository).coroutine { getGuestRoomLinkStatus() } .thenReturn(Either.Right(GuestRoomLinkStatus(isGuestRoomLinkEnabled = true, isStatusChanged = false))) - given(userConfigRepository).invocation { setGuestRoomStatus(status = false, isStatusChanged = false) } + given(userConfigRepository).coroutine { setGuestRoomStatus(status = false, isStatusChanged = false) } .thenReturn(Either.Right(Unit)) markGuestLinkFeatureFlagAsNotChanged() - verify(userConfigRepository).function(userConfigRepository::getGuestRoomLinkStatus) + verify(userConfigRepository).suspendFunction(userConfigRepository::getGuestRoomLinkStatus) .wasInvoked(exactly = once) - verify(userConfigRepository).function(userConfigRepository::setGuestRoomStatus).with(any(), eq(false)).wasInvoked(once) + verify(userConfigRepository).suspendFunction(userConfigRepository::setGuestRoomStatus).with(any(), eq(false)).wasInvoked(once) } } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/guestroomlink/ObserveGuestRoomLinkFeatureFlagUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/guestroomlink/ObserveGuestRoomLinkFeatureFlagUseCaseTest.kt index f3e8addf27a..99e107dad96 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/guestroomlink/ObserveGuestRoomLinkFeatureFlagUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/guestroomlink/ObserveGuestRoomLinkFeatureFlagUseCaseTest.kt @@ -49,7 +49,7 @@ class ObserveGuestRoomLinkFeatureFlagUseCaseTest { @OptIn(ExperimentalCoroutinesApi::class) @Test fun givenRepositoryEmitsFailure_whenRunningUseCase_thenEmitStatusWithNullValues() = runTest { - given(userConfigRepository).invocation { observeGuestRoomLinkFeatureFlag() } + given(userConfigRepository).coroutine { observeGuestRoomLinkFeatureFlag() } .thenReturn(flowOf(Either.Left(StorageFailure.DataNotFound))) val result = observeGuestRoomLinkFeatureFlag() @@ -63,7 +63,7 @@ class ObserveGuestRoomLinkFeatureFlagUseCaseTest { fun givenRepositoryEmitsValidValues_whenRunningUseCase_thenEmitThoseValidValues() = runTest { val expectedStatus = GuestRoomLinkStatus(isGuestRoomLinkEnabled = true, isStatusChanged = false) - given(userConfigRepository).invocation { observeGuestRoomLinkFeatureFlag() } + given(userConfigRepository).coroutine { observeGuestRoomLinkFeatureFlag() } .thenReturn(flowOf(Either.Right(expectedStatus))) val result = observeGuestRoomLinkFeatureFlag() diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/FeatureConfigEventReceiverTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/FeatureConfigEventReceiverTest.kt index beec4564067..de56a891f7a 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/FeatureConfigEventReceiverTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/FeatureConfigEventReceiverTest.kt @@ -27,6 +27,8 @@ import com.wire.kalium.logic.data.featureConfig.ConfigsStatusModel import com.wire.kalium.logic.data.featureConfig.SelfDeletingMessagesConfigModel import com.wire.kalium.logic.data.featureConfig.SelfDeletingMessagesModel import com.wire.kalium.logic.data.featureConfig.Status +import com.wire.kalium.logic.data.message.TeamSelfDeleteTimer +import com.wire.kalium.logic.data.message.TeamSettingsSelfDeletionStatus import com.wire.kalium.logic.feature.featureConfig.handler.AppLockConfigHandler import com.wire.kalium.logic.feature.featureConfig.handler.ClassifiedDomainsConfigHandler import com.wire.kalium.logic.feature.featureConfig.handler.ConferenceCallingConfigHandler @@ -35,16 +37,12 @@ import com.wire.kalium.logic.feature.featureConfig.handler.FileSharingConfigHand import com.wire.kalium.logic.feature.featureConfig.handler.GuestRoomConfigHandler import com.wire.kalium.logic.feature.featureConfig.handler.MLSConfigHandler import com.wire.kalium.logic.feature.featureConfig.handler.MLSMigrationConfigHandler -import com.wire.kalium.logic.feature.featureConfig.handler.SecondFactorPasswordChallengeConfigHandler import com.wire.kalium.logic.feature.featureConfig.handler.SelfDeletingMessagesConfigHandler -import com.wire.kalium.logic.data.message.TeamSelfDeleteTimer -import com.wire.kalium.logic.data.message.TeamSettingsSelfDeletionStatus import com.wire.kalium.logic.feature.user.UpdateSupportedProtocolsAndResolveOneOnOnesUseCase import com.wire.kalium.logic.featureFlags.KaliumConfigs import com.wire.kalium.logic.framework.TestEvent import com.wire.kalium.logic.framework.TestUser import com.wire.kalium.logic.functional.Either -import com.wire.kalium.logic.util.shouldFail import com.wire.kalium.logic.util.shouldSucceed import io.mockative.Mock import io.mockative.any @@ -317,21 +315,21 @@ class FeatureConfigEventReceiverTest { fun withSettingFileSharingEnabledSuccessful() = apply { given(userConfigRepository) - .function(userConfigRepository::setFileSharingStatus) + .suspendFunction(userConfigRepository::setFileSharingStatus) .whenInvokedWith(any(), any()) .thenReturn(Either.Right(Unit)) } fun withSettingConferenceCallingEnabledSuccessful() = apply { given(userConfigRepository) - .function(userConfigRepository::setConferenceCallingEnabled) + .suspendFunction(userConfigRepository::setConferenceCallingEnabled) .whenInvokedWith(any()) .thenReturn(Either.Right(Unit)) } fun withIsFileSharingEnabled(result: Either) = apply { given(userConfigRepository) - .function(userConfigRepository::isFileSharingEnabled) + .suspendFunction(userConfigRepository::isFileSharingEnabled) .whenInvoked() .thenReturn(result) } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/UserPropertiesEventReceiverTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/UserPropertiesEventReceiverTest.kt index 2e26c7f9239..53a1772cb5e 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/UserPropertiesEventReceiverTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/UserPropertiesEventReceiverTest.kt @@ -43,7 +43,7 @@ class UserPropertiesEventReceiverTest { eventReceiver.onEvent(event) verify(arrangement.userConfigRepository) - .function(arrangement.userConfigRepository::setReadReceiptsStatus) + .suspendFunction(arrangement.userConfigRepository::setReadReceiptsStatus) .with(any()) .wasInvoked(exactly = once) } @@ -59,7 +59,7 @@ class UserPropertiesEventReceiverTest { fun withUpdateReadReceiptsSuccess() = apply { given(userConfigRepository) - .function(userConfigRepository::setReadReceiptsStatus) + .suspendFunction(userConfigRepository::setReadReceiptsStatus) .whenInvokedWith(any()) .thenReturn(Either.Right(Unit)) } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/ApplicationMessageHandlerTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/ApplicationMessageHandlerTest.kt index 2a45f7d6f07..841225e9cd5 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/ApplicationMessageHandlerTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/ApplicationMessageHandlerTest.kt @@ -199,7 +199,7 @@ class ApplicationMessageHandlerTest { fun withFileSharingEnabled() = apply { given(userConfigRepository) - .function(userConfigRepository::isFileSharingEnabled) + .suspendFunction(userConfigRepository::isFileSharingEnabled) .whenInvoked() .thenReturn( Either.Right( diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/repository/UserConfigRepositoryArrangement.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/repository/UserConfigRepositoryArrangement.kt index 1ea16666fe4..ca1dbe747f2 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/repository/UserConfigRepositoryArrangement.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/repository/UserConfigRepositoryArrangement.kt @@ -17,7 +17,6 @@ */ package com.wire.kalium.logic.util.arrangement.repository -import com.wire.kalium.logic.CoreFailure import com.wire.kalium.logic.StorageFailure import com.wire.kalium.logic.configuration.UserConfigRepository import com.wire.kalium.logic.data.featureConfig.MLSMigrationModel @@ -59,14 +58,14 @@ internal class UserConfigRepositoryArrangementImpl : UserConfigRepositoryArrange override fun withSetDefaultProtocolSuccessful() { given(userConfigRepository) - .function(userConfigRepository::setDefaultProtocol) + .suspendFunction(userConfigRepository::setDefaultProtocol) .whenInvokedWith(any()) .thenReturn(Either.Right(Unit)) } override fun withSetMLSEnabledSuccessful() { given(userConfigRepository) - .function(userConfigRepository::setMLSEnabled) + .suspendFunction(userConfigRepository::setMLSEnabled) .whenInvokedWith(any()) .thenReturn(Either.Right(Unit)) } diff --git a/logic/src/jvmTest/kotlin/com/wire/kalium/logic/sync/receiver/asset/AssetMessageHandlerTest.kt b/logic/src/jvmTest/kotlin/com/wire/kalium/logic/sync/receiver/asset/AssetMessageHandlerTest.kt index dd82921898c..d1be8c548c4 100644 --- a/logic/src/jvmTest/kotlin/com/wire/kalium/logic/sync/receiver/asset/AssetMessageHandlerTest.kt +++ b/logic/src/jvmTest/kotlin/com/wire/kalium/logic/sync/receiver/asset/AssetMessageHandlerTest.kt @@ -44,7 +44,6 @@ import io.mockative.once import io.mockative.verify import junit.framework.TestCase.assertFalse import junit.framework.TestCase.assertTrue -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.Test @@ -279,7 +278,7 @@ class AssetMessageHandlerTest { fun withSuccessfulFileSharingFlag(value: FileSharingStatus.Value) = apply { given(userConfigRepository) - .function(userConfigRepository::isFileSharingEnabled) + .suspendFunction(userConfigRepository::isFileSharingEnabled) .whenInvoked() .thenReturn(Either.Right(FileSharingStatus(state = value, isStatusChanged = false))) } diff --git a/persistence-test/src/commonMain/kotlin/com/wire/kalium/persistence/config/TestUserConfigStorage.kt b/persistence-test/src/commonMain/kotlin/com/wire/kalium/persistence/config/TestUserConfigStorage.kt deleted file mode 100644 index 4ad988e6456..00000000000 --- a/persistence-test/src/commonMain/kotlin/com/wire/kalium/persistence/config/TestUserConfigStorage.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Wire - * Copyright (C) 2023 Wire Swiss GmbH - * - * This program 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. - * - * This program 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 this program. If not, see http://www.gnu.org/licenses/. - */ -package com.wire.kalium.persistence.config - -import com.russhwolf.settings.MapSettings -import com.wire.kalium.persistence.kmmSettings.KaliumPreferencesSettings - -fun inMemoryUserConfigStorage(): UserConfigStorage = UserConfigStorageImpl( - KaliumPreferencesSettings(MapSettings()) -)