From dff99cf0fc454ef3166b81b37ec0f457f20122f8 Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Fri, 30 Jul 2021 14:21:30 +1000 Subject: [PATCH] add unsend request proto --- Session.xcodeproj/project.pbxproj | 4 + .../Control Messages/UnsendRequest.swift | 69 +++++++++ .../Protos/Generated/SNProto.swift | 133 +++++++++++++++++- .../Protos/Generated/SessionProtos.pb.swift | 94 +++++++++++++ .../Protos/SessionProtos.proto | 8 ++ 5 files changed, 306 insertions(+), 2 deletions(-) create mode 100644 SessionMessagingKit/Messages/Control Messages/UnsendRequest.swift diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index 782dde5b6..a3ce7ad4a 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -136,6 +136,7 @@ 768A1A2B17FC9CD300E00ED8 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 768A1A2A17FC9CD300E00ED8 /* libz.dylib */; }; 76C87F19181EFCE600C4ACAB /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76C87F18181EFCE600C4ACAB /* MediaPlayer.framework */; }; 76EB054018170B33006006FC /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB03C318170B33006006FC /* AppDelegate.m */; }; + 7B4C75CB26B37E0F0000AC89 /* UnsendRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B4C75CA26B37E0F0000AC89 /* UnsendRequest.swift */; }; 7BC01A3E241F40AB00BC7C55 /* NotificationServiceExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BC01A3D241F40AB00BC7C55 /* NotificationServiceExtension.swift */; }; 7BC01A42241F40AB00BC7C55 /* SessionNotificationServiceExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 7BC01A3B241F40AB00BC7C55 /* SessionNotificationServiceExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 7BDCFC08242186E700641C39 /* NotificationServiceExtensionContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDCFC07242186E700641C39 /* NotificationServiceExtensionContext.swift */; }; @@ -1097,6 +1098,7 @@ 76C87F18181EFCE600C4ACAB /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; }; 76EB03C218170B33006006FC /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 76EB03C318170B33006006FC /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 7B4C75CA26B37E0F0000AC89 /* UnsendRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnsendRequest.swift; sourceTree = ""; }; 7BC01A3B241F40AB00BC7C55 /* SessionNotificationServiceExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = SessionNotificationServiceExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 7BC01A3D241F40AB00BC7C55 /* NotificationServiceExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationServiceExtension.swift; sourceTree = ""; }; 7BC01A3F241F40AB00BC7C55 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -2375,6 +2377,7 @@ B8F5F60225EDE16F003BF8D4 /* DataExtractionNotification.swift */, C300A5E62554B07300555489 /* ExpirationTimerUpdate.swift */, C3DA9C0625AE7396008F7C7E /* ConfigurationMessage.swift */, + 7B4C75CA26B37E0F0000AC89 /* UnsendRequest.swift */, ); path = "Control Messages"; sourceTree = ""; @@ -4619,6 +4622,7 @@ C3A3A156256E1B91004D228D /* ProtoUtils.m in Sources */, C3471ECB2555356A00297E91 /* MessageSender+Encryption.swift in Sources */, C352A32F2557549C00338F3E /* NotifyPNServerJob.swift in Sources */, + 7B4C75CB26B37E0F0000AC89 /* UnsendRequest.swift in Sources */, C300A5F22554B09800555489 /* MessageSender.swift in Sources */, C3C2A74D2553A39700C340D1 /* VisibleMessage.swift in Sources */, C32C5AAD256DBE8F003C73A2 /* TSInfoMessage.m in Sources */, diff --git a/SessionMessagingKit/Messages/Control Messages/UnsendRequest.swift b/SessionMessagingKit/Messages/Control Messages/UnsendRequest.swift new file mode 100644 index 000000000..d09dbf74b --- /dev/null +++ b/SessionMessagingKit/Messages/Control Messages/UnsendRequest.swift @@ -0,0 +1,69 @@ +import SessionUtilitiesKit + +@objc(SNUnsendRequest) +public final class UnsendRequest: ControlMessage { + public var timestamp: UInt64? + public var author: String? + + // MARK: Validation + public override var isValid: Bool { + guard super.isValid else { return false } + return timestamp != nil && author != nil + } + + // MARK: Initialization + public override init() { super.init() } + + internal init(timestamp: UInt64, author: String) { + super.init() + self.timestamp = timestamp + self.author = author + } + + // MARK: Coding + public required init?(coder: NSCoder) { + super.init(coder: coder) + if let timestamp = coder.decodeObject(forKey: "timestamp") as! UInt64? { self.timestamp = timestamp } + if let author = coder.decodeObject(forKey: "author") as! String? { self.author = author } + } + + public override func encode(with coder: NSCoder) { + super.encode(with: coder) + coder.encode(timestamp, forKey: "timestamp") + coder.encode(author, forKey: "author") + } + + // MARK: Proto Conversion + public override class func fromProto(_ proto: SNProtoContent) -> UnsendRequest? { + guard let unsendRequestProto = proto.unsendRequest else { return nil } + let timestamp = unsendRequestProto.timestamp + let author = unsendRequestProto.author + return UnsendRequest(timestamp: timestamp, author: author) + } + + public override func toProto(using transaction: YapDatabaseReadWriteTransaction) -> SNProtoContent? { + guard let timestamp = timestamp, let author = author else { + SNLog("Couldn't construct unsend request proto from: \(self).") + return nil + } + let unsendRequestProto = SNProtoUnsendRequest.builder(timestamp: timestamp, author: author) + let contentProto = SNProtoContent.builder() + do { + contentProto.setUnsendRequest(try unsendRequestProto.build()) + return try contentProto.build() + } catch { + SNLog("Couldn't construct unsend request proto from: \(self).") + return nil + } + } + + // MARK: Description + public override var description: String { + """ + UnsendRequest( + timestamp: \(timestamp?.description ?? "null") + author: \(author?.description ?? "null") + ) + """ + } +} diff --git a/SessionMessagingKit/Protos/Generated/SNProto.swift b/SessionMessagingKit/Protos/Generated/SNProto.swift index 997eab59c..8d4f98a4e 100644 --- a/SessionMessagingKit/Protos/Generated/SNProto.swift +++ b/SessionMessagingKit/Protos/Generated/SNProto.swift @@ -338,6 +338,118 @@ extension SNProtoTypingMessage.SNProtoTypingMessageBuilder { #endif +// MARK: - SNProtoUnsendRequest + +@objc public class SNProtoUnsendRequest: NSObject { + + // MARK: - SNProtoUnsendRequestBuilder + + @objc public class func builder(timestamp: UInt64, author: String) -> SNProtoUnsendRequestBuilder { + return SNProtoUnsendRequestBuilder(timestamp: timestamp, author: author) + } + + // asBuilder() constructs a builder that reflects the proto's contents. + @objc public func asBuilder() -> SNProtoUnsendRequestBuilder { + let builder = SNProtoUnsendRequestBuilder(timestamp: timestamp, author: author) + return builder + } + + @objc public class SNProtoUnsendRequestBuilder: NSObject { + + private var proto = SessionProtos_UnsendRequest() + + @objc fileprivate override init() {} + + @objc fileprivate init(timestamp: UInt64, author: String) { + super.init() + + setTimestamp(timestamp) + setAuthor(author) + } + + @objc public func setTimestamp(_ valueParam: UInt64) { + proto.timestamp = valueParam + } + + @objc public func setAuthor(_ valueParam: String) { + proto.author = valueParam + } + + @objc public func build() throws -> SNProtoUnsendRequest { + return try SNProtoUnsendRequest.parseProto(proto) + } + + @objc public func buildSerializedData() throws -> Data { + return try SNProtoUnsendRequest.parseProto(proto).serializedData() + } + } + + fileprivate let proto: SessionProtos_UnsendRequest + + @objc public let timestamp: UInt64 + + @objc public let author: String + + private init(proto: SessionProtos_UnsendRequest, + timestamp: UInt64, + author: String) { + self.proto = proto + self.timestamp = timestamp + self.author = author + } + + @objc + public func serializedData() throws -> Data { + return try self.proto.serializedData() + } + + @objc public class func parseData(_ serializedData: Data) throws -> SNProtoUnsendRequest { + let proto = try SessionProtos_UnsendRequest(serializedData: serializedData) + return try parseProto(proto) + } + + fileprivate class func parseProto(_ proto: SessionProtos_UnsendRequest) throws -> SNProtoUnsendRequest { + guard proto.hasTimestamp else { + throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: timestamp") + } + let timestamp = proto.timestamp + + guard proto.hasAuthor else { + throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: author") + } + let author = proto.author + + // MARK: - Begin Validation Logic for SNProtoUnsendRequest - + + // MARK: - End Validation Logic for SNProtoUnsendRequest - + + let result = SNProtoUnsendRequest(proto: proto, + timestamp: timestamp, + author: author) + return result + } + + @objc public override var debugDescription: String { + return "\(proto)" + } +} + +#if DEBUG + +extension SNProtoUnsendRequest { + @objc public func serializedDataIgnoringErrors() -> Data? { + return try! self.serializedData() + } +} + +extension SNProtoUnsendRequest.SNProtoUnsendRequestBuilder { + @objc public func buildIgnoringErrors() -> SNProtoUnsendRequest? { + return try! self.build() + } +} + +#endif + // MARK: - SNProtoContent @objc public class SNProtoContent: NSObject { @@ -366,6 +478,9 @@ extension SNProtoTypingMessage.SNProtoTypingMessageBuilder { if let _value = dataExtractionNotification { builder.setDataExtractionNotification(_value) } + if let _value = unsendRequest { + builder.setUnsendRequest(_value) + } return builder } @@ -395,6 +510,10 @@ extension SNProtoTypingMessage.SNProtoTypingMessageBuilder { proto.dataExtractionNotification = valueParam.proto } + @objc public func setUnsendRequest(_ valueParam: SNProtoUnsendRequest) { + proto.unsendRequest = valueParam.proto + } + @objc public func build() throws -> SNProtoContent { return try SNProtoContent.parseProto(proto) } @@ -416,18 +535,22 @@ extension SNProtoTypingMessage.SNProtoTypingMessageBuilder { @objc public let dataExtractionNotification: SNProtoDataExtractionNotification? + @objc public let unsendRequest: SNProtoUnsendRequest? + private init(proto: SessionProtos_Content, dataMessage: SNProtoDataMessage?, receiptMessage: SNProtoReceiptMessage?, typingMessage: SNProtoTypingMessage?, configurationMessage: SNProtoConfigurationMessage?, - dataExtractionNotification: SNProtoDataExtractionNotification?) { + dataExtractionNotification: SNProtoDataExtractionNotification?, + unsendRequest: SNProtoUnsendRequest?) { self.proto = proto self.dataMessage = dataMessage self.receiptMessage = receiptMessage self.typingMessage = typingMessage self.configurationMessage = configurationMessage self.dataExtractionNotification = dataExtractionNotification + self.unsendRequest = unsendRequest } @objc @@ -466,6 +589,11 @@ extension SNProtoTypingMessage.SNProtoTypingMessageBuilder { dataExtractionNotification = try SNProtoDataExtractionNotification.parseProto(proto.dataExtractionNotification) } + var unsendRequest: SNProtoUnsendRequest? = nil + if proto.hasUnsendRequest { + unsendRequest = try SNProtoUnsendRequest.parseProto(proto.unsendRequest) + } + // MARK: - Begin Validation Logic for SNProtoContent - // MARK: - End Validation Logic for SNProtoContent - @@ -475,7 +603,8 @@ extension SNProtoTypingMessage.SNProtoTypingMessageBuilder { receiptMessage: receiptMessage, typingMessage: typingMessage, configurationMessage: configurationMessage, - dataExtractionNotification: dataExtractionNotification) + dataExtractionNotification: dataExtractionNotification, + unsendRequest: unsendRequest) return result } diff --git a/SessionMessagingKit/Protos/Generated/SessionProtos.pb.swift b/SessionMessagingKit/Protos/Generated/SessionProtos.pb.swift index 37c95f8f0..ea16218a6 100644 --- a/SessionMessagingKit/Protos/Generated/SessionProtos.pb.swift +++ b/SessionMessagingKit/Protos/Generated/SessionProtos.pb.swift @@ -196,6 +196,39 @@ extension SessionProtos_TypingMessage.Action: CaseIterable { #endif // swift(>=4.2) +struct SessionProtos_UnsendRequest { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// @required + var timestamp: UInt64 { + get {return _timestamp ?? 0} + set {_timestamp = newValue} + } + /// Returns true if `timestamp` has been explicitly set. + var hasTimestamp: Bool {return self._timestamp != nil} + /// Clears the value of `timestamp`. Subsequent reads from it will return its default value. + mutating func clearTimestamp() {self._timestamp = nil} + + /// @required + var author: String { + get {return _author ?? String()} + set {_author = newValue} + } + /// Returns true if `author` has been explicitly set. + var hasAuthor: Bool {return self._author != nil} + /// Clears the value of `author`. Subsequent reads from it will return its default value. + mutating func clearAuthor() {self._author = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _timestamp: UInt64? = nil + fileprivate var _author: String? = nil +} + struct SessionProtos_Content { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for @@ -246,6 +279,15 @@ struct SessionProtos_Content { /// Clears the value of `dataExtractionNotification`. Subsequent reads from it will return its default value. mutating func clearDataExtractionNotification() {self._dataExtractionNotification = nil} + var unsendRequest: SessionProtos_UnsendRequest { + get {return _unsendRequest ?? SessionProtos_UnsendRequest()} + set {_unsendRequest = newValue} + } + /// Returns true if `unsendRequest` has been explicitly set. + var hasUnsendRequest: Bool {return self._unsendRequest != nil} + /// Clears the value of `unsendRequest`. Subsequent reads from it will return its default value. + mutating func clearUnsendRequest() {self._unsendRequest = nil} + var unknownFields = SwiftProtobuf.UnknownStorage() init() {} @@ -255,6 +297,7 @@ struct SessionProtos_Content { fileprivate var _typingMessage: SessionProtos_TypingMessage? = nil fileprivate var _configurationMessage: SessionProtos_ConfigurationMessage? = nil fileprivate var _dataExtractionNotification: SessionProtos_DataExtractionNotification? = nil + fileprivate var _unsendRequest: SessionProtos_UnsendRequest? = nil } struct SessionProtos_KeyPair { @@ -1504,6 +1547,50 @@ extension SessionProtos_TypingMessage.Action: SwiftProtobuf._ProtoNameProviding ] } +extension SessionProtos_UnsendRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".UnsendRequest" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "timestamp"), + 2: .same(proto: "author"), + ] + + public var isInitialized: Bool { + if self._timestamp == nil {return false} + if self._author == nil {return false} + return true + } + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularUInt64Field(value: &self._timestamp) }() + case 2: try { try decoder.decodeSingularStringField(value: &self._author) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if let v = self._timestamp { + try visitor.visitSingularUInt64Field(value: v, fieldNumber: 1) + } + if let v = self._author { + try visitor.visitSingularStringField(value: v, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: SessionProtos_UnsendRequest, rhs: SessionProtos_UnsendRequest) -> Bool { + if lhs._timestamp != rhs._timestamp {return false} + if lhs._author != rhs._author {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + extension SessionProtos_Content: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".Content" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ @@ -1512,6 +1599,7 @@ extension SessionProtos_Content: SwiftProtobuf.Message, SwiftProtobuf._MessageIm 6: .same(proto: "typingMessage"), 7: .same(proto: "configurationMessage"), 8: .same(proto: "dataExtractionNotification"), + 9: .same(proto: "unsendRequest"), ] public var isInitialized: Bool { @@ -1520,6 +1608,7 @@ extension SessionProtos_Content: SwiftProtobuf.Message, SwiftProtobuf._MessageIm if let v = self._typingMessage, !v.isInitialized {return false} if let v = self._configurationMessage, !v.isInitialized {return false} if let v = self._dataExtractionNotification, !v.isInitialized {return false} + if let v = self._unsendRequest, !v.isInitialized {return false} return true } @@ -1534,6 +1623,7 @@ extension SessionProtos_Content: SwiftProtobuf.Message, SwiftProtobuf._MessageIm case 6: try { try decoder.decodeSingularMessageField(value: &self._typingMessage) }() case 7: try { try decoder.decodeSingularMessageField(value: &self._configurationMessage) }() case 8: try { try decoder.decodeSingularMessageField(value: &self._dataExtractionNotification) }() + case 9: try { try decoder.decodeSingularMessageField(value: &self._unsendRequest) }() default: break } } @@ -1555,6 +1645,9 @@ extension SessionProtos_Content: SwiftProtobuf.Message, SwiftProtobuf._MessageIm if let v = self._dataExtractionNotification { try visitor.visitSingularMessageField(value: v, fieldNumber: 8) } + if let v = self._unsendRequest { + try visitor.visitSingularMessageField(value: v, fieldNumber: 9) + } try unknownFields.traverse(visitor: &visitor) } @@ -1564,6 +1657,7 @@ extension SessionProtos_Content: SwiftProtobuf.Message, SwiftProtobuf._MessageIm if lhs._typingMessage != rhs._typingMessage {return false} if lhs._configurationMessage != rhs._configurationMessage {return false} if lhs._dataExtractionNotification != rhs._dataExtractionNotification {return false} + if lhs._unsendRequest != rhs._unsendRequest {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } diff --git a/SessionMessagingKit/Protos/SessionProtos.proto b/SessionMessagingKit/Protos/SessionProtos.proto index 7d9d5f56e..5b1999255 100644 --- a/SessionMessagingKit/Protos/SessionProtos.proto +++ b/SessionMessagingKit/Protos/SessionProtos.proto @@ -34,12 +34,20 @@ message TypingMessage { required Action action = 2; } +message UnsendRequest { + // @required + required uint64 timestamp = 1; + // @required + required string author = 2; +} + message Content { optional DataMessage dataMessage = 1; optional ReceiptMessage receiptMessage = 5; optional TypingMessage typingMessage = 6; optional ConfigurationMessage configurationMessage = 7; optional DataExtractionNotification dataExtractionNotification = 8; + optional UnsendRequest unsendRequest = 9; } message KeyPair {