From 4dcf26b7e7fdfb8109d704035f045bdf80f18b28 Mon Sep 17 00:00:00 2001 From: Mikunj Date: Wed, 29 Apr 2020 10:45:54 +1000 Subject: [PATCH] Added migration. --- .../View Controllers/DeviceLinkingModal.swift | 9 ++++--- .../environment/VersionMigrations.m | 24 +++++++++++++++++-- SignalServiceKit/src/Contacts/TSThread.h | 7 +++--- .../FriendRequestProtocol.swift | 5 ++-- .../Multi Device/MultiDeviceProtocol.swift | 9 ++++--- .../src/Loki/Protocol/SessionProtocol.swift | 9 ++++++- .../Sync Messages/SyncMessagesProtocol.swift | 4 ++-- .../src/Loki/Shelved/LokiP2PAPI.swift | 14 +++++++---- 8 files changed, 60 insertions(+), 21 deletions(-) diff --git a/Signal/src/Loki/View Controllers/DeviceLinkingModal.swift b/Signal/src/Loki/View Controllers/DeviceLinkingModal.swift index 5a712f15c..85d87d8ba 100644 --- a/Signal/src/Loki/View Controllers/DeviceLinkingModal.swift +++ b/Signal/src/Loki/View Controllers/DeviceLinkingModal.swift @@ -184,13 +184,16 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate { let signedDeviceLink = DeviceLink(between: master, and: deviceLink.slave) LokiFileServerAPI.addDeviceLink(signedDeviceLink).done(on: DispatchQueue.main) { [weak self] in SSKEnvironment.shared.messageSender.send(linkingAuthorizationMessage, success: { - let thread = TSContactThread.getOrCreateThread(contactId: deviceLink.slave.hexEncodedPublicKey) + let hexEncodedPublicKey = deviceLink.slave.hexEncodedPublicKey + let thread = TSContactThread.getOrCreateThread(contactId: hexEncodedPublicKey) thread.save() let _ = SSKEnvironment.shared.syncManager.syncAllContacts() let _ = SSKEnvironment.shared.syncManager.syncAllGroups() let _ = SSKEnvironment.shared.syncManager.syncAllOpenGroups() - thread.friendRequestStatus = .friends - thread.save() + let storage = OWSPrimaryStorage.shared() + storage.dbReadWriteConnection.readWrite { transaction in + storage.setFriendRequestStatus(.friends, forContact: hexEncodedPublicKey, transaction: transaction) + } DispatchQueue.main.async { self?.dismiss(animated: true, completion: nil) self?.delegate?.handleDeviceLinkAuthorized(signedDeviceLink) diff --git a/SignalMessaging/environment/VersionMigrations.m b/SignalMessaging/environment/VersionMigrations.m index 80bc99d34..2199b9931 100644 --- a/SignalMessaging/environment/VersionMigrations.m +++ b/SignalMessaging/environment/VersionMigrations.m @@ -10,10 +10,12 @@ #import #import #import -#import +#import #import #import #import +#import +#import #import NS_ASSUME_NONNULL_BEGIN @@ -100,7 +102,7 @@ NS_ASSUME_NONNULL_BEGIN } if ([self isVersion:previousVersion lessThan:@"1.1.2"] && [self.tsAccountManager isRegistered]) { - // TODO: Migrate Friend Request Status + [self moveFriendRequestStatusFromThread]; } dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ @@ -208,6 +210,24 @@ NS_ASSUME_NONNULL_BEGIN }]; } +# pragma mark Loki - Upgrading Friend Request Status + + +// Versions less than or equal to 1.1.1 stored friend request status on the thread ++ (void)moveFriendRequestStatusFromThread +{ + OWSPrimaryStorage *storage = OWSPrimaryStorage.sharedManager; + [OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction * _Nonnull transaction) { + NSArray *threads = [TSThread allObjectsInCollection]; + for (TSThread *thread in threads) { + if (!thread.isGroupThread) { + NSString *hexEncodedPublicKey = thread.contactIdentifier; + [storage setFriendRequestStatus:thread.friendRequestStatus forContact:hexEncodedPublicKey transaction:transaction]; + } + } + }]; +} + @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Contacts/TSThread.h b/SignalServiceKit/src/Contacts/TSThread.h index e3ef225df..b05f1cc99 100644 --- a/SignalServiceKit/src/Contacts/TSThread.h +++ b/SignalServiceKit/src/Contacts/TSThread.h @@ -29,6 +29,7 @@ extern ConversationColorName const ConversationColorNameSteel; extern ConversationColorName const kConversationColorName_Default; +// TODO: Remove this once we don't use it typedef NS_ENUM(NSInteger, LKThreadFriendRequestStatus) { /// New conversation; no messages sent or received. LKThreadFriendRequestStatusNone, @@ -42,7 +43,7 @@ typedef NS_ENUM(NSInteger, LKThreadFriendRequestStatus) { LKThreadFriendRequestStatusFriends, /// A friend request was sent, but it timed out (i.e. the other user didn't accept within the allocated time). LKThreadFriendRequestStatusRequestExpired -}; +} __deprecated_enum_msg("Use LKFriendRequestStatus instead"); /** * TSThread is the superclass of TSContactThread and TSGroupThread @@ -55,7 +56,7 @@ typedef NS_ENUM(NSInteger, LKThreadFriendRequestStatus) { @property (nonatomic, readonly) TSInteraction *lastInteraction; // Loki friend request handling // ======== -@property (nonatomic) LKThreadFriendRequestStatus friendRequestStatus; +@property (nonatomic) NSInteger friendRequestStatus __deprecated_msg("use OWSPrimaryStorage.getFriendReeuqstStatusForContact instead"); @property (nonatomic, readonly) NSString *friendRequestStatusDescription; /// Shorthand for checking that `friendRequestStatus` is `LKThreadFriendRequestStatusRequestSending`, `LKThreadFriendRequestStatusRequestSent` /// or `LKThreadFriendRequestStatusRequestReceived`. @@ -204,7 +205,7 @@ typedef NS_ENUM(NSInteger, LKThreadFriendRequestStatus) { #pragma mark - Loki Friend Request Handling -- (void)saveFriendRequestStatus:(LKThreadFriendRequestStatus)friendRequestStatus withTransaction:(YapDatabaseReadWriteTransaction *_Nullable)transaction; +- (void)saveFriendRequestStatus:(LKThreadFriendRequestStatus)friendRequestStatus withTransaction:(YapDatabaseReadWriteTransaction *_Nullable)transaction __deprecated_msg("use OWSPrimaryStorate.setFriendRequestStatus instead"); /** Remove any outgoing friend request message which failed to send diff --git a/SignalServiceKit/src/Loki/Protocol/Friend Requests/FriendRequestProtocol.swift b/SignalServiceKit/src/Loki/Protocol/Friend Requests/FriendRequestProtocol.swift index f0509de66..59eabc5a5 100644 --- a/SignalServiceKit/src/Loki/Protocol/Friend Requests/FriendRequestProtocol.swift +++ b/SignalServiceKit/src/Loki/Protocol/Friend Requests/FriendRequestProtocol.swift @@ -132,10 +132,11 @@ public final class FriendRequestProtocol : NSObject { // If we get an envelope that isn't a friend request, then we can infer that we had to use // Signal cipher decryption and thus that we have a session with the other person. let thread = TSContactThread.getOrCreateThread(withContactId: hexEncodedPublicKey, transaction: transaction) + let friendRequestStatus = storage.getFriendRequestStatus(forContact: hexEncodedPublicKey, transaction: transaction); // We shouldn't be able to skip from none to friends - guard thread.friendRequestStatus != .none else { return } + guard friendRequestStatus != .none else { return } // Become friends - thread.saveFriendRequestStatus(.friends, with: transaction) + storage.setFriendRequestStatus(.friends, forContact: hexEncodedPublicKey, transaction: transaction) if let existingFriendRequestMessage = thread.getLastInteraction(with: transaction) as? TSOutgoingMessage, existingFriendRequestMessage.isFriendRequest { existingFriendRequestMessage.saveFriendRequestStatus(.accepted, with: transaction) diff --git a/SignalServiceKit/src/Loki/Protocol/Multi Device/MultiDeviceProtocol.swift b/SignalServiceKit/src/Loki/Protocol/Multi Device/MultiDeviceProtocol.swift index 6f9c8d939..c8b13fa72 100644 --- a/SignalServiceKit/src/Loki/Protocol/Multi Device/MultiDeviceProtocol.swift +++ b/SignalServiceKit/src/Loki/Protocol/Multi Device/MultiDeviceProtocol.swift @@ -109,10 +109,13 @@ public final class MultiDeviceProtocol : NSObject { let masterHexEncodedPublicKey = storage.getMasterHexEncodedPublicKey(for: hexEncodedPublicKey, in: transaction) let isSlaveDeviceThread = masterHexEncodedPublicKey != hexEncodedPublicKey thread.isForceHidden = isSlaveDeviceThread // TODO: Could we make this computed? - if thread.friendRequestStatus == .none || thread.friendRequestStatus == .requestExpired { - thread.saveFriendRequestStatus(.requestSent, with: transaction) // TODO: Should we always immediately mark the slave device as a friend? - } thread.save(with: transaction) + + // FIXME: I don't think this should be here, the function itself should just return a message + let friendRequestStatus = storage.getFriendRequestStatus(forContact: hexEncodedPublicKey, transaction: transaction) + if friendRequestStatus == .none || friendRequestStatus == .requestExpired { + storage.setFriendRequestStatus(.requestSent, forContact: hexEncodedPublicKey, transaction: transaction) + } let result = FriendRequestMessage(outgoingMessageWithTimestamp: NSDate.ows_millisecondTimeStamp(), in: thread, messageBody: "Please accept to enable messages to be synced across devices", attachmentIds: [], expiresInSeconds: 0, expireStartedAt: 0, isVoiceMessage: false, diff --git a/SignalServiceKit/src/Loki/Protocol/SessionProtocol.swift b/SignalServiceKit/src/Loki/Protocol/SessionProtocol.swift index 8b391e99c..d0d71430d 100644 --- a/SignalServiceKit/src/Loki/Protocol/SessionProtocol.swift +++ b/SignalServiceKit/src/Loki/Protocol/SessionProtocol.swift @@ -118,7 +118,14 @@ public final class SessionProtocol : NSObject { // Used from OWSOutgoingReceiptManager @objc(shouldSendReceiptForThread:) public static func shouldSendReceipt(for thread: TSThread) -> Bool { - return thread.friendRequestStatus == .friends && !thread.isGroupThread() + guard !thread.isGroupThread(), let contact = thread.contactIdentifier() else { return false } + + var shouldSendReceipt = false; + storage.dbReadConnection.read { transaction in + shouldSendReceipt = storage.getFriendRequestStatus(forContact: contact, transaction: transaction) == .friends + } + + return shouldSendReceipt } // MARK: - Receiving diff --git a/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift b/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift index 87e34a3fa..fd559ac35 100644 --- a/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift +++ b/SignalServiceKit/src/Loki/Protocol/Sync Messages/SyncMessagesProtocol.swift @@ -168,7 +168,7 @@ public final class SyncMessagesProtocol : NSObject { // Try to establish sessions for hexEncodedPublicKey in hexEncodedPublicKeys { let thread = TSContactThread.getOrCreateThread(withContactId: hexEncodedPublicKey, transaction: transaction) - let friendRequestStatus = thread.friendRequestStatus + let friendRequestStatus = storage.getFriendRequestStatus(forContact: hexEncodedPublicKey, transaction: transaction) switch friendRequestStatus { case .none: let messageSender = SSKEnvironment.shared.messageSender @@ -194,7 +194,7 @@ public final class SyncMessagesProtocol : NSObject { } }) case .requestReceived: - thread.saveFriendRequestStatus(.friends, with: transaction) + storage.setFriendRequestStatus(.friends, forContact: hexEncodedPublicKey, transaction: transaction) // Not sendFriendRequestAcceptanceMessage(to:in:using:) to take into account multi device FriendRequestProtocol.acceptFriendRequest(from: hexEncodedPublicKey, in: thread, using: transaction) default: break diff --git a/SignalServiceKit/src/Loki/Shelved/LokiP2PAPI.swift b/SignalServiceKit/src/Loki/Shelved/LokiP2PAPI.swift index b0b4edbea..ed002439e 100644 --- a/SignalServiceKit/src/Loki/Shelved/LokiP2PAPI.swift +++ b/SignalServiceKit/src/Loki/Shelved/LokiP2PAPI.swift @@ -211,11 +211,15 @@ public class LokiP2PAPI : NSObject { private static func getAllFriendThreads() -> [TSContactThread] { var friendThreadIds = [String]() - TSContactThread.enumerateCollectionObjects { (object, _) in - guard let thread = object as? TSContactThread, let uniqueId = thread.uniqueId else { return } - - if thread.friendRequestStatus == .friends && thread.contactIdentifier() != ourHexEncodedPubKey { - friendThreadIds.append(thread.uniqueId!) + + storage.dbReadConnection.read { transaction in + TSContactThread.enumerateCollectionObjects(with: transaction) { (object, _) in + guard let thread = object as? TSContactThread, let uniqueId = thread.uniqueId, thread.contactIdentifier() == ourHexEncodedPubKey else { return } + + let status = storage.getFriendRequestStatus(forContact: thread.contactIdentifier(), transaction: transaction) + if (status == .friends) { + friendThreadIds.append(uniqueId) + } } }