From 4f34f6da2181d718e0d7c8e9a419a65edb82f0fd Mon Sep 17 00:00:00 2001 From: Andrew Haisting <142518658+ahaisting-livefront@users.noreply.github.com> Date: Tue, 24 Sep 2024 17:09:27 -0500 Subject: [PATCH] BITAU-172 Rename Authenticator Bridge SDK (#3959) --- app/build.gradle.kts | 2 +- ...enticatorbridge-0.1.0-SNAPSHOT-release.aar | Bin 0 -> 57490 bytes app/libs/bridge-0.1.0-SNAPSHOT-release.aar | Bin 56817 -> 0 bytes .../manager/di/PlatformManagerModule.kt | 14 ++-- .../processor/AuthenticatorBridgeProcessor.kt | 16 +++++ ...kt => AuthenticatorBridgeProcessorImpl.kt} | 50 +++++++------ .../processor/BridgeServiceProcessor.kt | 14 ---- ...ry.kt => AuthenticatorBridgeRepository.kt} | 7 +- ...t => AuthenticatorBridgeRepositoryImpl.kt} | 8 +-- .../repository/SettingsRepositoryImpl.kt | 2 +- .../repository/di/PlatformRepositoryModule.kt | 8 +-- .../service/AuthenticatorBridgeService.kt | 27 +++++++ .../data/platform/service/BridgeService.kt | 27 ------- .../datasource/disk/AuthDiskSourceTest.kt | 2 +- ...kt => AuthenticatorBridgeProcessorTest.kt} | 66 +++++++++--------- ...t => AuthenticatorBridgeRepositoryTest.kt} | 28 ++++---- .../repository/SettingsRepositoryTest.kt | 2 +- {bridge => authenticatorbridge}/.gitignore | 0 {bridge => authenticatorbridge}/CHANGELOG.md | 0 .../CHANGELOG_FORMAT.MD | 0 {bridge => authenticatorbridge}/README.md | 4 +- .../build.gradle.kts | 4 +- .../consumer-rules.pro | 0 .../proguard-rules.pro | 0 .../src/main/AndroidManifest.xml | 0 .../IAuthenticatorBridgeService.aidl | 24 +++---- .../IAuthenticatorBridgeServiceCallback.aidl | 10 +++ .../model/EncryptedAddTotpLoginItemData.aidl | 3 + .../model/EncryptedSharedAccountData.aidl | 3 + .../model/SymmetricEncryptionKeyData.aidl | 3 + ...SymmetricEncryptionKeyFingerprintData.aidl | 2 +- .../model/AddTotpLoginItemData.kt | 5 +- .../model/AddTotpLoginItemDataJson.kt | 2 +- .../model/ByteArrayContainer.kt | 2 +- .../model/EncryptedAddTotpLoginItemData.kt | 2 +- .../model/EncryptedSharedAccountData.kt | 2 +- .../model/SharedAccountData.kt | 2 +- .../model/SharedAccountDataJson.kt | 2 +- .../model/SymmetricEncryptionKeyData.kt | 2 +- .../SymmetricEncryptionKeyFingerprintData.kt | 2 +- .../authenticatorbridge}/util/Constants.kt | 10 +-- .../util/EncryptionUtils.kt | 30 ++++---- .../util/EncryptionUtilTest.kt | 11 ++- .../bridge/IBridgeServiceCallback.aidl | 10 --- .../model/EncryptedAddTotpLoginItemData.aidl | 3 - .../model/EncryptedSharedAccountData.aidl | 3 - .../model/SymmetricEncryptionKeyData.aidl | 3 - settings.gradle.kts | 2 +- 48 files changed, 212 insertions(+), 207 deletions(-) create mode 100644 app/libs/authenticatorbridge-0.1.0-SNAPSHOT-release.aar delete mode 100644 app/libs/bridge-0.1.0-SNAPSHOT-release.aar create mode 100644 app/src/main/java/com/x8bit/bitwarden/data/platform/processor/AuthenticatorBridgeProcessor.kt rename app/src/main/java/com/x8bit/bitwarden/data/platform/processor/{BridgeServiceProcessorImpl.kt => AuthenticatorBridgeProcessorImpl.kt} (65%) delete mode 100644 app/src/main/java/com/x8bit/bitwarden/data/platform/processor/BridgeServiceProcessor.kt rename app/src/main/java/com/x8bit/bitwarden/data/platform/repository/{BridgeRepository.kt => AuthenticatorBridgeRepository.kt} (77%) rename app/src/main/java/com/x8bit/bitwarden/data/platform/repository/{BridgeRepositoryImpl.kt => AuthenticatorBridgeRepositoryImpl.kt} (96%) create mode 100644 app/src/main/java/com/x8bit/bitwarden/data/platform/service/AuthenticatorBridgeService.kt delete mode 100644 app/src/main/java/com/x8bit/bitwarden/data/platform/service/BridgeService.kt rename app/src/test/java/com/x8bit/bitwarden/data/platform/processor/{BridgeServiceProcessorTest.kt => AuthenticatorBridgeProcessorTest.kt} (73%) rename app/src/test/java/com/x8bit/bitwarden/data/platform/repository/{BridgeRepositoryTest.kt => AuthenticatorBridgeRepositoryTest.kt} (94%) rename {bridge => authenticatorbridge}/.gitignore (100%) rename {bridge => authenticatorbridge}/CHANGELOG.md (100%) rename {bridge => authenticatorbridge}/CHANGELOG_FORMAT.MD (100%) rename {bridge => authenticatorbridge}/README.md (95%) rename {bridge => authenticatorbridge}/build.gradle.kts (92%) rename {bridge => authenticatorbridge}/consumer-rules.pro (100%) rename {bridge => authenticatorbridge}/proguard-rules.pro (100%) rename {bridge => authenticatorbridge}/src/main/AndroidManifest.xml (100%) rename bridge/src/main/aidl/com/bitwarden/bridge/IBridgeService.aidl => authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/IAuthenticatorBridgeService.aidl (65%) create mode 100644 authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/IAuthenticatorBridgeServiceCallback.aidl create mode 100644 authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/model/EncryptedAddTotpLoginItemData.aidl create mode 100644 authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/model/EncryptedSharedAccountData.aidl create mode 100644 authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/model/SymmetricEncryptionKeyData.aidl rename {bridge/src/main/aidl/com/bitwarden/bridge => authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge}/model/SymmetricEncryptionKeyFingerprintData.aidl (51%) rename {bridge/src/main/java/com/bitwarden/bridge => authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge}/model/AddTotpLoginItemData.kt (67%) rename {bridge/src/main/java/com/bitwarden/bridge => authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge}/model/AddTotpLoginItemDataJson.kt (89%) rename {bridge/src/main/java/com/bitwarden/bridge => authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge}/model/ByteArrayContainer.kt (94%) rename {bridge/src/main/java/com/bitwarden/bridge => authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge}/model/EncryptedAddTotpLoginItemData.kt (91%) rename {bridge/src/main/java/com/bitwarden/bridge => authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge}/model/EncryptedSharedAccountData.kt (91%) rename {bridge/src/main/java/com/bitwarden/bridge => authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge}/model/SharedAccountData.kt (94%) rename {bridge/src/main/java/com/bitwarden/bridge => authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge}/model/SharedAccountDataJson.kt (96%) rename {bridge/src/main/java/com/bitwarden/bridge => authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge}/model/SymmetricEncryptionKeyData.kt (86%) rename {bridge/src/main/java/com/bitwarden/bridge => authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge}/model/SymmetricEncryptionKeyFingerprintData.kt (90%) rename {bridge/src/main/java/com/bitwarden/bridge => authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge}/util/Constants.kt (87%) rename {bridge/src/main/java/com/bitwarden/bridge => authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge}/util/EncryptionUtils.kt (86%) rename {bridge/src/test/java/com/bitwarden/bridge => authenticatorbridge/src/test/java/com/bitwarden/authenticatorbridge}/util/EncryptionUtilTest.kt (95%) delete mode 100644 bridge/src/main/aidl/com/bitwarden/bridge/IBridgeServiceCallback.aidl delete mode 100644 bridge/src/main/aidl/com/bitwarden/bridge/model/EncryptedAddTotpLoginItemData.aidl delete mode 100644 bridge/src/main/aidl/com/bitwarden/bridge/model/EncryptedSharedAccountData.aidl delete mode 100644 bridge/src/main/aidl/com/bitwarden/bridge/model/SymmetricEncryptionKeyData.aidl diff --git a/app/build.gradle.kts b/app/build.gradle.kts index db0bfe807..dcd98e3ab 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -136,7 +136,7 @@ dependencies { } // TODO: this should use a versioned AAR instead of referencing a local AAR BITAU-94 - implementation(files("libs/bridge-0.1.0-SNAPSHOT-release.aar")) + implementation(files("libs/authenticatorbridge-0.1.0-SNAPSHOT-release.aar")) implementation(libs.androidx.activity.compose) implementation(libs.androidx.appcompat) diff --git a/app/libs/authenticatorbridge-0.1.0-SNAPSHOT-release.aar b/app/libs/authenticatorbridge-0.1.0-SNAPSHOT-release.aar new file mode 100644 index 0000000000000000000000000000000000000000..d1ed04c5b5d87f39d19a5716f38295dffa4b9ff3 GIT binary patch literal 57490 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 diff --git a/app/src/main/java/com/x8bit/bitwarden/data/platform/manager/di/PlatformManagerModule.kt b/app/src/main/java/com/x8bit/bitwarden/data/platform/manager/di/PlatformManagerModule.kt index 59f055e73..2cf703678 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/platform/manager/di/PlatformManagerModule.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/platform/manager/di/PlatformManagerModule.kt @@ -20,8 +20,8 @@ import com.x8bit.bitwarden.data.platform.manager.AssetManager import com.x8bit.bitwarden.data.platform.manager.AssetManagerImpl import com.x8bit.bitwarden.data.platform.manager.BiometricsEncryptionManager import com.x8bit.bitwarden.data.platform.manager.BiometricsEncryptionManagerImpl -import com.x8bit.bitwarden.data.platform.processor.BridgeServiceProcessor -import com.x8bit.bitwarden.data.platform.processor.BridgeServiceProcessorImpl +import com.x8bit.bitwarden.data.platform.processor.AuthenticatorBridgeProcessor +import com.x8bit.bitwarden.data.platform.processor.AuthenticatorBridgeProcessorImpl import com.x8bit.bitwarden.data.platform.manager.CrashLogsManager import com.x8bit.bitwarden.data.platform.manager.CrashLogsManagerImpl import com.x8bit.bitwarden.data.platform.manager.DebugMenuFeatureFlagManagerImpl @@ -51,7 +51,7 @@ import com.x8bit.bitwarden.data.platform.manager.garbage.GarbageCollectionManage import com.x8bit.bitwarden.data.platform.manager.garbage.GarbageCollectionManagerImpl import com.x8bit.bitwarden.data.platform.manager.restriction.RestrictionManager import com.x8bit.bitwarden.data.platform.manager.restriction.RestrictionManagerImpl -import com.x8bit.bitwarden.data.platform.repository.BridgeRepository +import com.x8bit.bitwarden.data.platform.repository.AuthenticatorBridgeRepository import com.x8bit.bitwarden.data.platform.repository.DebugMenuRepository import com.x8bit.bitwarden.data.platform.repository.EnvironmentRepository import com.x8bit.bitwarden.data.platform.repository.ServerConfigRepository @@ -80,12 +80,12 @@ object PlatformManagerModule { @Provides @Singleton - fun provideBridgeServiceProcessor( - bridgeRepository: BridgeRepository, + fun provideAuthenticatorBridgeProcessor( + authenticatorBridgeRepository: AuthenticatorBridgeRepository, dispatcherManager: DispatcherManager, featureFlagManager: FeatureFlagManager, - ): BridgeServiceProcessor = BridgeServiceProcessorImpl( - bridgeRepository = bridgeRepository, + ): AuthenticatorBridgeProcessor = AuthenticatorBridgeProcessorImpl( + authenticatorBridgeRepository = authenticatorBridgeRepository, dispatcherManager = dispatcherManager, featureFlagManager = featureFlagManager, ) diff --git a/app/src/main/java/com/x8bit/bitwarden/data/platform/processor/AuthenticatorBridgeProcessor.kt b/app/src/main/java/com/x8bit/bitwarden/data/platform/processor/AuthenticatorBridgeProcessor.kt new file mode 100644 index 000000000..6b49f4714 --- /dev/null +++ b/app/src/main/java/com/x8bit/bitwarden/data/platform/processor/AuthenticatorBridgeProcessor.kt @@ -0,0 +1,16 @@ +package com.x8bit.bitwarden.data.platform.processor + +import com.bitwarden.authenticatorbridge.IAuthenticatorBridgeService + +/** + * Provides implementation of [IAuthenticatorBridgeService] APIs in an injectable and testable + * manner. + */ +interface AuthenticatorBridgeProcessor { + + /** + * Binder that implements [IAuthenticatorBridgeService]. Null can be returned to represent a + * no-op binder. + */ + val binder: IAuthenticatorBridgeService.Stub? +} diff --git a/app/src/main/java/com/x8bit/bitwarden/data/platform/processor/BridgeServiceProcessorImpl.kt b/app/src/main/java/com/x8bit/bitwarden/data/platform/processor/AuthenticatorBridgeProcessorImpl.kt similarity index 65% rename from app/src/main/java/com/x8bit/bitwarden/data/platform/processor/BridgeServiceProcessorImpl.kt rename to app/src/main/java/com/x8bit/bitwarden/data/platform/processor/AuthenticatorBridgeProcessorImpl.kt index e5dff3945..0b70ca04c 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/platform/processor/BridgeServiceProcessorImpl.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/platform/processor/AuthenticatorBridgeProcessorImpl.kt @@ -4,36 +4,36 @@ import android.content.Intent import android.os.Build import android.os.IInterface import android.os.RemoteCallbackList -import com.bitwarden.bridge.IBridgeService -import com.bitwarden.bridge.IBridgeServiceCallback -import com.bitwarden.bridge.model.EncryptedAddTotpLoginItemData -import com.bitwarden.bridge.model.SymmetricEncryptionKeyData -import com.bitwarden.bridge.model.SymmetricEncryptionKeyFingerprintData -import com.bitwarden.bridge.util.NATIVE_BRIDGE_SDK_VERSION -import com.bitwarden.bridge.util.encrypt -import com.bitwarden.bridge.util.toFingerprint -import com.bitwarden.bridge.util.toSymmetricEncryptionKeyData +import com.bitwarden.authenticatorbridge.IAuthenticatorBridgeService +import com.bitwarden.authenticatorbridge.IAuthenticatorBridgeServiceCallback +import com.bitwarden.authenticatorbridge.model.EncryptedAddTotpLoginItemData +import com.bitwarden.authenticatorbridge.model.SymmetricEncryptionKeyData +import com.bitwarden.authenticatorbridge.model.SymmetricEncryptionKeyFingerprintData +import com.bitwarden.authenticatorbridge.util.AUTHENTICATOR_BRIDGE_SDK_VERSION +import com.bitwarden.authenticatorbridge.util.encrypt +import com.bitwarden.authenticatorbridge.util.toFingerprint +import com.bitwarden.authenticatorbridge.util.toSymmetricEncryptionKeyData import com.x8bit.bitwarden.data.platform.manager.FeatureFlagManager import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager import com.x8bit.bitwarden.data.platform.manager.model.FlagKey -import com.x8bit.bitwarden.data.platform.repository.BridgeRepository +import com.x8bit.bitwarden.data.platform.repository.AuthenticatorBridgeRepository import com.x8bit.bitwarden.data.platform.util.isBuildVersionBelow import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch /** - * Default implementation of [BridgeServiceProcessor]. + * Default implementation of [AuthenticatorBridgeProcessor]. */ -class BridgeServiceProcessorImpl( - private val bridgeRepository: BridgeRepository, +class AuthenticatorBridgeProcessorImpl( + private val authenticatorBridgeRepository: AuthenticatorBridgeRepository, private val featureFlagManager: FeatureFlagManager, dispatcherManager: DispatcherManager, -) : BridgeServiceProcessor { +) : AuthenticatorBridgeProcessor { - private val callbacks by lazy { RemoteCallbackList() } + private val callbacks by lazy { RemoteCallbackList() } private val scope by lazy { CoroutineScope(dispatcherManager.default) } - override val binder: IBridgeService.Stub? + override val binder: IAuthenticatorBridgeService.Stub? get() { return if ( !featureFlagManager.getFeatureFlag(FlagKey.AuthenticatorSync) || @@ -51,16 +51,16 @@ class BridgeServiceProcessorImpl( /** * Default implementation of the bridge service binder. */ - private val defaultBinder = object : IBridgeService.Stub() { + private val defaultBinder = object : IAuthenticatorBridgeService.Stub() { - override fun getVersionNumber(): String = NATIVE_BRIDGE_SDK_VERSION + override fun getVersionNumber(): String = AUTHENTICATOR_BRIDGE_SDK_VERSION override fun checkSymmetricEncryptionKeyFingerprint( symmetricKeyFingerprint: SymmetricEncryptionKeyFingerprintData?, ): Boolean { if (symmetricKeyFingerprint == null) return false val localSymmetricKeyFingerprint = - bridgeRepository.authenticatorSyncSymmetricKey + authenticatorBridgeRepository.authenticatorSyncSymmetricKey ?.toSymmetricEncryptionKeyData() ?.toFingerprint() ?.getOrNull() @@ -68,14 +68,18 @@ class BridgeServiceProcessorImpl( } override fun getSymmetricEncryptionKeyData(): SymmetricEncryptionKeyData? = - bridgeRepository.authenticatorSyncSymmetricKey?.toSymmetricEncryptionKeyData() + authenticatorBridgeRepository + .authenticatorSyncSymmetricKey + ?.toSymmetricEncryptionKeyData() - override fun registerBridgeServiceCallback(callback: IBridgeServiceCallback?) { + override fun registerBridgeServiceCallback(callback: IAuthenticatorBridgeServiceCallback?) { if (callback == null) return callbacks.register(callback) } - override fun unregisterBridgeServiceCallback(callback: IBridgeServiceCallback?) { + override fun unregisterBridgeServiceCallback( + callback: IAuthenticatorBridgeServiceCallback?, + ) { if (callback == null) return callbacks.unregister(callback) } @@ -84,7 +88,7 @@ class BridgeServiceProcessorImpl( val symmetricEncryptionKey = symmetricEncryptionKeyData ?: return scope.launch { // Encrypt the shared account data with the symmetric key: - val encryptedSharedAccountData = bridgeRepository + val encryptedSharedAccountData = authenticatorBridgeRepository .getSharedAccounts() .encrypt(symmetricEncryptionKey) .getOrNull() diff --git a/app/src/main/java/com/x8bit/bitwarden/data/platform/processor/BridgeServiceProcessor.kt b/app/src/main/java/com/x8bit/bitwarden/data/platform/processor/BridgeServiceProcessor.kt deleted file mode 100644 index 50c54c068..000000000 --- a/app/src/main/java/com/x8bit/bitwarden/data/platform/processor/BridgeServiceProcessor.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.x8bit.bitwarden.data.platform.processor - -import com.bitwarden.bridge.IBridgeService - -/** - * Provides access to [IBridgeService] APIs in an injectable and testable manner. - */ -interface BridgeServiceProcessor { - - /** - * Binder that implements [IBridgeService]. Null can be returned to represent a no-op binder. - */ - val binder: IBridgeService.Stub? -} diff --git a/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/BridgeRepository.kt b/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/AuthenticatorBridgeRepository.kt similarity index 77% rename from app/src/main/java/com/x8bit/bitwarden/data/platform/repository/BridgeRepository.kt rename to app/src/main/java/com/x8bit/bitwarden/data/platform/repository/AuthenticatorBridgeRepository.kt index 0e118933b..e898fc33f 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/BridgeRepository.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/AuthenticatorBridgeRepository.kt @@ -1,11 +1,12 @@ package com.x8bit.bitwarden.data.platform.repository -import com.bitwarden.bridge.model.SharedAccountData +import com.bitwarden.authenticatorbridge.model.SharedAccountData /** - * Provides an API for querying disk sources required by Bridge service implementation. + * Provides an API for querying disk sources required by Authenticator Bridge + * service implementation. */ -interface BridgeRepository { +interface AuthenticatorBridgeRepository { /** * The currently persisted authenticator sync symmetric key. This key is used for diff --git a/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/BridgeRepositoryImpl.kt b/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/AuthenticatorBridgeRepositoryImpl.kt similarity index 96% rename from app/src/main/java/com/x8bit/bitwarden/data/platform/repository/BridgeRepositoryImpl.kt rename to app/src/main/java/com/x8bit/bitwarden/data/platform/repository/AuthenticatorBridgeRepositoryImpl.kt index 2892cda74..35de7ad9d 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/BridgeRepositoryImpl.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/AuthenticatorBridgeRepositoryImpl.kt @@ -1,6 +1,6 @@ package com.x8bit.bitwarden.data.platform.repository -import com.bitwarden.bridge.model.SharedAccountData +import com.bitwarden.authenticatorbridge.model.SharedAccountData import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource import com.x8bit.bitwarden.data.auth.repository.AuthRepository import com.x8bit.bitwarden.data.platform.datasource.disk.SettingsDiskSource @@ -14,16 +14,16 @@ import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedSdkCipher import kotlinx.coroutines.flow.first /** - * Default implementation of [BridgeRepository]. + * Default implementation of [AuthenticatorBridgeRepository]. */ -class BridgeRepositoryImpl( +class AuthenticatorBridgeRepositoryImpl( private val authRepository: AuthRepository, private val authDiskSource: AuthDiskSource, private val vaultRepository: VaultRepository, private val vaultDiskSource: VaultDiskSource, private val vaultSdkSource: VaultSdkSource, private val settingsDiskSource: SettingsDiskSource, -) : BridgeRepository { +) : AuthenticatorBridgeRepository { override val authenticatorSyncSymmetricKey: ByteArray? get() = authDiskSource.authenticatorSyncSymmetricKey diff --git a/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/SettingsRepositoryImpl.kt b/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/SettingsRepositoryImpl.kt index 65e09e9aa..f66a6a1bb 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/SettingsRepositoryImpl.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/SettingsRepositoryImpl.kt @@ -1,7 +1,7 @@ package com.x8bit.bitwarden.data.platform.repository import android.view.autofill.AutofillManager -import com.bitwarden.bridge.util.generateSecretKey +import com.bitwarden.authenticatorbridge.util.generateSecretKey import com.x8bit.bitwarden.BuildConfig import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource import com.x8bit.bitwarden.data.auth.repository.model.PolicyInformation diff --git a/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/di/PlatformRepositoryModule.kt b/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/di/PlatformRepositoryModule.kt index 2273aff0a..434ab18d9 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/di/PlatformRepositoryModule.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/platform/repository/di/PlatformRepositoryModule.kt @@ -13,8 +13,8 @@ import com.x8bit.bitwarden.data.platform.datasource.network.service.ConfigServic import com.x8bit.bitwarden.data.platform.manager.BiometricsEncryptionManager import com.x8bit.bitwarden.data.platform.manager.PolicyManager import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager -import com.x8bit.bitwarden.data.platform.repository.BridgeRepository -import com.x8bit.bitwarden.data.platform.repository.BridgeRepositoryImpl +import com.x8bit.bitwarden.data.platform.repository.AuthenticatorBridgeRepository +import com.x8bit.bitwarden.data.platform.repository.AuthenticatorBridgeRepositoryImpl import com.x8bit.bitwarden.data.platform.repository.DebugMenuRepository import com.x8bit.bitwarden.data.platform.repository.DebugMenuRepositoryImpl import com.x8bit.bitwarden.data.platform.repository.EnvironmentRepository @@ -42,14 +42,14 @@ object PlatformRepositoryModule { @Provides @Singleton - fun providesBridgeRepository( + fun providesAuthenticatorBridgeRepository( authRepository: AuthRepository, authDiskSource: AuthDiskSource, vaultRepository: VaultRepository, vaultDiskSource: VaultDiskSource, vaultSdkSource: VaultSdkSource, settingsDiskSource: SettingsDiskSource, - ): BridgeRepository = BridgeRepositoryImpl( + ): AuthenticatorBridgeRepository = AuthenticatorBridgeRepositoryImpl( authRepository = authRepository, authDiskSource = authDiskSource, vaultRepository = vaultRepository, diff --git a/app/src/main/java/com/x8bit/bitwarden/data/platform/service/AuthenticatorBridgeService.kt b/app/src/main/java/com/x8bit/bitwarden/data/platform/service/AuthenticatorBridgeService.kt new file mode 100644 index 000000000..903dce974 --- /dev/null +++ b/app/src/main/java/com/x8bit/bitwarden/data/platform/service/AuthenticatorBridgeService.kt @@ -0,0 +1,27 @@ +package com.x8bit.bitwarden.data.platform.service + +import android.app.Service +import android.content.Intent +import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage +import com.x8bit.bitwarden.data.platform.processor.AuthenticatorBridgeProcessor +import dagger.hilt.android.AndroidEntryPoint +import javax.inject.Inject + +/** + * Service exposed via a custom permission + */ +@AndroidEntryPoint +@OmitFromCoverage +class AuthenticatorBridgeService : Service() { + + @Inject + lateinit var authenticatorBridgeProcessor: AuthenticatorBridgeProcessor + + /** + * When binding this service, delegate logic to the [AuthenticatorBridgeProcessor]. + * + * Note that [AuthenticatorBridgeProcessor.binder] can return a null binder, which the OS + * will accept but never connect to, effectively making a null binder a noop binder. + */ + override fun onBind(intent: Intent) = authenticatorBridgeProcessor.binder +} diff --git a/app/src/main/java/com/x8bit/bitwarden/data/platform/service/BridgeService.kt b/app/src/main/java/com/x8bit/bitwarden/data/platform/service/BridgeService.kt deleted file mode 100644 index cac41216a..000000000 --- a/app/src/main/java/com/x8bit/bitwarden/data/platform/service/BridgeService.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.x8bit.bitwarden.data.platform.service - -import android.app.Service -import android.content.Intent -import com.x8bit.bitwarden.data.platform.processor.BridgeServiceProcessor -import com.bitwarden.bridge.IBridgeService -import dagger.hilt.android.AndroidEntryPoint -import javax.inject.Inject - -/** - * Service exposed via a custom permission - */ -@AndroidEntryPoint -class BridgeService : Service() { - - @Inject - lateinit var bridgeServiceProcessor: BridgeServiceProcessor - - /** - * When binding this service, logic to the [BridgeServiceProcessor], which implements - * [IBridgeService]. - * - * Note that [BridgeServiceProcessor.binder] can return a null binder, which the OS will accept - * but never connect to, effectively making a null binder a noop binder. - */ - override fun onBind(intent: Intent) = bridgeServiceProcessor.binder -} diff --git a/app/src/test/java/com/x8bit/bitwarden/data/auth/datasource/disk/AuthDiskSourceTest.kt b/app/src/test/java/com/x8bit/bitwarden/data/auth/datasource/disk/AuthDiskSourceTest.kt index 5a678ede4..58e680da6 100644 --- a/app/src/test/java/com/x8bit/bitwarden/data/auth/datasource/disk/AuthDiskSourceTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/data/auth/datasource/disk/AuthDiskSourceTest.kt @@ -2,7 +2,7 @@ package com.x8bit.bitwarden.data.auth.datasource.disk import androidx.core.content.edit import app.cash.turbine.test -import com.bitwarden.bridge.util.generateSecretKey +import com.bitwarden.authenticatorbridge.util.generateSecretKey import com.x8bit.bitwarden.data.auth.datasource.disk.model.AccountJson import com.x8bit.bitwarden.data.auth.datasource.disk.model.AccountTokensJson import com.x8bit.bitwarden.data.auth.datasource.disk.model.EnvironmentUrlDataJson diff --git a/app/src/test/java/com/x8bit/bitwarden/data/platform/processor/BridgeServiceProcessorTest.kt b/app/src/test/java/com/x8bit/bitwarden/data/platform/processor/AuthenticatorBridgeProcessorTest.kt similarity index 73% rename from app/src/test/java/com/x8bit/bitwarden/data/platform/processor/BridgeServiceProcessorTest.kt rename to app/src/test/java/com/x8bit/bitwarden/data/platform/processor/AuthenticatorBridgeProcessorTest.kt index 441887c57..483de21d6 100644 --- a/app/src/test/java/com/x8bit/bitwarden/data/platform/processor/BridgeServiceProcessorTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/data/platform/processor/AuthenticatorBridgeProcessorTest.kt @@ -2,19 +2,19 @@ package com.x8bit.bitwarden.data.platform.processor import android.os.Build import android.os.RemoteCallbackList -import com.bitwarden.bridge.IBridgeService -import com.bitwarden.bridge.IBridgeServiceCallback -import com.bitwarden.bridge.model.EncryptedSharedAccountData -import com.bitwarden.bridge.model.SharedAccountData -import com.bitwarden.bridge.util.NATIVE_BRIDGE_SDK_VERSION -import com.bitwarden.bridge.util.encrypt -import com.bitwarden.bridge.util.generateSecretKey -import com.bitwarden.bridge.util.toFingerprint -import com.bitwarden.bridge.util.toSymmetricEncryptionKeyData +import com.bitwarden.authenticatorbridge.IAuthenticatorBridgeService +import com.bitwarden.authenticatorbridge.IAuthenticatorBridgeServiceCallback +import com.bitwarden.authenticatorbridge.model.EncryptedSharedAccountData +import com.bitwarden.authenticatorbridge.model.SharedAccountData +import com.bitwarden.authenticatorbridge.util.AUTHENTICATOR_BRIDGE_SDK_VERSION +import com.bitwarden.authenticatorbridge.util.encrypt +import com.bitwarden.authenticatorbridge.util.generateSecretKey +import com.bitwarden.authenticatorbridge.util.toFingerprint +import com.bitwarden.authenticatorbridge.util.toSymmetricEncryptionKeyData import com.x8bit.bitwarden.data.platform.base.FakeDispatcherManager import com.x8bit.bitwarden.data.platform.manager.FeatureFlagManager import com.x8bit.bitwarden.data.platform.manager.model.FlagKey -import com.x8bit.bitwarden.data.platform.repository.BridgeRepository +import com.x8bit.bitwarden.data.platform.repository.AuthenticatorBridgeRepository import com.x8bit.bitwarden.data.platform.util.asSuccess import com.x8bit.bitwarden.data.platform.util.isBuildVersionBelow import io.mockk.coEvery @@ -34,17 +34,17 @@ import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test -class BridgeServiceProcessorTest { +class AuthenticatorBridgeProcessorTest { private val featureFlagManager = mockk() - private val bridgeRepository = mockk() + private val authenticatorBridgeRepository = mockk() - private lateinit var bridgeServiceProcessor: BridgeServiceProcessorImpl + private lateinit var bridgeServiceProcessor: AuthenticatorBridgeProcessorImpl @BeforeEach fun setup() { - bridgeServiceProcessor = BridgeServiceProcessorImpl( - bridgeRepository = bridgeRepository, + bridgeServiceProcessor = AuthenticatorBridgeProcessorImpl( + authenticatorBridgeRepository = authenticatorBridgeRepository, featureFlagManager = featureFlagManager, dispatcherManager = FakeDispatcherManager(), ) @@ -88,7 +88,7 @@ class BridgeServiceProcessorTest { fun `versionNumber should match version of compiled bridge sdk`() { val binder = getDefaultBinder() assertEquals( - NATIVE_BRIDGE_SDK_VERSION, + AUTHENTICATOR_BRIDGE_SDK_VERSION, binder.versionNumber, ) } @@ -98,7 +98,7 @@ class BridgeServiceProcessorTest { fun `checkSymmetricEncryptionKeyFingerprint should return false when given fingerprint is null`() { val binder = getDefaultBinder() // Set disk symmetric key to null so that it is technically equal to given null fingerprint: - every { bridgeRepository.authenticatorSyncSymmetricKey } returns null + every { authenticatorBridgeRepository.authenticatorSyncSymmetricKey } returns null // Binder should still return false in this case: assertFalse(binder.checkSymmetricEncryptionKeyFingerprint(null)) } @@ -107,7 +107,7 @@ class BridgeServiceProcessorTest { @Suppress("MaxLineLength") fun `checkSymmetricEncryptionKeyFingerprint should return false if fingerprint doesn't match`() { val binder = getDefaultBinder() - every { bridgeRepository.authenticatorSyncSymmetricKey } returns ByteArray(1) + every { authenticatorBridgeRepository.authenticatorSyncSymmetricKey } returns ByteArray(1) assertFalse(binder.checkSymmetricEncryptionKeyFingerprint(SYMMETRIC_KEY_FINGERPRINT)) } @@ -116,7 +116,7 @@ class BridgeServiceProcessorTest { fun `checkSymmetricEncryptionKeyFingerprint should return true if fingerprint does match`() { val binder = getDefaultBinder() every { - bridgeRepository.authenticatorSyncSymmetricKey + authenticatorBridgeRepository.authenticatorSyncSymmetricKey } returns SYMMETRIC_KEY.symmetricEncryptionKey.byteArray assertTrue(binder.checkSymmetricEncryptionKeyFingerprint(SYMMETRIC_KEY_FINGERPRINT)) } @@ -125,7 +125,7 @@ class BridgeServiceProcessorTest { @Suppress("MaxLineLength") fun `getSymmetricEncryptionKeyData should return null when there is no symmetric key stored on disk`() { val binder = getDefaultBinder() - every { bridgeRepository.authenticatorSyncSymmetricKey } returns null + every { authenticatorBridgeRepository.authenticatorSyncSymmetricKey } returns null assertNull(binder.symmetricEncryptionKeyData) } @@ -134,7 +134,7 @@ class BridgeServiceProcessorTest { fun `getSymmetricEncryptionKeyData should return the symmetric key stored on disk`() { val binder = getDefaultBinder() every { - bridgeRepository.authenticatorSyncSymmetricKey + authenticatorBridgeRepository.authenticatorSyncSymmetricKey } returns SYMMETRIC_KEY.symmetricEncryptionKey.byteArray assertEquals(SYMMETRIC_KEY, binder.symmetricEncryptionKeyData) } @@ -144,7 +144,7 @@ class BridgeServiceProcessorTest { private var lastAccountsSync: EncryptedSharedAccountData? = null - private val serviceCallback = object : IBridgeServiceCallback.Stub() { + private val serviceCallback = object : IAuthenticatorBridgeServiceCallback.Stub() { override fun onAccountsSync(data: EncryptedSharedAccountData?) { lastAccountsSync = data } @@ -155,15 +155,15 @@ class BridgeServiceProcessorTest { // Setup RemoteCallbackList to call back to serviceCallback: mockkConstructor(RemoteCallbackList::class) every { - anyConstructed>() + anyConstructed>() .register(serviceCallback) } returns true every { - anyConstructed>() + anyConstructed>() .beginBroadcast() } returns 1 every { - anyConstructed>() + anyConstructed>() .getBroadcastItem(0) } returns serviceCallback lastAccountsSync = null @@ -171,7 +171,7 @@ class BridgeServiceProcessorTest { @Test fun `syncAccounts when symmetricEncryptionKeyData is null should do nothing`() { - every { bridgeRepository.authenticatorSyncSymmetricKey } returns null + every { authenticatorBridgeRepository.authenticatorSyncSymmetricKey } returns null getDefaultBinder().syncAccounts() assertNull(lastAccountsSync) } @@ -181,25 +181,25 @@ class BridgeServiceProcessorTest { val sharedAccountData = mockk() val expected = mockk() every { - bridgeRepository.authenticatorSyncSymmetricKey + authenticatorBridgeRepository.authenticatorSyncSymmetricKey } returns SYMMETRIC_KEY.symmetricEncryptionKey.byteArray - coEvery { bridgeRepository.getSharedAccounts() } returns sharedAccountData + coEvery { authenticatorBridgeRepository.getSharedAccounts() } returns sharedAccountData mockkStatic(SharedAccountData::encrypt) every { sharedAccountData.encrypt(SYMMETRIC_KEY) } returns expected.asSuccess() getDefaultBinder().syncAccounts() assertEquals(expected, lastAccountsSync) - coVerify { bridgeRepository.getSharedAccounts() } + coVerify { authenticatorBridgeRepository.getSharedAccounts() } } } /** - * Helper function for accessing the default implementation of [IBridgeService.Stub]. This - * is particularly useful because the binder is nullable on [BridgeServiceProcessor] behind - * a feature flag. + * Helper function for accessing the default implementation of + * [IAuthenticatorBridgeService.Stub]. This is particularly useful because the binder + * is nullable on [AuthenticatorBridgeProcessor] behind a feature flag. */ - private fun getDefaultBinder(): IBridgeService.Stub { + private fun getDefaultBinder(): IAuthenticatorBridgeService.Stub { mockkStatic(::isBuildVersionBelow) every { isBuildVersionBelow(Build.VERSION_CODES.S) } returns false every { featureFlagManager.getFeatureFlag(FlagKey.AuthenticatorSync) } returns true diff --git a/app/src/test/java/com/x8bit/bitwarden/data/platform/repository/BridgeRepositoryTest.kt b/app/src/test/java/com/x8bit/bitwarden/data/platform/repository/AuthenticatorBridgeRepositoryTest.kt similarity index 94% rename from app/src/test/java/com/x8bit/bitwarden/data/platform/repository/BridgeRepositoryTest.kt rename to app/src/test/java/com/x8bit/bitwarden/data/platform/repository/AuthenticatorBridgeRepositoryTest.kt index 64964b50e..1d45f2113 100644 --- a/app/src/test/java/com/x8bit/bitwarden/data/platform/repository/BridgeRepositoryTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/data/platform/repository/AuthenticatorBridgeRepositoryTest.kt @@ -1,8 +1,8 @@ package com.x8bit.bitwarden.data.platform.repository -import com.bitwarden.bridge.model.SharedAccountData -import com.bitwarden.bridge.util.generateSecretKey -import com.bitwarden.bridge.util.toSymmetricEncryptionKeyData +import com.bitwarden.authenticatorbridge.model.SharedAccountData +import com.bitwarden.authenticatorbridge.util.generateSecretKey +import com.bitwarden.authenticatorbridge.util.toSymmetricEncryptionKeyData import com.bitwarden.vault.Cipher import com.bitwarden.vault.CipherView import com.x8bit.bitwarden.data.auth.datasource.disk.util.FakeAuthDiskSource @@ -36,7 +36,7 @@ import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import java.time.Instant -class BridgeRepositoryTest { +class AuthenticatorBridgeRepositoryTest { private val authRepository = mockk() private val vaultSdkSource = mockk() @@ -45,7 +45,7 @@ class BridgeRepositoryTest { private val fakeAuthDiskSource = FakeAuthDiskSource() private val fakeSettingsDiskSource = FakeSettingsDiskSource() - private val bridgeRepository = BridgeRepositoryImpl( + private val authenticatorBridgeRepository = AuthenticatorBridgeRepositoryImpl( authRepository = authRepository, authDiskSource = fakeAuthDiskSource, vaultRepository = vaultRepository, @@ -129,7 +129,7 @@ class BridgeRepositoryTest { @Suppress("MaxLineLength") fun `syncAccounts with user 1 vault unlocked and all data present should send expected shared accounts data`() = runTest { - val sharedAccounts = bridgeRepository.getSharedAccounts() + val sharedAccounts = authenticatorBridgeRepository.getSharedAccounts() assertEquals( BOTH_ACCOUNT_SUCCESS, sharedAccounts, @@ -155,7 +155,7 @@ class BridgeRepositoryTest { fun `syncAccounts when userStateFlow is null should return an empty list`() = runTest { every { authRepository.userStateFlow } returns MutableStateFlow(null) - val sharedData = bridgeRepository.getSharedAccounts() + val sharedData = authenticatorBridgeRepository.getSharedAccounts() assertTrue(sharedData.accounts.isEmpty()) verify { authRepository.userStateFlow } @@ -172,7 +172,7 @@ class BridgeRepositoryTest { assertEquals( SharedAccountData(listOf(USER_2_SHARED_ACCOUNT)), - bridgeRepository.getSharedAccounts(), + authenticatorBridgeRepository.getSharedAccounts(), ) verify { authRepository.userStateFlow } @@ -199,7 +199,7 @@ class BridgeRepositoryTest { } returns VaultUnlockResult.Success every { vaultRepository.lockVault(USER_1_ID) } returns Unit - val sharedAccounts = bridgeRepository.getSharedAccounts() + val sharedAccounts = authenticatorBridgeRepository.getSharedAccounts() assertEquals( BOTH_ACCOUNT_SUCCESS, sharedAccounts, @@ -232,7 +232,7 @@ class BridgeRepositoryTest { @Test fun `syncAccounts when getLastSyncTime is null should omit account from list`() = runTest { fakeSettingsDiskSource.storeLastSyncTime(USER_1_ID, null) - val sharedAccounts = bridgeRepository.getSharedAccounts() + val sharedAccounts = authenticatorBridgeRepository.getSharedAccounts() assertEquals(SharedAccountData(listOf(USER_2_SHARED_ACCOUNT)), sharedAccounts) verify { vaultRepository.vaultUnlockDataStateFlow } verify { vaultDiskSource.getCiphers(USER_1_ID) } @@ -261,7 +261,7 @@ class BridgeRepositoryTest { vaultRepository.unlockVaultWithDecryptedUserKey(USER_1_ID, USER_1_UNLOCK_KEY) } returns VaultUnlockResult.InvalidStateError - val sharedAccounts = bridgeRepository.getSharedAccounts() + val sharedAccounts = authenticatorBridgeRepository.getSharedAccounts() assertEquals(SharedAccountData(listOf(USER_2_SHARED_ACCOUNT)), sharedAccounts) assertNull(fakeAuthDiskSource.getAuthenticatorSyncUnlockKey(USER_1_ID)) verify { vaultRepository.vaultUnlockDataStateFlow } @@ -298,7 +298,7 @@ class BridgeRepositoryTest { ) every { vaultRepository.vaultUnlockDataStateFlow } returns vaultUnlockStateFlow val deferred = async { - val sharedAccounts = bridgeRepository.getSharedAccounts() + val sharedAccounts = authenticatorBridgeRepository.getSharedAccounts() assertEquals(BOTH_ACCOUNT_SUCCESS, sharedAccounts) } @@ -336,12 +336,12 @@ class BridgeRepositoryTest { @Test fun `authenticatorSyncSymmetricKey should read from authDiskSource`() { fakeAuthDiskSource.authenticatorSyncSymmetricKey = null - assertNull(bridgeRepository.authenticatorSyncSymmetricKey) + assertNull(authenticatorBridgeRepository.authenticatorSyncSymmetricKey) val syncKey = generateSecretKey().getOrThrow().encoded fakeAuthDiskSource.authenticatorSyncSymmetricKey = syncKey - assertEquals(syncKey, bridgeRepository.authenticatorSyncSymmetricKey) + assertEquals(syncKey, authenticatorBridgeRepository.authenticatorSyncSymmetricKey) } } diff --git a/app/src/test/java/com/x8bit/bitwarden/data/platform/repository/SettingsRepositoryTest.kt b/app/src/test/java/com/x8bit/bitwarden/data/platform/repository/SettingsRepositoryTest.kt index c3a23ac1a..52c5bf030 100644 --- a/app/src/test/java/com/x8bit/bitwarden/data/platform/repository/SettingsRepositoryTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/data/platform/repository/SettingsRepositoryTest.kt @@ -2,7 +2,7 @@ package com.x8bit.bitwarden.data.platform.repository import android.view.autofill.AutofillManager import app.cash.turbine.test -import com.bitwarden.bridge.util.generateSecretKey +import com.bitwarden.authenticatorbridge.util.generateSecretKey import com.bitwarden.core.DerivePinKeyResponse import com.x8bit.bitwarden.data.auth.datasource.disk.model.AccountJson import com.x8bit.bitwarden.data.auth.datasource.disk.model.EnvironmentUrlDataJson diff --git a/bridge/.gitignore b/authenticatorbridge/.gitignore similarity index 100% rename from bridge/.gitignore rename to authenticatorbridge/.gitignore diff --git a/bridge/CHANGELOG.md b/authenticatorbridge/CHANGELOG.md similarity index 100% rename from bridge/CHANGELOG.md rename to authenticatorbridge/CHANGELOG.md diff --git a/bridge/CHANGELOG_FORMAT.MD b/authenticatorbridge/CHANGELOG_FORMAT.MD similarity index 100% rename from bridge/CHANGELOG_FORMAT.MD rename to authenticatorbridge/CHANGELOG_FORMAT.MD diff --git a/bridge/README.md b/authenticatorbridge/README.md similarity index 95% rename from bridge/README.md rename to authenticatorbridge/README.md index 925ddb2cb..36515d7f2 100644 --- a/bridge/README.md +++ b/authenticatorbridge/README.md @@ -1,4 +1,4 @@ -# Bitwarden Native Bridge SDK +# Authenticator Bridge SDK ## Contents @@ -22,7 +22,7 @@ To build an AAR for inclusion in consumer applications, run: ```sh - $ ./gradlew bridge:assembleRelease + $ ./gradlew authenticatorbridge:assembleRelease ``` ## Versioning diff --git a/bridge/build.gradle.kts b/authenticatorbridge/build.gradle.kts similarity index 92% rename from bridge/build.gradle.kts rename to authenticatorbridge/build.gradle.kts index f28de39af..c878a6b75 100644 --- a/bridge/build.gradle.kts +++ b/authenticatorbridge/build.gradle.kts @@ -11,7 +11,7 @@ plugins { } android { - namespace = "com.bitwarden.bridge" + namespace = "com.bitwarden.authenticatorbridge" compileSdk = libs.versions.compileSdk.get().toInt() defaultConfig { @@ -46,7 +46,7 @@ android { outputs .map { it as com.android.build.gradle.internal.api.BaseVariantOutputImpl } .forEach { output -> - val outputFileName = "bridge-${version}-SNAPSHOT-${variant.baseName}.aar" + val outputFileName = "authenticatorbridge-${version}-SNAPSHOT-${variant.baseName}.aar" output.outputFileName = outputFileName } } diff --git a/bridge/consumer-rules.pro b/authenticatorbridge/consumer-rules.pro similarity index 100% rename from bridge/consumer-rules.pro rename to authenticatorbridge/consumer-rules.pro diff --git a/bridge/proguard-rules.pro b/authenticatorbridge/proguard-rules.pro similarity index 100% rename from bridge/proguard-rules.pro rename to authenticatorbridge/proguard-rules.pro diff --git a/bridge/src/main/AndroidManifest.xml b/authenticatorbridge/src/main/AndroidManifest.xml similarity index 100% rename from bridge/src/main/AndroidManifest.xml rename to authenticatorbridge/src/main/AndroidManifest.xml diff --git a/bridge/src/main/aidl/com/bitwarden/bridge/IBridgeService.aidl b/authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/IAuthenticatorBridgeService.aidl similarity index 65% rename from bridge/src/main/aidl/com/bitwarden/bridge/IBridgeService.aidl rename to authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/IAuthenticatorBridgeService.aidl index a954da747..431cb9937 100644 --- a/bridge/src/main/aidl/com/bitwarden/bridge/IBridgeService.aidl +++ b/authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/IAuthenticatorBridgeService.aidl @@ -1,20 +1,20 @@ -package com.bitwarden.bridge; +package com.bitwarden.authenticatorbridge; -import com.bitwarden.bridge.model.EncryptedAddTotpLoginItemData; -import com.bitwarden.bridge.model.SymmetricEncryptionKeyData; -import com.bitwarden.bridge.model.SymmetricEncryptionKeyFingerprintData; -import com.bitwarden.bridge.IBridgeServiceCallback; +import com.bitwarden.authenticatorbridge.model.EncryptedAddTotpLoginItemData; +import com.bitwarden.authenticatorbridge.model.SymmetricEncryptionKeyData; +import com.bitwarden.authenticatorbridge.model.SymmetricEncryptionKeyFingerprintData; +import com.bitwarden.authenticatorbridge.IAuthenticatorBridgeServiceCallback; -interface IBridgeService { +interface IAuthenticatorBridgeService { // ============== // Configuration // ============== - // Returns the version number string of the Bridge SDK. This is useful so that callers - // can compare the version of their Bridge SDK with this value and ensure that the two are - // compatible. + // Returns the version number string of the Authenticator Bridge SDK. This is useful so that + // callers can compare the version of their Authenticator Bridge SDK with this value and + // ensure that the two are compatible. // - // For more info about versioning the Bridge SDK, see the Bridge SDK README. + // For more info about versioning the Authenticator Bridge SDK, see the README. String getVersionNumber(); // Returns true when the given symmetric fingerprint data matches that contained by the SDK. @@ -32,10 +32,10 @@ interface IBridgeService { // ============== // Register the given callback to receive updates after syncAccounts is called. - void registerBridgeServiceCallback(IBridgeServiceCallback callback); + void registerBridgeServiceCallback(IAuthenticatorBridgeServiceCallback callback); // Unregister the given callback from receiving updates. - void unregisterBridgeServiceCallback(IBridgeServiceCallback callback); + void unregisterBridgeServiceCallback(IAuthenticatorBridgeServiceCallback callback); // ============== // Data Syncing diff --git a/authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/IAuthenticatorBridgeServiceCallback.aidl b/authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/IAuthenticatorBridgeServiceCallback.aidl new file mode 100644 index 000000000..2d1b7ff29 --- /dev/null +++ b/authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/IAuthenticatorBridgeServiceCallback.aidl @@ -0,0 +1,10 @@ +package com.bitwarden.authenticatorbridge; + +import com.bitwarden.authenticatorbridge.model.EncryptedSharedAccountData; + +interface IAuthenticatorBridgeServiceCallback { + + // This function will be called when there is updated shared account data. + void onAccountsSync(in EncryptedSharedAccountData data); + +} diff --git a/authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/model/EncryptedAddTotpLoginItemData.aidl b/authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/model/EncryptedAddTotpLoginItemData.aidl new file mode 100644 index 000000000..8f8f03f36 --- /dev/null +++ b/authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/model/EncryptedAddTotpLoginItemData.aidl @@ -0,0 +1,3 @@ +package com.bitwarden.authenticatorbridge.model; + +parcelable EncryptedAddTotpLoginItemData; diff --git a/authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/model/EncryptedSharedAccountData.aidl b/authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/model/EncryptedSharedAccountData.aidl new file mode 100644 index 000000000..17fc89038 --- /dev/null +++ b/authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/model/EncryptedSharedAccountData.aidl @@ -0,0 +1,3 @@ +package com.bitwarden.authenticatorbridge.model; + +parcelable EncryptedSharedAccountData; diff --git a/authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/model/SymmetricEncryptionKeyData.aidl b/authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/model/SymmetricEncryptionKeyData.aidl new file mode 100644 index 000000000..eec46b1ac --- /dev/null +++ b/authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/model/SymmetricEncryptionKeyData.aidl @@ -0,0 +1,3 @@ +package com.bitwarden.authenticatorbridge.model; + +parcelable SymmetricEncryptionKeyData; diff --git a/bridge/src/main/aidl/com/bitwarden/bridge/model/SymmetricEncryptionKeyFingerprintData.aidl b/authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/model/SymmetricEncryptionKeyFingerprintData.aidl similarity index 51% rename from bridge/src/main/aidl/com/bitwarden/bridge/model/SymmetricEncryptionKeyFingerprintData.aidl rename to authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/model/SymmetricEncryptionKeyFingerprintData.aidl index c362df5e7..3b639f378 100644 --- a/bridge/src/main/aidl/com/bitwarden/bridge/model/SymmetricEncryptionKeyFingerprintData.aidl +++ b/authenticatorbridge/src/main/aidl/com/bitwarden/authenticatorbridge/model/SymmetricEncryptionKeyFingerprintData.aidl @@ -1,3 +1,3 @@ -package com.bitwarden.bridge.model; +package com.bitwarden.authenticatorbridge.model; parcelable SymmetricEncryptionKeyFingerprintData; diff --git a/bridge/src/main/java/com/bitwarden/bridge/model/AddTotpLoginItemData.kt b/authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/AddTotpLoginItemData.kt similarity index 67% rename from bridge/src/main/java/com/bitwarden/bridge/model/AddTotpLoginItemData.kt rename to authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/AddTotpLoginItemData.kt index 7a576d863..e97977b3b 100644 --- a/bridge/src/main/java/com/bitwarden/bridge/model/AddTotpLoginItemData.kt +++ b/authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/AddTotpLoginItemData.kt @@ -1,7 +1,4 @@ -package com.bitwarden.bridge.model - -import android.os.Parcelable -import kotlinx.parcelize.Parcelize +package com.bitwarden.authenticatorbridge.model /** * Domain level model for a TOTP item to be added to the Bitwarden app. diff --git a/bridge/src/main/java/com/bitwarden/bridge/model/AddTotpLoginItemDataJson.kt b/authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/AddTotpLoginItemDataJson.kt similarity index 89% rename from bridge/src/main/java/com/bitwarden/bridge/model/AddTotpLoginItemDataJson.kt rename to authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/AddTotpLoginItemDataJson.kt index 006a0c5d1..cbf048180 100644 --- a/bridge/src/main/java/com/bitwarden/bridge/model/AddTotpLoginItemDataJson.kt +++ b/authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/AddTotpLoginItemDataJson.kt @@ -1,4 +1,4 @@ -package com.bitwarden.bridge.model +package com.bitwarden.authenticatorbridge.model import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable diff --git a/bridge/src/main/java/com/bitwarden/bridge/model/ByteArrayContainer.kt b/authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/ByteArrayContainer.kt similarity index 94% rename from bridge/src/main/java/com/bitwarden/bridge/model/ByteArrayContainer.kt rename to authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/ByteArrayContainer.kt index 01eb71a05..7385be19a 100644 --- a/bridge/src/main/java/com/bitwarden/bridge/model/ByteArrayContainer.kt +++ b/authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/ByteArrayContainer.kt @@ -1,4 +1,4 @@ -package com.bitwarden.bridge.model +package com.bitwarden.authenticatorbridge.model import android.os.Parcelable import kotlinx.parcelize.Parcelize diff --git a/bridge/src/main/java/com/bitwarden/bridge/model/EncryptedAddTotpLoginItemData.kt b/authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/EncryptedAddTotpLoginItemData.kt similarity index 91% rename from bridge/src/main/java/com/bitwarden/bridge/model/EncryptedAddTotpLoginItemData.kt rename to authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/EncryptedAddTotpLoginItemData.kt index 3b7ac83be..4e5f6f3d9 100644 --- a/bridge/src/main/java/com/bitwarden/bridge/model/EncryptedAddTotpLoginItemData.kt +++ b/authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/EncryptedAddTotpLoginItemData.kt @@ -1,4 +1,4 @@ -package com.bitwarden.bridge.model +package com.bitwarden.authenticatorbridge.model import android.os.Parcelable import kotlinx.parcelize.Parcelize diff --git a/bridge/src/main/java/com/bitwarden/bridge/model/EncryptedSharedAccountData.kt b/authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/EncryptedSharedAccountData.kt similarity index 91% rename from bridge/src/main/java/com/bitwarden/bridge/model/EncryptedSharedAccountData.kt rename to authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/EncryptedSharedAccountData.kt index 0b89f4d42..89feadb3e 100644 --- a/bridge/src/main/java/com/bitwarden/bridge/model/EncryptedSharedAccountData.kt +++ b/authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/EncryptedSharedAccountData.kt @@ -1,4 +1,4 @@ -package com.bitwarden.bridge.model +package com.bitwarden.authenticatorbridge.model import android.os.Parcelable import kotlinx.parcelize.Parcelize diff --git a/bridge/src/main/java/com/bitwarden/bridge/model/SharedAccountData.kt b/authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/SharedAccountData.kt similarity index 94% rename from bridge/src/main/java/com/bitwarden/bridge/model/SharedAccountData.kt rename to authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/SharedAccountData.kt index b7bb4ac64..0c10150a3 100644 --- a/bridge/src/main/java/com/bitwarden/bridge/model/SharedAccountData.kt +++ b/authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/SharedAccountData.kt @@ -1,4 +1,4 @@ -package com.bitwarden.bridge.model +package com.bitwarden.authenticatorbridge.model import java.time.Instant diff --git a/bridge/src/main/java/com/bitwarden/bridge/model/SharedAccountDataJson.kt b/authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/SharedAccountDataJson.kt similarity index 96% rename from bridge/src/main/java/com/bitwarden/bridge/model/SharedAccountDataJson.kt rename to authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/SharedAccountDataJson.kt index a85601c33..3aba5aa5b 100644 --- a/bridge/src/main/java/com/bitwarden/bridge/model/SharedAccountDataJson.kt +++ b/authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/SharedAccountDataJson.kt @@ -1,4 +1,4 @@ -package com.bitwarden.bridge.model +package com.bitwarden.authenticatorbridge.model import kotlinx.serialization.Contextual import kotlinx.serialization.SerialName diff --git a/bridge/src/main/java/com/bitwarden/bridge/model/SymmetricEncryptionKeyData.kt b/authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/SymmetricEncryptionKeyData.kt similarity index 86% rename from bridge/src/main/java/com/bitwarden/bridge/model/SymmetricEncryptionKeyData.kt rename to authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/SymmetricEncryptionKeyData.kt index 6f40dae7a..c42bad377 100644 --- a/bridge/src/main/java/com/bitwarden/bridge/model/SymmetricEncryptionKeyData.kt +++ b/authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/SymmetricEncryptionKeyData.kt @@ -1,4 +1,4 @@ -package com.bitwarden.bridge.model +package com.bitwarden.authenticatorbridge.model import android.os.Parcelable import kotlinx.parcelize.Parcelize diff --git a/bridge/src/main/java/com/bitwarden/bridge/model/SymmetricEncryptionKeyFingerprintData.kt b/authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/SymmetricEncryptionKeyFingerprintData.kt similarity index 90% rename from bridge/src/main/java/com/bitwarden/bridge/model/SymmetricEncryptionKeyFingerprintData.kt rename to authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/SymmetricEncryptionKeyFingerprintData.kt index 926d78262..898be8fb3 100644 --- a/bridge/src/main/java/com/bitwarden/bridge/model/SymmetricEncryptionKeyFingerprintData.kt +++ b/authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/model/SymmetricEncryptionKeyFingerprintData.kt @@ -1,4 +1,4 @@ -package com.bitwarden.bridge.model +package com.bitwarden.authenticatorbridge.model import android.os.Parcelable import kotlinx.parcelize.Parcelize diff --git a/bridge/src/main/java/com/bitwarden/bridge/util/Constants.kt b/authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/util/Constants.kt similarity index 87% rename from bridge/src/main/java/com/bitwarden/bridge/util/Constants.kt rename to authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/util/Constants.kt index bb2af5628..b42dab69b 100644 --- a/bridge/src/main/java/com/bitwarden/bridge/util/Constants.kt +++ b/authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/util/Constants.kt @@ -1,6 +1,6 @@ -package com.bitwarden.bridge.util +package com.bitwarden.authenticatorbridge.util -import com.bitwarden.bridge.BuildConfig +import com.bitwarden.authenticatorbridge.BuildConfig import kotlinx.serialization.KSerializer import kotlinx.serialization.descriptors.PrimitiveKind import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor @@ -13,12 +13,12 @@ import kotlinx.serialization.modules.contextual import java.time.Instant /** - * Version of the native bridge sdk. + * Version of the Authenticator Bridge SDK. */ -const val NATIVE_BRIDGE_SDK_VERSION = BuildConfig.VERSION +const val AUTHENTICATOR_BRIDGE_SDK_VERSION = BuildConfig.VERSION /** - * Common instance of [Json] that should be used throughout the app. + * Common instance of [Json] that should be used throughout the SDK. */ internal val JSON = Json { // If there are keys returned by the server not modeled by a serializable class, diff --git a/bridge/src/main/java/com/bitwarden/bridge/util/EncryptionUtils.kt b/authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/util/EncryptionUtils.kt similarity index 86% rename from bridge/src/main/java/com/bitwarden/bridge/util/EncryptionUtils.kt rename to authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/util/EncryptionUtils.kt index 4110b0c8a..ce8a84281 100644 --- a/bridge/src/main/java/com/bitwarden/bridge/util/EncryptionUtils.kt +++ b/authenticatorbridge/src/main/java/com/bitwarden/authenticatorbridge/util/EncryptionUtils.kt @@ -1,16 +1,16 @@ -package com.bitwarden.bridge.util +package com.bitwarden.authenticatorbridge.util import android.security.keystore.KeyProperties -import com.bitwarden.bridge.IBridgeService -import com.bitwarden.bridge.model.AddTotpLoginItemData -import com.bitwarden.bridge.model.AddTotpLoginItemDataJson -import com.bitwarden.bridge.model.EncryptedAddTotpLoginItemData -import com.bitwarden.bridge.model.EncryptedSharedAccountData -import com.bitwarden.bridge.model.SharedAccountData -import com.bitwarden.bridge.model.SharedAccountDataJson -import com.bitwarden.bridge.model.SymmetricEncryptionKeyData -import com.bitwarden.bridge.model.SymmetricEncryptionKeyFingerprintData -import com.bitwarden.bridge.model.toByteArrayContainer +import com.bitwarden.authenticatorbridge.IAuthenticatorBridgeService +import com.bitwarden.authenticatorbridge.model.AddTotpLoginItemData +import com.bitwarden.authenticatorbridge.model.AddTotpLoginItemDataJson +import com.bitwarden.authenticatorbridge.model.EncryptedAddTotpLoginItemData +import com.bitwarden.authenticatorbridge.model.EncryptedSharedAccountData +import com.bitwarden.authenticatorbridge.model.SharedAccountData +import com.bitwarden.authenticatorbridge.model.SharedAccountDataJson +import com.bitwarden.authenticatorbridge.model.SymmetricEncryptionKeyData +import com.bitwarden.authenticatorbridge.model.SymmetricEncryptionKeyFingerprintData +import com.bitwarden.authenticatorbridge.model.toByteArrayContainer import kotlinx.serialization.encodeToString import java.security.MessageDigest import javax.crypto.Cipher @@ -22,7 +22,8 @@ import javax.crypto.spec.SecretKeySpec /** * Generate a symmetric [SecretKey] that will used for encrypting IPC traffic. * - * This is intended to be used for implementing [IBridgeService.getSymmetricEncryptionKeyData]. + * This is intended to be used for implementing + * [IAuthenticatorBridgeService.getSymmetricEncryptionKeyData]. */ fun generateSecretKey(): Result = runCatching { val keygen = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES) @@ -34,7 +35,7 @@ fun generateSecretKey(): Result = runCatching { * Generate a fingerprint for the given symmetric key. * * This is intended to be used for implementing - * [IBridgeService.checkSymmetricEncryptionKeyFingerprint], which allows callers of the service + * [IAuthenticatorBridgeService.checkSymmetricEncryptionKeyFingerprint], which allows callers of the service * to verify that they have the correct symmetric key without actually having to send the key. */ fun SymmetricEncryptionKeyData.toFingerprint(): Result = @@ -48,7 +49,8 @@ fun SymmetricEncryptionKeyData.toFingerprint(): Result