From 98de0b7cfb4e9effb982db0360308c124812c843 Mon Sep 17 00:00:00 2001 From: Artem Chepurnoy Date: Sun, 30 Jun 2024 20:55:52 +0300 Subject: [PATCH] refactor: Align User-Agent with what official Bitwarden clients send #324 --- .../util/PlatformUserAgent.android.kt | 8 ++++++ .../platform/util/PlatformUserAgent.kt | 5 ++++ .../keyguard/provider/bitwarden/api/login.kt | 27 +++++++++++++------ .../util/PlatformUserAgent.desktop.kt | 12 +++++++++ .../artemchep/keyguard/di/GlobalModuleJvm.kt | 5 ++-- 5 files changed, 47 insertions(+), 10 deletions(-) create mode 100644 common/src/androidMain/kotlin/com/artemchep/keyguard/platform/util/PlatformUserAgent.android.kt create mode 100644 common/src/commonMain/kotlin/com/artemchep/keyguard/platform/util/PlatformUserAgent.kt create mode 100644 common/src/desktopMain/kotlin/com/artemchep/keyguard/platform/util/PlatformUserAgent.desktop.kt diff --git a/common/src/androidMain/kotlin/com/artemchep/keyguard/platform/util/PlatformUserAgent.android.kt b/common/src/androidMain/kotlin/com/artemchep/keyguard/platform/util/PlatformUserAgent.android.kt new file mode 100644 index 0000000..81fcadb --- /dev/null +++ b/common/src/androidMain/kotlin/com/artemchep/keyguard/platform/util/PlatformUserAgent.android.kt @@ -0,0 +1,8 @@ +package com.artemchep.keyguard.platform.util + +import android.os.Build +import com.artemchep.keyguard.platform.Platform +import com.artemchep.keyguard.provider.bitwarden.api.BitwardenPersona + +actual val Platform.userAgent: String + get() = "Bitwarden_Mobile/${BitwardenPersona.CLIENT_VERSION} (Android ${Build.VERSION.RELEASE}; SDK ${Build.VERSION.SDK_INT}; Model ${Build.MODEL})" diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/platform/util/PlatformUserAgent.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/platform/util/PlatformUserAgent.kt new file mode 100644 index 0000000..2c32f56 --- /dev/null +++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/platform/util/PlatformUserAgent.kt @@ -0,0 +1,5 @@ +package com.artemchep.keyguard.platform.util + +import com.artemchep.keyguard.platform.Platform + +expect val Platform.userAgent: String diff --git a/common/src/commonMain/kotlin/com/artemchep/keyguard/provider/bitwarden/api/login.kt b/common/src/commonMain/kotlin/com/artemchep/keyguard/provider/bitwarden/api/login.kt index ad6bd36..31b32d1 100644 --- a/common/src/commonMain/kotlin/com/artemchep/keyguard/provider/bitwarden/api/login.kt +++ b/common/src/commonMain/kotlin/com/artemchep/keyguard/provider/bitwarden/api/login.kt @@ -11,6 +11,7 @@ import com.artemchep.keyguard.common.util.int import com.artemchep.keyguard.core.store.bitwarden.BitwardenToken import com.artemchep.keyguard.platform.CurrentPlatform import com.artemchep.keyguard.platform.Platform +import com.artemchep.keyguard.platform.util.userAgent import com.artemchep.keyguard.provider.bitwarden.ServerEnv import com.artemchep.keyguard.provider.bitwarden.ServerTwoFactorToken import com.artemchep.keyguard.provider.bitwarden.api.builder.api @@ -49,43 +50,53 @@ data class BitwardenPersona( val clientVersion: String, val deviceType: String, val deviceName: String, + val userAgent: String, ) { companion object { - private const val CLIENT_VERSION = "2024.4.0" + const val CLIENT_VERSION = "2024.4.0" fun of(platform: Platform) = when (platform) { - is Platform.Mobile -> desktopLinux() + is Platform.Mobile -> { + Platform.Desktop.Linux.bitwardenPersona() + } + is Platform.Desktop -> when (platform) { - is Platform.Desktop.Windows -> desktopWindows() - is Platform.Desktop.MacOS -> desktopMacOs() + is Platform.Desktop.Windows -> platform.bitwardenPersona() + is Platform.Desktop.MacOS -> platform.bitwardenPersona() is Platform.Desktop.Other, is Platform.Desktop.Linux, - -> desktopLinux() + -> Platform.Desktop.Linux.bitwardenPersona() } } - private fun desktopLinux() = BitwardenPersona( + private fun Platform.Desktop.Linux.bitwardenPersona( + ) = BitwardenPersona( clientId = "desktop", clientName = "desktop", clientVersion = CLIENT_VERSION, deviceType = "8", deviceName = "linux", + userAgent = userAgent, ) - private fun desktopMacOs() = BitwardenPersona( + private fun Platform.Desktop.MacOS.bitwardenPersona( + ) = BitwardenPersona( clientId = "desktop", clientName = "desktop", clientVersion = CLIENT_VERSION, deviceType = "7", deviceName = "macos", + userAgent = userAgent, ) - private fun desktopWindows() = BitwardenPersona( + private fun Platform.Desktop.Windows.bitwardenPersona( + ) = BitwardenPersona( clientId = "desktop", clientName = "desktop", clientVersion = CLIENT_VERSION, deviceType = "6", deviceName = "windows", + userAgent = userAgent, ) } } diff --git a/common/src/desktopMain/kotlin/com/artemchep/keyguard/platform/util/PlatformUserAgent.desktop.kt b/common/src/desktopMain/kotlin/com/artemchep/keyguard/platform/util/PlatformUserAgent.desktop.kt new file mode 100644 index 0000000..a207d49 --- /dev/null +++ b/common/src/desktopMain/kotlin/com/artemchep/keyguard/platform/util/PlatformUserAgent.desktop.kt @@ -0,0 +1,12 @@ +package com.artemchep.keyguard.platform.util + +import com.artemchep.keyguard.platform.Platform + +// Taken from: +// https://releases.electronjs.org/releases/stable +private const val CHROME_VERSION = "126.0.6478.114" + +// Seems like desktop clients always use the Windows user-agents for +// privacy reasons. +actual val Platform.userAgent: String + get() = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/$CHROME_VERSION Safari/537.36" diff --git a/common/src/jvmMain/kotlin/com/artemchep/keyguard/di/GlobalModuleJvm.kt b/common/src/jvmMain/kotlin/com/artemchep/keyguard/di/GlobalModuleJvm.kt index dfe9540..2715863 100644 --- a/common/src/jvmMain/kotlin/com/artemchep/keyguard/di/GlobalModuleJvm.kt +++ b/common/src/jvmMain/kotlin/com/artemchep/keyguard/di/GlobalModuleJvm.kt @@ -359,7 +359,9 @@ import com.artemchep.keyguard.core.store.bitwarden.BitwardenCipher import com.artemchep.keyguard.crypto.CipherEncryptorImpl import com.artemchep.keyguard.crypto.CryptoGeneratorJvm import com.artemchep.keyguard.crypto.FileEncryptorImpl +import com.artemchep.keyguard.platform.CurrentPlatform import com.artemchep.keyguard.platform.util.isRelease +import com.artemchep.keyguard.platform.util.userAgent import com.artemchep.keyguard.provider.bitwarden.usecase.CipherUrlCheckImpl import com.artemchep.keyguard.provider.bitwarden.usecase.CipherUrlDuplicateCheckImpl import io.ktor.client.HttpClient @@ -1293,8 +1295,7 @@ fun globalModuleJvm() = DI.Module( val okHttpClient: OkHttpClient = instance() HttpClient(OkHttp) { install(UserAgent) { - agent = - "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36" + agent = CurrentPlatform.userAgent } engine { preconfigured = okHttpClient