diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index 148832f84..c9bbee887 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -519,7 +519,7 @@ C3471ED42555386B00297E91 /* AESGCM.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C2A5D72553860B00C340D1 /* AESGCM.swift */; }; C3471F4C25553AB000297E91 /* MessageReceiver+Decryption.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3471F4B25553AB000297E91 /* MessageReceiver+Decryption.swift */; }; C3471FA42555439E00297E91 /* Notification+MessageSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3471FA32555439E00297E91 /* Notification+MessageSender.swift */; }; - C34A977425A3E34A00852C71 /* ClosedGroupUpdateV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = C34A977325A3E34A00852C71 /* ClosedGroupUpdateV2.swift */; }; + C34A977425A3E34A00852C71 /* ClosedGroupUpdate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C34A977325A3E34A00852C71 /* ClosedGroupUpdate.swift */; }; C34C8F7423A7830B00D82669 /* SpaceMono-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = C34C8F7323A7830A00D82669 /* SpaceMono-Bold.ttf */; }; C352A2F525574B4700338F3E /* Job.swift in Sources */ = {isa = PBXBuildFile; fileRef = C352A2F425574B4700338F3E /* Job.swift */; }; C352A2FF25574B6300338F3E /* MessageSendJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = C352A2FE25574B6300338F3E /* MessageSendJob.swift */; }; @@ -1523,7 +1523,7 @@ C3471ECA2555356A00297E91 /* MessageSender+Encryption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MessageSender+Encryption.swift"; sourceTree = ""; }; C3471F4B25553AB000297E91 /* MessageReceiver+Decryption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MessageReceiver+Decryption.swift"; sourceTree = ""; }; C3471FA32555439E00297E91 /* Notification+MessageSender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Notification+MessageSender.swift"; sourceTree = ""; }; - C34A977325A3E34A00852C71 /* ClosedGroupUpdateV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClosedGroupUpdateV2.swift; sourceTree = ""; }; + C34A977325A3E34A00852C71 /* ClosedGroupUpdate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClosedGroupUpdate.swift; sourceTree = ""; }; C34C8F7323A7830A00D82669 /* SpaceMono-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SpaceMono-Bold.ttf"; sourceTree = ""; }; C352A2F425574B4700338F3E /* Job.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Job.swift; sourceTree = ""; }; C352A2FE25574B6300338F3E /* MessageSendJob.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageSendJob.swift; sourceTree = ""; }; @@ -2368,7 +2368,7 @@ C3C2A7702553A41E00C340D1 /* ControlMessage.swift */, C300A5BC2554B00D00555489 /* ReadReceipt.swift */, C300A5D22554B05A00555489 /* TypingIndicator.swift */, - C34A977325A3E34A00852C71 /* ClosedGroupUpdateV2.swift */, + C34A977325A3E34A00852C71 /* ClosedGroupUpdate.swift */, C300A5E62554B07300555489 /* ExpirationTimerUpdate.swift */, C3DA9C0625AE7396008F7C7E /* ConfigurationMessage.swift */, ); @@ -4933,7 +4933,7 @@ C3471FA42555439E00297E91 /* Notification+MessageSender.swift in Sources */, C32C5BEF256DC8EE003C73A2 /* OWSDisappearingMessagesJob.m in Sources */, C3A7222A2558C1E40043A11F /* DotNetAPI.swift in Sources */, - C34A977425A3E34A00852C71 /* ClosedGroupUpdateV2.swift in Sources */, + C34A977425A3E34A00852C71 /* ClosedGroupUpdate.swift in Sources */, C32C5E97256DE0CB003C73A2 /* OWSPrimaryStorage.m in Sources */, C32C5EB9256DE130003C73A2 /* OWSQuotedReplyModel+Conversion.swift in Sources */, C3A71D1F25589AC30043A11F /* WebSocketResources.pb.swift in Sources */, diff --git a/SessionMessagingKit/Messages/Control Messages/ClosedGroupUpdateV2.swift b/SessionMessagingKit/Messages/Control Messages/ClosedGroupUpdate.swift similarity index 97% rename from SessionMessagingKit/Messages/Control Messages/ClosedGroupUpdateV2.swift rename to SessionMessagingKit/Messages/Control Messages/ClosedGroupUpdate.swift index f5ca20f7a..464f03b50 100644 --- a/SessionMessagingKit/Messages/Control Messages/ClosedGroupUpdateV2.swift +++ b/SessionMessagingKit/Messages/Control Messages/ClosedGroupUpdate.swift @@ -1,7 +1,7 @@ import SessionProtocolKit import SessionUtilitiesKit -public final class ClosedGroupUpdateV2 : ControlMessage { +public final class ClosedGroupUpdate : ControlMessage { public var kind: Kind? public override var ttl: UInt64 { @@ -11,6 +11,13 @@ public final class ClosedGroupUpdateV2 : ControlMessage { } } + public override var isSelfSendValid: Bool { + switch kind { + case .update, .encryptionKeyPair: return true + default: return false + } + } + // MARK: Kind public enum Kind : CustomStringConvertible { case new(publicKey: Data, name: String, encryptionKeyPair: ECKeyPair, members: [Data], admins: [Data]) @@ -131,7 +138,7 @@ public final class ClosedGroupUpdateV2 : ControlMessage { } // MARK: Proto Conversion - public override class func fromProto(_ proto: SNProtoContent) -> ClosedGroupUpdateV2? { + public override class func fromProto(_ proto: SNProtoContent) -> ClosedGroupUpdate? { guard let closedGroupUpdateProto = proto.dataMessage?.closedGroupUpdateV2 else { return nil } let kind: Kind switch closedGroupUpdateProto.type { @@ -153,7 +160,7 @@ public final class ClosedGroupUpdateV2 : ControlMessage { let wrappers = closedGroupUpdateProto.wrappers.compactMap { KeyPairWrapper.fromProto($0) } kind = .encryptionKeyPair(wrappers) } - return ClosedGroupUpdateV2(kind: kind) + return ClosedGroupUpdate(kind: kind) } public override func toProto(using transaction: YapDatabaseReadWriteTransaction) -> SNProtoContent? { diff --git a/SessionMessagingKit/Messages/Control Messages/ConfigurationMessage.swift b/SessionMessagingKit/Messages/Control Messages/ConfigurationMessage.swift index 1f505cec8..18b234cb8 100644 --- a/SessionMessagingKit/Messages/Control Messages/ConfigurationMessage.swift +++ b/SessionMessagingKit/Messages/Control Messages/ConfigurationMessage.swift @@ -5,6 +5,8 @@ public final class ConfigurationMessage : ControlMessage { public var closedGroups: Set = [] public var openGroups: Set = [] + public override var isSelfSendValid: Bool { true } + // MARK: Initialization public override init() { super.init() } diff --git a/SessionMessagingKit/Messages/Message.swift b/SessionMessagingKit/Messages/Message.swift index f457c7fa9..f39136b4a 100644 --- a/SessionMessagingKit/Messages/Message.swift +++ b/SessionMessagingKit/Messages/Message.swift @@ -12,6 +12,7 @@ public class Message : NSObject, NSCoding { // NSObject/NSCoding conformance is public var openGroupServerMessageID: UInt64? public var ttl: UInt64 { 2 * 24 * 60 * 60 * 1000 } + public var isSelfSendValid: Bool { false } public override init() { } diff --git a/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift b/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift index d137c5afe..7b99ff194 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift @@ -11,7 +11,7 @@ extension MessageReceiver { switch message { case let message as ReadReceipt: handleReadReceipt(message, using: transaction) case let message as TypingIndicator: handleTypingIndicator(message, using: transaction) - case let message as ClosedGroupUpdateV2: handleClosedGroupUpdateV2(message, using: transaction) + case let message as ClosedGroupUpdate: handleClosedGroupUpdateV2(message, using: transaction) case let message as ExpirationTimerUpdate: handleExpirationTimerUpdate(message, using: transaction) case let message as ConfigurationMessage: handleConfigurationMessage(message, using: transaction) case let message as VisibleMessage: try handleVisibleMessage(message, associatedWithProto: proto, openGroupID: openGroupID, isBackgroundPoll: isBackgroundPoll, using: transaction) @@ -233,7 +233,7 @@ extension MessageReceiver { return tsIncomingMessageID } - private static func handleClosedGroupUpdateV2(_ message: ClosedGroupUpdateV2, using transaction: Any) { + private static func handleClosedGroupUpdateV2(_ message: ClosedGroupUpdate, using transaction: Any) { switch message.kind! { case .new: handleNewClosedGroup(message, using: transaction) case .update: handleClosedGroupUpdate(message, using: transaction) @@ -241,7 +241,7 @@ extension MessageReceiver { } } - private static func handleNewClosedGroup(_ message: ClosedGroupUpdateV2, using transaction: Any) { + private static func handleNewClosedGroup(_ message: ClosedGroupUpdate, using transaction: Any) { guard case let .new(publicKeyAsData, name, encryptionKeyPair, membersAsData, adminsAsData) = message.kind else { return } let groupPublicKey = publicKeyAsData.toHexString() let members = membersAsData.map { $0.toHexString() } @@ -273,7 +273,7 @@ extension MessageReceiver { infoMessage.save(with: transaction) } - private static func handleClosedGroupUpdate(_ message: ClosedGroupUpdateV2, using transaction: Any) { + private static func handleClosedGroupUpdate(_ message: ClosedGroupUpdate, using transaction: Any) { // Prepare guard case let .update(name, membersAsData) = message.kind else { return } let transaction = transaction as! YapDatabaseReadWriteTransaction @@ -332,7 +332,7 @@ extension MessageReceiver { } } - private static func handleClosedGroupEncryptionKeyPair(_ message: ClosedGroupUpdateV2, using transaction: Any) { + private static func handleClosedGroupEncryptionKeyPair(_ message: ClosedGroupUpdate, using transaction: Any) { // Prepare guard case let .encryptionKeyPair(wrappers) = message.kind, let groupPublicKey = message.groupPublicKey else { return } let transaction = transaction as! YapDatabaseReadWriteTransaction diff --git a/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift b/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift index 3cf72f01a..e57cf38fc 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageReceiver.swift @@ -107,7 +107,7 @@ public enum MessageReceiver { let message: Message? = { if let readReceipt = ReadReceipt.fromProto(proto) { return readReceipt } if let typingIndicator = TypingIndicator.fromProto(proto) { return typingIndicator } - if let closedGroupUpdate = ClosedGroupUpdateV2.fromProto(proto) { return closedGroupUpdate } + if let closedGroupUpdate = ClosedGroupUpdate.fromProto(proto) { return closedGroupUpdate } if let expirationTimerUpdate = ExpirationTimerUpdate.fromProto(proto) { return expirationTimerUpdate } if let configurationMessage = ConfigurationMessage.fromProto(proto) { return configurationMessage } if let visibleMessage = VisibleMessage.fromProto(proto) { return visibleMessage } @@ -115,7 +115,7 @@ public enum MessageReceiver { }() if let message = message { // Ignore self sends if needed - if !(message is ConfigurationMessage) { + if !message.isSelfSendValid { guard sender != userPublicKey else { throw Error.selfSend } } // Guard against control messages in open groups diff --git a/SessionMessagingKit/Sending & Receiving/MessageSender+ClosedGroups.swift b/SessionMessagingKit/Sending & Receiving/MessageSender+ClosedGroups.swift index 6facbebec..3a7775a8e 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageSender+ClosedGroups.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageSender+ClosedGroups.swift @@ -27,9 +27,9 @@ extension MessageSender { guard member != userPublicKey else { continue } let thread = TSContactThread.getOrCreateThread(withContactId: member, transaction: transaction) thread.save(with: transaction) - let closedGroupUpdateKind = ClosedGroupUpdateV2.Kind.new(publicKey: Data(hex: groupPublicKey), name: name, + let closedGroupUpdateKind = ClosedGroupUpdate.Kind.new(publicKey: Data(hex: groupPublicKey), name: name, encryptionKeyPair: encryptionKeyPair, members: membersAsData, admins: adminsAsData) - let closedGroupUpdate = ClosedGroupUpdateV2(kind: closedGroupUpdateKind) + let closedGroupUpdate = ClosedGroupUpdate(kind: closedGroupUpdateKind) let promise = MessageSender.sendNonDurably(closedGroupUpdate, in: thread, using: transaction) promises.append(promise) } @@ -81,7 +81,7 @@ extension MessageSender { } } // Send the update to the group - let mainClosedGroupUpdate = ClosedGroupUpdateV2(kind: .update(name: name, members: membersAsData)) + let mainClosedGroupUpdate = ClosedGroupUpdate(kind: .update(name: name, members: membersAsData)) if isUserLeaving { let _ = MessageSender.sendNonDurably(mainClosedGroupUpdate, in: thread, using: transaction).done { SNMessagingKitConfiguration.shared.storage.write { transaction in @@ -101,9 +101,9 @@ extension MessageSender { for member in newMembers { let thread = TSContactThread.getOrCreateThread(withContactId: member, transaction: transaction) thread.save(with: transaction) - let closedGroupUpdateKind = ClosedGroupUpdateV2.Kind.new(publicKey: Data(hex: groupPublicKey), name: name, + let closedGroupUpdateKind = ClosedGroupUpdate.Kind.new(publicKey: Data(hex: groupPublicKey), name: name, encryptionKeyPair: encryptionKeyPair, members: membersAsData, admins: adminsAsData) - let closedGroupUpdate = ClosedGroupUpdateV2(kind: closedGroupUpdateKind) + let closedGroupUpdate = ClosedGroupUpdate(kind: closedGroupUpdateKind) MessageSender.send(closedGroupUpdate, in: thread, using: transaction) } } @@ -155,11 +155,11 @@ extension MessageSender { let proto = try SNProtoKeyPair.builder(publicKey: newKeyPair.publicKey, privateKey: newKeyPair.privateKey).build() let plaintext = try proto.serializedData() - let wrappers = try targetMembers.compactMap { publicKey -> ClosedGroupUpdateV2.KeyPairWrapper in + let wrappers = try targetMembers.compactMap { publicKey -> ClosedGroupUpdate.KeyPairWrapper in let ciphertext = try MessageSender.encryptWithSessionProtocol(plaintext, for: publicKey) - return ClosedGroupUpdateV2.KeyPairWrapper(publicKey: publicKey, encryptedKeyPair: ciphertext) + return ClosedGroupUpdate.KeyPairWrapper(publicKey: publicKey, encryptedKeyPair: ciphertext) } - let closedGroupUpdate = ClosedGroupUpdateV2(kind: .encryptionKeyPair(wrappers)) + let closedGroupUpdate = ClosedGroupUpdate(kind: .encryptionKeyPair(wrappers)) let _ = MessageSender.sendNonDurably(closedGroupUpdate, in: thread, using: transaction).done { // FIXME: It'd be great if we could make this a durable operation // Store it * after * having sent out the message to the group SNMessagingKitConfiguration.shared.storage.write { transaction in diff --git a/SessionMessagingKit/Sending & Receiving/MessageSender.swift b/SessionMessagingKit/Sending & Receiving/MessageSender.swift index e269ef29b..81be60be7 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageSender.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageSender.swift @@ -242,7 +242,7 @@ public final class MessageSender : NSObject { storage.write(with: { transaction in MessageSender.handleSuccessfulMessageSend(message, to: destination, using: transaction) var shouldNotify = (message is VisibleMessage) - if let closedGroupUpdate = message as? ClosedGroupUpdateV2, case .new = closedGroupUpdate.kind { + if let closedGroupUpdate = message as? ClosedGroupUpdate, case .new = closedGroupUpdate.kind { shouldNotify = true } if shouldNotify { @@ -340,6 +340,7 @@ public final class MessageSender : NSObject { // MARK: Success & Failure Handling public static func handleSuccessfulMessageSend(_ message: Message, to destination: Message.Destination, using transaction: Any) { + Storage.shared.addReceivedMessageTimestamp(message.sentTimestamp!, using: transaction) // To later ignore self-sends in a multi device context guard let tsMessage = TSOutgoingMessage.find(withTimestamp: message.sentTimestamp!) else { return } tsMessage.openGroupServerMessageID = message.openGroupServerMessageID ?? 0 var recipients = [ message.recipient! ] diff --git a/SessionNotificationServiceExtension/NotificationServiceExtension.swift b/SessionNotificationServiceExtension/NotificationServiceExtension.swift index 065e6d9e0..60de986f7 100644 --- a/SessionNotificationServiceExtension/NotificationServiceExtension.swift +++ b/SessionNotificationServiceExtension/NotificationServiceExtension.swift @@ -55,7 +55,7 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension group.groupModel.groupType == .closedGroup { // Should always be true because we don't get PNs for open groups senderDisplayName = String(format: NotificationStrings.incomingGroupMessageTitleFormat, senderDisplayName, group.groupModel.groupName ?? MessageStrings.newGroupDefaultTitle) } - case let closedGroupUpdate as ClosedGroupUpdateV2: + case let closedGroupUpdate as ClosedGroupUpdate: // TODO: We could consider actually handling the update here. Not sure if there's enough time though, seeing as though // in some cases we need to send messages (e.g. our sender key) to a number of other users. switch closedGroupUpdate.kind {