diff --git a/BitwardenShared/Core/Auth/Services/TestHelpers/MockClientPlatform.swift b/BitwardenShared/Core/Auth/Services/TestHelpers/MockClientPlatform.swift index 0481b8858..eda6a8ef4 100644 --- a/BitwardenShared/Core/Auth/Services/TestHelpers/MockClientPlatform.swift +++ b/BitwardenShared/Core/Auth/Services/TestHelpers/MockClientPlatform.swift @@ -5,6 +5,7 @@ import BitwardenSdk class MockClientPlatform: ClientPlatformProtocol { var fingerprintMaterialString: String? var fingerprintResult: Result = .success("a-fingerprint-phrase-string-placeholder") + var featureFlags: [String: Bool] = ["": false] var userFingerprintCalled = false func fingerprint(req: BitwardenSdk.FingerprintRequest) async throws -> String { @@ -12,8 +13,7 @@ class MockClientPlatform: ClientPlatformProtocol { } func loadFlags(flags: [String: Bool]) async throws { - // Nothing yet. - throw BitwardenTestError.example + featureFlags = flags } func userFingerprint(fingerprintMaterial: String) async throws -> String { diff --git a/BitwardenShared/Core/Platform/Utilities/FeatureFlagsConstants.swift b/BitwardenShared/Core/Platform/Utilities/FeatureFlagsConstants.swift new file mode 100644 index 000000000..e5f3b7bef --- /dev/null +++ b/BitwardenShared/Core/Platform/Utilities/FeatureFlagsConstants.swift @@ -0,0 +1,12 @@ +import Foundation + +// MARK: - FeatureFlagsConstants + +/// An enumeration of feature flags. +/// +enum FeatureFlagsConstants { + // MARK: Properties + + /// A flag that enables individual cipher encryption. + static let enableCipherKeyEncryption = "enableCipherKeyEncryption" +} diff --git a/BitwardenShared/UI/Platform/Application/AppProcessor.swift b/BitwardenShared/UI/Platform/Application/AppProcessor.swift index 726e6d4b8..9a2a6393c 100644 --- a/BitwardenShared/UI/Platform/Application/AppProcessor.swift +++ b/BitwardenShared/UI/Platform/Application/AppProcessor.swift @@ -86,9 +86,10 @@ public class AppProcessor { } } + await loadFlags() await services.migrationService.performMigrations() - await services.environmentService.loadURLsForActiveAccount() + services.application?.registerForRemoteNotifications() if let initialRoute { @@ -199,3 +200,17 @@ extension AppProcessor: SyncServiceDelegate { await coordinator?.handleEvent(.didLogout(userId: userId, userInitiated: false)) } } + +// MARK: - Feature flags + +extension AppProcessor { + /// Loads feature flags. + /// + func loadFlags() async { + do { + try await services.clientPlatform.loadFlags(flags: [FeatureFlagsConstants.enableCipherKeyEncryption: true]) + } catch { + services.errorReporter.log(error: error) + } + } +} diff --git a/BitwardenShared/UI/Platform/Application/AppProcessorTests.swift b/BitwardenShared/UI/Platform/Application/AppProcessorTests.swift index 49b5c6007..3187bb629 100644 --- a/BitwardenShared/UI/Platform/Application/AppProcessorTests.swift +++ b/BitwardenShared/UI/Platform/Application/AppProcessorTests.swift @@ -8,6 +8,7 @@ class AppProcessorTests: BitwardenTestCase { var appModule: MockAppModule! var authRepository: MockAuthRepository! + var clientPlatform: MockClientPlatform! var coordinator: MockCoordinator! var errorReporter: MockErrorReporter! var migrationService: MockMigrationService! @@ -28,6 +29,7 @@ class AppProcessorTests: BitwardenTestCase { router = MockRouter(routeForEvent: { _ in .landing }) appModule = MockAppModule() authRepository = MockAuthRepository() + clientPlatform = MockClientPlatform() coordinator = MockCoordinator() appModule.authRouter = router appModule.appCoordinator = coordinator @@ -44,6 +46,7 @@ class AppProcessorTests: BitwardenTestCase { appModule: appModule, services: ServiceContainer.withMocks( authRepository: authRepository, + clientService: MockClientService(clientPlatform: clientPlatform), errorReporter: errorReporter, migrationService: migrationService, notificationService: notificationService, @@ -114,6 +117,12 @@ class AppProcessorTests: BitwardenTestCase { XCTAssertIdentical(syncService.delegate, subject) } + /// `.loadFlags()` loads the feature flags. + func test_loadFlags() async { + await subject.loadFlags() + XCTAssertEqual(clientPlatform.featureFlags, ["enableCipherKeyEncryption": true]) + } + /// `messageReceived(_:notificationDismissed:notificationTapped)` passes the data to the notification service. func test_messageReceived() async { let message: [AnyHashable: Any] = ["knock knock": "who's there?"] diff --git a/project.yml b/project.yml index 72e05f333..85fc23eea 100644 --- a/project.yml +++ b/project.yml @@ -13,7 +13,7 @@ options: indentWidth: 4 tabWidth: 4 settings: - MARKETING_VERSION: 1.0.0 # Bump this for a new version update. + MARKETING_VERSION: 2024.03.0 # Bump this for a new version update. CURRENT_PROJECT_VERSION: 1 packages: BitwardenSdk: