From cf1f1b0e1a63e497b1808e94f5998ca9009327db Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Thu, 2 Jun 2022 16:32:05 +1000 Subject: [PATCH] Added code so the 'isUserMentioned' flag should support mentions within open groups Added the new storage methods to MockStorage Fixed an odd bug where the 'isBackgroundPoll' flag could have been coded incorrectly preventing the MessageReceiveJob from getting processed --- Session/Notifications/AppNotifications.swift | 2 +- SessionMessagingKit/Database/TSDatabaseView.m | 2 +- .../Jobs/MessageReceiveJob.swift | 5 ++- .../Messages/Signal/TSIncomingMessage.h | 4 +-- .../Messages/Signal/TSIncomingMessage.m | 36 +++++++++++++++++-- .../Utilities/Sodium+Utilities.swift | 17 +++++++++ .../_TestUtilities/MockStorage.swift | 10 ++++++ .../NSENotificationPresenter.swift | 2 +- 8 files changed, 68 insertions(+), 10 deletions(-) diff --git a/Session/Notifications/AppNotifications.swift b/Session/Notifications/AppNotifications.swift index a39574cce..0698b0118 100644 --- a/Session/Notifications/AppNotifications.swift +++ b/Session/Notifications/AppNotifications.swift @@ -197,7 +197,7 @@ public class NotificationPresenter: NSObject, NotificationsProtocol { // Don't fire the notification if the current user isn't mentioned // and isOnlyNotifyingForMentions is on. - if let groupThread = thread as? TSGroupThread, groupThread.isOnlyNotifyingForMentions && !incomingMessage.isUserMentioned { + if let groupThread = thread as? TSGroupThread, groupThread.isOnlyNotifyingForMentions && !incomingMessage.isUserMentioned(with: transaction) { return } diff --git a/SessionMessagingKit/Database/TSDatabaseView.m b/SessionMessagingKit/Database/TSDatabaseView.m index ec47b53b7..7f78ac4e0 100644 --- a/SessionMessagingKit/Database/TSDatabaseView.m +++ b/SessionMessagingKit/Database/TSDatabaseView.m @@ -140,7 +140,7 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup" YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) { if ([object isKindOfClass:[TSIncomingMessage class]]) { TSIncomingMessage *message = (TSIncomingMessage *)object; - if (!message.wasRead && message.isUserMentioned) { + if (!message.wasRead && [message isUserMentionedWithTransaction: transaction]) { return message.uniqueThreadId; } } diff --git a/SessionMessagingKit/Jobs/MessageReceiveJob.swift b/SessionMessagingKit/Jobs/MessageReceiveJob.swift index 16827b0de..6b3944b98 100644 --- a/SessionMessagingKit/Jobs/MessageReceiveJob.swift +++ b/SessionMessagingKit/Jobs/MessageReceiveJob.swift @@ -31,13 +31,12 @@ public final class MessageReceiveJob : NSObject, Job, NSCoding { // NSObject/NSC // MARK: Coding public init?(coder: NSCoder) { guard let data = coder.decodeObject(forKey: "data") as! Data?, - let id = coder.decodeObject(forKey: "id") as! String?, - let isBackgroundPoll = coder.decodeObject(forKey: "isBackgroundPoll") as! Bool? else { return nil } + let id = coder.decodeObject(forKey: "id") as! String? else { return nil } self.data = data self.serverHash = coder.decodeObject(forKey: "serverHash") as! String? self.openGroupMessageServerID = coder.decodeObject(forKey: "openGroupMessageServerID") as! UInt64? self.openGroupID = coder.decodeObject(forKey: "openGroupID") as! String? - self.isBackgroundPoll = isBackgroundPoll + self.isBackgroundPoll = ((coder.decodeObject(forKey: "isBackgroundPoll") as? Bool) ?? false) self.id = id self.failureCount = coder.decodeObject(forKey: "failureCount") as! UInt? ?? 0 } diff --git a/SessionMessagingKit/Messages/Signal/TSIncomingMessage.h b/SessionMessagingKit/Messages/Signal/TSIncomingMessage.h index c965ff51b..a1aef0933 100644 --- a/SessionMessagingKit/Messages/Signal/TSIncomingMessage.h +++ b/SessionMessagingKit/Messages/Signal/TSIncomingMessage.h @@ -14,8 +14,6 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, readonly) BOOL wasReceivedByUD; -@property (nonatomic, readonly) BOOL isUserMentioned; - @property (nonatomic, readonly, nullable) NSString *notificationIdentifier; - (instancetype)initMessageWithTimestamp:(uint64_t)timestamp @@ -91,6 +89,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)setNotificationIdentifier:(NSString * _Nullable)notificationIdentifier transaction:(YapDatabaseReadWriteTransaction *)transaction; +- (BOOL)isUserMentionedWithTransaction:(YapDatabaseReadTransaction *)transaction; + @end NS_ASSUME_NONNULL_END diff --git a/SessionMessagingKit/Messages/Signal/TSIncomingMessage.m b/SessionMessagingKit/Messages/Signal/TSIncomingMessage.m index a6578df0c..25ece9ca0 100644 --- a/SessionMessagingKit/Messages/Signal/TSIncomingMessage.m +++ b/SessionMessagingKit/Messages/Signal/TSIncomingMessage.m @@ -121,10 +121,42 @@ NS_ASSUME_NONNULL_BEGIN return self.isExpiringMessage; } -- (BOOL)isUserMentioned +- (BOOL)isUserMentionedWithTransaction:(YapDatabaseReadTransaction *)transaction { NSString *userPublicKey = [SNGeneralUtilities getUserPublicKey]; - return (self.body != nil && [self.body containsString:[NSString stringWithFormat:@"@%@", userPublicKey]]) || (self.quotedMessage != nil && [self.quotedMessage.authorId isEqualToString:userPublicKey]); + NSArray *publicKeysToCheck = @[userPublicKey]; + TSThread *thread = [self threadWithTransaction:transaction]; + + if (thread != nil) { + BOOL isOpenGroupThread = (thread.isGroupThread && ((TSGroupThread *)thread).isOpenGroup); + + if (isOpenGroupThread) { + SNOpenGroupV2 *openGroup = [[LKStorage shared] getOpenGroupForThreadID:self.uniqueThreadId]; + + if (openGroup != nil) { + NSString *openGroupPublicKey = [SNBlindingUtils userBlindedIdFor:openGroup.publicKey]; + + if (openGroupPublicKey != nil) { + publicKeysToCheck = [publicKeysToCheck arrayByAddingObject:openGroupPublicKey]; + } + } + } + } + + BOOL userMentioned = false; + + for (NSString *publicKey in publicKeysToCheck) { + userMentioned = ( + (self.body != nil && [self.body containsString:[NSString stringWithFormat:@"@%@", publicKey]]) || + (self.quotedMessage != nil && [self.quotedMessage.authorId isEqualToString:publicKey]) + ); + + if (userMentioned == true) { + break; + } + } + + return userMentioned; } - (void)setNotificationIdentifier:(NSString * _Nullable)notificationIdentifier transaction:(nonnull YapDatabaseReadWriteTransaction *)transaction diff --git a/SessionMessagingKit/Utilities/Sodium+Utilities.swift b/SessionMessagingKit/Utilities/Sodium+Utilities.swift index feddd0df4..de0ea0ac0 100644 --- a/SessionMessagingKit/Utilities/Sodium+Utilities.swift +++ b/SessionMessagingKit/Utilities/Sodium+Utilities.swift @@ -311,3 +311,20 @@ extension AeadXChaCha20Poly1305IetfType { return authenticatedCipherText } } + +// MARK: - Objective-C Support + +@objc public class SNBlindingUtils: NSObject { + @objc public static func userBlindedId(for openGroupPublicKey: String) -> String? { + let sodium: Sodium = Sodium() + + guard let userEd25519KeyPair = Storage.shared.getUserED25519KeyPair() else { + return nil + } + guard let blindedKeyPair = sodium.blindedKeyPair(serverPublicKey: openGroupPublicKey, edKeyPair: userEd25519KeyPair, genericHash: sodium.genericHash) else { + return nil + } + + return SessionId(.blinded, publicKey: blindedKeyPair.publicKey).hexString + } +} diff --git a/SessionMessagingKitTests/_TestUtilities/MockStorage.swift b/SessionMessagingKitTests/_TestUtilities/MockStorage.swift index de0bdcb19..4f6b46c0f 100644 --- a/SessionMessagingKitTests/_TestUtilities/MockStorage.swift +++ b/SessionMessagingKitTests/_TestUtilities/MockStorage.swift @@ -215,4 +215,14 @@ class MockStorage: Mock, SessionMessagingKit func persist(_ stream: TSAttachmentStream, associatedWith tsIncomingMessageID: String, using transaction: Any) { accept(args: [stream, tsIncomingMessageID, transaction]) } + + // MARK: - Calls + + func getReceivedCalls(for publicKey: String, using transaction: Any) -> Set { + return accept(args: [publicKey, transaction]) as! Set + } + + func setReceivedCalls(to receivedCalls: Set, for publicKey: String, using transaction: Any) { + accept(args: [receivedCalls, publicKey, transaction]) + } } diff --git a/SessionNotificationServiceExtension/NSENotificationPresenter.swift b/SessionNotificationServiceExtension/NSENotificationPresenter.swift index c19184a5d..081204ed5 100644 --- a/SessionNotificationServiceExtension/NSENotificationPresenter.swift +++ b/SessionNotificationServiceExtension/NSENotificationPresenter.swift @@ -46,7 +46,7 @@ public class NSENotificationPresenter: NSObject, NotificationsProtocol { var notificationTitle = senderName if let group = thread as? TSGroupThread { - if group.isOnlyNotifyingForMentions && !incomingMessage.isUserMentioned { + if group.isOnlyNotifyingForMentions && !incomingMessage.isUserMentioned(with: transaction) { // Ignore PNs if the group is set to only notify for mentions return }