Calculate password strength during the initial sync of the ciphers
This commit is contained in:
parent
fcdb373998
commit
3805164489
@ -80,7 +80,7 @@ inline fun <T> IO<T>.handleErrorWith(
|
||||
|
||||
inline fun <T> IO<T>.handleError(
|
||||
crossinline predicate: (Throwable) -> Boolean = { true },
|
||||
crossinline block: (Throwable) -> T,
|
||||
crossinline block: suspend (Throwable) -> T,
|
||||
): IO<T> = ioEffect {
|
||||
try {
|
||||
invoke()
|
||||
|
@ -143,61 +143,11 @@ private const val ROUTE_NAME = "home"
|
||||
|
||||
private val vaultRoute = VaultRoute()
|
||||
|
||||
@Composable
|
||||
fun HomeEffect() {
|
||||
val db by rememberInstance<DatabaseManager>()
|
||||
val ps by rememberInstance<GetPasswordStrength>()
|
||||
LaunchedEffect(Unit) {
|
||||
db.mutate {
|
||||
val ciphers = it.cipherQueries.get().executeAsList()
|
||||
val www = ciphers
|
||||
.filter { it.data_.login?.password != null && it.data_.login.passwordStrength == null }
|
||||
.mapNotNull {
|
||||
val password = it.data_.login?.password!!
|
||||
val s = ps(password)
|
||||
.attempt()
|
||||
.bind()
|
||||
.getOrNull()
|
||||
if (s != null) {
|
||||
val login = it.data_.login.copy(
|
||||
passwordStrength = BitwardenCipher.Login.PasswordStrength(
|
||||
password = password,
|
||||
crackTimeSeconds = s.crackTimeSeconds,
|
||||
version = 1,
|
||||
),
|
||||
)
|
||||
it.copy(
|
||||
data_ = it.data_.copy(
|
||||
login = login,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
.toTypedArray()
|
||||
recordLog("Replaced ${www.size} entities")
|
||||
it.transaction {
|
||||
www.forEach { cipher ->
|
||||
it.cipherQueries.insert(
|
||||
cipherId = cipher.cipherId,
|
||||
accountId = cipher.accountId,
|
||||
folderId = cipher.folderId,
|
||||
data = cipher.data_,
|
||||
)
|
||||
}
|
||||
}
|
||||
}.attempt().bind()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun HomeScreen(
|
||||
defaultRoute: Route = vaultRoute,
|
||||
navBarVisible: Boolean = true,
|
||||
) {
|
||||
HomeEffect()
|
||||
|
||||
val navRoutes = remember {
|
||||
listOf(
|
||||
Rail(
|
||||
|
@ -6,6 +6,7 @@ import com.artemchep.keyguard.common.service.crypto.CipherEncryptor
|
||||
import com.artemchep.keyguard.common.service.crypto.CryptoGenerator
|
||||
import com.artemchep.keyguard.common.service.logging.LogRepository
|
||||
import com.artemchep.keyguard.common.service.text.Base64Service
|
||||
import com.artemchep.keyguard.common.usecase.GetPasswordStrength
|
||||
import com.artemchep.keyguard.core.store.DatabaseManager
|
||||
import com.artemchep.keyguard.core.store.DatabaseSyncer
|
||||
import com.artemchep.keyguard.core.store.bitwarden.BitwardenCipher
|
||||
@ -71,6 +72,7 @@ class SyncEngine(
|
||||
private val cryptoGenerator: CryptoGenerator,
|
||||
private val cipherEncryptor: CipherEncryptor,
|
||||
private val logRepository: LogRepository,
|
||||
private val getPasswordStrength: GetPasswordStrength,
|
||||
private val user: BitwardenToken,
|
||||
private val syncer: DatabaseSyncer,
|
||||
) {
|
||||
@ -500,7 +502,7 @@ class SyncEngine(
|
||||
)
|
||||
.let { remoteDecoded ->
|
||||
// inject the local model into newly decoded remote one
|
||||
local?.let { merge(remoteDecoded, it) } ?: remoteDecoded
|
||||
merge(remoteDecoded, local, getPasswordStrength)
|
||||
}
|
||||
},
|
||||
remoteDeleteById = { id ->
|
||||
@ -554,7 +556,7 @@ class SyncEngine(
|
||||
// types
|
||||
type = BitwardenCipher.Type.Card,
|
||||
)
|
||||
localOrNull?.let { merge(model, it) } ?: model
|
||||
merge(model, localOrNull, getPasswordStrength)
|
||||
},
|
||||
remotePut = { (r, local) ->
|
||||
val ciphersApi = user.env.back().api.ciphers
|
||||
@ -661,7 +663,7 @@ class SyncEngine(
|
||||
)
|
||||
.let { remoteDecoded ->
|
||||
// inject the local model into newly decoded remote one
|
||||
merge(remoteDecoded, r.source)
|
||||
merge(remoteDecoded, r.source, getPasswordStrength)
|
||||
}
|
||||
},
|
||||
onLog = { msg, logLevel ->
|
||||
|
@ -12,6 +12,7 @@ import com.artemchep.keyguard.common.io.ioEffect
|
||||
import com.artemchep.keyguard.common.io.measure
|
||||
import com.artemchep.keyguard.common.io.parallel
|
||||
import com.artemchep.keyguard.common.service.logging.LogLevel
|
||||
import com.artemchep.keyguard.common.usecase.GetPasswordStrength
|
||||
import com.artemchep.keyguard.core.store.bitwarden.BitwardenCipher
|
||||
import com.artemchep.keyguard.core.store.bitwarden.BitwardenService
|
||||
import com.artemchep.keyguard.provider.bitwarden.sync.SyncManager
|
||||
@ -24,12 +25,13 @@ import kotlin.Throwable
|
||||
import kotlin.Unit
|
||||
import kotlin.let
|
||||
|
||||
fun merge(
|
||||
suspend fun merge(
|
||||
remote: BitwardenCipher,
|
||||
local: BitwardenCipher,
|
||||
local: BitwardenCipher?,
|
||||
getPasswordStrength: GetPasswordStrength,
|
||||
): BitwardenCipher {
|
||||
val attachments = remote.attachments.toMutableList()
|
||||
local.attachments.forEachIndexed { localIndex, attachment ->
|
||||
local?.attachments?.forEachIndexed { localIndex, attachment ->
|
||||
val localAttachment = attachment as? BitwardenCipher.Attachment.Local
|
||||
?: return@forEachIndexed
|
||||
|
||||
@ -57,8 +59,34 @@ fun merge(
|
||||
}
|
||||
}
|
||||
|
||||
val ignoredAlerts = local.ignoredAlerts
|
||||
var login = remote.login
|
||||
// Calculate or copy over the password strength of
|
||||
// the password.
|
||||
if (remote.login != null) run {
|
||||
val password = remote.login.password
|
||||
?: return@run
|
||||
val strength = local?.login?.passwordStrength
|
||||
.takeIf { local?.login?.password == remote.login.password }
|
||||
// Generate a password strength badge.
|
||||
?: getPasswordStrength(password)
|
||||
.attempt()
|
||||
.bind()
|
||||
.getOrNull()
|
||||
?.let { ps ->
|
||||
BitwardenCipher.Login.PasswordStrength(
|
||||
password = password,
|
||||
crackTimeSeconds = ps.crackTimeSeconds,
|
||||
version = ps.version,
|
||||
)
|
||||
}
|
||||
login = login?.copy(
|
||||
passwordStrength = strength,
|
||||
)
|
||||
}
|
||||
|
||||
val ignoredAlerts = local?.ignoredAlerts.orEmpty()
|
||||
return remote.copy(
|
||||
login = login,
|
||||
attachments = attachments,
|
||||
ignoredAlerts = ignoredAlerts,
|
||||
)
|
||||
@ -86,9 +114,9 @@ suspend fun <
|
||||
shouldOverwrite: (Local, Remote) -> Boolean = { _, _ -> false },
|
||||
remoteItems: Collection<Remote>,
|
||||
remoteLens: SyncManager.Lens<Remote>,
|
||||
remoteDecoder: (Remote, Local?) -> RemoteDecoded,
|
||||
remoteDecoder: suspend (Remote, Local?) -> RemoteDecoded,
|
||||
remoteDecodedToString: (RemoteDecoded) -> String = { it.toString() },
|
||||
remoteDecodedFallback: (Remote, Local?, Throwable) -> RemoteDecoded,
|
||||
remoteDecodedFallback: suspend (Remote, Local?, Throwable) -> RemoteDecoded,
|
||||
remoteDeleteById: suspend (String) -> Unit,
|
||||
remotePut: suspend RemotePutScope<Remote>.(LocalDecoded) -> RemoteDecoded,
|
||||
onLog: (String, LogLevel) -> Unit,
|
||||
|
@ -13,6 +13,7 @@ import com.artemchep.keyguard.common.service.crypto.CipherEncryptor
|
||||
import com.artemchep.keyguard.common.service.crypto.CryptoGenerator
|
||||
import com.artemchep.keyguard.common.service.logging.LogRepository
|
||||
import com.artemchep.keyguard.common.service.text.Base64Service
|
||||
import com.artemchep.keyguard.common.usecase.GetPasswordStrength
|
||||
import com.artemchep.keyguard.common.usecase.Watchdog
|
||||
import com.artemchep.keyguard.core.store.DatabaseManager
|
||||
import com.artemchep.keyguard.core.store.DatabaseSyncer
|
||||
@ -38,6 +39,7 @@ class SyncByTokenImpl(
|
||||
private val cipherEncryptor: CipherEncryptor,
|
||||
private val cryptoGenerator: CryptoGenerator,
|
||||
private val base64Service: Base64Service,
|
||||
private val getPasswordStrength: GetPasswordStrength,
|
||||
private val json: Json,
|
||||
private val httpClient: HttpClient,
|
||||
private val db: DatabaseManager,
|
||||
@ -55,6 +57,7 @@ class SyncByTokenImpl(
|
||||
cipherEncryptor = directDI.instance(),
|
||||
cryptoGenerator = directDI.instance(),
|
||||
base64Service = directDI.instance(),
|
||||
getPasswordStrength = directDI.instance(),
|
||||
json = directDI.instance(),
|
||||
httpClient = directDI.instance(),
|
||||
db = directDI.instance(),
|
||||
@ -83,6 +86,7 @@ class SyncByTokenImpl(
|
||||
cryptoGenerator = cryptoGenerator,
|
||||
cipherEncryptor = cipherEncryptor,
|
||||
logRepository = logRepository,
|
||||
getPasswordStrength = getPasswordStrength,
|
||||
user = latestUser,
|
||||
syncer = dbSyncer,
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user