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
This commit is contained in:
Morgan Pretty 2022-06-02 16:32:05 +10:00
parent 07d1d8acee
commit cf1f1b0e1a
8 changed files with 68 additions and 10 deletions

View File

@ -197,7 +197,7 @@ public class NotificationPresenter: NSObject, NotificationsProtocol {
// Don't fire the notification if the current user isn't mentioned // Don't fire the notification if the current user isn't mentioned
// and isOnlyNotifyingForMentions is on. // 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 return
} }

View File

@ -140,7 +140,7 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) { YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
if ([object isKindOfClass:[TSIncomingMessage class]]) { if ([object isKindOfClass:[TSIncomingMessage class]]) {
TSIncomingMessage *message = (TSIncomingMessage *)object; TSIncomingMessage *message = (TSIncomingMessage *)object;
if (!message.wasRead && message.isUserMentioned) { if (!message.wasRead && [message isUserMentionedWithTransaction: transaction]) {
return message.uniqueThreadId; return message.uniqueThreadId;
} }
} }

View File

@ -31,13 +31,12 @@ public final class MessageReceiveJob : NSObject, Job, NSCoding { // NSObject/NSC
// MARK: Coding // MARK: Coding
public init?(coder: NSCoder) { public init?(coder: NSCoder) {
guard let data = coder.decodeObject(forKey: "data") as! Data?, guard let data = coder.decodeObject(forKey: "data") as! Data?,
let id = coder.decodeObject(forKey: "id") as! String?, let id = coder.decodeObject(forKey: "id") as! String? else { return nil }
let isBackgroundPoll = coder.decodeObject(forKey: "isBackgroundPoll") as! Bool? else { return nil }
self.data = data self.data = data
self.serverHash = coder.decodeObject(forKey: "serverHash") as! String? self.serverHash = coder.decodeObject(forKey: "serverHash") as! String?
self.openGroupMessageServerID = coder.decodeObject(forKey: "openGroupMessageServerID") as! UInt64? self.openGroupMessageServerID = coder.decodeObject(forKey: "openGroupMessageServerID") as! UInt64?
self.openGroupID = coder.decodeObject(forKey: "openGroupID") as! String? self.openGroupID = coder.decodeObject(forKey: "openGroupID") as! String?
self.isBackgroundPoll = isBackgroundPoll self.isBackgroundPoll = ((coder.decodeObject(forKey: "isBackgroundPoll") as? Bool) ?? false)
self.id = id self.id = id
self.failureCount = coder.decodeObject(forKey: "failureCount") as! UInt? ?? 0 self.failureCount = coder.decodeObject(forKey: "failureCount") as! UInt? ?? 0
} }

View File

@ -14,8 +14,6 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) BOOL wasReceivedByUD; @property (nonatomic, readonly) BOOL wasReceivedByUD;
@property (nonatomic, readonly) BOOL isUserMentioned;
@property (nonatomic, readonly, nullable) NSString *notificationIdentifier; @property (nonatomic, readonly, nullable) NSString *notificationIdentifier;
- (instancetype)initMessageWithTimestamp:(uint64_t)timestamp - (instancetype)initMessageWithTimestamp:(uint64_t)timestamp
@ -91,6 +89,8 @@ NS_ASSUME_NONNULL_BEGIN
- (void)setNotificationIdentifier:(NSString * _Nullable)notificationIdentifier - (void)setNotificationIdentifier:(NSString * _Nullable)notificationIdentifier
transaction:(YapDatabaseReadWriteTransaction *)transaction; transaction:(YapDatabaseReadWriteTransaction *)transaction;
- (BOOL)isUserMentionedWithTransaction:(YapDatabaseReadTransaction *)transaction;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@ -121,10 +121,42 @@ NS_ASSUME_NONNULL_BEGIN
return self.isExpiringMessage; return self.isExpiringMessage;
} }
- (BOOL)isUserMentioned - (BOOL)isUserMentionedWithTransaction:(YapDatabaseReadTransaction *)transaction
{ {
NSString *userPublicKey = [SNGeneralUtilities getUserPublicKey]; 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 - (void)setNotificationIdentifier:(NSString * _Nullable)notificationIdentifier transaction:(nonnull YapDatabaseReadWriteTransaction *)transaction

View File

@ -311,3 +311,20 @@ extension AeadXChaCha20Poly1305IetfType {
return authenticatedCipherText 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
}
}

View File

@ -215,4 +215,14 @@ class MockStorage: Mock<SessionMessagingKitStorageProtocol>, SessionMessagingKit
func persist(_ stream: TSAttachmentStream, associatedWith tsIncomingMessageID: String, using transaction: Any) { func persist(_ stream: TSAttachmentStream, associatedWith tsIncomingMessageID: String, using transaction: Any) {
accept(args: [stream, tsIncomingMessageID, transaction]) accept(args: [stream, tsIncomingMessageID, transaction])
} }
// MARK: - Calls
func getReceivedCalls(for publicKey: String, using transaction: Any) -> Set<String> {
return accept(args: [publicKey, transaction]) as! Set<String>
}
func setReceivedCalls(to receivedCalls: Set<String>, for publicKey: String, using transaction: Any) {
accept(args: [receivedCalls, publicKey, transaction])
}
} }

View File

@ -46,7 +46,7 @@ public class NSENotificationPresenter: NSObject, NotificationsProtocol {
var notificationTitle = senderName var notificationTitle = senderName
if let group = thread as? TSGroupThread { 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 // Ignore PNs if the group is set to only notify for mentions
return return
} }