Skip to content

[BITAU-152] Handle Vault Lock/Unlock with Sync #998

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 92 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from 85 commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
ce280a3
[BITAU-171] Rename Package to AuthenticatorBridgeKit
brant-livefront Sep 12, 2024
74212c6
Added Initial CoreData structure and tests
brant-livefront Sep 12, 2024
acf1c5e
Merge branch 'main' into brant/create-coredata-store
brant-livefront Sep 12, 2024
7838129
Merge branch 'main' into brant/create-coredata-store
brant-livefront Sep 13, 2024
61163d7
Updated tests to match the style guide, implemented additional tests
brant-livefront Sep 13, 2024
d0ad4c9
Remove cryptography serivce (for now). Clean up comments and other liโ€ฆ
brant-livefront Sep 13, 2024
cf4e610
Moved to using a more direct batvh insert. Cleaned up tests. Cleaned โ€ฆ
brant-livefront Sep 16, 2024
1bcf93a
Merge branch 'main' into brant/create-coredata-store
brant-livefront Sep 16, 2024
4a15366
]BITAU-122] [BITAU-133] Add encryption to/from shared the CoreData store
brant-livefront Sep 16, 2024
1dc0757
Added name to list of encrypted pieces of the data model
brant-livefront Sep 16, 2024
0113798
Merge branch 'main' into brant/create-coredata-store
brant-livefront Sep 16, 2024
603c70b
Merge branch 'brant/create-coredata-store' into brant/add-encryption-โ€ฆ
brant-livefront Sep 16, 2024
fd6e158
Merge branch 'main' into brant/create-coredata-store
brant-livefront Sep 17, 2024
f78ab0a
Address comments from PR review
brant-livefront Sep 17, 2024
3d1beda
Merged in latest from brant/create-coredata-store - reverted all chanโ€ฆ
brant-livefront Sep 17, 2024
f68fac0
First step of refactor - move convenience methods out to new service.โ€ฆ
brant-livefront Sep 17, 2024
15add85
Pull in reusable CoreData code from main project. Refactor to adopt Pโ€ฆ
brant-livefront Sep 17, 2024
18c014c
Reuse model name for sqlite reference as well
brant-livefront Sep 17, 2024
7ed13ae
Merge branch 'main' into brant/create-coredata-store
brant-livefront Sep 17, 2024
1c5d2b3
Merge branch 'main' into brant/create-coredata-store
brant-livefront Sep 17, 2024
cef0741
Merged in latest from brant/create-coredata-store fixed conflicts
brant-livefront Sep 17, 2024
3d0c1fb
Implement encryption in the new item service
brant-livefront Sep 17, 2024
af008bc
[BITAU-149] Add Setting to Turn On Authenticator Syncing for an Account
brant-livefront Sep 18, 2024
ee63c9d
[BITAU-149] Add Setting to Turn On Authenticator Syncing for an Account
brant-livefront Sep 18, 2024
3e5dd06
[BITAU-148] First pass at adding the sync service to the PM app
brant-livefront Sep 18, 2024
47a98d2
Added tests for all of the new Settings pieces
brant-livefront Sep 18, 2024
1fa2fbc
Merge branch 'brant/add-authenticator-sync-setting' into brant/add-pmโ€ฆ
brant-livefront Sep 18, 2024
f4fbc16
Checking in progress on tests and subscribing to sync setting updates
brant-livefront Sep 19, 2024
3e8508e
Merged in latest from main, fixed conflicts
brant-livefront Sep 19, 2024
7efb7f3
Merge in latest from main
brant-livefront Sep 19, 2024
3ede938
Implement encryption in the new item service
brant-livefront Sep 17, 2024
d83f2e2
Fix missing declaration
brant-livefront Sep 19, 2024
0c3167e
Cleaned up merge issues
brant-livefront Sep 19, 2024
6bca7ab
Added doc comment for new param
brant-livefront Sep 19, 2024
cb3fa10
Merge branch 'brant/add-encryption-to-coredata-store' into brant/add-โ€ฆ
brant-livefront Sep 19, 2024
12f399b
Merge branch 'brant/add-authenticator-sync-setting' into brant/add-pmโ€ฆ
brant-livefront Sep 19, 2024
605fc3b
Merge branch 'main' into brant/add-encryption-to-coredata-store
brant-livefront Sep 19, 2024
3ecc76a
Further tests and progress
brant-livefront Sep 19, 2024
f7ed8d7
Merge branch 'main' into brant/add-encryption-to-coredata-store
brant-livefront Sep 19, 2024
c165ba7
Added new AuthenticatorBridgeItemDataView to differentiate unencrypteโ€ฆ
brant-livefront Sep 20, 2024
6441c3e
Merge branch 'brant/add-encryption-to-coredata-store' into brant/add-โ€ฆ
brant-livefront Sep 20, 2024
aa5987e
Merge branch 'brant/add-authenticator-sync-setting' into brant/add-pmโ€ฆ
brant-livefront Sep 20, 2024
7122d7d
Fix typo in doc comment
brant-livefront Sep 20, 2024
48b9db6
Merge branch 'brant/add-encryption-to-coredata-store' into brant/add-โ€ฆ
brant-livefront Sep 20, 2024
40713f6
Merge branch 'brant/add-encryption-to-coredata-store' into brant/add-โ€ฆ
brant-livefront Sep 20, 2024
5236618
Merge branch 'brant/add-authenticator-sync-setting' into brant/add-pmโ€ฆ
brant-livefront Sep 20, 2024
e129b11
[BITAU-149] Add Setting to Turn On Authenticator Syncing for an Account
brant-livefront Sep 20, 2024
d815124
Updated doc comments
brant-livefront Sep 20, 2024
80f4c20
Merge in latest; fix conflicts
brant-livefront Sep 20, 2024
1462e77
Added tests for most of the cases in the sync service
brant-livefront Sep 23, 2024
19f971f
Updated tests for 100% coverage
brant-livefront Sep 23, 2024
4012c32
Doc comment cleanup
brant-livefront Sep 23, 2024
66a74d2
Update to use MainActor so that Application returns the correct valueโ€ฆ
brant-livefront Sep 23, 2024
b9f0646
Pulling application out of the SyncService entirely. Was too unreliabโ€ฆ
brant-livefront Sep 23, 2024
dd969c7
Merge branch 'main' into brant/add-authenticator-sync-setting
brant-livefront Sep 24, 2024
13162c0
Respond to PR feedback
brant-livefront Sep 24, 2024
011eebb
Merge branch 'main' into brant/add-authenticator-sync-setting
brant-livefront Sep 24, 2024
ed19b6c
Updated to use assert true with == operator
brant-livefront Sep 24, 2024
cc79977
Added cancel before creating new settings task
brant-livefront Sep 24, 2024
c27e92a
Added start() method to allow ServiceContainer a way to explicitly stโ€ฆ
brant-livefront Sep 24, 2024
aac820e
Add sharedItemsPublisher to BridgeItemService
brant-livefront Sep 25, 2024
8f2bdf8
Added more tests, fixed issue with Future extension not being presentโ€ฆ
brant-livefront Sep 25, 2024
329d4de
Merge branch 'main' into brant/add-authenticator-sync-setting
brant-livefront Sep 25, 2024
70cc033
Merge branch 'brant/add-authenticator-sync-setting' into brant/add-pmโ€ฆ
brant-livefront Sep 25, 2024
74c1de8
Reverted to XCTAssertEqual
brant-livefront Sep 25, 2024
b3bdf51
Merge branch 'brant/add-authenticator-sync-setting' into brant/add-pmโ€ฆ
brant-livefront Sep 25, 2024
75021cc
Changed to remove AsyncThrowingPublisher wrapper, which makes things โ€ฆ
brant-livefront Sep 26, 2024
e3df37a
Merge branch 'main' into brant/add-pm-sync-service
brant-livefront Sep 26, 2024
96c7cc5
Merge branch 'main' into brant/add-pm-sync-service
brant-livefront Sep 26, 2024
774def9
Added test coverage for new Cryptography method
brant-livefront Sep 26, 2024
e2e99ed
Incorporate suggestions from PR feedback
brant-livefront Sep 27, 2024
26b3952
Fixed typo
brant-livefront Sep 27, 2024
a099e89
Removed debug logs from code; fixed concurrnecy issue with tests
brant-livefront Sep 27, 2024
c3c7902
Merge branch 'main' into brant/add-pm-sync-service
brant-livefront Sep 30, 2024
eb567e1
Repsond to PR feedback
brant-livefront Oct 1, 2024
fad1b70
Merge branch 'main' into brant/add-pm-sync-service
brant-livefront Oct 1, 2024
d7a1fd3
Update to support new MainActor requirement for configService
brant-livefront Oct 1, 2024
d5ed7c4
Merge branch 'main' into brant/add-pm-sync-service
brant-livefront Oct 1, 2024
41f0b1a
Merge branch 'main' into brant/add-pm-sync-service
brant-livefront Oct 1, 2024
79cc61b
Added new approach to Vault unlocking and new tests.
brant-livefront Oct 2, 2024
7a6e7ee
Merge in latest from main, fix conflicts
brant-livefront Oct 2, 2024
162b1a4
Cleaned up tests, fixed bug that tests revealed
brant-livefront Oct 3, 2024
8b4efe8
Merge branch 'main' into brant/add-vault-key-handling
brant-livefront Oct 3, 2024
019ba96
Clean up doc comments
brant-livefront Oct 3, 2024
cb2fd64
Fixed test for feature flag off
brant-livefront Oct 3, 2024
f877aa3
Removed property references to the two long-running tasks, per PR sugโ€ฆ
brant-livefront Oct 3, 2024
c17da1d
Merge branch 'main' into brant/BITAU-152-handle-vault-lock-unlock
brant-livefront Oct 3, 2024
1a1fc5d
Merge branch 'main' into brant/BITAU-152-handle-vault-lock-unlock
brant-livefront Oct 4, 2024
5735a98
Respond to PR feedback - ensure Vault is unlocked when decrypting
brant-livefront Oct 7, 2024
3346c96
Merge branch 'main' into brant/BITAU-152-handle-vault-lock-unlock
brant-livefront Oct 7, 2024
de99ef8
Merge branch 'main' into brant/BITAU-152-handle-vault-lock-unlock
brant-livefront Oct 7, 2024
d15186c
Removed the unneeded optional
brant-livefront Oct 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ actor DefaultAuthenticatorSyncService: NSObject, AuthenticatorSyncService {
private var cipherPublisherTasks = [String: Task<Void, Error>?]()

/// The service used to manage syncing and updates to the user's ciphers.
private let cipherService: CipherService
private let cipherDataStore: CipherDataStore

/// The service that handles common client functionality such as encryption and decryption.
private let clientService: ClientService
Expand All @@ -55,6 +55,10 @@ actor DefaultAuthenticatorSyncService: NSObject, AuthenticatorSyncService {
/// a user opts-in to Authenticator sync.
private var syncSettingSubscriberTask: Task<Void, Error>?

/// a Task that subscribes to the vault lock publisher for accounts. This allows us to take action once
/// a user unlocks their vault..
private var vaultUnlockSubscriberTask: Task<Void, Error>?

/// The service used by the application to manage vault access.
private let vaultTimeoutService: VaultTimeoutService

Expand All @@ -64,7 +68,7 @@ actor DefaultAuthenticatorSyncService: NSObject, AuthenticatorSyncService {
///
/// - Parameters:
/// - authBridgeItemService: The service for managing sharing items to/from the Authenticator app.
/// - cipherService: The service used to manage syncing and updates to the user's ciphers.
/// - cipherDataStore: The service used to manage syncing and updates to the user's ciphers.
/// - clientService: The service that handles common client functionality such as encryption and decryption.
/// - configService: The service to get server-specified configuration.
/// - errorReporter: The service used by the application to report non-fatal errors.\ organizations.
Expand All @@ -76,7 +80,7 @@ actor DefaultAuthenticatorSyncService: NSObject, AuthenticatorSyncService {
///
init(
authBridgeItemService: AuthenticatorBridgeItemService,
cipherService: CipherService,
cipherDataStore: CipherDataStore,
clientService: ClientService,
configService: ConfigService,
errorReporter: ErrorReporter,
Expand All @@ -86,7 +90,7 @@ actor DefaultAuthenticatorSyncService: NSObject, AuthenticatorSyncService {
vaultTimeoutService: VaultTimeoutService
) {
self.authBridgeItemService = authBridgeItemService
self.cipherService = cipherService
self.cipherDataStore = cipherDataStore
self.clientService = clientService
self.configService = configService
self.errorReporter = errorReporter
Expand All @@ -102,9 +106,33 @@ actor DefaultAuthenticatorSyncService: NSObject, AuthenticatorSyncService {
public func start() async {
guard !started else { return }
started = true
if await configService.getFeatureFlag(FeatureFlag.enableAuthenticatorSync,
defaultValue: false) {
subscribeToAppState()

guard await configService.getFeatureFlag(FeatureFlag.enableAuthenticatorSync,
defaultValue: false) else {
return
}

syncSettingSubscriberTask = Task {
for await (userId, _) in await self.stateService.syncToAuthenticatorPublisher().values {
guard let userId else { continue }

do {
try await determineSyncForUserId(userId)
} catch {
errorReporter.log(error: error)
}
}
}
vaultUnlockSubscriberTask = Task {
for await vaultStatus in await self.vaultTimeoutService.vaultLockStatusPublisher().values {
guard let vaultStatus else { continue }

do {
try await determineSyncForUserId(vaultStatus.userId)
} catch {
errorReporter.log(error: error)
}
}
}
}

Expand Down Expand Up @@ -141,7 +169,7 @@ actor DefaultAuthenticatorSyncService: NSObject, AuthenticatorSyncService {
try await self.clientService.vault().ciphers().decrypt(cipher: cipher)
}
let account = try await stateService.getActiveAccount()
let username = account.profile.name ?? account.profile.email
let username = account.profile.email

return decryptedCiphers.map { cipher in
AuthenticatorBridgeItemDataView(
Expand All @@ -154,43 +182,24 @@ actor DefaultAuthenticatorSyncService: NSObject, AuthenticatorSyncService {
}
}

/// This function handles the initial syncing with the Authenticator app as well as listening for updates
/// when the user adds new items. This is called when the sync is turned on.
/// Determine if the given userId has sync turned on and an unlocked vault. This method serves as the
/// integration point of both the sync settings subscriber and the vault subscriber. When the user has sync turned
/// on and the vault unlocked, we can proceed with the sync.
///
/// - Parameter userId: The userId of the user who has turned on sync.
/// - Parameter userId: The userId of the user whose sync status is being determined.
///
private func handleSyncOnForUserId(_ userId: String) async {
guard !vaultTimeoutService.isLocked(userId: userId) else {
private func determineSyncForUserId(_ userId: String) async throws {
guard try await stateService.getSyncToAuthenticator(userId: userId),
!vaultTimeoutService.isLocked(userId: userId) else {
cipherPublisherTasks[userId]??.cancel()
cipherPublisherTasks[userId] = nil
return
}

do {
try await createAuthenticatorKeyIfNeeded()
} catch {
errorReporter.log(error: error)
}
try await createAuthenticatorKeyIfNeeded()
subscribeToCipherUpdates(userId: userId)
}

/// This function handles stopping sync and cleaning up all sync-related items when a user has turned sync Off.
///
/// - Parameter userId: The userId of the user who has turned off sync.
///
private func handleSyncOffForUserId(_ userId: String) {
cipherPublisherTasks[userId]??.cancel()
cipherPublisherTasks[userId] = nil
}

/// Subscribe to NotificationCenter updates about if the app is in the foreground vs. background.
///
private func subscribeToAppState() {
Task {
for await _ in notificationCenterService.willEnterForegroundPublisher() {
subscribeToSyncToAuthenticatorSetting()
}
}
}

/// Create a task for the given userId to listen for Cipher updates and sync to the Authenticator store.
///
/// - Parameter userId: The userId of the account to listen for.
Expand All @@ -200,7 +209,7 @@ actor DefaultAuthenticatorSyncService: NSObject, AuthenticatorSyncService {

cipherPublisherTasks[userId] = Task {
do {
for try await ciphers in try await self.cipherService.ciphersPublisher().values {
for try await ciphers in self.cipherDataStore.cipherPublisher(userId: userId).values {
try await writeCiphers(ciphers: ciphers, userId: userId)
}
} catch {
Expand All @@ -209,24 +218,6 @@ actor DefaultAuthenticatorSyncService: NSObject, AuthenticatorSyncService {
}
}

/// Subscribe to the Sync to Authenticator setting to handle when the user grants (or revokes)
/// permission to sync items to the Authenticator app.
///
private func subscribeToSyncToAuthenticatorSetting() {
syncSettingSubscriberTask?.cancel()
syncSettingSubscriberTask = Task {
for await (userId, shouldSync) in await self.stateService.syncToAuthenticatorPublisher().values {
guard let userId else { continue }

if shouldSync {
await handleSyncOnForUserId(userId)
} else {
handleSyncOffForUserId(userId)
}
}
}
}

/// Takes in a list of encrypted Ciphers, decrypts them, and writes ones with TOTP codes to the shared store.
///
/// - Parameters:
Expand Down
Loading
Loading