From aa0e250cb786c28dab39dc4251f0fed48e2e1f92 Mon Sep 17 00:00:00 2001 From: Harry <109690906+harry-signal@users.noreply.github.com> Date: Thu, 5 Oct 2023 08:56:08 -0700 Subject: [PATCH] [Death to TSAccountManager, long live TSAccountManager][9] Migrate usages of old TSAccountManager to new --- Signal.xcodeproj/project.pbxproj | 28 ++- Signal/OrphanData/OWSOrphanDataCleaner.m | 3 +- Signal/OrphanData/OWSOrphanDataCleaner.swift | 2 +- .../RegistrationCoodinatorShims.swift | 136 ----------- .../RegistrationCoordinatorDependencies.swift | 8 +- .../RegistrationCoordinatorImpl.swift | 43 ++-- Signal/URLs/UrlOpener.swift | 8 +- Signal/src/AppDelegate+Lifecycle.swift | 15 +- Signal/src/AppDelegate.m | 11 +- Signal/src/AppDelegate.swift | 103 ++++---- Signal/src/Calls/CallService.swift | 8 +- .../Individual/IndividualCallService.swift | 12 +- .../Signaling/WebRTCCallMessageHandler.swift | 2 +- .../CallKit/CallKitCallManager.swift | 2 +- .../Group/GroupCallMemberSheet.swift | 6 +- .../Group/GroupCallMemberView.swift | 2 +- .../Group/GroupCallViewController.swift | 4 +- .../Upgrade Views/RemoteMegaphone.swift | 2 +- Signal/src/Launch/LaunchJobs.swift | 4 +- Signal/src/Models/AccountManager.swift | 63 +++-- .../AccountSettingsViewController.swift | 19 +- ...eteAccountConfirmationViewController.swift | 12 +- .../AppSettingsViewController.swift | 12 +- ...dgeGiftingConfirmationViewController.swift | 2 +- .../DonationSettingsViewController.swift | 11 +- .../InternalSettingsViewController.swift | 9 +- .../LinkDeviceViewController.swift | 2 +- ...dvancedPrivacySettingsViewController.swift | 2 +- ...eNumberPrivacySettingsViewController.swift | 29 ++- .../PrivacySettingsViewController.swift | 2 +- .../BadgeConfigurationViewController.swift | 2 +- ...ersationViewController+BodyTextItems.swift | 4 +- ...rsationViewController+MessageRequest.swift | 2 +- .../ConversationViewController+UI.swift | 3 +- .../ConversationViewModel.swift | 2 +- .../InteractionReactionState.swift | 2 +- .../DebugUI/DebugUIGroupsV2.swift | 2 +- .../DebugUI/DebugUIMessages.swift | 8 +- .../ViewControllers/DebugUI/DebugUIMisc.swift | 6 +- .../DebugUI/DebugUIProfile.swift | 5 +- .../DebugUI/DebugUIStress.swift | 2 +- .../Donations/BadgeDetailsSheet.swift | 2 +- .../Donations/BadgeExpirationSheet.swift | 2 +- .../DonateChoosePaymentMethodSheet.swift | 2 +- .../Donations/DonateViewController.swift | 6 +- .../ViewControllers/GroupInviteLinksUI.swift | 2 +- .../ChatListViewController+Reminders.swift | 5 +- .../Chat List/ChatListViewController.swift | 8 +- .../HomeView/Stories/MyStoryCell.swift | 2 +- .../StoryGroupReplyLoader.swift | 6 +- .../StoryPrivacySettingsViewController.swift | 2 +- .../Stories/StoriesViewController.swift | 2 +- .../MediaGallery/MediaGallery.swift | 2 +- .../NewGroupConfirmViewController.swift | 2 +- .../OWSPinSetupViewController.swift | 6 +- ...DeviceTransferProgressViewController.swift | 9 +- ...viceTransferQRScanningViewController.swift | 3 +- .../Payments/SendPaymentViewController.swift | 4 +- .../Provisioning/ProvisioningController.swift | 2 +- .../ConversationSettingsViewController.swift | 10 +- ...mberRequestsAndInvitesViewController.swift | 2 +- .../GroupViewHelper+MemberActionSheet.swift | 6 +- .../ThreadSettings/GroupViewHelper.swift | 2 +- Signal/src/environment/AppEnvironment.swift | 2 +- Signal/src/environment/SignalApp.swift | 2 +- .../DeviceTransferService+Manifest.swift | 6 +- ...ceTransferService+MultipeerDelegates.swift | 2 +- .../DeviceTransferService+Restore.swift | 8 +- .../DeviceTransferService+URL.swift | 3 +- .../DeviceTransferService.swift | 26 +- Signal/src/util/RegistrationUtils.swift | 23 +- Signal/test/AppDelegateTest.swift | 4 +- .../RegistrationCoordinatorTest.swift | 12 +- .../RegistrationCoordinatorTestShims.swift | 102 -------- .../test/contact/OWSContactsManagerTest.swift | 7 +- Signal/test/util/ContactStreamTest.swift | 7 +- .../util/FTS/GRDBFullTextSearcherTest.swift | 34 ++- Signal/test/util/GRDBFinderTest.swift | 11 +- Signal/test/util/UserProfileTest.swift | 7 +- .../Jobs/IncomingContactSyncJobQueue.swift | 2 +- .../Notifications/AppNotifications.swift | 6 +- .../UserNotificationsPresenter.swift | 6 +- .../Payments/PaymentsCurrenciesImpl.swift | 8 +- .../Payments/PaymentsHelperImpl.swift | 12 +- .../StorageServiceManagerImpl.swift | 20 +- .../StorageServiceProto+Sync.swift | 48 ++-- .../SubscriptionManagerImpl.swift | 2 +- SignalMessaging/contacts/OWSContactsManager.m | 2 +- .../contacts/OWSContactsManager.swift | 15 +- SignalMessaging/contacts/OWSSyncManager.m | 20 +- SignalMessaging/contacts/OWSSyncManager.swift | 18 +- SignalMessaging/environment/AppSetup.swift | 10 +- .../groups/GroupV2UpdatesImpl.swift | 8 +- .../groups/GroupsV2Impl+RestoreGroups.swift | 2 +- SignalMessaging/groups/GroupsV2Impl.swift | 20 +- .../groups/GroupsV2OutgoingChangesImpl.swift | 4 +- .../groups/GroupsV2ProfileKeyUpdater.swift | 20 +- SignalMessaging/profiles/OWSProfileManager.m | 22 +- .../profiles/OWSProfileManager.swift | 55 +++-- .../profiles/VersionedProfilesImpl.swift | 2 +- .../utils/Avatars/AvatarBuilder.swift | 6 +- SignalMessaging/utils/CallMessageRelay.swift | 2 +- SignalMessaging/utils/RefreshEvent.swift | 8 +- SignalMessaging/utils/ThreadUtil.swift | 4 +- .../ChangePhoneNumberPniManager+Shims.swift | 27 --- .../ChangePhoneNumberPniManager.swift | 8 +- .../LegacyChangePhoneNumber.swift | 14 +- .../Dependencies/DependenciesBridge.swift | 229 ++++++++++-------- .../ExperienceUpgradeManifest.swift | 10 +- .../KeyBackupServiceImpl.swift | 23 +- .../KeyBackupServiceShims.swift | 32 --- .../SVRLocalStorage.swift | 77 ++++-- .../Orchestrating/OrchestratingSVRImpl.swift | 11 +- .../SVR2/SecureValueRecovery2Impl.swift | 28 ++- .../src/Account/LearnMyOwnPniManager.swift | 48 +--- .../Account/LinkedDevicePniKeyManager.swift | 50 +--- .../src/Account/PniHelloWorldManager.swift | 45 +--- .../Account/PreKeys/GeneratePreKeyTask.swift | 10 +- .../PreKeys/PreKeyOperation+Shims.swift | 19 -- .../src/Account/PreKeys/PreKeyTasks.swift | 6 +- .../MockTSAccountManager.swift | 18 +- .../MockRegistrationStateChangeManager.swift | 26 +- .../RegistrationStateChangeManager.swift | 24 +- .../RegistrationStateChangeManagerImpl.swift | 41 +++- ...rationStateChangeManagerObjcTestUtil.swift | 24 ++ .../TSAccountManagerImpl.swift | 35 ++- .../TSAccountManagerObjcBridge.swift | 74 ++++++ .../TSAccountManagerProtocol.swift | 17 ++ .../TSRegistrationState.swift | 33 ++- SignalServiceKit/src/Contacts/Contact.m | 8 +- .../Discovery/ContactDiscoveryManager.swift | 2 +- .../Discovery/ContactDiscoveryTask.swift | 6 +- .../src/Contacts/SignalServiceAddress.swift | 2 +- .../Contacts/Threads/TSContactThread.swift | 4 +- .../src/Contacts/Threads/TSGroupThread.m | 2 +- .../src/Contacts/Threads/TSGroupThread.swift | 2 +- .../src/Contacts/Threads/TSThread+OWS.swift | 2 +- .../src/Devices/OWSRecordTranscriptJob.m | 2 +- .../src/Messages/BlockingManager.swift | 2 +- .../OWSSyncContactsMessage.swift | 2 +- .../src/Messages/EarlyMessageManager.swift | 6 +- .../IncomingPniChangeNumberProcessor.swift | 153 ++++++++++++ .../Interactions/TSInfoMessage+Swift.swift | 10 +- .../Messages/Interactions/TSOutgoingMessage.m | 5 +- .../Interactions/TSOutgoingMessage.swift | 6 +- .../Messages/Interactions/TSQuotedMessage.m | 2 +- .../src/Messages/MessageFetcherJob.swift | 4 +- .../src/Messages/MessageProcessor.swift | 6 +- .../src/Messages/MessageSender+Errors.swift | 2 +- .../Messages/MessageSender+SenderKey.swift | 4 +- .../src/Messages/MessageSender.swift | 23 +- .../src/Messages/OWSIdentityManager.swift | 139 +---------- .../src/Messages/OWSMessageDecrypter.swift | 9 +- .../src/Messages/OWSMessageManager.m | 13 +- .../src/Messages/OWSMessageManager.swift | 13 +- .../src/Messages/OWSReceiptManager.swift | 8 +- .../Reactions/OutgoingReactionMessage.swift | 4 +- .../Messages/Reactions/ReactionManager.swift | 6 +- ...ntHidingManager+SignalServiceAddress.swift | 14 +- .../src/Messages/RecipientHidingManager.swift | 8 +- .../Messages/Stickers/StickerManager.swift | 6 +- .../Stories/OutgoingStoryMessage.swift | 7 +- .../src/Messages/Stories/StoryFinder.swift | 2 +- .../src/Messages/Stories/StoryManager.swift | 2 +- .../src/Messages/Stories/StoryMessage.swift | 2 +- .../Messages/Stories/SystemStoryManager.swift | 16 +- .../src/Messages/UD/OWSUDManager.swift | 10 +- .../src/Network/API/RESTNetworkManager.swift | 6 +- .../AccountAttributes+Dependencies.swift | 10 +- .../AccountAttributesRequestFactory.swift | 2 +- .../AccountAttributesUpdaterImpl.swift | 8 +- .../Network/API/Requests/OWSRequestFactory.m | 6 +- .../src/Network/API/Requests/TSRequest.swift | 4 +- .../src/Network/OWSSignalService.swift | 12 +- .../src/Network/OWSSignalServiceMock.swift | 2 + .../Network/OWSSignalServiceProtocol.swift | 2 + .../Receiving/GroupsV2MessageProcessor.swift | 8 +- .../src/Network/SignalServiceClient.swift | 2 +- .../src/Network/WebSockets/OWSWebSocket.swift | 14 +- .../RemoteAttestation.swift | 2 +- SignalServiceKit/src/SSKEnvironment.swift | 2 +- .../src/Security/OWSFingerprintBuilder.swift | 6 +- .../OWSRecipientIdentity+Queries.swift | 2 +- .../Storage/AxolotlStore/SenderKeyStore.swift | 14 +- .../Storage/Database/GRDBSchemaMigrator.swift | 11 +- .../SDSDatabaseStorage.swift | 4 +- .../Snapshots/DatabaseChangeObserver.swift | 14 +- .../src/TestUtils/MockSSKEnvironment.swift | 4 +- .../src/TestUtils/TestProtocolRunner.swift | 4 +- SignalServiceKit/src/Util/FeatureFlags.swift | 4 +- SignalServiceKit/src/Util/OWS2FAManager.m | 12 +- SignalServiceKit/src/Util/OWS2FAManager.swift | 12 +- SignalServiceKit/src/Util/OWSUserProfile.m | 10 +- .../src/Util/Profiles/BulkProfileFetch.swift | 14 +- .../src/Util/Profiles/ProfileFetcherJob.swift | 4 +- .../src/Util/RemoteConfigManager.swift | 14 +- .../src/Util/ViewOnceMessages.swift | 2 +- .../src/groups/GroupManager.swift | 20 +- .../src/groups/GroupMembership.swift | 10 +- .../Account/LearnMyOwnPniManagerTest.swift | 64 +++-- .../LinkedDevicePniKeyManagerTest.swift | 71 +++--- .../Account/PniHelloWorldManagerTest.swift | 35 +-- .../Account/PreKeys/PreKeyTaskTestMocks.swift | 6 - .../Account/PreKeys/PreKeyTaskTests.swift | 8 +- .../Account/SignalAccountFinderTest.swift | 7 +- .../OutgoingCallEventSyncMessageTest.swift | 15 +- .../OutgoingGroupCallUpdateMessageTest.swift | 15 +- .../ChangePhoneNumberPniManagerTest.swift | 18 +- .../tests/Contacts/BlockingManagerTests.swift | 7 +- .../Contacts/OWSRecipientIdentityTest.swift | 11 +- .../tests/Contacts/SignalRecipientTest.swift | 7 +- .../tests/Contacts/TSContactThreadTest.swift | 7 +- .../Interactions/TSOutgoingMessageTest.swift | 23 +- .../Messages/MessageDecryptionTest.swift | 15 +- .../MessageProcessingIntegrationTest.swift | 13 +- .../tests/Messages/OWSUDManagerTest.swift | 13 +- .../Messages/TestProtocolRunnerTest.swift | 33 ++- .../KeyBackupServiceTestShims.swift | 22 -- .../KeyBackupServiceTests.swift | 9 +- .../SVR2/SVR2ConcurrencyTests.swift | 18 +- .../SVR2/SecureValueRecovery2Tests.swift | 16 +- .../Database/DatabaseRecoveryTest.swift | 13 +- .../tests/Storage/ModelReadCacheTest.swift | 7 +- .../Storage/OWSIdentityManagerTests.swift | 11 +- .../Storage/SDSDatabaseStorageTest.swift | 11 +- .../tests/Stories/StoryManagerTest.swift | 7 +- .../Stories/SystemStoryManagerTest.swift | 11 +- .../tests/Util/TSMessageStorageTests.m | 2 +- .../tests/Util/ViewOnceMessagesTest.swift | 11 +- .../ShareViewController.swift | 27 +-- .../DeleteSystemContactViewController.swift | 6 +- .../RecipientContextMenuHelper.swift | 12 +- SignalUI/Payments/PaymentsImpl.swift | 12 +- SignalUI/Payments/PaymentsProcessor.swift | 8 +- .../Payments/PaymentsReconciliation.swift | 8 +- SignalUI/Usernames/UsernameQuerier.swift | 10 +- SignalUI/Utils/FullTextSearcher.swift | 11 +- .../ConversationPicker.swift | 4 +- .../FindByPhoneNumberViewController.swift | 4 +- .../RecipientPickerViewController.swift | 6 +- .../FingerprintViewController.swift | 2 +- SignalUI/ViewModels/QuotedReplyModel.swift | 2 +- SignalUI/Views/ContactsViewHelper.m | 2 +- SignalUI/Views/ContactsViewHelper.swift | 2 +- 244 files changed, 1921 insertions(+), 1650 deletions(-) rename SignalServiceKit/SecureValueRecovery/{SVR2 => LocalStorage}/SVRLocalStorage.swift (53%) create mode 100644 SignalServiceKit/src/Account/TSAccountManager/RegistrationStateChangeManager/RegistrationStateChangeManagerObjcTestUtil.swift create mode 100644 SignalServiceKit/src/Account/TSAccountManager/TSAccountManagerObjcBridge.swift create mode 100644 SignalServiceKit/src/Messages/IncomingPniChangeNumberProcessor.swift diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 066e9267d0..9b62a71c4b 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -791,13 +791,15 @@ 662C44092A1567E4001F83E2 /* svr2.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = 662C44082A1567E4001F83E2 /* svr2.pb.swift */; }; 662C440B2A156DF7001F83E2 /* SecureValueRecovery2Impl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 662C440A2A156DF7001F83E2 /* SecureValueRecovery2Impl.swift */; }; 662C440F2A17DB8A001F83E2 /* OrchestratingSVRImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 662C440E2A17DB8A001F83E2 /* OrchestratingSVRImpl.swift */; }; - 662C44132A1835F4001F83E2 /* SVRLocalStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 662C44122A1835F4001F83E2 /* SVRLocalStorage.swift */; }; 662C44172A1D21D7001F83E2 /* SecureValueRecovery2Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 662C44152A1D2101001F83E2 /* SecureValueRecovery2Tests.swift */; }; 663BA3182A4B8595004B9A43 /* SpoilerRenderState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 663BA3172A4B8595004B9A43 /* SpoilerRenderState.swift */; }; 663BA31C2A4C9997004B9A43 /* safety-numbers.json in Resources */ = {isa = PBXBuildFile; fileRef = 663BA31B2A4C9997004B9A43 /* safety-numbers.json */; }; 663BA3202A4CF96B004B9A43 /* MessageBodyDisplayConfigurations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 663BA31F2A4CF96B004B9A43 /* MessageBodyDisplayConfigurations.swift */; }; 663D6A7C292319BC00CABC49 /* ConversationPickerFailedRecipientsSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 663D6A7B292319BC00CABC49 /* ConversationPickerFailedRecipientsSheet.swift */; }; 6640639E294D20A900997E0B /* OutgoingCallEventSyncMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6640639D294D20A900997E0B /* OutgoingCallEventSyncMessage.swift */; }; + 6640DD5E2ACCCDC000CE9A8C /* RegistrationStateChangeManagerObjcTestUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6640DD5D2ACCCDC000CE9A8C /* RegistrationStateChangeManagerObjcTestUtil.swift */; }; + 6640DD602ACDBEC500CE9A8C /* IncomingPniChangeNumberProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6640DD5F2ACDBEC500CE9A8C /* IncomingPniChangeNumberProcessor.swift */; }; + 6640DD632ACDD5DE00CE9A8C /* SVRLocalStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6640DD622ACDD5DE00CE9A8C /* SVRLocalStorage.swift */; }; 664160D029A6D60A00F5BA85 /* ChatServiceAuth.swift in Sources */ = {isa = PBXBuildFile; fileRef = 664160CF29A6D60A00F5BA85 /* ChatServiceAuth.swift */; }; 6642A8702A8D7B4B00E591C2 /* OWSPaymentActivationRequestFinishedMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 6642A86F2A8D7B3400E591C2 /* OWSPaymentActivationRequestFinishedMessage.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6642A8722A8D7C5700E591C2 /* OWSPaymentActivationRequestFinishedMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 6642A8712A8D7C5700E591C2 /* OWSPaymentActivationRequestFinishedMessage.m */; }; @@ -820,6 +822,7 @@ 6646573F2AC3B9190099DE1C /* MockRegistrationStateChangeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6646573E2AC3B9190099DE1C /* MockRegistrationStateChangeManager.swift */; }; 664657412AC4FB720099DE1C /* NotificationsProtocolSwift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 664657402AC4FB720099DE1C /* NotificationsProtocolSwift.swift */; }; 664657452ACB34AA0099DE1C /* TSAccountManagerImpl+Shims.swift in Sources */ = {isa = PBXBuildFile; fileRef = 664657442ACB34AA0099DE1C /* TSAccountManagerImpl+Shims.swift */; }; + 664657472ACB66630099DE1C /* TSAccountManagerObjcBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 664657462ACB66630099DE1C /* TSAccountManagerObjcBridge.swift */; }; 6652DF672A04494200EF90E7 /* StyleOnlyMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6652DF662A04494200EF90E7 /* StyleOnlyMessageBody.swift */; }; 6652DF6A2A045EF000EF90E7 /* StyleOnlyMessageBodyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6652DF682A045ED600EF90E7 /* StyleOnlyMessageBodyTests.swift */; }; 6652DF6C2A04828800EF90E7 /* StoryMessageAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6652DF6B2A04828800EF90E7 /* StoryMessageAttachment.swift */; }; @@ -3351,13 +3354,15 @@ 662C44082A1567E4001F83E2 /* svr2.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = svr2.pb.swift; sourceTree = ""; }; 662C440A2A156DF7001F83E2 /* SecureValueRecovery2Impl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureValueRecovery2Impl.swift; sourceTree = ""; }; 662C440E2A17DB8A001F83E2 /* OrchestratingSVRImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrchestratingSVRImpl.swift; sourceTree = ""; }; - 662C44122A1835F4001F83E2 /* SVRLocalStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SVRLocalStorage.swift; sourceTree = ""; }; 662C44152A1D2101001F83E2 /* SecureValueRecovery2Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureValueRecovery2Tests.swift; sourceTree = ""; }; 663BA3172A4B8595004B9A43 /* SpoilerRenderState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpoilerRenderState.swift; sourceTree = ""; }; 663BA31B2A4C9997004B9A43 /* safety-numbers.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "safety-numbers.json"; sourceTree = ""; }; 663BA31F2A4CF96B004B9A43 /* MessageBodyDisplayConfigurations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageBodyDisplayConfigurations.swift; sourceTree = ""; }; 663D6A7B292319BC00CABC49 /* ConversationPickerFailedRecipientsSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationPickerFailedRecipientsSheet.swift; sourceTree = ""; }; 6640639D294D20A900997E0B /* OutgoingCallEventSyncMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OutgoingCallEventSyncMessage.swift; sourceTree = ""; }; + 6640DD5D2ACCCDC000CE9A8C /* RegistrationStateChangeManagerObjcTestUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegistrationStateChangeManagerObjcTestUtil.swift; sourceTree = ""; }; + 6640DD5F2ACDBEC500CE9A8C /* IncomingPniChangeNumberProcessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IncomingPniChangeNumberProcessor.swift; sourceTree = ""; }; + 6640DD622ACDD5DE00CE9A8C /* SVRLocalStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SVRLocalStorage.swift; sourceTree = ""; }; 664160CF29A6D60A00F5BA85 /* ChatServiceAuth.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatServiceAuth.swift; sourceTree = ""; }; 6642A86F2A8D7B3400E591C2 /* OWSPaymentActivationRequestFinishedMessage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OWSPaymentActivationRequestFinishedMessage.h; sourceTree = ""; }; 6642A8712A8D7C5700E591C2 /* OWSPaymentActivationRequestFinishedMessage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OWSPaymentActivationRequestFinishedMessage.m; sourceTree = ""; }; @@ -3380,6 +3385,7 @@ 6646573E2AC3B9190099DE1C /* MockRegistrationStateChangeManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRegistrationStateChangeManager.swift; sourceTree = ""; }; 664657402AC4FB720099DE1C /* NotificationsProtocolSwift.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsProtocolSwift.swift; sourceTree = ""; }; 664657442ACB34AA0099DE1C /* TSAccountManagerImpl+Shims.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSAccountManagerImpl+Shims.swift"; sourceTree = ""; }; + 664657462ACB66630099DE1C /* TSAccountManagerObjcBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAccountManagerObjcBridge.swift; sourceTree = ""; }; 6652DF662A04494200EF90E7 /* StyleOnlyMessageBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StyleOnlyMessageBody.swift; sourceTree = ""; }; 6652DF682A045ED600EF90E7 /* StyleOnlyMessageBodyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StyleOnlyMessageBodyTests.swift; sourceTree = ""; }; 6652DF6B2A04828800EF90E7 /* StoryMessageAttachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoryMessageAttachment.swift; sourceTree = ""; }; @@ -6690,6 +6696,7 @@ 661170C02ABA459D00A1B16D /* RegistrationIdGenerator.swift */, 664657442ACB34AA0099DE1C /* TSAccountManagerImpl+Shims.swift */, 661170C72ABA4F3A00A1B16D /* TSAccountManagerImpl.swift */, + 664657462ACB66630099DE1C /* TSAccountManagerObjcBridge.swift */, 661170C32ABA4D9900A1B16D /* TSAccountManagerProtocol.swift */, 6615553E2ABA5A7500AA302B /* TSRegistrationState.swift */, ); @@ -6756,6 +6763,14 @@ path = SVR2; sourceTree = ""; }; + 6640DD612ACDD5CD00CE9A8C /* LocalStorage */ = { + isa = PBXGroup; + children = ( + 6640DD622ACDD5DE00CE9A8C /* SVRLocalStorage.swift */, + ); + path = LocalStorage; + sourceTree = ""; + }; 6645F30629BF8D1000B58EBD /* AccountAttributes */ = { isa = PBXGroup; children = ( @@ -6785,6 +6800,7 @@ 6646573E2AC3B9190099DE1C /* MockRegistrationStateChangeManager.swift */, 6646573A2AC388C70099DE1C /* RegistrationStateChangeManager.swift */, 6646573C2AC3894D0099DE1C /* RegistrationStateChangeManagerImpl.swift */, + 6640DD5D2ACCCDC000CE9A8C /* RegistrationStateChangeManagerObjcTestUtil.swift */, ); path = RegistrationStateChangeManager; sourceTree = ""; @@ -6839,6 +6855,7 @@ isa = PBXGroup; children = ( 66C2B1342A0DA16F008DDE72 /* KeyBackupService */, + 6640DD612ACDD5CD00CE9A8C /* LocalStorage */, 66C2B13E2A0E9147008DDE72 /* Orchestrating */, 66C2B13B2A0E9108008DDE72 /* SVR2 */, 66138FB5298326C7002E0CFE /* SecureValueRecovery.swift */, @@ -6979,7 +6996,6 @@ 66C2B13C2A0E9116008DDE72 /* SVR2AuthCredential.swift */, 669947B92A20129000E4DC0C /* SVR2Shims.swift */, 66C2B1552A1400E8008DDE72 /* SVR2WebsocketConfigurator.swift */, - 662C44122A1835F4001F83E2 /* SVRLocalStorage.swift */, ); path = SVR2; sourceTree = ""; @@ -8852,6 +8868,7 @@ F9C5C99D289453B100548EEE /* EarlyMessageManager.swift */, F9C5C999289453B100548EEE /* FailedAttachmentDownloadsJob.swift */, F9C5C92B289453B100548EEE /* FailedMessagesJob.swift */, + 6640DD5F2ACDBEC500CE9A8C /* IncomingPniChangeNumberProcessor.swift */, F9C5C97B289453B100548EEE /* IncompleteCallsJob.swift */, F9C5C97F289453B100548EEE /* MessageFetcherJob.swift */, F9C5C95E289453B100548EEE /* MessagePipelineSupervisor.swift */, @@ -12413,6 +12430,7 @@ F9C5CDA5289453B400548EEE /* IncomingGroupsV2MessageJob+SDS.swift in Sources */, F9C5CDA0289453B400548EEE /* IncomingGroupsV2MessageJob.m in Sources */, D9AE0AD1291870220063488B /* IncomingGroupSyncJobRecord.swift in Sources */, + 6640DD602ACDBEC500CE9A8C /* IncomingPniChangeNumberProcessor.swift in Sources */, F9C5CC69289453B300548EEE /* IncompleteCallsJob.swift in Sources */, D9B95A9B29E8923B00D7CB95 /* InMemoryDatabase.swift in Sources */, 6612780C2996BC2900A1D5A1 /* InMemoryKeyValueStore.swift in Sources */, @@ -12726,6 +12744,7 @@ 6691E7F22996E9BC0032A68A /* RegistrationSessionManagerMock.swift in Sources */, 6646573B2AC388C70099DE1C /* RegistrationStateChangeManager.swift in Sources */, 6646573D2AC3894D0099DE1C /* RegistrationStateChangeManagerImpl.swift in Sources */, + 6640DD5E2ACCCDC000CE9A8C /* RegistrationStateChangeManagerObjcTestUtil.swift in Sources */, F9C5CCB0289453B300548EEE /* RemoteAttestation.swift in Sources */, F9C5CCB1289453B300548EEE /* RemoteAttestationQuote.m in Sources */, F9C5CE17289453B400548EEE /* RemoteConfigManager.swift in Sources */, @@ -12851,7 +12870,7 @@ 6673FF702978C40300F96CFD /* SVRAuthCredentialStorage.swift in Sources */, 6673FF722979B33800F96CFD /* SVRAuthCredentialStorageImpl.swift in Sources */, C18E3C742AA0F8CE003D1CF1 /* SVRAuthCredentialStorageMock.swift in Sources */, - 662C44132A1835F4001F83E2 /* SVRLocalStorage.swift in Sources */, + 6640DD632ACDD5DE00CE9A8C /* SVRLocalStorage.swift in Sources */, 66C2B1362A0DB02E008DDE72 /* SVRUtil.swift in Sources */, F9C5CE2F289453B400548EEE /* SwiftSingletons.swift in Sources */, F9C5CE04289453B400548EEE /* SyncManagerProtocol.swift in Sources */, @@ -12882,6 +12901,7 @@ F9C5CCAB289453B300548EEE /* TSAccountManager.swift in Sources */, 664657452ACB34AA0099DE1C /* TSAccountManagerImpl+Shims.swift in Sources */, 661170C82ABA4F3A00A1B16D /* TSAccountManagerImpl.swift in Sources */, + 664657472ACB66630099DE1C /* TSAccountManagerObjcBridge.swift in Sources */, 661170C42ABA4D9900A1B16D /* TSAccountManagerProtocol.swift in Sources */, D9C2D77C299D4F2600D79715 /* TSAccountState.swift in Sources */, F9C5CC77289453B300548EEE /* TSAttachment+SDS.swift in Sources */, diff --git a/Signal/OrphanData/OWSOrphanDataCleaner.m b/Signal/OrphanData/OWSOrphanDataCleaner.m index 343a1e4d23..39ad6dd3bf 100644 --- a/Signal/OrphanData/OWSOrphanDataCleaner.m +++ b/Signal/OrphanData/OWSOrphanDataCleaner.m @@ -310,7 +310,8 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); NSString *grdbHotswapDirectoryPath = [GRDBDatabaseStorageAdapter databaseDirUrlWithDirectoryMode:DirectoryModeHotswapLegacy].path; NSString *grdbTransferDirectoryPath = nil; - if (GRDBDatabaseStorageAdapter.hasAssignedTransferDirectory && TSAccountManager.shared.isTransferInProgress) { + if (GRDBDatabaseStorageAdapter.hasAssignedTransferDirectory && + [TSAccountManagerObjcBridge isTransferInProgressWithMaybeTransaction]) { grdbTransferDirectoryPath = [GRDBDatabaseStorageAdapter databaseDirUrlWithDirectoryMode:DirectoryModeTransfer].path; } diff --git a/Signal/OrphanData/OWSOrphanDataCleaner.swift b/Signal/OrphanData/OWSOrphanDataCleaner.swift index 568ab073f3..ef729d4255 100644 --- a/Signal/OrphanData/OWSOrphanDataCleaner.swift +++ b/Signal/OrphanData/OWSOrphanDataCleaner.swift @@ -26,7 +26,7 @@ extension OWSOrphanDataCleaner { let currentAppVersion = AppVersionImpl.shared.currentAppReleaseVersion return databaseStorage.read { transaction -> Bool in - guard TSAccountManager.shared.isRegistered(transaction: transaction) else { + guard DependenciesBridge.shared.tsAccountManager.registrationState(tx: transaction.asV2Read).isRegistered else { Logger.info("Orphan data audit skipped because we're not registered") return false } diff --git a/Signal/Registration/RegistrationCoodinatorShims.swift b/Signal/Registration/RegistrationCoodinatorShims.swift index 24c697da69..1f34670fa0 100644 --- a/Signal/Registration/RegistrationCoodinatorShims.swift +++ b/Signal/Registration/RegistrationCoodinatorShims.swift @@ -23,7 +23,6 @@ extension RegistrationCoordinatorImpl { public typealias PushRegistrationManager = _RegistrationCoordinator_PushRegistrationManagerShim public typealias ReceiptManager = _RegistrationCoordinator_ReceiptManagerShim public typealias RemoteConfig = _RegistrationCoordinator_RemoteConfigShim - public typealias TSAccountManager = _RegistrationCoordinator_TSAccountManagerShim public typealias UDManager = _RegistrationCoordinator_UDManagerShim } public enum Wrappers { @@ -38,7 +37,6 @@ extension RegistrationCoordinatorImpl { public typealias PushRegistrationManager = _RegistrationCoordinator_PushRegistrationManagerWrapper public typealias ReceiptManager = _RegistrationCoordinator_ReceiptManagerWrapper public typealias RemoteConfig = _RegistrationCoordinator_RemoteConfigWrapper - public typealias TSAccountManager = _RegistrationCoordinator_TSAccountManagerWrapper public typealias UDManager = _RegistrationCoordinator_UDManagerWrapper } } @@ -410,140 +408,6 @@ public class _RegistrationCoordinator_RemoteConfigWrapper: _RegistrationCoordina } } -// MARK: - TSAccountManager - -public protocol _RegistrationCoordinator_TSAccountManagerShim { - - func isManualMessageFetchEnabled(_ transaction: DBReadTransaction) -> Bool - func setIsManualMessageFetchEnabled(_ isEnabled: Bool, _ transaction: DBWriteTransaction) - - func getOrGenerateRegistrationId(_ transaction: DBWriteTransaction) -> UInt32 - func getOrGeneratePniRegistrationId(_ transaction: DBWriteTransaction) -> UInt32 - - func hasDefinedIsDiscoverableByPhoneNumber(_ transaction: DBReadTransaction) -> Bool - func isDiscoverableByPhoneNumber(_ transaction: DBReadTransaction) -> Bool - func setIsDiscoverableByPhoneNumber( - _ isDiscoverable: Bool, - updateStorageService: Bool, - authedAccount: AuthedAccount, - _ transaction: DBWriteTransaction - ) - - func resetForReregistration( - e164: E164, - aci: Aci, - _ tx: DBWriteTransaction - ) - - func didRegister( - e164: E164, - aci: Aci, - pni: Pni, - authToken: String, - _ tx: DBWriteTransaction - ) - - func updateLocalPhoneNumber( - e164: E164, - aci: Aci, - pni: Pni, - _ tx: DBWriteTransaction - ) - - func setIsOnboarded(_ tx: DBWriteTransaction) -} - -public class _RegistrationCoordinator_TSAccountManagerWrapper: _RegistrationCoordinator_TSAccountManagerShim { - - private let manager: TSAccountManager - public init(_ manager: TSAccountManager) { self.manager = manager } - - public func hasDefinedIsDiscoverableByPhoneNumber(_ transaction: DBReadTransaction) -> Bool { - return manager.hasDefinedIsDiscoverableByPhoneNumber(with: SDSDB.shimOnlyBridge(transaction)) - } - - public func setIsManualMessageFetchEnabled(_ isEnabled: Bool, _ transaction: DBWriteTransaction) { - manager.setIsManualMessageFetchEnabled(isEnabled, transaction: SDSDB.shimOnlyBridge(transaction)) - } - - public func isManualMessageFetchEnabled(_ transaction: DBReadTransaction) -> Bool { - return manager.isManualMessageFetchEnabled(SDSDB.shimOnlyBridge(transaction)) - } - - public func getOrGenerateRegistrationId(_ transaction: DBWriteTransaction) -> UInt32 { - return manager.getOrGenerateRegistrationId(transaction: SDSDB.shimOnlyBridge(transaction)) - } - - public func getOrGeneratePniRegistrationId(_ transaction: DBWriteTransaction) -> UInt32 { - return manager.getOrGeneratePniRegistrationId(transaction: SDSDB.shimOnlyBridge(transaction)) - } - - public func isDiscoverableByPhoneNumber(_ transaction: DBReadTransaction) -> Bool { - return manager.isDiscoverableByPhoneNumber(with: SDSDB.shimOnlyBridge(transaction)) - } - - public func setIsDiscoverableByPhoneNumber( - _ isDiscoverable: Bool, - updateStorageService: Bool, - authedAccount: AuthedAccount, - _ transaction: DBWriteTransaction - ) { - manager.setIsDiscoverableByPhoneNumber( - isDiscoverable, - updateStorageService: updateStorageService, - authedAccount: authedAccount, - transaction: SDSDB.shimOnlyBridge(transaction) - ) - } - - public func resetForReregistration( - e164: E164, - aci: Aci, - _ tx: DBWriteTransaction - ) { - manager.resetForReregistration( - localPhoneNumber: e164, - localAci: aci, - wasPrimaryDevice: true, - transaction: SDSDB.shimOnlyBridge(tx) - ) - } - - public func didRegister( - e164: E164, - aci: Aci, - pni: Pni, - authToken: String, - _ tx: DBWriteTransaction - ) { - manager.didRegisterPrimary( - withE164: E164ObjC(e164), - aci: AciObjC(aci), - pni: PniObjC(pni), - authToken: authToken, - transaction: SDSDB.shimOnlyBridge(tx) - ) - } - - public func updateLocalPhoneNumber( - e164: E164, - aci: Aci, - pni: Pni, - _ tx: DBWriteTransaction - ) { - manager.updateLocalPhoneNumber( - E164ObjC(e164), - aci: AciObjC(aci), - pni: PniObjC(pni), - transaction: SDSDB.shimOnlyBridge(tx) - ) - } - - public func setIsOnboarded(_ tx: DBWriteTransaction) { - manager.setIsOnboarded(true, transaction: SDSDB.shimOnlyBridge(tx)) - } -} - // MARK: - UDManager public protocol _RegistrationCoordinator_UDManagerShim { diff --git a/Signal/Registration/RegistrationCoordinatorDependencies.swift b/Signal/Registration/RegistrationCoordinatorDependencies.swift index c0bc9d3c31..7568753f18 100644 --- a/Signal/Registration/RegistrationCoordinatorDependencies.swift +++ b/Signal/Registration/RegistrationCoordinatorDependencies.swift @@ -19,10 +19,12 @@ public struct RegistrationCoordinatorDependencies { public let messagePipelineSupervisor: RegistrationCoordinatorImpl.Shims.MessagePipelineSupervisor public let messageProcessor: RegistrationCoordinatorImpl.Shims.MessageProcessor public let ows2FAManager: RegistrationCoordinatorImpl.Shims.OWS2FAManager + public let phoneNumberDiscoverabilityManager: PhoneNumberDiscoverabilityManager public let preKeyManager: PreKeyManager public let profileManager: RegistrationCoordinatorImpl.Shims.ProfileManager public let pushRegistrationManager: RegistrationCoordinatorImpl.Shims.PushRegistrationManager public let receiptManager: RegistrationCoordinatorImpl.Shims.ReceiptManager + public let registrationStateChangeManager: RegistrationStateChangeManager public let remoteConfig: RegistrationCoordinatorImpl.Shims.RemoteConfig public let schedulers: Schedulers public let sessionManager: RegistrationSessionManager @@ -30,7 +32,7 @@ public struct RegistrationCoordinatorDependencies { public let storageServiceManager: StorageServiceManager public let svr: SecureValueRecovery public let svrAuthCredentialStore: SVRAuthCredentialStorage - public let tsAccountManager: RegistrationCoordinatorImpl.Shims.TSAccountManager + public let tsAccountManager: TSAccountManagerProtocol public let udManager: RegistrationCoordinatorImpl.Shims.UDManager public static func from(_ object: NSObject) -> RegistrationCoordinatorDependencies { @@ -47,10 +49,12 @@ public struct RegistrationCoordinatorDependencies { messagePipelineSupervisor: RegistrationCoordinatorImpl.Wrappers.MessagePipelineSupervisor(object.messagePipelineSupervisor), messageProcessor: RegistrationCoordinatorImpl.Wrappers.MessageProcessor(object.messageProcessor), ows2FAManager: RegistrationCoordinatorImpl.Wrappers.OWS2FAManager(object.ows2FAManager), + phoneNumberDiscoverabilityManager: DependenciesBridge.shared.phoneNumberDiscoverabilityManager, preKeyManager: DependenciesBridge.shared.preKeyManager, profileManager: RegistrationCoordinatorImpl.Wrappers.ProfileManager(object.profileManager), pushRegistrationManager: RegistrationCoordinatorImpl.Wrappers.PushRegistrationManager(object.pushRegistrationManager), receiptManager: RegistrationCoordinatorImpl.Wrappers.ReceiptManager(object.receiptManager), + registrationStateChangeManager: DependenciesBridge.shared.registrationStateChangeManager, remoteConfig: RegistrationCoordinatorImpl.Wrappers.RemoteConfig(object.remoteConfigManager), schedulers: DependenciesBridge.shared.schedulers, sessionManager: DependenciesBridge.shared.registrationSessionManager, @@ -58,7 +62,7 @@ public struct RegistrationCoordinatorDependencies { storageServiceManager: object.storageServiceManager, svr: DependenciesBridge.shared.svr, svrAuthCredentialStore: DependenciesBridge.shared.svrCredentialStorage, - tsAccountManager: RegistrationCoordinatorImpl.Wrappers.TSAccountManager(object.tsAccountManager), + tsAccountManager: DependenciesBridge.shared.tsAccountManager, udManager: RegistrationCoordinatorImpl.Wrappers.UDManager(object.udManager) ) } diff --git a/Signal/Registration/RegistrationCoordinatorImpl.swift b/Signal/Registration/RegistrationCoordinatorImpl.swift index 1654928228..ca2160d255 100644 --- a/Signal/Registration/RegistrationCoordinatorImpl.swift +++ b/Signal/Registration/RegistrationCoordinatorImpl.swift @@ -874,9 +874,9 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator { } loadSVRAuthCredentialCandidates(tx) - inMemoryState.isManualMessageFetchEnabled = deps.tsAccountManager.isManualMessageFetchEnabled(tx) - inMemoryState.registrationId = deps.tsAccountManager.getOrGenerateRegistrationId(tx) - inMemoryState.pniRegistrationId = deps.tsAccountManager.getOrGeneratePniRegistrationId(tx) + inMemoryState.isManualMessageFetchEnabled = deps.tsAccountManager.isManualMessageFetchEnabled(tx: tx) + inMemoryState.registrationId = deps.tsAccountManager.getOrGenerateAciRegistrationId(tx: tx) + inMemoryState.pniRegistrationId = deps.tsAccountManager.getOrGeneratePniRegistrationId(tx: tx) inMemoryState.allowUnrestrictedUD = deps.udManager.shouldAllowUnrestrictedAccessLocal(transaction: tx) @@ -932,15 +932,14 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator { deps.experienceManager.clearIntroducingPinsExperience(tx) } - deps.tsAccountManager.didRegister( + deps.registrationStateChangeManager.didRegisterPrimary( e164: accountIdentity.e164, aci: accountIdentity.aci, pni: accountIdentity.pni, authToken: accountIdentity.authPassword, - tx + tx: tx ) - deps.tsAccountManager.setIsOnboarded(tx) - deps.tsAccountManager.setIsManualMessageFetchEnabled(inMemoryState.isManualMessageFetchEnabled, tx) + deps.tsAccountManager.setIsManualMessageFetchEnabled(inMemoryState.isManualMessageFetchEnabled, tx: tx) } func setupContactsAndFinish() -> Guarantee { @@ -2986,7 +2985,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator { return .value(.showErrorSheet(.genericError)) } strongSelf.db.write { tx in - strongSelf.deps.tsAccountManager.setIsManualMessageFetchEnabled(true, tx) + strongSelf.deps.tsAccountManager.setIsManualMessageFetchEnabled(true, tx: tx) strongSelf.updatePersistedState(tx) { // Say that we synced push tokens so that we skip this step hereafter. $0.legacy_didSyncPushTokens = true @@ -3305,8 +3304,10 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator { inMemoryState.udAccessKey = udAccessKey inMemoryState.hasProfileName = deps.profileManager.hasProfileName db.read { tx in - inMemoryState.hasDefinedIsDiscoverableByPhoneNumber = deps.tsAccountManager.hasDefinedIsDiscoverableByPhoneNumber(tx) - inMemoryState.isDiscoverableByPhoneNumber = deps.tsAccountManager.isDiscoverableByPhoneNumber(tx) + inMemoryState.hasDefinedIsDiscoverableByPhoneNumber = + deps.phoneNumberDiscoverabilityManager.hasDefinedIsDiscoverableByPhoneNumber(tx: tx) + inMemoryState.isDiscoverableByPhoneNumber = + deps.phoneNumberDiscoverabilityManager.isDiscoverableByPhoneNumber(tx: tx) } } @@ -3332,11 +3333,11 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator { db.write { tx in // We will update storage service at the end of registration. - deps.tsAccountManager.setIsDiscoverableByPhoneNumber( + deps.phoneNumberDiscoverabilityManager.setIsDiscoverableByPhoneNumber( true, updateStorageService: false, authedAccount: accountIdentity.authedAccount, - tx + tx: tx ) } } @@ -3385,11 +3386,11 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator { // We do these here, and not in export state, so that we don't risk // syncing out-of-date state to storage service. - strongSelf.deps.tsAccountManager.updateLocalPhoneNumber( - e164: accountIdentity.e164, + strongSelf.deps.registrationStateChangeManager.didUpdateLocalPhoneNumber( + accountIdentity.e164, aci: accountIdentity.aci, pni: accountIdentity.pni, - tx + tx: tx ) // Make sure we update our local account. strongSelf.deps.storageServiceManager.recordPendingLocalAccountUpdates() @@ -3440,10 +3441,12 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator { case .reRegistering(let state): if persistedState.hasResetForReRegistration.negated { db.write { tx in - deps.tsAccountManager.resetForReregistration( - e164: state.e164, - aci: state.aci, - tx + let isPrimaryDevice = deps.tsAccountManager.registrationState(tx: tx).isPrimaryDevice ?? true + deps.registrationStateChangeManager.resetForReregistration( + localPhoneNumber: state.e164, + localAci: state.aci, + wasPrimaryDevice: isPrimaryDevice, + tx: tx ) updatePersistedState(tx) { $0.hasResetForReRegistration = true @@ -3483,7 +3486,7 @@ public class RegistrationCoordinatorImpl: RegistrationCoordinator { self.inMemoryState.isManualMessageFetchEnabled = isManualMessageFetchEnabled if isManualMessageFetchEnabled { self.db.write { tx in - self.deps.tsAccountManager.setIsManualMessageFetchEnabled(true, tx) + self.deps.tsAccountManager.setIsManualMessageFetchEnabled(true, tx: tx) } } let accountAttributes = self.makeAccountAttributes( diff --git a/Signal/URLs/UrlOpener.swift b/Signal/URLs/UrlOpener.swift index 0eb898b4bb..13ac28507d 100644 --- a/Signal/URLs/UrlOpener.swift +++ b/Signal/URLs/UrlOpener.swift @@ -18,11 +18,11 @@ private enum OpenableUrl { class UrlOpener { private let databaseStorage: SDSDatabaseStorage - private let tsAccountManager: TSAccountManager + private let tsAccountManager: TSAccountManagerProtocol init( databaseStorage: SDSDatabaseStorage, - tsAccountManager: TSAccountManager + tsAccountManager: TSAccountManagerProtocol ) { self.databaseStorage = databaseStorage self.tsAccountManager = tsAccountManager @@ -103,7 +103,7 @@ class UrlOpener { // MARK: - Opening URLs func openUrl(_ parsedUrl: ParsedUrl, in window: UIWindow) { - guard tsAccountManager.isRegistered else { + guard tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return owsFailDebug("Ignoring URL; not registered.") } guard let rootViewController = window.rootViewController else { @@ -148,7 +148,7 @@ class UrlOpener { rootViewController.present(ProxyLinkSheetViewController(url: url)!, animated: true) case .linkDevice(let deviceProvisioningURL): - guard tsAccountManager.isPrimaryDevice else { + guard tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegisteredPrimaryDevice else { return owsFailDebug("Ignoring URL; not primary device.") } let linkedDevicesViewController = LinkedDevicesTableViewController() diff --git a/Signal/src/AppDelegate+Lifecycle.swift b/Signal/src/AppDelegate+Lifecycle.swift index 205ba7d0d2..11c1f52aab 100644 --- a/Signal/src/AppDelegate+Lifecycle.swift +++ b/Signal/src/AppDelegate+Lifecycle.swift @@ -78,11 +78,13 @@ extension AppDelegate { Logger.warn("handleActivation.") - databaseStorage.read { tx in + let tsRegistrationState: TSRegistrationState = DependenciesBridge.shared.db.read { tx in // Always check prekeys after app launches, and sometimes check on app activation. - if TSAccountManager.shared.isRegisteredAndReady(transaction: tx) { - DependenciesBridge.shared.preKeyManager.checkPreKeysIfNecessary(tx: tx.asV2Read) + let registrationState = DependenciesBridge.shared.tsAccountManager.registrationState(tx: tx) + if registrationState.isRegistered { + DependenciesBridge.shared.preKeyManager.checkPreKeysIfNecessary(tx: tx) } + return registrationState } if !Self.hasActivated { @@ -90,12 +92,11 @@ extension AppDelegate { RTCInitializeSSL() - if tsAccountManager.isRegistered { + if tsRegistrationState.isRegistered { // At this point, potentially lengthy DB locking migrations could be running. // Avoid blocking app launch by putting all further possible DB access in async block DispatchQueue.global(qos: .default).async { - let localAddress = self.tsAccountManager.localAddress - Logger.info("running post launch block for registered user: \(String(describing: localAddress))") + Logger.info("running post launch block for registered user.") // Clean up any messages that expired since last launch immediately // and continue cleaning in the background. @@ -110,7 +111,7 @@ extension AppDelegate { } // Every time we become active... - if tsAccountManager.isRegistered { + if tsRegistrationState.isRegistered { // At this point, potentially lengthy DB locking migrations could be running. // Avoid blocking app launch by putting all further possible DB access in async block DispatchQueue.main.async { diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 2057bc089b..b9ec7a23b2 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -24,7 +24,6 @@ #import #import #import -#import #import #import @@ -196,7 +195,7 @@ static void uncaughtExceptionHandler(NSException *exception) } AppReadinessRunNowOrWhenUIDidBecomeReadySync(^{ - if (![self.tsAccountManager isRegisteredAndReady]) { + if (![TSAccountManagerObjcBridge isRegisteredWithMaybeTransaction]) { ActionSheetController *controller = [[ActionSheetController alloc] initWithTitle:NSLocalizedString(@"REGISTER_CONTACTS_WELCOME", nil) message:NSLocalizedString(@"REGISTRATION_RESTRICTED_MESSAGE", nil)]; @@ -261,7 +260,7 @@ static void uncaughtExceptionHandler(NSException *exception) } AppReadinessRunNowOrWhenAppDidBecomeReadySync(^{ - if (![self.tsAccountManager isRegisteredAndReady]) { + if (![TSAccountManagerObjcBridge isRegisteredWithMaybeTransaction]) { OWSLogInfo(@"Ignoring user activity; app not ready."); return; } @@ -292,7 +291,7 @@ static void uncaughtExceptionHandler(NSException *exception) } AppReadinessRunNowOrWhenAppDidBecomeReadySync(^{ - if (![self.tsAccountManager isRegisteredAndReady]) { + if (![TSAccountManagerObjcBridge isRegisteredWithMaybeTransaction]) { OWSLogInfo(@"Ignoring user activity; app not ready."); return; } @@ -349,7 +348,7 @@ static void uncaughtExceptionHandler(NSException *exception) } AppReadinessRunNowOrWhenAppDidBecomeReadySync(^{ - if (![self.tsAccountManager isRegisteredAndReady]) { + if (![TSAccountManagerObjcBridge isRegisteredWithMaybeTransaction]) { OWSLogInfo(@"Ignoring user activity; app not ready."); return; } @@ -390,7 +389,7 @@ static void uncaughtExceptionHandler(NSException *exception) BOOL isVideo = startCallIntent.callCapability == INCallCapabilityVideoCall; AppReadinessRunNowOrWhenAppDidBecomeReadySync(^{ - if (![self.tsAccountManager isRegisteredAndReady]) { + if (![TSAccountManagerObjcBridge isRegisteredWithMaybeTransaction]) { OWSLogInfo(@"Ignoring user activity; app not ready."); return; } diff --git a/Signal/src/AppDelegate.swift b/Signal/src/AppDelegate.swift index d80b4f0305..65936b2e53 100644 --- a/Signal/src/AppDelegate.swift +++ b/Signal/src/AppDelegate.swift @@ -245,6 +245,10 @@ extension AppDelegate { Logger.info("") AssertIsOnMainThread() + // First thing; clean up any transfer state in case we are launching after a transfer. + // This needs to happen before we check any registration state. + DependenciesBridge.shared.registrationStateChangeManager.cleanUpTransferStateOnAppLaunchIfNeeded() + let regLoader = RegistrationCoordinatorLoaderImpl(dependencies: .from(self)) // Before we mark ready, block message processing on any pending change numbers. @@ -256,13 +260,6 @@ extension AppDelegate { messagePipelineSupervisor.suspendMessageProcessingWithoutHandle(for: .pendingChangeNumber) } - // If user is missing profile name, redirect to onboarding flow. - if !profileManager.hasProfileName { - databaseStorage.write { transaction in - tsAccountManager.setIsOnboarded(false, transaction: transaction) - } - } - let launchInterface = buildLaunchInterface(regLoader: regLoader) let hasInProgressRegistration: Bool @@ -293,7 +290,10 @@ extension AppDelegate { ) case nil: firstly { - LaunchJobs.run(tsAccountManager: tsAccountManager, databaseStorage: databaseStorage) + LaunchJobs.run( + tsAccountManager: DependenciesBridge.shared.tsAccountManager, + databaseStorage: databaseStorage + ) }.done(on: DispatchQueue.main) { self.setAppIsReady( launchInterface: launchInterface, @@ -324,22 +324,25 @@ extension AppDelegate { CurrentAppContext().appUserDefaults().removeObject(forKey: kAppLaunchesAttemptedKey) - if tsAccountManager.isRegistered { - databaseStorage.read { transaction in - let localAddress = self.tsAccountManager.localAddress(with: transaction) - let deviceId = self.tsAccountManager.storedDeviceId(transaction: transaction) - let deviceCount = OWSDevice.anyCount(transaction: transaction) + let tsAccountManager = DependenciesBridge.shared.tsAccountManager + let tsRegistrationState: TSRegistrationState = databaseStorage.read { tx in + let registrationState = tsAccountManager.registrationState(tx: tx.asV2Read) + if registrationState.isRegistered { + let localAddress = tsAccountManager.localIdentifiers(tx: tx.asV2Read)?.aciAddress + let deviceId = tsAccountManager.storedDeviceId(tx: tx.asV2Read) + let deviceCount = OWSDevice.anyCount(transaction: tx) let linkedDeviceMessage = deviceCount > 1 ? "\(deviceCount) devices including the primary" : "no linked devices" Logger.info("localAddress: \(String(describing: localAddress)), deviceId: \(deviceId) (\(linkedDeviceMessage))") } + return registrationState } - if tsAccountManager.isRegisteredAndReady { + if tsRegistrationState.isRegistered { // This should happen at any launch, background or foreground. SyncPushTokensJob.run() } - if tsAccountManager.isRegisteredAndReady { + if tsRegistrationState.isRegistered { APNSRotationStore.rotateIfNeededOnAppLaunchAndReadiness(performRotation: { SyncPushTokensJob.run(mode: .rotateIfEligible) }).map { @@ -352,7 +355,7 @@ extension AppDelegate { AppVersionImpl.shared.mainAppLaunchDidComplete() enableBackgroundRefreshIfNecessary() - Self.updateApplicationShortcutItems(isRegisteredAndReady: tsAccountManager.isRegisteredAndReady) + Self.updateApplicationShortcutItems(isRegistered: tsRegistrationState.isRegistered) let notificationCenter = NotificationCenter.default notificationCenter.addObserver( @@ -381,14 +384,17 @@ extension AppDelegate { ) } - checkDatabaseIntegrityIfNecessary(isRegistered: tsAccountManager.isRegistered) + checkDatabaseIntegrityIfNecessary(isRegistered: tsRegistrationState.isRegistered) SignalApp.shared.showLaunchInterface(launchInterface, launchStartedAt: launchStartedAt) } private func enableBackgroundRefreshIfNecessary() { let interval: TimeInterval - if OWS2FAManager.shared.isRegistrationLockEnabled, self.tsAccountManager.isRegisteredAndReady { + if + OWS2FAManager.shared.isRegistrationLockEnabled, + DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered + { // Ping server once a day to keep-alive reglock clients. interval = 24 * 60 * 60 } else { @@ -441,39 +447,45 @@ extension AppDelegate { // MARK: - Registration private func buildLaunchInterface(regLoader: RegistrationCoordinatorLoader) -> LaunchInterface { + // If user is missing profile name, we will redirect to onboarding flow. + let hasProfileName = profileManager.hasProfileName + let ( - isOnboarded, - isRegistered, + tsRegistrationState, lastMode ) = databaseStorage.read { tx in return ( - tsAccountManager.isOnboarded(transaction: tx), - tsAccountManager.isRegistered(transaction: tx), + DependenciesBridge.shared.tsAccountManager.registrationState(tx: tx.asV2Read), regLoader.restoreLastMode(transaction: tx.asV2Read) ) } if let lastMode { Logger.info("Found ongoing registration; continuing") return .registration(regLoader, lastMode) - // TODO[Registration]: use a db migration to move isOnboarded state to reg coordinator. - } else if !(isOnboarded && isRegistered) { + } else if !(hasProfileName && tsRegistrationState.isRegistered) { if UIDevice.current.isIPad { return .secondaryProvisioning } else { let desiredMode: RegistrationMode - if - let reregNumber = tsAccountManager.reregistrationPhoneNumber, - let reregE164 = E164(reregNumber), - let reregAci = tsAccountManager.reregistrationAci - { - Logger.info("Found legacy re-registration; continuing in new registration") - // A user who started re-registration before the new - // registration flow shipped; kick them to new re-reg. - desiredMode = .reRegistering(.init(e164: reregE164, aci: reregAci)) - } else { - Logger.info("Found legacy initial registration; continuing in new registration") + + switch tsRegistrationState { + case .reregistering(let reregNumber, let reregAci): + if let reregE164 = E164(reregNumber), let reregAci { + Logger.info("Found legacy re-registration; continuing in new registration") + // A user who started re-registration before the new + // registration flow shipped; kick them to new re-reg. + desiredMode = .reRegistering(.init(e164: reregE164, aci: reregAci)) + } else { + // If we're missing the e164 or aci, drop into normal reg. + Logger.info("Found legacy initial registration; continuing in new registration") + desiredMode = .registering + } + default: + // We got here (past the isRegistered check above) which means we should register + // but its not a reregistration. desiredMode = .registering } + return .registration(regLoader, desiredMode) } } else { @@ -774,7 +786,7 @@ extension AppDelegate { AssertIsOnMainThread() AppReadiness.runNowOrWhenAppDidBecomeReadySync { - guard self.tsAccountManager.isRegisteredAndReady else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { Logger.info("Ignoring remote notification; user is not registered.") return } @@ -818,11 +830,12 @@ extension AppDelegate { enableBackgroundRefreshIfNecessary() - let isRegisteredAndReady = tsAccountManager.isRegisteredAndReady - if isRegisteredAndReady { + let tsAccountManager = DependenciesBridge.shared.tsAccountManager + let isRegistered = tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered + if isRegistered { AppReadiness.runNowOrWhenAppDidBecomeReadySync { self.databaseStorage.write { transaction in - let localAddress = self.tsAccountManager.localAddress(with: transaction) + let localAddress = tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aciAddress Logger.info("localAddress: \(String(describing: localAddress))") ExperienceUpgradeFinder.markAllCompleteForNewUser(transaction: transaction.unwrapGrdbWrite) @@ -834,7 +847,7 @@ extension AppDelegate { } } - Self.updateApplicationShortcutItems(isRegisteredAndReady: isRegisteredAndReady) + Self.updateApplicationShortcutItems(isRegistered: isRegistered) } @objc @@ -844,13 +857,13 @@ extension AppDelegate { // MARK: - Utilities - public static func updateApplicationShortcutItems(isRegisteredAndReady: Bool) { + public static func updateApplicationShortcutItems(isRegistered: Bool) { guard CurrentAppContext().isMainApp else { return } - UIApplication.shared.shortcutItems = applicationShortcutItems(isRegisteredAndReady: isRegisteredAndReady) + UIApplication.shared.shortcutItems = applicationShortcutItems(isRegistered: isRegistered) } - static func applicationShortcutItems(isRegisteredAndReady: Bool) -> [UIApplicationShortcutItem] { - guard isRegisteredAndReady else { return [] } + static func applicationShortcutItems(isRegistered: Bool) -> [UIApplicationShortcutItem] { + guard isRegistered else { return [] } return [.init( type: "\(Bundle.main.bundleIdPrefix).quickCompose", localizedTitle: OWSLocalizedString( @@ -879,7 +892,7 @@ extension AppDelegate { AppReadiness.runNowOrWhenUIDidBecomeReadySync { let urlOpener = UrlOpener( databaseStorage: self.databaseStorage, - tsAccountManager: self.tsAccountManager + tsAccountManager: DependenciesBridge.shared.tsAccountManager ) urlOpener.openUrl(parsedUrl, in: self.window!) diff --git a/Signal/src/Calls/CallService.swift b/Signal/src/Calls/CallService.swift index 49712ad39c..6f82a3d49d 100644 --- a/Signal/src/Calls/CallService.swift +++ b/Signal/src/Calls/CallService.swift @@ -198,7 +198,7 @@ public final class CallService: LightweightCallManager { } AppReadiness.runNowOrWhenAppWillBecomeReady { - if let localAci = self.tsAccountManager.localAci { + if let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aci { self.callManager.setSelfUuid(localAci.rawUUID) } } @@ -615,8 +615,8 @@ public final class CallService: LightweightCallManager { @discardableResult @objc public func initiateCall(thread: TSThread, isVideo: Bool) -> Bool { - guard tsAccountManager.isOnboarded else { - Logger.warn("aborting due to user not being onboarded.") + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { + Logger.warn("aborting due to user not being registered.") OWSActionSheets.showActionSheet(title: OWSLocalizedString("YOU_MUST_COMPLETE_ONBOARDING_BEFORE_PROCEEDING", comment: "alert body shown when trying to use features in the app before completing registration-related setup.")) return false @@ -726,7 +726,7 @@ public final class CallService: LightweightCallManager { @objc private func registrationChanged() { AssertIsOnMainThread() - if let localAci = tsAccountManager.localAci { + if let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aci { callManager.setSelfUuid(localAci.rawUUID) } } diff --git a/Signal/src/Calls/Individual/IndividualCallService.swift b/Signal/src/Calls/Individual/IndividualCallService.swift index 42fa230ad3..2f8e50e87c 100644 --- a/Signal/src/Calls/Individual/IndividualCallService.swift +++ b/Signal/src/Calls/Individual/IndividualCallService.swift @@ -47,7 +47,7 @@ final public class IndividualCallService: NSObject { call.individualCall.createOrUpdateCallInteractionAsync(callType: .outgoingIncomplete) // Get the current local device Id, must be valid for lifetime of the call. - let localDeviceId = tsAccountManager.storedDeviceId + let localDeviceId = DependenciesBridge.shared.tsAccountManager.storedDeviceIdWithMaybeTransaction do { try callManager.placeCall(call: call, callMediaType: call.individualCall.offerMediaType.asCallMediaType, localDevice: localDeviceId) @@ -216,8 +216,8 @@ final public class IndividualCallService: NSObject { BenchEventStart(title: "Incoming Call Connection", eventId: "call-\(newCall.localId)") - guard tsAccountManager.isOnboarded(transaction: transaction) else { - Logger.warn("user is not onboarded, skipping call.") + guard DependenciesBridge.shared.tsAccountManager.registrationState(tx: transaction.asV2Read).isRegistered else { + Logger.warn("user is not registered, skipping call.") newCall.individualCall.createOrUpdateCallInteraction(callType: .incomingMissed, transaction: transaction) newCall.individualCall.state = .localFailure @@ -272,7 +272,7 @@ final public class IndividualCallService: NSObject { Logger.info("Ignoring call offer from \(thread.contactAddress) due to insufficient permissions.") // Send the need permission message to the caller, so they know why we rejected their call. - let localDeviceId = tsAccountManager.storedDeviceId(transaction: transaction) + let localDeviceId = DependenciesBridge.shared.tsAccountManager.storedDeviceId(tx: transaction.asV2Read) callManager( callManager, shouldSendHangup: callId, @@ -320,8 +320,8 @@ final public class IndividualCallService: NSObject { } // Get the current local device Id, must be valid for lifetime of the call. - let localDeviceId = tsAccountManager.storedDeviceId(transaction: transaction) - let isPrimaryDevice = tsAccountManager.isPrimaryDevice(transaction: transaction) + let localDeviceId = DependenciesBridge.shared.tsAccountManager.storedDeviceId(tx: transaction.asV2Read) + let isPrimaryDevice = DependenciesBridge.shared.tsAccountManager.registrationState(tx: transaction.asV2Read).isPrimaryDevice ?? true do { try callManager.receivedOffer(call: newCall, diff --git a/Signal/src/Calls/Signaling/WebRTCCallMessageHandler.swift b/Signal/src/Calls/Signaling/WebRTCCallMessageHandler.swift index 74e9941e3a..01120cc427 100644 --- a/Signal/src/Calls/Signaling/WebRTCCallMessageHandler.swift +++ b/Signal/src/Calls/Signaling/WebRTCCallMessageHandler.swift @@ -149,7 +149,7 @@ public class WebRTCCallMessageHandler: NSObject, OWSCallMessageHandler { messageAgeSec = (serverDeliveryTimestamp - serverReceivedTimestamp) / 1000 } - let localDeviceId = Self.tsAccountManager.storedDeviceId(transaction: transaction) + let localDeviceId = DependenciesBridge.shared.tsAccountManager.storedDeviceId(tx: transaction.asV2Read) self.callService.callManager.receivedCallMessage( senderUuid: caller.rawUUID, diff --git a/Signal/src/Calls/UserInterface/CallKit/CallKitCallManager.swift b/Signal/src/Calls/UserInterface/CallKit/CallKitCallManager.swift index 2c24e02616..b25ca34bb6 100644 --- a/Signal/src/Calls/UserInterface/CallKit/CallKitCallManager.swift +++ b/Signal/src/Calls/UserInterface/CallKit/CallKitCallManager.swift @@ -86,7 +86,7 @@ final class CallKitCallManager: NSObject { } let phoneNumber: String? = { - guard let localNumber = tsAccountManager.localNumber else { + guard let localNumber = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber else { return nil } let phoneNumbers = PhoneNumber.tryParsePhoneNumbers( diff --git a/Signal/src/Calls/UserInterface/Group/GroupCallMemberSheet.swift b/Signal/src/Calls/UserInterface/Group/GroupCallMemberSheet.swift index e88bd57989..9be142df05 100644 --- a/Signal/src/Calls/UserInterface/Group/GroupCallMemberSheet.swift +++ b/Signal/src/Calls/UserInterface/Group/GroupCallMemberSheet.swift @@ -98,7 +98,11 @@ class GroupCallMemberSheet: InteractiveSheetViewController { ) } - guard let localAddress = self.tsAccountManager.localAddress else { return members } + guard let localAddress = DependenciesBridge.shared.tsAccountManager + .localIdentifiersWithMaybeSneakyTransaction?.aciAddress + else { + return members + } let displayName = CommonStrings.you let comparableName = displayName diff --git a/Signal/src/Calls/UserInterface/Group/GroupCallMemberView.swift b/Signal/src/Calls/UserInterface/Group/GroupCallMemberView.swift index bc17bb94f0..e8ec9728d7 100644 --- a/Signal/src/Calls/UserInterface/Group/GroupCallMemberView.swift +++ b/Signal/src/Calls/UserInterface/Group/GroupCallMemberView.swift @@ -170,7 +170,7 @@ class GroupCallLocalMemberView: GroupCallMemberView { // In full-screen mode the image is shown as part of the "Your camera is off" message. videoOffIndicatorImage.isHidden = noVideoView.isHidden || isFullScreen - guard let localAddress = tsAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress else { return owsFailDebug("missing local address") } diff --git a/Signal/src/Calls/UserInterface/Group/GroupCallViewController.swift b/Signal/src/Calls/UserInterface/Group/GroupCallViewController.swift index 90fd5528cc..ac4dc7aa9f 100644 --- a/Signal/src/Calls/UserInterface/Group/GroupCallViewController.swift +++ b/Signal/src/Calls/UserInterface/Group/GroupCallViewController.swift @@ -106,7 +106,7 @@ class GroupCallViewController: UIViewController { @discardableResult class func presentLobby(thread: TSGroupThread, videoMuted: Bool = false) -> Bool { - guard tsAccountManager.isOnboarded else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { Logger.warn("aborting due to user not being onboarded.") OWSActionSheets.showActionSheet(title: OWSLocalizedString( "YOU_MUST_COMPLETE_ONBOARDING_BEFORE_PROCEEDING", @@ -616,7 +616,7 @@ extension GroupCallViewController: CallViewControllerWindowReference { var remoteVideoAddress: SignalServiceAddress { guard let firstMember = groupCall.remoteDeviceStates.sortedByAddedTime.first else { - return tsAccountManager.localAddress! + return DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction!.aciAddress } return firstMember.address } diff --git a/Signal/src/Experience Upgrades/Upgrade Views/RemoteMegaphone.swift b/Signal/src/Experience Upgrades/Upgrade Views/RemoteMegaphone.swift index bfc29fb2ba..b4743805c7 100644 --- a/Signal/src/Experience Upgrades/Upgrade Views/RemoteMegaphone.swift +++ b/Signal/src/Experience Upgrades/Upgrade Views/RemoteMegaphone.swift @@ -92,7 +92,7 @@ class RemoteMegaphone: MegaphoneView { } guard DonationUtilities.canDonateInAnyWay( - localNumber: Self.tsAccountManager.localNumber + localNumber: DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber ) else { done() DonationViewsUtil.openDonateWebsite() diff --git a/Signal/src/Launch/LaunchJobs.swift b/Signal/src/Launch/LaunchJobs.swift index a5c1d2fdb1..469c4656c7 100644 --- a/Signal/src/Launch/LaunchJobs.swift +++ b/Signal/src/Launch/LaunchJobs.swift @@ -8,12 +8,12 @@ import SignalServiceKit enum LaunchJobs { static func run( - tsAccountManager: TSAccountManager, + tsAccountManager: TSAccountManagerProtocol, databaseStorage: SDSDatabaseStorage ) -> Guarantee { AssertIsOnMainThread() - guard tsAccountManager.isRegistered else { + guard tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return .value(()) } diff --git a/Signal/src/Models/AccountManager.swift b/Signal/src/Models/AccountManager.swift index 016be2b54f..6b8037f74b 100644 --- a/Signal/src/Models/AccountManager.swift +++ b/Signal/src/Models/AccountManager.swift @@ -54,46 +54,41 @@ public class AccountManager: NSObject, Dependencies { // MARK: Linking func completeSecondaryLinking(provisionMessage: ProvisionMessage, deviceName: String) -> Promise { - // * Primary devices _can_ re-register with a new uuid. - // * Secondary devices _cannot_ be re-linked to primaries with a different uuid. - if tsAccountManager.isReregistering { + // * Primary devices that are re-registering can provision instead with a new uuid. + // * Secondary devices _cannot_ be re-linked to primaries with a different uuid, but + // `reregistering` state does not apply to secondaries. + switch DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction { + case .reregistering(let reregistrationPhoneNumber, let reregistrationAci): var canChangePhoneNumbers = false - if let oldAci = tsAccountManager.reregistrationAci, let newAci = provisionMessage.aci { - if !tsAccountManager.isPrimaryDevice, oldAci != newAci { - Logger.warn("Cannot re-link with a different uuid.") - return Promise(error: AccountManagerError.reregistrationDifferentAccount) - } else if oldAci == newAci { - // Secondary devices _can_ re-link to primaries with different - // phone numbers if the uuid is present and has not changed. - canChangePhoneNumbers = true - } + if let oldAci = reregistrationAci, let newAci = provisionMessage.aci, oldAci == newAci { + canChangePhoneNumbers = true } - // * Primary devices _cannot_ re-register with a new phone number. - // * Secondary devices _cannot_ be re-linked to primaries with a different phone number - // unless the uuid is present and has not changed. - if !canChangePhoneNumbers, - let reregistrationPhoneNumber = tsAccountManager.reregistrationPhoneNumber, - reregistrationPhoneNumber != provisionMessage.phoneNumber { - Logger.warn("Cannot re-register with a different phone number.") + if + !canChangePhoneNumbers, + reregistrationPhoneNumber != provisionMessage.phoneNumber + { + Logger.warn("Cannot provision with a different phone number from reregistration.") return Promise(error: AccountManagerError.reregistrationDifferentAccount) } + default: + break } - guard let phoneNumber = E164(provisionMessage.phoneNumber).map({ E164ObjC($0) }) else { + guard let phoneNumber = E164(provisionMessage.phoneNumber) else { return Promise(error: OWSAssertionError("Primary E164 isn't valid")) } - guard let aci = provisionMessage.aci.map({ AciObjC($0) }) else { + guard let aci = provisionMessage.aci else { return Promise(error: OWSAssertionError("Missing ACI in provisioning message!")) } - guard let pni = provisionMessage.pni.map({ PniObjC($0) }) else { + guard let pni = provisionMessage.pni else { return Promise(error: OWSAssertionError("Missing PNI in provisioning message!")) } - tsAccountManager.phoneNumberAwaitingVerification = phoneNumber - tsAccountManager.aciAwaitingVerification = aci - tsAccountManager.pniAwaitingVerification = pni + // Cycle socket and censorship circumvention state as e164 could be changing. + signalService.updateHasCensoredPhoneNumberDuringProvisioning(phoneNumber) + socketManager.cycleSocket() let serverAuthToken = generateServerAuthToken() @@ -140,7 +135,7 @@ public class AccountManager: NSObject, Dependencies { prekeyBundles: prekeyBundles ) }.done { (response: VerifySecondaryDeviceResponse) in - if pni.wrappedPniValue != response.pni { + if pni != response.pni { throw OWSAssertionError("PNI from primary is out of sync with the server!") } @@ -173,17 +168,13 @@ public class AccountManager: NSObject, Dependencies { ) } - self.tsAccountManager.storeLocalNumber( - phoneNumber, + DependenciesBridge.shared.registrationStateChangeManager.didLinkSecondary( + e164: phoneNumber, aci: aci, pni: pni, - transaction: transaction - ) - - self.tsAccountManager.setStoredServerAuthToken( - serverAuthToken, + authToken: serverAuthToken, deviceId: response.deviceId, - transaction: transaction + tx: transaction.asV2Write ) } }.then { _ -> Promise in @@ -208,7 +199,9 @@ public class AccountManager: NSObject, Dependencies { } return self.serviceClient.updateSecondaryDeviceCapabilities(hasBackedUpMasterKey: hasBackedUpMasterKey) }.done { - self.tsAccountManager.postRegistrationStateDidChangeNotification() + DependenciesBridge.shared.db.write { tx in + DependenciesBridge.shared.registrationStateChangeManager.didFinishProvisioningSecondary(tx: tx) + } }.then { _ -> Promise in BenchEventStart(title: "waiting for initial storage service restore", eventId: "initial-storage-service-restore") diff --git a/Signal/src/ViewControllers/AppSettings/Account/AccountSettingsViewController.swift b/Signal/src/ViewControllers/AppSettings/Account/AccountSettingsViewController.swift index bfec41ecff..8662eaf04b 100644 --- a/Signal/src/ViewControllers/AppSettings/Account/AccountSettingsViewController.swift +++ b/Signal/src/ViewControllers/AppSettings/Account/AccountSettingsViewController.swift @@ -36,7 +36,7 @@ class AccountSettingsViewController: OWSTableViewController2 { let contents = OWSTableContents() // Show the change pin and reglock sections - if tsAccountManager.isRegisteredPrimaryDevice { + if DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegisteredPrimaryDevice { let pinSection = OWSTableSection() pinSection.headerTitle = OWSLocalizedString( "SETTINGS_PINS_TITLE", @@ -121,9 +121,10 @@ class AccountSettingsViewController: OWSTableViewController2 { let accountSection = OWSTableSection() accountSection.headerTitle = OWSLocalizedString("SETTINGS_ACCOUNT", comment: "Title for the 'account' link in settings.") - if tsAccountManager.isDeregistered { + let tsRegistrationState = DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction + if tsRegistrationState.isDeregistered { accountSection.add(.actionItem( - withText: tsAccountManager.isPrimaryDevice + withText: tsRegistrationState.isPrimaryDevice ?? true ? OWSLocalizedString("SETTINGS_REREGISTER_BUTTON", comment: "Label for re-registration button.") : OWSLocalizedString("SETTINGS_RELINK_BUTTON", comment: "Label for re-link button."), textColor: .ows_accentBlue, @@ -141,7 +142,7 @@ class AccountSettingsViewController: OWSTableViewController2 { self?.deleteUnregisterUserData() } )) - } else if tsAccountManager.isRegisteredPrimaryDevice { + } else if tsRegistrationState.isRegisteredPrimaryDevice { switch self.changeNumberState() { case .disallowed: break @@ -250,7 +251,9 @@ class AccountSettingsViewController: OWSTableViewController2 { guard self.legacyChangePhoneNumber.localUserSupportsChangePhoneNumber(transaction: transaction) else { return .disallowed } - guard self.tsAccountManager.isDeregistered(transaction: transaction).negated else { + let tsAccountManager = DependenciesBridge.shared.tsAccountManager + let tsRegistrationState = tsAccountManager.registrationState(tx: transaction.asV2Read) + guard tsRegistrationState.isRegistered else { return .disallowed } let loader = RegistrationCoordinatorLoaderImpl(dependencies: .from(self)) @@ -262,9 +265,9 @@ class AccountSettingsViewController: OWSTableViewController2 { return .disallowed } guard - let localIdentifiers = tsAccountManager.localIdentifiers(transaction: transaction), + let localIdentifiers = tsAccountManager.localIdentifiers(tx: transaction.asV2Read), let localE164 = E164(localIdentifiers.phoneNumber), - let authToken = tsAccountManager.storedServerAuthToken(transaction: transaction), + let authToken = tsAccountManager.storedServerAuthToken(tx: transaction.asV2Read), let localRecipient = SignalRecipient.fetchRecipient( for: localIdentifiers.aciAddress, onlyIfRegistered: false, @@ -274,7 +277,7 @@ class AccountSettingsViewController: OWSTableViewController2 { else { return .disallowed } - let localDeviceId = tsAccountManager.storedDeviceId(transaction: transaction) + let localDeviceId = tsAccountManager.storedDeviceId(tx: transaction.asV2Read) let localUserAllDeviceIds = localRecipient.deviceIds return .allowed(RegistrationMode.ChangeNumberParams( diff --git a/Signal/src/ViewControllers/AppSettings/Account/DeleteAccountConfirmationViewController.swift b/Signal/src/ViewControllers/AppSettings/Account/DeleteAccountConfirmationViewController.swift index a6994f2741..17cd3a102d 100644 --- a/Signal/src/ViewControllers/AppSettings/Account/DeleteAccountConfirmationViewController.swift +++ b/Signal/src/ViewControllers/AppSettings/Account/DeleteAccountConfirmationViewController.swift @@ -342,17 +342,13 @@ class DeleteAccountConfirmationViewController: OWSTableViewController2 { private func unregisterAccount() -> Promise { Logger.info("Unregistering...") - let (promise, future) = Promise.pending() - TSAccountManager.unregisterTextSecure { - future.resolve() - } failure: { error in - future.reject(error) + return Promise.wrapAsync { + try await DependenciesBridge.shared.registrationStateChangeManager.unregisterFromService(auth: .implicit()) } - return promise } var hasEnteredLocalNumber: Bool { - guard let localNumber = TSAccountManager.localNumber else { + guard let localNumber = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber else { owsFailDebug("local number unexpectedly nil") return false } @@ -382,7 +378,7 @@ extension DeleteAccountConfirmationViewController: CountryCodeViewControllerDele } func populateDefaultCountryCode() { - guard let localNumber = TSAccountManager.localNumber else { + guard let localNumber = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber else { return owsFailDebug("Local number unexpectedly nil") } diff --git a/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.swift b/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.swift index 36f4d20745..7ed121f551 100644 --- a/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.swift +++ b/Signal/src/ViewControllers/AppSettings/AppSettingsViewController.swift @@ -30,7 +30,7 @@ class AppSettingsViewController: OWSTableViewController2 { updateHasExpiredGiftBadge() updateTableContents() - if let localAddress = tsAccountManager.localAddress { + if let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress { bulkProfileFetch.fetchProfile(address: localAddress) } @@ -142,7 +142,7 @@ class AppSettingsViewController: OWSTableViewController2 { self?.navigationController?.pushViewController(vc, animated: true) } )) - if self.tsAccountManager.isPrimaryDevice { + if DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isPrimaryDevice == true { section1.add(.disclosureItem( icon: .settingsLinkedDevices, name: OWSLocalizedString("LINKED_DEVICES_TITLE", comment: "Menu item and navbar title for the device manager"), @@ -389,7 +389,7 @@ class AppSettingsViewController: OWSTableViewController2 { localUserDisplayMode: .asUser ) - if let localAddress = tsAccountManager.localAddress { + if let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress { avatarImageView.updateWithSneakyTransactionIfNecessary { config in config.dataSource = .address(localAddress) } @@ -438,7 +438,7 @@ class AppSettingsViewController: OWSTableViewController2 { addSubtitleLabel(text: OWSUserProfile.bioForDisplay(bio: snapshot.bio, bioEmoji: snapshot.bioEmoji)) - if let phoneNumber = tsAccountManager.localNumber { + if let phoneNumber = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber { addSubtitleLabel( text: PhoneNumber.bestEffortFormatPartialUserSpecifiedText(toLookLikeAPhoneNumber: phoneNumber), isLast: true @@ -501,7 +501,9 @@ class AppSettingsViewController: OWSTableViewController2 { let vc: UIViewController if DonationSettingsViewController.hasAnythingToShowWithSneakyTransaction() { vc = DonationSettingsViewController() - } else if DonationUtilities.canDonateInAnyWay(localNumber: tsAccountManager.localNumber) { + } else if DonationUtilities.canDonateInAnyWay( + localNumber: DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber + ) { vc = DonateViewController(preferredDonateMode: .oneTime) { finishResult in let frontVc = { CurrentAppContext().frontmostViewController() } switch finishResult { diff --git a/Signal/src/ViewControllers/AppSettings/Donations/BadgeGiftingConfirmationViewController.swift b/Signal/src/ViewControllers/AppSettings/Donations/BadgeGiftingConfirmationViewController.swift index 4ca2b0bb61..81a192790e 100644 --- a/Signal/src/ViewControllers/AppSettings/Donations/BadgeGiftingConfirmationViewController.swift +++ b/Signal/src/ViewControllers/AppSettings/Donations/BadgeGiftingConfirmationViewController.swift @@ -160,7 +160,7 @@ class BadgeGiftingConfirmationViewController: OWSTableViewController2 { forDonationMode: .gift, usingCurrency: self.price.currencyCode, withConfiguration: self.paymentMethodsConfiguration, - localNumber: Self.tsAccountManager.localNumber + localNumber: DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber ) ) { [weak self] (sheet, paymentMethod) in sheet.dismiss(animated: true) { [weak self] in diff --git a/Signal/src/ViewControllers/AppSettings/Donations/DonationSettingsViewController.swift b/Signal/src/ViewControllers/AppSettings/Donations/DonationSettingsViewController.swift index f85b1bd16f..acca65f4b6 100644 --- a/Signal/src/ViewControllers/AppSettings/Donations/DonationSettingsViewController.swift +++ b/Signal/src/ViewControllers/AppSettings/Donations/DonationSettingsViewController.swift @@ -70,11 +70,16 @@ class DonationSettingsViewController: OWSTableViewController2 { private lazy var statusLabel = LinkingTextView() private static var canDonateInAnyWay: Bool { - DonationUtilities.canDonateInAnyWay(localNumber: tsAccountManager.localNumber) + DonationUtilities.canDonateInAnyWay( + localNumber: DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber + ) } private static var canSendGiftBadges: Bool { - DonationUtilities.canDonate(inMode: .gift, localNumber: tsAccountManager.localNumber) + DonationUtilities.canDonate( + inMode: .gift, + localNumber: DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber + ) } public override func viewDidLoad() { @@ -226,7 +231,7 @@ class DonationSettingsViewController: OWSTableViewController2 { private func setUpAvatarView() { databaseStorage.read { transaction in self.avatarView.update(transaction) { config in - if let address = tsAccountManager.localAddress(with: transaction) { + if let address = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aciAddress { config.dataSource = .address(address) config.addBadgeIfApplicable = true } diff --git a/Signal/src/ViewControllers/AppSettings/Internal/InternalSettingsViewController.swift b/Signal/src/ViewControllers/AppSettings/Internal/InternalSettingsViewController.swift index bf743bb520..9af43ed432 100644 --- a/Signal/src/ViewControllers/AppSettings/Internal/InternalSettingsViewController.swift +++ b/Signal/src/ViewControllers/AppSettings/Internal/InternalSettingsViewController.swift @@ -104,13 +104,14 @@ class InternalSettingsViewController: OWSTableViewController2 { // The first version of the app that was run on this device. infoSection.add(.copyableItem(label: "First Version", value: AppVersionImpl.shared.firstAppVersion)) - infoSection.add(.copyableItem(label: "Local Phone Number", value: tsAccountManager.localNumber)) + let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction + infoSection.add(.copyableItem(label: "Local Phone Number", value: localIdentifiers?.phoneNumber)) - infoSection.add(.copyableItem(label: "Local ACI", value: tsAccountManager.localAci?.serviceIdString)) + infoSection.add(.copyableItem(label: "Local ACI", value: localIdentifiers?.aci.serviceIdString)) - infoSection.add(.copyableItem(label: "Local PNI", value: tsAccountManager.localPni?.serviceIdString)) + infoSection.add(.copyableItem(label: "Local PNI", value: localIdentifiers?.pni?.serviceIdString)) - infoSection.add(.copyableItem(label: "Device ID", value: "\(tsAccountManager.storedDeviceId)")) + infoSection.add(.copyableItem(label: "Device ID", value: "\(DependenciesBridge.shared.tsAccountManager.storedDeviceIdWithMaybeTransaction)")) if let buildDetails = Bundle.main.object(forInfoDictionaryKey: "BuildDetails") as? [String: AnyObject] { if let signalCommit = (buildDetails["SignalCommit"] as? String)?.strippedOrNil?.prefix(12) { diff --git a/Signal/src/ViewControllers/AppSettings/Linked Devices/LinkDeviceViewController.swift b/Signal/src/ViewControllers/AppSettings/Linked Devices/LinkDeviceViewController.swift index 7f2b9c4404..e77a53c614 100644 --- a/Signal/src/ViewControllers/AppSettings/Linked Devices/LinkDeviceViewController.swift +++ b/Signal/src/ViewControllers/AppSettings/Linked Devices/LinkDeviceViewController.swift @@ -141,7 +141,7 @@ class LinkDeviceViewController: OWSViewController { var pniIdentityKeyPair: ECKeyPair? var areReadReceiptsEnabled: Bool = true databaseStorage.read { tx in - localIdentifiers = tsAccountManager.localIdentifiers(transaction: tx) + localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read) let identityManager = DependenciesBridge.shared.identityManager aciIdentityKeyPair = identityManager.identityKeyPair(for: .aci, tx: tx.asV2Read) pniIdentityKeyPair = identityManager.identityKeyPair(for: .pni, tx: tx.asV2Read) diff --git a/Signal/src/ViewControllers/AppSettings/Privacy/AdvancedPrivacySettingsViewController.swift b/Signal/src/ViewControllers/AppSettings/Privacy/AdvancedPrivacySettingsViewController.swift index 202511c0bf..3ac9696a27 100644 --- a/Signal/src/ViewControllers/AppSettings/Privacy/AdvancedPrivacySettingsViewController.swift +++ b/Signal/src/ViewControllers/AppSettings/Privacy/AdvancedPrivacySettingsViewController.swift @@ -218,7 +218,7 @@ class AdvancedPrivacySettingsViewController: OWSTableViewController2 { } )) - if tsAccountManager.isRegisteredPrimaryDevice { + if DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegisteredPrimaryDevice { sealedSenderSection.add(.switch( withText: OWSLocalizedString( "SETTINGS_UNIDENTIFIED_DELIVERY_UNRESTRICTED_ACCESS", diff --git a/Signal/src/ViewControllers/AppSettings/Privacy/PhoneNumberPrivacySettingsViewController.swift b/Signal/src/ViewControllers/AppSettings/Privacy/PhoneNumberPrivacySettingsViewController.swift index 9dfef30fb7..2a88f0ffaf 100644 --- a/Signal/src/ViewControllers/AppSettings/Privacy/PhoneNumberPrivacySettingsViewController.swift +++ b/Signal/src/ViewControllers/AppSettings/Privacy/PhoneNumberPrivacySettingsViewController.swift @@ -17,7 +17,8 @@ class PhoneNumberPrivacySettingsViewController: OWSTableViewController2 { override func viewDidLoad() { super.viewDidLoad() sharingFeatureEnabled = FeatureFlags.phoneNumberSharing - discoverabilityFeatureEnabled = FeatureFlags.phoneNumberDiscoverability && tsAccountManager.isPrimaryDevice + discoverabilityFeatureEnabled = FeatureFlags.phoneNumberDiscoverability + && (DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isPrimaryDevice ?? true) phoneNumberSharingMode = databaseStorage.read { tx in udManager.phoneNumberSharingMode(tx: tx) } title = OWSLocalizedString( "SETTINGS_PHONE_NUMBER_PRIVACY_TITLE", @@ -71,7 +72,9 @@ class PhoneNumberPrivacySettingsViewController: OWSTableViewController2 { // MARK: Update Setting Values private func discoverabilityItem(_ isDiscoverable: Bool) -> OWSTableItem { - let currentlyIsDiscoverable = tsAccountManager.isDiscoverableByPhoneNumber() + let currentlyIsDiscoverable = DependenciesBridge.shared.db.read( + block: DependenciesBridge.shared.tsAccountManager.isDiscoverableByPhoneNumber(tx:) + ) return OWSTableItem( text: PhoneNumberDiscoverability.nameForDiscoverability(isDiscoverable), actionBlock: { [weak self] in @@ -94,17 +97,18 @@ class PhoneNumberPrivacySettingsViewController: OWSTableViewController2 { // MARK: Update Table UI private func updateDiscoverability(_ isDiscoverable: Bool) { - guard tsAccountManager.isDiscoverableByPhoneNumber() != isDiscoverable else { return } + let currentlyIsDiscoverable = DependenciesBridge.shared.db.read( + block: DependenciesBridge.shared.tsAccountManager.isDiscoverableByPhoneNumber(tx:) + ) + guard currentlyIsDiscoverable != isDiscoverable else { return } - databaseStorage.asyncWrite(block: { [weak self] transaction in - - self?.tsAccountManager.setIsDiscoverableByPhoneNumber( + databaseStorage.asyncWrite(block: { transaction in + DependenciesBridge.shared.phoneNumberDiscoverabilityManager.setIsDiscoverableByPhoneNumber( isDiscoverable, updateStorageService: true, authedAccount: .implicit(), - transaction: transaction + tx: transaction.asV2Write ) - }) { [weak self] in self?.updateTableContents() } @@ -119,11 +123,11 @@ class PhoneNumberPrivacySettingsViewController: OWSTableViewController2 { // If sharing is set to `everybody`, discovery needs to be // updated to match this. if mode == .everybody { - self?.tsAccountManager.setIsDiscoverableByPhoneNumber( + DependenciesBridge.shared.phoneNumberDiscoverabilityManager.setIsDiscoverableByPhoneNumber( true, updateStorageService: true, authedAccount: .implicit(), - transaction: transaction + tx: transaction.asV2Write ) } }) { [weak self] in @@ -162,7 +166,10 @@ struct PhoneNumberDiscoverability { extension PhoneNumberPrivacySettingsViewController { fileprivate class var descriptionForCurrentDiscoverability: String { - return PhoneNumberDiscoverability.descriptionForDiscoverability(tsAccountManager.isDiscoverableByPhoneNumber()) + let isDiscoverable = DependenciesBridge.shared.db.read { + return DependenciesBridge.shared.tsAccountManager.isDiscoverableByPhoneNumber(tx: $0) + } + return PhoneNumberDiscoverability.descriptionForDiscoverability(isDiscoverable) } fileprivate var descriptionForCurrentPhoneNumberSharingMode: String { diff --git a/Signal/src/ViewControllers/AppSettings/Privacy/PrivacySettingsViewController.swift b/Signal/src/ViewControllers/AppSettings/Privacy/PrivacySettingsViewController.swift index 98aab32b54..1ea1b837e7 100644 --- a/Signal/src/ViewControllers/AppSettings/Privacy/PrivacySettingsViewController.swift +++ b/Signal/src/ViewControllers/AppSettings/Privacy/PrivacySettingsViewController.swift @@ -36,7 +36,7 @@ class PrivacySettingsViewController: OWSTableViewController2 { if FeatureFlags.phoneNumberSharing || (FeatureFlags.phoneNumberDiscoverability && - tsAccountManager.isPrimaryDevice) { + DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isPrimaryDevice == true) { whoCanSection.add(.disclosureItem( withText: OWSLocalizedString( "SETTINGS_PHONE_NUMBER_PRIVACY_TITLE", diff --git a/Signal/src/ViewControllers/AppSettings/Profile/BadgeConfigurationViewController.swift b/Signal/src/ViewControllers/AppSettings/Profile/BadgeConfigurationViewController.swift index 7ac3d945a1..fd3d88214f 100644 --- a/Signal/src/ViewControllers/AppSettings/Profile/BadgeConfigurationViewController.swift +++ b/Signal/src/ViewControllers/AppSettings/Profile/BadgeConfigurationViewController.swift @@ -158,7 +158,7 @@ class BadgeConfigurationViewController: OWSTableViewController2, BadgeCollection guard let self = self else { return cell } let collectionView = BadgeCollectionView(dataSource: self) - if let localAddress = self.tsAccountManager.localAddress { + if let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress { let localShortName = self.databaseStorage.read { self.contactsManager.shortDisplayName(for: localAddress, transaction: $0) } collectionView.badgeSelectionMode = .detailsSheet(owner: .local(shortName: localShortName)) } else { diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController+BodyTextItems.swift b/Signal/src/ViewControllers/ConversationView/ConversationViewController+BodyTextItems.swift index 620041ab27..9989795e6b 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController+BodyTextItems.swift +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController+BodyTextItems.swift @@ -34,7 +34,7 @@ extension ConversationViewController { public func didTapBodyTextItem(_ item: CVTextLabel.Item) { AssertIsOnMainThread() - guard tsAccountManager.isRegisteredAndReady else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return } @@ -75,7 +75,7 @@ extension ConversationViewController { public func didLongPressBodyTextItem(_ item: CVTextLabel.Item) { AssertIsOnMainThread() - guard tsAccountManager.isRegisteredAndReady else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return } diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController+MessageRequest.swift b/Signal/src/ViewControllers/ConversationView/ConversationViewController+MessageRequest.swift index 0c5642ccbd..478ac60842 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController+MessageRequest.swift +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController+MessageRequest.swift @@ -33,7 +33,7 @@ extension ConversationViewController: MessageRequestDelegate { return } - guard let localIdentifiers = tsAccountManager.localIdentifiers else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction else { owsFailDebug("Missing local identifiers!") return } diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewController+UI.swift b/Signal/src/ViewControllers/ConversationView/ConversationViewController+UI.swift index 74fc0969d4..095b092692 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewController+UI.swift +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewController+UI.swift @@ -280,7 +280,8 @@ extension ConversationViewController { return incoming.authorAddress.aci == draftReply.author } if candidate is TSOutgoingMessage { - return tsAccountManager.localIdentifiers(transaction: transaction)?.aci == draftReply.author + return DependenciesBridge.shared.tsAccountManager + .localIdentifiers(tx: transaction.asV2Read)?.aci == draftReply.author } return false }, diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewModel.swift b/Signal/src/ViewControllers/ConversationView/ConversationViewModel.swift index 6869429500..331f098399 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewModel.swift +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewModel.swift @@ -26,7 +26,7 @@ class ConversationViewModel { } let unreadMentionMessageIds = MentionFinder.messagesMentioning( - aci: NSObject.tsAccountManager.localIdentifiers(transaction: tx)!.aci, + aci: DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read)!.aci, in: thread, includeReadMessages: false, tx: tx diff --git a/Signal/src/ViewControllers/ConversationView/InteractionReactionState.swift b/Signal/src/ViewControllers/ConversationView/InteractionReactionState.swift index 83490149ee..f81a616d1b 100644 --- a/Signal/src/ViewControllers/ConversationView/InteractionReactionState.swift +++ b/Signal/src/ViewControllers/ConversationView/InteractionReactionState.swift @@ -22,7 +22,7 @@ public class InteractionReactionState: NSObject { // No reactions on non-message interactions guard let message = interaction as? TSMessage else { return nil } - guard let localAddress = TSAccountManager.shared.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aciAddress else { owsFailDebug("missing local address") return nil } diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIGroupsV2.swift b/Signal/src/ViewControllers/DebugUI/DebugUIGroupsV2.swift index 42be5fc6c9..4b708ade2d 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIGroupsV2.swift +++ b/Signal/src/ViewControllers/DebugUI/DebugUIGroupsV2.swift @@ -52,7 +52,7 @@ class DebugUIGroupsV2: DebugUIPage, Dependencies { // MARK: - private func kickOtherGroupMembers(groupModel: TSGroupModelV2) { - guard let localAci = tsAccountManager.localIdentifiers?.aci else { + guard let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aci else { return owsFailDebug("Missing localAddress.") } diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIMessages.swift b/Signal/src/ViewControllers/DebugUI/DebugUIMessages.swift index 86b810baff..edee4e4b2e 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIMessages.swift +++ b/Signal/src/ViewControllers/DebugUI/DebugUIMessages.swift @@ -3345,7 +3345,7 @@ class DebugUIMessages: DebugUIPage, Dependencies { private static func createUUIDGroup() { let uuidMembers = (0...3).map { _ in CommonGenerator.address(hasPhoneNumber: false) } - let members = uuidMembers + [TSAccountManager.localAddress!] + let members = uuidMembers + [DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction!.aciAddress] let groupName = "UUID Group" _ = GroupManager.localCreateNewGroup(members: members, name: groupName, disappearingMessageToken: .disabledToken, shouldSendMessage: true) @@ -3697,7 +3697,7 @@ class DebugUIMessages: DebugUIPage, Dependencies { member: SignalServiceAddress, completion: @escaping (TSGroupThread) -> Void ) { - let members = [ member, TSAccountManager.localAddress! ] + let members = [ member, DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction!.aciAddress ] GroupManager.localCreateNewGroup( members: members, disappearingMessageToken: .disabledToken, @@ -4205,7 +4205,7 @@ class DebugUIMessages: DebugUIPage, Dependencies { if let contactThread = thread as? TSContactThread { return contactThread.contactAddress } else if let groupThread = thread as? TSGroupThread { - guard let localAddress = Self.tsAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress else { owsFailDebug("Missing localAddress.") return nil } @@ -4230,7 +4230,7 @@ class DebugUIMessages: DebugUIPage, Dependencies { wasReceivedByUD: false, serverDeliveryTimestamp: 0, shouldDiscardVisibleMessages: false, - localIdentifiers: tsAccountManager.localIdentifiers(transaction: tx)!, + localIdentifiers: DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read)!, tx: tx ) } diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIMisc.swift b/Signal/src/ViewControllers/DebugUI/DebugUIMisc.swift index 6507f05b3f..83e029af94 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIMisc.swift +++ b/Signal/src/ViewControllers/DebugUI/DebugUIMisc.swift @@ -103,7 +103,9 @@ class DebugUIMisc: DebugUIPage, Dependencies { }), OWSTableItem(title: "Update account attributes", actionBlock: { - TSAccountManager.shared.updateAccountAttributes() + Task { + try? await DependenciesBridge.shared.accountAttributesUpdater.updateAccountAttributes(authedAccount: .implicit()) + } }), OWSTableItem(title: "Check Prekeys", actionBlock: { @@ -378,7 +380,7 @@ class DebugUIMisc: DebugUIPage, Dependencies { } private static func logLocalAccount() { - guard let localAddress = tsAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress else { owsFailDebug("Missing localAddress.") return } diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIProfile.swift b/Signal/src/ViewControllers/DebugUI/DebugUIProfile.swift index b999cf6ab1..16df1c6714 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIProfile.swift +++ b/Signal/src/ViewControllers/DebugUI/DebugUIProfile.swift @@ -63,7 +63,10 @@ class DebugUIProfile: DebugUIPage, Dependencies { Self.profileManagerImpl.logLocalProfile() }, OWSTableItem(title: "Fetch Local Profile") { - ProfileFetcherJob.fetchProfile(address: TSAccountManager.localAddress!, ignoreThrottling: true) + ProfileFetcherJob.fetchProfile( + address: DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction!.aciAddress, + ignoreThrottling: true + ) } ].compactMap { $0 } diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIStress.swift b/Signal/src/ViewControllers/DebugUI/DebugUIStress.swift index 8d5d60e503..6f665b6250 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIStress.swift +++ b/Signal/src/ViewControllers/DebugUI/DebugUIStress.swift @@ -215,7 +215,7 @@ class DebugUIStress: DebugUIPage, Dependencies { return SignalServiceAddress(serviceId: Aci(fromUUID: UUID()), phoneNumber: phoneNumber) } - if let localAddress = tsAccountManager.localAddress { + if let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress { recipientAddresses.append(localAddress) } diff --git a/Signal/src/ViewControllers/Donations/BadgeDetailsSheet.swift b/Signal/src/ViewControllers/Donations/BadgeDetailsSheet.swift index df8897c866..fe803a523d 100644 --- a/Signal/src/ViewControllers/Donations/BadgeDetailsSheet.swift +++ b/Signal/src/ViewControllers/Donations/BadgeDetailsSheet.swift @@ -164,7 +164,7 @@ class BadgeDetailsSheet: OWSTableSheetViewController { private func didTapDonate() { dismiss(animated: true) { if DonationUtilities.canDonateInAnyWay( - localNumber: Self.tsAccountManager.localNumber + localNumber: DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber ) { let frontVc = { CurrentAppContext().frontmostViewController() } diff --git a/Signal/src/ViewControllers/Donations/BadgeExpirationSheet.swift b/Signal/src/ViewControllers/Donations/BadgeExpirationSheet.swift index d0ef8584be..8867cbff2c 100644 --- a/Signal/src/ViewControllers/Donations/BadgeExpirationSheet.swift +++ b/Signal/src/ViewControllers/Donations/BadgeExpirationSheet.swift @@ -168,7 +168,7 @@ class BadgeExpirationSheet: OWSTableSheetViewController { badge: badge, mode: mode, canDonate: DonationUtilities.canDonateInAnyWay( - localNumber: Self.tsAccountManager.localNumber + localNumber: DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber ) ) owsAssertDebug(state.badge.assets != nil) diff --git a/Signal/src/ViewControllers/Donations/DonateChoosePaymentMethodSheet.swift b/Signal/src/ViewControllers/Donations/DonateChoosePaymentMethodSheet.swift index 4ab62d7a2f..1a717e19fd 100644 --- a/Signal/src/ViewControllers/Donations/DonateChoosePaymentMethodSheet.swift +++ b/Signal/src/ViewControllers/Donations/DonateChoosePaymentMethodSheet.swift @@ -209,7 +209,7 @@ class DonateChoosePaymentMethodSheet: OWSTableSheetViewController { let paymentMethods: [DonationPaymentMethod] let applePayFirstRegions = PhoneNumberRegions(arrayLiteral: "1") - if let localNumber = Self.tsAccountManager.localNumber, + if let localNumber = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber, applePayFirstRegions.contains(e164: localNumber) { paymentMethods = [ .applePay, diff --git a/Signal/src/ViewControllers/Donations/DonateViewController.swift b/Signal/src/ViewControllers/Donations/DonateViewController.swift index 6a4db2763a..f227f0a638 100644 --- a/Signal/src/ViewControllers/Donations/DonateViewController.swift +++ b/Signal/src/ViewControllers/Donations/DonateViewController.swift @@ -15,7 +15,7 @@ class DonateViewController: OWSViewController, OWSNavigationChildController { ) -> Bool { DonationUtilities.canDonate( inMode: donateMode.asDonationMode, - localNumber: tsAccountManager.localNumber + localNumber: DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber ) } @@ -631,7 +631,7 @@ class DonateViewController: OWSViewController, OWSNavigationChildController { previousMonthlySubscriptionCurrencyCode: previousSubscriberCurrencyCode, previousMonthlySubscriptionPaymentMethod: previousSubscriberPaymentMethod, locale: Locale.current, - localNumber: Self.tsAccountManager.localNumber + localNumber: DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber ) return .value(loadedState) @@ -688,7 +688,7 @@ class DonateViewController: OWSViewController, OWSNavigationChildController { databaseStorage.read { [weak self] transaction in self?.avatarView.update(transaction) { config in - guard let address = self?.tsAccountManager.localAddress(with: transaction) else { + guard let address = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aciAddress else { return } config.dataSource = .address(address) diff --git a/Signal/src/ViewControllers/GroupInviteLinksUI.swift b/Signal/src/ViewControllers/GroupInviteLinksUI.swift index c91c1f955b..ce5cac3903 100644 --- a/Signal/src/ViewControllers/GroupInviteLinksUI.swift +++ b/Signal/src/ViewControllers/GroupInviteLinksUI.swift @@ -423,7 +423,7 @@ private class GroupInviteLinksActionSheet: ActionSheetController, Dependencies { } private var doesLocalUserSupportGroupsV2: Bool { - guard let localAddress = tsAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress else { owsFailDebug("missing local address") return false } diff --git a/Signal/src/ViewControllers/HomeView/Chat List/ChatListViewController+Reminders.swift b/Signal/src/ViewControllers/HomeView/Chat List/ChatListViewController+Reminders.swift index d0fb21e281..c031bd6f80 100644 --- a/Signal/src/ViewControllers/HomeView/Chat List/ChatListViewController+Reminders.swift +++ b/Signal/src/ViewControllers/HomeView/Chat List/ChatListViewController+Reminders.swift @@ -38,7 +38,7 @@ public class CLVReminderViews: Dependencies { let deregisteredText: String let deregisteredActionTitle: String - if TSAccountManager.shared.isPrimaryDevice { + if DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isPrimaryDevice ?? true { deregisteredText = OWSLocalizedString( "DEREGISTRATION_WARNING", comment: "Label warning the user that they have been de-registered." @@ -199,7 +199,8 @@ extension ChatListViewController { AssertIsOnMainThread() archiveReminderView.isHidden = chatListMode != .archive - deregisteredView.isHidden = !tsAccountManager.isDeregistered || tsAccountManager.isTransferInProgress + let tsRegistrationState = DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction + deregisteredView.isHidden = !tsRegistrationState.isDeregistered outageView.isHidden = !OutageDetection.shared.hasOutage expiredView.update() diff --git a/Signal/src/ViewControllers/HomeView/Chat List/ChatListViewController.swift b/Signal/src/ViewControllers/HomeView/Chat List/ChatListViewController.swift index 0b324f609e..0c4739ff1d 100644 --- a/Signal/src/ViewControllers/HomeView/Chat List/ChatListViewController.swift +++ b/Signal/src/ViewControllers/HomeView/Chat List/ChatListViewController.swift @@ -587,7 +587,7 @@ public class ChatListViewController: OWSViewController { } private func addPullToRefreshIfNeeded() { - if tsAccountManager.isPrimaryDevice { + if DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isPrimaryDevice ?? true { return } @@ -601,7 +601,7 @@ public class ChatListViewController: OWSViewController { @objc private func pullToRefreshPerformed(_ refreshControl: UIRefreshControl) { AssertIsOnMainThread() - owsAssert(!tsAccountManager.isPrimaryDevice) + owsAssert(DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isPrimaryDevice == false) syncManager.sendAllSyncRequestMessages(timeout: 20).ensure { refreshControl.endRefreshing() @@ -983,7 +983,7 @@ extension ChatListViewController { let avatarView = ConversationAvatarView(sizeClass: .twentyEight, localUserDisplayMode: .asUser) databaseStorage.read { readTx in avatarView.update(readTx) { config in - if let address = tsAccountManager.localAddress(with: readTx) { + if let address = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: readTx.asV2Read)?.aciAddress { config.dataSource = .address(address) config.applyConfigurationSynchronously() } @@ -1103,7 +1103,7 @@ extension ChatListViewController { case let .donate(donateMode): guard DonationUtilities.canDonate( inMode: donateMode.asDonationMode, - localNumber: tsAccountManager.localNumber + localNumber: DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber ) else { DonationViewsUtil.openDonateWebsite() return diff --git a/Signal/src/ViewControllers/HomeView/Stories/MyStoryCell.swift b/Signal/src/ViewControllers/HomeView/Stories/MyStoryCell.swift index b869f22a52..4fcfd88a02 100644 --- a/Signal/src/ViewControllers/HomeView/Stories/MyStoryCell.swift +++ b/Signal/src/ViewControllers/HomeView/Stories/MyStoryCell.swift @@ -96,7 +96,7 @@ class MyStoryCell: UITableViewCell { addStoryButton.block = addStoryAction avatarView.updateWithSneakyTransactionIfNecessary { config in - config.dataSource = .address(Self.tsAccountManager.localAddress!) + config.dataSource = .address(DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction!.aciAddress) // We reload the row when this state changes, so don't make the avatar auto update. config.storyConfiguration = .fixed(model.messages.isEmpty ? .noStories : .viewed) config.usePlaceholderImages() diff --git a/Signal/src/ViewControllers/HomeView/Stories/Replies & Views Sheets/Group Reply Sheet/StoryGroupReplyLoader.swift b/Signal/src/ViewControllers/HomeView/Stories/Replies & Views Sheets/Group Reply Sheet/StoryGroupReplyLoader.swift index 47936fc4b2..dfeb2eb801 100644 --- a/Signal/src/ViewControllers/HomeView/Stories/Replies & Views Sheets/Group Reply Sheet/StoryGroupReplyLoader.swift +++ b/Signal/src/ViewControllers/HomeView/Stories/Replies & Views Sheets/Group Reply Sheet/StoryGroupReplyLoader.swift @@ -221,10 +221,12 @@ class StoryGroupReplyLoader: Dependencies { var messages = [(SignalServiceAddress, TSMessage)]() var authorAddresses = Set() + let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)!.aciAddress + for interaction in loadedInteractions { if let outgoingMessage = interaction as? TSOutgoingMessage { - messages.append((tsAccountManager.localAddress!, outgoingMessage)) - authorAddresses.insert(tsAccountManager.localAddress!) + messages.append((localAddress, outgoingMessage)) + authorAddresses.insert(localAddress) } else if let incomingMessage = interaction as? TSIncomingMessage { messages.append((incomingMessage.authorAddress, incomingMessage)) authorAddresses.insert(incomingMessage.authorAddress) diff --git a/Signal/src/ViewControllers/HomeView/Stories/Settings/StoryPrivacySettingsViewController.swift b/Signal/src/ViewControllers/HomeView/Stories/Settings/StoryPrivacySettingsViewController.swift index 2c8f2332cd..666253c8a0 100644 --- a/Signal/src/ViewControllers/HomeView/Stories/Settings/StoryPrivacySettingsViewController.swift +++ b/Signal/src/ViewControllers/HomeView/Stories/Settings/StoryPrivacySettingsViewController.swift @@ -263,7 +263,7 @@ private class StoryThreadCell: ContactTableViewCell { configuration = ContactCellConfiguration(groupThread: groupThread, localUserDisplayMode: .noteToSelf) case .privateStory(_, let isMyStory): if isMyStory { - guard let localAddress = tsAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress else { owsFailDebug("Unexpectedly missing local address") return } diff --git a/Signal/src/ViewControllers/HomeView/Stories/StoriesViewController.swift b/Signal/src/ViewControllers/HomeView/Stories/StoriesViewController.swift index f4bea38477..12926b4e56 100644 --- a/Signal/src/ViewControllers/HomeView/Stories/StoriesViewController.swift +++ b/Signal/src/ViewControllers/HomeView/Stories/StoriesViewController.swift @@ -306,7 +306,7 @@ class StoriesViewController: OWSViewController, StoryListDataSourceDelegate { let avatarView = ConversationAvatarView(sizeClass: .twentyEight, localUserDisplayMode: .asUser) databaseStorage.read { transaction in avatarView.update(transaction) { config in - if let address = tsAccountManager.localAddress(with: transaction) { + if let address = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aciAddress { config.dataSource = .address(address) config.applyConfigurationSynchronously() } diff --git a/Signal/src/ViewControllers/MediaGallery/MediaGallery.swift b/Signal/src/ViewControllers/MediaGallery/MediaGallery.swift index 8f956ff55a..60f8a4a1f9 100644 --- a/Signal/src/ViewControllers/MediaGallery/MediaGallery.swift +++ b/Signal/src/ViewControllers/MediaGallery/MediaGallery.swift @@ -460,7 +460,7 @@ class MediaGallery: Dependencies { return incomingMessage.authorAddress } - return tsAccountManager.localAddress(with: transaction) + return DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aciAddress }() if let senderAddress { diff --git a/Signal/src/ViewControllers/NewGroupView/NewGroupConfirmViewController.swift b/Signal/src/ViewControllers/NewGroupView/NewGroupConfirmViewController.swift index a668660a63..7a1858086b 100644 --- a/Signal/src/ViewControllers/NewGroupView/NewGroupConfirmViewController.swift +++ b/Signal/src/ViewControllers/NewGroupView/NewGroupConfirmViewController.swift @@ -203,7 +203,7 @@ public class NewGroupConfirmViewController: OWSTableViewController2 { private func createNewGroup() { AssertIsOnMainThread() - guard let localAddress = tsAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress else { owsFailDebug("missing local address") return } diff --git a/Signal/src/ViewControllers/OWSPinSetupViewController.swift b/Signal/src/ViewControllers/OWSPinSetupViewController.swift index a789918a83..2b145f6e83 100644 --- a/Signal/src/ViewControllers/OWSPinSetupViewController.swift +++ b/Signal/src/ViewControllers/OWSPinSetupViewController.swift @@ -250,7 +250,7 @@ public class PinSetupViewController: OWSViewController, OWSNavigationChildContro enableRegistrationLock: Bool, completionHandler: @escaping (PinSetupViewController, Error?) -> Void ) { - assert(TSAccountManager.shared.isRegisteredPrimaryDevice) + assert(DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegisteredPrimaryDevice) self.mode = mode self.initialMode = initialMode self.pinType = pinType @@ -671,7 +671,9 @@ public class PinSetupViewController: OWSViewController, OWSNavigationChildContro // registration recovery password. // We might have already done this in the steps above, but re-upload to be sure. // Just kick it off, don't wait on the result. - _ = TSAccountManager.shared.updateAccountAttributes().cauterize() + DependenciesBridge.shared.db.write { + DependenciesBridge.shared.accountAttributesUpdater.scheduleAccountAttributesUpdate(authedAccount: .implicit(), tx: $0) + } } .done { AssertIsOnMainThread() diff --git a/Signal/src/ViewControllers/OutgoingDeviceTransfer/OutgoingDeviceTransferProgressViewController.swift b/Signal/src/ViewControllers/OutgoingDeviceTransfer/OutgoingDeviceTransferProgressViewController.swift index 9b18117aa4..03e402f9bc 100644 --- a/Signal/src/ViewControllers/OutgoingDeviceTransfer/OutgoingDeviceTransferProgressViewController.swift +++ b/Signal/src/ViewControllers/OutgoingDeviceTransfer/OutgoingDeviceTransferProgressViewController.swift @@ -9,7 +9,14 @@ import SignalUI class OutgoingDeviceTransferProgressViewController: DeviceTransferBaseViewController { - override var requiresDismissConfirmation: Bool { TSAccountManager.shared.isTransferInProgress } + override var requiresDismissConfirmation: Bool { + switch DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction { + case .transferringLinkedOutgoing, .transferringPrimaryOutgoing: + return true + default: + return false + } + } let progressView: TransferProgressView init(progress: Progress) { diff --git a/Signal/src/ViewControllers/OutgoingDeviceTransfer/OutgoingDeviceTransferQRScanningViewController.swift b/Signal/src/ViewControllers/OutgoingDeviceTransfer/OutgoingDeviceTransferQRScanningViewController.swift index 4de0fd47b6..6ff26172c4 100644 --- a/Signal/src/ViewControllers/OutgoingDeviceTransfer/OutgoingDeviceTransferQRScanningViewController.swift +++ b/Signal/src/ViewControllers/OutgoingDeviceTransfer/OutgoingDeviceTransferQRScanningViewController.swift @@ -204,7 +204,8 @@ extension OutgoingDeviceTransferQRScanningViewController: QRCodeScanDelegate { return case .modeMismatch: let desiredMode: DeviceTransferService.TransferMode = - TSAccountManager.shared.isPrimaryDevice ? .linked : .primary + DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isPrimaryDevice ?? true + ? .linked : .primary switch desiredMode { case .linked: self.showError( diff --git a/Signal/src/ViewControllers/Payments/SendPaymentViewController.swift b/Signal/src/ViewControllers/Payments/SendPaymentViewController.swift index 893b336598..f80d5eafa7 100644 --- a/Signal/src/ViewControllers/Payments/SendPaymentViewController.swift +++ b/Signal/src/ViewControllers/Payments/SendPaymentViewController.swift @@ -167,7 +167,7 @@ public class SendPaymentViewController: OWSViewController { showEnablePaymentsActionSheet() return } - guard tsAccountManager.isRegisteredAndReady else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { Logger.info("Local user is not registered and ready.") showNotRegisteredActionSheet() return @@ -356,7 +356,7 @@ public class SendPaymentViewController: OWSViewController { message: interaction.asPreparer, transaction: transaction ) - if let localAci = self.tsAccountManager.localIdentifiers(transaction: transaction)?.aci { + if let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aci { let infoMessage = TSInfoMessage( thread: thread, messageType: .paymentsActivationRequest, diff --git a/Signal/src/ViewControllers/Registration/Provisioning/ProvisioningController.swift b/Signal/src/ViewControllers/Registration/Provisioning/ProvisioningController.swift index 42942028fa..cde6e9108c 100644 --- a/Signal/src/ViewControllers/Registration/Provisioning/ProvisioningController.swift +++ b/Signal/src/ViewControllers/Registration/Provisioning/ProvisioningController.swift @@ -339,7 +339,7 @@ public class ProvisioningController: NSObject { public func provisioningDidComplete(from viewController: UIViewController) { self.databaseStorage.write { Logger.info("completed provisioning") - self.tsAccountManager.setIsOnboarded(true, transaction: $0) + DependenciesBridge.shared.registrationStateChangeManager.didFinishProvisioningSecondary(tx: $0.asV2Write) } SignalApp.shared.showConversationSplitView() } diff --git a/Signal/src/ViewControllers/ThreadSettings/ConversationSettingsViewController.swift b/Signal/src/ViewControllers/ThreadSettings/ConversationSettingsViewController.swift index 388a6d4acd..7da70df1a5 100644 --- a/Signal/src/ViewControllers/ThreadSettings/ConversationSettingsViewController.swift +++ b/Signal/src/ViewControllers/ThreadSettings/ConversationSettingsViewController.swift @@ -260,7 +260,11 @@ class ConversationSettingsViewController: OWSTableViewController2, BadgeCollecti private(set) var groupMemberStateMap = [SignalServiceAddress: OWSVerificationState]() private(set) var sortedGroupMembers = [SignalServiceAddress]() func updateGroupMembers(transaction tx: SDSAnyReadTransaction) { - guard let groupModel = currentGroupModel, !groupModel.isPlaceholder, let localAddress = tsAccountManager.localAddress else { + guard + let groupModel = currentGroupModel, + !groupModel.isPlaceholder, + let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress + else { groupMemberStateMap = [:] sortedGroupMembers = [] return @@ -642,7 +646,7 @@ class ConversationSettingsViewController: OWSTableViewController2, BadgeCollecti guard let groupModelV2 = groupThread.groupModel as? TSGroupModelV2 else { return true } - guard let localAci = tsAccountManager.localIdentifiers?.aci else { + guard let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aci else { owsFailDebug("missing local address") return true } @@ -660,7 +664,7 @@ class ConversationSettingsViewController: OWSTableViewController2, BadgeCollecti guard let groupModelV2 = groupThread.groupModel as? TSGroupModelV2 else { return [] } - guard let localAddress = tsAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress else { owsFailDebug("missing local address") return [] } diff --git a/Signal/src/ViewControllers/ThreadSettings/GroupMemberRequestsAndInvitesViewController.swift b/Signal/src/ViewControllers/ThreadSettings/GroupMemberRequestsAndInvitesViewController.swift index a9fca66b9e..b4393af0db 100644 --- a/Signal/src/ViewControllers/ThreadSettings/GroupMemberRequestsAndInvitesViewController.swift +++ b/Signal/src/ViewControllers/ThreadSettings/GroupMemberRequestsAndInvitesViewController.swift @@ -227,7 +227,7 @@ public class GroupMemberRequestsAndInvitesViewController: OWSTableViewController } private func addContentsForPendingInvites(contents: OWSTableContents) { - guard let localAci = tsAccountManager.localIdentifiers?.aci else { + guard let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aci else { owsFailDebug("missing local address") return } diff --git a/Signal/src/ViewControllers/ThreadSettings/GroupViewHelper+MemberActionSheet.swift b/Signal/src/ViewControllers/ThreadSettings/GroupViewHelper+MemberActionSheet.swift index ed37b65f47..13d6ae9382 100644 --- a/Signal/src/ViewControllers/ThreadSettings/GroupViewHelper+MemberActionSheet.swift +++ b/Signal/src/ViewControllers/ThreadSettings/GroupViewHelper+MemberActionSheet.swift @@ -57,7 +57,7 @@ extension GroupViewHelper { groupThread.isGroupV2Thread else { return false } - guard let localAddress = tsAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress else { owsFailDebug("Missing localAddress.") return false } @@ -91,7 +91,7 @@ extension GroupViewHelper { groupThread.isGroupV2Thread else { return false } - guard let localAddress = tsAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress else { owsFailDebug("Missing localAddress.") return false } @@ -125,7 +125,7 @@ extension GroupViewHelper { groupThread.isGroupV2Thread else { return false } - guard let localAddress = tsAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress else { owsFailDebug("Missing localAddress.") return false } diff --git a/Signal/src/ViewControllers/ThreadSettings/GroupViewHelper.swift b/Signal/src/ViewControllers/ThreadSettings/GroupViewHelper.swift index c8a22249cf..38e4b29402 100644 --- a/Signal/src/ViewControllers/ThreadSettings/GroupViewHelper.swift +++ b/Signal/src/ViewControllers/ThreadSettings/GroupViewHelper.swift @@ -59,7 +59,7 @@ class GroupViewHelper: Dependencies { // All users can edit v1 groups. return true } - guard let localAddress = tsAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress else { owsFailDebug("Missing localAddress.") return false } diff --git a/Signal/src/environment/AppEnvironment.swift b/Signal/src/environment/AppEnvironment.swift index c376459b1c..b7e24ec9fe 100644 --- a/Signal/src/environment/AppEnvironment.swift +++ b/Signal/src/environment/AppEnvironment.swift @@ -88,7 +88,7 @@ public class AppEnvironment: NSObject { AppReadiness.runNowOrWhenAppDidBecomeReadyAsync { let isPrimaryDevice = self.databaseStorage.read { tx -> Bool in - return self.tsAccountManager.isPrimaryDevice(transaction: tx) + return DependenciesBridge.shared.tsAccountManager.registrationState(tx: tx.asV2Read).isPrimaryDevice ?? true } let db = DependenciesBridge.shared.db diff --git a/Signal/src/environment/SignalApp.swift b/Signal/src/environment/SignalApp.swift index b02548bb80..b7543ad6e0 100644 --- a/Signal/src/environment/SignalApp.swift +++ b/Signal/src/environment/SignalApp.swift @@ -264,7 +264,7 @@ extension SignalApp { OWSFileSystem.deleteContents(ofDirectory: OWSFileSystem.cachesDirectoryPath()) OWSFileSystem.deleteContents(ofDirectory: OWSTemporaryDirectory()) OWSFileSystem.deleteContents(ofDirectory: NSTemporaryDirectory()) - AppDelegate.updateApplicationShortcutItems(isRegisteredAndReady: false) + AppDelegate.updateApplicationShortcutItems(isRegistered: false) } DebugLogger.shared().wipeLogsAlways(appContext: CurrentAppContext() as! MainAppContext) diff --git a/Signal/src/util/Device Transfer/DeviceTransferService+Manifest.swift b/Signal/src/util/Device Transfer/DeviceTransferService+Manifest.swift index 99a4bae431..7aaf5ae004 100644 --- a/Signal/src/util/Device Transfer/DeviceTransferService+Manifest.swift +++ b/Signal/src/util/Device Transfer/DeviceTransferService+Manifest.swift @@ -171,7 +171,7 @@ extension DeviceTransferService { stopTransfer() return owsFailDebug("Failed to parse manifest proto") } - guard !tsAccountManager.isRegistered else { + guard !DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { stopTransfer() return owsFailDebug("Ignoring incoming transfer to a registered device") } @@ -198,7 +198,9 @@ extension DeviceTransferService { progress: progress ) - tsAccountManager.isTransferInProgress = true + DependenciesBridge.shared.db.write { tx in + DependenciesBridge.shared.registrationStateChangeManager.setIsTransferInProgress(tx: tx) + } notifyObservers { $0.deviceTransferServiceDidStartTransfer(progress: progress) } diff --git a/Signal/src/util/Device Transfer/DeviceTransferService+MultipeerDelegates.swift b/Signal/src/util/Device Transfer/DeviceTransferService+MultipeerDelegates.swift index 808e91060c..8caf0a727d 100644 --- a/Signal/src/util/Device Transfer/DeviceTransferService+MultipeerDelegates.swift +++ b/Signal/src/util/Device Transfer/DeviceTransferService+MultipeerDelegates.swift @@ -362,7 +362,7 @@ extension DeviceTransferService: MCSessionDelegate { guard case .outgoing(let newDevicePeerId, let expectedCertificateHash, _, _, _) = transferState else { // Accept all connections if we're not doing an outgoing transfer AND we aren't yet registered. // Registered devices can only ever perform outgoing transfers. - certificateIsTrusted = !tsAccountManager.isRegistered + certificateIsTrusted = !DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered return } diff --git a/Signal/src/util/Device Transfer/DeviceTransferService+Restore.swift b/Signal/src/util/Device Transfer/DeviceTransferService+Restore.swift index 6cf22bf211..c651534806 100644 --- a/Signal/src/util/Device Transfer/DeviceTransferService+Restore.swift +++ b/Signal/src/util/Device Transfer/DeviceTransferService+Restore.swift @@ -547,13 +547,17 @@ extension DeviceTransferService { let (promise, future) = Guarantee.pending() AppReadiness.runNowOrWhenAppDidBecomeReadySync { - self.tsAccountManager.isTransferInProgress = false + DependenciesBridge.shared.db.write { tx in + DependenciesBridge.shared.registrationStateChangeManager.setIsTransferComplete( + sendStateUpdateNotification: true, + tx: tx + ) + } // Consult both the modern and legacy restoration flag let currentPhase = (try? self.restorationPhase) ?? .noCurrentRestoration if currentPhase == .cleanup || LegacyRestorationFlags.pendingWasTransferredClear { Logger.info("Performing one-time post-restore cleanup...") - self.tsAccountManager.wasTransferred = false GRDBDatabaseStorageAdapter.removeOrphanedGRDBDirectories() LegacyRestorationFlags.pendingWasTransferredClear = false self.rawRestorationPhase = RestorationPhase.noCurrentRestoration.rawValue diff --git a/Signal/src/util/Device Transfer/DeviceTransferService+URL.swift b/Signal/src/util/Device Transfer/DeviceTransferService+URL.swift index e55d593595..bb12b00f21 100644 --- a/Signal/src/util/Device Transfer/DeviceTransferService+URL.swift +++ b/Signal/src/util/Device Transfer/DeviceTransferService+URL.swift @@ -58,7 +58,8 @@ extension DeviceTransferService { throw Error.unsupportedVersion } - let currentMode: TransferMode = tsAccountManager.isPrimaryDevice ? .primary : .linked + let currentMode: TransferMode = DependenciesBridge.shared.tsAccountManager + .registrationStateWithMaybeSneakyTransaction.isPrimaryDevice == true ? .primary : .linked guard let rawMode = queryItemsDictionary[DeviceTransferService.transferModeKey], rawMode == currentMode.rawValue else { diff --git a/Signal/src/util/Device Transfer/DeviceTransferService.swift b/Signal/src/util/Device Transfer/DeviceTransferService.swift index 62edc47f88..8ef3dc99cf 100644 --- a/Signal/src/util/Device Transfer/DeviceTransferService.swift +++ b/Signal/src/util/Device Transfer/DeviceTransferService.swift @@ -183,11 +183,20 @@ class DeviceTransferService: NSObject { // Marking the transfer as "in progress" does a few things, most notably it: // * prevents any WAL checkpoints while the transfer is in progress // * causes the device to behave is if it's not registered - tsAccountManager.isTransferInProgress = true + DependenciesBridge.shared.db.write { tx in + DependenciesBridge.shared.registrationStateChangeManager.setIsTransferInProgress(tx: tx) + } defer { // If we failed to start the transfer, clear the transfer in progress flag - if case .idle = transferState { tsAccountManager.isTransferInProgress = false } + if case .idle = transferState { + DependenciesBridge.shared.db.write { tx in + DependenciesBridge.shared.registrationStateChangeManager.setIsTransferComplete( + sendStateUpdateNotification: true, + tx: tx + ) + } + } } let manifest = try buildManifest() @@ -268,10 +277,11 @@ class DeviceTransferService: NSObject { // simply return in the .idle case above since none of the values being // reset should have values if we are idle, but I am scared of it. if case .idle = transferState {} else { - if notifyRegState { - tsAccountManager.isTransferInProgress = false - } else { - tsAccountManager.setIsTransferInProgressWithoutNotification(false) + DependenciesBridge.shared.db.write { tx in + DependenciesBridge.shared.registrationStateChangeManager.setIsTransferComplete( + sendStateUpdateNotification: notifyRegState, + tx: tx + ) } } @@ -357,7 +367,9 @@ class DeviceTransferService: NSObject { } Promise.when(fulfilled: promises).done { - self.tsAccountManager.wasTransferred = true + DependenciesBridge.shared.db.write { tx in + DependenciesBridge.shared.registrationStateChangeManager.setWasTransferred(tx: tx) + } try self.sendDoneMessage(to: newDevicePeerId) }.catch { error in if !(error is DeviceTransferOperation.CancelError) { diff --git a/Signal/src/util/RegistrationUtils.swift b/Signal/src/util/RegistrationUtils.swift index b2b6c44fc7..0f3b10e1a5 100644 --- a/Signal/src/util/RegistrationUtils.swift +++ b/Signal/src/util/RegistrationUtils.swift @@ -16,13 +16,13 @@ public class RegistrationUtils: Dependencies { AssertIsOnMainThread() // If this is not the primary device, jump directly to the re-linking flow. - guard tsAccountManager.isPrimaryDevice else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isPrimaryDevice == true else { showRelinkingUI() return } guard - let localIdentifiers = tsAccountManager.localIdentifiers, + let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction, let e164 = E164(localIdentifiers.phoneNumber) else { owsFailDebug("could not get local address for re-registration.") @@ -38,7 +38,7 @@ public class RegistrationUtils: Dependencies { class func showReregistrationUI(fromViewController viewController: UIViewController) { // If this is not the primary device, jump directly to the re-linking flow. - guard tsAccountManager.isPrimaryDevice else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isPrimaryDevice == true else { showRelinkingUI() return } @@ -62,7 +62,22 @@ public class RegistrationUtils: Dependencies { private class func showRelinkingUI() { Logger.info("showRelinkingUI") - guard tsAccountManager.resetForReregistration() else { + let success = DependenciesBridge.shared.db.write { tx -> Bool in + guard + let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx), + let localE164 = E164(localIdentifiers.phoneNumber) + else { + return false + } + DependenciesBridge.shared.registrationStateChangeManager.resetForReregistration( + localPhoneNumber: localE164, + localAci: localIdentifiers.aci, + wasPrimaryDevice: DependenciesBridge.shared.tsAccountManager.registrationState(tx: tx).isPrimaryDevice ?? false, + tx: tx + ) + return true + } + guard success else { owsFailDebug("could not reset for re-registration.") return } diff --git a/Signal/test/AppDelegateTest.swift b/Signal/test/AppDelegateTest.swift index b6139369bf..9fb5165eec 100644 --- a/Signal/test/AppDelegateTest.swift +++ b/Signal/test/AppDelegateTest.swift @@ -12,10 +12,10 @@ class AppDelegateTest: XCTestCase { shortcuts.contains(where: { $0.type.contains("quickCompose") }) } - let unregistered = AppDelegate.applicationShortcutItems(isRegisteredAndReady: false) + let unregistered = AppDelegate.applicationShortcutItems(isRegistered: false) XCTAssertFalse(hasNewMessageShortcut(unregistered)) - let registered = AppDelegate.applicationShortcutItems(isRegisteredAndReady: true) + let registered = AppDelegate.applicationShortcutItems(isRegistered: true) XCTAssertTrue(hasNewMessageShortcut(registered)) } } diff --git a/Signal/test/Registration/RegistrationCoordinatorTest.swift b/Signal/test/Registration/RegistrationCoordinatorTest.swift index 8ad93ef704..d268a14bd3 100644 --- a/Signal/test/Registration/RegistrationCoordinatorTest.swift +++ b/Signal/test/Registration/RegistrationCoordinatorTest.swift @@ -40,16 +40,18 @@ public class RegistrationCoordinatorTest: XCTestCase { private var mockMessageProcessor: RegistrationCoordinatorImpl.TestMocks.MessageProcessor! private var mockURLSession: TSRequestOWSURLSessionMock! private var ows2FAManagerMock: RegistrationCoordinatorImpl.TestMocks.OWS2FAManager! + private var phoneNumberDiscoverabilityManagerMock: MockPhoneNumberDiscoverabilityManager! private var preKeyManagerMock: RegistrationCoordinatorImpl.TestMocks.PreKeyManager! private var profileManagerMock: RegistrationCoordinatorImpl.TestMocks.ProfileManager! private var pushRegistrationManagerMock: RegistrationCoordinatorImpl.TestMocks.PushRegistrationManager! private var receiptManagerMock: RegistrationCoordinatorImpl.TestMocks.ReceiptManager! + private var registrationStateChangeManagerMock: MockRegistrationStateChangeManager! private var remoteConfigMock: RegistrationCoordinatorImpl.TestMocks.RemoteConfig! private var sessionManager: RegistrationSessionManagerMock! private var storageServiceManagerMock: FakeStorageServiceManager! private var svr: SecureValueRecoveryMock! private var svrAuthCredentialStore: SVRAuthCredentialStorageMock! - private var tsAccountManagerMock: RegistrationCoordinatorImpl.TestMocks.TSAccountManager! + private var tsAccountManagerMock: MockTSAccountManager! public override func setUp() { super.setUp() @@ -71,14 +73,16 @@ public class RegistrationCoordinatorTest: XCTestCase { mockMessagePipelineSupervisor = RegistrationCoordinatorImpl.TestMocks.MessagePipelineSupervisor() mockMessageProcessor = RegistrationCoordinatorImpl.TestMocks.MessageProcessor() ows2FAManagerMock = RegistrationCoordinatorImpl.TestMocks.OWS2FAManager() + phoneNumberDiscoverabilityManagerMock = MockPhoneNumberDiscoverabilityManager() preKeyManagerMock = RegistrationCoordinatorImpl.TestMocks.PreKeyManager() profileManagerMock = RegistrationCoordinatorImpl.TestMocks.ProfileManager() pushRegistrationManagerMock = RegistrationCoordinatorImpl.TestMocks.PushRegistrationManager() receiptManagerMock = RegistrationCoordinatorImpl.TestMocks.ReceiptManager() + registrationStateChangeManagerMock = MockRegistrationStateChangeManager() remoteConfigMock = RegistrationCoordinatorImpl.TestMocks.RemoteConfig() sessionManager = RegistrationSessionManagerMock() storageServiceManagerMock = FakeStorageServiceManager() - tsAccountManagerMock = RegistrationCoordinatorImpl.TestMocks.TSAccountManager() + tsAccountManagerMock = MockTSAccountManager(dateProvider: dateProvider) let mockURLSession = TSRequestOWSURLSessionMock() self.mockURLSession = mockURLSession @@ -102,10 +106,12 @@ public class RegistrationCoordinatorTest: XCTestCase { messagePipelineSupervisor: mockMessagePipelineSupervisor, messageProcessor: mockMessageProcessor, ows2FAManager: ows2FAManagerMock, + phoneNumberDiscoverabilityManager: phoneNumberDiscoverabilityManagerMock, preKeyManager: preKeyManagerMock, profileManager: profileManagerMock, pushRegistrationManager: pushRegistrationManagerMock, receiptManager: receiptManagerMock, + registrationStateChangeManager: registrationStateChangeManagerMock, remoteConfig: remoteConfigMock, schedulers: TestSchedulers(scheduler: scheduler), sessionManager: sessionManager, @@ -3346,7 +3352,7 @@ public class RegistrationCoordinatorTest: XCTestCase { } private func setAllProfileInfo() { - tsAccountManagerMock.hasDefinedIsDiscoverableByPhoneNumberMock = { true } + phoneNumberDiscoverabilityManagerMock.hasDefinedIsDiscoverableByPhoneNumberMock = { true } profileManagerMock.hasProfileNameMock = { true } } diff --git a/Signal/test/Registration/RegistrationCoordinatorTestShims.swift b/Signal/test/Registration/RegistrationCoordinatorTestShims.swift index 4646fd61da..37b347f24d 100644 --- a/Signal/test/Registration/RegistrationCoordinatorTestShims.swift +++ b/Signal/test/Registration/RegistrationCoordinatorTestShims.swift @@ -24,7 +24,6 @@ extension RegistrationCoordinatorImpl { public typealias PushRegistrationManager = _RegistrationCoordinator_PushRegistrationManagerMock public typealias ReceiptManager = _RegistrationCoordinator_ReceiptManagerMock public typealias RemoteConfig = _RegistrationCoordinator_RemoteConfigMock - public typealias TSAccountManager = _RegistrationCoordinator_TSAccountManagerMock public typealias UDManager = _RegistrationCoordinator_UDManagerMock } } @@ -294,107 +293,6 @@ public class _RegistrationCoordinator_RemoteConfigMock: _RegistrationCoordinator } } -// MARK: - TSAccountManager - -public class _RegistrationCoordinator_TSAccountManagerMock: _RegistrationCoordinator_TSAccountManagerShim { - - public init() {} - - public var hasDefinedIsDiscoverableByPhoneNumberMock: (() -> Bool)? - - public func hasDefinedIsDiscoverableByPhoneNumber(_ transaction: DBReadTransaction) -> Bool { - return hasDefinedIsDiscoverableByPhoneNumberMock!() - } - - public var isDiscoverableByPhoneNumberMock: () -> Bool = { true } - - public func isDiscoverableByPhoneNumber(_ transaction: DBReadTransaction) -> Bool { - return isDiscoverableByPhoneNumberMock() - } - - public var setIsDiscoverableByPhoneNumberMock: ((_ isDiscoverable: Bool, _ authedAccount: AuthedAccount, _ updateStorageService: Bool) -> Void)? - - public func setIsDiscoverableByPhoneNumber( - _ isDiscoverable: Bool, - updateStorageService: Bool, - authedAccount: AuthedAccount, - _ transaction: SignalServiceKit.DBWriteTransaction - ) { - setIsDiscoverableByPhoneNumberMock?(isDiscoverable, authedAccount, updateStorageService) - } - - public var isManualMessageFetchEnabledMock: () -> Bool = { false } - - public func isManualMessageFetchEnabled(_ transaction: DBReadTransaction) -> Bool { - return isManualMessageFetchEnabledMock() - } - - public var setIsManualMessageFetchEnabledMock: ((_ isEnabled: Bool) -> Void)? - - public func setIsManualMessageFetchEnabled(_ isEnabled: Bool, _ transaction: DBWriteTransaction) { - setIsManualMessageFetchEnabledMock?(isEnabled) - } - - public var resetForReregistrationMock: (( - _ e164: E164, - _ aci: Aci - ) -> Void)? - - public func resetForReregistration( - e164: E164, - aci: Aci, - _ tx: DBWriteTransaction - ) { - resetForReregistrationMock?(e164, aci) - } - - public var didRegisterMock: (( - _ e164: E164, - _ aci: Aci, - _ pni: Pni, - _ authToken: String - ) -> Void)? - - public func didRegister( - e164: E164, - aci: Aci, - pni: Pni, - authToken: String, - _ tx: DBWriteTransaction - ) { - didRegisterMock?(e164, aci, pni, authToken) - } - - public var updateLocalPhoneNumberMock: (( - _ e164: E164, - _ aci: Aci, - _ pni: Pni - ) -> Void)? - - public func updateLocalPhoneNumber( - e164: E164, - aci: Aci, - pni: Pni, - _ tx: DBWriteTransaction - ) { - updateLocalPhoneNumberMock?(e164, aci, pni) - } - - public var registrationIdMock: (() -> UInt32) = { 8 /* an arbitrary default value */ } - - public func getOrGenerateRegistrationId(_ transaction: DBWriteTransaction) -> UInt32 { - return registrationIdMock() - } - - public var pniRegistrationIdMock: (() -> UInt32) = { 9 /* an arbitrary default value */ } - - public func getOrGeneratePniRegistrationId(_ transaction: DBWriteTransaction) -> UInt32 { - return pniRegistrationIdMock() - } - - public func setIsOnboarded(_ tx: SignalServiceKit.DBWriteTransaction) {} -} - // MARK: UDManager public class _RegistrationCoordinator_UDManagerMock: _RegistrationCoordinator_UDManagerShim { diff --git a/Signal/test/contact/OWSContactsManagerTest.swift b/Signal/test/contact/OWSContactsManagerTest.swift index 16a9aa714c..1437b96c27 100644 --- a/Signal/test/contact/OWSContactsManagerTest.swift +++ b/Signal/test/contact/OWSContactsManagerTest.swift @@ -19,7 +19,12 @@ class OWSContactsManagerTest: SignalBaseTest { super.setUp() // Create local account. - tsAccountManager.registerForTests(localIdentifiers: .forUnitTests) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .forUnitTests, + tx: tx.asV2Write + ) + } // Replace the fake contacts manager with the real one just for this test. SSKEnvironment.shared.setContactsManagerForUnitTests(makeContactsManager()) diff --git a/Signal/test/util/ContactStreamTest.swift b/Signal/test/util/ContactStreamTest.swift index b36b12213d..8dbcce86e8 100644 --- a/Signal/test/util/ContactStreamTest.swift +++ b/Signal/test/util/ContactStreamTest.swift @@ -14,7 +14,12 @@ class ContactStreamTest: SignalBaseTest { override func setUp() { super.setUp() - tsAccountManager.registerForTests(localIdentifiers: .forUnitTests) + Self.databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .forUnitTests, + tx: tx.asV2Write + ) + } } // MARK: - diff --git a/Signal/test/util/FTS/GRDBFullTextSearcherTest.swift b/Signal/test/util/FTS/GRDBFullTextSearcherTest.swift index 981182f471..24ac66cbb2 100644 --- a/Signal/test/util/FTS/GRDBFullTextSearcherTest.swift +++ b/Signal/test/util/FTS/GRDBFullTextSearcherTest.swift @@ -172,10 +172,19 @@ class GRDBFullTextSearcherTest: SignalBaseTest { // ensure local client has necessary "registered" state let localE164Identifier = "+13235551234" let localUUID = UUID() - tsAccountManager.registerForTests(withLocalNumber: localE164Identifier, uuid: localUUID) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .init( + aci: .init(fromUUID: localUUID), + pni: nil, + e164: E164(localE164Identifier)! + ), + tx: tx.asV2Write + ) + } self.write { transaction in - let bookClubGroupThread = try! GroupManager.createGroupForTests(members: [self.aliceRecipient, self.bobRecipient, self.tsAccountManager.localAddress!], + let bookClubGroupThread = try! GroupManager.createGroupForTests(members: [self.aliceRecipient, self.bobRecipient, DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)!.aciAddress], name: "Book Club", transaction: transaction) self.bookClubThread = ThreadViewModel(thread: bookClubGroupThread, @@ -412,7 +421,7 @@ class GRDBFullTextSearcherTest: SignalBaseTest { var thread: TSGroupThread! = nil self.write { transaction in - thread = try! GroupManager.createGroupForTests(members: [self.aliceRecipient, self.bobRecipient, self.tsAccountManager.localAddress!], + thread = try! GroupManager.createGroupForTests(members: [self.aliceRecipient, self.bobRecipient, DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)!.aciAddress], name: "Lifecycle", transaction: transaction) } @@ -466,7 +475,7 @@ class GRDBFullTextSearcherTest: SignalBaseTest { func testModelLifecycle2() { self.write { transaction in - let thread = try! GroupManager.createGroupForTests(members: [self.aliceRecipient, self.bobRecipient, self.tsAccountManager.localAddress!], + let thread = try! GroupManager.createGroupForTests(members: [self.aliceRecipient, self.bobRecipient, DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)!.aciAddress], name: "Lifecycle", transaction: transaction) @@ -495,7 +504,7 @@ class GRDBFullTextSearcherTest: SignalBaseTest { func testDiacritics() { self.write { transaction in - let thread = try! GroupManager.createGroupForTests(members: [self.aliceRecipient, self.bobRecipient, self.tsAccountManager.localAddress!], + let thread = try! GroupManager.createGroupForTests(members: [self.aliceRecipient, self.bobRecipient, DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)!.aciAddress], name: "Lifecycle", transaction: transaction) @@ -545,7 +554,7 @@ class GRDBFullTextSearcherTest: SignalBaseTest { var thread: TSGroupThread! = nil self.write { transaction in - thread = try! GroupManager.createGroupForTests(members: [self.aliceRecipient, self.bobRecipient, self.tsAccountManager.localAddress!], + thread = try! GroupManager.createGroupForTests(members: [self.aliceRecipient, self.bobRecipient, DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)!.aciAddress], name: "Lifecycle", transaction: transaction) } @@ -578,7 +587,16 @@ class GRDBFullTextSearcherTest: SignalBaseTest { let aliceE164 = "+13213214321" let aliceUuid = UUID() - tsAccountManager.registerForTests(withLocalNumber: aliceE164, uuid: aliceUuid) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .init( + aci: .init(fromUUID: aliceUuid), + pni: nil, + e164: E164(aliceE164)! + ), + tx: tx.asV2Write + ) + } let string1 = "krazy" let string2 = "kat" @@ -586,7 +604,7 @@ class GRDBFullTextSearcherTest: SignalBaseTest { Bench(title: "Populate Index", memorySamplerRatio: 1) { _ in self.write { transaction in - let thread = try! GroupManager.createGroupForTests(members: [self.aliceRecipient, self.bobRecipient, self.tsAccountManager.localAddress!], + let thread = try! GroupManager.createGroupForTests(members: [self.aliceRecipient, self.bobRecipient, DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)!.aciAddress], name: "Perf", transaction: transaction) diff --git a/Signal/test/util/GRDBFinderTest.swift b/Signal/test/util/GRDBFinderTest.swift index b392abbce4..bea5000097 100644 --- a/Signal/test/util/GRDBFinderTest.swift +++ b/Signal/test/util/GRDBFinderTest.swift @@ -17,7 +17,16 @@ class GRDBFinderTest: SignalBaseTest { // ensure local client has necessary "registered" state let localE164Identifier = "+13235551234" let localUUID = UUID() - tsAccountManager.registerForTests(withLocalNumber: localE164Identifier, uuid: localUUID) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .init( + aci: .init(fromUUID: localUUID), + pni: nil, + e164: E164(localE164Identifier)! + ), + tx: tx.asV2Write + ) + } } func testThreadFinder() { diff --git a/Signal/test/util/UserProfileTest.swift b/Signal/test/util/UserProfileTest.swift index 5e8b3a0f0a..6bb0231561 100644 --- a/Signal/test/util/UserProfileTest.swift +++ b/Signal/test/util/UserProfileTest.swift @@ -12,7 +12,12 @@ class UserProfileTest: SignalBaseTest { override func setUp() { super.setUp() // Create local account. - tsAccountManager.registerForTests(localIdentifiers: .forUnitTests) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .forUnitTests, + tx: tx.asV2Write + ) + } } func testUserProfileForAci() { diff --git a/SignalMessaging/Jobs/IncomingContactSyncJobQueue.swift b/SignalMessaging/Jobs/IncomingContactSyncJobQueue.swift index 1813e2f52d..3121ead84e 100644 --- a/SignalMessaging/Jobs/IncomingContactSyncJobQueue.swift +++ b/SignalMessaging/Jobs/IncomingContactSyncJobQueue.swift @@ -51,7 +51,7 @@ public class IncomingContactSyncJobQueue: NSObject, JobQueue { } public func buildOperation(jobRecord: IncomingContactSyncJobRecord, transaction: SDSAnyReadTransaction) throws -> IncomingContactSyncOperation { - guard let localIdentifiers = tsAccountManager.localIdentifiers(transaction: transaction) else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read) else { throw OWSAssertionError("Not registered.") } return IncomingContactSyncOperation(jobRecord: jobRecord, localIdentifiers: localIdentifiers) diff --git a/SignalMessaging/Notifications/AppNotifications.swift b/SignalMessaging/Notifications/AppNotifications.swift index adf948e82a..8ef470ad30 100644 --- a/SignalMessaging/Notifications/AppNotifications.swift +++ b/SignalMessaging/Notifications/AppNotifications.swift @@ -513,7 +513,7 @@ public class NotificationPresenter: NSObject, NotificationsProtocolSwift { return false } - let localAci = tsAccountManager.localIdentifiers(transaction: transaction)?.aci + let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aci // Always notify for replies to group stories you sent if storyAuthorAci == localAci { return true } @@ -535,7 +535,7 @@ public class NotificationPresenter: NSObject, NotificationsProtocolSwift { guard thread.isGroupThread else { return false } - guard let localAddress = TSAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress else { owsFailDebug("Missing local address") return false } @@ -1166,7 +1166,7 @@ public class NotificationPresenter: NSObject, NotificationsProtocolSwift { // Use a default sound so we don't read from // the db (which doesn't work until we relaunch) sound: .standard(.note), - forceBeforeOnboarded: true, + forceBeforeRegistered: true, completion: { innerCompletion() completion?() diff --git a/SignalMessaging/Notifications/UserNotificationsPresenter.swift b/SignalMessaging/Notifications/UserNotificationsPresenter.swift index d557f94747..4ca795858b 100644 --- a/SignalMessaging/Notifications/UserNotificationsPresenter.swift +++ b/SignalMessaging/Notifications/UserNotificationsPresenter.swift @@ -185,13 +185,13 @@ class UserNotificationPresenter: Dependencies { interaction: INInteraction?, sound: Sound?, replacingIdentifier: String? = nil, - forceBeforeOnboarded: Bool = false, + forceBeforeRegistered: Bool = false, completion: NotificationActionCompletion? ) { dispatchPrecondition(condition: .onQueue(notifyQueue)) - guard forceBeforeOnboarded || tsAccountManager.isOnboarded else { - Logger.info("suppressing notification since user hasn't yet completed onboarding.") + guard forceBeforeRegistered || DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { + Logger.info("suppressing notification since user hasn't yet completed registration.") completion?() return } diff --git a/SignalMessaging/Payments/PaymentsCurrenciesImpl.swift b/SignalMessaging/Payments/PaymentsCurrenciesImpl.swift index 5a9d587d67..cbfe6c59ae 100644 --- a/SignalMessaging/Payments/PaymentsCurrenciesImpl.swift +++ b/SignalMessaging/Payments/PaymentsCurrenciesImpl.swift @@ -166,9 +166,11 @@ public class PaymentsCurrenciesImpl: NSObject, PaymentsCurrenciesSwift, Payments private let isUpdateInFlight = AtomicBool(false) func updateConversationRates() { - guard AppReadiness.isAppReady, - CurrentAppContext().isMainAppAndActive, - Self.tsAccountManager.isRegisteredAndReady else { + guard + AppReadiness.isAppReady, + CurrentAppContext().isMainAppAndActive, + DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered + else { return } guard Self.paymentsHelper.arePaymentsEnabled else { diff --git a/SignalMessaging/Payments/PaymentsHelperImpl.swift b/SignalMessaging/Payments/PaymentsHelperImpl.swift index f7a11e61ba..7c46c8ee2d 100644 --- a/SignalMessaging/Payments/PaymentsHelperImpl.swift +++ b/SignalMessaging/Payments/PaymentsHelperImpl.swift @@ -31,10 +31,10 @@ public class PaymentsHelperImpl: Dependencies, PaymentsHelperSwift, PaymentsHelp } public var hasValidPhoneNumberForPayments: Bool { - guard Self.tsAccountManager.isRegisteredAndReady else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return false } - guard let localNumber = Self.tsAccountManager.localNumber else { + guard let localNumber = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber else { return false } let paymentsDisabledRegions = RemoteConfig.paymentsDisabledRegions @@ -203,7 +203,7 @@ public class PaymentsHelperImpl: Dependencies, PaymentsHelperSwift, PaymentsHelp paymentsEvents.updateLastKnownLocalPaymentAddressProtoData(transaction: transaction) - let localAci = self.tsAccountManager.localIdentifiers(transaction: transaction)?.aci + let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aci TSPaymentsActivationRequestModel .allThreadsWithPaymentActivationRequests(transaction: transaction) .forEach { thread in @@ -248,7 +248,7 @@ public class PaymentsHelperImpl: Dependencies, PaymentsHelperSwift, PaymentsHelp } private static func loadPaymentsState(transaction: SDSAnyReadTransaction) -> PaymentsState { - guard tsAccountManager.isRegisteredAndReady(transaction: transaction) else { + guard DependenciesBridge.shared.tsAccountManager.registrationState(tx: transaction.asV2Read).isRegistered else { return .disabled } let paymentsEntropy = keyValueStore.getData(paymentsEntropyKey, transaction: transaction) @@ -344,7 +344,7 @@ public class PaymentsHelperImpl: Dependencies, PaymentsHelperSwift, PaymentsHelp if Self.loadPaymentsState(transaction: transaction).isEnabled { - if self.tsAccountManager.isPrimaryDevice(transaction: transaction) { + if DependenciesBridge.shared.tsAccountManager.registrationState(tx: transaction.asV2Read).isPrimaryDevice ?? false { let message = OWSPaymentActivationRequestFinishedMessage(thread: thread, transaction: transaction) Self.sskJobQueues.messageSenderJobQueue.add(message: message.asPreparer, transaction: transaction) } @@ -506,7 +506,7 @@ public class PaymentsHelperImpl: Dependencies, PaymentsHelperSwift, PaymentsHelp if paymentType == .outgoingPaymentFromLinkedDevice, let recipientAci, - recipientAci != tsAccountManager.localIdentifiers(transaction: transaction)?.aci + recipientAci != DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aci { let thread = TSContactThread.getOrCreateThread( withContactAddress: SignalServiceAddress(recipientAci), diff --git a/SignalMessaging/Storage Service/StorageServiceManagerImpl.swift b/SignalMessaging/Storage Service/StorageServiceManagerImpl.swift index c87be95a07..53a2ccc985 100644 --- a/SignalMessaging/Storage Service/StorageServiceManagerImpl.swift +++ b/SignalMessaging/Storage Service/StorageServiceManagerImpl.swift @@ -42,7 +42,7 @@ public class StorageServiceManagerImpl: NSObject, StorageServiceManager { } AppReadiness.runNowOrWhenMainAppDidBecomeReadyAsync { - guard self.tsAccountManager.isRegisteredAndReady else { return } + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return } // Schedule a restore. This will do nothing unless we've never // registered a manifest before. @@ -219,7 +219,7 @@ public class StorageServiceManagerImpl: NSObject, StorageServiceManager { case .implicit: // Under the new reg flow, we will sync kbs keys before being fully ready with // ts account manager auth set up. skip if so. - guard tsAccountManager.isRegisteredAndReady else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegisteredOrFinishingProvisioning else { Logger.info("Skipping storage service operation with implicit auth during registration.") return nil } @@ -721,7 +721,7 @@ class StorageServiceOperation: OWSOperation { let identifiers = StorageService.StorageIdentifier.deduplicate(identifiersParam) var manifestBuilder = StorageServiceProtoManifestRecord.builder(version: manifestVersion) manifestBuilder.setKeys(try identifiers.map { try $0.buildRecord() }) - manifestBuilder.setSourceDevice(tsAccountManager.storedDeviceId) + manifestBuilder.setSourceDevice(DependenciesBridge.shared.tsAccountManager.storedDeviceIdWithMaybeTransaction) return try manifestBuilder.build() } @@ -762,7 +762,7 @@ class StorageServiceOperation: OWSOperation { if case .manifestDecryptionFailed(let previousManifestVersion) = storageError { // If this is the primary device, throw everything away and re-encrypt // the social graph with the keys we have locally. - if TSAccountManager.shared.isPrimaryDevice { + if DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegisteredPrimaryDevice { Logger.info("Manifest decryption failed, recreating manifest.") return self.createNewManifest(version: previousManifestVersion + 1) } @@ -783,7 +783,7 @@ class StorageServiceOperation: OWSOperation { } } else if case .manifestProtoDeserializationFailed(let previousManifestVersion) = storageError, - TSAccountManager.shared.isPrimaryDevice + DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegisteredPrimaryDevice { // If decryption succeeded but proto deserialization failed, we somehow ended up with // byte garbage in storage service. Our only recourse is to throw everything away and @@ -1139,7 +1139,7 @@ class StorageServiceOperation: OWSOperation { if case .itemDecryptionFailed = storageError { // If this is the primary device, throw everything away and re-encrypt // the social graph with the keys we have locally. - if TSAccountManager.shared.isPrimaryDevice { + if DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegisteredPrimaryDevice { Logger.info("Item decryption failed, recreating manifest.") return self.createNewManifest(version: manifest.version + 1) } @@ -1160,7 +1160,7 @@ class StorageServiceOperation: OWSOperation { } } else if case .itemProtoDeserializationFailed = storageError, - TSAccountManager.shared.isPrimaryDevice + DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegisteredPrimaryDevice { // If decryption succeeded but proto deserialization failed, we somehow ended up with // byte garbage in storage service. Our only recourse is to throw everything away and @@ -1439,13 +1439,15 @@ class StorageServiceOperation: OWSOperation { legacyChangePhoneNumber: legacyChangePhoneNumber, localUsernameManager: DependenciesBridge.shared.localUsernameManager, paymentsHelper: paymentsHelperSwift, + phoneNumberDiscoverabilityManager: DependenciesBridge.shared.phoneNumberDiscoverabilityManager, preferences: preferences, profileManager: profileManagerImpl, receiptManager: receiptManager, + registrationStateChangeManager: DependenciesBridge.shared.registrationStateChangeManager, storageServiceManager: storageServiceManager, subscriptionManager: subscriptionManager, systemStoryManager: systemStoryManager, - tsAccountManager: tsAccountManager, + tsAccountManager: DependenciesBridge.shared.tsAccountManager, typingIndicators: typingIndicatorsImpl, udManager: udManager, usernameEducationManager: DependenciesBridge.shared.usernameEducationManager @@ -1466,7 +1468,7 @@ class StorageServiceOperation: OWSOperation { contactsManager: contactsManagerImpl, identityManager: DependenciesBridge.shared.identityManager, profileManager: profileManagerImpl, - tsAccountManager: tsAccountManager, + tsAccountManager: DependenciesBridge.shared.tsAccountManager, usernameLookupManager: DependenciesBridge.shared.usernameLookupManager, recipientMerger: DependenciesBridge.shared.recipientMerger, recipientHidingManager: DependenciesBridge.shared.recipientHidingManager diff --git a/SignalMessaging/Storage Service/StorageServiceProto+Sync.swift b/SignalMessaging/Storage Service/StorageServiceProto+Sync.swift index 505279e048..e0e7130e44 100644 --- a/SignalMessaging/Storage Service/StorageServiceProto+Sync.swift +++ b/SignalMessaging/Storage Service/StorageServiceProto+Sync.swift @@ -175,7 +175,7 @@ class StorageServiceContactRecordUpdater: StorageServiceRecordUpdater { private let contactsManager: OWSContactsManager private let identityManager: OWSIdentityManager private let profileManager: OWSProfileManager - private let tsAccountManager: TSAccountManager + private let tsAccountManager: TSAccountManagerProtocol private let usernameLookupManager: UsernameLookupManager private let recipientMerger: RecipientMerger private let recipientHidingManager: RecipientHidingManager @@ -188,7 +188,7 @@ class StorageServiceContactRecordUpdater: StorageServiceRecordUpdater { contactsManager: OWSContactsManager, identityManager: OWSIdentityManager, profileManager: OWSProfileManager, - tsAccountManager: TSAccountManager, + tsAccountManager: TSAccountManagerProtocol, usernameLookupManager: UsernameLookupManager, recipientMerger: RecipientMerger, recipientHidingManager: RecipientHidingManager @@ -296,8 +296,9 @@ class StorageServiceContactRecordUpdater: StorageServiceRecordUpdater { // case, we want to preserve the name the primary device // originally uploaded. - let isPrimaryAndHasLocalContact = tsAccountManager.isPrimaryDevice && contact.isFromLocalAddressBook - let isLinkedAndHasSyncedContact = !tsAccountManager.isPrimaryDevice && !contact.isFromLocalAddressBook + let isPrimary = tsAccountManager.registrationState(tx: transaction.asV2Read).isPrimaryDevice ?? false + let isPrimaryAndHasLocalContact = isPrimary && contact.isFromLocalAddressBook + let isLinkedAndHasSyncedContact = !isPrimary && !contact.isFromLocalAddressBook if isPrimaryAndHasLocalContact || isLinkedAndHasSyncedContact { if let systemGivenName = contact.firstName { @@ -566,7 +567,7 @@ class StorageServiceContactRecordUpdater: StorageServiceRecordUpdater { let localAccount = contactsManager.fetchSignalAccount(for: address, transaction: transaction) - if tsAccountManager.isPrimaryDevice { + if tsAccountManager.registrationState(tx: transaction.asV2Read).isPrimaryDevice ?? false { let localContact = localAccount?.contact?.isFromLocalAddressBook == true ? localAccount?.contact : nil let localSystemGivenName = localContact?.firstName?.nilIfEmpty let localSystemFamilyName = localContact?.lastName?.nilIfEmpty @@ -918,13 +919,15 @@ class StorageServiceAccountRecordUpdater: StorageServiceRecordUpdater { private let legacyChangePhoneNumber: LegacyChangePhoneNumber private let localUsernameManager: LocalUsernameManager private let paymentsHelper: PaymentsHelperSwift + private let phoneNumberDiscoverabilityManager: PhoneNumberDiscoverabilityManager private let preferences: Preferences private let profileManager: OWSProfileManager private let receiptManager: OWSReceiptManager + private let registrationStateChangeManager: RegistrationStateChangeManager private let storageServiceManager: StorageServiceManager private let subscriptionManager: SubscriptionManager private let systemStoryManager: SystemStoryManagerProtocol - private let tsAccountManager: TSAccountManager + private let tsAccountManager: TSAccountManagerProtocol private let typingIndicators: TypingIndicators private let udManager: OWSUDManager private let usernameEducationManager: UsernameEducationManager @@ -936,13 +939,15 @@ class StorageServiceAccountRecordUpdater: StorageServiceRecordUpdater { legacyChangePhoneNumber: LegacyChangePhoneNumber, localUsernameManager: LocalUsernameManager, paymentsHelper: PaymentsHelperSwift, + phoneNumberDiscoverabilityManager: PhoneNumberDiscoverabilityManager, preferences: Preferences, profileManager: OWSProfileManager, receiptManager: OWSReceiptManager, + registrationStateChangeManager: RegistrationStateChangeManager, storageServiceManager: StorageServiceManager, subscriptionManager: SubscriptionManager, systemStoryManager: SystemStoryManagerProtocol, - tsAccountManager: TSAccountManager, + tsAccountManager: TSAccountManagerProtocol, typingIndicators: TypingIndicators, udManager: OWSUDManager, usernameEducationManager: UsernameEducationManager @@ -953,9 +958,11 @@ class StorageServiceAccountRecordUpdater: StorageServiceRecordUpdater { self.legacyChangePhoneNumber = legacyChangePhoneNumber self.localUsernameManager = localUsernameManager self.paymentsHelper = paymentsHelper + self.phoneNumberDiscoverabilityManager = phoneNumberDiscoverabilityManager self.preferences = preferences self.profileManager = profileManager self.receiptManager = receiptManager + self.registrationStateChangeManager = registrationStateChangeManager self.storageServiceManager = storageServiceManager self.subscriptionManager = subscriptionManager self.systemStoryManager = systemStoryManager @@ -1050,7 +1057,7 @@ class StorageServiceAccountRecordUpdater: StorageServiceRecordUpdater { let phoneNumberSharingMode = udManager.phoneNumberSharingMode(tx: transaction) builder.setPhoneNumberSharingMode(phoneNumberSharingMode.asProtoMode) - let notDiscoverableByPhoneNumber = !tsAccountManager.isDiscoverableByPhoneNumber(with: transaction) + let notDiscoverableByPhoneNumber = !tsAccountManager.isDiscoverableByPhoneNumber(tx: transaction.asV2Read) builder.setNotDiscoverableByPhoneNumber(notDiscoverableByPhoneNumber) let pinnedConversationProtos = PinnedThreadManager.pinnedConversationProtos(transaction: transaction) @@ -1140,7 +1147,8 @@ class StorageServiceAccountRecordUpdater: StorageServiceRecordUpdater { // allows us to restore your profile during onboarding, // but ensures no other device can ever change the profile // key other than the primary device. - let allowsRemoteProfileKeyChanges = !profileManager.hasLocalProfile() || !tsAccountManager.isPrimaryDevice + let isPrimary = tsAccountManager.registrationState(tx: transaction.asV2Read).isPrimaryDevice ?? false + let allowsRemoteProfileKeyChanges = !profileManager.hasLocalProfile() || !isPrimary if allowsRemoteProfileKeyChanges, let profileKey = record.profileKey, localProfileKey?.keyData != profileKey { profileManager.setProfileKeyData( profileKey, @@ -1257,13 +1265,13 @@ class StorageServiceAccountRecordUpdater: StorageServiceRecordUpdater { } } - let localNotDiscoverableByPhoneNumber = !tsAccountManager.isDiscoverableByPhoneNumber(with: transaction) - if record.notDiscoverableByPhoneNumber != localNotDiscoverableByPhoneNumber || !tsAccountManager.hasDefinedIsDiscoverableByPhoneNumber(with: transaction) { - tsAccountManager.setIsDiscoverableByPhoneNumber( + let localNotDiscoverableByPhoneNumber = !tsAccountManager.isDiscoverableByPhoneNumber(tx: transaction.asV2Read) + if record.notDiscoverableByPhoneNumber != localNotDiscoverableByPhoneNumber || !tsAccountManager.hasDefinedIsDiscoverableByPhoneNumber(tx: transaction.asV2Read) { + phoneNumberDiscoverabilityManager.setIsDiscoverableByPhoneNumber( !record.notDiscoverableByPhoneNumber, updateStorageService: false, authedAccount: authedAccount, - transaction: transaction + tx: transaction.asV2Write ) } @@ -1368,7 +1376,7 @@ class StorageServiceAccountRecordUpdater: StorageServiceRecordUpdater { if localAddress.e164 != serviceLocalE164 { Logger.warn("localAddress.e164: \(String(describing: localAddress.e164)) != serviceLocalE164: \(serviceLocalE164)") - if tsAccountManager.isPrimaryDevice(transaction: transaction) { + if tsAccountManager.registrationState(tx: transaction.asV2Read).isPrimaryDevice ?? false { // It's not clear how we got into this scenario, but if we // do it's bad. Once all clients are PNI-capable we can // ignore the AccountRecord's e164 entirely, and remove @@ -1389,14 +1397,14 @@ class StorageServiceAccountRecordUpdater: StorageServiceRecordUpdater { // the primary needs to update the storage service. self.storageServiceManager.recordPendingLocalAccountUpdates() } - } else if let localIdentifiers = tsAccountManager.localIdentifiers(transaction: transaction) { + } else if let localIdentifiers = tsAccountManager.localIdentifiers(tx: transaction.asV2Read) { // If we're a linked device, we should always take the e164 // from StorageService. - tsAccountManager.updateLocalPhoneNumber( - E164ObjC(serviceLocalE164), - aci: AciObjC(localIdentifiers.aci), - pni: localIdentifiers.pni.map { PniObjC($0) }, - transaction: transaction + registrationStateChangeManager.didUpdateLocalPhoneNumber( + serviceLocalE164, + aci: localIdentifiers.aci, + pni: localIdentifiers.pni, + tx: transaction.asV2Write ) } else { owsFailDebug("Linked device missing local ACI!") diff --git a/SignalMessaging/Subscriptions/SubscriptionManagerImpl.swift b/SignalMessaging/Subscriptions/SubscriptionManagerImpl.swift index 2e9299d89e..2f3a0a2321 100644 --- a/SignalMessaging/Subscriptions/SubscriptionManagerImpl.swift +++ b/SignalMessaging/Subscriptions/SubscriptionManagerImpl.swift @@ -743,7 +743,7 @@ public class SubscriptionManagerImpl: NSObject { Logger.info("[Donations] Performing subscription heartbeat") - guard tsAccountManager.isPrimaryDevice else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isPrimaryDevice ?? false else { Logger.info("[Donations] Bailing out of remaining heartbeat tasks, this is not the primary device") return } diff --git a/SignalMessaging/contacts/OWSContactsManager.m b/SignalMessaging/contacts/OWSContactsManager.m index 9c0a816ff6..31519dd58b 100644 --- a/SignalMessaging/contacts/OWSContactsManager.m +++ b/SignalMessaging/contacts/OWSContactsManager.m @@ -86,7 +86,7 @@ NSString *const OWSContactsManagerCollection = @"OWSContactsManagerCollection"; - (BOOL)isEditingAllowed { - return self.tsAccountManager.isPrimaryDevice; + return [TSAccountManagerObjcBridge isPrimaryDeviceWithMaybeTransaction]; } - (ContactAuthorizationForEditing)editingAuthorization diff --git a/SignalMessaging/contacts/OWSContactsManager.swift b/SignalMessaging/contacts/OWSContactsManager.swift index 48e556aef4..7b9555a95a 100644 --- a/SignalMessaging/contacts/OWSContactsManager.swift +++ b/SignalMessaging/contacts/OWSContactsManager.swift @@ -193,7 +193,7 @@ private extension OWSContactsManager { return cachedValue } let result: Bool = { - guard let localAddress = tsAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress else { owsFailDebug("Missing localAddress.") return false } @@ -768,7 +768,7 @@ extension OWSContactsManager { allSignalAccountsBeforeFetch: [SignalServiceAddress: SignalAccount], allSignalAccountsAfterFetch: [SignalServiceAddress: SignalAccount] ) { - guard tsAccountManager.isPrimaryDevice else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isPrimaryDevice ?? false else { Logger.info("Skipping updating StorageService on contact change, not primary device!") return } @@ -862,7 +862,7 @@ extension OWSContactsManager { private func _updateContacts(_ addressBookContacts: [Contact]?, isUserRequested: Bool) { let (localNumber, contactsMaps) = databaseStorage.write { tx in - let localNumber = tsAccountManager.localNumber(with: tx) + let localNumber = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read)?.phoneNumber let contactsMaps = ContactsMaps.build(contacts: addressBookContacts ?? [], localNumber: localNumber) setContactsMaps(contactsMaps, localNumber: localNumber, transaction: tx) return (localNumber, contactsMaps) @@ -1185,12 +1185,13 @@ extension OWSContactsManager { } private func updateSystemContactsDataProvider(forcePrimary: Bool = false) { + let tsRegistrationState = DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction let dataProvider: SystemContactsDataProvider? if forcePrimary { dataProvider = PrimaryDeviceSystemContactsDataProvider() - } else if !tsAccountManager.isRegistered { + } else if !tsRegistrationState.isRegistered { dataProvider = nil - } else if tsAccountManager.isPrimaryDevice { + } else if tsRegistrationState.isPrimaryDevice ?? true { dataProvider = PrimaryDeviceSystemContactsDataProvider() } else { dataProvider = LinkedDeviceSystemContactsDataProvider() @@ -1237,7 +1238,7 @@ extension OWSContactsManager { transaction: SDSAnyReadTransaction ) -> ContactsMaps { let systemContacts = dataProvider.fetchAllSystemContacts(transaction: transaction) - let localNumber = tsAccountManager.localNumber(with: transaction) + let localNumber = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.phoneNumber return ContactsMaps.build(contacts: systemContacts, localNumber: localNumber) } @@ -1274,7 +1275,7 @@ extension OWSContactsManager { owsFailDebug("Can't access contacts until registration is finished.") return [] } - let localNumber = tsAccountManager.localNumber(with: transaction) + let localNumber = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.phoneNumber return dataProvider.fetchAllSystemContacts(transaction: transaction) .filter { !$0.hasPhoneNumber(localNumber) } } diff --git a/SignalMessaging/contacts/OWSSyncManager.m b/SignalMessaging/contacts/OWSSyncManager.m index 5643f0a6a5..2d9b9ea1a2 100644 --- a/SignalMessaging/contacts/OWSSyncManager.m +++ b/SignalMessaging/contacts/OWSSyncManager.m @@ -61,11 +61,11 @@ NSString *const OWSSyncManagerSyncRequestedAppVersionKey = @"SyncRequestedAppVer AppReadinessRunNowOrWhenMainAppDidBecomeReadyAsync(^{ [self addObservers]; - - if ([self.tsAccountManager isRegisteredAndReady]) { + + if ([TSAccountManagerObjcBridge isRegisteredWithMaybeTransaction]) { OWSAssertDebug(self.contactsManagerImpl.isSetup); - if (self.tsAccountManager.isPrimaryDevice) { + if ([TSAccountManagerObjcBridge isPrimaryDeviceWithMaybeTransaction]) { // Flush any pending changes. // // sendSyncContactsMessageIfNecessary will skipIfRedundant, @@ -141,10 +141,7 @@ NSString *const OWSSyncManagerSyncRequestedAppVersionKey = @"SyncRequestedAppVer // Don't bother if the contacts manager hasn't finished setup. return NO; } - if (!self.tsAccountManager.isRegisteredAndReady) { - return NO; - } - if (!self.tsAccountManager.isRegisteredPrimaryDevice) { + if (![TSAccountManagerObjcBridge isRegisteredPrimaryDeviceWithMaybeTransaction]) { return NO; } return YES; @@ -152,7 +149,7 @@ NSString *const OWSSyncManagerSyncRequestedAppVersionKey = @"SyncRequestedAppVer - (void)sendConfigurationSyncMessage { AppReadinessRunNowOrWhenAppDidBecomeReadyAsync(^{ - if (!self.tsAccountManager.isRegisteredAndReady) { + if (![TSAccountManagerObjcBridge isRegisteredWithMaybeTransaction]) { return; } @@ -165,7 +162,7 @@ NSString *const OWSSyncManagerSyncRequestedAppVersionKey = @"SyncRequestedAppVer - (void)sendConfigurationSyncMessage_AppReady { OWSLogInfo(@""); - if (!self.tsAccountManager.isRegisteredAndReady) { + if (![TSAccountManagerObjcBridge isRegisteredWithMaybeTransaction]) { return; } @@ -329,7 +326,8 @@ typedef NS_ENUM(NSUInteger, OWSContactSyncMode) { } // This might create a transaction -- call it outside of our own transaction. - SignalServiceAddress *const localAddress = self.tsAccountManager.localAddress; + SignalServiceAddress *const localAddress = + [TSAccountManagerObjcBridge localAciAddressWithMaybeTransaction]; __block NSString *fullSyncRequestId; __block BOOL fullSyncRequired = YES; @@ -516,7 +514,7 @@ typedef NS_ENUM(NSUInteger, OWSContactSyncMode) { { OWSLogInfo(@""); - if (!self.tsAccountManager.isRegisteredAndReady) { + if (![TSAccountManagerObjcBridge isRegisteredWithMaybeTransaction]) { OWSFailDebug(@"Unexpectedly tried to send sync message before registration."); return; } diff --git a/SignalMessaging/contacts/OWSSyncManager.swift b/SignalMessaging/contacts/OWSSyncManager.swift index 251962ec1a..984ebeacbb 100644 --- a/SignalMessaging/contacts/OWSSyncManager.swift +++ b/SignalMessaging/contacts/OWSSyncManager.swift @@ -23,7 +23,7 @@ extension OWSSyncManager: SyncManagerProtocol, SyncManagerProtocolSwift { } private func _sendAllSyncRequestMessages(onlyIfNecessary: Bool) -> Promise { - guard tsAccountManager.isRegisteredAndReady else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return Promise(error: OWSAssertionError("Unexpectedly tried to send sync request before registration.")) } @@ -65,11 +65,11 @@ extension OWSSyncManager: SyncManagerProtocol, SyncManagerProtocolSwift { public func sendKeysSyncMessage() { Logger.info("") - guard tsAccountManager.isRegisteredAndReady else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return owsFailDebug("Unexpectedly tried to send sync request before registration.") } - guard tsAccountManager.isRegisteredPrimaryDevice else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isPrimaryDevice ?? false else { return owsFailDebug("Keys sync should only be initiated from the primary device") } @@ -92,7 +92,7 @@ extension OWSSyncManager: SyncManagerProtocol, SyncManagerProtocolSwift { @objc public func processIncomingKeysSyncMessage(_ syncMessage: SSKProtoSyncMessageKeys, transaction: SDSAnyWriteTransaction) { - guard !tsAccountManager.isRegisteredPrimaryDevice else { + guard !DependenciesBridge.shared.tsAccountManager.registrationState(tx: transaction.asV2Read).isRegisteredPrimaryDevice else { return owsFailDebug("Key sync messages should only be processed on linked devices") } @@ -161,7 +161,7 @@ extension OWSSyncManager: SyncManagerProtocol, SyncManagerProtocolSwift { public func sendMessageRequestResponseSyncMessage(thread: TSThread, responseType: OWSSyncMessageRequestResponseType) { Logger.info("") - guard tsAccountManager.isRegisteredAndReady else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return owsFailDebug("Unexpectedly tried to send sync message before registration.") } @@ -177,7 +177,7 @@ extension OWSSyncManager: SyncManagerProtocol, SyncManagerProtocolSwift { ) { Logger.info("") - guard tsAccountManager.isRegisteredAndReady else { + guard DependenciesBridge.shared.tsAccountManager.registrationState(tx: transaction.asV2Read).isRegistered else { return owsFailDebug("Unexpectedly tried to send sync message before registration.") } @@ -192,7 +192,7 @@ public extension OWSSyncManager { func sendInitialSyncRequestsAwaitingCreatedThreadOrdering(timeoutSeconds: TimeInterval) -> Promise<[String]> { Logger.info("") - guard tsAccountManager.isRegisteredAndReady else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return Promise(error: OWSAssertionError("Unexpectedly tried to send sync request before registration.")) } @@ -238,11 +238,11 @@ public extension OWSSyncManager { Logger.info("keys") } - guard tsAccountManager.isRegisteredAndReady else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return owsFailDebug("Unexpectedly tried to send sync request before registration.") } - guard !tsAccountManager.isRegisteredPrimaryDevice else { + guard !DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegisteredPrimaryDevice else { return owsFailDebug("Sync request should only be sent from a linked device") } diff --git a/SignalMessaging/environment/AppSetup.swift b/SignalMessaging/environment/AppSetup.swift index 44c73101a9..5ca3df65dc 100644 --- a/SignalMessaging/environment/AppSetup.swift +++ b/SignalMessaging/environment/AppSetup.swift @@ -112,7 +112,7 @@ public class AppSetup { // MARK: SSK environment properties - let appExpiry = DependenciesBridge.shared.appExpiry + let appExpiry = dependenciesBridge.appExpiry let contactsManager = OWSContactsManager(swiftValues: .makeWithValuesFromDependenciesBridge()) let linkPreviewManager = OWSLinkPreviewManager() let pendingReceiptRecorder = MessageRequestPendingReceipts() @@ -121,8 +121,8 @@ public class AppSetup { let remoteConfigManager = ServiceRemoteConfigManager( appExpiry: appExpiry, db: DependenciesBridge.shared.db, - keyValueStoreFactory: DependenciesBridge.shared.keyValueStoreFactory, - tsAccountManager: tsAccountManager, + keyValueStoreFactory: dependenciesBridge.keyValueStoreFactory, + tsAccountManager: dependenciesBridge.tsAccountManager, serviceClient: SignalServiceRestClient.shared ) let messageDecrypter = OWSMessageDecrypter() @@ -140,7 +140,7 @@ public class AppSetup { let bulkProfileFetch = BulkProfileFetch( databaseStorage: databaseStorage, reachabilityManager: reachabilityManager, - tsAccountManager: tsAccountManager + tsAccountManager: dependenciesBridge.tsAccountManager ) let earlyMessageManager = EarlyMessageManager() let messagePipelineSupervisor = MessagePipelineSupervisor() @@ -157,7 +157,7 @@ public class AppSetup { recipientFetcher: dependenciesBridge.recipientFetcher, recipientMerger: dependenciesBridge.recipientMerger, recipientStore: dependenciesBridge.recipientStore, - tsAccountManager: tsAccountManager, + tsAccountManager: dependenciesBridge.tsAccountManager, udManager: udManager, websocketFactory: webSocketFactory ) diff --git a/SignalMessaging/groups/GroupV2UpdatesImpl.swift b/SignalMessaging/groups/GroupV2UpdatesImpl.swift index fafd77a50c..d040baac61 100644 --- a/SignalMessaging/groups/GroupV2UpdatesImpl.swift +++ b/SignalMessaging/groups/GroupV2UpdatesImpl.swift @@ -43,7 +43,7 @@ public class GroupV2UpdatesImpl: Dependencies { // On launch, we refresh a few randomly-selected groups. private func autoRefreshGroupOnLaunch() { guard CurrentAppContext().isMainApp, - tsAccountManager.isRegisteredAndReady, + DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered, reachabilityManager.isReachable, !CurrentAppContext().isRunningTests else { return @@ -166,7 +166,7 @@ extension GroupV2UpdatesImpl: GroupV2UpdatesSwift { guard groupThread.groupModel.groupsVersion == .V2 else { throw OWSAssertionError("Invalid groupsVersion.") } - guard let localIdentifiers = tsAccountManager.localIdentifiers(transaction: transaction) else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read) else { throw OWSAssertionError("Not registered.") } let changedGroupModel = try GroupsV2IncomingChanges.applyChangesToGroupModel( @@ -637,7 +637,7 @@ private extension GroupV2UpdatesImpl { groupModelOptions: TSGroupModelOptions ) -> Promise { return databaseStorage.write(.promise) { (transaction: SDSAnyWriteTransaction) throws -> TSGroupThread in - guard let localIdentifiers = Self.tsAccountManager.localIdentifiers(transaction: transaction) else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read) else { throw OWSAssertionError("Missing localIdentifiers.") } @@ -1020,7 +1020,7 @@ private extension GroupV2UpdatesImpl { let localProfileKey = profileManager.localProfileKey() return databaseStorage.write(.promise) { (transaction: SDSAnyWriteTransaction) throws -> TSGroupThread in - guard let localIdentifiers = Self.tsAccountManager.localIdentifiers(transaction: transaction) else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read) else { throw OWSAssertionError("Missing localIdentifiers.") } let localAci = localIdentifiers.aci diff --git a/SignalMessaging/groups/GroupsV2Impl+RestoreGroups.swift b/SignalMessaging/groups/GroupsV2Impl+RestoreGroups.swift index c8e65acc4e..1941e371dc 100644 --- a/SignalMessaging/groups/GroupsV2Impl+RestoreGroups.swift +++ b/SignalMessaging/groups/GroupsV2Impl+RestoreGroups.swift @@ -111,7 +111,7 @@ public extension GroupsV2Impl { case .explicit: break case .implicit: - guard tsAccountManager.isRegisteredAndReady else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return false } } diff --git a/SignalMessaging/groups/GroupsV2Impl.swift b/SignalMessaging/groups/GroupsV2Impl.swift index 2e42810bcb..34b6e9d892 100644 --- a/SignalMessaging/groups/GroupsV2Impl.swift +++ b/SignalMessaging/groups/GroupsV2Impl.swift @@ -23,7 +23,7 @@ public class GroupsV2Impl: GroupsV2Swift, GroupsV2, Dependencies { // if we've just reset the zkgroup state, since that // have the same effect. guard !didReset, - self.tsAccountManager.isRegisteredAndReady else { + DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return } @@ -81,7 +81,7 @@ public class GroupsV2Impl: GroupsV2Swift, GroupsV2, Dependencies { self.serviceStore.setInt(zkgroupVersionCounter, key: lastZKgroupVersionCounterKey, transaction: transaction) } AppReadiness.runNowOrWhenAppDidBecomeReadyAsync { - if self.tsAccountManager.isRegisteredAndReady { + if DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered { Logger.info("Re-uploading local profile due to zkgroup update.") firstly { self.reuploadLocalProfilePromise() @@ -205,7 +205,7 @@ public class GroupsV2Impl: GroupsV2Swift, GroupsV2, Dependencies { groupV2Params: GroupV2Params, shouldForceRefreshProfileKeyCredentials: Bool = false ) -> Promise { - guard let localAci = tsAccountManager.localIdentifiers?.aci else { + guard let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aci else { return Promise(error: OWSAssertionError("Missing localAci.")) } @@ -1084,7 +1084,7 @@ public class GroupsV2Impl: GroupsV2Swift, GroupsV2, Dependencies { behavior404: Behavior404, remainingRetries: UInt = 3 ) -> Promise { - guard let localIdentifiers = tsAccountManager.localIdentifiers else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction else { return Promise(error: OWSAssertionError("Missing localIdentifiers.")) } @@ -1932,7 +1932,7 @@ public class GroupsV2Impl: GroupsV2Swift, GroupsV2, Dependencies { self.groupV2Updates.tryToRefreshV2GroupUpToCurrentRevisionImmediately(groupId: groupId, groupSecretParamsData: groupV2Params.groupSecretParamsData) }.then(on: DispatchQueue.global()) { (groupThread: TSGroupThread) -> Promise in - guard let localAci = self.tsAccountManager.localIdentifiers?.aci else { + guard let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aci else { throw OWSAssertionError("Missing localAci.") } guard let groupModelV2 = groupThread.groupModel as? TSGroupModelV2 else { @@ -2069,7 +2069,7 @@ public class GroupsV2Impl: GroupsV2Swift, GroupsV2, Dependencies { throw OWSAssertionError("Missing revisionForPlaceholderModel.") } return try databaseStorage.write { (transaction) throws -> TSGroupThread in - guard let localIdentifiers = Self.tsAccountManager.localIdentifiers(transaction: transaction) else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read) else { throw OWSAssertionError("Missing localIdentifiers.") } @@ -2168,7 +2168,7 @@ public class GroupsV2Impl: GroupsV2Swift, GroupsV2, Dependencies { groupV2Params: GroupV2Params, revisionForPlaceholderModel: AtomicOptional) -> Promise { - guard let localAci = self.tsAccountManager.localIdentifiers?.aci else { + guard let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aci else { return Promise(error: OWSAssertionError("Missing localAci.")) } @@ -2261,7 +2261,7 @@ public class GroupsV2Impl: GroupsV2Swift, GroupsV2, Dependencies { newRevision proposedRevision: UInt32? ) throws -> TSGroupThread { return try databaseStorage.write { transaction -> TSGroupThread in - guard let localIdentifiers = self.tsAccountManager.localIdentifiers(transaction: transaction) else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read) else { throw OWSAssertionError("Missing localIdentifiers.") } TSGroupThread.ensureGroupIdMapping(forGroupId: groupId, transaction: transaction) @@ -2362,7 +2362,7 @@ public class GroupsV2Impl: GroupsV2Swift, GroupsV2, Dependencies { revisionForPlaceholderModel: AtomicOptional) -> Promise { return firstly(on: DispatchQueue.global()) { () -> GroupsProtoGroupChangeActions in - guard let localAci = self.tsAccountManager.localIdentifiers?.aci else { + guard let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aci else { throw OWSAssertionError("Missing localAci.") } let oldRevision = groupInviteLinkPreview.revision @@ -2417,7 +2417,7 @@ public class GroupsV2Impl: GroupsV2Swift, GroupsV2, Dependencies { firstly(on: DispatchQueue.global()) { let groupId = try self.groupId(forGroupSecretParamsData: groupSecretParamsData) try self.databaseStorage.write { transaction in - guard let localIdentifiers = self.tsAccountManager.localIdentifiers(transaction: transaction) else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read) else { throw OWSAssertionError("Missing localIdentifiers.") } TSGroupThread.ensureGroupIdMapping(forGroupId: groupId, transaction: transaction) diff --git a/SignalMessaging/groups/GroupsV2OutgoingChangesImpl.swift b/SignalMessaging/groups/GroupsV2OutgoingChangesImpl.swift index 5adc06372a..7ad81f0af0 100644 --- a/SignalMessaging/groups/GroupsV2OutgoingChangesImpl.swift +++ b/SignalMessaging/groups/GroupsV2OutgoingChangesImpl.swift @@ -246,7 +246,7 @@ public class GroupsV2OutgoingChangesImpl: Dependencies, GroupsV2OutgoingChanges guard groupId == currentGroupModel.groupId else { return Promise(error: OWSAssertionError("Mismatched groupId.")) } - guard let localAci = tsAccountManager.localIdentifiers?.aci else { + guard let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aci else { return Promise(error: OWSAssertionError("Missing localAci.")) } @@ -319,7 +319,7 @@ public class GroupsV2OutgoingChangesImpl: Dependencies, GroupsV2OutgoingChanges let groupV2Params = try currentGroupModel.groupV2Params() var actionsBuilder = GroupsProtoGroupChangeActions.builder() - guard let localIdentifiers = tsAccountManager.localIdentifiers else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction else { throw OWSAssertionError("Missing local identifiers!") } diff --git a/SignalMessaging/groups/GroupsV2ProfileKeyUpdater.swift b/SignalMessaging/groups/GroupsV2ProfileKeyUpdater.swift index 65c4771547..3d2bfe54b1 100644 --- a/SignalMessaging/groups/GroupsV2ProfileKeyUpdater.swift +++ b/SignalMessaging/groups/GroupsV2ProfileKeyUpdater.swift @@ -88,12 +88,13 @@ class GroupsV2ProfileKeyUpdater: Dependencies { private func tryToScheduleGroupForProfileKeyUpdate(groupThread: TSGroupThread, transaction: SDSAnyWriteTransaction) { - guard !CurrentAppContext().isRunningTests, - tsAccountManager.isRegisteredAndReady, - tsAccountManager.isPrimaryDevice else { + guard + !CurrentAppContext().isRunningTests, + DependenciesBridge.shared.tsAccountManager.registrationState(tx: transaction.asV2Read).isRegisteredPrimaryDevice + else { return } - guard let localAddress = tsAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aciAddress else { owsFailDebug("missing local address") return } @@ -119,10 +120,11 @@ class GroupsV2ProfileKeyUpdater: Dependencies { private var isUpdating = false private func tryToUpdateNext(retryDelay: TimeInterval = 1) { - guard CurrentAppContext().isMainAppAndActive, - !CurrentAppContext().isRunningTests, - tsAccountManager.isRegisteredAndReady, - tsAccountManager.isPrimaryDevice else { + guard + CurrentAppContext().isMainAppAndActive, + !CurrentAppContext().isRunningTests, + DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegisteredPrimaryDevice + else { return } guard reachabilityManager.isReachable else { @@ -216,7 +218,7 @@ class GroupsV2ProfileKeyUpdater: Dependencies { private func tryToUpdate(groupId: Data) -> Promise { let profileKeyData = profileManager.localProfileKey().keyData - guard let localAci = tsAccountManager.localIdentifiers?.aci else { + guard let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aci else { owsFailDebug("missing local address") return Promise(error: GroupsV2Error.shouldDiscard) } diff --git a/SignalMessaging/profiles/OWSProfileManager.m b/SignalMessaging/profiles/OWSProfileManager.m index 322630e68b..bc108efac3 100644 --- a/SignalMessaging/profiles/OWSProfileManager.m +++ b/SignalMessaging/profiles/OWSProfileManager.m @@ -107,15 +107,15 @@ NSString *const kNSNotificationKey_UserProfileWriter = @"kNSNotificationKey_User OWSSingletonAssert(); AppReadinessRunNowOrWhenAppDidBecomeReadySync(^{ - if (CurrentAppContext().isMainApp && !CurrentAppContext().isRunningTests - && TSAccountManager.shared.isRegistered) { + if (CurrentAppContext().isMainApp && !CurrentAppContext().isRunningTests && + [TSAccountManagerObjcBridge isRegisteredWithMaybeTransaction]) { [self logLocalAvatarStatus]; [self fetchLocalUsersProfileWithAuthedAccount:AuthedAccount.implicit]; } }); AppReadinessRunNowOrWhenAppDidBecomeReadyAsync(^{ - if (TSAccountManager.shared.isRegistered) { + if ([TSAccountManagerObjcBridge isRegisteredWithMaybeTransaction]) { [self rotateLocalProfileKeyIfNecessary]; [self updateProfileOnServiceIfNecessaryWithAuthedAccount:AuthedAccount.implicit]; [OWSProfileManager updateStorageServiceIfNecessary]; @@ -149,7 +149,7 @@ NSString *const kNSNotificationKey_UserProfileWriter = @"kNSNotificationKey_User { OWSAssertDebug(CurrentAppContext().isMainApp); OWSAssertDebug(!CurrentAppContext().isRunningTests); - OWSAssertDebug(TSAccountManager.shared.isRegistered); + OWSAssertDebug([TSAccountManagerObjcBridge isRegisteredWithMaybeTransaction]); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [self logLocalAvatarStatus:self.localUserProfile label:@"cached copy"]; @@ -430,7 +430,7 @@ NSString *const kNSNotificationKey_UserProfileWriter = @"kNSNotificationKey_User if (authAddress != nil) { localAddress = authAddress; } else { - localAddress = self.tsAccountManager.localAddress; + localAddress = [TSAccountManagerObjcBridge localAciAddressWithMaybeTransaction]; } if (!localAddress.isValid) { return; @@ -445,7 +445,12 @@ NSString *const kNSNotificationKey_UserProfileWriter = @"kNSNotificationKey_User - (AnyPromise *)fetchLocalUsersProfilePromiseWithAuthedAccount:(AuthedAccount *)authedAccount { - ServiceIdObjC *_Nullable localAci = self.tsAccountManager.localAddress.serviceIdObjC; + LocalIdentifiersObjC *_Nullable localIdentifiers = + [TSAccountManagerObjcBridge localIdentifiersWithMaybeTransaction]; + if (!localIdentifiers) { + return [AnyPromise promiseWithError:OWSErrorMakeAssertionError(@"Missing local address.")]; + } + ServiceIdObjC *localAci = localIdentifiers.aci; if (![localAci isKindOfClass:[AciObjC class]]) { return [AnyPromise promiseWithError:OWSErrorMakeAssertionError(@"Missing local address.")]; } @@ -544,9 +549,8 @@ NSString *const kNSNotificationKey_UserProfileWriter = @"kNSNotificationKey_User transaction:transaction completion:nil]; }); - [self.tsAccountManager updateAccountAttributes].catch(^(NSError *error) { - OWSLogError(@"Error: %@.", error); - }); + [AccountAttributesUpdaterObjcBridge updateAccountAttributes].catch( + ^(NSError *error) { OWSLogError(@"Error: %@.", error); }); } - (void)setLocalProfileKey:(OWSAES256Key *)key diff --git a/SignalMessaging/profiles/OWSProfileManager.swift b/SignalMessaging/profiles/OWSProfileManager.swift index dee6172ef8..7485cddab8 100644 --- a/SignalMessaging/profiles/OWSProfileManager.swift +++ b/SignalMessaging/profiles/OWSProfileManager.swift @@ -51,7 +51,7 @@ public extension OWSProfileManager { case .explicit(let info): localAci = info.localIdentifiers.aci case .implicit: - guard let implicitLocalAci = TSAccountManager.shared.localIdentifiers?.aci else { + guard let implicitLocalAci = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aci else { throw OWSAssertionError("missing local address") } localAci = implicitLocalAci @@ -154,13 +154,11 @@ public extension OWSProfileManager { return } - let isPrimaryDevice = tsAccountManager.isPrimaryDevice(transaction: tx) + let tsRegistrationState = DependenciesBridge.shared.tsAccountManager.registrationState(tx: tx.asV2Read) guard - tsAccountManager.isRegistered(transaction: tx), - isPrimaryDevice + tsRegistrationState.isRegisteredPrimaryDevice else { - owsAssertDebug(self.tsAccountManager.isRegistered) - Logger.verbose("Not rotating profile key on unregistered and/or non-primary device") + owsFailDebug("Not rotating profile key on unregistered and/or non-primary device") return } @@ -173,7 +171,7 @@ public extension OWSProfileManager { guard !triggers.isEmpty else { // No need to rotate the profile key. - if isPrimaryDevice { + if tsRegistrationState.isPrimaryDevice ?? true { // But if it's been more than a week since we checked that our groups are up to date, schedule that. if -(lastGroupProfileKeyCheckTimestamp?.timeIntervalSinceNow ?? 0) > kWeekInterval { self.groupsV2.scheduleAllGroupsV2ForProfileKeyUpdate(transaction: tx) @@ -264,7 +262,7 @@ public extension OWSProfileManager { return .value(()) } - guard tsAccountManager.isRegisteredPrimaryDevice else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegisteredPrimaryDevice else { return Promise(error: OWSAssertionError("tsAccountManager.isRegistered was unexpectedly false")) } @@ -293,7 +291,7 @@ public extension OWSProfileManager { let newProfileKey = OWSAES256Key.generateRandom() return self.reuploadLocalProfilePromise(unsavedRotatedProfileKey: newProfileKey, authedAccount: authedAccount).map { newProfileKey } }.then(on: DispatchQueue.global()) { newProfileKey -> Promise in - guard let localAci = self.tsAccountManager.localIdentifiers?.aci else { + guard let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aci else { throw OWSAssertionError("Missing localAci.") } @@ -337,7 +335,9 @@ public extension OWSProfileManager { } }.then(on: DispatchQueue.global()) { () -> Promise in Logger.info("Updating account attributes after profile key rotation.") - return self.tsAccountManager.updateAccountAttributes() + return Promise.wrapAsync { + try await DependenciesBridge.shared.accountAttributesUpdater.updateAccountAttributes(authedAccount: authedAccount) + } }.done(on: DispatchQueue.global()) { Logger.info("Completed profile key rotation.") self.groupsV2.processProfileKeyUpdates() @@ -542,12 +542,13 @@ public extension OWSProfileManager { } class func updateStorageServiceIfNecessary() { - guard CurrentAppContext().isMainApp, - !CurrentAppContext().isRunningTests, - tsAccountManager.isRegisteredAndReady, - tsAccountManager.isRegisteredPrimaryDevice else { - return - } + guard + CurrentAppContext().isMainApp, + !CurrentAppContext().isRunningTests, + DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegisteredPrimaryDevice + else { + return + } let hasUpdated = databaseStorage.read { transaction in storageServiceStore.getBool(Self.hasUpdatedStorageServiceKey, @@ -719,7 +720,7 @@ extension OWSProfileManager { guard AppReadiness.isAppReady else { return .notReady } - guard tsAccountManager.isRegisteredAndReady else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return .notReady } guard !profileManagerImpl.isUpdatingProfileOnService else { @@ -766,7 +767,10 @@ extension OWSProfileManager { guard avatarRepairNeeded() else { return } - guard TSAccountManager.shared.isPrimaryDevice, self.localProfileAvatarData() != nil else { + guard + DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isPrimaryDevice ?? false, + self.localProfileAvatarData() != nil + else { clearAvatarRepairNeeded() return } @@ -904,7 +908,8 @@ extension OWSProfileManager { // // NOTE: We also inform the desktop in the failure case, // since that _may have_ affected service state. - if self.tsAccountManager.isRegisteredPrimaryDevice { + let tsRegistrationState = DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction + if tsRegistrationState.isRegisteredPrimaryDevice { firstly { self.syncManager.syncLocalContact() }.catch { error in @@ -914,7 +919,7 @@ extension OWSProfileManager { // Notify all our devices that the profile has changed. // Older linked devices may not handle this message. - if tsAccountManager.isRegisteredAndReady { + if tsRegistrationState.isRegistered { self.syncManager.sendFetchLatestProfileSyncMessage() } @@ -1068,11 +1073,12 @@ internal extension OWSProfileManager { /// - Parameter tx: The transaction to use for this operation. @objc func rotateProfileKeyUponRecipientHideObjC(tx: SDSAnyWriteTransaction) { - guard tsAccountManager.isRegistered(transaction: tx) else { + let tsRegistrationState = DependenciesBridge.shared.tsAccountManager.registrationState(tx: tx.asV2Read) + guard tsRegistrationState.isRegistered else { OWSLogger.verbose("[Recipient Hiding] Not rotating profile key on unregistered device.") return } - guard tsAccountManager.isPrimaryDevice(transaction: tx) else { + guard tsRegistrationState.isPrimaryDevice ?? false else { OWSLogger.verbose("[Recipient Hiding] Not rotating profile key on non-primary device.") return } @@ -1084,11 +1090,12 @@ internal extension OWSProfileManager { @objc func forceRotateLocalProfileKeyForGroupDepartureObjc(tx: SDSAnyWriteTransaction) { - guard tsAccountManager.isRegistered(transaction: tx) else { + let tsRegistrationState = DependenciesBridge.shared.tsAccountManager.registrationState(tx: tx.asV2Read) + guard tsRegistrationState.isRegistered else { OWSLogger.verbose("Not rotating profile key on unregistered device.") return } - guard tsAccountManager.isPrimaryDevice(transaction: tx) else { + guard tsRegistrationState.isPrimaryDevice ?? false else { OWSLogger.verbose("Not rotating profile key on non-primary device.") return } diff --git a/SignalMessaging/profiles/VersionedProfilesImpl.swift b/SignalMessaging/profiles/VersionedProfilesImpl.swift index 839c74860c..5d5de450f7 100644 --- a/SignalMessaging/profiles/VersionedProfilesImpl.swift +++ b/SignalMessaging/profiles/VersionedProfilesImpl.swift @@ -137,7 +137,7 @@ public class VersionedProfilesImpl: NSObject, VersionedProfilesSwift, VersionedP case .explicit(let info): localAci = info.localIdentifiers.aci case .implicit: - guard let implicitLocalAci = self.tsAccountManager.localIdentifiers?.aci else { + guard let implicitLocalAci = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aci else { throw OWSAssertionError("Missing localUuid.") } localAci = implicitLocalAci diff --git a/SignalMessaging/utils/Avatars/AvatarBuilder.swift b/SignalMessaging/utils/Avatars/AvatarBuilder.swift index aaff0b058a..d0a437d8fe 100644 --- a/SignalMessaging/utils/Avatars/AvatarBuilder.swift +++ b/SignalMessaging/utils/Avatars/AvatarBuilder.swift @@ -114,7 +114,7 @@ public class AvatarBuilder: NSObject { @objc private func localUsersProfileDidChange(notification: Notification) { AssertIsOnMainThread() - if let address = tsAccountManager.localAddress { + if let address = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress { addressToAvatarIdentifierCache.removeObject(forKey: address) } } @@ -264,7 +264,7 @@ public class AvatarBuilder: NSObject { localUserDisplayMode: LocalUserDisplayMode, transaction: SDSAnyReadTransaction) -> UIImage? { let diameterPixels = CGFloat(diameterPoints).pointsAsPixels - guard let address = tsAccountManager.localAddress else { + guard let address = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aciAddress else { owsFailDebug("Missing localAddress.") return nil } @@ -340,7 +340,7 @@ public class AvatarBuilder: NSObject { transaction: SDSAnyReadTransaction ) -> UIImage? { let requestType: RequestType = { - guard let localAddress = tsAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aciAddress else { return .contactDefaultIcon(theme: .default) } diff --git a/SignalMessaging/utils/CallMessageRelay.swift b/SignalMessaging/utils/CallMessageRelay.swift index faa93bb753..f2ddcb6a0b 100644 --- a/SignalMessaging/utils/CallMessageRelay.swift +++ b/SignalMessaging/utils/CallMessageRelay.swift @@ -51,7 +51,7 @@ public class CallMessageRelay: Dependencies { return } - guard let localIdentifiers = tsAccountManager.localIdentifiers(transaction: transaction) else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read) else { owsFailDebug("Can't process VoIP payload when not registered.") return } diff --git a/SignalMessaging/utils/RefreshEvent.swift b/SignalMessaging/utils/RefreshEvent.swift index 6a6ef162f4..590320c38d 100644 --- a/SignalMessaging/utils/RefreshEvent.swift +++ b/SignalMessaging/utils/RefreshEvent.swift @@ -52,9 +52,11 @@ public class RefreshEvent: Dependencies { } private var canFire: Bool { - guard AppReadiness.isAppReady, - CurrentAppContext().isMainAppAndActive, - tsAccountManager.isRegisteredAndReady else { + guard + AppReadiness.isAppReady, + CurrentAppContext().isMainAppAndActive, + DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered + else { return false } return true diff --git a/SignalMessaging/utils/ThreadUtil.swift b/SignalMessaging/utils/ThreadUtil.swift index 4a716cf340..96ca8a3683 100644 --- a/SignalMessaging/utils/ThreadUtil.swift +++ b/SignalMessaging/utils/ThreadUtil.swift @@ -305,7 +305,7 @@ extension TSThread { public func generateSendMessageIntent(context: IntentContext, transaction: SDSAnyReadTransaction) -> INSendMessageIntent? { guard SSKPreferences.areIntentDonationsEnabled(transaction: transaction) else { return nil } - guard let localAddress = tsAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aciAddress else { owsFailDebug("Missing local address") return nil } @@ -453,7 +453,7 @@ extension TSThread { public func intentStoryAvatarImage(tx: SDSAnyReadTransaction) -> INImage? { if let storyThread = self as? TSPrivateStoryThread { if storyThread.isMyStory { - guard let localAddress = tsAccountManager.localAddress(with: tx) else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read)?.aciAddress else { Logger.warn("Missing local address") return nil } diff --git a/SignalServiceKit/ChangePhoneNumber/ChangePhoneNumberPniManager+Shims.swift b/SignalServiceKit/ChangePhoneNumber/ChangePhoneNumberPniManager+Shims.swift index 3857c8056d..70bc5ba3fa 100644 --- a/SignalServiceKit/ChangePhoneNumber/ChangePhoneNumberPniManager+Shims.swift +++ b/SignalServiceKit/ChangePhoneNumber/ChangePhoneNumberPniManager+Shims.swift @@ -10,14 +10,12 @@ extension ChangePhoneNumberPniManagerImpl { typealias IdentityManager = _ChangePhoneNumberPniManager_IdentityManagerShim typealias PreKeyManager = _ChangePhoneNumberPniManager_PreKeyManagerShim typealias SignedPreKeyStore = _ChangePhoneNumberPniManager_SignedPreKeyStoreShim - typealias TSAccountManager = _ChangePhoneNumberPniManager_TSAccountManagerShim } enum Wrappers { typealias IdentityManager = _ChangePhoneNumberPniManager_IdentityManagerWrapper typealias PreKeyManager = _ChangePhoneNumberPniManager_PreKeyManagerWrapper typealias SignedPreKeyStore = _ChangePhoneNumberPniManager_SignedPreKeyStoreWrapper - typealias TSAccountManager = _ChangePhoneNumberPniManager_TSAccountManagerWrapper } } @@ -50,13 +48,6 @@ protocol _ChangePhoneNumberPniManager_SignedPreKeyStoreShim { ) } -protocol _ChangePhoneNumberPniManager_TSAccountManagerShim { - func setPniRegistrationId( - newRegistrationId: UInt32, - transaction: DBWriteTransaction - ) -} - // MARK: - Wrappers class _ChangePhoneNumberPniManager_IdentityManagerWrapper: _ChangePhoneNumberPniManager_IdentityManagerShim { @@ -114,21 +105,3 @@ class _ChangePhoneNumberPniManager_SignedPreKeyStoreWrapper: _ChangePhoneNumberP ) } } - -class _ChangePhoneNumberPniManager_TSAccountManagerWrapper: _ChangePhoneNumberPniManager_TSAccountManagerShim { - private let tsAccountManager: TSAccountManager - - init(_ tsAccountManager: TSAccountManager) { - self.tsAccountManager = tsAccountManager - } - - func setPniRegistrationId( - newRegistrationId: UInt32, - transaction: DBWriteTransaction - ) { - tsAccountManager.setPniRegistrationId( - newRegistrationId: newRegistrationId, - transaction: SDSDB.shimOnlyBridge(transaction) - ) - } -} diff --git a/SignalServiceKit/ChangePhoneNumber/ChangePhoneNumberPniManager.swift b/SignalServiceKit/ChangePhoneNumber/ChangePhoneNumberPniManager.swift index cdc41f0394..c2b718c866 100644 --- a/SignalServiceKit/ChangePhoneNumber/ChangePhoneNumberPniManager.swift +++ b/SignalServiceKit/ChangePhoneNumber/ChangePhoneNumberPniManager.swift @@ -106,7 +106,7 @@ class ChangePhoneNumberPniManagerImpl: ChangePhoneNumberPniManager { private let preKeyManager: Shims.PreKeyManager private let registrationIdGenerator: RegistrationIdGenerator private let schedulers: Schedulers - private let tsAccountManager: Shims.TSAccountManager + private let tsAccountManager: TSAccountManagerProtocol init( identityManager: Shims.IdentityManager, @@ -116,7 +116,7 @@ class ChangePhoneNumberPniManagerImpl: ChangePhoneNumberPniManager { preKeyManager: Shims.PreKeyManager, registrationIdGenerator: RegistrationIdGenerator, schedulers: Schedulers, - tsAccountManager: Shims.TSAccountManager + tsAccountManager: TSAccountManagerProtocol ) { self.identityManager = identityManager self.pniDistributionParameterBuilder = pniDistributionParameterBuilder @@ -207,8 +207,8 @@ class ChangePhoneNumberPniManagerImpl: ChangePhoneNumberPniManager { ) tsAccountManager.setPniRegistrationId( - newRegistrationId: pendingState.localDevicePniRegistrationId, - transaction: transaction + pendingState.localDevicePniRegistrationId, + tx: transaction ) // Followup tasks diff --git a/SignalServiceKit/ChangePhoneNumber/LegacyChangePhoneNumber.swift b/SignalServiceKit/ChangePhoneNumber/LegacyChangePhoneNumber.swift index 10654e85fa..ab84a7779d 100644 --- a/SignalServiceKit/ChangePhoneNumber/LegacyChangePhoneNumber.swift +++ b/SignalServiceKit/ChangePhoneNumber/LegacyChangePhoneNumber.swift @@ -144,7 +144,7 @@ public class LegacyChangePhoneNumber: NSObject { guard CurrentAppContext().isMainApp, - tsAccountManager.isRegisteredAndReady + DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return } @@ -214,7 +214,7 @@ public class LegacyChangePhoneNumber: NSObject { transaction: SDSAnyWriteTransaction ) throws -> E164 { guard - let localIdentifiers = tsAccountManager.localIdentifiers(transaction: transaction), + let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read), let localE164 = E164(localIdentifiers.phoneNumber) else { throw OWSAssertionError("Missing or invalid local parameters!") @@ -255,11 +255,11 @@ public class LegacyChangePhoneNumber: NSObject { "Recording new phone number: \(serviceE164), PNI: \(servicePni)" ) - self.tsAccountManager.updateLocalPhoneNumber( - E164ObjC(serviceE164), - aci: AciObjC(serviceAci), // Verified equal to `localAci` above - pni: PniObjC(servicePni), - transaction: transaction + DependenciesBridge.shared.registrationStateChangeManager.didUpdateLocalPhoneNumber( + serviceE164, + aci: serviceAci, + pni: servicePni, + tx: transaction.asV2Write ) self.storageServiceManager.recordPendingLocalAccountUpdates() diff --git a/SignalServiceKit/Dependencies/DependenciesBridge.swift b/SignalServiceKit/Dependencies/DependenciesBridge.swift index 2f17af168e..320043fd8a 100644 --- a/SignalServiceKit/Dependencies/DependenciesBridge.swift +++ b/SignalServiceKit/Dependencies/DependenciesBridge.swift @@ -56,6 +56,8 @@ public class DependenciesBridge { public let identityManager: OWSIdentityManager + public let incomingPniChangeNumberProcessor: IncomingPniChangeNumberProcessor + public let keyValueStoreFactory: KeyValueStoreFactory public let learnMyOwnPniManager: LearnMyOwnPniManager @@ -230,7 +232,7 @@ public class DependenciesBridge { recipientFetcher: recipientFetcher, schedulers: schedulers, storageServiceManager: storageServiceManager, - tsAccountManager: tsAccountManager + tsAccountManager: newTSAccountManager ) self.changePhoneNumberPniManager = ChangePhoneNumberPniManagerImpl( @@ -241,7 +243,7 @@ public class DependenciesBridge { preKeyManager: ChangePhoneNumberPniManagerImpl.Wrappers.PreKeyManager(), registrationIdGenerator: RegistrationIdGenerator(), schedulers: schedulers, - tsAccountManager: ChangePhoneNumberPniManagerImpl.Wrappers.TSAccountManager(tsAccountManager) + tsAccountManager: newTSAccountManager ) self.deviceManager = OWSDeviceManagerImpl( @@ -264,8 +266,25 @@ public class DependenciesBridge { ) self.svrCredentialStorage = SVRAuthCredentialStorageImpl(keyValueStoreFactory: keyValueStoreFactory) + let svrLocalStorage = SVRLocalStorageImpl(keyValueStoreFactory: keyValueStoreFactory) + + let accountAttributesUpdater = AccountAttributesUpdaterImpl( + appReadiness: AccountAttributesUpdaterImpl.Wrappers.AppReadiness(), + appVersion: appVersion, + dateProvider: dateProvider, + db: db, + profileManager: profileManager, + keyValueStoreFactory: keyValueStoreFactory, + serviceClient: SignalServiceRestClient(), + schedulers: schedulers, + svrLocalStorage: svrLocalStorage, + syncManager: syncManager, + tsAccountManager: newTSAccountManager + ) + self.accountAttributesUpdater = accountAttributesUpdater + self.svr = OrchestratingSVRImpl( - accountManager: SVR.Wrappers.TSAccountManager(tsAccountManager), + accountAttributesUpdater: accountAttributesUpdater, appContext: CurrentAppContext(), appReadiness: SVR2.Wrappers.AppReadiness(), appVersion: appVersion, @@ -277,78 +296,13 @@ public class DependenciesBridge { schedulers: schedulers, signalService: signalService, storageServiceManager: storageServiceManager, + svrLocalStorage: svrLocalStorage, syncManager: syncManager, + tsAccountManager: newTSAccountManager, tsConstants: tsConstants, twoFAManager: SVR.Wrappers.OWS2FAManager(ows2FAManager) ) - let pniIdentityKeyChecker = PniIdentityKeyCheckerImpl( - db: db, - identityManager: PniIdentityKeyCheckerImpl.Wrappers.IdentityManager(identityManager), - profileFetcher: PniIdentityKeyCheckerImpl.Wrappers.ProfileFetcher(schedulers: schedulers), - schedulers: schedulers - ) - self.linkedDevicePniKeyManager = LinkedDevicePniKeyManagerImpl( - db: db, - keyValueStoreFactory: keyValueStoreFactory, - messageProcessor: LinkedDevicePniKeyManagerImpl.Wrappers.MessageProcessor(messageProcessor), - pniIdentityKeyChecker: pniIdentityKeyChecker, - schedulers: schedulers, - tsAccountManager: LinkedDevicePniKeyManagerImpl.Wrappers.TSAccountManager(tsAccountManager) - ) - self.pniHelloWorldManager = PniHelloWorldManagerImpl( - database: db, - identityManager: PniHelloWorldManagerImpl.Wrappers.IdentityManager(identityManager), - keyValueStoreFactory: keyValueStoreFactory, - networkManager: PniHelloWorldManagerImpl.Wrappers.NetworkManager(networkManager), - pniDistributionParameterBuilder: pniDistributionParameterBuilder, - pniSignedPreKeyStore: pniProtocolStore.signedPreKeyStore, - pniKyberPreKeyStore: pniProtocolStore.kyberPreKeyStore, - profileManager: PniHelloWorldManagerImpl.Wrappers.ProfileManager(profileManager), - schedulers: schedulers, - signalRecipientStore: PniHelloWorldManagerImpl.Wrappers.SignalRecipientStore(), - tsAccountManager: PniHelloWorldManagerImpl.Wrappers.TSAccountManager(tsAccountManager) - ) - - let preKeyOperationFactory: PreKeyOperationFactory = PreKeyOperationFactoryImpl( - context: .init( - accountManager: PreKey.Operation.Wrappers.AccountManager(accountManager: tsAccountManager), - dateProvider: dateProvider, - db: db, - identityManager: PreKey.Operation.Wrappers.IdentityManager(identityManager: identityManager), - linkedDevicePniKeyManager: linkedDevicePniKeyManager, - messageProcessor: PreKey.Operation.Wrappers.MessageProcessor(messageProcessor: messageProcessor), - protocolStoreManager: signalProtocolStoreManager, - schedulers: schedulers, - serviceClient: accountServiceClient - ) - ) - self.preKeyManager = PreKeyManagerImpl( - db: db, - identityManager: PreKey.Manager.Wrappers.IdentityManager(identityManager), - messageProcessor: PreKey.Manager.Wrappers.MessageProcessor(messageProcessor: messageProcessor), - preKeyOperationFactory: preKeyOperationFactory, - protocolStoreManager: signalProtocolStoreManager - ) - - self.learnMyOwnPniManager = LearnMyOwnPniManagerImpl( - accountServiceClient: LearnMyOwnPniManagerImpl.Wrappers.AccountServiceClient(accountServiceClient), - db: db, - keyValueStoreFactory: keyValueStoreFactory, - pniIdentityKeyChecker: pniIdentityKeyChecker, - preKeyManager: preKeyManager, - schedulers: schedulers, - tsAccountManager: LearnMyOwnPniManagerImpl.Wrappers.TSAccountManager(tsAccountManager) - ) - - self.registrationSessionManager = RegistrationSessionManagerImpl( - dateProvider: dateProvider, - db: db, - keyValueStoreFactory: keyValueStoreFactory, - schedulers: schedulers, - signalService: signalService - ) - self.chatColorSettingStore = ChatColorSettingStore(keyValueStoreFactory: self.keyValueStoreFactory) let groupMemberStore = GroupMemberStoreImpl() self.groupMemberStore = groupMemberStore @@ -360,12 +314,7 @@ public class DependenciesBridge { keyValueStoreFactory: self.keyValueStoreFactory, notificationScheduler: self.schedulers.main ) - - self.groupMemberUpdater = GroupMemberUpdaterImpl( - temporaryShims: GroupMemberUpdaterTemporaryShimsImpl(), - groupMemberStore: groupMemberStore, - signalServiceAddressCache: signalServiceAddressCache - ) + let userProfileStore = UserProfileStoreImpl() self.disappearingMessagesConfigurationStore = DisappearingMessagesConfigurationStoreImpl() @@ -383,7 +332,11 @@ public class DependenciesBridge { wallpaperStore: self.wallpaperStore ) - let userProfileStore = UserProfileStoreImpl() + self.groupMemberUpdater = GroupMemberUpdaterImpl( + temporaryShims: GroupMemberUpdaterTemporaryShimsImpl(), + groupMemberStore: groupMemberStore, + signalServiceAddressCache: signalServiceAddressCache + ) self.recipientMerger = RecipientMergerImpl( temporaryShims: SignalRecipientMergerTemporaryShims( @@ -410,10 +363,96 @@ public class DependenciesBridge { storageServiceManager: storageServiceManager ) + self.registrationStateChangeManager = RegistrationStateChangeManagerImpl( + appContext: appContext, + groupsV2: groupsV2, + identityManager: identityManager, + notificationPresenter: notificationsManager, + paymentsEvents: RegistrationStateChangeManagerImpl.Wrappers.PaymentsEvents(paymentsEvents), + recipientMerger: recipientMerger, + schedulers: schedulers, + senderKeyStore: RegistrationStateChangeManagerImpl.Wrappers.SenderKeyStore(senderKeyStore), + signalProtocolStoreManager: signalProtocolStoreManager, + signalService: signalService, + storageServiceManager: storageServiceManager, + tsAccountManager: newTSAccountManager, + udManager: udManager, + versionedProfiles: versionedProfiles + ) + + let pniIdentityKeyChecker = PniIdentityKeyCheckerImpl( + db: db, + identityManager: PniIdentityKeyCheckerImpl.Wrappers.IdentityManager(identityManager), + profileFetcher: PniIdentityKeyCheckerImpl.Wrappers.ProfileFetcher(schedulers: schedulers), + schedulers: schedulers + ) + self.linkedDevicePniKeyManager = LinkedDevicePniKeyManagerImpl( + db: db, + keyValueStoreFactory: keyValueStoreFactory, + messageProcessor: LinkedDevicePniKeyManagerImpl.Wrappers.MessageProcessor(messageProcessor), + pniIdentityKeyChecker: pniIdentityKeyChecker, + registrationStateChangeManager: registrationStateChangeManager, + schedulers: schedulers, + tsAccountManager: newTSAccountManager + ) + self.pniHelloWorldManager = PniHelloWorldManagerImpl( + database: db, + identityManager: PniHelloWorldManagerImpl.Wrappers.IdentityManager(identityManager), + keyValueStoreFactory: keyValueStoreFactory, + networkManager: PniHelloWorldManagerImpl.Wrappers.NetworkManager(networkManager), + pniDistributionParameterBuilder: pniDistributionParameterBuilder, + pniSignedPreKeyStore: pniProtocolStore.signedPreKeyStore, + pniKyberPreKeyStore: pniProtocolStore.kyberPreKeyStore, + profileManager: PniHelloWorldManagerImpl.Wrappers.ProfileManager(profileManager), + schedulers: schedulers, + signalRecipientStore: PniHelloWorldManagerImpl.Wrappers.SignalRecipientStore(), + tsAccountManager: newTSAccountManager + ) + + let preKeyOperationFactory: PreKeyOperationFactory = PreKeyOperationFactoryImpl( + context: .init( + dateProvider: dateProvider, + db: db, + identityManager: PreKey.Operation.Wrappers.IdentityManager(identityManager: identityManager), + linkedDevicePniKeyManager: linkedDevicePniKeyManager, + messageProcessor: PreKey.Operation.Wrappers.MessageProcessor(messageProcessor: messageProcessor), + protocolStoreManager: signalProtocolStoreManager, + schedulers: schedulers, + serviceClient: accountServiceClient, + tsAccountManager: newTSAccountManager + ) + ) + self.preKeyManager = PreKeyManagerImpl( + db: db, + identityManager: PreKey.Manager.Wrappers.IdentityManager(identityManager), + messageProcessor: PreKey.Manager.Wrappers.MessageProcessor(messageProcessor: messageProcessor), + preKeyOperationFactory: preKeyOperationFactory, + protocolStoreManager: signalProtocolStoreManager + ) + + self.learnMyOwnPniManager = LearnMyOwnPniManagerImpl( + accountServiceClient: LearnMyOwnPniManagerImpl.Wrappers.AccountServiceClient(accountServiceClient), + db: db, + keyValueStoreFactory: keyValueStoreFactory, + pniIdentityKeyChecker: pniIdentityKeyChecker, + preKeyManager: preKeyManager, + registrationStateChangeManager: registrationStateChangeManager, + schedulers: schedulers, + tsAccountManager: newTSAccountManager + ) + + self.registrationSessionManager = RegistrationSessionManagerImpl( + dateProvider: dateProvider, + db: db, + keyValueStoreFactory: keyValueStoreFactory, + schedulers: schedulers, + signalService: signalService + ) + self.recipientHidingManager = RecipientHidingManagerImpl( profileManager: profileManager, storageServiceManager: storageServiceManager, - tsAccountManager: tsAccountManager, + tsAccountManager: newTSAccountManager, jobQueues: jobQueues ) @@ -449,41 +488,19 @@ public class DependenciesBridge { usernameLinkManager: usernameLinkManager )) - let accountAttributesUpdater = AccountAttributesUpdaterImpl( - appReadiness: AccountAttributesUpdaterImpl.Wrappers.AppReadiness(), - appVersion: appVersion, - dateProvider: dateProvider, - db: db, - profileManager: profileManager, - keyValueStoreFactory: keyValueStoreFactory, - serviceClient: SignalServiceRestClient(), - schedulers: schedulers, - svr: svr, - syncManager: syncManager, - tsAccountManager: newTSAccountManager - ) - self.accountAttributesUpdater = accountAttributesUpdater self.phoneNumberDiscoverabilityManager = PhoneNumberDiscoverabilityManagerImpl( accountAttributesUpdater: accountAttributesUpdater, schedulers: schedulers, storageServiceManager: storageServiceManager, tsAccountManager: newTSAccountManager ) - self.registrationStateChangeManager = RegistrationStateChangeManagerImpl( - appContext: appContext, - groupsV2: groupsV2, + + self.incomingPniChangeNumberProcessor = IncomingPniChangeNumberProcessorImpl( identityManager: identityManager, - notificationPresenter: notificationsManager, - paymentsEvents: RegistrationStateChangeManagerImpl.Wrappers.PaymentsEvents(paymentsEvents), - recipientMerger: recipientMerger, - schedulers: schedulers, - senderKeyStore: RegistrationStateChangeManagerImpl.Wrappers.SenderKeyStore(senderKeyStore), - signalProtocolStoreManager: signalProtocolStoreManager, - signalService: signalService, - storageServiceManager: storageServiceManager, - tsAccountManager: newTSAccountManager, - udManager: udManager, - versionedProfiles: versionedProfiles + pniProtocolStore: pniProtocolStore, + preKeyManager: preKeyManager, + registrationStateChangeManager: registrationStateChangeManager, + tsAccountManager: newTSAccountManager ) } } diff --git a/SignalServiceKit/Experience Upgrades/ExperienceUpgradeManifest.swift b/SignalServiceKit/Experience Upgrades/ExperienceUpgradeManifest.swift index 6da35005b1..284640ea1c 100644 --- a/SignalServiceKit/Experience Upgrades/ExperienceUpgradeManifest.swift +++ b/SignalServiceKit/Experience Upgrades/ExperienceUpgradeManifest.swift @@ -437,7 +437,7 @@ extension ExperienceUpgradeManifest { extension ExperienceUpgradeManifest { func shouldBeShown(transaction: SDSAnyReadTransaction) -> Bool { if - let registrationDate = tsAccountManager.registrationDate(transaction: transaction), + let registrationDate = DependenciesBridge.shared.tsAccountManager.registrationDate(tx: transaction.asV2Read), Date().timeIntervalSince(registrationDate) < delayAfterRegistration { // We have not waited long enough after registration to show this @@ -450,7 +450,7 @@ extension ExperienceUpgradeManifest { return false } - guard showOnLinkedDevices || tsAccountManager.isRegisteredPrimaryDevice else { + guard showOnLinkedDevices || DependenciesBridge.shared.tsAccountManager.registrationState(tx: transaction.asV2Read).isRegisteredPrimaryDevice else { // We are a linked device, which should not show this upgrade. return false } @@ -530,7 +530,7 @@ extension ExperienceUpgradeManifest { return false } - guard !tsAccountManager.isDiscoverableByPhoneNumber(with: transaction) else { + guard !DependenciesBridge.shared.tsAccountManager.isDiscoverableByPhoneNumber(tx: transaction.asV2Read) else { // If phone number discovery is enabled, do not prompt to create a // username. return false @@ -539,8 +539,8 @@ extension ExperienceUpgradeManifest { /// The elapsed interval since the user disabled phone number /// discovery. Note that we need to invert the sign as this date will /// be in the past. - let timeIntervalSinceDisabledDiscovery = tsAccountManager - .lastSetIsDiscoverablyByPhoneNumberAt(with: transaction) + let timeIntervalSinceDisabledDiscovery = DependenciesBridge.shared.tsAccountManager + .lastSetIsDiscoverablyByPhoneNumber(tx: transaction.asV2Read) .timeIntervalSinceNow * -1 let requiredDelayAfterDisablingDiscovery: TimeInterval = 3 * kDayInterval diff --git a/SignalServiceKit/SecureValueRecovery/KeyBackupService/KeyBackupServiceImpl.swift b/SignalServiceKit/SecureValueRecovery/KeyBackupService/KeyBackupServiceImpl.swift index 21fb454a2b..bfec0be451 100644 --- a/SignalServiceKit/SecureValueRecovery/KeyBackupService/KeyBackupServiceImpl.swift +++ b/SignalServiceKit/SecureValueRecovery/KeyBackupService/KeyBackupServiceImpl.swift @@ -12,21 +12,20 @@ public class KeyBackupServiceImpl: SecureValueRecovery { // MARK: - Init private let appContext: AppContext - private let accountManager: SVR.Shims.TSAccountManager private let credentialStorage: SVRAuthCredentialStorage private let db: DB private let keyValueStoreFactory: KeyValueStoreFactory - private let localStorage: SVRLocalStorage + private let localStorage: SVRLocalStorageInternal private let remoteAttestation: SVR.Shims.RemoteAttestation private let schedulers: Schedulers private let signalService: OWSSignalServiceProtocol private let storageServiceManager: StorageServiceManager private let syncManager: SyncManagerProtocolSwift + private let tsAccountManager: TSAccountManagerProtocol private let tsConstants: TSConstantsProtocol private let twoFAManager: SVR.Shims.OWS2FAManager public init( - accountManager: SVR.Shims.TSAccountManager, appContext: AppContext, credentialStorage: SVRAuthCredentialStorage, databaseStorage: DB, @@ -35,21 +34,23 @@ public class KeyBackupServiceImpl: SecureValueRecovery { schedulers: Schedulers, signalService: OWSSignalServiceProtocol, storageServiceManager: StorageServiceManager, + svrLocalStorage: SVRLocalStorageInternal, syncManager: SyncManagerProtocolSwift, + tsAccountManager: TSAccountManagerProtocol, tsConstants: TSConstantsProtocol, twoFAManager: SVR.Shims.OWS2FAManager ) { - self.accountManager = accountManager self.appContext = appContext self.credentialStorage = credentialStorage self.db = databaseStorage self.keyValueStoreFactory = keyValueStoreFactory - self.localStorage = SVRLocalStorage(keyValueStoreFactory: keyValueStoreFactory) + self.localStorage = svrLocalStorage self.remoteAttestation = remoteAttestation self.schedulers = schedulers self.signalService = signalService self.storageServiceManager = storageServiceManager self.syncManager = syncManager + self.tsAccountManager = tsAccountManager self.tsConstants = tsConstants self.twoFAManager = twoFAManager } @@ -568,7 +569,7 @@ public class KeyBackupServiceImpl: SecureValueRecovery { // This should only happen if we're a linked device and received // the derived key via a sync message, since we won't know about // the master key. - let isPrimaryDevice = accountManager.isPrimaryDevice(transaction: transaction) + let isPrimaryDevice = tsAccountManager.registrationState(tx: transaction).isPrimaryDevice ?? true if (!isPrimaryDevice || appContext.isRunningTests), let cachedData = getOrLoadState(transaction: transaction).syncedDerivedKeys[key] { return SVR.DerivedKeyData(cachedData, key) @@ -673,7 +674,7 @@ public class KeyBackupServiceImpl: SecureValueRecovery { let syncedDerivedKeys: [SVR.DerivedKey: Data] let enclaveName: String? - init(localStorage: SVRLocalStorage, transaction: DBReadTransaction) { + init(localStorage: SVRLocalStorageInternal, transaction: DBReadTransaction) { masterKey = localStorage.getMasterKey(transaction) pinType = localStorage.getPinType(transaction) encodedVerificationString = localStorage.getEncodedPINVerificationString(transaction) @@ -718,7 +719,7 @@ public class KeyBackupServiceImpl: SecureValueRecovery { private func migrateEnclavesIfNecessary(state: State) { let (isRegisteredAndReady, pinCode) = db.read { return ( - accountManager.isRegisteredAndReady(transaction: $0), + tsAccountManager.registrationState(tx: $0).isRegistered, self.twoFAManager.pinCode(transaction: $0) ) } @@ -783,7 +784,7 @@ public class KeyBackupServiceImpl: SecureValueRecovery { authedAccount: AuthedAccount, transaction: DBWriteTransaction ) { - owsAssertDebug(accountManager.isPrimaryDevice(transaction: transaction)) + owsAssertDebug(tsAccountManager.registrationState(tx: transaction).isPrimaryDevice != false) let previousState = getOrLoadState(transaction: transaction) @@ -811,7 +812,7 @@ public class KeyBackupServiceImpl: SecureValueRecovery { reloadState(transaction: transaction) // Only continue if we didn't previously have a master key or our master key has changed - guard masterKey != previousState.masterKey, accountManager.isRegisteredAndReady(transaction: transaction) else { return } + guard masterKey != previousState.masterKey, tsAccountManager.registrationState(tx: transaction).isRegistered else { return } // Trigger a re-creation of the storage manifest, our keys have changed storageServiceManager.resetLocalData(transaction: transaction) @@ -831,7 +832,7 @@ public class KeyBackupServiceImpl: SecureValueRecovery { authedAccount: AuthedAccount, transaction: DBWriteTransaction ) { - guard !accountManager.isPrimaryDevice(transaction: transaction) || appContext.isRunningTests else { + guard tsAccountManager.registrationState(tx: transaction).isPrimaryDevice != true || appContext.isRunningTests else { return owsFailDebug("primary device should never store synced keys") } diff --git a/SignalServiceKit/SecureValueRecovery/KeyBackupService/KeyBackupServiceShims.swift b/SignalServiceKit/SecureValueRecovery/KeyBackupService/KeyBackupServiceShims.swift index 09ca6b775f..310c48898d 100644 --- a/SignalServiceKit/SecureValueRecovery/KeyBackupService/KeyBackupServiceShims.swift +++ b/SignalServiceKit/SecureValueRecovery/KeyBackupService/KeyBackupServiceShims.swift @@ -22,48 +22,16 @@ import Foundation extension SVR { public enum Shims { - public typealias TSAccountManager = _KeyBackupServiceImpl_TSAccountManagerShim public typealias OWS2FAManager = _KeyBackupServiceImpl_OWS2FAManagerShim public typealias RemoteAttestation = _KeyBackupServiceImpl_RemoteAttestationShim } public enum Wrappers { - public typealias TSAccountManager = _KeyBackupServiceImpl_TSAccountManagerWrapper public typealias OWS2FAManager = _KeyBackupServiceImpl_OWS2FAManagerWrapper public typealias RemoteAttestation = _KeyBackupServiceImpl_RemoteAttestationWrapper } } -// MARK: - TSAccountManager - -public protocol _KeyBackupServiceImpl_TSAccountManagerShim { - - func isPrimaryDevice(transaction: DBReadTransaction) -> Bool - func isRegisteredAndReady(transaction: DBReadTransaction) -> Bool - - func scheduleAccountAttributesUpdate(authedAccount: AuthedAccount, transaction: DBWriteTransaction) -} - -public class _KeyBackupServiceImpl_TSAccountManagerWrapper: SVR.Shims.TSAccountManager { - private let accountManager: TSAccountManager - public init(_ accountManager: TSAccountManager) { self.accountManager = accountManager } - - public func isPrimaryDevice(transaction: DBReadTransaction) -> Bool { - return accountManager.isPrimaryDevice(transaction: SDSDB.shimOnlyBridge(transaction)) - } - - public func isRegisteredAndReady(transaction: DBReadTransaction) -> Bool { - return accountManager.isRegisteredAndReady(transaction: SDSDB.shimOnlyBridge(transaction)) - } - - public func scheduleAccountAttributesUpdate(authedAccount: AuthedAccount, transaction: DBWriteTransaction) { - accountManager.scheduleAccountAttributesUpdate( - authedAccount: authedAccount, - transaction: SDSDB.shimOnlyBridge(transaction) - ) - } -} - // MARK: - OWS2FAManager public protocol _KeyBackupServiceImpl_OWS2FAManagerShim { diff --git a/SignalServiceKit/SecureValueRecovery/SVR2/SVRLocalStorage.swift b/SignalServiceKit/SecureValueRecovery/LocalStorage/SVRLocalStorage.swift similarity index 53% rename from SignalServiceKit/SecureValueRecovery/SVR2/SVRLocalStorage.swift rename to SignalServiceKit/SecureValueRecovery/LocalStorage/SVRLocalStorage.swift index 3f0b6ad83a..7ecfe96203 100644 --- a/SignalServiceKit/SecureValueRecovery/SVR2/SVRLocalStorage.swift +++ b/SignalServiceKit/SecureValueRecovery/LocalStorage/SVRLocalStorage.swift @@ -5,13 +5,56 @@ import Foundation +public protocol SVRLocalStorage { + + func getIsMasterKeyBackedUp(_ transaction: DBReadTransaction) -> Bool +} + +public protocol SVRLocalStorageInternal: SVRLocalStorage { + + func getMasterKey(_ transaction: DBReadTransaction) -> Data? + + func getPinType(_ transaction: DBReadTransaction) -> SVR.PinType? + + func getEncodedPINVerificationString(_ transaction: DBReadTransaction) -> String? + + // Linked devices get the storage service key and store it locally. The primary doesn't do this. + func getSyncedStorageServiceKey(_ transaction: DBReadTransaction) -> Data? + + func getSVR1EnclaveName(_ transaction: DBReadTransaction) -> String? + + func getSVR2MrEnclaveStringValue(_ transaction: DBReadTransaction) -> String? + + // MARK: - Setters + + func setIsMasterKeyBackedUp(_ value: Bool, _ transaction: DBWriteTransaction) + + func setMasterKey(_ value: Data, _ transaction: DBWriteTransaction) + + func setPinType(_ value: SVR.PinType, _ transaction: DBWriteTransaction) + + func setEncodedPINVerificationString(_ value: String?, _ transaction: DBWriteTransaction) + + // Linked devices get the storage service key and store it locally. The primary doesn't do this. + func setSyncedStorageServiceKey(_ value: Data?, _ transaction: DBWriteTransaction) + + func setSVR1EnclaveName(_ value: String?, _ transaction: DBWriteTransaction) + + func setSVR2MrEnclaveStringValue(_ value: String?, _ transaction: DBWriteTransaction) + + // MARK: - Clearing Keys + + func clearKeys(_ transaction: DBWriteTransaction) + +} + /// Stores state related to SVR independent of enclave; e.g. do we have backups at all, /// what type is our pin, etc. -internal class SVRLocalStorage { +internal class SVRLocalStorageImpl: SVRLocalStorageInternal { private let keyValueStore: KeyValueStore - internal init( + public init( keyValueStoreFactory: KeyValueStoreFactory ) { // Collection name must not be changed; matches that historically kept in KeyBackupServiceImpl. @@ -20,72 +63,72 @@ internal class SVRLocalStorage { // MARK: - Getters - internal func getIsMasterKeyBackedUp(_ transaction: DBReadTransaction) -> Bool { + public func getIsMasterKeyBackedUp(_ transaction: DBReadTransaction) -> Bool { return keyValueStore.getBool(Keys.isMasterKeyBackedUp, defaultValue: false, transaction: transaction) } - internal func getMasterKey(_ transaction: DBReadTransaction) -> Data? { + public func getMasterKey(_ transaction: DBReadTransaction) -> Data? { return keyValueStore.getData(Keys.masterKey, transaction: transaction) } - internal func getPinType(_ transaction: DBReadTransaction) -> SVR.PinType? { + public func getPinType(_ transaction: DBReadTransaction) -> SVR.PinType? { guard let raw = keyValueStore.getInt(Keys.pinType, transaction: transaction) else { return nil } return SVR.PinType(rawValue: raw) } - internal func getEncodedPINVerificationString(_ transaction: DBReadTransaction) -> String? { + public func getEncodedPINVerificationString(_ transaction: DBReadTransaction) -> String? { return keyValueStore.getString(Keys.encodedPINVerificationString, transaction: transaction) } // Linked devices get the storage service key and store it locally. The primary doesn't do this. - internal func getSyncedStorageServiceKey(_ transaction: DBReadTransaction) -> Data? { + public func getSyncedStorageServiceKey(_ transaction: DBReadTransaction) -> Data? { return keyValueStore.getData(Keys.syncedStorageServiceKey, transaction: transaction) } - internal func getSVR1EnclaveName(_ transaction: DBReadTransaction) -> String? { + public func getSVR1EnclaveName(_ transaction: DBReadTransaction) -> String? { return keyValueStore.getString(Keys.svr1EnclaveName, transaction: transaction) } - internal func getSVR2MrEnclaveStringValue(_ transaction: DBReadTransaction) -> String? { + public func getSVR2MrEnclaveStringValue(_ transaction: DBReadTransaction) -> String? { return keyValueStore.getString(Keys.svr2MrEnclaveStringValue, transaction: transaction) } // MARK: - Setters - internal func setIsMasterKeyBackedUp(_ value: Bool, _ transaction: DBWriteTransaction) { + public func setIsMasterKeyBackedUp(_ value: Bool, _ transaction: DBWriteTransaction) { keyValueStore.setBool(value, key: Keys.isMasterKeyBackedUp, transaction: transaction) } - internal func setMasterKey(_ value: Data, _ transaction: DBWriteTransaction) { + public func setMasterKey(_ value: Data, _ transaction: DBWriteTransaction) { keyValueStore.setData(value, key: Keys.masterKey, transaction: transaction) } - internal func setPinType(_ value: SVR.PinType, _ transaction: DBWriteTransaction) { + public func setPinType(_ value: SVR.PinType, _ transaction: DBWriteTransaction) { keyValueStore.setInt(value.rawValue, key: Keys.pinType, transaction: transaction) } - internal func setEncodedPINVerificationString(_ value: String?, _ transaction: DBWriteTransaction) { + public func setEncodedPINVerificationString(_ value: String?, _ transaction: DBWriteTransaction) { keyValueStore.setString(value, key: Keys.encodedPINVerificationString, transaction: transaction) } // Linked devices get the storage service key and store it locally. The primary doesn't do this. - internal func setSyncedStorageServiceKey(_ value: Data?, _ transaction: DBWriteTransaction) { + public func setSyncedStorageServiceKey(_ value: Data?, _ transaction: DBWriteTransaction) { keyValueStore.setData(value, key: Keys.syncedStorageServiceKey, transaction: transaction) } - internal func setSVR1EnclaveName(_ value: String?, _ transaction: DBWriteTransaction) { + public func setSVR1EnclaveName(_ value: String?, _ transaction: DBWriteTransaction) { keyValueStore.setString(value, key: Keys.svr1EnclaveName, transaction: transaction) } - internal func setSVR2MrEnclaveStringValue(_ value: String?, _ transaction: DBWriteTransaction) { + public func setSVR2MrEnclaveStringValue(_ value: String?, _ transaction: DBWriteTransaction) { keyValueStore.setString(value, key: Keys.svr2MrEnclaveStringValue, transaction: transaction) } // MARK: - Clearing Keys - internal func clearKeys(_ transaction: DBWriteTransaction) { + public func clearKeys(_ transaction: DBWriteTransaction) { keyValueStore.removeValues( forKeys: [ Keys.masterKey, diff --git a/SignalServiceKit/SecureValueRecovery/Orchestrating/OrchestratingSVRImpl.swift b/SignalServiceKit/SecureValueRecovery/Orchestrating/OrchestratingSVRImpl.swift index c8a6db9495..44849e16ca 100644 --- a/SignalServiceKit/SecureValueRecovery/Orchestrating/OrchestratingSVRImpl.swift +++ b/SignalServiceKit/SecureValueRecovery/Orchestrating/OrchestratingSVRImpl.swift @@ -15,7 +15,7 @@ public class OrchestratingSVRImpl: SecureValueRecovery { private let schedulers: Schedulers public init( - accountManager: SVR.Shims.TSAccountManager, + accountAttributesUpdater: AccountAttributesUpdater, appContext: AppContext, appReadiness: SVR2.Shims.AppReadiness, appVersion: AppVersion, @@ -27,11 +27,14 @@ public class OrchestratingSVRImpl: SecureValueRecovery { schedulers: Schedulers, signalService: OWSSignalServiceProtocol, storageServiceManager: StorageServiceManager, + svrLocalStorage: SVRLocalStorageInternal, syncManager: SyncManagerProtocolSwift, + tsAccountManager: TSAccountManagerProtocol, tsConstants: TSConstantsProtocol, twoFAManager: SVR.Shims.OWS2FAManager ) { self.svr2 = SecureValueRecovery2Impl( + accountAttributesUpdater: accountAttributesUpdater, appReadiness: appReadiness, appVersion: appVersion, connectionFactory: connectionFactory, @@ -40,13 +43,13 @@ public class OrchestratingSVRImpl: SecureValueRecovery { keyValueStoreFactory: keyValueStoreFactory, schedulers: schedulers, storageServiceManager: storageServiceManager, + svrLocalStorage: svrLocalStorage, syncManager: syncManager, - tsAccountManager: accountManager, + tsAccountManager: tsAccountManager, tsConstants: tsConstants, twoFAManager: twoFAManager ) self.kbs = KeyBackupServiceImpl( - accountManager: accountManager, appContext: appContext, credentialStorage: credentialStorage, databaseStorage: databaseStorage, @@ -55,7 +58,9 @@ public class OrchestratingSVRImpl: SecureValueRecovery { schedulers: schedulers, signalService: signalService, storageServiceManager: storageServiceManager, + svrLocalStorage: svrLocalStorage, syncManager: syncManager, + tsAccountManager: tsAccountManager, tsConstants: tsConstants, twoFAManager: twoFAManager ) diff --git a/SignalServiceKit/SecureValueRecovery/SVR2/SecureValueRecovery2Impl.swift b/SignalServiceKit/SecureValueRecovery/SVR2/SecureValueRecovery2Impl.swift index 2cc7df51ed..7867fc4be6 100644 --- a/SignalServiceKit/SecureValueRecovery/SVR2/SecureValueRecovery2Impl.swift +++ b/SignalServiceKit/SecureValueRecovery/SVR2/SecureValueRecovery2Impl.swift @@ -9,6 +9,7 @@ import LibSignalClient /// Implementation of `SecureValueRecovery` that talks to the SVR2 server. public class SecureValueRecovery2Impl: SecureValueRecovery { + private let accountAttributesUpdater: AccountAttributesUpdater private let appReadiness: SVR2.Shims.AppReadiness private let appVersion: AppVersion private let clientWrapper: SVR2ClientWrapper @@ -16,15 +17,16 @@ public class SecureValueRecovery2Impl: SecureValueRecovery { private let credentialStorage: SVRAuthCredentialStorage private let db: DB private let keyValueStoreFactory: KeyValueStoreFactory - private let localStorage: SVRLocalStorage + private let localStorage: SVRLocalStorageInternal private let schedulers: Schedulers private let storageServiceManager: StorageServiceManager private let syncManager: SyncManagerProtocolSwift - private let tsAccountManager: SVR.Shims.TSAccountManager + private let tsAccountManager: TSAccountManagerProtocol private let tsConstants: TSConstantsProtocol private let twoFAManager: SVR.Shims.OWS2FAManager public convenience init( + accountAttributesUpdater: AccountAttributesUpdater, appReadiness: SVR2.Shims.AppReadiness, appVersion: AppVersion, connectionFactory: SgxWebsocketConnectionFactory, @@ -33,12 +35,14 @@ public class SecureValueRecovery2Impl: SecureValueRecovery { keyValueStoreFactory: KeyValueStoreFactory, schedulers: Schedulers, storageServiceManager: StorageServiceManager, + svrLocalStorage: SVRLocalStorageInternal, syncManager: SyncManagerProtocolSwift, - tsAccountManager: SVR.Shims.TSAccountManager, + tsAccountManager: TSAccountManagerProtocol, tsConstants: TSConstantsProtocol, twoFAManager: SVR.Shims.OWS2FAManager ) { self.init( + accountAttributesUpdater: accountAttributesUpdater, appReadiness: appReadiness, appVersion: appVersion, clientWrapper: SVR2ClientWrapperImpl(), @@ -48,6 +52,7 @@ public class SecureValueRecovery2Impl: SecureValueRecovery { keyValueStoreFactory: keyValueStoreFactory, schedulers: schedulers, storageServiceManager: storageServiceManager, + svrLocalStorage: svrLocalStorage, syncManager: syncManager, tsAccountManager: tsAccountManager, tsConstants: tsConstants, @@ -58,6 +63,7 @@ public class SecureValueRecovery2Impl: SecureValueRecovery { private let scheduler: Scheduler internal init( + accountAttributesUpdater: AccountAttributesUpdater, appReadiness: SVR2.Shims.AppReadiness, appVersion: AppVersion, clientWrapper: SVR2ClientWrapper, @@ -67,11 +73,13 @@ public class SecureValueRecovery2Impl: SecureValueRecovery { keyValueStoreFactory: KeyValueStoreFactory, schedulers: Schedulers, storageServiceManager: StorageServiceManager, + svrLocalStorage: SVRLocalStorageInternal, syncManager: SyncManagerProtocolSwift, - tsAccountManager: SVR.Shims.TSAccountManager, + tsAccountManager: TSAccountManagerProtocol, tsConstants: TSConstantsProtocol, twoFAManager: SVR.Shims.OWS2FAManager ) { + self.accountAttributesUpdater = accountAttributesUpdater self.appReadiness = appReadiness self.appVersion = appVersion self.clientWrapper = clientWrapper @@ -79,10 +87,10 @@ public class SecureValueRecovery2Impl: SecureValueRecovery { self.credentialStorage = credentialStorage self.db = db self.keyValueStoreFactory = keyValueStoreFactory - self.localStorage = SVRLocalStorage(keyValueStoreFactory: keyValueStoreFactory) self.schedulers = schedulers self.storageServiceManager = storageServiceManager self.syncManager = syncManager + self.localStorage = svrLocalStorage self.tsAccountManager = tsAccountManager self.tsConstants = tsConstants self.twoFAManager = twoFAManager @@ -133,7 +141,7 @@ public class SecureValueRecovery2Impl: SecureValueRecovery { return } let needsRefresh = self.db.read { tx -> Bool in - guard self.tsAccountManager.isRegisteredAndReady(transaction: tx) else { + guard self.tsAccountManager.registrationState(tx: tx).isRegistered else { // Only refresh if registered. return false } @@ -203,7 +211,7 @@ public class SecureValueRecovery2Impl: SecureValueRecovery { // We should update account attributes so we wipe the reglock and // reg recovery password. - tsAccountManager.scheduleAccountAttributesUpdate(authedAccount: authedAccount, transaction: transaction) + accountAttributesUpdater.scheduleAccountAttributesUpdate(authedAccount: authedAccount, tx: transaction) } // MARK: - PIN Management @@ -1126,7 +1134,7 @@ public class SecureValueRecovery2Impl: SecureValueRecovery { Logger.info("Checking old enclaves to wipe") var (isRegistered, enclavesToDeleteFrom) = db.read { tx in return ( - self.tsAccountManager.isRegisteredAndReady(transaction: tx), + self.tsAccountManager.registrationState(tx: tx).isRegistered, self.getOldEnclavesToDeleteFrom(tx) ) } @@ -1168,7 +1176,7 @@ public class SecureValueRecovery2Impl: SecureValueRecovery { return self?.db.read { tx in guard let self, - self.tsAccountManager.isRegisteredAndReady(transaction: tx), + self.tsAccountManager.registrationState(tx: tx).isRegistered, let masterKey = self.localStorage.getMasterKey(tx), let pin = self.twoFAManager.pinCode(transaction: tx) else { @@ -1558,7 +1566,7 @@ public class SecureValueRecovery2Impl: SecureValueRecovery { } // Only continue if we didn't previously have a master key or our master key has changed - guard masterKeyChanged, tsAccountManager.isRegisteredAndReady(transaction: transaction) else { return } + guard masterKeyChanged, tsAccountManager.registrationState(tx: transaction).isRegistered else { return } // Trigger a re-creation of the storage manifest, our keys have changed storageServiceManager.resetLocalData(transaction: transaction) diff --git a/SignalServiceKit/src/Account/LearnMyOwnPniManager.swift b/SignalServiceKit/src/Account/LearnMyOwnPniManager.swift index 18eef4bd93..a02ec2bc41 100644 --- a/SignalServiceKit/src/Account/LearnMyOwnPniManager.swift +++ b/SignalServiceKit/src/Account/LearnMyOwnPniManager.swift @@ -27,7 +27,8 @@ final class LearnMyOwnPniManagerImpl: LearnMyOwnPniManager { private let accountServiceClient: Shims.AccountServiceClient private let pniIdentityKeyChecker: PniIdentityKeyChecker private let preKeyManager: PreKeyManager - private let tsAccountManager: Shims.TSAccountManager + private let registrationStateChangeManager: RegistrationStateChangeManager + private let tsAccountManager: TSAccountManagerProtocol private let db: DB private let keyValueStore: KeyValueStore @@ -39,12 +40,14 @@ final class LearnMyOwnPniManagerImpl: LearnMyOwnPniManager { keyValueStoreFactory: KeyValueStoreFactory, pniIdentityKeyChecker: PniIdentityKeyChecker, preKeyManager: PreKeyManager, + registrationStateChangeManager: RegistrationStateChangeManager, schedulers: Schedulers, - tsAccountManager: Shims.TSAccountManager + tsAccountManager: TSAccountManagerProtocol ) { self.accountServiceClient = accountServiceClient self.pniIdentityKeyChecker = pniIdentityKeyChecker self.preKeyManager = preKeyManager + self.registrationStateChangeManager = registrationStateChangeManager self.tsAccountManager = tsAccountManager self.db = db @@ -88,7 +91,7 @@ final class LearnMyOwnPniManagerImpl: LearnMyOwnPniManager { return .value(()) } - guard tsAccountManager.isPrimaryDevice(tx: tx) else { + guard tsAccountManager.registrationState(tx: tx).isPrimaryDevice ?? true else { logger.info("Skipping PNI learning on linked device.") return .value(()) } @@ -138,8 +141,8 @@ final class LearnMyOwnPniManagerImpl: LearnMyOwnPniManager { } self.db.write { tx in - self.tsAccountManager.updateLocalIdentifiers( - e164: remoteE164, + self.registrationStateChangeManager.didUpdateLocalPhoneNumber( + remoteE164, aci: remoteAci, pni: remotePni, tx: tx @@ -199,12 +202,10 @@ final class LearnMyOwnPniManagerImpl: LearnMyOwnPniManager { extension LearnMyOwnPniManagerImpl { enum Shims { typealias AccountServiceClient = _LearnMyOwnPniManagerImpl_AccountServiceClient_Shim - typealias TSAccountManager = _LearnMyOwnPniManagerImpl_TSAccountManager_Shim } enum Wrappers { typealias AccountServiceClient = _LearnMyOwnPniManagerImpl_AccountServiceClient_Wrapper - typealias TSAccountManager = _LearnMyOwnPniManagerImpl_TSAccountManager_Wrapper } } @@ -225,36 +226,3 @@ class _LearnMyOwnPniManagerImpl_AccountServiceClient_Wrapper: _LearnMyOwnPniMana accountServiceClient.getAccountWhoAmI() } } - -// MARK: TSAccountManager - -protocol _LearnMyOwnPniManagerImpl_TSAccountManager_Shim { - func isPrimaryDevice(tx: DBReadTransaction) -> Bool - func localIdentifiers(tx: DBReadTransaction) -> LocalIdentifiers? - func updateLocalIdentifiers(e164: E164, aci: Aci, pni: Pni, tx: DBWriteTransaction) -} - -class _LearnMyOwnPniManagerImpl_TSAccountManager_Wrapper: _LearnMyOwnPniManagerImpl_TSAccountManager_Shim { - private let tsAccountManager: TSAccountManager - - init(_ tsAccountManager: TSAccountManager) { - self.tsAccountManager = tsAccountManager - } - - func isPrimaryDevice(tx: DBReadTransaction) -> Bool { - return tsAccountManager.isPrimaryDevice(transaction: SDSDB.shimOnlyBridge(tx)) - } - - func localIdentifiers(tx: DBReadTransaction) -> LocalIdentifiers? { - return tsAccountManager.localIdentifiers(transaction: SDSDB.shimOnlyBridge(tx)) - } - - func updateLocalIdentifiers(e164: E164, aci: Aci, pni: Pni, tx: DBWriteTransaction) { - tsAccountManager.updateLocalPhoneNumber( - E164ObjC(e164), - aci: AciObjC(aci), - pni: PniObjC(pni), - transaction: SDSDB.shimOnlyBridge(tx) - ) - } -} diff --git a/SignalServiceKit/src/Account/LinkedDevicePniKeyManager.swift b/SignalServiceKit/src/Account/LinkedDevicePniKeyManager.swift index c71f5a05e3..d3f64ae24e 100644 --- a/SignalServiceKit/src/Account/LinkedDevicePniKeyManager.swift +++ b/SignalServiceKit/src/Account/LinkedDevicePniKeyManager.swift @@ -68,8 +68,9 @@ class LinkedDevicePniKeyManagerImpl: LinkedDevicePniKeyManager { private let kvStore: KeyValueStore private let messageProcessor: Shims.MessageProcessor private let pniIdentityKeyChecker: PniIdentityKeyChecker + private let registrationStateChangeManager: RegistrationStateChangeManager private let schedulers: Schedulers - private let tsAccountManager: Shims.TSAccountManager + private let tsAccountManager: TSAccountManagerProtocol private let isValidating = AtomicBool(false, lock: .init()) @@ -78,19 +79,21 @@ class LinkedDevicePniKeyManagerImpl: LinkedDevicePniKeyManager { keyValueStoreFactory: KeyValueStoreFactory, messageProcessor: Shims.MessageProcessor, pniIdentityKeyChecker: PniIdentityKeyChecker, + registrationStateChangeManager: RegistrationStateChangeManager, schedulers: Schedulers, - tsAccountManager: Shims.TSAccountManager + tsAccountManager: TSAccountManagerProtocol ) { self.db = db self.kvStore = keyValueStoreFactory.keyValueStore(collection: Constants.collection) self.messageProcessor = messageProcessor self.pniIdentityKeyChecker = pniIdentityKeyChecker + self.registrationStateChangeManager = registrationStateChangeManager self.schedulers = schedulers self.tsAccountManager = tsAccountManager } func recordSuspectedIssueWithPniIdentityKey(tx: DBWriteTransaction) { - guard !tsAccountManager.isPrimaryDevice(tx: tx) else { + guard tsAccountManager.registrationState(tx: tx).isPrimaryDevice == false else { logger.warn("Not recording suspected PNI identity key issue - not a linked device!") return } @@ -112,7 +115,7 @@ class LinkedDevicePniKeyManagerImpl: LinkedDevicePniKeyManager { return } - guard !tsAccountManager.isPrimaryDevice(tx: syncTx) else { + guard tsAccountManager.registrationState(tx: syncTx).isPrimaryDevice == false else { logger.info("Skipping validation - not a linked device!") return } @@ -162,12 +165,11 @@ class LinkedDevicePniKeyManagerImpl: LinkedDevicePniKeyManager { return } - if interrupt.shouldResultInUnlink { - logger.warn("Marking as deregistered.") - self.tsAccountManager.setIsDeregistered() - } - self.db.write { tx in + if interrupt.shouldResultInUnlink { + logger.warn("Marking as deregistered.") + self.registrationStateChangeManager.setIsDeregisteredOrDelinked(true, tx: tx) + } self.clearPniMessageDecryptionError(tx: tx) } } @@ -190,12 +192,10 @@ class LinkedDevicePniKeyManagerImpl: LinkedDevicePniKeyManager { extension LinkedDevicePniKeyManagerImpl { enum Shims { typealias MessageProcessor = _LinkedDevicePniKeyManagerImpl_MessageProcessor_Shim - typealias TSAccountManager = _LinkedDevicePniKeyManagerImpl_TSAccountManager_Shim } enum Wrappers { typealias MessageProcessor = _LinkedDevicePniKeyManagerImpl_MessageProcessor_Wrapper - typealias TSAccountManager = _LinkedDevicePniKeyManagerImpl_TSAccountManager_Wrapper } } @@ -216,31 +216,3 @@ class _LinkedDevicePniKeyManagerImpl_MessageProcessor_Wrapper: _LinkedDevicePniK messageProcessor.fetchingAndProcessingCompletePromise() } } - -// MARK: TSAccountManager - -protocol _LinkedDevicePniKeyManagerImpl_TSAccountManager_Shim { - func localIdentifiers(tx: DBReadTransaction) -> LocalIdentifiers? - func isPrimaryDevice(tx: DBReadTransaction) -> Bool - func setIsDeregistered() -} - -class _LinkedDevicePniKeyManagerImpl_TSAccountManager_Wrapper: _LinkedDevicePniKeyManagerImpl_TSAccountManager_Shim { - private let tsAccountManager: TSAccountManager - - init(_ tsAccountManager: TSAccountManager) { - self.tsAccountManager = tsAccountManager - } - - func localIdentifiers(tx: DBReadTransaction) -> LocalIdentifiers? { - return tsAccountManager.localIdentifiers(transaction: SDSDB.shimOnlyBridge(tx)) - } - - func isPrimaryDevice(tx: DBReadTransaction) -> Bool { - return tsAccountManager.isPrimaryDevice(transaction: SDSDB.shimOnlyBridge(tx)) - } - - func setIsDeregistered() { - tsAccountManager.isDeregistered = true - } -} diff --git a/SignalServiceKit/src/Account/PniHelloWorldManager.swift b/SignalServiceKit/src/Account/PniHelloWorldManager.swift index 808ebd5f77..551801c10f 100644 --- a/SignalServiceKit/src/Account/PniHelloWorldManager.swift +++ b/SignalServiceKit/src/Account/PniHelloWorldManager.swift @@ -40,7 +40,7 @@ class PniHelloWorldManagerImpl: PniHelloWorldManager { private let profileManager: Shims.ProfileManager private let schedulers: Schedulers private let signalRecipientStore: Shims.SignalRecipientStore - private let tsAccountManager: Shims.TSAccountManager + private let tsAccountManager: TSAccountManagerProtocol init( database: DB, @@ -53,7 +53,7 @@ class PniHelloWorldManagerImpl: PniHelloWorldManager { profileManager: Shims.ProfileManager, schedulers: Schedulers, signalRecipientStore: Shims.SignalRecipientStore, - tsAccountManager: Shims.TSAccountManager + tsAccountManager: TSAccountManagerProtocol ) { self.database = database self.identityManager = identityManager @@ -71,7 +71,7 @@ class PniHelloWorldManagerImpl: PniHelloWorldManager { func sayHelloWorldIfNecessary(tx syncTx: DBWriteTransaction) { let logger = logger - guard tsAccountManager.isPrimaryDevice(tx: syncTx) else { + guard tsAccountManager.registrationState(tx: syncTx).isRegisteredPrimaryDevice else { logger.info("Skipping PNI Hello World, am a linked device.") return } @@ -116,8 +116,8 @@ class PniHelloWorldManagerImpl: PniHelloWorldManager { return } - let localDeviceId = tsAccountManager.localDeviceId(tx: syncTx) - let localDevicePniRegistrationId = tsAccountManager.getPniRegistrationId(tx: syncTx) + let localDeviceId = tsAccountManager.storedDeviceId(tx: syncTx) + let localDevicePniRegistrationId = tsAccountManager.getOrGeneratePniRegistrationId(tx: syncTx) firstly(on: schedulers.sync) { () -> Guarantee in logger.info("Building PNI distribution parameters.") @@ -182,7 +182,6 @@ extension PniHelloWorldManagerImpl { typealias NetworkManager = _PniHelloWorldManagerImpl_NetworkManager_Shim typealias ProfileManager = _PniHelloWorldManagerImpl_ProfileManager_Shim typealias SignalRecipientStore = _PniHelloWorldManagerImpl_SignalRecipientStore_Shim - typealias TSAccountManager = _PniHelloWorldManagerImpl_TSAccountManager_Shim } enum Wrappers { @@ -190,7 +189,6 @@ extension PniHelloWorldManagerImpl { typealias NetworkManager = _PniHelloWorldManagerImpl_NetworkManager_Wrapper typealias ProfileManager = _PniHelloWorldManagerImpl_ProfileManager_Wrapper typealias SignalRecipientStore = _PniHelloWorldManagerImpl_SignalRecipientStore_Wrapper - typealias TSAccountManager = _PniHelloWorldManagerImpl_TSAccountManager_Wrapper } } @@ -282,36 +280,3 @@ class _PniHelloWorldManagerImpl_SignalRecipientStore_Wrapper: _PniHelloWorldMana ) } } - -// MARK: TSAccountManager - -protocol _PniHelloWorldManagerImpl_TSAccountManager_Shim { - func isPrimaryDevice(tx: DBReadTransaction) -> Bool - func localIdentifiers(tx: DBReadTransaction) -> LocalIdentifiers? - func localDeviceId(tx: DBReadTransaction) -> UInt32 - func getPniRegistrationId(tx: DBWriteTransaction) -> UInt32 -} - -class _PniHelloWorldManagerImpl_TSAccountManager_Wrapper: _PniHelloWorldManagerImpl_TSAccountManager_Shim { - private let tsAccountManager: TSAccountManager - - init(_ tsAccountManager: TSAccountManager) { - self.tsAccountManager = tsAccountManager - } - - func isPrimaryDevice(tx: DBReadTransaction) -> Bool { - return tsAccountManager.isPrimaryDevice(transaction: SDSDB.shimOnlyBridge(tx)) - } - - func localIdentifiers(tx: DBReadTransaction) -> LocalIdentifiers? { - return tsAccountManager.localIdentifiers(transaction: SDSDB.shimOnlyBridge(tx)) - } - - func localDeviceId(tx: DBReadTransaction) -> UInt32 { - return tsAccountManager.storedDeviceId(transaction: SDSDB.shimOnlyBridge(tx)) - } - - func getPniRegistrationId(tx: DBWriteTransaction) -> UInt32 { - return tsAccountManager.getOrGeneratePniRegistrationId(transaction: SDSDB.shimOnlyBridge(tx)) - } -} diff --git a/SignalServiceKit/src/Account/PreKeys/GeneratePreKeyTask.swift b/SignalServiceKit/src/Account/PreKeys/GeneratePreKeyTask.swift index dfb1eefacc..e20939a9bf 100644 --- a/SignalServiceKit/src/Account/PreKeys/GeneratePreKeyTask.swift +++ b/SignalServiceKit/src/Account/PreKeys/GeneratePreKeyTask.swift @@ -167,16 +167,16 @@ extension PreKeyTasks { /// ALWAYS changes the targeted keys (regardless of current key state) internal class Legacy_Generate: GenerateBase { - private let accountManager: PreKey.Operation.Shims.AccountManager private let messageProcessor: PreKey.Operation.Shims.MessageProcessor + private let tsAccountManager: TSAccountManagerProtocol internal init( - accountManager: PreKey.Operation.Shims.AccountManager, context: Generate.Context, - messageProcessor: PreKey.Operation.Shims.MessageProcessor + messageProcessor: PreKey.Operation.Shims.MessageProcessor, + tsAccountManager: TSAccountManagerProtocol ) { - self.accountManager = accountManager self.messageProcessor = messageProcessor + self.tsAccountManager = tsAccountManager super.init(context: context) } @@ -187,7 +187,7 @@ extension PreKeyTasks { let messageProcessingPromise: Promise // Legacy code was reliant on this check. To be removed soon. - if context.db.read(block: accountManager.isRegisteredAndReady(tx:)) { + if context.db.read(block: tsAccountManager.registrationState(tx:)).isRegistered { messageProcessingPromise = messageProcessor.fetchingAndProcessingCompletePromise() } else { messageProcessingPromise = .value(()) diff --git a/SignalServiceKit/src/Account/PreKeys/PreKeyOperation+Shims.swift b/SignalServiceKit/src/Account/PreKeys/PreKeyOperation+Shims.swift index 22fc58cbf6..4442e92948 100644 --- a/SignalServiceKit/src/Account/PreKeys/PreKeyOperation+Shims.swift +++ b/SignalServiceKit/src/Account/PreKeys/PreKeyOperation+Shims.swift @@ -9,35 +9,16 @@ import Foundation extension PreKey.Operation { internal enum Shims { - internal typealias AccountManager = _PreKey_AccountManagerShim internal typealias IdentityManager = _PreKey_IdentityManagerShim internal typealias MessageProcessor = _PreKey_MessageProcessorShim } internal enum Wrappers { - internal typealias AccountManager = _PreKey_AccountManagerWrapper internal typealias IdentityManager = _PreKey_IdentityManagerWrapper internal typealias MessageProcessor = _PreKey_MessageProcessorWrapper } } -// MARK: - AccountManager Shim - -internal protocol _PreKey_AccountManagerShim { - func isRegisteredAndReady(tx: DBReadTransaction) -> Bool -} - -internal class _PreKey_AccountManagerWrapper: _PreKey_AccountManagerShim { - private let accountManager: TSAccountManager - init(accountManager: TSAccountManager) { - self.accountManager = accountManager - } - - func isRegisteredAndReady(tx: DBReadTransaction) -> Bool { - return accountManager.isRegisteredAndReady(transaction: SDSDB.shimOnlyBridge(tx)) - } -} - // MARK: - IdentityManager Shim internal protocol _PreKey_IdentityManagerShim { diff --git a/SignalServiceKit/src/Account/PreKeys/PreKeyTasks.swift b/SignalServiceKit/src/Account/PreKeys/PreKeyTasks.swift index 95286edab2..690810840f 100644 --- a/SignalServiceKit/src/Account/PreKeys/PreKeyTasks.swift +++ b/SignalServiceKit/src/Account/PreKeys/PreKeyTasks.swift @@ -10,7 +10,6 @@ import SignalCoreKit public enum PreKeyTasks { public struct Context { - let accountManager: PreKey.Operation.Shims.AccountManager let dateProvider: DateProvider let db: DB let identityManager: PreKey.Operation.Shims.IdentityManager @@ -19,6 +18,7 @@ public enum PreKeyTasks { let protocolStoreManager: SignalProtocolStoreManager let schedulers: Schedulers let serviceClient: AccountServiceClient + let tsAccountManager: TSAccountManagerProtocol } } @@ -142,9 +142,9 @@ extension PreKeyTasks { PreKey.logger.info("[\(identity)] Legacy prekey operation [\(targets)]") bundlePromise = Legacy_Generate .init( - accountManager: context.accountManager, context: generateContext, - messageProcessor: context.messageProcessor + messageProcessor: context.messageProcessor, + tsAccountManager: context.tsAccountManager ) .runTask( identity: action.identity, diff --git a/SignalServiceKit/src/Account/TSAccountManager/MockTSAccountManager.swift b/SignalServiceKit/src/Account/TSAccountManager/MockTSAccountManager.swift index a2b0d7d57a..8bbe79e899 100644 --- a/SignalServiceKit/src/Account/TSAccountManager/MockTSAccountManager.swift +++ b/SignalServiceKit/src/Account/TSAccountManager/MockTSAccountManager.swift @@ -70,12 +70,20 @@ public class MockTSAccountManager: TSAccountManagerProtocol { return .registered } - public var registrationStateWithMaybeSneakyTransaction: TSRegistrationState { registrationStateMock() } + open var registrationStateWithMaybeSneakyTransaction: TSRegistrationState { registrationStateMock() } - public func registrationState(tx: DBReadTransaction) -> TSRegistrationState { + open func registrationState(tx: DBReadTransaction) -> TSRegistrationState { return registrationStateWithMaybeSneakyTransaction } + public var registrationDateMock: (() -> Date?) = { + return .distantPast + } + + open func registrationDate(tx: DBReadTransaction) -> Date? { + return registrationDateMock() + } + // MARK: - RegistrationIds public var aciRegistrationIdMock: () -> UInt32 = { @@ -135,6 +143,12 @@ public class MockTSAccountManager: TSAccountManagerProtocol { open func isDiscoverableByPhoneNumber(tx: DBReadTransaction) -> Bool { return isDiscoverableByPhoneNumberMock() } + + public var lastSetIsDiscoverableByPhoneNumberMock: () -> Date = { .distantPast } + + open func lastSetIsDiscoverablyByPhoneNumber(tx: DBReadTransaction) -> Date { + return lastSetIsDiscoverableByPhoneNumberMock() + } } #endif diff --git a/SignalServiceKit/src/Account/TSAccountManager/RegistrationStateChangeManager/MockRegistrationStateChangeManager.swift b/SignalServiceKit/src/Account/TSAccountManager/RegistrationStateChangeManager/MockRegistrationStateChangeManager.swift index 3394077905..1f8ee99a55 100644 --- a/SignalServiceKit/src/Account/TSAccountManager/RegistrationStateChangeManager/MockRegistrationStateChangeManager.swift +++ b/SignalServiceKit/src/Account/TSAccountManager/RegistrationStateChangeManager/MockRegistrationStateChangeManager.swift @@ -75,12 +75,11 @@ open class MockRegistrationStateChangeManager: RegistrationStateChangeManager { _ localPhoneNumber: E164, _ localAci: Aci, _ wasPrimaryDevice: Bool - ) -> Bool = { [weak self] phoneNumber, aci, _ in + ) -> Void = { [weak self] phoneNumber, aci, _ in self?.registrationStateMock = { .reregistering(phoneNumber: phoneNumber.stringValue, aci: aci) } - return true } - open func resetForReregistration(localPhoneNumber: E164, localAci: Aci, wasPrimaryDevice: Bool, tx: DBWriteTransaction) -> Bool { + open func resetForReregistration(localPhoneNumber: E164, localAci: Aci, wasPrimaryDevice: Bool, tx: DBWriteTransaction) { return resetForReregistrationMock(localPhoneNumber, localAci, wasPrimaryDevice) } @@ -108,6 +107,27 @@ open class MockRegistrationStateChangeManager: RegistrationStateChangeManager { setWasTransferredMock() } + public var cleanUpTransferStateOnAppLaunchIfNeededMock: () -> Void = {} + + open func cleanUpTransferStateOnAppLaunchIfNeeded() { + cleanUpTransferStateOnAppLaunchIfNeededMock() + } + + public lazy var setIsDeregisteredOrDelinkedMock: ( + _ isDeregisteredOrDelinked: Bool + ) -> Void = { [weak self] isDeregisteredOrDelinked in + let wasPrimary = self?.registrationStateMock().isPrimaryDevice ?? true + if isDeregisteredOrDelinked { + self?.registrationStateMock = wasPrimary ? { .deregistered } : { .delinked } + } else { + self?.registrationStateMock = wasPrimary ? { .registered } : { .provisioned } + } + } + + open func setIsDeregisteredOrDelinked(_ isDeregisteredOrDelinked: Bool, tx: DBWriteTransaction) { + setIsDeregisteredOrDelinkedMock(isDeregisteredOrDelinked) + } + public var unregisterFromServiceMock: (_ auth: ChatServiceAuth) async throws -> Void = { _ in } open func unregisterFromService(auth: ChatServiceAuth) async throws { diff --git a/SignalServiceKit/src/Account/TSAccountManager/RegistrationStateChangeManager/RegistrationStateChangeManager.swift b/SignalServiceKit/src/Account/TSAccountManager/RegistrationStateChangeManager/RegistrationStateChangeManager.swift index 034a60a6a9..2993298017 100644 --- a/SignalServiceKit/src/Account/TSAccountManager/RegistrationStateChangeManager/RegistrationStateChangeManager.swift +++ b/SignalServiceKit/src/Account/TSAccountManager/RegistrationStateChangeManager/RegistrationStateChangeManager.swift @@ -114,7 +114,7 @@ public protocol RegistrationStateChangeManager { localAci: Aci, wasPrimaryDevice: Bool, tx: DBWriteTransaction - ) -> Bool + ) /** * Set when a transfer (incoming or outgoing) begins. @@ -148,6 +148,28 @@ public protocol RegistrationStateChangeManager { */ func setWasTransferred(tx: DBWriteTransaction) + /** + * After we succesully transfer, we need to do some cleanup the next time + * the app launches. + * + * We clean up all transfer in progress state (set isTransferInProgress to false). + * This will also run if the transfer did not finish; thats fine because transfers + * don't survice the app being killed, so its ok to do so on fresh app launch. + * + * This is especially important after a successful transfer; because the db, + * having been copied from the old device's state at the time of transfer, + * will have a transfer in progress, which needs to be cleaned up. + */ + func cleanUpTransferStateOnAppLaunchIfNeeded() + + /** + * When we discover the user is deregistered/delinked via a service response, or conversely + * discover they are _not_ deregistered, we call this method to update state. + * + * No-ops if deregistration state is unchanged. + */ + func setIsDeregisteredOrDelinked(_ isDeregisteredOrDelinked: Bool, tx: DBWriteTransaction) + /** * Unregisters with the server, resetting all app data after completion (if successful). */ diff --git a/SignalServiceKit/src/Account/TSAccountManager/RegistrationStateChangeManager/RegistrationStateChangeManagerImpl.swift b/SignalServiceKit/src/Account/TSAccountManager/RegistrationStateChangeManager/RegistrationStateChangeManagerImpl.swift index b1ff0767e4..745812dd1e 100644 --- a/SignalServiceKit/src/Account/TSAccountManager/RegistrationStateChangeManager/RegistrationStateChangeManagerImpl.swift +++ b/SignalServiceKit/src/Account/TSAccountManager/RegistrationStateChangeManager/RegistrationStateChangeManagerImpl.swift @@ -165,7 +165,7 @@ public class RegistrationStateChangeManagerImpl: RegistrationStateChangeManager localAci: Aci, wasPrimaryDevice: Bool, tx: DBWriteTransaction - ) -> Bool { + ) { tsAccountManager.resetForReregistration(localNumber: localPhoneNumber, localAci: localAci, tx: tx) signalProtocolStoreManager.signalProtocolStore(for: .aci).sessionStore.resetSessionStore(tx: tx) @@ -189,8 +189,6 @@ public class RegistrationStateChangeManagerImpl: RegistrationStateChangeManager self.tmp_postOnboardingStateDidChangeNotification() } } - - return true } public func setIsTransferInProgress(tx: DBWriteTransaction) { @@ -225,6 +223,10 @@ public class RegistrationStateChangeManagerImpl: RegistrationStateChangeManager } } + public func cleanUpTransferStateOnAppLaunchIfNeeded() { + tsAccountManager.cleanUpTransferStateOnAppLaunchIfNeeded() + } + public func unregisterFromService(auth: ChatServiceAuth) async throws { owsAssertBeta(appContext.isMainAppAndActive) let request = OWSRequestFactory.unregisterAccountRequest() @@ -354,3 +356,36 @@ public class _RegistrationStateChangeManagerImpl_SenderKeyStoreWrapper: _Registr senderKeyStore.resetSenderKeyStore(transaction: SDSDB.shimOnlyBridge(tx)) } } + +// MARK: - Unit Tests + +#if TESTABLE_BUILD + +extension RegistrationStateChangeManagerImpl { + + public func registerForTests( + localIdentifiers: LocalIdentifiers, + tx: DBWriteTransaction + ) { + owsAssertDebug(FeatureFlags.storageMode == .grdbTests) + owsAssertDebug(CurrentAppContext().isRunningTests) + + tsAccountManager.initializeLocalIdentifiers( + e164: E164(localIdentifiers.phoneNumber)!, + aci: localIdentifiers.aci, + pni: localIdentifiers.pni, + deviceId: OWSDevice.primaryDeviceId, + serverAuthToken: "", + tmp_setIsOnboarded: true, + tx: tx + ) + didUpdateLocalIdentifiers( + e164: E164(localIdentifiers.phoneNumber)!, + aci: localIdentifiers.aci, + pni: localIdentifiers.pni, + tx: tx + ) + } +} + +#endif diff --git a/SignalServiceKit/src/Account/TSAccountManager/RegistrationStateChangeManager/RegistrationStateChangeManagerObjcTestUtil.swift b/SignalServiceKit/src/Account/TSAccountManager/RegistrationStateChangeManager/RegistrationStateChangeManagerObjcTestUtil.swift new file mode 100644 index 0000000000..a0ff7c656f --- /dev/null +++ b/SignalServiceKit/src/Account/TSAccountManager/RegistrationStateChangeManager/RegistrationStateChangeManagerObjcTestUtil.swift @@ -0,0 +1,24 @@ +// +// Copyright 2023 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only +// + +import Foundation + +@objcMembers +public class RegistrationStateChangeManagerObjcTestUtil: NSObject { + + private override init() { super.init() } + + public static func registerForTests( + localNumber: String, + aci: UUID + ) { + DependenciesBridge.shared.db.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as? RegistrationStateChangeManagerImpl)?.registerForTests( + localIdentifiers: .init(aci: .init(fromUUID: aci), pni: nil, phoneNumber: localNumber), + tx: tx + ) + } + } +} diff --git a/SignalServiceKit/src/Account/TSAccountManager/TSAccountManagerImpl.swift b/SignalServiceKit/src/Account/TSAccountManager/TSAccountManagerImpl.swift index b6d62d1505..2b8a9e5f9a 100644 --- a/SignalServiceKit/src/Account/TSAccountManager/TSAccountManagerImpl.swift +++ b/SignalServiceKit/src/Account/TSAccountManager/TSAccountManagerImpl.swift @@ -76,6 +76,10 @@ public class TSAccountManagerImpl: TSAccountManagerProtocol { return getOrLoadAccountState(tx: tx).registrationState } + public func registrationDate(tx: DBReadTransaction) -> Date? { + return getOrLoadAccountState(tx: tx).registrationDate + } + public var storedServerUsernameWithMaybeTransaction: String? { return getOrLoadAccountStateWithMaybeTransaction().serverUsername } @@ -163,6 +167,10 @@ public class TSAccountManagerImpl: TSAccountManagerProtocol { public func isDiscoverableByPhoneNumber(tx: DBReadTransaction) -> Bool { return getOrLoadAccountState(tx: tx).isDiscoverableByPhoneNumber } + + public func lastSetIsDiscoverablyByPhoneNumber(tx: DBReadTransaction) -> Date { + return getOrLoadAccountState(tx: tx).lastSetIsDiscoverableByPhoneNumberAt + } } extension TSAccountManagerImpl: PhoneNumberDiscoverabilitySetter { @@ -304,6 +312,21 @@ extension TSAccountManagerImpl: LocalIdentifiersSetter { } return true } + + public func cleanUpTransferStateOnAppLaunchIfNeeded() { + guard getOrLoadAccountStateWithMaybeTransaction().isTransferInProgress else { + // No need for cleanup if transfer wasn't already in progress. + return + } + db.write { tx in + mutateWithLock(tx: tx) { + guard kvStore.getBool(Keys.isTransferInProgress, defaultValue: false, transaction: tx) else { + return + } + kvStore.setBool(false, key: Keys.isTransferInProgress, transaction: tx) + } + } + } } extension TSAccountManagerImpl: DBChangeDelegate { @@ -404,6 +427,8 @@ extension TSAccountManagerImpl { let registrationState: TSRegistrationState let registrationDate: Date? + fileprivate let isTransferInProgress: Bool + let isDiscoverableByPhoneNumber: Bool let hasDefinedIsDiscoverableByPhoneNumber: Bool let lastSetIsDiscoverableByPhoneNumberAt: Date @@ -443,9 +468,13 @@ extension TSAccountManagerImpl { isPrimaryDevice = nil } + let isTransferInProgress = kvStore.getBool(Keys.isTransferInProgress, defaultValue: false, transaction: tx) + self.isTransferInProgress = isTransferInProgress + self.registrationState = Self.loadRegistrationState( localIdentifiers: localIdentifiers, isPrimaryDevice: isPrimaryDevice, + isTransferInProgress: isTransferInProgress, kvStore: kvStore, tx: tx ) @@ -512,6 +541,7 @@ extension TSAccountManagerImpl { private static func loadRegistrationState( localIdentifiers: LocalIdentifiers?, isPrimaryDevice: Bool?, + isTransferInProgress: Bool, kvStore: KeyValueStore, tx: DBReadTransaction ) -> TSRegistrationState { @@ -536,11 +566,6 @@ extension TSAccountManagerImpl { transaction: tx ) - let isTransferInProgress = kvStore.getBool( - Keys.isTransferInProgress, - defaultValue: false, - transaction: tx - ) let wasTransferred = kvStore.getBool( Keys.wasTransferred, defaultValue: false, diff --git a/SignalServiceKit/src/Account/TSAccountManager/TSAccountManagerObjcBridge.swift b/SignalServiceKit/src/Account/TSAccountManager/TSAccountManagerObjcBridge.swift new file mode 100644 index 0000000000..ea0036b6b9 --- /dev/null +++ b/SignalServiceKit/src/Account/TSAccountManager/TSAccountManagerObjcBridge.swift @@ -0,0 +1,74 @@ +// +// Copyright 2023 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only +// + +import Foundation + +@objc +@objcMembers +public class TSAccountManagerObjcBridge: NSObject { + + private override init() { super.init() } + + public static var isRegisteredWithMaybeTransaction: Bool { + return DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered + } + + public static func isRegistered(with tx: SDSAnyReadTransaction) -> Bool { + return DependenciesBridge.shared.tsAccountManager.registrationState(tx: tx.asV2Read).isRegistered + } + + public static var isRegisteredPrimaryDeviceWithMaybeTransaction: Bool { + return DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegisteredPrimaryDevice + } + + public static var isPrimaryDeviceWithMaybeTransaction: Bool { + return DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isPrimaryDevice ?? true + } + + public static func isPrimaryDevice(with tx: SDSAnyReadTransaction) -> Bool { + return DependenciesBridge.shared.tsAccountManager.registrationState(tx: tx.asV2Read).isPrimaryDevice ?? true + } + + public static var localIdentifiersWithMaybeTransaction: LocalIdentifiersObjC? { + return DependenciesBridge.shared.tsAccountManager + .localIdentifiersWithMaybeSneakyTransaction + .map(LocalIdentifiersObjC.init) + } + + public static func localIdentifiers(with tx: SDSAnyReadTransaction) -> LocalIdentifiersObjC? { + return DependenciesBridge.shared.tsAccountManager + .localIdentifiers(tx: tx.asV2Read) + .map(LocalIdentifiersObjC.init) + } + + public static var localAciAddressWithMaybeTransaction: SignalServiceAddress? { + return DependenciesBridge.shared.tsAccountManager + .localIdentifiersWithMaybeSneakyTransaction? + .aciAddress + } + + public static func localAciAddress(with tx: SDSAnyReadTransaction) -> SignalServiceAddress? { + return DependenciesBridge.shared.tsAccountManager + .localIdentifiers(tx: tx.asV2Read)? + .aciAddress + } + + public static var storedDeviceIdWithMaybeTransaction: UInt32 { + return DependenciesBridge.shared.tsAccountManager.storedDeviceIdWithMaybeTransaction + } + + public static func storedDeviceId(with tx: SDSAnyReadTransaction) -> UInt32 { + return DependenciesBridge.shared.tsAccountManager.storedDeviceId(tx: tx.asV2Read) + } + + public static var isTransferInProgressWithMaybeTransaction: Bool { + switch DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction { + case .transferringIncoming, .transferringLinkedOutgoing, .transferringPrimaryOutgoing: + return true + default: + return false + } + } +} diff --git a/SignalServiceKit/src/Account/TSAccountManager/TSAccountManagerProtocol.swift b/SignalServiceKit/src/Account/TSAccountManager/TSAccountManagerProtocol.swift index 8f8179bcdf..44298ade85 100644 --- a/SignalServiceKit/src/Account/TSAccountManager/TSAccountManagerProtocol.swift +++ b/SignalServiceKit/src/Account/TSAccountManager/TSAccountManagerProtocol.swift @@ -41,6 +41,8 @@ public protocol TSAccountManagerProtocol { func registrationState(tx: DBReadTransaction) -> TSRegistrationState + func registrationDate(tx: DBReadTransaction) -> Date? + // MARK: - RegistrationIds func getOrGenerateAciRegistrationId(tx: DBWriteTransaction) -> UInt32 @@ -68,6 +70,7 @@ public protocol TSAccountManagerProtocol { func hasDefinedIsDiscoverableByPhoneNumber(tx: DBReadTransaction) -> Bool func isDiscoverableByPhoneNumber(tx: DBReadTransaction) -> Bool + func lastSetIsDiscoverablyByPhoneNumber(tx: DBReadTransaction) -> Date } /// Should only be used in ``PhoneNumberDiscoverabilityManager``, so that necessary @@ -130,4 +133,18 @@ public protocol LocalIdentifiersSetter { /// Returns true if value changed, false otherwise. func setWasTransferred(_ wasTransferred: Bool, tx: DBWriteTransaction) -> Bool + + /** + * After we succesully transfer, we need to do some cleanup the next time + * the app launches. + * + * We clean up all transfer in progress state (set isTransferInProgress to false). + * This will also run if the transfer did not finish; thats fine because transfers + * don't survice the app being killed, so its ok to do so on fresh app launch. + * + * This is especially important after a successful transfer; because the db, + * having been copied from the old device's state at the time of transfer, + * will have a transfer in progress, which needs to be cleaned up. + */ + func cleanUpTransferStateOnAppLaunchIfNeeded() } diff --git a/SignalServiceKit/src/Account/TSAccountManager/TSRegistrationState.swift b/SignalServiceKit/src/Account/TSAccountManager/TSRegistrationState.swift index af3cd46dd7..68cc4c33b8 100644 --- a/SignalServiceKit/src/Account/TSAccountManager/TSRegistrationState.swift +++ b/SignalServiceKit/src/Account/TSAccountManager/TSRegistrationState.swift @@ -6,7 +6,7 @@ import Foundation import LibSignalClient -public enum TSRegistrationState { +public enum TSRegistrationState: Equatable { /// We are unregistered and never have been. /// Depending on the device, the user might register as a primary /// or provision as a linked device. @@ -74,6 +74,22 @@ extension TSRegistrationState { } } + /// Useful for checks that need to happen in the steps that themselves happen + /// during provisioning, but after linking. + public var isRegisteredOrFinishingProvisioning: Bool { + switch self { + case + .unregistered, .reregistering, + .deregistered, .delinked, + .transferringPrimaryOutgoing, .transferringLinkedOutgoing, + .transferringIncoming, + .transferred: + return false + case .registered, .provisioned, .linkedButUnprovisioned: + return true + } + } + public var wasEverRegistered: Bool { switch self { case .unregistered, .transferringIncoming, .linkedButUnprovisioned: @@ -117,6 +133,21 @@ extension TSRegistrationState { .transferringPrimaryOutgoing, .transferringLinkedOutgoing, .transferringIncoming, .transferred: + return false + } + } + + public var isDeregistered: Bool { + switch self { + case + .unregistered, .reregistering, + .linkedButUnprovisioned, + .registered, .provisioned, + .transferringPrimaryOutgoing, .transferringLinkedOutgoing, + .transferringIncoming, + .transferred: + return false + case .deregistered, .delinked: return true } } diff --git a/SignalServiceKit/src/Contacts/Contact.m b/SignalServiceKit/src/Contacts/Contact.m index 6feac873d8..6a97554a0f 100644 --- a/SignalServiceKit/src/Contacts/Contact.m +++ b/SignalServiceKit/src/Contacts/Contact.m @@ -182,10 +182,12 @@ NS_ASSUME_NONNULL_BEGIN NSMutableDictionary *parsedPhoneNumberNameMap = [NSMutableDictionary new]; NSMutableArray *parsedPhoneNumbers = [NSMutableArray new]; + LocalIdentifiersObjC *localIdentifiers = [TSAccountManagerObjcBridge localIdentifiersWithMaybeTransaction]; + // Force unwrap. + NSString *localNumber = localIdentifiers.phoneNumber; for (NSString *phoneNumberString in userTextPhoneNumbers) { - for (PhoneNumber *phoneNumber in - [PhoneNumber tryParsePhoneNumbersFromUserSpecifiedText:phoneNumberString - clientPhoneNumber:[TSAccountManager localNumber]]) { + for (PhoneNumber *phoneNumber in [PhoneNumber tryParsePhoneNumbersFromUserSpecifiedText:phoneNumberString + clientPhoneNumber:localNumber]) { [parsedPhoneNumbers addObject:phoneNumber]; NSString *phoneNumberName = phoneNumberNameMap[phoneNumberString]; if (phoneNumberName) { diff --git a/SignalServiceKit/src/Contacts/Discovery/ContactDiscoveryManager.swift b/SignalServiceKit/src/Contacts/Discovery/ContactDiscoveryManager.swift index e9d4d15c74..9070a8deba 100644 --- a/SignalServiceKit/src/Contacts/Discovery/ContactDiscoveryManager.swift +++ b/SignalServiceKit/src/Contacts/Discovery/ContactDiscoveryManager.swift @@ -104,7 +104,7 @@ public final class ContactDiscoveryManagerImpl: NSObject, ContactDiscoveryManage recipientFetcher: RecipientFetcher, recipientMerger: RecipientMerger, recipientStore: RecipientDataStore, - tsAccountManager: TSAccountManager, + tsAccountManager: TSAccountManagerProtocol, udManager: OWSUDManager, websocketFactory: WebSocketFactory ) { diff --git a/SignalServiceKit/src/Contacts/Discovery/ContactDiscoveryTask.swift b/SignalServiceKit/src/Contacts/Discovery/ContactDiscoveryTask.swift index d1759c81ca..d9cf44ba41 100644 --- a/SignalServiceKit/src/Contacts/Discovery/ContactDiscoveryTask.swift +++ b/SignalServiceKit/src/Contacts/Discovery/ContactDiscoveryTask.swift @@ -16,7 +16,7 @@ final class ContactDiscoveryTaskQueueImpl: ContactDiscoveryTaskQueue { private let recipientFetcher: RecipientFetcher private let recipientMerger: RecipientMerger private let recipientStore: RecipientDataStore - private let tsAccountManager: TSAccountManager + private let tsAccountManager: TSAccountManagerProtocol private let udManager: OWSUDManager private let websocketFactory: WebSocketFactory @@ -25,7 +25,7 @@ final class ContactDiscoveryTaskQueueImpl: ContactDiscoveryTaskQueue { recipientFetcher: RecipientFetcher, recipientMerger: RecipientMerger, recipientStore: RecipientDataStore, - tsAccountManager: TSAccountManager, + tsAccountManager: TSAccountManagerProtocol, udManager: OWSUDManager, websocketFactory: WebSocketFactory ) { @@ -75,7 +75,7 @@ final class ContactDiscoveryTaskQueueImpl: ContactDiscoveryTaskQueue { guard let aci = discoveryResult.aci else { return } - guard let localIdentifiers = tsAccountManager.localIdentifiers(transaction: SDSDB.shimOnlyBridge(tx)) else { + guard let localIdentifiers = tsAccountManager.localIdentifiers(tx: tx) else { throw OWSAssertionError("Not registered.") } let recipient = recipientMerger.applyMergeFromContactDiscovery( diff --git a/SignalServiceKit/src/Contacts/SignalServiceAddress.swift b/SignalServiceKit/src/Contacts/SignalServiceAddress.swift index 35e928f58c..86367b42b8 100644 --- a/SignalServiceKit/src/Contacts/SignalServiceAddress.swift +++ b/SignalServiceKit/src/Contacts/SignalServiceAddress.swift @@ -382,7 +382,7 @@ public class SignalServiceAddress: NSObject, NSCopying, NSSecureCoding, Codable @objc public var isLocalAddress: Bool { - return TSAccountManager.localAddress == self + return DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress == self } @objc diff --git a/SignalServiceKit/src/Contacts/Threads/TSContactThread.swift b/SignalServiceKit/src/Contacts/Threads/TSContactThread.swift index bc386b8077..41ab339750 100644 --- a/SignalServiceKit/src/Contacts/Threads/TSContactThread.swift +++ b/SignalServiceKit/src/Contacts/Threads/TSContactThread.swift @@ -9,7 +9,7 @@ extension TSContactThread { @objc public static func getOrCreateLocalThread(transaction: SDSAnyWriteTransaction) -> TSThread? { - guard let localAddress = tsAccountManager.localAddress(with: transaction) else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aciAddress else { owsFailDebug("Missing localAddress.") return nil } @@ -21,7 +21,7 @@ extension TSContactThread { assert(!Thread.isMainThread) let thread: TSContactThread? = databaseStorage.read { tx in - guard let localAddress = self.tsAccountManager.localAddress(with: tx) else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read)?.aciAddress else { owsFailDebug("Missing localAddress.") return nil } diff --git a/SignalServiceKit/src/Contacts/Threads/TSGroupThread.m b/SignalServiceKit/src/Contacts/Threads/TSGroupThread.m index a8e249dd2b..355eb8f9dc 100644 --- a/SignalServiceKit/src/Contacts/Threads/TSGroupThread.m +++ b/SignalServiceKit/src/Contacts/Threads/TSGroupThread.m @@ -126,7 +126,7 @@ lastVisibleSortIdOnScreenPercentageObsolete:lastVisibleSortIdOnScreenPercentageO return @[]; } - [groupMembers removeObject:TSAccountManager.localAddress]; + [groupMembers removeObject:[TSAccountManagerObjcBridge localAciAddressWith:transaction]]; return [groupMembers copy]; } diff --git a/SignalServiceKit/src/Contacts/Threads/TSGroupThread.swift b/SignalServiceKit/src/Contacts/Threads/TSGroupThread.swift index d373e1a021..074d0a566c 100644 --- a/SignalServiceKit/src/Contacts/Threads/TSGroupThread.swift +++ b/SignalServiceKit/src/Contacts/Threads/TSGroupThread.swift @@ -88,7 +88,7 @@ extension TSGroupThread { let senderAddress: SignalServiceAddress? = { if message is TSOutgoingMessage { - return tsAccountManager.localAddress(with: tx) + return DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read)?.aciAddress } else if let incomingMessage = message as? TSIncomingMessage { return incomingMessage.authorAddress } diff --git a/SignalServiceKit/src/Contacts/Threads/TSThread+OWS.swift b/SignalServiceKit/src/Contacts/Threads/TSThread+OWS.swift index 815b38a72b..6fb2ab9aba 100644 --- a/SignalServiceKit/src/Contacts/Threads/TSThread+OWS.swift +++ b/SignalServiceKit/src/Contacts/Threads/TSThread+OWS.swift @@ -221,7 +221,7 @@ extension TSThread { public func editTarget(transaction: SDSAnyReadTransaction) -> TSOutgoingMessage? { guard let editTargetTimestamp = editTargetTimestamp?.uint64Value, - let localAddress = tsAccountManager.localAddress + let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aciAddress else { return nil } diff --git a/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m b/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m index 1c0d40156d..f3107b99a9 100644 --- a/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m +++ b/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m @@ -114,7 +114,7 @@ NS_ASSUME_NONNULL_BEGIN storyReactionEmoji:nil giftBadge:transcript.giftBadge] buildWithTransaction:transaction]; - LocalIdentifiersObjC *_Nullable localIdentifiers = [self.tsAccountManager localIdentifiersObjCWithTx:transaction]; + LocalIdentifiersObjC *_Nullable localIdentifiers = [TSAccountManagerObjcBridge localIdentifiersWith:transaction]; if (localIdentifiers == nil) { OWSFailDebug(@"Missing localIdentifiers."); return; diff --git a/SignalServiceKit/src/Messages/BlockingManager.swift b/SignalServiceKit/src/Messages/BlockingManager.swift index 25cd0f2255..f7c462eff1 100644 --- a/SignalServiceKit/src/Messages/BlockingManager.swift +++ b/SignalServiceKit/src/Messages/BlockingManager.swift @@ -348,7 +348,7 @@ extension BlockingManager { } private func sendBlockListSyncMessage(force: Bool) { - guard tsAccountManager.isRegistered else { return } + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return } databaseStorage.write { transaction in withCurrentState(transaction: transaction) { state in diff --git a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.swift b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.swift index 028966b511..9068b1b980 100644 --- a/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.swift +++ b/SignalServiceKit/src/Messages/DeviceSyncing/OWSSyncContactsMessage.swift @@ -10,7 +10,7 @@ extension OWSSyncContactsMessage { @objc public func buildPlainTextAttachmentFile(transaction tx: SDSAnyReadTransaction) -> URL? { - guard let localAddress = tsAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read)?.aciAddress else { owsFailDebug("Missing localAddress.") return nil } diff --git a/SignalServiceKit/src/Messages/EarlyMessageManager.swift b/SignalServiceKit/src/Messages/EarlyMessageManager.swift index 1a01d4965a..f3d3764201 100644 --- a/SignalServiceKit/src/Messages/EarlyMessageManager.swift +++ b/SignalServiceKit/src/Messages/EarlyMessageManager.swift @@ -240,7 +240,7 @@ public class EarlyMessageManager: NSObject { associatedMessageTimestamp: UInt64, tx: SDSAnyWriteTransaction ) { - guard let localAci = tsAccountManager.localIdentifiers(transaction: tx)?.aci else { + guard let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read)?.aci else { return owsFailDebug("missing local address") } @@ -342,7 +342,7 @@ public class EarlyMessageManager: NSObject { @objc public func applyPendingMessages(for message: TSMessage, transaction: SDSAnyWriteTransaction) { - guard let localIdentifiers = tsAccountManager.localIdentifiers(transaction: transaction) else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read) else { owsFailDebug("Can't process messages when not registered.") return } @@ -427,7 +427,7 @@ public class EarlyMessageManager: NSObject { Logger.info("Not processing viewed receipt for system story") return } - guard let localIdentifiers = tsAccountManager.localIdentifiers(transaction: transaction) else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read) else { owsFailDebug("Can't process messages when not registered.") return } diff --git a/SignalServiceKit/src/Messages/IncomingPniChangeNumberProcessor.swift b/SignalServiceKit/src/Messages/IncomingPniChangeNumberProcessor.swift new file mode 100644 index 0000000000..e4247b2a80 --- /dev/null +++ b/SignalServiceKit/src/Messages/IncomingPniChangeNumberProcessor.swift @@ -0,0 +1,153 @@ +// +// Copyright 2023 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only +// + +import Foundation +import LibSignalClient + +public protocol IncomingPniChangeNumberProcessor { + + func processIncomingPniChangePhoneNumber( + proto: SSKProtoSyncMessagePniChangeNumber, + updatedPni updatedPniString: String?, + tx: DBWriteTransaction + ) +} + +public class IncomingPniChangeNumberProcessorImpl: IncomingPniChangeNumberProcessor { + + private let identityManager: OWSIdentityManager + private let pniProtocolStore: SignalProtocolStore + private let preKeyManager: PreKeyManager + private let registrationStateChangeManager: RegistrationStateChangeManager + private let tsAccountManager: TSAccountManagerProtocol + + public init( + identityManager: OWSIdentityManager, + pniProtocolStore: SignalProtocolStore, + preKeyManager: PreKeyManager, + registrationStateChangeManager: RegistrationStateChangeManager, + tsAccountManager: TSAccountManagerProtocol + ) { + self.identityManager = identityManager + self.pniProtocolStore = pniProtocolStore + self.preKeyManager = preKeyManager + self.registrationStateChangeManager = registrationStateChangeManager + self.tsAccountManager = tsAccountManager + } + + private struct PniChangePhoneNumberData { + let identityKeyPair: ECKeyPair + let signedPreKey: SignalServiceKit.SignedPreKeyRecord + // TODO (PQXDH): 8/14/2023 - This should me made non-optional after 90 days + let lastResortKyberPreKey: SignalServiceKit.KyberPreKeyRecord? + let registrationId: UInt32 + let e164: E164 + } + + public func processIncomingPniChangePhoneNumber( + proto: SSKProtoSyncMessagePniChangeNumber, + updatedPni updatedPniString: String?, + tx: DBWriteTransaction + ) { + guard + let updatedPniString, + let updatedPni = UUID(uuidString: updatedPniString).map({ Pni(fromUUID: $0) }) + else { + owsFailDebug("Missing or invalid updated PNI string while processing incoming PNI change-number sync message!") + return + } + + guard let localAci = tsAccountManager.localIdentifiers(tx: tx)?.aci else { + owsFailDebug("Missing ACI while processing incoming PNI change-number sync message!") + return + } + + guard let pniChangeData = deserializeIncomingPniChangePhoneNumber(proto: proto) else { + return + } + + // Store in the right places + + // attempt this first and return before writing any other information + do { + if let lastResortKey = pniChangeData.lastResortKyberPreKey { + try pniProtocolStore.kyberPreKeyStore.storeLastResortPreKeyAndMarkAsCurrent( + record: lastResortKey, + tx: tx + ) + } + } catch { + owsFailDebug("Failed to store last resort Kyber prekey") + return + } + + identityManager.setIdentityKeyPair( + pniChangeData.identityKeyPair, + for: .pni, + tx: tx + ) + + pniChangeData.signedPreKey.markAsAcceptedByService() + pniProtocolStore.signedPreKeyStore.storeSignedPreKeyAsAcceptedAndCurrent( + signedPreKeyId: pniChangeData.signedPreKey.id, + signedPreKeyRecord: pniChangeData.signedPreKey, + tx: tx + ) + + tsAccountManager.setPniRegistrationId(pniChangeData.registrationId, tx: tx) + registrationStateChangeManager.didUpdateLocalPhoneNumber( + pniChangeData.e164, + aci: localAci, + pni: updatedPni, + tx: tx + ) + + // Clean up thereafter + + // We need to refresh our one-time pre-keys, and should also refresh + // our signed pre-key so we use the one generated on the primary for as + // little time as possible. + preKeyManager.refreshOneTimePreKeys(forIdentity: .pni, alsoRefreshSignedPreKey: true) + } + + private func deserializeIncomingPniChangePhoneNumber( + proto: SSKProtoSyncMessagePniChangeNumber + ) -> PniChangePhoneNumberData? { + guard + let pniIdentityKeyPairData = proto.identityKeyPair, + let pniSignedPreKeyData = proto.signedPreKey, + proto.hasRegistrationID, proto.registrationID > 0, + let newE164 = E164(proto.newE164) + else { + owsFailDebug("Invalid PNI change number proto, missing fields!") + return nil + } + + do { + let pniIdentityKeyPair = ECKeyPair(try IdentityKeyPair(bytes: pniIdentityKeyPairData)) + let pniSignedPreKey = try LibSignalClient.SignedPreKeyRecord(bytes: pniSignedPreKeyData).asSSKRecord() + + var pniLastResortKyberPreKey: KyberPreKeyRecord? + if let pniLastResortKyberKeyData = proto.lastResortKyberPreKey { + pniLastResortKyberPreKey = try LibSignalClient.KyberPreKeyRecord( + bytes: pniLastResortKyberKeyData + ).asSSKLastResortRecord() + } + + let pniRegistrationId = proto.registrationID + + return PniChangePhoneNumberData( + identityKeyPair: pniIdentityKeyPair, + signedPreKey: pniSignedPreKey, + lastResortKyberPreKey: pniLastResortKyberPreKey, + registrationId: pniRegistrationId, + e164: newE164 + ) + } catch let error { + owsFailDebug("Error while deserializing PNI change-number proto: \(error)") + return nil + } + } +} diff --git a/SignalServiceKit/src/Messages/Interactions/TSInfoMessage+Swift.swift b/SignalServiceKit/src/Messages/Interactions/TSInfoMessage+Swift.swift index 0b7678ae2c..67f57a4f76 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSInfoMessage+Swift.swift +++ b/SignalServiceKit/src/Messages/Interactions/TSInfoMessage+Swift.swift @@ -18,7 +18,7 @@ public extension TSInfoMessage { guard let newGroupModel, - let localIdentifiers = tsAccountManager.localIdentifiers(transaction: transaction) + let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read) else { return GroupUpdateItemBuilderImpl( contactsManager: GroupUpdateItemBuilderImpl.Wrappers.ContactsManager(contactsManager) @@ -45,8 +45,8 @@ public extension TSInfoMessage { return nil } - guard let localIdentifiers = tsAccountManager.localIdentifiers( - transaction: transaction + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers( + tx: transaction.asV2Read ) else { owsFailDebug("Missing local identifiers!") return nil @@ -209,7 +209,7 @@ extension TSInfoMessage { private func paymentsActivationRequestType(transaction: SDSAnyReadTransaction) -> PaymentsInfoMessageType? { guard let paymentActivationRequestSenderAci, - let localAci = tsAccountManager.localIdentifiers(transaction: transaction)?.aci + let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aci else { return nil } @@ -229,7 +229,7 @@ extension TSInfoMessage { private func paymentsActivatedType(transaction: SDSAnyReadTransaction) -> PaymentsInfoMessageType? { guard let paymentActivatedAci, - let localAci = tsAccountManager.localIdentifiers(transaction: transaction)?.aci + let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aci else { return nil } diff --git a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m index 5ebb3e5c65..9b0d04aa34 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m @@ -304,8 +304,9 @@ NSUInteger const TSOutgoingMessageSchemaVersion = 1; NSMutableSet *recipientAddresses = [NSMutableSet new]; if ([self isKindOfClass:[OWSOutgoingSyncMessage class]]) { // 1. Sync messages should only be sent to linked devices. - OWSAssertDebug(TSAccountManager.localAddress); - [recipientAddresses addObject:TSAccountManager.localAddress]; + SignalServiceAddress *localAddress = [TSAccountManagerObjcBridge localAciAddressWith:transaction]; + OWSAssertDebug(localAddress); + [recipientAddresses addObject:localAddress]; } else { // 2. Most messages should only be sent to the current members of the group. [recipientAddresses addObjectsFromArray:[thread recipientAddressesWithTransaction:transaction]]; diff --git a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.swift b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.swift index b78397369c..79533df14f 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.swift +++ b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.swift @@ -193,7 +193,7 @@ public extension TSOutgoingMessage { // No PNI signature needed. return nil } - guard let pni = tsAccountManager.localPni else { + guard let pni = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read)?.pni else { owsFailDebug("missing PNI") return nil } @@ -265,7 +265,7 @@ public extension TSOutgoingMessage { return } - guard let currentPni = tsAccountManager.localPni else { + guard let currentPni = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.pni else { owsFailDebug("missing local PNI") return } @@ -437,7 +437,7 @@ public extension TSOutgoingMessage { throw OWSAssertionError("Missing local thread") } - guard let localIdentifiers = Self.tsAccountManager.localIdentifiers(transaction: tx) else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read) else { throw OWSAssertionError("Missing localIdentifiers.") } diff --git a/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.m b/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.m index 1e8a966162..2b1762a46c 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.m @@ -378,7 +378,7 @@ typedef NS_ENUM(NSUInteger, OWSAttachmentInfoReference) { if ([quotedMessage isKindOfClass:[TSIncomingMessage class]]) { address = ((TSIncomingMessage *)quotedMessage).authorAddress; } else if ([quotedMessage isKindOfClass:[TSOutgoingMessage class]]) { - address = [TSAccountManager localAddress]; + address = [TSAccountManagerObjcBridge localAciAddressWith:transaction]; } else { OWSFailDebug(@"Received message of type: %@", NSStringFromClass(quotedMessage.class)); return nil; diff --git a/SignalServiceKit/src/Messages/MessageFetcherJob.swift b/SignalServiceKit/src/Messages/MessageFetcherJob.swift index 94cd4085f2..35772385e7 100644 --- a/SignalServiceKit/src/Messages/MessageFetcherJob.swift +++ b/SignalServiceKit/src/Messages/MessageFetcherJob.swift @@ -41,7 +41,7 @@ public class MessageFetcherJob: NSObject { // Fetch messages as soon as possible after launching. In particular, when // launching from the background, without this, we end up waiting some extra // seconds before receiving an actionable push notification. - if Self.tsAccountManager.isRegistered { + if DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered { firstly(on: DispatchQueue.global()) { self.run() }.catch(on: DispatchQueue.global()) { error in @@ -208,7 +208,7 @@ public class MessageFetcherJob: NSObject { throw OWSAssertionError("This extension should not fetch messages.") } - guard tsAccountManager.isRegisteredAndReady else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { assert(AppReadiness.isAppReady) Logger.warn("Not registered.") return diff --git a/SignalServiceKit/src/Messages/MessageProcessor.swift b/SignalServiceKit/src/Messages/MessageProcessor.swift index 115744ef0e..c33d8b18be 100644 --- a/SignalServiceKit/src/Messages/MessageProcessor.swift +++ b/SignalServiceKit/src/Messages/MessageProcessor.swift @@ -309,7 +309,7 @@ public class MessageProcessor: NSObject { private func drainPendingEnvelopes() { guard CurrentAppContext().shouldProcessIncomingMessages else { return } - guard tsAccountManager.isRegisteredAndReady else { return } + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return } guard Self.messagePipelineSupervisor.isMessageProcessingPermitted else { return } @@ -354,10 +354,10 @@ public class MessageProcessor: NSObject { // This is only called via `drainPendingEnvelopes`, and that confirms that // we're registered. If we're registered, we must have `LocalIdentifiers`, // so this (generally) shouldn't fail. - guard let localIdentifiers = tsAccountManager.localIdentifiers(transaction: tx) else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read) else { return } - let localDeviceId = tsAccountManager.storedDeviceId(transaction: tx) + let localDeviceId = DependenciesBridge.shared.tsAccountManager.storedDeviceId(tx: tx.asV2Read) var remainingEnvelopes = batchEnvelopes while !remainingEnvelopes.isEmpty { diff --git a/SignalServiceKit/src/Messages/MessageSender+Errors.swift b/SignalServiceKit/src/Messages/MessageSender+Errors.swift index b96aaf3574..c684baf053 100644 --- a/SignalServiceKit/src/Messages/MessageSender+Errors.swift +++ b/SignalServiceKit/src/Messages/MessageSender+Errors.swift @@ -384,7 +384,7 @@ public class AppDeregisteredError: NSObject, CustomNSError, IsRetryableProvider, } public var localizedDescription: String { - TSAccountManager.shared.isPrimaryDevice + DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isPrimaryDevice ?? true ? OWSLocalizedString("ERROR_SENDING_DEREGISTERED", comment: "Error indicating a send failure due to a deregistered application.") : OWSLocalizedString("ERROR_SENDING_DELINKED", diff --git a/SignalServiceKit/src/Messages/MessageSender+SenderKey.swift b/SignalServiceKit/src/Messages/MessageSender+SenderKey.swift index 7cd1f97ed3..c7e5731866 100644 --- a/SignalServiceKit/src/Messages/MessageSender+SenderKey.swift +++ b/SignalServiceKit/src/Messages/MessageSender+SenderKey.swift @@ -324,7 +324,7 @@ extension MessageSender { return databaseStorage.write(.promise) { writeTx -> [OWSMessageSend] in // Here we fetch all of the recipients that need an SKDM // We then construct an OWSMessageSend for each recipient that needs an SKDM. - guard let localIdentifiers = self.tsAccountManager.localIdentifiers(transaction: writeTx) else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: writeTx.asV2Read) else { throw OWSAssertionError("Not registered.") } @@ -345,7 +345,7 @@ extension MessageSender { guard let skdmBytes = self.senderKeyStore.skdmBytesForThread( thread, localAci: localIdentifiers.aci, - localDeviceId: self.tsAccountManager.storedDeviceId(transaction: writeTx), + localDeviceId: DependenciesBridge.shared.tsAccountManager.storedDeviceId(tx: writeTx.asV2Read), tx: writeTx ) else { throw OWSAssertionError("Couldn't build SKDM") diff --git a/SignalServiceKit/src/Messages/MessageSender.swift b/SignalServiceKit/src/Messages/MessageSender.swift index b2014cf3a5..b3cbc27c17 100644 --- a/SignalServiceKit/src/Messages/MessageSender.swift +++ b/SignalServiceKit/src/Messages/MessageSender.swift @@ -444,7 +444,7 @@ extension MessageSender { in thread: TSThread, tx: SDSAnyReadTransaction ) throws -> [SignalServiceAddress] { - guard let localAddress = tsAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read)?.aciAddress else { throw OWSAssertionError("Missing localAddress.") } if message.isSyncMessage { @@ -584,7 +584,7 @@ extension MessageSender { if DependenciesBridge.shared.appExpiry.isExpired { return Promise(error: AppExpiredError()) } - if tsAccountManager.isDeregistered || tsAccountManager.isReregistering { + if DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered.negated { return Promise(error: AppDeregisteredError()) } if message.shouldBeSaved { @@ -723,7 +723,7 @@ extension MessageSender { throw OWSAssertionError("Couldn't build message.") } - guard let localIdentifiers = tsAccountManager.localIdentifiers(transaction: tx) else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read) else { throw OWSAssertionError("Not registered.") } @@ -940,7 +940,7 @@ extension MessageSender { if let thread = message.thread(tx: tx) as? TSContactThread, self.shouldMessageSendUnhideRecipient(message), - let localAddress = tsAccountManager.localAddress(with: tx), + let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read)?.aciAddress, !localAddress.isEqualToAddress(thread.contactAddress) { DependenciesBridge.shared.recipientHidingManager.removeHiddenRecipient( @@ -966,7 +966,12 @@ extension MessageSender { if message.isSyncMessage { return } - let thread = self.databaseStorage.read { tx in message.thread(tx: tx) } + let (thread, deviceId) = self.databaseStorage.read { tx in + return ( + message.thread(tx: tx), + DependenciesBridge.shared.tsAccountManager.storedDeviceId(tx: tx.asV2Read) + ) + } guard let contactThread = thread as? TSContactThread, contactThread.contactAddress.isLocalAddress else { return } @@ -975,14 +980,14 @@ extension MessageSender { for sendingAddress in message.sendingRecipientAddresses() { message.update( withReadRecipient: sendingAddress, - deviceId: self.tsAccountManager.storedDeviceId, + deviceId: deviceId, readTimestamp: message.timestamp, tx: tx ) if message.isVoiceMessage || message.isViewOnceMessage { message.update( withViewedRecipient: sendingAddress, - deviceId: self.tsAccountManager.storedDeviceId, + deviceId: deviceId, viewedTimestamp: message.timestamp, tx: tx ) @@ -1128,7 +1133,7 @@ extension MessageSender { owsAssertDebug(messageSend.message.canSendToLocalAddress) let hasMessageForLinkedDevice = deviceMessages.contains(where: { - $0.destinationDeviceId != tsAccountManager.storedDeviceId + $0.destinationDeviceId != DependenciesBridge.shared.tsAccountManager.storedDeviceIdWithMaybeTransaction }) if hasMessageForLinkedDevice { @@ -1164,7 +1169,7 @@ extension MessageSender { var recipientDeviceIds = registeredRecipient.deviceIds if messageSend.localIdentifiers.contains(serviceId: messageSend.serviceId) { - let localDeviceId = tsAccountManager.storedDeviceId + let localDeviceId = DependenciesBridge.shared.tsAccountManager.storedDeviceIdWithMaybeTransaction recipientDeviceIds.removeAll(where: { $0 == localDeviceId }) } diff --git a/SignalServiceKit/src/Messages/OWSIdentityManager.swift b/SignalServiceKit/src/Messages/OWSIdentityManager.swift index c3e73f9b7b..9537242ddf 100644 --- a/SignalServiceKit/src/Messages/OWSIdentityManager.swift +++ b/SignalServiceKit/src/Messages/OWSIdentityManager.swift @@ -50,12 +50,6 @@ public protocol OWSIdentityManager { ) func processIncomingVerifiedProto(_ verified: SSKProtoVerified, tx: DBWriteTransaction) throws - func processIncomingPniChangePhoneNumber( - proto: SSKProtoSyncMessagePniChangeNumber, - updatedPni updatedPniString: String?, - preKeyManager: PreKeyManager, - tx: DBWriteTransaction - ) func shouldSharePhoneNumber(with serviceId: ServiceId, tx: DBReadTransaction) -> Bool func setShouldSharePhoneNumber(with recipient: Aci, tx: DBWriteTransaction) @@ -101,12 +95,12 @@ extension OWSIdentity: CustomStringConvertible { public class IdentityStore: IdentityKeyStore { private let identityManager: OWSIdentityManager private let identityKeyPair: IdentityKeyPair - private let tsAccountManager: TSAccountManager + private let tsAccountManager: TSAccountManagerProtocol fileprivate init( identityManager: OWSIdentityManager, identityKeyPair: IdentityKeyPair, - tsAccountManager: TSAccountManager + tsAccountManager: TSAccountManagerProtocol ) { self.identityManager = identityManager self.identityKeyPair = identityKeyPair @@ -119,7 +113,7 @@ public class IdentityStore: IdentityKeyStore { public func localRegistrationId(context: StoreContext) throws -> UInt32 { // PNI TODO: Return the PNI registration ID here if needed. - return tsAccountManager.getOrGenerateRegistrationId(transaction: context.asTransaction) + return tsAccountManager.getOrGenerateAciRegistrationId(tx: context.asTransaction.asV2Write) } public func saveIdentity( @@ -206,7 +200,7 @@ public class OWSIdentityManagerImpl: OWSIdentityManager { private let schedulers: Schedulers private let shareMyPhoneNumberStore: KeyValueStore private let storageServiceManager: StorageServiceManager - private let tsAccountManager: TSAccountManager + private let tsAccountManager: TSAccountManagerProtocol public init( aciProtocolStore: SignalProtocolStore, @@ -219,7 +213,7 @@ public class OWSIdentityManagerImpl: OWSIdentityManager { recipientFetcher: RecipientFetcher, schedulers: Schedulers, storageServiceManager: StorageServiceManager, - tsAccountManager: TSAccountManager + tsAccountManager: TSAccountManagerProtocol ) { self.aciProtocolStore = aciProtocolStore self.db = db @@ -528,7 +522,7 @@ public class OWSIdentityManagerImpl: OWSIdentityManager { } private func syncQueuedVerificationStates() { - guard tsAccountManager.isRegisteredAndReady else { + guard tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return } guard let thread = TSContactThread.getOrCreateLocalThreadWithSneakyTransaction() else { @@ -861,127 +855,6 @@ public class OWSIdentityManagerImpl: OWSIdentityManager { } } - // MARK: - PNIs - - private struct PniChangePhoneNumberData { - let identityKeyPair: ECKeyPair - let signedPreKey: SignalServiceKit.SignedPreKeyRecord - // TODO (PQXDH): 8/14/2023 - This should me made non-optional after 90 days - let lastResortKyberPreKey: SignalServiceKit.KyberPreKeyRecord? - let registrationId: UInt32 - let e164: E164 - } - - public func processIncomingPniChangePhoneNumber( - proto: SSKProtoSyncMessagePniChangeNumber, - updatedPni updatedPniString: String?, - preKeyManager: PreKeyManager, - tx: DBWriteTransaction - ) { - guard - let updatedPniString, - let updatedPni = UUID(uuidString: updatedPniString).map({ Pni(fromUUID: $0) }) - else { - owsFailDebug("Missing or invalid updated PNI string while processing incoming PNI change-number sync message!") - return - } - - guard let localAci = tsAccountManager.localIdentifiers(transaction: SDSDB.shimOnlyBridge(tx))?.aci else { - owsFailDebug("Missing ACI while processing incoming PNI change-number sync message!") - return - } - - guard let pniChangeData = deserializeIncomingPniChangePhoneNumber(proto: proto) else { - return - } - - // Store in the right places - - // attempt this first and return before writing any other information - do { - if let lastResortKey = pniChangeData.lastResortKyberPreKey { - try pniProtocolStore.kyberPreKeyStore.storeLastResortPreKeyAndMarkAsCurrent( - record: lastResortKey, - tx: tx - ) - } - } catch { - owsFailDebug("Failed to store last resort Kyber prekey") - return - } - - setIdentityKeyPair( - pniChangeData.identityKeyPair, - for: .pni, - tx: tx - ) - - pniChangeData.signedPreKey.markAsAcceptedByService() - pniProtocolStore.signedPreKeyStore.storeSignedPreKeyAsAcceptedAndCurrent( - signedPreKeyId: pniChangeData.signedPreKey.id, - signedPreKeyRecord: pniChangeData.signedPreKey, - tx: tx - ) - - tsAccountManager.setPniRegistrationId( - newRegistrationId: pniChangeData.registrationId, - transaction: SDSDB.shimOnlyBridge(tx) - ) - - tsAccountManager.updateLocalPhoneNumber( - E164ObjC(pniChangeData.e164), - aci: AciObjC(localAci), - pni: PniObjC(updatedPni), - transaction: SDSDB.shimOnlyBridge(tx) - ) - - // Clean up thereafter - - // We need to refresh our one-time pre-keys, and should also refresh - // our signed pre-key so we use the one generated on the primary for as - // little time as possible. - preKeyManager.refreshOneTimePreKeys(forIdentity: .pni, alsoRefreshSignedPreKey: true) - } - - private func deserializeIncomingPniChangePhoneNumber( - proto: SSKProtoSyncMessagePniChangeNumber - ) -> PniChangePhoneNumberData? { - guard - let pniIdentityKeyPairData = proto.identityKeyPair, - let pniSignedPreKeyData = proto.signedPreKey, - proto.hasRegistrationID, proto.registrationID > 0, - let newE164 = E164(proto.newE164) - else { - owsFailDebug("Invalid PNI change number proto, missing fields!") - return nil - } - - do { - let pniIdentityKeyPair = ECKeyPair(try IdentityKeyPair(bytes: pniIdentityKeyPairData)) - let pniSignedPreKey = try LibSignalClient.SignedPreKeyRecord(bytes: pniSignedPreKeyData).asSSKRecord() - - var pniLastResortKyberPreKey: KyberPreKeyRecord? - if let pniLastResortKyberKeyData = proto.lastResortKyberPreKey { - pniLastResortKyberPreKey = try LibSignalClient.KyberPreKeyRecord( - bytes: pniLastResortKyberKeyData - ).asSSKLastResortRecord() - } - - let pniRegistrationId = proto.registrationID - - return PniChangePhoneNumberData( - identityKeyPair: pniIdentityKeyPair, - signedPreKey: pniSignedPreKey, - lastResortKyberPreKey: pniLastResortKyberPreKey, - registrationId: pniRegistrationId, - e164: newE164 - ) - } catch let error { - owsFailDebug("Error while deserializing PNI change-number proto: \(error)") - return nil - } - } - // MARK: - Phone Number Sharing public func shouldSharePhoneNumber(with recipient: ServiceId, tx: DBReadTransaction) -> Bool { diff --git a/SignalServiceKit/src/Messages/OWSMessageDecrypter.swift b/SignalServiceKit/src/Messages/OWSMessageDecrypter.swift index 84f8ed1fce..eedbb62817 100644 --- a/SignalServiceKit/src/Messages/OWSMessageDecrypter.swift +++ b/SignalServiceKit/src/Messages/OWSMessageDecrypter.swift @@ -439,7 +439,7 @@ public class OWSMessageDecrypter: OWSMessageHandler { ) sendReactiveProfileKeyIfNecessary(to: sourceAci, tx: transaction) case .preKey: - if tsAccountManager.isRegisteredAndReady(transaction: transaction) { + if DependenciesBridge.shared.tsAccountManager.registrationState(tx: transaction.asV2Read).isRegistered { DependenciesBridge.shared.preKeyManager.checkPreKeysIfNecessary(tx: transaction.asV2Read) } let message = try PreKeySignalMessage(bytes: encryptedData) @@ -500,7 +500,7 @@ public class OWSMessageDecrypter: OWSMessageHandler { } private func sendReactiveProfileKeyIfNecessary(to sourceAci: Aci, tx transaction: SDSAnyWriteTransaction) { - if tsAccountManager.localIdentifiers(transaction: transaction)?.aci == sourceAci { + if DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aci == sourceAci { return } @@ -600,7 +600,10 @@ public class OWSMessageDecrypter: OWSMessageHandler { ) } - if decryptResult.messageType == .prekey, tsAccountManager.isRegisteredAndReady(transaction: transaction) { + if + decryptResult.messageType == .prekey, + DependenciesBridge.shared.tsAccountManager.registrationState(tx: transaction.asV2Read).isRegistered + { DependenciesBridge.shared.preKeyManager.checkPreKeysIfNecessary(tx: transaction.asV2Read) } diff --git a/SignalServiceKit/src/Messages/OWSMessageManager.m b/SignalServiceKit/src/Messages/OWSMessageManager.m index 6e8e6c4a9c..7fba6be5e1 100644 --- a/SignalServiceKit/src/Messages/OWSMessageManager.m +++ b/SignalServiceKit/src/Messages/OWSMessageManager.m @@ -282,7 +282,7 @@ NS_ASSUME_NONNULL_BEGIN if ([dataMessage hasProfileKey]) { NSData *profileKey = [dataMessage profileKey]; SignalServiceAddress *address = decryptedEnvelope.envelope.sourceAddress; - if (address.isLocalAddress && self.tsAccountManager.isPrimaryDevice) { + if (address.isLocalAddress && [TSAccountManagerObjcBridge isPrimaryDeviceWithMaybeTransaction]) { OWSLogVerbose(@"Ignoring profile key for local device on primary."); } else if (profileKey.length != kAES256_KeyByteLength) { OWSFailDebug( @@ -448,7 +448,7 @@ NS_ASSUME_NONNULL_BEGIN if (![thread isKindOfClass:[TSContactThread class]]) { return; } - LocalIdentifiersObjC *localIdentifiers = [self.tsAccountManager localIdentifiersObjCWithTx:transaction]; + LocalIdentifiersObjC *localIdentifiers = [TSAccountManagerObjcBridge localIdentifiersWith:transaction]; if (localIdentifiers == nil) { OWSFailDebug(@"Not registered."); return; @@ -572,9 +572,12 @@ NS_ASSUME_NONNULL_BEGIN [self ensureGroupIdMapping:envelope withCallMessage:callMessage transaction:transaction]; // If destinationDevice is defined, ignore messages not addressed to this device. + uint32_t deviceId = [TSAccountManagerObjcBridge storedDeviceIdWith:transaction]; if ([callMessage hasDestinationDeviceID]) { - if ([callMessage destinationDeviceID] != self.tsAccountManager.storedDeviceId) { - OWSLogInfo(@"Ignoring call message that is not for this device! intended: %u this: %u", [callMessage destinationDeviceID], self.tsAccountManager.storedDeviceId); + if ([callMessage destinationDeviceID] != deviceId) { + OWSLogInfo(@"Ignoring call message that is not for this device! intended: %u this: %u", + [callMessage destinationDeviceID], + deviceId); return; } } @@ -582,7 +585,7 @@ NS_ASSUME_NONNULL_BEGIN if ([callMessage hasProfileKey]) { NSData *profileKey = [callMessage profileKey]; SignalServiceAddress *address = envelope.sourceAddress; - if (address.isLocalAddress && self.tsAccountManager.isPrimaryDevice) { + if (address.isLocalAddress && [TSAccountManagerObjcBridge isPrimaryDeviceWith:transaction]) { OWSLogVerbose(@"Ignoring profile key for local device on primary."); } else if (profileKey.length != kAES256_KeyByteLength) { OWSFailDebug( diff --git a/SignalServiceKit/src/Messages/OWSMessageManager.swift b/SignalServiceKit/src/Messages/OWSMessageManager.swift index 9d5d7ebcb2..cd8b89a94f 100644 --- a/SignalServiceKit/src/Messages/OWSMessageManager.swift +++ b/SignalServiceKit/src/Messages/OWSMessageManager.swift @@ -265,7 +265,7 @@ extension OWSMessageManager { serverDeliveryTimestamp: UInt64, tx: SDSAnyWriteTransaction ) { - guard decryptedEnvelope.sourceAci == tsAccountManager.localIdentifiers(transaction: tx)?.aci else { + guard decryptedEnvelope.sourceAci == DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read)?.aci else { // Sync messages should only come from linked devices. owsFailDebug("Received sync message from another user.") return @@ -494,11 +494,10 @@ extension OWSMessageManager { callEvent, messageTimestamp: decryptedEnvelope.timestamp, transaction: tx ) } else if let pniChangeNumber = syncMessage.pniChangeNumber { - let identityManager = DependenciesBridge.shared.identityManager - identityManager.processIncomingPniChangePhoneNumber( + let pniProcessor = DependenciesBridge.shared.incomingPniChangeNumberProcessor + pniProcessor.processIncomingPniChangePhoneNumber( proto: pniChangeNumber, updatedPni: envelope.updatedPni, - preKeyManager: DependenciesBridge.shared.preKeyManager, tx: tx.asV2Write ) } else { @@ -507,7 +506,7 @@ extension OWSMessageManager { } private func handleIncomingSyncRequest(_ request: SSKProtoSyncMessageRequest, tx: SDSAnyWriteTransaction) { - guard tsAccountManager.isRegisteredPrimaryDevice else { + guard DependenciesBridge.shared.tsAccountManager.registrationState(tx: tx.asV2Read).isRegisteredPrimaryDevice else { // Don't respond to sync requests from a linked device. return } @@ -596,7 +595,7 @@ extension OWSMessageManager { throw OWSGenericError("Can't receive DEMs at our PNI.") } let errorMessage = try DecryptionErrorMessage(bytes: bytes) - guard errorMessage.deviceId == tsAccountManager.storedDeviceId(transaction: writeTx) else { + guard errorMessage.deviceId == DependenciesBridge.shared.tsAccountManager.storedDeviceId(tx: writeTx.asV2Read) else { Logger.info("Received a DecryptionError message targeting a linked device. Ignoring.") return } @@ -912,7 +911,7 @@ extension OWSMessageManager { let aci = envelope.sourceAci let deviceId = envelope.sourceDeviceId - guard aci == tsAccountManager.localIdentifiers(transaction: tx)?.aci else { + guard aci == DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read)?.aci else { return } diff --git a/SignalServiceKit/src/Messages/OWSReceiptManager.swift b/SignalServiceKit/src/Messages/OWSReceiptManager.swift index b20b3aadbd..6394dd1da7 100644 --- a/SignalServiceKit/src/Messages/OWSReceiptManager.swift +++ b/SignalServiceKit/src/Messages/OWSReceiptManager.swift @@ -165,7 +165,7 @@ public extension OWSReceiptManager { func enqueueLinkedDeviceViewedReceipt(forOutgoingMessage message: TSOutgoingMessage, transaction: SDSAnyWriteTransaction) { - guard let localAddress = self.tsAccountManager.localAddress(with: transaction) else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aciAddress else { owsFailDebug("no local address") return } @@ -313,7 +313,7 @@ public extension OWSReceiptManager { let messages = interactions.compactMap({ $0 as? TSMessage }).filter { switch $0 { case is TSOutgoingMessage: - return senderAci == tsAccountManager.localIdentifiers(transaction: tx)?.aci + return senderAci == DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read)?.aci case let incomingMessage as TSIncomingMessage: return senderAci == incomingMessage.authorAddress.serviceId default: @@ -398,7 +398,7 @@ public extension OWSReceiptManager { return } - let localAci = self.tsAccountManager.localIdentifiers?.aci + let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aci let readTimestamp = Date.ows_millisecondTimestamp() let maxBatchSize = 500 @@ -759,7 +759,7 @@ extension OWSReceiptManager { } return true } - let localAci = tsAccountManager.localIdentifiers(transaction: tx)!.aci + let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read)!.aci let storyMessage = StoryFinder.story(timestamp: sentTimestamp, author: localAci, transaction: tx) if let storyMessage { if StoryManager.areViewReceiptsEnabled { diff --git a/SignalServiceKit/src/Messages/Reactions/OutgoingReactionMessage.swift b/SignalServiceKit/src/Messages/Reactions/OutgoingReactionMessage.swift index 22f95e1a36..dc5273b0f0 100644 --- a/SignalServiceKit/src/Messages/Reactions/OutgoingReactionMessage.swift +++ b/SignalServiceKit/src/Messages/Reactions/OutgoingReactionMessage.swift @@ -21,7 +21,7 @@ extension OWSOutgoingReactionMessage { let messageAuthor: Aci? switch message { case is TSOutgoingMessage: - messageAuthor = tsAccountManager.localIdentifiers(transaction: tx)?.aci + messageAuthor = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read)?.aci case let message as TSIncomingMessage: messageAuthor = message.authorAddress.aci default: @@ -50,7 +50,7 @@ extension OWSOutgoingReactionMessage { return } - guard let localAci = tsAccountManager.localIdentifiers(transaction: tx)?.aci else { + guard let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read)?.aci else { owsFailDebug("Missing localAci.") return } diff --git a/SignalServiceKit/src/Messages/Reactions/ReactionManager.swift b/SignalServiceKit/src/Messages/Reactions/ReactionManager.swift index ea96958ba9..c0dbbd7d98 100644 --- a/SignalServiceKit/src/Messages/Reactions/ReactionManager.swift +++ b/SignalServiceKit/src/Messages/Reactions/ReactionManager.swift @@ -71,7 +71,7 @@ public class ReactionManager: NSObject { Logger.info("Sending reaction, isRemoving: \(isRemoving)") - guard let localAci = tsAccountManager.localIdentifiers(transaction: tx)?.aci else { + guard let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read)?.aci else { throw OWSAssertionError("missing local address") } @@ -181,7 +181,7 @@ public class ReactionManager: NSObject { ) // If this is a reaction to a message we sent, notify the user. - let localAci = tsAccountManager.localIdentifiers(transaction: transaction)?.aci + let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aci if let reaction, let message = message as? TSOutgoingMessage, reactor != localAci { self.notificationsManager.notifyUser( forReaction: reaction, @@ -220,7 +220,7 @@ public class ReactionManager: NSObject { let message: TSMessage - let localAci = tsAccountManager.localIdentifiers(transaction: transaction)?.aci + let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aci if reactor == localAci { let builder = TSOutgoingMessageBuilder(thread: thread) populateStoryContext(on: builder) diff --git a/SignalServiceKit/src/Messages/RecipientHidingManager+SignalServiceAddress.swift b/SignalServiceKit/src/Messages/RecipientHidingManager+SignalServiceAddress.swift index bd0ae4987d..7e626aad32 100644 --- a/SignalServiceKit/src/Messages/RecipientHidingManager+SignalServiceAddress.swift +++ b/SignalServiceKit/src/Messages/RecipientHidingManager+SignalServiceAddress.swift @@ -39,7 +39,7 @@ extension RecipientHidingManager { /// - Returns: True if the address is hidden. public func isHiddenAddress(_ address: SignalServiceAddress, tx: DBReadTransaction) -> Bool { guard - let localAddress = tsAccountManager.localAddress(with: SDSDB.shimOnlyBridge(tx)), + let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx)?.aciAddress, !localAddress.isEqualToAddress(address) else { return false @@ -63,7 +63,7 @@ extension RecipientHidingManager { throw RecipientHidingError.invalidRecipientAddress(address) } guard - let localAddress = tsAccountManager.localAddress(with: SDSDB.shimOnlyBridge(tx)), + let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx)?.aciAddress, !localAddress.isEqualToAddress(address) else { throw RecipientHidingError.cannotHideLocalAddress @@ -84,7 +84,7 @@ extension RecipientHidingManager { /// - Parameter tx: The transaction to use for database operations. public func removeHiddenRecipient(_ address: SignalServiceAddress, wasLocallyInitiated: Bool, tx: DBWriteTransaction) { guard - let localAddress = tsAccountManager.localAddress(with: SDSDB.shimOnlyBridge(tx)), + let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx)?.aciAddress, !localAddress.isEqualToAddress(address) else { owsFailDebug("Cannot unhide the local address") @@ -105,12 +105,4 @@ extension RecipientHidingManager { private func recipient(from address: SignalServiceAddress, tx: DBReadTransaction) -> SignalRecipient? { return SignalRecipient.fetchRecipient(for: address, onlyIfRegistered: false, tx: SDSDB.shimOnlyBridge(tx)) } - - /// It is not good form to access global state. It is also not good form to do "work" in an extension. - /// Since these extension methods _already_ make testing impossible, since they cannot be overriden - /// in a mock subclass, we may as well access global state in a way that breaks tests. - /// If you find yourself hitting this in tests: DONT USE THE FUNCTIONS IN THIS EXTENSION. - /// Ultimately, if you want to be able to stub out RecipientHidingManager, you should use - /// its SignalRecipient based methods and mock out the production of SignalRecipient instances. - private var tsAccountManager: TSAccountManager { .shared } } diff --git a/SignalServiceKit/src/Messages/RecipientHidingManager.swift b/SignalServiceKit/src/Messages/RecipientHidingManager.swift index f8ad30a8b4..7a75bea121 100644 --- a/SignalServiceKit/src/Messages/RecipientHidingManager.swift +++ b/SignalServiceKit/src/Messages/RecipientHidingManager.swift @@ -80,13 +80,13 @@ public final class RecipientHidingManagerImpl: RecipientHidingManager { private let profileManager: ProfileManagerProtocol private let storageServiceManager: StorageServiceManager - private let tsAccountManager: TSAccountManager + private let tsAccountManager: TSAccountManagerProtocol private let jobQueues: SSKJobQueues public init( profileManager: ProfileManagerProtocol, storageServiceManager: StorageServiceManager, - tsAccountManager: TSAccountManager, + tsAccountManager: TSAccountManagerProtocol, jobQueues: SSKJobQueues ) { self.profileManager = profileManager @@ -229,9 +229,9 @@ private extension RecipientHidingManagerImpl { } if - tsAccountManager.isPrimaryDevice(transaction: SDSDB.shimOnlyBridge(tx)), + tsAccountManager.registrationState(tx: tx).isRegisteredPrimaryDevice, let recipientServiceId = recipient.address.serviceId, - let localAci = self.tsAccountManager.localIdentifiers(transaction: SDSDB.shimOnlyBridge(tx))?.aci, + let localAci = self.tsAccountManager.localIdentifiers(tx: tx)?.aci, !GroupManager.hasMutualGroupThread( with: recipientServiceId, localAci: localAci, diff --git a/SignalServiceKit/src/Messages/Stickers/StickerManager.swift b/SignalServiceKit/src/Messages/Stickers/StickerManager.swift index 11ed77aac1..2e52184094 100644 --- a/SignalServiceKit/src/Messages/Stickers/StickerManager.swift +++ b/SignalServiceKit/src/Messages/Stickers/StickerManager.swift @@ -85,7 +85,7 @@ public class StickerManager: NSObject { // Resume sticker and sticker pack downloads when app is ready. AppReadiness.runNowOrWhenMainAppDidBecomeReadyAsync { - if TSAccountManager.shared.isRegisteredAndReady { + if DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered { StickerManager.refreshContents() } } @@ -1181,7 +1181,7 @@ public class StickerManager: NSObject { private class func enqueueStickerSyncMessage(operationType: StickerPackOperationType, packs: [StickerPackInfo], transaction: SDSAnyWriteTransaction) { - guard tsAccountManager.isRegisteredAndReady else { + guard DependenciesBridge.shared.tsAccountManager.registrationState(tx: transaction.asV2Read).isRegistered else { return } guard let thread = TSContactThread.getOrCreateLocalThread(transaction: transaction) else { @@ -1195,7 +1195,7 @@ public class StickerManager: NSObject { @objc public class func syncAllInstalledPacks(transaction: SDSAnyWriteTransaction) { - guard tsAccountManager.isRegisteredAndReady else { + guard DependenciesBridge.shared.tsAccountManager.registrationState(tx: transaction.asV2Read).isRegistered else { return } diff --git a/SignalServiceKit/src/Messages/Stories/OutgoingStoryMessage.swift b/SignalServiceKit/src/Messages/Stories/OutgoingStoryMessage.swift index be2e0c8c8c..18a482f189 100644 --- a/SignalServiceKit/src/Messages/Stories/OutgoingStoryMessage.swift +++ b/SignalServiceKit/src/Messages/Stories/OutgoingStoryMessage.swift @@ -86,7 +86,7 @@ public class OutgoingStoryMessage: TSOutgoingMessage { ) let storyMessage = StoryMessage( timestamp: Date.ows_millisecondTimestamp(), - authorAci: tsAccountManager.localIdentifiers(transaction: transaction)!.aci, + authorAci: DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)!.aci, groupId: (thread as? TSGroupThread)?.groupId, manifest: storyManifest, attachment: attachment, @@ -178,7 +178,10 @@ public class OutgoingStoryMessage: TSOutgoingMessage { } let builder = SSKProtoStoryMessage.builder() - if let profileKey = profileManager.profileKeyData(for: tsAccountManager.localAddress!, transaction: transaction) { + if let profileKey = profileManager.profileKeyData( + for: DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)!.aciAddress, + transaction: transaction + ) { builder.setProfileKey(profileKey) } diff --git a/SignalServiceKit/src/Messages/Stories/StoryFinder.swift b/SignalServiceKit/src/Messages/Stories/StoryFinder.swift index 02ae54d701..5b1754ad8b 100644 --- a/SignalServiceKit/src/Messages/Stories/StoryFinder.swift +++ b/SignalServiceKit/src/Messages/Stories/StoryFinder.swift @@ -10,7 +10,7 @@ import LibSignalClient @objc public class StoryFinder: NSObject { public static func unviewedSenderCount(transaction: SDSAnyReadTransaction) -> Int { - let ownAciClause = tsAccountManager.localIdentifiers(transaction: transaction).map { + let ownAciClause = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read).map { "AND \(StoryContextAssociatedData.columnName(.contactAci)) IS NOT '\($0.aci.serviceIdUppercaseString)'" } ?? "" let sql = """ diff --git a/SignalServiceKit/src/Messages/Stories/StoryManager.swift b/SignalServiceKit/src/Messages/Stories/StoryManager.swift index 90b94d9a53..688ac8151f 100644 --- a/SignalServiceKit/src/Messages/Stories/StoryManager.swift +++ b/SignalServiceKit/src/Messages/Stories/StoryManager.swift @@ -130,7 +130,7 @@ public class StoryManager: NSObject { let existingStory = StoryFinder.story( timestamp: proto.timestamp, - author: tsAccountManager.localIdentifiers(transaction: transaction)!.aci, + author: DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)!.aci, transaction: transaction ) diff --git a/SignalServiceKit/src/Messages/Stories/StoryMessage.swift b/SignalServiceKit/src/Messages/Stories/StoryMessage.swift index 47ccf595c7..1c37fa67c9 100644 --- a/SignalServiceKit/src/Messages/Stories/StoryMessage.swift +++ b/SignalServiceKit/src/Messages/Stories/StoryMessage.swift @@ -307,7 +307,7 @@ public final class StoryMessage: NSObject, SDSCodableModel, Decodable { throw OWSAssertionError("Missing attachment for StoryMessage.") } - let authorAci = tsAccountManager.localIdentifiers(transaction: transaction)!.aci + let authorAci = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)!.aci // Count replies in some recipient replied and sent us the reply // before our linked device sent us the transcript. diff --git a/SignalServiceKit/src/Messages/Stories/SystemStoryManager.swift b/SignalServiceKit/src/Messages/Stories/SystemStoryManager.swift index c4d7f87729..4cd8f3f28c 100644 --- a/SignalServiceKit/src/Messages/Stories/SystemStoryManager.swift +++ b/SignalServiceKit/src/Messages/Stories/SystemStoryManager.swift @@ -62,9 +62,9 @@ public class SystemStoryManager: NSObject, Dependencies, SystemStoryManagerProto if CurrentAppContext().isMainApp { AppReadiness.runNowOrWhenMainAppDidBecomeReadyAsync { [weak self] in - guard Self.tsAccountManager.isOnboarded else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { // Observe when the account is ready before we try and download. - self?.observeOnboardingChanges() + self?.observeRegistrationChanges() return } self?.enqueueOnboardingStoryDownload() @@ -172,21 +172,21 @@ public class SystemStoryManager: NSObject, Dependencies, SystemStoryManagerProto // MARK: - Internal Event Observation - private func observeOnboardingChanges() { + private func observeRegistrationChanges() { NotificationCenter.default.addObserver( self, - selector: #selector(onboardingStateDidChange), - name: .onboardingStateDidChange, + selector: #selector(registrationStateDidChange), + name: .registrationStateDidChange, object: nil ) } @objc - private func onboardingStateDidChange() { - guard Self.tsAccountManager.isOnboarded else { + private func registrationStateDidChange() { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return } - NotificationCenter.default.removeObserver(self, name: .onboardingStateDidChange, object: nil) + NotificationCenter.default.removeObserver(self, name: .registrationStateDidChange, object: nil) _ = self.enqueueOnboardingStoryDownload() } diff --git a/SignalServiceKit/src/Messages/UD/OWSUDManager.swift b/SignalServiceKit/src/Messages/UD/OWSUDManager.swift index bd4144d730..d121eaa67e 100644 --- a/SignalServiceKit/src/Messages/UD/OWSUDManager.swift +++ b/SignalServiceKit/src/Messages/UD/OWSUDManager.swift @@ -398,7 +398,7 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager { } public func ensureSenderCertificates(certificateExpirationPolicy: OWSUDCertificateExpirationPolicy) -> Promise { - guard tsAccountManager.isRegisteredAndReady else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { // We don't want to assert but we should log and fail. return Promise(error: OWSGenericError("Not registered and ready.")) } @@ -443,12 +443,12 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager { private func isValidCertificate(_ certificate: SenderCertificate) -> Bool { let sender = certificate.sender - guard sender.deviceId == tsAccountManager.storedDeviceId else { + guard sender.deviceId == DependenciesBridge.shared.tsAccountManager.storedDeviceIdWithMaybeTransaction else { Logger.warn("Sender certificate has incorrect device ID") return false } - let localIdentifiers = tsAccountManager.localIdentifiers + let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction guard sender.e164 == nil || sender.e164 == localIdentifiers?.phoneNumber else { Logger.warn("Sender certificate has incorrect phone number") @@ -506,7 +506,9 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager { // Try to update the account attributes to reflect this change. firstly(on: DispatchQueue.global()) { - Self.tsAccountManager.updateAccountAttributes() + return Promise.wrapAsync { + try await DependenciesBridge.shared.accountAttributesUpdater.updateAccountAttributes(authedAccount: .implicit()) + } }.catch(on: DispatchQueue.global()) { error in Logger.warn("Error: \(error)") } diff --git a/SignalServiceKit/src/Network/API/RESTNetworkManager.swift b/SignalServiceKit/src/Network/API/RESTNetworkManager.swift index 94d0b9aefe..34d8df713a 100644 --- a/SignalServiceKit/src/Network/API/RESTNetworkManager.swift +++ b/SignalServiceKit/src/Network/API/RESTNetworkManager.swift @@ -88,11 +88,13 @@ public class RESTSessionManager: NSObject { ) { let isDeregisteredRequest = WhoAmIRequestFactory.amIDeregisteredRequest() - let handleDeregisteredResponse: (WhoAmIRequestFactory.Responses.AmIDeregistered?) -> Void = { [tsAccountManager] response in + let handleDeregisteredResponse: (WhoAmIRequestFactory.Responses.AmIDeregistered?) -> Void = { response in switch response { case .deregistered: Logger.warn("AmIDeregistered response says we are deregistered, marking as such.") - tsAccountManager.isDeregistered = true + DependenciesBridge.shared.db.write { tx in + DependenciesBridge.shared.registrationStateChangeManager.setIsDeregisteredOrDelinked(true, tx: tx) + } case .notDeregistered: Logger.info("AmIDeregistered response says not deregistered; account probably disabled. Doing nothing.") case .none, .unexpectedError: diff --git a/SignalServiceKit/src/Network/API/Requests/AccountAttributes/AccountAttributes+Dependencies.swift b/SignalServiceKit/src/Network/API/Requests/AccountAttributes/AccountAttributes+Dependencies.swift index 39fa181c4d..efe061fe25 100644 --- a/SignalServiceKit/src/Network/API/Requests/AccountAttributes/AccountAttributes+Dependencies.swift +++ b/SignalServiceKit/src/Network/API/Requests/AccountAttributes/AccountAttributes+Dependencies.swift @@ -12,7 +12,7 @@ extension AccountAttributes { svr: SecureValueRecovery, transaction: SDSAnyWriteTransaction ) -> AccountAttributes { - owsAssertDebug(dependencies.tsAccountManager.isPrimaryDevice) + owsAssertDebug(DependenciesBridge.shared.tsAccountManager.registrationState(tx: transaction.asV2Read).isPrimaryDevice == true) return generate( fromDependencies: dependencies, svr: svr, @@ -58,11 +58,11 @@ extension AccountAttributes { // TODO: can we change this with atomic device linking? isManualMessageFetchEnabled = true } else { - isManualMessageFetchEnabled = dependencies.tsAccountManager.isManualMessageFetchEnabled(transaction) + isManualMessageFetchEnabled = DependenciesBridge.shared.tsAccountManager.isManualMessageFetchEnabled(tx: transaction.asV2Read) } - let registrationId = dependencies.tsAccountManager .getOrGenerateRegistrationId(transaction: transaction) - let pniRegistrationId = dependencies.tsAccountManager .getOrGeneratePniRegistrationId(transaction: transaction) + let registrationId = DependenciesBridge.shared.tsAccountManager.getOrGenerateAciRegistrationId(tx: transaction.asV2Write) + let pniRegistrationId = DependenciesBridge.shared.tsAccountManager.getOrGeneratePniRegistrationId(tx: transaction.asV2Write) let profileKey = dependencies.profileManager.localProfileKey() let udAccessKey: String @@ -106,7 +106,7 @@ extension AccountAttributes { let encryptedDeviceName = (encryptedDeviceNameRaw?.isEmpty ?? true) ? nil : encryptedDeviceNameRaw?.base64EncodedString() let isDiscoverableByPhoneNumber: Bool? = FeatureFlags.phoneNumberDiscoverability - ? dependencies.tsAccountManager.isDiscoverableByPhoneNumber(with: transaction) + ? DependenciesBridge.shared.phoneNumberDiscoverabilityManager.isDiscoverableByPhoneNumber(tx: transaction.asV2Read) : nil let hasSVRBackups = svr.hasBackedUpMasterKey(transaction: transaction.asV2Read) diff --git a/SignalServiceKit/src/Network/API/Requests/AccountAttributes/AccountAttributesRequestFactory.swift b/SignalServiceKit/src/Network/API/Requests/AccountAttributes/AccountAttributesRequestFactory.swift index 090c6eea8c..7b17f92306 100644 --- a/SignalServiceKit/src/Network/API/Requests/AccountAttributes/AccountAttributesRequestFactory.swift +++ b/SignalServiceKit/src/Network/API/Requests/AccountAttributes/AccountAttributesRequestFactory.swift @@ -10,7 +10,7 @@ public enum AccountAttributesRequestFactory { public static func updatePrimaryDeviceAttributesRequest(_ attributes: AccountAttributes) -> TSRequest { // If you are updating capabilities for a secondary device, use `updateSecondaryDeviceCapabilities` instead owsAssert( - TSAccountManager.shared.isPrimaryDevice, + DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isPrimaryDevice ?? true, "Trying to set primary device attributes from secondary/linked device" ) diff --git a/SignalServiceKit/src/Network/API/Requests/AccountAttributes/AccountAttributesUpdaterImpl.swift b/SignalServiceKit/src/Network/API/Requests/AccountAttributes/AccountAttributesUpdaterImpl.swift index d3b4524181..c26042bd3e 100644 --- a/SignalServiceKit/src/Network/API/Requests/AccountAttributes/AccountAttributesUpdaterImpl.swift +++ b/SignalServiceKit/src/Network/API/Requests/AccountAttributes/AccountAttributesUpdaterImpl.swift @@ -14,7 +14,7 @@ public class AccountAttributesUpdaterImpl: AccountAttributesUpdater { private let profileManager: ProfileManagerProtocol private let serviceClient: SignalServiceClient private let schedulers: Schedulers - private let svr: SecureValueRecovery + private let svrLocalStorage: SVRLocalStorage private let syncManager: SyncManagerProtocol private let tsAccountManager: TSAccountManagerProtocol @@ -29,7 +29,7 @@ public class AccountAttributesUpdaterImpl: AccountAttributesUpdater { keyValueStoreFactory: KeyValueStoreFactory, serviceClient: SignalServiceClient, schedulers: Schedulers, - svr: SecureValueRecovery, + svrLocalStorage: SVRLocalStorage, syncManager: SyncManagerProtocol, tsAccountManager: TSAccountManagerProtocol ) { @@ -40,7 +40,7 @@ public class AccountAttributesUpdaterImpl: AccountAttributesUpdater { self.profileManager = profileManager self.serviceClient = serviceClient self.schedulers = schedulers - self.svr = svr + self.svrLocalStorage = svrLocalStorage self.syncManager = syncManager self.tsAccountManager = tsAccountManager @@ -133,7 +133,7 @@ public class AccountAttributesUpdaterImpl: AccountAttributesUpdater { // has non-nil value if isRegistered is true. let isPrimaryDevice = registrationState.isPrimaryDevice ?? true - let hasBackedUpMasterKey = self.svr.hasBackedUpMasterKey(transaction: tx) + let hasBackedUpMasterKey = self.svrLocalStorage.getIsMasterKeyBackedUp(tx) let currentDeviceCapabilities = OWSRequestFactory.deviceCapabilitiesForLocalDevice( withHasBackedUpMasterKey: hasBackedUpMasterKey, isRegistered: isRegistered, diff --git a/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.m b/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.m index d10a51012a..440977637d 100644 --- a/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.m +++ b/SignalServiceKit/src/Network/API/Requests/OWSRequestFactory.m @@ -260,7 +260,7 @@ NSString *const OWSRequestKey_AuthKey = @"AuthKey"; + (TSRequest *)updateSecondaryDeviceCapabilitiesRequestWithHasBackedUpMasterKey:(BOOL)hasBackedUpMasterKey { // If you are updating capabilities for a primary device, use `updateAccountAttributes` instead - OWSAssertDebug(!self.tsAccountManager.isPrimaryDevice); + OWSAssertDebug(![TSAccountManagerObjcBridge isPrimaryDeviceWithMaybeTransaction]); return [TSRequest requestWithUrl:[NSURL URLWithString:@"v1/devices/capabilities"] method:@"PUT" @@ -273,10 +273,10 @@ NSString *const OWSRequestKey_AuthKey = @"AuthKey"; { // tsAccountManager.isPrimaryDevice only has a valid value for registered // devices. - BOOL isRegisteredAndReady = self.tsAccountManager.isRegisteredAndReady; + BOOL isRegisteredAndReady = [TSAccountManagerObjcBridge isRegisteredWithMaybeTransaction]; OWSAssertDebug(isRegisteredAndReady); - BOOL isPrimaryDevice = self.tsAccountManager.isPrimaryDevice; + BOOL isPrimaryDevice = [TSAccountManagerObjcBridge isPrimaryDeviceWithMaybeTransaction]; return [self deviceCapabilitiesForLocalDeviceWithHasBackedUpMasterKey:hasBackedUpMasterKey isRegistered:isRegisteredAndReady isPrimaryDevice:isPrimaryDevice]; diff --git a/SignalServiceKit/src/Network/API/Requests/TSRequest.swift b/SignalServiceKit/src/Network/API/Requests/TSRequest.swift index 3c65935019..acef69d420 100644 --- a/SignalServiceKit/src/Network/API/Requests/TSRequest.swift +++ b/SignalServiceKit/src/Network/API/Requests/TSRequest.swift @@ -65,7 +65,7 @@ public class TSRequest: NSMutableURLRequest { get { owsAssertDebug(shouldHaveAuthorizationHeaders) return authLock.withLock { - let result = _authUsername ?? self.tsAccountManager.storedServerUsername + let result = _authUsername ?? DependenciesBridge.shared.tsAccountManager.storedServerUsernameWithMaybeTransaction if result.isEmptyOrNil { Logger.verbose(self.debugDescription) } @@ -86,7 +86,7 @@ public class TSRequest: NSMutableURLRequest { get { owsAssertDebug(shouldHaveAuthorizationHeaders) return authLock.withLock { - let result = _authPassword ?? self.tsAccountManager.storedServerAuthToken + let result = _authPassword ?? DependenciesBridge.shared.tsAccountManager.storedServerAuthTokenWithMaybeTransaction if result.isEmptyOrNil { Logger.verbose(self.debugDescription) } diff --git a/SignalServiceKit/src/Network/OWSSignalService.swift b/SignalServiceKit/src/Network/OWSSignalService.swift index 3343717090..a3f15c42b5 100644 --- a/SignalServiceKit/src/Network/OWSSignalService.swift +++ b/SignalServiceKit/src/Network/OWSSignalService.swift @@ -101,7 +101,7 @@ public class OWSSignalService: OWSSignalServiceProtocol, Dependencies { } guard - let localNumber = TSAccountManager.localNumber, + let localNumber = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber, let configuration = OWSCensorshipConfiguration(phoneNumber: localNumber) else { return .default() @@ -205,7 +205,15 @@ public class OWSSignalService: OWSSignalServiceProtocol, Dependencies { } private func updateHasCensoredPhoneNumber() { - let localNumber = TSAccountManager.localNumber + updateHasCensoredPhoneNumber(DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber) + } + + public func updateHasCensoredPhoneNumberDuringProvisioning(_ e164: E164) { + updateHasCensoredPhoneNumber(e164.stringValue) + } + + private func updateHasCensoredPhoneNumber(_ localNumber: String?) { + let localNumber = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber if let localNumber = localNumber { self.hasCensoredPhoneNumber = OWSCensorshipConfiguration.isCensoredPhoneNumber(localNumber) diff --git a/SignalServiceKit/src/Network/OWSSignalServiceMock.swift b/SignalServiceKit/src/Network/OWSSignalServiceMock.swift index bd19c0a882..1d20f16fb4 100644 --- a/SignalServiceKit/src/Network/OWSSignalServiceMock.swift +++ b/SignalServiceKit/src/Network/OWSSignalServiceMock.swift @@ -20,6 +20,8 @@ public class OWSSignalServiceMock: OWSSignalServiceProtocol, Dependencies { public var manualCensorshipCircumventionCountryCode: String? + public func updateHasCensoredPhoneNumberDuringProvisioning(_ e164: E164) {} + public var urlEndpointBuilder: ((SignalServiceInfo) -> OWSURLSessionEndpoint)? public func buildUrlEndpoint(for signalServiceInfo: SignalServiceInfo) -> OWSURLSessionEndpoint { diff --git a/SignalServiceKit/src/Network/OWSSignalServiceProtocol.swift b/SignalServiceKit/src/Network/OWSSignalServiceProtocol.swift index 963c420b18..759aad46b8 100644 --- a/SignalServiceKit/src/Network/OWSSignalServiceProtocol.swift +++ b/SignalServiceKit/src/Network/OWSSignalServiceProtocol.swift @@ -16,6 +16,8 @@ public protocol OWSSignalServiceProtocol: AnyObject { var isCensorshipCircumventionManuallyDisabled: Bool { get set } var manualCensorshipCircumventionCountryCode: String? { get set } + func updateHasCensoredPhoneNumberDuringProvisioning(_ e164: E164) + func buildUrlEndpoint(for signalServiceInfo: SignalServiceInfo) -> OWSURLSessionEndpoint func buildUrlSession( for signalServiceInfo: SignalServiceInfo, diff --git a/SignalServiceKit/src/Network/Receiving/GroupsV2MessageProcessor.swift b/SignalServiceKit/src/Network/Receiving/GroupsV2MessageProcessor.swift index 9cbe556444..d5cd84d6b0 100644 --- a/SignalServiceKit/src/Network/Receiving/GroupsV2MessageProcessor.swift +++ b/SignalServiceKit/src/Network/Receiving/GroupsV2MessageProcessor.swift @@ -151,7 +151,7 @@ class IncomingGroupsV2MessageQueue: NSObject, MessageProcessingPipelineStage { let canProcess = ( messagePipelineSupervisor.isMessageProcessingPermitted && - tsAccountManager.isRegisteredAndReady + DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered ) guard canProcess else { @@ -316,7 +316,7 @@ internal class GroupsMessageProcessor: MessageProcessingPipelineStage, Dependenc let canProcess = ( messagePipelineSupervisor.isMessageProcessingPermitted && - tsAccountManager.isRegisteredAndReady + DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered ) guard canProcess else { @@ -573,7 +573,7 @@ internal class GroupsMessageProcessor: MessageProcessingPipelineStage, Dependenc wasReceivedByUD: job.wasReceivedByUD, serverDeliveryTimestamp: job.serverDeliveryTimestamp, shouldDiscardVisibleMessages: discardMode == .discardVisibleMessages, - localIdentifiers: tsAccountManager.localIdentifiers(transaction: transaction)!, + localIdentifiers: DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)!, tx: transaction ) } @@ -1026,7 +1026,7 @@ public class GroupsV2MessageProcessor: NSObject { // processing if they correspond to v2 groups of which we are a // non-pending member. if shouldCheckGroupModel { - guard let localAddress = self.tsAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aciAddress else { owsFailDebug("Missing localAddress.") return .discard } diff --git a/SignalServiceKit/src/Network/SignalServiceClient.swift b/SignalServiceKit/src/Network/SignalServiceClient.swift index 6a183e2ca5..680f939664 100644 --- a/SignalServiceKit/src/Network/SignalServiceClient.swift +++ b/SignalServiceKit/src/Network/SignalServiceClient.swift @@ -149,7 +149,7 @@ public class SignalServiceRestClient: NSObject, SignalServiceClient, Dependencie } public func updatePrimaryDeviceAccountAttributes(authedAccount: AuthedAccount) -> Promise { - guard tsAccountManager.isPrimaryDevice else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isPrimaryDevice == true else { return Promise(error: OWSAssertionError("only primary device should update account attributes")) } diff --git a/SignalServiceKit/src/Network/WebSockets/OWSWebSocket.swift b/SignalServiceKit/src/Network/WebSockets/OWSWebSocket.swift index 3d2b26d49a..0798778050 100644 --- a/SignalServiceKit/src/Network/WebSockets/OWSWebSocket.swift +++ b/SignalServiceKit/src/Network/WebSockets/OWSWebSocket.swift @@ -630,8 +630,8 @@ public class OWSWebSocket: NSObject { // UD socket is unauthenticated. return nil case .identified: - let login = tsAccountManager.storedServerUsername ?? "" - let password = tsAccountManager.storedServerAuthToken ?? "" + let login = DependenciesBridge.shared.tsAccountManager.storedServerUsernameWithMaybeTransaction ?? "" + let password = DependenciesBridge.shared.tsAccountManager.storedServerAuthTokenWithMaybeTransaction ?? "" owsAssertDebug(login.nilIfEmpty != nil) owsAssertDebug(password.nilIfEmpty != nil) return [ @@ -679,7 +679,7 @@ public class OWSWebSocket: NSObject { return .closed(reason: "!isAppReady") } - guard tsAccountManager.isRegisteredAndReady else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return .closed(reason: "!isRegisteredAndReady") } @@ -1158,7 +1158,9 @@ extension OWSWebSocket: SSKWebSocketDelegate { if webSocketType == .identified { // If socket opens, we know we're not de-registered. - tsAccountManager.isDeregistered = false + DependenciesBridge.shared.db.write { tx in + DependenciesBridge.shared.registrationStateChangeManager.setIsDeregisteredOrDelinked(false, tx: tx) + } } outageDetection.reportConnectionSuccess() @@ -1180,7 +1182,9 @@ extension OWSWebSocket: SSKWebSocketDelegate { self.currentWebSocket = nil if webSocketType == .identified, case WebSocketError.httpError(statusCode: 403, _) = error { - tsAccountManager.isDeregistered = true + DependenciesBridge.shared.db.write { tx in + DependenciesBridge.shared.registrationStateChangeManager.setIsDeregisteredOrDelinked(true, tx: tx) + } } if shouldSocketBeOpen { diff --git a/SignalServiceKit/src/Remote Attestation/RemoteAttestation.swift b/SignalServiceKit/src/Remote Attestation/RemoteAttestation.swift index 8d6a67a0b3..e1163f7a77 100644 --- a/SignalServiceKit/src/Remote Attestation/RemoteAttestation.swift +++ b/SignalServiceKit/src/Remote Attestation/RemoteAttestation.swift @@ -152,7 +152,7 @@ fileprivate extension RemoteAttestation.Auth { switch auth.credentials { case .implicit: - guard tsAccountManager.isRegisteredAndReady else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return Promise(error: OWSGenericError("Not registered.")) } case let .explicit(username, password): diff --git a/SignalServiceKit/src/SSKEnvironment.swift b/SignalServiceKit/src/SSKEnvironment.swift index 9083651a54..3e8043fc74 100644 --- a/SignalServiceKit/src/SSKEnvironment.swift +++ b/SignalServiceKit/src/SSKEnvironment.swift @@ -260,7 +260,7 @@ public class SSKEnvironment: NSObject { /// always consistent with TSAccountManager's values. private func fixLocalRecipientIfNeeded() { databaseStorage.write { tx in - guard let localIdentifiers = tsAccountManager.localIdentifiers(transaction: tx) else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read) else { return // Not registered yet. } guard let phoneNumber = E164(localIdentifiers.phoneNumber) else { diff --git a/SignalServiceKit/src/Security/OWSFingerprintBuilder.swift b/SignalServiceKit/src/Security/OWSFingerprintBuilder.swift index f43a4a5ede..a53440252d 100644 --- a/SignalServiceKit/src/Security/OWSFingerprintBuilder.swift +++ b/SignalServiceKit/src/Security/OWSFingerprintBuilder.swift @@ -13,12 +13,12 @@ public class OWSFingerprintBuilder { private let contactsManager: ContactsManagerProtocol private let identityManager: OWSIdentityManager - private let tsAccountManager: TSAccountManager + private let tsAccountManager: TSAccountManagerProtocol public init( contactsManager: ContactsManagerProtocol, identityManager: OWSIdentityManager, - tsAccountManager: TSAccountManager + tsAccountManager: TSAccountManagerProtocol ) { self.contactsManager = contactsManager self.identityManager = identityManager @@ -34,7 +34,7 @@ public class OWSFingerprintBuilder { tx: SDSAnyReadTransaction ) -> FingerprintResult? { guard - let localIdentifiers = tsAccountManager.localIdentifiers(transaction: tx), + let localIdentifiers = tsAccountManager.localIdentifiers(tx: tx.asV2Read), let myE164 = E164(localIdentifiers.phoneNumber), let myAciIdentityKey = identityManager.identityKeyPair(for: .aci, tx: tx.asV2Read)?.publicKey else { diff --git a/SignalServiceKit/src/Security/OWSRecipientIdentity+Queries.swift b/SignalServiceKit/src/Security/OWSRecipientIdentity+Queries.swift index 5e41fedbd6..abe81febb3 100644 --- a/SignalServiceKit/src/Security/OWSRecipientIdentity+Queries.swift +++ b/SignalServiceKit/src/Security/OWSRecipientIdentity+Queries.swift @@ -93,7 +93,7 @@ extension OWSRecipientIdentity { case .grdbRead(let grdbTransaction): // There should always be a recipient UUID, but just in case there isn't provide a fake value that won't // affect the results of the query. - let localRecipientAci = tsAccountManager.localIdentifiers(transaction: transaction)?.aci + let localRecipientAci = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aci let sql = sqlQueryToFetchVerifiedAddresses( groupUniqueID: groupUniqueID, withVerificationState: state, diff --git a/SignalServiceKit/src/Storage/AxolotlStore/SenderKeyStore.swift b/SignalServiceKit/src/Storage/AxolotlStore/SenderKeyStore.swift index 614b091834..b2839b8aac 100644 --- a/SignalServiceKit/src/Storage/AxolotlStore/SenderKeyStore.swift +++ b/SignalServiceKit/src/Storage/AxolotlStore/SenderKeyStore.swift @@ -173,13 +173,13 @@ public class SenderKeyStore: NSObject { @objc public func skdmBytesForThread(_ thread: TSThread, tx: SDSAnyWriteTransaction) -> Data? { - guard let localIdentifiers = tsAccountManager.localIdentifiers(transaction: tx) else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read) else { return nil } return skdmBytesForThread( thread, localAci: localIdentifiers.aci, - localDeviceId: tsAccountManager.storedDeviceId(transaction: tx), + localDeviceId: DependenciesBridge.shared.tsAccountManager.storedDeviceId(tx: tx.asV2Read), tx: tx ) } @@ -222,7 +222,7 @@ extension SenderKeyStore: LibSignalClient.SenderKeyStore { throw OWSAssertionError("Invalid protocol address: must have ACI") } - guard let localIdentifiers = tsAccountManager.localIdentifiers(transaction: tx) else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read) else { throw OWSAssertionError("Not registered.") } @@ -238,7 +238,7 @@ extension SenderKeyStore: LibSignalClient.SenderKeyStore { senderAci: senderAci, senderDeviceId: sender.deviceId, localIdentifiers: localIdentifiers, - localDeviceId: tsAccountManager.storedDeviceId(transaction: tx), + localDeviceId: DependenciesBridge.shared.tsAccountManager.storedDeviceId(tx: tx.asV2Read), distributionId: distributionId ) } @@ -325,7 +325,7 @@ extension SenderKeyStore { fileprivate func keyIdForSendingToThreadId(_ threadId: ThreadUniqueId, readTx: SDSAnyReadTransaction) -> KeyId? { storageLock.assertOwner() - guard let localAci = tsAccountManager.localIdentifiers(transaction: readTx)?.aci else { + guard let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: readTx.asV2Read)?.aci else { owsFailDebug("Not registered.") return nil } @@ -351,7 +351,7 @@ extension SenderKeyStore { fileprivate func keyIdForSendingToThreadId(_ threadId: ThreadUniqueId, writeTx: SDSAnyWriteTransaction) -> KeyId? { storageLock.assertOwner() - guard let localAci = tsAccountManager.localIdentifiers(transaction: writeTx)?.aci else { + guard let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: writeTx.asV2Read)?.aci else { owsFailDebug("Not registered.") return nil } @@ -387,7 +387,7 @@ extension SenderKeyStore { // This method traverses all groups where `recipient` is a member and logs out information on any sent // sender key distribution messages. public func logSKDMInfo(for recipient: SignalServiceAddress, transaction: SDSAnyReadTransaction) { - guard let localAci = tsAccountManager.localIdentifiers(transaction: transaction)?.aci else { return } + guard let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aci else { return } // To avoid doing too much work for a flood of failed decryptions, we'll only honor an SKDM log // dump request every 10s. That's frequent enough to be captured in a log zip. diff --git a/SignalServiceKit/src/Storage/Database/GRDBSchemaMigrator.swift b/SignalServiceKit/src/Storage/Database/GRDBSchemaMigrator.swift index 3134f5c993..cf7e3eaf07 100644 --- a/SignalServiceKit/src/Storage/Database/GRDBSchemaMigrator.swift +++ b/SignalServiceKit/src/Storage/Database/GRDBSchemaMigrator.swift @@ -89,7 +89,7 @@ public class GRDBSchemaMigrator: NSObject { // which won't work because migrations use a barrier block to prevent observing database state // before migration. try grdbStorageAdapter.read { transaction in - _ = self.tsAccountManager.localAddress(with: transaction.asAnyRead) + _ = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asAnyRead.asV2Read)?.aciAddress } // Finally, do data migrations. @@ -2368,10 +2368,7 @@ public class GRDBSchemaMigrator: NSObject { } migrator.registerMigration(.dataMigration_markOnboardedUsers_v2) { transaction in - if TSAccountManager.shared.isRegistered(transaction: transaction.asAnyWrite) { - Logger.info("marking existing user as onboarded") - TSAccountManager.shared.setIsOnboarded(true, transaction: transaction.asAnyWrite) - } + // No-op; this state is not read anywhere that matters. return .success(()) } @@ -2754,7 +2751,7 @@ public class GRDBSchemaMigrator: NSObject { // We only want to do this if we are the primary device, since only // the primary device's system contacts are synced. - guard tsAccountManager.isPrimaryDevice else { + guard DependenciesBridge.shared.tsAccountManager.registrationState(tx: transaction.asAnyRead.asV2Read).isPrimaryDevice ?? false else { return .success(()) } @@ -2777,7 +2774,7 @@ public class GRDBSchemaMigrator: NSObject { } migrator.registerMigration(.dataMigration_removeLinkedDeviceSystemContacts) { transaction in - guard !tsAccountManager.isPrimaryDevice else { + guard DependenciesBridge.shared.tsAccountManager.registrationState(tx: transaction.asAnyRead.asV2Read).isPrimaryDevice != true else { return .success(()) } diff --git a/SignalServiceKit/src/Storage/Database/SDSDatabaseStorage/SDSDatabaseStorage.swift b/SignalServiceKit/src/Storage/Database/SDSDatabaseStorage/SDSDatabaseStorage.swift index b24ff256cb..88ca30c412 100644 --- a/SignalServiceKit/src/Storage/Database/SDSDatabaseStorage/SDSDatabaseStorage.swift +++ b/SignalServiceKit/src/Storage/Database/SDSDatabaseStorage/SDSDatabaseStorage.swift @@ -190,7 +190,7 @@ public class SDSDatabaseStorage: SDSTransactable { Logger.info("") - let wasRegistered = TSAccountManager.shared.isRegistered + let wasRegistered = DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered let (promise, future) = Guarantee.pending() let completion: () -> Void = { @@ -211,7 +211,7 @@ public class SDSDatabaseStorage: SDSTransactable { SSKEnvironment.shared.warmCaches() - if wasRegistered != TSAccountManager.shared.isRegistered { + if wasRegistered != DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered { NotificationCenter.default.post(name: .registrationStateDidChange, object: nil, userInfo: nil) } future.resolve(.success) diff --git a/SignalServiceKit/src/Storage/Database/Snapshots/DatabaseChangeObserver.swift b/SignalServiceKit/src/Storage/Database/Snapshots/DatabaseChangeObserver.swift index 6708ae65c7..d8d7862b5b 100644 --- a/SignalServiceKit/src/Storage/Database/Snapshots/DatabaseChangeObserver.swift +++ b/SignalServiceKit/src/Storage/Database/Snapshots/DatabaseChangeObserver.swift @@ -174,7 +174,14 @@ public class DatabaseChangeObserver: NSObject { } let shouldBeActive: Bool = { - guard AppReadiness.isAppReady, !tsAccountManager.isTransferInProgress else { + let tsRegistrationState = DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction + switch tsRegistrationState { + case .transferringIncoming, .transferringLinkedOutgoing, .transferringPrimaryOutgoing: + return false + default: + break + } + guard AppReadiness.isAppReady else { return false } guard !CurrentAppContext().isInBackground() else { @@ -455,10 +462,13 @@ extension DatabaseChangeObserver: TransactionObserver { private func publishUpdatesIfNecessary() { AssertIsOnMainThread() - guard !tsAccountManager.isTransferInProgress else { + switch DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction { + case .transferringIncoming, .transferringLinkedOutgoing, .transferringPrimaryOutgoing: Logger.info("Skipping publishing of updates; transfer in progress.") displayLink?.invalidate() return + default: + break } if let lastPublishUpdatesDate = self.lastPublishUpdatesDate { diff --git a/SignalServiceKit/src/TestUtils/MockSSKEnvironment.swift b/SignalServiceKit/src/TestUtils/MockSSKEnvironment.swift index 2ba7c9f0ae..5f329f4826 100644 --- a/SignalServiceKit/src/TestUtils/MockSSKEnvironment.swift +++ b/SignalServiceKit/src/TestUtils/MockSSKEnvironment.swift @@ -134,7 +134,7 @@ public class MockSSKEnvironment: SSKEnvironment { let bulkProfileFetch = BulkProfileFetch( databaseStorage: databaseStorage, reachabilityManager: reachabilityManager, - tsAccountManager: tsAccountManager + tsAccountManager: dependenciesBridge.tsAccountManager ) let earlyMessageManager = EarlyMessageManager() let messagePipelineSupervisor = MessagePipelineSupervisor() @@ -152,7 +152,7 @@ public class MockSSKEnvironment: SSKEnvironment { recipientFetcher: dependenciesBridge.recipientFetcher, recipientMerger: dependenciesBridge.recipientMerger, recipientStore: dependenciesBridge.recipientStore, - tsAccountManager: tsAccountManager, + tsAccountManager: dependenciesBridge.tsAccountManager, udManager: udManager, websocketFactory: webSocketFactory ) diff --git a/SignalServiceKit/src/TestUtils/TestProtocolRunner.swift b/SignalServiceKit/src/TestUtils/TestProtocolRunner.swift index 60970bae1a..e36a142839 100644 --- a/SignalServiceKit/src/TestUtils/TestProtocolRunner.swift +++ b/SignalServiceKit/src/TestUtils/TestProtocolRunner.swift @@ -230,11 +230,11 @@ public struct LocalSignalClient: TestSignalClient { } public var e164Identifier: SignalE164Identifier? { - return TSAccountManager.localNumber + return DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber } public var serviceId: ServiceId { - let localIdentifiers = TSAccountManager.shared.localIdentifiers! + let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction! switch identity { case .aci: return localIdentifiers.aci case .pni: return localIdentifiers.pni! diff --git a/SignalServiceKit/src/Util/FeatureFlags.swift b/SignalServiceKit/src/Util/FeatureFlags.swift index 0b289b8967..71e1719f6a 100644 --- a/SignalServiceKit/src/Util/FeatureFlags.swift +++ b/SignalServiceKit/src/Util/FeatureFlags.swift @@ -527,7 +527,9 @@ public class TestableFlag: NSObject { private func updateCapabilities() { firstly(on: DispatchQueue.global()) { () -> Promise in - TSAccountManager.shared.updateAccountAttributes().asVoid() + return Promise.wrapAsync { + try await DependenciesBridge.shared.accountAttributesUpdater.updateAccountAttributes(authedAccount: .implicit()) + } }.done { Logger.info("") }.catch { error in diff --git a/SignalServiceKit/src/Util/OWS2FAManager.m b/SignalServiceKit/src/Util/OWS2FAManager.m index 1cb767359a..71c8a216f8 100644 --- a/SignalServiceKit/src/Util/OWS2FAManager.m +++ b/SignalServiceKit/src/Util/OWS2FAManager.m @@ -134,9 +134,8 @@ const NSUInteger kLegacyTruncated2FAv1PinLength = 16; object:nil userInfo:nil]; - [self.tsAccountManager updateAccountAttributes].catch(^(NSError *error) { - OWSLogError(@"Error: %@", error); - }); + [AccountAttributesUpdaterObjcBridge updateAccountAttributes].catch( + ^(NSError *error) { OWSLogError(@"Error: %@", error); }); }]; } @@ -158,9 +157,8 @@ const NSUInteger kLegacyTruncated2FAv1PinLength = 16; object:nil userInfo:nil]; - [self.tsAccountManager updateAccountAttributes].catch(^(NSError *error) { - OWSLogError(@"Error: %@", error); - }); + [AccountAttributesUpdaterObjcBridge updateAccountAttributes].catch( + ^(NSError *error) { OWSLogError(@"Error: %@", error); }); }]; } @@ -263,7 +261,7 @@ const NSUInteger kLegacyTruncated2FAv1PinLength = 16; - (BOOL)isDueForV2ReminderWithTransaction:(SDSAnyReadTransaction *)transaction { - if (!self.tsAccountManager.isRegisteredPrimaryDevice) { + if (![TSAccountManagerObjcBridge isRegisteredPrimaryDeviceWithMaybeTransaction]) { return NO; } diff --git a/SignalServiceKit/src/Util/OWS2FAManager.swift b/SignalServiceKit/src/Util/OWS2FAManager.swift index 6103d34499..3ea0311a0f 100644 --- a/SignalServiceKit/src/Util/OWS2FAManager.swift +++ b/SignalServiceKit/src/Util/OWS2FAManager.swift @@ -81,7 +81,9 @@ extension OWS2FAManager { ) } firstly { - TSAccountManager.shared.updateAccountAttributes() + return Promise.wrapAsync { + try await DependenciesBridge.shared.accountAttributesUpdater.updateAccountAttributes(authedAccount: .implicit()) + } }.catch { error in Logger.error("Error: \(error)") } @@ -89,7 +91,7 @@ extension OWS2FAManager { } public func markRegistrationLockV2Enabled(transaction: SDSAnyWriteTransaction) { - guard !TSAccountManager.shared.isRegistered else { + guard !DependenciesBridge.shared.tsAccountManager.registrationState(tx: transaction.asV2Read).isRegistered else { return owsFailDebug("Unexpectedly attempted to mark reglock as enabled after registration") } @@ -118,7 +120,9 @@ extension OWS2FAManager { ) } firstly { - TSAccountManager.shared.updateAccountAttributes() + return Promise.wrapAsync { + try await DependenciesBridge.shared.accountAttributesUpdater.updateAccountAttributes(authedAccount: .implicit()) + } }.catch { error in Logger.error("Error: \(error)") } @@ -126,7 +130,7 @@ extension OWS2FAManager { } public func markRegistrationLockV2Disabled(transaction: SDSAnyWriteTransaction) { - guard !TSAccountManager.shared.isRegistered else { + guard !DependenciesBridge.shared.tsAccountManager.registrationState(tx: transaction.asV2Read).isRegistered else { return owsFailDebug("Unexpectedly attempted to mark reglock as disabled after registration") } diff --git a/SignalServiceKit/src/Util/OWSUserProfile.m b/SignalServiceKit/src/Util/OWSUserProfile.m index 12a0576ff3..9e44beae3d 100644 --- a/SignalServiceKit/src/Util/OWSUserProfile.m +++ b/SignalServiceKit/src/Util/OWSUserProfile.m @@ -226,7 +226,7 @@ NSString *NSStringForUserProfileWriter(UserProfileWriter userProfileWriter) + (SignalServiceAddress *)publicAddressForAddress:(SignalServiceAddress *)address { if ([self isLocalProfileAddress:address]) { - SignalServiceAddress *_Nullable localAddress = self.tsAccountManager.localAddress; + SignalServiceAddress *_Nullable localAddress = [TSAccountManagerObjcBridge localAciAddressWithMaybeTransaction]; if (localAddress == nil) { OWSFailDebug(@"Missing localAddress."); } else { @@ -711,7 +711,7 @@ NSString *NSStringForUserProfileWriter(UserProfileWriter userProfileWriter) } BOOL isUpdatingDatabaseInstance = self != profile; - if (shouldReupload && self.tsAccountManager.isPrimaryDevice + if (shouldReupload && [TSAccountManagerObjcBridge isPrimaryDeviceWith:transaction] && CurrentAppContext().isMainApp && isUpdatingDatabaseInstance) { // shouldReuploadProtectedProfileName has side effects, // so only invoke it if shouldReupload is true. @@ -824,7 +824,7 @@ NSString *NSStringForUserProfileWriter(UserProfileWriter userProfileWriter) shouldUpdateStorageService = NO; } - if (self.tsAccountManager.isRegisteredAndReady && shouldUpdateStorageService + if ([TSAccountManagerObjcBridge isRegisteredWith:transaction] && shouldUpdateStorageService && (!onlyAvatarChanged || isLocalUserProfile)) { [transaction addAsyncCompletionOffMain:^{ if (isLocalUserProfile) { @@ -833,7 +833,7 @@ NSString *NSStringForUserProfileWriter(UserProfileWriter userProfileWriter) // Replace it with the real deal, from either auth or tsAccountManager. SignalServiceAddress *localAddress = [authedAccount localUserAddress]; if (localAddress == nil) { - localAddress = self.tsAccountManager.localAddress; + localAddress = [TSAccountManagerObjcBridge localAciAddressWith:transaction]; } [self.storageServiceManagerObjc recordPendingUpdatesWithUpdatedAddresses:@[ localAddress ]]; } else { @@ -849,7 +849,7 @@ NSString *NSStringForUserProfileWriter(UserProfileWriter userProfileWriter) // We populate an initial (empty) profile on launch of a new install, but // until we have a registered account, syncing will fail (and there could not // be any linked device to sync to at this point anyway). - if (self.tsAccountManager.isRegisteredPrimaryDevice + if ([TSAccountManagerObjcBridge isRegisteredPrimaryDeviceWithMaybeTransaction] && CurrentAppContext().isMainApp) { [self.syncManager syncLocalContact].catchInBackground( ^(NSError *error) { OWSLogError(@"Error: %@", error); }); diff --git a/SignalServiceKit/src/Util/Profiles/BulkProfileFetch.swift b/SignalServiceKit/src/Util/Profiles/BulkProfileFetch.swift index dd577ec0eb..2885c3cb72 100644 --- a/SignalServiceKit/src/Util/Profiles/BulkProfileFetch.swift +++ b/SignalServiceKit/src/Util/Profiles/BulkProfileFetch.swift @@ -39,12 +39,12 @@ public actor BulkProfileFetch { private let databaseStorage: SDSDatabaseStorage private let reachabilityManager: SSKReachabilityManager - private let tsAccountManager: TSAccountManager + private let tsAccountManager: TSAccountManagerProtocol public init( databaseStorage: SDSDatabaseStorage, reachabilityManager: SSKReachabilityManager, - tsAccountManager: TSAccountManager + tsAccountManager: TSAccountManagerProtocol ) { self.databaseStorage = databaseStorage self.reachabilityManager = reachabilityManager @@ -115,10 +115,10 @@ public actor BulkProfileFetch { } private func _fetchProfiles(serviceIds: [ServiceId]) async { - guard tsAccountManager.isRegisteredAndReady else { + guard tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return } - guard let localIdentifiers = tsAccountManager.localIdentifiers else { + guard let localIdentifiers = tsAccountManager.localIdentifiersWithMaybeSneakyTransaction else { owsFailDebug("missing localIdentifiers") return } @@ -160,7 +160,7 @@ public actor BulkProfileFetch { guard CurrentAppContext().isMainApp, reachabilityManager.isReachable, - tsAccountManager.isRegisteredAndReady, + tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered, !DebugFlags.reduceLogChatter else { return @@ -226,7 +226,7 @@ public actor BulkProfileFetch { lastOutcomeMap[serviceId] = UpdateOutcome(.noProfile) } else { // TODO: We may need to handle more status codes. - if tsAccountManager.isRegisteredAndReady { + if tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered { owsFailDebug("Error: \(error)") } else { Logger.warn("Error: \(error)") @@ -272,7 +272,7 @@ public actor BulkProfileFetch { guard CurrentAppContext().isMainApp else { return } - guard tsAccountManager.isRegisteredAndReady else { + guard tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return } diff --git a/SignalServiceKit/src/Util/Profiles/ProfileFetcherJob.swift b/SignalServiceKit/src/Util/Profiles/ProfileFetcherJob.swift index c6615e5166..b204d85e36 100644 --- a/SignalServiceKit/src/Util/Profiles/ProfileFetcherJob.swift +++ b/SignalServiceKit/src/Util/Profiles/ProfileFetcherJob.swift @@ -145,7 +145,7 @@ public class ProfileFetcherJob: NSObject { case ProfileFetchError.missing: Logger.warn("Error: \(error)") case ProfileFetchError.unauthorized: - if self.tsAccountManager.isRegisteredAndReady { + if DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered { owsFailDebug("Error: \(error)") } else { Logger.warn("Error: \(error)") @@ -322,7 +322,7 @@ public class ProfileFetcherJob: NSObject { case .explicit(let info): localIdentifiers = info.localIdentifiers case .implicit: - guard let implicitLocalIdentifiers = tsAccountManager.localIdentifiers else { + guard let implicitLocalIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction else { owsFailDebug("Fetching without localIdentifiers.") return false } diff --git a/SignalServiceKit/src/Util/RemoteConfigManager.swift b/SignalServiceKit/src/Util/RemoteConfigManager.swift index ecd7972fbc..9da961eb3b 100644 --- a/SignalServiceKit/src/Util/RemoteConfigManager.swift +++ b/SignalServiceKit/src/Util/RemoteConfigManager.swift @@ -375,7 +375,7 @@ public class RemoteConfig: BaseFlags { case .explicit(let explicitAccount): localE164 = explicitAccount.e164.stringValue case .implicit: - guard let e164 = TSAccountManager.shared.localNumber else { + guard let e164 = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber else { owsFailDebug("Missing local number") return nil } @@ -396,7 +396,7 @@ public class RemoteConfig: BaseFlags { case .explicit(let explicitAccount): aci = explicitAccount.aci case .implicit: - guard let localAci = TSAccountManager.shared.localIdentifiers?.aci else { + guard let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aci else { owsFailDebug("Missing localAci.") return false } @@ -708,7 +708,7 @@ public class ServiceRemoteConfigManager: RemoteConfigManager { private let appExpiry: AppExpiry private let db: DB private let keyValueStore: KeyValueStore - private let tsAccountManager: TSAccountManager + private let tsAccountManager: TSAccountManagerProtocol private let serviceClient: SignalServiceClient // MARK: - @@ -731,7 +731,7 @@ public class ServiceRemoteConfigManager: RemoteConfigManager { appExpiry: AppExpiry, db: DB, keyValueStoreFactory: KeyValueStoreFactory, - tsAccountManager: TSAccountManager, + tsAccountManager: TSAccountManagerProtocol, serviceClient: SignalServiceClient ) { self.appExpiry = appExpiry @@ -744,7 +744,7 @@ public class ServiceRemoteConfigManager: RemoteConfigManager { // That's not ideal, but we can't risk changing configs in the middle // of an app lifetime. AppReadiness.runNowOrWhenMainAppDidBecomeReadyAsync { - guard self.tsAccountManager.isRegistered else { + guard self.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return } self.scheduleNextRefresh() @@ -767,7 +767,7 @@ public class ServiceRemoteConfigManager: RemoteConfigManager { func registrationStateDidChange() { AssertIsOnMainThread() - guard tsAccountManager.isRegistered && !tsAccountManager.isDeregistered else { return } + guard tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return } Logger.info("Refreshing and immediately applying new flags due to new registration.") refresh().catch { error in Logger.error("Failed to update remote config after registration change \(error)") @@ -796,7 +796,7 @@ public class ServiceRemoteConfigManager: RemoteConfigManager { ) } // swiftlint:enable large_tuple - if TSAccountManager.shared.isRegisteredAndReady { + if DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered { let remoteConfig = cacheCurrent( clockSkew: lastKnownClockSkew, isEnabledFlags: isEnabledFlags, diff --git a/SignalServiceKit/src/Util/ViewOnceMessages.swift b/SignalServiceKit/src/Util/ViewOnceMessages.swift index efbda4be3f..f11e9a9c51 100644 --- a/SignalServiceKit/src/Util/ViewOnceMessages.swift +++ b/SignalServiceKit/src/Util/ViewOnceMessages.swift @@ -231,7 +231,7 @@ public class ViewOnceMessages: NSObject { if let incomingMessage = message as? TSIncomingMessage { return incomingMessage.authorAddress } else if message as? TSOutgoingMessage != nil { - guard let localAddress = tsAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress else { owsFailDebug("Could not process sync message; no local number.") return nil } diff --git a/SignalServiceKit/src/groups/GroupManager.swift b/SignalServiceKit/src/groups/GroupManager.swift index 1fcffcec91..cc2ad40572 100644 --- a/SignalServiceKit/src/groups/GroupManager.swift +++ b/SignalServiceKit/src/groups/GroupManager.swift @@ -193,7 +193,7 @@ public class GroupManager: NSObject { newGroupSeed: NewGroupSeed? = nil, shouldSendMessage: Bool) -> Promise { - guard let localIdentifiers = tsAccountManager.localIdentifiers else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction else { return Promise(error: OWSAssertionError("Missing localIdentifiers.")) } @@ -318,7 +318,7 @@ public class GroupManager: NSObject { withMembership newGroupMembership: GroupMembership, transaction tx: SDSAnyReadTransaction ) -> GroupMembership { - guard let localAci = tsAccountManager.localIdentifiers(transaction: tx)?.aci else { + guard let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read)?.aci else { owsFailDebug("Missing localAci.") return newGroupMembership } @@ -391,7 +391,7 @@ public class GroupManager: NSObject { groupsVersion: GroupsVersion = .V1, transaction: SDSAnyWriteTransaction) throws -> TSGroupThread { - guard let localIdentifiers = tsAccountManager.localIdentifiers(transaction: transaction) else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read) else { throw OWSAssertionError("Missing localIdentifiers.") } @@ -474,7 +474,7 @@ public class GroupManager: NSObject { inContactOrGroupV1Thread thread: TSThread, tx: SDSAnyWriteTransaction ) { - guard let localIdentifiers = tsAccountManager.localIdentifiers(transaction: tx) else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: tx.asV2Read) else { owsFailDebug("Not registered.") return } @@ -854,7 +854,7 @@ public class GroupManager: NSObject { // MARK: - Removed from Group or Invite Revoked public static func handleNotInGroup(groupId: Data, transaction: SDSAnyWriteTransaction) { - guard let localIdentifiers = tsAccountManager.localIdentifiers(transaction: transaction) else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read) else { owsFailDebug("Missing localIdentifiers.") return } @@ -1184,8 +1184,8 @@ public class GroupManager: NSObject { } if - tsAccountManager.isPrimaryDevice(transaction: transaction), - let localAci = tsAccountManager.localIdentifiers(transaction: transaction)?.aci, + DependenciesBridge.shared.tsAccountManager.registrationState(tx: transaction.asV2Read).isPrimaryDevice ?? true, + let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aci, oldGroupModelV2.membership.hasProfileKeyInGroup(serviceId: localAci), !newGroupModelV2.membership.hasProfileKeyInGroup(serviceId: localAci) { @@ -1470,10 +1470,10 @@ public class GroupManager: NSObject { /// our profile key credential from the service until we've uploaded a profile /// key commitment to the service. public static func ensureLocalProfileHasCommitmentIfNecessary() -> Promise { - guard tsAccountManager.isOnboarded else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return Promise.value(()) } - guard let localAddress = self.tsAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress else { return Promise(error: OWSAssertionError("Missing localAddress.")) } @@ -1502,7 +1502,7 @@ public class GroupManager: NSObject { } guard - tsAccountManager.isRegisteredPrimaryDevice, + DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegisteredPrimaryDevice, CurrentAppContext().isMainApp else { Logger.warn("Skipping upload of local profile key commitment, not in main app!") diff --git a/SignalServiceKit/src/groups/GroupMembership.swift b/SignalServiceKit/src/groups/GroupMembership.swift index 0cd634fa86..e9bc8ff0f2 100644 --- a/SignalServiceKit/src/groups/GroupMembership.swift +++ b/SignalServiceKit/src/groups/GroupMembership.swift @@ -722,7 +722,7 @@ public extension GroupMembership { @objc var isLocalUserMemberOfAnyKind: Bool { - guard let localIdentifiers = tsAccountManager.localIdentifiers else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction else { return false } @@ -735,7 +735,7 @@ public extension GroupMembership { @objc var isLocalUserFullMember: Bool { - guard let localAci = tsAccountManager.localIdentifiers?.aci else { + guard let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aci else { return false } @@ -765,7 +765,7 @@ public extension GroupMembership { /// Checks membership for the local ACI first. If none is available, falls /// back to checking membership for the local PNI. var isLocalUserInvitedMember: Bool { - guard let localIdentifiers = tsAccountManager.localIdentifiers else { + guard let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction else { return false } @@ -773,7 +773,7 @@ public extension GroupMembership { } var isLocalUserRequestingMember: Bool { - guard let localAci = tsAccountManager.localIdentifiers?.aci else { + guard let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aci else { return false } @@ -786,7 +786,7 @@ public extension GroupMembership { } var isLocalUserFullMemberAndAdministrator: Bool { - guard let localAci = tsAccountManager.localIdentifiers?.aci else { + guard let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aci else { return false } diff --git a/SignalServiceKit/tests/Account/LearnMyOwnPniManagerTest.swift b/SignalServiceKit/tests/Account/LearnMyOwnPniManagerTest.swift index 5df26d96f3..504b3513b2 100644 --- a/SignalServiceKit/tests/Account/LearnMyOwnPniManagerTest.swift +++ b/SignalServiceKit/tests/Account/LearnMyOwnPniManagerTest.swift @@ -30,7 +30,8 @@ class LearnMyOwnPniManagerTest: XCTestCase { private var accountServiceClientMock: AccountServiceClientMock! private var pniIdentityKeyCheckerMock: PniIdentityKeyCheckerMock! private var preKeyManagerMock: PreKeyManagerMock! - private var tsAccountManagerMock: TSAccountManagerMock! + private var registrationStateChangeManagerMock: MockRegistrationStateChangeManager! + private var tsAccountManagerMock: MockTSAccountManager! private var kvStore: TestKeyValueStore! private let db = MockDB() @@ -38,12 +39,19 @@ class LearnMyOwnPniManagerTest: XCTestCase { private var learnMyOwnPniManager: LearnMyOwnPniManager! + private var updatedPni: Pni? + override func setUp() { accountServiceClientMock = .init() pniIdentityKeyCheckerMock = .init() preKeyManagerMock = .init() + registrationStateChangeManagerMock = .init() tsAccountManagerMock = .init() + registrationStateChangeManagerMock.didUpdateLocalPhoneNumberMock = { [weak self] _, _, pni in + self?.updatedPni = pni + } + let kvStoreFactory = InMemoryKeyValueStoreFactory() kvStore = TestKeyValueStore(kvStoreFactory: kvStoreFactory) @@ -57,6 +65,7 @@ class LearnMyOwnPniManagerTest: XCTestCase { keyValueStoreFactory: kvStoreFactory, pniIdentityKeyChecker: pniIdentityKeyCheckerMock, preKeyManager: preKeyManagerMock, + registrationStateChangeManager: registrationStateChangeManagerMock, schedulers: schedulers, tsAccountManager: tsAccountManagerMock ) @@ -73,23 +82,24 @@ class LearnMyOwnPniManagerTest: XCTestCase { learnMyOwnPniManager.learnMyOwnPniIfNecessary().cauterize() - XCTAssertNil(tsAccountManagerMock.updatedPni) + XCTAssertNil(self.updatedPni) XCTAssertTrue(db.read { kvStore.hasSucceeded(tx: $0) }) } func testSkipsIfLinkedDevice() { - tsAccountManagerMock.isPrimaryDevice = false + tsAccountManagerMock.registrationStateMock = { .provisioned } learnMyOwnPniManager.learnMyOwnPniIfNecessary().cauterize() - XCTAssertNil(tsAccountManagerMock.updatedPni) + XCTAssertNil(self.updatedPni) XCTAssertFalse(db.read { kvStore.hasSucceeded(tx: $0) }) } func testSkipsIfNoLocalIdentifiers() { + tsAccountManagerMock.localIdentifiersMock = { nil } learnMyOwnPniManager.learnMyOwnPniIfNecessary().cauterize() - XCTAssertNil(tsAccountManagerMock.updatedPni) + XCTAssertNil(self.updatedPni) XCTAssertFalse(db.read { kvStore.hasSucceeded(tx: $0) }) } @@ -98,14 +108,14 @@ class LearnMyOwnPniManagerTest: XCTestCase { let localE164 = E164("+17735550199")! let remotePni = Pni.randomForTesting() - tsAccountManagerMock.mockIdentifiers = .init(aci: localAci, pni: nil, e164: localE164) + tsAccountManagerMock.localIdentifiersMock = { .init(aci: localAci, pni: nil, e164: localE164) } accountServiceClientMock.whoAmIResult = .value(.init(aci: localAci, pni: remotePni, e164: localE164)) pniIdentityKeyCheckerMock.checkResult = .value(false) // Can assume false since we didn't even know the PNI preKeyManagerMock.createKeysResult = .value(()) learnMyOwnPniManager.learnMyOwnPniIfNecessary().cauterize() - XCTAssertEqual(remotePni, tsAccountManagerMock.updatedPni) + XCTAssertEqual(remotePni, self.updatedPni) XCTAssertTrue(db.read { kvStore.hasSucceeded(tx: $0) }) } @@ -114,13 +124,13 @@ class LearnMyOwnPniManagerTest: XCTestCase { let localPni = Pni.randomForTesting() let localE164 = E164("+17735550199")! - tsAccountManagerMock.mockIdentifiers = .init(aci: localAci, pni: localPni, e164: localE164) + tsAccountManagerMock.localIdentifiersMock = { .init(aci: localAci, pni: localPni, e164: localE164) } pniIdentityKeyCheckerMock.checkResult = .value(false) preKeyManagerMock.createKeysResult = .value(()) learnMyOwnPniManager.learnMyOwnPniIfNecessary().cauterize() - XCTAssertNil(tsAccountManagerMock.updatedPni) + XCTAssertNil(self.updatedPni) XCTAssertTrue(db.read { kvStore.hasSucceeded(tx: $0) }) } @@ -129,12 +139,12 @@ class LearnMyOwnPniManagerTest: XCTestCase { let localPni = Pni.randomForTesting() let localE164 = E164("+17735550199")! - tsAccountManagerMock.mockIdentifiers = .init(aci: localAci, pni: localPni, e164: localE164) + tsAccountManagerMock.localIdentifiersMock = { .init(aci: localAci, pni: localPni, e164: localE164) } pniIdentityKeyCheckerMock.checkResult = .value(true) learnMyOwnPniManager.learnMyOwnPniIfNecessary().cauterize() - XCTAssertNil(tsAccountManagerMock.updatedPni) + XCTAssertNil(self.updatedPni) XCTAssertTrue(db.read { kvStore.hasSucceeded(tx: $0) }) } @@ -145,12 +155,12 @@ class LearnMyOwnPniManagerTest: XCTestCase { let remoteAci = Aci.randomForTesting() let remotePni = Pni.randomForTesting() - tsAccountManagerMock.mockIdentifiers = .init(aci: localAci, pni: nil, e164: localE164) + tsAccountManagerMock.localIdentifiersMock = { .init(aci: localAci, pni: nil, e164: localE164) } accountServiceClientMock.whoAmIResult = .value(.init(aci: remoteAci, pni: remotePni, e164: localE164)) learnMyOwnPniManager.learnMyOwnPniIfNecessary().cauterize() - XCTAssertNil(tsAccountManagerMock.updatedPni) + XCTAssertNil(self.updatedPni) XCTAssertFalse(db.read { kvStore.hasSucceeded(tx: $0) }) } @@ -161,12 +171,12 @@ class LearnMyOwnPniManagerTest: XCTestCase { let remotePni = Pni.randomForTesting() let remoteE164 = E164("+17735550198")! - tsAccountManagerMock.mockIdentifiers = .init(aci: localAci, pni: nil, e164: localE164) + tsAccountManagerMock.localIdentifiersMock = { .init(aci: localAci, pni: nil, e164: localE164) } accountServiceClientMock.whoAmIResult = .value(.init(aci: localAci, pni: remotePni, e164: remoteE164)) learnMyOwnPniManager.learnMyOwnPniIfNecessary().cauterize() - XCTAssertNil(tsAccountManagerMock.updatedPni) + XCTAssertNil(self.updatedPni) XCTAssertFalse(db.read { kvStore.hasSucceeded(tx: $0) }) } @@ -175,7 +185,7 @@ class LearnMyOwnPniManagerTest: XCTestCase { let localE164 = E164("+17735550199")! let remotePni = Pni.randomForTesting() - tsAccountManagerMock.mockIdentifiers = .init(aci: localAci, pni: nil, e164: localE164) + tsAccountManagerMock.localIdentifiersMock = { .init(aci: localAci, pni: nil, e164: localE164) } accountServiceClientMock.whoAmIResult = .value(.init(aci: localAci, pni: remotePni, e164: localE164)) pniIdentityKeyCheckerMock.checkResult = .value(true) @@ -185,7 +195,7 @@ class LearnMyOwnPniManagerTest: XCTestCase { learnMyOwnPniManager.learnMyOwnPniIfNecessary().cauterize() scheduler.start() - XCTAssertEqual(remotePni, tsAccountManagerMock.updatedPni) + XCTAssertEqual(remotePni, self.updatedPni) XCTAssertTrue(db.read { kvStore.hasSucceeded(tx: $0) }) } @@ -230,23 +240,3 @@ private class PreKeyManagerMock: MockPreKeyManager { return createKeysResult.consumeIntoPromise() } } - -// MARK: TSAccountManager - -private class TSAccountManagerMock: LearnMyOwnPniManagerImpl.Shims.TSAccountManager { - var isPrimaryDevice: Bool = true - var mockIdentifiers: LocalIdentifiers? - var updatedPni: Pni? - - func isPrimaryDevice(tx _: DBReadTransaction) -> Bool { - return isPrimaryDevice - } - - func localIdentifiers(tx _: DBReadTransaction) -> LocalIdentifiers? { - return mockIdentifiers - } - - func updateLocalIdentifiers(e164 _: E164, aci _: Aci, pni: Pni, tx _: DBWriteTransaction) { - updatedPni = pni - } -} diff --git a/SignalServiceKit/tests/Account/LinkedDevicePniKeyManagerTest.swift b/SignalServiceKit/tests/Account/LinkedDevicePniKeyManagerTest.swift index a3e3efaeba..3263036325 100644 --- a/SignalServiceKit/tests/Account/LinkedDevicePniKeyManagerTest.swift +++ b/SignalServiceKit/tests/Account/LinkedDevicePniKeyManagerTest.swift @@ -29,11 +29,14 @@ final class LinkedDevicePniKeyManagerTest: XCTestCase { private var kvStore: TestKVStore! private var messageProcessorMock: MessageProcessorMock! private var pniIdentityKeyCheckerMock: PniIdentityKeyCheckerMock! + private var registrationStateChangeManagerMock: MockRegistrationStateChangeManager! private var testScheduler: TestScheduler! - private var tsAccountManagerMock: TSAccountManagerMock! + private var tsAccountManagerMock: MockTSAccountManager! private var linkedDevicePniKeyManager: LinkedDevicePniKeyManagerImpl! + private var isMarkedDeregistered: Bool = false + override func setUp() { let kvStoreFactory = InMemoryKeyValueStoreFactory() @@ -44,13 +47,21 @@ final class LinkedDevicePniKeyManagerTest: XCTestCase { kvStore = TestKVStore(db: db, kvStoreFactory: kvStoreFactory) messageProcessorMock = MessageProcessorMock(schedulers: testSchedulers) pniIdentityKeyCheckerMock = PniIdentityKeyCheckerMock() - tsAccountManagerMock = TSAccountManagerMock() + registrationStateChangeManagerMock = .init() + tsAccountManagerMock = .init() + + registrationStateChangeManagerMock.setIsDeregisteredOrDelinkedMock = { [weak self] isDeregistered in + self?.isMarkedDeregistered = isDeregistered + } + + tsAccountManagerMock.registrationStateMock = { .provisioned } linkedDevicePniKeyManager = LinkedDevicePniKeyManagerImpl( db: db, keyValueStoreFactory: kvStoreFactory, messageProcessor: messageProcessorMock, pniIdentityKeyChecker: pniIdentityKeyCheckerMock, + registrationStateChangeManager: registrationStateChangeManagerMock, schedulers: testSchedulers, tsAccountManager: tsAccountManagerMock ) @@ -74,7 +85,7 @@ final class LinkedDevicePniKeyManagerTest: XCTestCase { } func testDoesntRecordIfPrimaryDevice() { - tsAccountManagerMock.isPrimaryDevice = true + tsAccountManagerMock.registrationStateMock = { .registered } db.write { tx in linkedDevicePniKeyManager.recordSuspectedIssueWithPniIdentityKey(tx: tx) @@ -87,23 +98,23 @@ final class LinkedDevicePniKeyManagerTest: XCTestCase { func testUnlinkedIfDecryptionErrorAndMissingPni() { messageProcessorMock.fetchProcessResult = .value({}) - tsAccountManagerMock.localIdentifiers = .missingPni + tsAccountManagerMock.localIdentifiersMock = { .missingPni } runRunRun(recordIssue: true) XCTAssertFalse(kvStore.hasDecryptionError()) - XCTAssertTrue(tsAccountManagerMock.isDeregistered) + XCTAssertTrue(self.isMarkedDeregistered) } func testUnlinkedIfDecryptionErrorAndMismatchedIdentityKey() { messageProcessorMock.fetchProcessResult = .value({}) - tsAccountManagerMock.localIdentifiers = .mock + tsAccountManagerMock.localIdentifiersMock = { .mock } pniIdentityKeyCheckerMock.matchResult = .value(false) runRunRun(recordIssue: true) XCTAssertFalse(kvStore.hasDecryptionError()) - XCTAssertTrue(tsAccountManagerMock.isDeregistered) + XCTAssertTrue(self.isMarkedDeregistered) } func testNotUnlinkedIfMessageFetchingProcessingFails() { @@ -112,39 +123,39 @@ final class LinkedDevicePniKeyManagerTest: XCTestCase { runRunRun(recordIssue: true) XCTAssertTrue(kvStore.hasDecryptionError()) - XCTAssertFalse(tsAccountManagerMock.isDeregistered) + XCTAssertFalse(self.isMarkedDeregistered) } func testNotUnlinkedIfIdentityKeyCheckingFails() { messageProcessorMock.fetchProcessResult = .value({}) - tsAccountManagerMock.localIdentifiers = .mock + tsAccountManagerMock.localIdentifiersMock = { .mock } pniIdentityKeyCheckerMock.matchResult = .error() runRunRun(recordIssue: true) XCTAssertTrue(kvStore.hasDecryptionError()) - XCTAssertFalse(tsAccountManagerMock.isDeregistered) + XCTAssertFalse(self.isMarkedDeregistered) } func testNotUnlinkedIfIdentityKeyMatches() { messageProcessorMock.fetchProcessResult = .value({}) - tsAccountManagerMock.localIdentifiers = .mock + tsAccountManagerMock.localIdentifiersMock = { .mock } pniIdentityKeyCheckerMock.matchResult = .value(true) runRunRun(recordIssue: true) XCTAssertFalse(kvStore.hasDecryptionError()) - XCTAssertFalse(tsAccountManagerMock.isDeregistered) + XCTAssertFalse(self.isMarkedDeregistered) } func testEarlyExitIfPrimary() { - tsAccountManagerMock.isPrimaryDevice = true + tsAccountManagerMock.registrationStateMock = { .registered } // This will fail if it doesn't early-exit, due to missing mocks. runRunRun(recordIssue: false) XCTAssertFalse(kvStore.hasDecryptionError()) - XCTAssertFalse(tsAccountManagerMock.isDeregistered) + XCTAssertFalse(self.isMarkedDeregistered) } func testEarlyExitIfNoError() { @@ -154,7 +165,7 @@ final class LinkedDevicePniKeyManagerTest: XCTestCase { runRunRun(recordIssue: false) XCTAssertFalse(kvStore.hasDecryptionError()) - XCTAssertFalse(tsAccountManagerMock.isDeregistered) + XCTAssertFalse(self.isMarkedDeregistered) } /// It's important that we don't check for the decryption error until @@ -162,21 +173,21 @@ final class LinkedDevicePniKeyManagerTest: XCTestCase { /// register the error. func testChecksForDecryptionErrorAfterClearingQueue() { messageProcessorMock.fetchProcessResult = .value({ self.runRunRun(recordIssue: true) }) - tsAccountManagerMock.localIdentifiers = .mock + tsAccountManagerMock.localIdentifiersMock = { .mock } pniIdentityKeyCheckerMock.matchResult = .value(false) runRunRun(recordIssue: false) // Expect an unlink XCTAssertFalse(kvStore.hasDecryptionError()) - XCTAssertTrue(tsAccountManagerMock.isDeregistered) + XCTAssertTrue(self.isMarkedDeregistered) } /// Checks that multiple overlapping validation attempts are collapsed into /// one. Also checks that a subsequent validation runs. func testMultipleCallsResultInOneRun() { messageProcessorMock.fetchProcessResult = .value({}) - tsAccountManagerMock.localIdentifiers = .mock + tsAccountManagerMock.localIdentifiersMock = { .mock } pniIdentityKeyCheckerMock.matchResult = .value(true) db.write { tx in @@ -186,10 +197,10 @@ final class LinkedDevicePniKeyManagerTest: XCTestCase { testScheduler.runUntilIdle() XCTAssertFalse(kvStore.hasDecryptionError()) - XCTAssertFalse(tsAccountManagerMock.isDeregistered) + XCTAssertFalse(self.isMarkedDeregistered) messageProcessorMock.fetchProcessResult = .value({}) - tsAccountManagerMock.localIdentifiers = .mock + tsAccountManagerMock.localIdentifiersMock = { .mock } pniIdentityKeyCheckerMock.matchResult = .value(false) db.write { tx in @@ -198,7 +209,7 @@ final class LinkedDevicePniKeyManagerTest: XCTestCase { testScheduler.runUntilIdle() XCTAssertFalse(kvStore.hasDecryptionError()) - XCTAssertTrue(tsAccountManagerMock.isDeregistered) + XCTAssertTrue(self.isMarkedDeregistered) } } @@ -239,21 +250,3 @@ private class PniIdentityKeyCheckerMock: PniIdentityKeyChecker { return matchResult.consumeIntoPromise() } } - -private class TSAccountManagerMock: LinkedDevicePniKeyManagerImpl.Shims.TSAccountManager { - var localIdentifiers: LocalIdentifiers? - var isPrimaryDevice = false - var isDeregistered = false - - func localIdentifiers(tx: DBReadTransaction) -> LocalIdentifiers? { - return localIdentifiers - } - - func isPrimaryDevice(tx: DBReadTransaction) -> Bool { - return isPrimaryDevice - } - - func setIsDeregistered() { - isDeregistered = true - } -} diff --git a/SignalServiceKit/tests/Account/PniHelloWorldManagerTest.swift b/SignalServiceKit/tests/Account/PniHelloWorldManagerTest.swift index a08e60e04e..c1a28e7b3b 100644 --- a/SignalServiceKit/tests/Account/PniHelloWorldManagerTest.swift +++ b/SignalServiceKit/tests/Account/PniHelloWorldManagerTest.swift @@ -34,7 +34,7 @@ class PniHelloWorldManagerTest: XCTestCase { private var pniKyberPreKeyStoreMock: MockKyberPreKeyStore! private var profileManagerMock: ProfileManagerMock! private var signalRecipientStoreMock: SignalRecipientStoreMock! - private var tsAccountManagerMock: TSAccountManagerMock! + private var tsAccountManagerMock: MockTSAccountManager! private let db = MockDB() private var kvStore: TestKeyValueStore! @@ -88,8 +88,8 @@ class PniHelloWorldManagerTest: XCTestCase { private func setMocksForHappyPath( includingNetworkRequest mockNetworkRequest: Bool = false ) { - tsAccountManagerMock.isPrimaryDevice = true - tsAccountManagerMock.localIdentifiers = .mock + tsAccountManagerMock.registrationStateMock = { .registered } + tsAccountManagerMock.localIdentifiersMock = { .mock } signalRecipientStoreMock.localAccountId = "foobar" signalRecipientStoreMock.deviceIds = [1, 2, 3] profileManagerMock.isPniCapable = true @@ -124,7 +124,7 @@ class PniHelloWorldManagerTest: XCTestCase { func testSkipsIfLinkedDevice() { setMocksForHappyPath() - tsAccountManagerMock.isPrimaryDevice = false + tsAccountManagerMock.registrationStateMock = { .provisioned } runRunRun() @@ -144,7 +144,7 @@ class PniHelloWorldManagerTest: XCTestCase { func testSkipsIfMissingLocalIdentifiers() { setMocksForHappyPath() - tsAccountManagerMock.localIdentifiers = nil + tsAccountManagerMock.localIdentifiersMock = { nil } runRunRun() @@ -154,7 +154,7 @@ class PniHelloWorldManagerTest: XCTestCase { func testSkipsIfMissingLocalPni() { setMocksForHappyPath() - tsAccountManagerMock.localIdentifiers = .missingPni + tsAccountManagerMock.localIdentifiersMock = { .missingPni } runRunRun() @@ -326,26 +326,3 @@ private class SignalRecipientStoreMock: _PniHelloWorldManagerImpl_SignalRecipien return (localAccountId, deviceIds) } } - -// MARK: TSAccountManager - -private class TSAccountManagerMock: _PniHelloWorldManagerImpl_TSAccountManager_Shim { - var isPrimaryDevice: Bool = false - var localIdentifiers: LocalIdentifiers? - - func isPrimaryDevice(tx: DBReadTransaction) -> Bool { - return isPrimaryDevice - } - - func localIdentifiers(tx: DBReadTransaction) -> LocalIdentifiers? { - return localIdentifiers - } - - func localDeviceId(tx: DBReadTransaction) -> UInt32 { - return 1 - } - - func getPniRegistrationId(tx: DBWriteTransaction) -> UInt32 { - return UInt32.random(in: 0..<500) - } -} diff --git a/SignalServiceKit/tests/Account/PreKeys/PreKeyTaskTestMocks.swift b/SignalServiceKit/tests/Account/PreKeys/PreKeyTaskTestMocks.swift index 23fc18bc37..c988d7e37e 100644 --- a/SignalServiceKit/tests/Account/PreKeys/PreKeyTaskTestMocks.swift +++ b/SignalServiceKit/tests/Account/PreKeys/PreKeyTaskTestMocks.swift @@ -13,7 +13,6 @@ import Foundation // extension PreKey.Operation { enum Mocks { - typealias AccountManager = _PreKey_AccountManagerMock typealias AccountServiceClient = _PreKey_AccountServiceClientMock typealias DateProvider = _PreKey_DateProviderMock typealias IdentityManager = _PreKey_IdentityManagerMock @@ -28,11 +27,6 @@ extension PreKey.Operation { // // -class _PreKey_AccountManagerMock: PreKey.Operation.Shims.AccountManager { - var isRegisteredAndReady: Bool = true - func isRegisteredAndReady(tx: SignalServiceKit.DBReadTransaction) -> Bool { isRegisteredAndReady } -} - class _PreKey_IdentityManagerMock: PreKey.Operation.Shims.IdentityManager { var aciKeyPair: ECKeyPair? diff --git a/SignalServiceKit/tests/Account/PreKeys/PreKeyTaskTests.swift b/SignalServiceKit/tests/Account/PreKeys/PreKeyTaskTests.swift index e637b58556..3a1dd5d657 100644 --- a/SignalServiceKit/tests/Account/PreKeys/PreKeyTaskTests.swift +++ b/SignalServiceKit/tests/Account/PreKeys/PreKeyTaskTests.swift @@ -12,7 +12,7 @@ final class PreKeyTaskTests: XCTestCase { private var testSchedulers: TestSchedulers! - private var mockAccountManager: PreKey.Operation.Mocks.AccountManager! + private var mockTSAccountManager: MockTSAccountManager! private var mockIdentityManager: PreKey.Operation.Mocks.IdentityManager! private var mockLinkedDevicePniKeyManager: PreKey.Operation.Mocks.LinkedDevicePniKeyManager! private var mockServiceClient: PreKey.Operation.Mocks.AccountServiceClient! @@ -26,7 +26,7 @@ final class PreKeyTaskTests: XCTestCase { override func setUp() { super.setUp() testSchedulers = TestSchedulers(scheduler: TestScheduler()) - mockAccountManager = .init() + mockTSAccountManager = .init() mockIdentityManager = .init() mockLinkedDevicePniKeyManager = .init() mockServiceClient = .init(schedulers: testSchedulers) @@ -40,7 +40,6 @@ final class PreKeyTaskTests: XCTestCase { ) context = PreKeyTasks.Context( - accountManager: mockAccountManager, dateProvider: mockDateProvider.targetDate, db: MockDB(schedulers: testSchedulers), identityManager: mockIdentityManager, @@ -48,7 +47,8 @@ final class PreKeyTaskTests: XCTestCase { messageProcessor: PreKey.Operation.Mocks.MessageProcessor(), protocolStoreManager: mockProtocolStoreManager, schedulers: testSchedulers, - serviceClient: mockServiceClient + serviceClient: mockServiceClient, + tsAccountManager: mockTSAccountManager ) } diff --git a/SignalServiceKit/tests/Account/SignalAccountFinderTest.swift b/SignalServiceKit/tests/Account/SignalAccountFinderTest.swift index c5c96cacc3..e47978bfbd 100644 --- a/SignalServiceKit/tests/Account/SignalAccountFinderTest.swift +++ b/SignalServiceKit/tests/Account/SignalAccountFinderTest.swift @@ -12,7 +12,12 @@ class SignalAccountFinderTest: SSKBaseTestSwift { override func setUp() { super.setUp() // Create local account. - tsAccountManager.registerForTests(localIdentifiers: .forUnitTests) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .forUnitTests, + tx: tx.asV2Write + ) + } } private func createAccount(serviceId: ServiceId, phoneNumber: E164?) -> SignalAccount { diff --git a/SignalServiceKit/tests/Calls/OutgoingCallEventSyncMessageTest.swift b/SignalServiceKit/tests/Calls/OutgoingCallEventSyncMessageTest.swift index c85a2369c4..c67a312834 100644 --- a/SignalServiceKit/tests/Calls/OutgoingCallEventSyncMessageTest.swift +++ b/SignalServiceKit/tests/Calls/OutgoingCallEventSyncMessageTest.swift @@ -56,11 +56,16 @@ final class OutgoingCallEventSyncMessageSerializationTest: SSKBaseTestSwift { /// ``OutgoingCallEventSyncMessage`` will continue to serialize/deserialize /// correctly. This should be trivial, but Mantle makes me nervous. func testCallEventRoundTrip() throws { - tsAccountManager.registerForTests(localIdentifiers: LocalIdentifiers( - aci: Aci(fromUUID: UUID()), - pni: Pni(fromUUID: UUID()), - phoneNumber: "+17735550199" - )) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .init( + aci: .init(fromUUID: UUID()), + pni: .init(fromUUID: UUID()), + e164: .init("+17735550199")! + ), + tx: tx.asV2Write + ) + } let syncMessage: OutgoingCallEventSyncMessage = write { tx in return OutgoingCallEventSyncMessage( diff --git a/SignalServiceKit/tests/Calls/OutgoingGroupCallUpdateMessageTest.swift b/SignalServiceKit/tests/Calls/OutgoingGroupCallUpdateMessageTest.swift index 1972728330..b1837440bd 100644 --- a/SignalServiceKit/tests/Calls/OutgoingGroupCallUpdateMessageTest.swift +++ b/SignalServiceKit/tests/Calls/OutgoingGroupCallUpdateMessageTest.swift @@ -11,11 +11,16 @@ import XCTest final class OutgoingGroupCallUpdateMessageSerializationTest: SSKBaseTestSwift { /// Confirms that an ``OutgoingGroupCallUpdateMessage`` (de)serializes. func testGroupCallUpdateMessageRoundTrip() throws { - tsAccountManager.registerForTests(localIdentifiers: LocalIdentifiers( - aci: Aci(fromUUID: UUID()), - pni: Pni(fromUUID: UUID()), - phoneNumber: "+17735550199" - )) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .init( + aci: .init(fromUUID: UUID()), + pni: .init(fromUUID: UUID()), + e164: .init("+17735550199")! + ), + tx: tx.asV2Write + ) + } let updateMessage = write { tx in return OutgoingGroupCallUpdateMessage( diff --git a/SignalServiceKit/tests/ChangePhoneNumber/ChangePhoneNumberPniManagerTest.swift b/SignalServiceKit/tests/ChangePhoneNumber/ChangePhoneNumberPniManagerTest.swift index 43d0855771..32ddebf39d 100644 --- a/SignalServiceKit/tests/ChangePhoneNumber/ChangePhoneNumberPniManagerTest.swift +++ b/SignalServiceKit/tests/ChangePhoneNumber/ChangePhoneNumberPniManagerTest.swift @@ -16,7 +16,7 @@ class ChangePhoneNumberPniManagerTest: XCTestCase { private var signedPreKeyStoreMock: MockSignalSignedPreKeyStore! private var kyberPreKeyStoreMock: MockKyberPreKeyStore! private var registrationIdGeneratorMock: MockRegistrationIdGenerator! - private var tsAccountManagerMock: TSAccountManagerMock! + private var tsAccountManagerMock: MockTSAccountManager! private var schedulers: TestSchedulers! private var db: MockDB! @@ -131,7 +131,7 @@ class ChangePhoneNumberPniManagerTest: XCTestCase { ) XCTAssertEqual( - tsAccountManagerMock.storedPniRegistrationId, + tsAccountManagerMock.pniRegistrationIdMock(), pendingState.localDevicePniRegistrationId ) @@ -263,17 +263,3 @@ private class PniDistributionParameterBuilderMock: PniDistributionParamaterBuild } } } - -// MARK: TSAccountManager - -private class TSAccountManagerMock: ChangePhoneNumberPniManagerImpl.Shims.TSAccountManager { - - var storedPniRegistrationId: UInt32? - - func setPniRegistrationId( - newRegistrationId: UInt32, - transaction: DBWriteTransaction - ) { - storedPniRegistrationId = newRegistrationId - } -} diff --git a/SignalServiceKit/tests/Contacts/BlockingManagerTests.swift b/SignalServiceKit/tests/Contacts/BlockingManagerTests.swift index 5ef3642e51..3e7d2b42ae 100644 --- a/SignalServiceKit/tests/Contacts/BlockingManagerTests.swift +++ b/SignalServiceKit/tests/Contacts/BlockingManagerTests.swift @@ -197,7 +197,12 @@ class BlockingManagerTests: SSKBaseTestSwift { // ensure local client has necessary "registered" state let identityManager = DependenciesBridge.shared.identityManager identityManager.generateAndPersistNewIdentityKey(for: .aci) - tsAccountManager.registerForTests(localIdentifiers: .forUnitTests) + Self.databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .forUnitTests, + tx: tx.asV2Write + ) + } BlockingManager.TestingFlags.optimisticallyCommitSyncToken = true // Test diff --git a/SignalServiceKit/tests/Contacts/OWSRecipientIdentityTest.swift b/SignalServiceKit/tests/Contacts/OWSRecipientIdentityTest.swift index 170b199359..7f2269ec6c 100644 --- a/SignalServiceKit/tests/Contacts/OWSRecipientIdentityTest.swift +++ b/SignalServiceKit/tests/Contacts/OWSRecipientIdentityTest.swift @@ -32,7 +32,16 @@ class OWSRecipientIdentityTest: SSKBaseTestSwift { private func createFakeGroup() throws { // Create local account. - tsAccountManager.registerForTests(localIdentifiers: LocalIdentifiers(aci: localAci, pni: nil, phoneNumber: "+16505550100")) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .init( + aci: localAci, + pni: nil, + e164: E164("+16505550100")! + ), + tx: tx.asV2Write + ) + } // Create recipients & identities for them. write { tx in let recipientFetcher = DependenciesBridge.shared.recipientFetcher diff --git a/SignalServiceKit/tests/Contacts/SignalRecipientTest.swift b/SignalServiceKit/tests/Contacts/SignalRecipientTest.swift index 920665fbc7..d5b6aa0b8a 100644 --- a/SignalServiceKit/tests/Contacts/SignalRecipientTest.swift +++ b/SignalServiceKit/tests/Contacts/SignalRecipientTest.swift @@ -21,7 +21,12 @@ class SignalRecipientTest: SSKBaseTestSwift { override func setUp() { super.setUp() - tsAccountManager.registerForTests(localIdentifiers: localIdentifiers) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: localIdentifiers, + tx: tx.asV2Write + ) + } } func testSelfRecipientWithExistingRecord() { diff --git a/SignalServiceKit/tests/Contacts/TSContactThreadTest.swift b/SignalServiceKit/tests/Contacts/TSContactThreadTest.swift index db175e544e..fc5bd182d8 100644 --- a/SignalServiceKit/tests/Contacts/TSContactThreadTest.swift +++ b/SignalServiceKit/tests/Contacts/TSContactThreadTest.swift @@ -14,7 +14,12 @@ class TSContactThreadTest: SSKBaseTestSwift { override func setUp() { super.setUp() - tsAccountManager.registerForTests(localIdentifiers: .forUnitTests) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .forUnitTests, + tx: tx.asV2Write + ) + } } func testHasSafetyNumbersWithoutRemoteIdentity() { diff --git a/SignalServiceKit/tests/Messages/Interactions/TSOutgoingMessageTest.swift b/SignalServiceKit/tests/Messages/Interactions/TSOutgoingMessageTest.swift index 59e1011c85..4fd218ca28 100644 --- a/SignalServiceKit/tests/Messages/Interactions/TSOutgoingMessageTest.swift +++ b/SignalServiceKit/tests/Messages/Interactions/TSOutgoingMessageTest.swift @@ -13,7 +13,12 @@ class TSOutgoingMessageTest: SSKBaseTestSwift { override func setUp() { super.setUp() - tsAccountManager.registerForTests(localIdentifiers: .forUnitTests) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .forUnitTests, + tx: tx.asV2Write + ) + } identityManager.generateAndPersistNewIdentityKey(for: .aci) identityManager.generateAndPersistNewIdentityKey(for: .pni) } @@ -107,7 +112,7 @@ class TSOutgoingMessageTest: SSKBaseTestSwift { let content = try! SSKProtoContent(serializedData: messageData) let messagePni = content.pniSignatureMessage!.pni - XCTAssertEqual(messagePni, tsAccountManager.localPni!.rawUUID.data) + XCTAssertEqual(messagePni, DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)!.pni!.rawUUID.data) let aciKeyPair = identityManager.identityKeyPair(for: .aci, tx: transaction.asV2Read)!.identityKeyPair let pniKeyPair = identityManager.identityKeyPair(for: .pni, tx: transaction.asV2Read)!.identityKeyPair @@ -323,9 +328,17 @@ class TSOutgoingMessageTest: SSKBaseTestSwift { // Change our PNI, using registerForTests(...) instead of updateLocalPhoneNumber(...) because the latter kicks // off a request to check with the server. - tsAccountManager.registerForTests(withLocalNumber: "+17775550199", - uuid: tsAccountManager.localAci!.rawUUID, - pni: UUID()) + let aci = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction!.aci + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .init( + aci: aci, + pni: .init(fromUUID: .init()), + e164: .init("+17775550199")! + ), + tx: tx.asV2Write + ) + } write { transaction in // Changing your number resets this setting. diff --git a/SignalServiceKit/tests/Messages/MessageDecryptionTest.swift b/SignalServiceKit/tests/Messages/MessageDecryptionTest.swift index 33abfa5c72..4106db24ad 100644 --- a/SignalServiceKit/tests/Messages/MessageDecryptionTest.swift +++ b/SignalServiceKit/tests/Messages/MessageDecryptionTest.swift @@ -34,7 +34,16 @@ class MessageDecryptionTest: SSKBaseTestSwift { let identityManager = DependenciesBridge.shared.identityManager identityManager.generateAndPersistNewIdentityKey(for: .aci) identityManager.generateAndPersistNewIdentityKey(for: .pni) - tsAccountManager.registerForTests(withLocalNumber: localE164Identifier, uuid: localAci, pni: localPni) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .init( + aci: .init(fromUUID: localAci), + pni: .init(fromUUID: localPni), + e164: .init(localE164Identifier)! + ), + tx: tx.asV2Write + ) + } (notificationsManager as! NoopNotificationsManager).expectErrors = true (udManager as! OWSUDManagerImpl).trustRoot = try! sealedSenderTrustRoot.ecPublicKey() @@ -122,7 +131,7 @@ class MessageDecryptionTest: SSKBaseTestSwift { prepareForDecryption(localProtocolStore, transaction) - let localIdentifiers = tsAccountManager.localIdentifiers(transaction: transaction)! + let localIdentifiers = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)! let decryptedEnvelope: Result = Result { let validatedEnvelope = try ValidatedIncomingEnvelope(envelope, localIdentifiers: localIdentifiers) switch validatedEnvelope.kind { @@ -132,7 +141,7 @@ class MessageDecryptionTest: SSKBaseTestSwift { return try messageDecrypter.decryptUnidentifiedSenderEnvelope( validatedEnvelope, localIdentifiers: localIdentifiers, - localDeviceId: tsAccountManager.storedDeviceId(transaction: transaction), + localDeviceId: DependenciesBridge.shared.tsAccountManager.storedDeviceId(tx: transaction.asV2Read), tx: transaction ) case .identifiedSender(let cipherType): diff --git a/SignalServiceKit/tests/Messages/MessageProcessingIntegrationTest.swift b/SignalServiceKit/tests/Messages/MessageProcessingIntegrationTest.swift index 7092796a3a..0f675d34a0 100644 --- a/SignalServiceKit/tests/Messages/MessageProcessingIntegrationTest.swift +++ b/SignalServiceKit/tests/Messages/MessageProcessingIntegrationTest.swift @@ -37,7 +37,16 @@ class MessageProcessingIntegrationTest: SSKBaseTestSwift { let identityManager = DependenciesBridge.shared.identityManager identityManager.generateAndPersistNewIdentityKey(for: .aci) identityManager.generateAndPersistNewIdentityKey(for: .pni) - tsAccountManager.registerForTests(withLocalNumber: localE164Identifier, uuid: localUUID, pni: UUID()) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .init( + aci: .init(fromUUID: localUUID), + pni: .init(fromUUID: UUID()), + e164: .init(localE164Identifier)! + ), + tx: tx.asV2Write + ) + } bobClient = FakeSignalClient.generate(e164Identifier: bobE164Identifier) aliceClient = FakeSignalClient.generate(e164Identifier: aliceE164Identifier) @@ -200,7 +209,7 @@ class MessageProcessingIntegrationTest: SSKBaseTestSwift { envelopeBuilder.setSourceDevice(1) envelopeBuilder.setServerTimestamp(NSDate.ows_millisecondTimeStamp()) envelopeBuilder.setServerGuid(UUID().uuidString) - envelopeBuilder.setDestinationServiceID(tsAccountManager.localIdentifiers!.pni!.serviceIdString) + envelopeBuilder.setDestinationServiceID(DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction!.pni!.serviceIdString) let envelopeData = try! envelopeBuilder.buildSerializedData() messageProcessor.processReceivedEnvelopeData( envelopeData, diff --git a/SignalServiceKit/tests/Messages/OWSUDManagerTest.swift b/SignalServiceKit/tests/Messages/OWSUDManagerTest.swift index 4bad310c85..0b6d2ab76c 100644 --- a/SignalServiceKit/tests/Messages/OWSUDManagerTest.swift +++ b/SignalServiceKit/tests/Messages/OWSUDManagerTest.swift @@ -25,7 +25,12 @@ class OWSUDManagerTest: SSKBaseTestSwift { override func setUp() { super.setUp() - tsAccountManager.registerForTests(localIdentifiers: LocalIdentifiers(aci: aliceAci, pni: nil, phoneNumber: aliceE164)) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .init(aci: aliceAci, pni: nil, e164: E164(aliceE164)!), + tx: tx.asV2Write + ) + } // Configure UDManager self.write { transaction in @@ -42,7 +47,7 @@ class OWSUDManagerTest: SSKBaseTestSwift { // MARK: - Tests func testMode_noProfileKey() { - XCTAssert(tsAccountManager.isRegistered) + XCTAssert(DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered) // Ensure UD is enabled by setting our own access level to enabled. write { tx in @@ -86,8 +91,8 @@ class OWSUDManagerTest: SSKBaseTestSwift { } func testMode_withProfileKey() { - XCTAssert(tsAccountManager.isRegistered) - guard let localAddress = tsAccountManager.localAddress else { + XCTAssert(DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered) + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress else { XCTFail("localAddress was unexpectedly nil") return } diff --git a/SignalServiceKit/tests/Messages/TestProtocolRunnerTest.swift b/SignalServiceKit/tests/Messages/TestProtocolRunnerTest.swift index 4bb6011d3f..b92739e125 100644 --- a/SignalServiceKit/tests/Messages/TestProtocolRunnerTest.swift +++ b/SignalServiceKit/tests/Messages/TestProtocolRunnerTest.swift @@ -18,7 +18,16 @@ class TestProtocolRunnerTest: SSKBaseTestSwift { aliceClient = FakeSignalClient.generate(e164Identifier: "+122233alice") bobClient = FakeSignalClient.generate(e164Identifier: "+12223334bob") - tsAccountManager.registerForTests(withLocalNumber: "+13235551234", uuid: UUID()) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .init( + aci: .init(fromUUID: .init()), + pni: nil, + e164: .init("+13235551234")! + ), + tx: tx.asV2Write + ) + } } let runner = TestProtocolRunner() @@ -118,7 +127,16 @@ class TestProtocolRunnerTest: SSKBaseTestSwift { func test_localClient_receives() { let identityManager = DependenciesBridge.shared.identityManager identityManager.generateAndPersistNewIdentityKey(for: .aci) - Self.tsAccountManager.registerForTests(withLocalNumber: "+13235551234", uuid: UUID()) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .init( + aci: .init(fromUUID: .init()), + pni: nil, + e164: .init("+13235551234")! + ), + tx: tx.asV2Write + ) + } let localClient = LocalSignalClient() write { transaction in @@ -145,7 +163,16 @@ class TestProtocolRunnerTest: SSKBaseTestSwift { func test_localClient_sends() { let identityManager = DependenciesBridge.shared.identityManager identityManager.generateAndPersistNewIdentityKey(for: .aci) - Self.tsAccountManager.registerForTests(withLocalNumber: "+13235551234", uuid: UUID()) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .init( + aci: .init(fromUUID: .init()), + pni: nil, + e164: .init("+13235551234")! + ), + tx: tx.asV2Write + ) + } let localClient = LocalSignalClient() write { transaction in diff --git a/SignalServiceKit/tests/SecureValueRecovery/KeyBackupService/KeyBackupServiceTestShims.swift b/SignalServiceKit/tests/SecureValueRecovery/KeyBackupService/KeyBackupServiceTestShims.swift index 0882e58402..411f817482 100644 --- a/SignalServiceKit/tests/SecureValueRecovery/KeyBackupService/KeyBackupServiceTestShims.swift +++ b/SignalServiceKit/tests/SecureValueRecovery/KeyBackupService/KeyBackupServiceTestShims.swift @@ -10,34 +10,12 @@ import Foundation extension SVR { public enum TestMocks { - public typealias TSAccountManager = _KeyBackupServiceImpl_TSAccountManagerTestMock public typealias OWS2FAManager = _KeyBackupServiceImpl_OWS2FAManagerTestMock public typealias RemoteAttestation = _KeyBackupServiceImpl_RemoteAttestationMock public typealias URLSession = _KeyBackupServiceImpl_OWSURLSessionMock } } -// MARK: - TSAccountManager - -public class _KeyBackupServiceImpl_TSAccountManagerTestMock: SVR.Shims.TSAccountManager { - - public init() {} - - public var isPrimaryDevice: Bool = true - - public func isPrimaryDevice(transaction: DBReadTransaction) -> Bool { - return isPrimaryDevice - } - - public var isRegisteredAndReady: Bool = true - - public func isRegisteredAndReady(transaction: DBReadTransaction) -> Bool { - return isRegisteredAndReady - } - - public func scheduleAccountAttributesUpdate(authedAccount: AuthedAccount, transaction: DBWriteTransaction) {} -} - // MARK: - OWS2FAManager public class _KeyBackupServiceImpl_OWS2FAManagerTestMock: SVR.Shims.OWS2FAManager { diff --git a/SignalServiceKit/tests/SecureValueRecovery/KeyBackupService/KeyBackupServiceTests.swift b/SignalServiceKit/tests/SecureValueRecovery/KeyBackupService/KeyBackupServiceTests.swift index f417e2469c..b27e65de5b 100644 --- a/SignalServiceKit/tests/SecureValueRecovery/KeyBackupService/KeyBackupServiceTests.swift +++ b/SignalServiceKit/tests/SecureValueRecovery/KeyBackupService/KeyBackupServiceTests.swift @@ -26,19 +26,24 @@ class KeyBackupServiceTests: XCTestCase { self.mockSignalService = OWSSignalServiceMock() self.tsConstants = TSConstants.shared self.scheduler = TestScheduler() + + let kvStore = InMemoryKeyValueStoreFactory() + let localStorage = SVRLocalStorageImpl(keyValueStoreFactory: kvStore) + // Start the scheduler so everything executes synchronously. self.scheduler.start() self.keyBackupService = KeyBackupServiceImpl( - accountManager: SVR.TestMocks.TSAccountManager(), appContext: TestAppContext(), credentialStorage: credentialStorage, databaseStorage: db, - keyValueStoreFactory: InMemoryKeyValueStoreFactory(), + keyValueStoreFactory: kvStore, remoteAttestation: remoteAttestation, schedulers: TestSchedulers(scheduler: scheduler), signalService: mockSignalService, storageServiceManager: FakeStorageServiceManager(), + svrLocalStorage: localStorage, syncManager: OWSMockSyncManager(), + tsAccountManager: MockTSAccountManager(), tsConstants: tsConstants, twoFAManager: SVR.TestMocks.OWS2FAManager() ) diff --git a/SignalServiceKit/tests/SecureValueRecovery/SVR2/SVR2ConcurrencyTests.swift b/SignalServiceKit/tests/SecureValueRecovery/SVR2/SVR2ConcurrencyTests.swift index 8d7453b187..7d9f6194c4 100644 --- a/SignalServiceKit/tests/SecureValueRecovery/SVR2/SVR2ConcurrencyTests.swift +++ b/SignalServiceKit/tests/SecureValueRecovery/SVR2/SVR2ConcurrencyTests.swift @@ -29,18 +29,23 @@ class SVR2ConcurrencyTests: XCTestCase { let mockClientWrapper = MockSVR2ClientWrapper() + let kvStore = InMemoryKeyValueStoreFactory() + let localStorage = SVRLocalStorageImpl(keyValueStoreFactory: kvStore) + self.svr = SecureValueRecovery2Impl( + accountAttributesUpdater: MockAccountAttributesUpdater(), appReadiness: SVR2.Mocks.AppReadiness(), appVersion: MockAppVerion(), clientWrapper: mockClientWrapper, connectionFactory: mockConnectionFactory, credentialStorage: credentialStorage, db: db, - keyValueStoreFactory: InMemoryKeyValueStoreFactory(), + keyValueStoreFactory: kvStore, schedulers: Schedulers(queue), storageServiceManager: FakeStorageServiceManager(), + svrLocalStorage: localStorage, syncManager: OWSMockSyncManager(), - tsAccountManager: SVR.TestMocks.TSAccountManager(), + tsAccountManager: MockTSAccountManager(), tsConstants: TSConstants.shared, twoFAManager: SVR.TestMocks.OWS2FAManager() ) @@ -322,18 +327,23 @@ class SVR2ConcurrencyTests: XCTestCase { return requestPromise } + let kvStore = InMemoryKeyValueStoreFactory() + let localStorage = SVRLocalStorageImpl(keyValueStoreFactory: kvStore) + let svr = SecureValueRecovery2Impl( + accountAttributesUpdater: MockAccountAttributesUpdater(), appReadiness: SVR2.Mocks.AppReadiness(), appVersion: MockAppVerion(), clientWrapper: MockSVR2ClientWrapper(), connectionFactory: mockConnectionFactory, credentialStorage: credentialStorage, db: db, - keyValueStoreFactory: InMemoryKeyValueStoreFactory(), + keyValueStoreFactory: kvStore, schedulers: Schedulers(queue), storageServiceManager: FakeStorageServiceManager(), + svrLocalStorage: localStorage, syncManager: OWSMockSyncManager(), - tsAccountManager: SVR.TestMocks.TSAccountManager(), + tsAccountManager: MockTSAccountManager(), tsConstants: TSConstants.shared, twoFAManager: SVR.TestMocks.OWS2FAManager() ) diff --git a/SignalServiceKit/tests/SecureValueRecovery/SVR2/SecureValueRecovery2Tests.swift b/SignalServiceKit/tests/SecureValueRecovery/SVR2/SecureValueRecovery2Tests.swift index 1a92ea868b..048f88f236 100644 --- a/SignalServiceKit/tests/SecureValueRecovery/SVR2/SecureValueRecovery2Tests.swift +++ b/SignalServiceKit/tests/SecureValueRecovery/SVR2/SecureValueRecovery2Tests.swift @@ -16,11 +16,13 @@ class SecureValueRecovery2Tests: XCTestCase { private var credentialStorage: SVRAuthCredentialStorageMock! private var scheduler: TestScheduler! + private var mockAccountAttributesUpdater: MockAccountAttributesUpdater! private var mock2FAManager: SVR.TestMocks.OWS2FAManager! private var keyValueStoreFactory: InMemoryKeyValueStoreFactory! + private var localStorage: SVRLocalStorageImpl! private var mockConnectionFactory: MockSgxWebsocketConnectionFactory! private var mockConnection: MockSgxWebsocketConnection! - private var mockTSAccountManager: SVR.TestMocks.TSAccountManager! + private var mockTSAccountManager: MockTSAccountManager! private var mockTSConstants: TSConstantsMock! override func setUp() { @@ -32,16 +34,19 @@ class SecureValueRecovery2Tests: XCTestCase { mock2FAManager = SVR.TestMocks.OWS2FAManager() keyValueStoreFactory = InMemoryKeyValueStoreFactory() + localStorage = .init(keyValueStoreFactory: keyValueStoreFactory) let mockConnection = MockSgxWebsocketConnection() mockConnection.mockAuth = RemoteAttestation.Auth(username: "username", password: "password") self.mockConnection = mockConnection mockConnectionFactory = MockSgxWebsocketConnectionFactory() - mockTSAccountManager = SVR.TestMocks.TSAccountManager() + mockAccountAttributesUpdater = .init() + mockTSAccountManager = .init() mockTSConstants = TSConstantsMock() self.svr = SecureValueRecovery2Impl( + accountAttributesUpdater: mockAccountAttributesUpdater, appReadiness: SVR2.Mocks.AppReadiness(), appVersion: MockAppVerion(), clientWrapper: MockSVR2ClientWrapper(), @@ -51,6 +56,7 @@ class SecureValueRecovery2Tests: XCTestCase { keyValueStoreFactory: keyValueStoreFactory, schedulers: TestSchedulers(scheduler: scheduler), storageServiceManager: FakeStorageServiceManager(), + svrLocalStorage: localStorage, syncManager: OWSMockSyncManager(), tsAccountManager: mockTSAccountManager, tsConstants: mockTSConstants, @@ -83,13 +89,12 @@ class SecureValueRecovery2Tests: XCTestCase { let pin = "0000" // Set up the local data needed. - let localStorage = SVRLocalStorage(keyValueStoreFactory: keyValueStoreFactory) db.write { tx in localStorage.setIsMasterKeyBackedUp(true, tx) localStorage.setMasterKey(masterKey, tx) localStorage.setSVR2MrEnclaveStringValue(oldEnclave.stringValue, tx) } - mockTSAccountManager.isRegisteredAndReady = true + mockTSAccountManager.registrationStateMock = { .registered } mock2FAManager.pinCode = pin mockTSConstants.svr2Enclave = newEnclave @@ -185,13 +190,12 @@ class SecureValueRecovery2Tests: XCTestCase { let pin = "0000" // Set up the local data needed. - let localStorage = SVRLocalStorage(keyValueStoreFactory: keyValueStoreFactory) db.write { tx in localStorage.setIsMasterKeyBackedUp(true, tx) localStorage.setMasterKey(masterKey, tx) localStorage.setSVR2MrEnclaveStringValue(oldEnclave.stringValue, tx) } - mockTSAccountManager.isRegisteredAndReady = true + mockTSAccountManager.registrationStateMock = { .registered } mock2FAManager.pinCode = pin mockTSConstants.svr2Enclave = newEnclave diff --git a/SignalServiceKit/tests/Storage/Database/DatabaseRecoveryTest.swift b/SignalServiceKit/tests/Storage/Database/DatabaseRecoveryTest.swift index 4555d75e2f..02d5ec2e4a 100644 --- a/SignalServiceKit/tests/Storage/Database/DatabaseRecoveryTest.swift +++ b/SignalServiceKit/tests/Storage/Database/DatabaseRecoveryTest.swift @@ -14,7 +14,16 @@ final class DatabaseRecoveryTest: SSKBaseTestSwift { override func setUp() { super.setUp() - tsAccountManager.registerForTests(withLocalNumber: "+12225550101", uuid: UUID(), pni: UUID()) + Self.databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .init( + aci: .init(fromUUID: .init()), + pni: .init(fromUUID: .init()), + phoneNumber: "+12225550101" + ), + tx: tx.asV2Write + ) + } } // MARK: - Rebuild existing database @@ -116,7 +125,7 @@ final class DatabaseRecoveryTest: SSKBaseTestSwift { let contactAci = Aci.randomForTesting() - guard let localAci = tsAccountManager.localIdentifiers?.aci else { + guard let localAci = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aci else { XCTFail("No local address. Test is not set up correctly") return } diff --git a/SignalServiceKit/tests/Storage/ModelReadCacheTest.swift b/SignalServiceKit/tests/Storage/ModelReadCacheTest.swift index d4af61cf6a..24d9572981 100644 --- a/SignalServiceKit/tests/Storage/ModelReadCacheTest.swift +++ b/SignalServiceKit/tests/Storage/ModelReadCacheTest.swift @@ -36,7 +36,12 @@ class ModelReadCacheTest: SSKBaseTestSwift { override func setUp() { super.setUp() // Create local account. - tsAccountManager.registerForTests(localIdentifiers: .forUnitTests) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .forUnitTests, + tx: tx.asV2Write + ) + } } // MARK: - Test ModelReadCache.readValues(for:, transaction:) diff --git a/SignalServiceKit/tests/Storage/OWSIdentityManagerTests.swift b/SignalServiceKit/tests/Storage/OWSIdentityManagerTests.swift index 120da32a32..cc35debd87 100644 --- a/SignalServiceKit/tests/Storage/OWSIdentityManagerTests.swift +++ b/SignalServiceKit/tests/Storage/OWSIdentityManagerTests.swift @@ -13,7 +13,16 @@ class OWSIdentityManagerTests: SSKBaseTestSwift { override func setUp() { super.setUp() - tsAccountManager.registerForTests(withLocalNumber: "+13235551234", uuid: UUID()) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .init( + aci: .init(fromUUID: UUID()), + pni: nil, + e164: .init("+13235551234")! + ), + tx: tx.asV2Write + ) + } } func testNewEmptyKey() { diff --git a/SignalServiceKit/tests/Storage/SDSDatabaseStorageTest.swift b/SignalServiceKit/tests/Storage/SDSDatabaseStorageTest.swift index f659f0ff97..ec395da5d0 100644 --- a/SignalServiceKit/tests/Storage/SDSDatabaseStorageTest.swift +++ b/SignalServiceKit/tests/Storage/SDSDatabaseStorageTest.swift @@ -43,7 +43,16 @@ class SDSDatabaseStorageTest: SSKBaseTestSwift { // ensure local client has necessary "registered" state let localE164Identifier = "+13235551234" let localUUID = UUID() - tsAccountManager.registerForTests(withLocalNumber: localE164Identifier, uuid: localUUID) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .init( + aci: .init(fromUUID: localUUID), + pni: nil, + e164: .init(localE164Identifier)! + ), + tx: tx.asV2Write + ) + } } // MARK: - diff --git a/SignalServiceKit/tests/Stories/StoryManagerTest.swift b/SignalServiceKit/tests/Stories/StoryManagerTest.swift index 3523c39a8d..ed5a065080 100644 --- a/SignalServiceKit/tests/Stories/StoryManagerTest.swift +++ b/SignalServiceKit/tests/Stories/StoryManagerTest.swift @@ -14,7 +14,12 @@ class StoryManagerTest: SSKBaseTestSwift { override func setUp() { super.setUp() - tsAccountManager.registerForTests(localIdentifiers: .forUnitTests) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .forUnitTests, + tx: tx.asV2Write + ) + } } // MARK: - Message Creation diff --git a/SignalServiceKit/tests/Stories/SystemStoryManagerTest.swift b/SignalServiceKit/tests/Stories/SystemStoryManagerTest.swift index c6593aec5b..4fa690450d 100644 --- a/SignalServiceKit/tests/Stories/SystemStoryManagerTest.swift +++ b/SignalServiceKit/tests/Stories/SystemStoryManagerTest.swift @@ -21,7 +21,16 @@ class SystemStoryManagerTest: SSKBaseTestSwift { override func setUp() { super.setUp() scheduler = TestScheduler() - tsAccountManager.registerForTests(withLocalNumber: "+17875550101", uuid: UUID(), pni: UUID()) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .init( + aci: .init(fromUUID: UUID()), + pni: .init(fromUUID: UUID()), + e164: .init("+17875550101")! + ), + tx: tx.asV2Write + ) + } manager = SystemStoryManager( fileSystem: OnboardingStoryManagerFilesystemMock.self, schedulers: TestSchedulers(scheduler: scheduler) diff --git a/SignalServiceKit/tests/Util/TSMessageStorageTests.m b/SignalServiceKit/tests/Util/TSMessageStorageTests.m index b31122127a..f997047593 100644 --- a/SignalServiceKit/tests/Util/TSMessageStorageTests.m +++ b/SignalServiceKit/tests/Util/TSMessageStorageTests.m @@ -51,7 +51,7 @@ // ensure local client has necessary "registered" state NSString *localE164Identifier = @"+13235551234"; NSUUID *localUUID = NSUUID.UUID; - [self.tsAccountManager registerForTestsWithLocalNumber:localE164Identifier uuid:localUUID]; + [RegistrationStateChangeManagerObjcTestUtil registerForTestsWithLocalNumber:localE164Identifier aci:localUUID]; [self writeWithBlock:^(SDSAnyWriteTransaction *transaction) { self.thread = [TSContactThread getOrCreateThreadWithContactAddress:self.otherAddress transaction:transaction]; diff --git a/SignalServiceKit/tests/Util/ViewOnceMessagesTest.swift b/SignalServiceKit/tests/Util/ViewOnceMessagesTest.swift index 1c6dd4a287..d9f926a305 100644 --- a/SignalServiceKit/tests/Util/ViewOnceMessagesTest.swift +++ b/SignalServiceKit/tests/Util/ViewOnceMessagesTest.swift @@ -12,7 +12,16 @@ class ViewOnceMessagesTest: SSKBaseTestSwift { override func setUp() { super.setUp() - tsAccountManager.registerForTests(withLocalNumber: "+13334445555", uuid: UUID()) + databaseStorage.write { tx in + (DependenciesBridge.shared.registrationStateChangeManager as! RegistrationStateChangeManagerImpl).registerForTests( + localIdentifiers: .init( + aci: .init(fromUUID: .init()), + pni: nil, + e164: .init("+13334445555")! + ), + tx: tx.asV2Write + ) + } } // MARK: - diff --git a/SignalShareExtension/ShareViewController.swift b/SignalShareExtension/ShareViewController.swift index 217394204f..4245e0c5d9 100644 --- a/SignalShareExtension/ShareViewController.swift +++ b/SignalShareExtension/ShareViewController.swift @@ -143,15 +143,15 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed // Always check prekeys after app launches, and sometimes check on app activation. self.databaseStorage.read { tx in - if TSAccountManager.shared.isRegisteredAndReady(transaction: tx) { + if DependenciesBridge.shared.tsAccountManager.registrationState(tx: tx.asV2Read).isRegistered { DependenciesBridge.shared.preKeyManager.checkPreKeysIfNecessary(tx: tx.asV2Read) } } // We don't need to use RTCInitializeSSL() in the SAE. - if tsAccountManager.isRegistered { - Logger.info("running post launch block for registered user: \(String(describing: TSAccountManager.localAddress))") + if DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered { + Logger.info("running post launch block for registered user: \(String(describing: DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress))") } else { Logger.info("running post launch block for unregistered user.") @@ -160,10 +160,10 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed // We don't need to prod the SocketManager in the SAE. } - if tsAccountManager.isRegistered { + if DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered { DispatchQueue.main.async { [weak self] in guard self != nil else { return } - Logger.info("running post launch block for registered user: \(String(describing: TSAccountManager.localAddress))") + Logger.info("running post launch block for registered user: \(String(describing: DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress))") // We don't need to use the SocketManager in the SAE. @@ -187,8 +187,8 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed // Note that this does much more than set a flag; it will also run all deferred blocks. AppReadiness.setAppIsReady() - if tsAccountManager.isRegistered { - Logger.info("localAddress: \(String(describing: TSAccountManager.localAddress))") + if DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered { + Logger.info("localAddress: \(String(describing: DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress))") // We don't need to use messageFetcherJob in the SAE. @@ -210,8 +210,8 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed Logger.debug("") - if tsAccountManager.isRegistered { - Logger.info("localAddress: \(String(describing: TSAccountManager.localAddress))") + if DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered { + Logger.info("localAddress: \(String(describing: DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress))") // We don't need to use ExperienceUpgradeFinder in the SAE. @@ -248,7 +248,7 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed Logger.info("Presenting content view") - guard tsAccountManager.registrationState == .registered else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { showNotRegisteredView() return } @@ -263,11 +263,6 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed return } - guard tsAccountManager.isOnboarded else { - showNotReadyView() - return - } - buildAttachmentsAndPresentConversationPicker() // We don't use the AppUpdateNag in the SAE. } @@ -352,7 +347,7 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed // If a user unregisters in the main app, the SAE should shut down // immediately. - guard !tsAccountManager.isRegistered else { + guard !DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { // If user is registered, do nothing. return } diff --git a/SignalUI/Context Menus/DeleteSystemContactViewController.swift b/SignalUI/Context Menus/DeleteSystemContactViewController.swift index 3393fb9c42..b04ae3acff 100644 --- a/SignalUI/Context Menus/DeleteSystemContactViewController.swift +++ b/SignalUI/Context Menus/DeleteSystemContactViewController.swift @@ -22,7 +22,7 @@ class DeleteSystemContactViewController: OWSTableViewController2 { let contactsManager: ContactsManagerProtocol let databaseStorage: SDSDatabaseStorage let recipientHidingManager: RecipientHidingManager - let tsAccountManager: TSAccountManager + let tsAccountManager: TSAccountManagerProtocol } /// The e164 of the contact represented by this contact card. @@ -42,7 +42,7 @@ class DeleteSystemContactViewController: OWSTableViewController2 { contactsManager: ContactsManagerProtocol, databaseStorage: SDSDatabaseStorage, recipientHidingManager: RecipientHidingManager, - tsAccountManager: TSAccountManager + tsAccountManager: TSAccountManagerProtocol ) { self.e164 = e164 self.serviceId = serviceId @@ -74,7 +74,7 @@ class DeleteSystemContactViewController: OWSTableViewController2 { // This screen is for primary devices only. If a non primary // manages to get here bad things could happen. - owsAssert(tsAccountManager.isPrimaryDevice) + owsAssert(DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegisteredPrimaryDevice) self.navigationItem.leftBarButtonItem = UIBarButtonItem( barButtonSystemItem: .cancel, diff --git a/SignalUI/Context Menus/RecipientContextMenuHelper.swift b/SignalUI/Context Menus/RecipientContextMenuHelper.swift index e8ea136991..b3d36e3476 100644 --- a/SignalUI/Context Menus/RecipientContextMenuHelper.swift +++ b/SignalUI/Context Menus/RecipientContextMenuHelper.swift @@ -13,7 +13,7 @@ class RecipientContextMenuHelper { private let recipientHidingManager: RecipientHidingManager // TODO: When BlockingManager is protocolized, this should be the protocol type. private let blockingManager: BlockingManager - private let accountManager: TSAccountManager + private let accountManager: TSAccountManagerProtocol private let contactsManager: ContactsManagerProtocol /// The view controller from which to present action @@ -26,7 +26,7 @@ class RecipientContextMenuHelper { databaseStorage: SDSDatabaseStorage, blockingManager: BlockingManager, recipientHidingManager: RecipientHidingManager, - accountManager: TSAccountManager, + accountManager: TSAccountManagerProtocol, contactsManager: ContactsManagerProtocol, fromViewController: UIViewController ) { @@ -50,7 +50,7 @@ class RecipientContextMenuHelper { } let localAddress: SignalServiceAddress? = self.databaseStorage.read { [weak self] tx in guard let self else { return nil } - return self.accountManager.localAddress(with: tx) + return self.accountManager.localIdentifiers(tx: tx.asV2Read)?.aciAddress } guard let localAddress, @@ -154,7 +154,7 @@ class RecipientContextMenuHelper { return } let (localAddress, recipientDisplayName) = databaseStorage.read { tx in - let localAddress = accountManager.localAddress(with: tx) + let localAddress = accountManager.localIdentifiers(tx: tx.asV2Read)?.aciAddress let recipientDisplayName = contactsManager.displayName( for: address, transaction: tx @@ -246,13 +246,13 @@ class RecipientContextMenuHelper { localAddress, recipientDisplayName ) = databaseStorage.read { tx in - let localAddress = accountManager.localAddress(with: tx) + let localAddress = accountManager.localIdentifiers(tx: tx.asV2Read)?.aciAddress let recipientDisplayName = contactsManager.displayName( for: address, transaction: tx ).formattedForActionSheetTitle() return ( - accountManager.isPrimaryDevice(transaction: tx), + accountManager.registrationState(tx: tx.asV2Read).isPrimaryDevice ?? true, localAddress, recipientDisplayName ) diff --git a/SignalUI/Payments/PaymentsImpl.swift b/SignalUI/Payments/PaymentsImpl.swift index b269a01688..717d53fda1 100644 --- a/SignalUI/Payments/PaymentsImpl.swift +++ b/SignalUI/Payments/PaymentsImpl.swift @@ -46,7 +46,7 @@ public class PaymentsImpl: NSObject, PaymentsSwift { fileprivate var keyValueStore: SDSKeyValueStore { paymentsHelper.keyValueStore} private func updateLastKnownLocalPaymentAddressProtoDataIfNecessary() { - guard tsAccountManager.isRegisteredAndReady else { + guard DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return } guard AppReadiness.isAppReady else { @@ -259,9 +259,11 @@ public class PaymentsImpl: NSObject, PaymentsSwift { guard canUsePayments else { return } - guard AppReadiness.isAppReady, - CurrentAppContext().isMainAppAndActive, - Self.tsAccountManager.isRegisteredAndReady else { + guard + AppReadiness.isAppReady, + CurrentAppContext().isMainAppAndActive, + DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered + else { return } @@ -620,7 +622,7 @@ public extension PaymentsImpl { guard paymentAmount.currency == .mobileCoin else { return Promise(error: OWSAssertionError("Invalid currency.")) } - guard recipientAci != Self.tsAccountManager.localIdentifiers?.aci else { + guard recipientAci != DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aci else { return Promise(error: OWSAssertionError("Can't make payment to yourself.")) } diff --git a/SignalUI/Payments/PaymentsProcessor.swift b/SignalUI/Payments/PaymentsProcessor.swift index 56c6cc4277..3b526fa406 100644 --- a/SignalUI/Payments/PaymentsProcessor.swift +++ b/SignalUI/Payments/PaymentsProcessor.swift @@ -103,9 +103,11 @@ public class PaymentsProcessor: NSObject { guard Self.paymentsHelper.arePaymentsEnabled else { return } - guard AppReadiness.isAppReady, - CurrentAppContext().isMainAppAndActive, - Self.tsAccountManager.isRegisteredAndReady else { + guard + AppReadiness.isAppReady, + CurrentAppContext().isMainAppAndActive, + DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered + else { return } guard !DebugFlags.paymentsHaltProcessing.get() else { diff --git a/SignalUI/Payments/PaymentsReconciliation.swift b/SignalUI/Payments/PaymentsReconciliation.swift index 49a77363da..b47e1996a2 100644 --- a/SignalUI/Payments/PaymentsReconciliation.swift +++ b/SignalUI/Payments/PaymentsReconciliation.swift @@ -64,9 +64,11 @@ public class PaymentsReconciliation: Dependencies { guard Self.paymentsHelper.arePaymentsEnabled else { return false } - guard AppReadiness.isAppReady, - CurrentAppContext().isMainAppAndActive, - Self.tsAccountManager.isRegisteredAndReady else { + guard + AppReadiness.isAppReady, + CurrentAppContext().isMainAppAndActive, + DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered + else { return false } guard shouldReconcileByDateWithSneakyTransaction() else { diff --git a/SignalUI/Usernames/UsernameQuerier.swift b/SignalUI/Usernames/UsernameQuerier.swift index fdaba5b009..1cb142c851 100644 --- a/SignalUI/Usernames/UsernameQuerier.swift +++ b/SignalUI/Usernames/UsernameQuerier.swift @@ -16,7 +16,7 @@ public struct UsernameQuerier { private let recipientFetcher: RecipientFetcher private let schedulers: Schedulers private let storageServiceManager: StorageServiceManager - private let tsAccountManager: TSAccountManager + private let tsAccountManager: TSAccountManagerProtocol private let usernameApiClient: UsernameApiClient private let usernameLinkManager: UsernameLinkManager private let usernameLookupManager: UsernameLookupManager @@ -34,7 +34,7 @@ public struct UsernameQuerier { recipientFetcher: DependenciesBridge.shared.recipientFetcher, schedulers: DependenciesBridge.shared.schedulers, storageServiceManager: deps.storageServiceManager, - tsAccountManager: deps.tsAccountManager, + tsAccountManager: DependenciesBridge.shared.tsAccountManager, usernameApiClient: DependenciesBridge.shared.usernameApiClient, usernameLinkManager: DependenciesBridge.shared.usernameLinkManager, usernameLookupManager: DependenciesBridge.shared.usernameLookupManager @@ -50,7 +50,7 @@ public struct UsernameQuerier { recipientFetcher: RecipientFetcher, schedulers: Schedulers, storageServiceManager: StorageServiceManager, - tsAccountManager: TSAccountManager, + tsAccountManager: TSAccountManagerProtocol, usernameApiClient: UsernameApiClient, usernameLinkManager: UsernameLinkManager, usernameLookupManager: UsernameLookupManager @@ -76,7 +76,7 @@ public struct UsernameQuerier { onSuccess: @escaping (Aci) -> Void ) { if - let localAci = tsAccountManager.localIdentifiers(transaction: tx)?.aci, + let localAci = tsAccountManager.localIdentifiers(tx: tx.asV2Read)?.aci, let localLink = localUsernameManager.usernameState(tx: tx.asV2Read).usernameLink, localLink == link { @@ -132,7 +132,7 @@ public struct UsernameQuerier { onSuccess: @escaping (Aci) -> Void ) { if - let localAci = tsAccountManager.localIdentifiers(transaction: tx)?.aci, + let localAci = tsAccountManager.localIdentifiers(tx: tx.asV2Read)?.aci, let localUsername = localUsernameManager.usernameState(tx: tx.asV2Read).username, localUsername.caseInsensitiveCompare(username) == .orderedSame { diff --git a/SignalUI/Utils/FullTextSearcher.swift b/SignalUI/Utils/FullTextSearcher.swift index 0348f2da09..eb241d1fc5 100644 --- a/SignalUI/Utils/FullTextSearcher.swift +++ b/SignalUI/Utils/FullTextSearcher.swift @@ -457,7 +457,7 @@ public class FullTextSearcher: NSObject { } } - if let localAddress = TSAccountManager.localAddress { + if let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aciAddress { if matchesNoteToSelf(searchText: searchText, transaction: transaction) { if signalContactMap[localAddress] == nil { let localAccount = SignalAccount(address: localAddress) @@ -572,7 +572,7 @@ public class FullTextSearcher: NSObject { } } - if let localAddress = TSAccountManager.localAddress { + if let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aciAddress { if matchesNoteToSelf(searchText: searchText, transaction: transaction) { if signalContactMap[localAddress] == nil { let localAccount = SignalAccount(address: localAddress) @@ -623,7 +623,7 @@ public class FullTextSearcher: NSObject { } func matchesNoteToSelf(searchText: String, transaction: SDSAnyReadTransaction) -> Bool { - guard let localAddress = TSAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aciAddress else { return false } let noteToSelfText = self.conversationIndexingString(address: localAddress, transaction: transaction) @@ -902,7 +902,10 @@ public class FullTextSearcher: NSObject { } if matchesNoteToSelf(searchText: searchText, transaction: transaction) { - if let localAddress = TSAccountManager.localAddress, contactsMap[localAddress] == nil { + if + let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aciAddress, + contactsMap[localAddress] == nil + { let localAccount = SignalAccount(address: localAddress) let localResult = ContactSearchResult(signalAccount: localAccount, transaction: transaction) contactsMap[localAddress] = localResult diff --git a/SignalUI/ViewControllers/ConversationPicker/ConversationPicker.swift b/SignalUI/ViewControllers/ConversationPicker/ConversationPicker.swift index cff3061e51..6d6bc30004 100644 --- a/SignalUI/ViewControllers/ConversationPicker/ConversationPicker.swift +++ b/SignalUI/ViewControllers/ConversationPicker/ConversationPicker.swift @@ -685,7 +685,7 @@ open class ConversationPickerViewController: OWSTableViewController2 { databaseStorage: databaseStorage, blockingManager: blockingManager, recipientHidingManager: DependenciesBridge.shared.recipientHidingManager, - accountManager: tsAccountManager, + accountManager: DependenciesBridge.shared.tsAccountManager, contactsManager: contactsManager, fromViewController: self ) @@ -1330,7 +1330,7 @@ internal class ConversationPickerCell: ContactTableViewCell { configuration = ContactCellConfiguration(groupThread: groupThread, localUserDisplayMode: .noteToSelf) case .privateStory(_, let isMyStory): if isMyStory { - guard let localAddress = tsAccountManager.localAddress else { + guard let localAddress = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.aciAddress else { owsFailDebug("Unexpectedly missing local address") return } diff --git a/SignalUI/ViewControllers/FindByPhoneNumberViewController.swift b/SignalUI/ViewControllers/FindByPhoneNumberViewController.swift index 3358eada76..297361c214 100644 --- a/SignalUI/ViewControllers/FindByPhoneNumberViewController.swift +++ b/SignalUI/ViewControllers/FindByPhoneNumberViewController.swift @@ -173,7 +173,7 @@ public class FindByPhoneNumberViewController: OWSViewController, OWSNavigationCh } func validPhoneNumber() -> String? { - guard let localNumber = TSAccountManager.localNumber else { + guard let localNumber = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber else { owsFailDebug("local number unexpectedly nil") return nil } @@ -252,7 +252,7 @@ extension FindByPhoneNumberViewController: CountryCodeViewControllerDelegate { } func populateDefaultCountryCode() { - guard let localNumber = TSAccountManager.localNumber else { + guard let localNumber = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber else { return owsFailDebug("Local number unexpectedly nil") } diff --git a/SignalUI/ViewControllers/Recipient Picker/RecipientPickerViewController.swift b/SignalUI/ViewControllers/Recipient Picker/RecipientPickerViewController.swift index a24ebb2096..db01a24885 100644 --- a/SignalUI/ViewControllers/Recipient Picker/RecipientPickerViewController.swift +++ b/SignalUI/ViewControllers/Recipient Picker/RecipientPickerViewController.swift @@ -290,7 +290,7 @@ public class RecipientPickerViewController: OWSViewController, OWSNavigationChil databaseStorage: databaseStorage, blockingManager: blockingManager, recipientHidingManager: DependenciesBridge.shared.recipientHidingManager, - accountManager: tsAccountManager, + accountManager: DependenciesBridge.shared.tsAccountManager, contactsManager: contactsManager, fromViewController: self ) @@ -447,7 +447,7 @@ public class RecipientPickerViewController: OWSViewController, OWSNavigationChil Logger.info("Beginning refreshing") let refreshPromise: AnyPromise - if tsAccountManager.isRegisteredPrimaryDevice { + if DependenciesBridge.shared.tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegisteredPrimaryDevice { refreshPromise = contactsManagerImpl.userRequestedSystemContactsRefresh() } else { refreshPromise = syncManager.sendAllSyncRequestMessages(timeout: 20) @@ -1315,7 +1315,7 @@ extension RecipientPickerViewController { skipping alreadyMatchedPhoneNumbers: Set ) -> OWSTableSection? { let phoneNumberFinder = PhoneNumberFinder( - localNumber: TSAccountManager.localNumber, + localNumber: DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber, contactDiscoveryManager: contactDiscoveryManager ) var phoneNumberResults = phoneNumberFinder.parseResults(for: searchResults.searchText) diff --git a/SignalUI/ViewControllers/Safety Numbers/FingerprintViewController.swift b/SignalUI/ViewControllers/Safety Numbers/FingerprintViewController.swift index dd0247684a..63b147677f 100644 --- a/SignalUI/ViewControllers/Safety Numbers/FingerprintViewController.swift +++ b/SignalUI/ViewControllers/Safety Numbers/FingerprintViewController.swift @@ -41,7 +41,7 @@ public class FingerprintViewController: OWSViewController, OWSNavigationChildCon return OWSFingerprintBuilder( contactsManager: contactsManager, identityManager: identityManager, - tsAccountManager: tsAccountManager + tsAccountManager: DependenciesBridge.shared.tsAccountManager ).fingerprints( theirAddress: theirAddress, theirRecipientIdentity: theirRecipientIdentity, diff --git a/SignalUI/ViewModels/QuotedReplyModel.swift b/SignalUI/ViewModels/QuotedReplyModel.swift index b105f99409..1f1db254bc 100644 --- a/SignalUI/ViewModels/QuotedReplyModel.swift +++ b/SignalUI/ViewModels/QuotedReplyModel.swift @@ -191,7 +191,7 @@ public class QuotedReplyModel: NSObject { let authorAddress: SignalServiceAddress? = { if message is TSOutgoingMessage { - return TSAccountManager.localAddress(with: transaction) + return DependenciesBridge.shared.tsAccountManager.localIdentifiers(tx: transaction.asV2Read)?.aciAddress } if let incomingMessage = message as? TSIncomingMessage { return incomingMessage.authorAddress diff --git a/SignalUI/Views/ContactsViewHelper.m b/SignalUI/Views/ContactsViewHelper.m index 59990b6f87..924b80d85f 100644 --- a/SignalUI/Views/ContactsViewHelper.m +++ b/SignalUI/Views/ContactsViewHelper.m @@ -141,7 +141,7 @@ NS_ASSUME_NONNULL_BEGIN { OWSAssertDebug(!CurrentAppContext().isNSE); - return TSAccountManager.localAddress; + return [TSAccountManagerObjcBridge localAciAddressWithMaybeTransaction]; } - (BOOL)hasUpdatedContactsAtLeastOnce diff --git a/SignalUI/Views/ContactsViewHelper.swift b/SignalUI/Views/ContactsViewHelper.swift index 86a569715e..12406f8bc1 100644 --- a/SignalUI/Views/ContactsViewHelper.swift +++ b/SignalUI/Views/ContactsViewHelper.swift @@ -16,7 +16,7 @@ public extension ContactsViewHelper { return allSignalAccounts case false: - let localNumber = tsAccountManager.localNumber + let localNumber = DependenciesBridge.shared.tsAccountManager.localIdentifiersWithMaybeSneakyTransaction?.phoneNumber return allSignalAccounts .filter { !($0.recipientAddress.isLocalAddress || $0.contact?.hasPhoneNumber(localNumber) == true) } }