mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Include the sender public key in sender key messages
This commit is contained in:
parent
b12937ef00
commit
00abf4e5fe
7 changed files with 85 additions and 44 deletions
|
@ -250,9 +250,11 @@ message DataMessage {
|
|||
|
||||
message SenderKey {
|
||||
// @required
|
||||
optional bytes chainKey = 1;
|
||||
optional bytes chainKey = 1;
|
||||
// @required
|
||||
optional uint32 keyIndex = 2;
|
||||
optional uint32 keyIndex = 2;
|
||||
// @required
|
||||
optional string senderPublicKey = 3;
|
||||
}
|
||||
|
||||
optional string name = 1;
|
||||
|
|
|
@ -2,43 +2,48 @@
|
|||
internal final class ClosedGroupSenderKey : NSObject, NSCoding {
|
||||
internal let chainKey: Data
|
||||
internal let keyIndex: UInt
|
||||
internal let senderPublicKey: String
|
||||
|
||||
// MARK: Initialization
|
||||
init(chainKey: Data, keyIndex: UInt) {
|
||||
init(chainKey: Data, keyIndex: UInt, senderPublicKey: String) {
|
||||
self.chainKey = chainKey
|
||||
self.keyIndex = keyIndex
|
||||
self.senderPublicKey = senderPublicKey
|
||||
}
|
||||
|
||||
// MARK: Coding
|
||||
public init?(coder: NSCoder) {
|
||||
guard let chainKey = coder.decodeObject(forKey: "chainKey") as? Data,
|
||||
let keyIndex = coder.decodeObject(forKey: "keyIndex") as? UInt else { return nil }
|
||||
let keyIndex = coder.decodeObject(forKey: "keyIndex") as? UInt,
|
||||
let senderPublicKey = coder.decodeObject(forKey: "senderPublicKey") as? String else { return nil }
|
||||
self.chainKey = chainKey
|
||||
self.keyIndex = UInt(keyIndex)
|
||||
self.senderPublicKey = senderPublicKey
|
||||
super.init()
|
||||
}
|
||||
|
||||
public func encode(with coder: NSCoder) {
|
||||
coder.encode(chainKey, forKey: "chainKey")
|
||||
coder.encode(keyIndex, forKey: "keyIndex")
|
||||
coder.encode(senderPublicKey, forKey: "senderPublicKey")
|
||||
}
|
||||
|
||||
// MARK: Proto Conversion
|
||||
internal func toProto() throws -> SSKProtoDataMessageClosedGroupUpdateSenderKey {
|
||||
return try SSKProtoDataMessageClosedGroupUpdateSenderKey.builder(chainKey: chainKey, keyIndex: UInt32(keyIndex)).build()
|
||||
return try SSKProtoDataMessageClosedGroupUpdateSenderKey.builder(chainKey: chainKey, keyIndex: UInt32(keyIndex), senderPublicKey: senderPublicKey).build()
|
||||
}
|
||||
|
||||
// MARK: Equality
|
||||
override public func isEqual(_ other: Any?) -> Bool {
|
||||
guard let other = other as? ClosedGroupSenderKey else { return false }
|
||||
return chainKey == other.chainKey && keyIndex == other.keyIndex
|
||||
return chainKey == other.chainKey && keyIndex == other.keyIndex && senderPublicKey == other.senderPublicKey
|
||||
}
|
||||
|
||||
// MARK: Hashing
|
||||
override public var hash: Int { // Override NSObject.hash and not Hashable.hashValue or Hashable.hash(into:)
|
||||
return chainKey.hashValue ^ keyIndex.hashValue
|
||||
return chainKey.hashValue ^ keyIndex.hashValue ^ senderPublicKey.hashValue
|
||||
}
|
||||
|
||||
// MARK: Description
|
||||
override public var description: String { return "[ chainKey : \(chainKey), keyIndex : \(keyIndex) ]" }
|
||||
override public var description: String { return "[ chainKey : \(chainKey), keyIndex : \(keyIndex), senderPublicKey: \(senderPublicKey) ]" }
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ internal final class ClosedGroupUpdateMessage : TSOutgoingMessage {
|
|||
closedGroupUpdate.setMembers(members)
|
||||
closedGroupUpdate.setAdmins(admins)
|
||||
case .senderKey(let groupPublicKey, let senderKey):
|
||||
closedGroupUpdate = SSKProtoDataMessageClosedGroupUpdate.builder(groupPublicKey: groupPublicKey, type: .chainKey)
|
||||
closedGroupUpdate = SSKProtoDataMessageClosedGroupUpdate.builder(groupPublicKey: groupPublicKey, type: .senderKey)
|
||||
closedGroupUpdate.setSenderKeys([ try senderKey.toProto() ])
|
||||
}
|
||||
builder.setClosedGroupUpdate(try closedGroupUpdate.build())
|
||||
|
|
|
@ -50,7 +50,9 @@ public final class ClosedGroupsProtocol : NSObject {
|
|||
// Establish sessions if needed
|
||||
establishSessionsIfNeeded(with: members, using: transaction) // Not `membersAndLinkedDevices` as this internally takes care of multi device already
|
||||
// Send a closed group update message to all members (and their linked devices) using established channels
|
||||
let senderKeys = ratchets.map { ClosedGroupSenderKey(chainKey: Data(hex: $0.chainKey), keyIndex: $0.keyIndex) }
|
||||
let senderKeys = zip(ratchets, membersAndLinkedDevices).map { ratchet, publicKey in
|
||||
ClosedGroupSenderKey(chainKey: Data(hex: ratchet.chainKey), keyIndex: ratchet.keyIndex, senderPublicKey: publicKey)
|
||||
}
|
||||
for member in members { // Not `membersAndLinkedDevices` as this internally takes care of multi device already
|
||||
let thread = TSContactThread.getOrCreateThread(withContactId: member, transaction: transaction)
|
||||
thread.save(with: transaction)
|
||||
|
@ -97,7 +99,9 @@ public final class ClosedGroupsProtocol : NSObject {
|
|||
SharedSenderKeysImplementation.shared.generateRatchet(for: groupPublicKey, senderPublicKey: $0, using: transaction)
|
||||
}
|
||||
// Send a closed group update message to the existing members with the new members' ratchets (this message is aimed at the group)
|
||||
let senderKeys = ratchets.map { ClosedGroupSenderKey(chainKey: Data(hex: $0.chainKey), keyIndex: $0.keyIndex) }
|
||||
let senderKeys = zip(ratchets, newMembersAndLinkedDevices).map { ratchet, publicKey in
|
||||
ClosedGroupSenderKey(chainKey: Data(hex: ratchet.chainKey), keyIndex: ratchet.keyIndex, senderPublicKey: publicKey)
|
||||
}
|
||||
let closedGroupUpdateMessageKind = ClosedGroupUpdateMessage.Kind.info(groupPublicKey: Data(hex: groupPublicKey), name: name, senderKeys: senderKeys,
|
||||
members: members, admins: admins)
|
||||
let closedGroupUpdateMessage = ClosedGroupUpdateMessage(thread: thread, kind: closedGroupUpdateMessageKind)
|
||||
|
@ -105,9 +109,7 @@ public final class ClosedGroupsProtocol : NSObject {
|
|||
// Establish sessions if needed
|
||||
establishSessionsIfNeeded(with: [String](newMembersAsSet), using: transaction) // Not `newMembersAndLinkedDevices` as this internally takes care of multi device already
|
||||
// Send closed group update messages to the new members (and their linked devices) using established channels
|
||||
let allSenderKeys = Storage.getAllClosedGroupRatchets(for: groupPublicKey).map { // This includes the newly generated ratchets
|
||||
ClosedGroupSenderKey(chainKey: Data(hex: $0.chainKey), keyIndex: $0.keyIndex)
|
||||
}
|
||||
let allSenderKeys = [ClosedGroupSenderKey](Storage.getAllClosedGroupSenderKeys(for: groupPublicKey)) // This includes the newly generated sender keys
|
||||
for member in newMembersAsSet { // Not `newMembersAndLinkedDevices` as this internally takes care of multi device already
|
||||
let thread = TSContactThread.getOrCreateThread(contactId: member)
|
||||
thread.save(with: transaction)
|
||||
|
@ -167,7 +169,7 @@ public final class ClosedGroupsProtocol : NSObject {
|
|||
establishSessionsIfNeeded(with: members, using: transaction) // This internally takes care of multi device
|
||||
// Send out the user's new ratchet to all members (minus the removed ones) and their linked devices using established channels
|
||||
let userRatchet = SharedSenderKeysImplementation.shared.generateRatchet(for: groupPublicKey, senderPublicKey: userPublicKey, using: transaction)
|
||||
let userSenderKey = ClosedGroupSenderKey(chainKey: Data(hex: userRatchet.chainKey), keyIndex: userRatchet.keyIndex)
|
||||
let userSenderKey = ClosedGroupSenderKey(chainKey: Data(hex: userRatchet.chainKey), keyIndex: userRatchet.keyIndex, senderPublicKey: userPublicKey)
|
||||
for member in members { // This internally takes care of multi device
|
||||
let thread = TSContactThread.getOrCreateThread(withContactId: member, transaction: transaction)
|
||||
thread.save(with: transaction)
|
||||
|
@ -195,7 +197,7 @@ public final class ClosedGroupsProtocol : NSObject {
|
|||
switch closedGroupUpdate.type {
|
||||
case .new: handleNewGroupMessage(closedGroupUpdate, using: transaction)
|
||||
case .info: handleInfoMessage(closedGroupUpdate, from: publicKey, using: transaction)
|
||||
case .chainKey: handleChainKeyMessage(closedGroupUpdate, from: publicKey, using: transaction)
|
||||
case .senderKey: handleSenderKeyMessage(closedGroupUpdate, from: publicKey, using: transaction)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,19 +256,18 @@ public final class ClosedGroupsProtocol : NSObject {
|
|||
}
|
||||
// Establish sessions if needed (it's important that this happens before the code below)
|
||||
establishSessionsIfNeeded(with: members, using: transaction) // This internally takes care of multi device
|
||||
// Parse out any new members and store their ratchets (it's important that this happens before the code below)
|
||||
let oldMembers = group.groupMemberIds
|
||||
let newMembers = members.filter { !oldMembers.contains($0) }
|
||||
zip(newMembers, senderKeys).forEach { (member, senderKey) in
|
||||
// Store the ratchets for any new members (it's important that this happens before the code below)
|
||||
senderKeys.forEach { senderKey in
|
||||
let ratchet = ClosedGroupRatchet(chainKey: senderKey.chainKey.toHexString(), keyIndex: UInt(senderKey.keyIndex), messageKeys: [])
|
||||
Storage.setClosedGroupRatchet(for: groupPublicKey, senderPublicKey: member, ratchet: ratchet, using: transaction)
|
||||
Storage.setClosedGroupRatchet(for: groupPublicKey, senderPublicKey: senderKey.senderPublicKey, ratchet: ratchet, using: transaction)
|
||||
}
|
||||
// Delete all ratchets and send out the user's new ratchet using established channels if any member of the group left or was removed
|
||||
let oldMembers = group.groupMemberIds
|
||||
if Set(members).intersection(oldMembers) != Set(oldMembers) {
|
||||
Storage.removeAllClosedGroupRatchets(for: groupPublicKey, using: transaction)
|
||||
let userPublicKey = getUserHexEncodedPublicKey()
|
||||
let userRatchet = SharedSenderKeysImplementation.shared.generateRatchet(for: groupPublicKey, senderPublicKey: userPublicKey, using: transaction)
|
||||
let userSenderKey = ClosedGroupSenderKey(chainKey: Data(hex: userRatchet.chainKey), keyIndex: userRatchet.keyIndex)
|
||||
let userSenderKey = ClosedGroupSenderKey(chainKey: Data(hex: userRatchet.chainKey), keyIndex: userRatchet.keyIndex, senderPublicKey: userPublicKey)
|
||||
for member in members {
|
||||
let thread = TSContactThread.getOrCreateThread(withContactId: member, transaction: transaction)
|
||||
thread.save(with: transaction)
|
||||
|
@ -286,7 +287,7 @@ public final class ClosedGroupsProtocol : NSObject {
|
|||
}
|
||||
|
||||
/// Invoked upon receiving a chain key from another user.
|
||||
private static func handleChainKeyMessage(_ closedGroupUpdate: SSKProtoDataMessageClosedGroupUpdate, from senderPublicKey: String, using transaction: YapDatabaseReadWriteTransaction) {
|
||||
private static func handleSenderKeyMessage(_ closedGroupUpdate: SSKProtoDataMessageClosedGroupUpdate, from senderPublicKey: String, using transaction: YapDatabaseReadWriteTransaction) {
|
||||
let groupPublicKey = closedGroupUpdate.groupPublicKey.toHexString()
|
||||
guard let senderKey = closedGroupUpdate.senderKeys.first else {
|
||||
return print("[Loki] Ignoring invalid closed group update.")
|
||||
|
|
|
@ -20,13 +20,14 @@ internal extension Storage {
|
|||
transaction.setObject(ratchet, forKey: senderPublicKey, inCollection: collection)
|
||||
}
|
||||
|
||||
internal static func getAllClosedGroupRatchets(for groupPublicKey: String) -> Set<ClosedGroupRatchet> {
|
||||
internal static func getAllClosedGroupSenderKeys(for groupPublicKey: String) -> Set<ClosedGroupSenderKey> {
|
||||
let collection = getClosedGroupRatchetCollection(for: groupPublicKey)
|
||||
var result: Set<ClosedGroupRatchet> = []
|
||||
var result: Set<ClosedGroupSenderKey> = []
|
||||
read { transaction in
|
||||
transaction.enumerateRows(inCollection: collection) { _, object, _, _ in
|
||||
guard let ratchet = object as? ClosedGroupRatchet else { return }
|
||||
result.insert(ratchet)
|
||||
transaction.enumerateRows(inCollection: collection) { key, object, _, _ in
|
||||
guard let senderPublicKey = key as? String, let ratchet = object as? ClosedGroupRatchet else { return }
|
||||
let senderKey = ClosedGroupSenderKey(chainKey: Data(hex: ratchet.chainKey), keyIndex: ratchet.keyIndex, senderPublicKey: senderPublicKey)
|
||||
result.insert(senderKey)
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
|
|
@ -3293,13 +3293,13 @@ extension SSKProtoDataMessageLokiProfile.SSKProtoDataMessageLokiProfileBuilder {
|
|||
|
||||
// MARK: - SSKProtoDataMessageClosedGroupUpdateSenderKeyBuilder
|
||||
|
||||
@objc public class func builder(chainKey: Data, keyIndex: UInt32) -> SSKProtoDataMessageClosedGroupUpdateSenderKeyBuilder {
|
||||
return SSKProtoDataMessageClosedGroupUpdateSenderKeyBuilder(chainKey: chainKey, keyIndex: keyIndex)
|
||||
@objc public class func builder(chainKey: Data, keyIndex: UInt32, senderPublicKey: String) -> SSKProtoDataMessageClosedGroupUpdateSenderKeyBuilder {
|
||||
return SSKProtoDataMessageClosedGroupUpdateSenderKeyBuilder(chainKey: chainKey, keyIndex: keyIndex, senderPublicKey: senderPublicKey)
|
||||
}
|
||||
|
||||
// asBuilder() constructs a builder that reflects the proto's contents.
|
||||
@objc public func asBuilder() -> SSKProtoDataMessageClosedGroupUpdateSenderKeyBuilder {
|
||||
let builder = SSKProtoDataMessageClosedGroupUpdateSenderKeyBuilder(chainKey: chainKey, keyIndex: keyIndex)
|
||||
let builder = SSKProtoDataMessageClosedGroupUpdateSenderKeyBuilder(chainKey: chainKey, keyIndex: keyIndex, senderPublicKey: senderPublicKey)
|
||||
return builder
|
||||
}
|
||||
|
||||
|
@ -3309,11 +3309,12 @@ extension SSKProtoDataMessageLokiProfile.SSKProtoDataMessageLokiProfileBuilder {
|
|||
|
||||
@objc fileprivate override init() {}
|
||||
|
||||
@objc fileprivate init(chainKey: Data, keyIndex: UInt32) {
|
||||
@objc fileprivate init(chainKey: Data, keyIndex: UInt32, senderPublicKey: String) {
|
||||
super.init()
|
||||
|
||||
setChainKey(chainKey)
|
||||
setKeyIndex(keyIndex)
|
||||
setSenderPublicKey(senderPublicKey)
|
||||
}
|
||||
|
||||
@objc public func setChainKey(_ valueParam: Data) {
|
||||
|
@ -3324,6 +3325,10 @@ extension SSKProtoDataMessageLokiProfile.SSKProtoDataMessageLokiProfileBuilder {
|
|||
proto.keyIndex = valueParam
|
||||
}
|
||||
|
||||
@objc public func setSenderPublicKey(_ valueParam: String) {
|
||||
proto.senderPublicKey = valueParam
|
||||
}
|
||||
|
||||
@objc public func build() throws -> SSKProtoDataMessageClosedGroupUpdateSenderKey {
|
||||
return try SSKProtoDataMessageClosedGroupUpdateSenderKey.parseProto(proto)
|
||||
}
|
||||
|
@ -3339,12 +3344,16 @@ extension SSKProtoDataMessageLokiProfile.SSKProtoDataMessageLokiProfileBuilder {
|
|||
|
||||
@objc public let keyIndex: UInt32
|
||||
|
||||
@objc public let senderPublicKey: String
|
||||
|
||||
private init(proto: SignalServiceProtos_DataMessage.ClosedGroupUpdate.SenderKey,
|
||||
chainKey: Data,
|
||||
keyIndex: UInt32) {
|
||||
keyIndex: UInt32,
|
||||
senderPublicKey: String) {
|
||||
self.proto = proto
|
||||
self.chainKey = chainKey
|
||||
self.keyIndex = keyIndex
|
||||
self.senderPublicKey = senderPublicKey
|
||||
}
|
||||
|
||||
@objc
|
||||
|
@ -3368,13 +3377,19 @@ extension SSKProtoDataMessageLokiProfile.SSKProtoDataMessageLokiProfileBuilder {
|
|||
}
|
||||
let keyIndex = proto.keyIndex
|
||||
|
||||
guard proto.hasSenderPublicKey else {
|
||||
throw SSKProtoError.invalidProtobuf(description: "\(logTag) missing required field: senderPublicKey")
|
||||
}
|
||||
let senderPublicKey = proto.senderPublicKey
|
||||
|
||||
// MARK: - Begin Validation Logic for SSKProtoDataMessageClosedGroupUpdateSenderKey -
|
||||
|
||||
// MARK: - End Validation Logic for SSKProtoDataMessageClosedGroupUpdateSenderKey -
|
||||
|
||||
let result = SSKProtoDataMessageClosedGroupUpdateSenderKey(proto: proto,
|
||||
chainKey: chainKey,
|
||||
keyIndex: keyIndex)
|
||||
keyIndex: keyIndex,
|
||||
senderPublicKey: senderPublicKey)
|
||||
return result
|
||||
}
|
||||
|
||||
|
@ -3408,14 +3423,14 @@ extension SSKProtoDataMessageClosedGroupUpdateSenderKey.SSKProtoDataMessageClose
|
|||
@objc public enum SSKProtoDataMessageClosedGroupUpdateType: Int32 {
|
||||
case new = 0
|
||||
case info = 1
|
||||
case chainKey = 2
|
||||
case senderKey = 2
|
||||
}
|
||||
|
||||
private class func SSKProtoDataMessageClosedGroupUpdateTypeWrap(_ value: SignalServiceProtos_DataMessage.ClosedGroupUpdate.TypeEnum) -> SSKProtoDataMessageClosedGroupUpdateType {
|
||||
switch value {
|
||||
case .new: return .new
|
||||
case .info: return .info
|
||||
case .chainKey: return .chainKey
|
||||
case .senderKey: return .senderKey
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3423,7 +3438,7 @@ extension SSKProtoDataMessageClosedGroupUpdateSenderKey.SSKProtoDataMessageClose
|
|||
switch value {
|
||||
case .new: return .new
|
||||
case .info: return .info
|
||||
case .chainKey: return .chainKey
|
||||
case .senderKey: return .senderKey
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1546,14 +1546,14 @@ struct SignalServiceProtos_DataMessage {
|
|||
enum TypeEnum: SwiftProtobuf.Enum {
|
||||
typealias RawValue = Int
|
||||
|
||||
/// groupPublicKey, name, groupPrivateKey, chainKeys, members, admins
|
||||
/// groupPublicKey, name, groupPrivateKey, senderKeys, members, admins
|
||||
case new // = 0
|
||||
|
||||
/// groupPublicKey, name, chainKeys, members, admins
|
||||
/// groupPublicKey, name, senderKeys, members, admins
|
||||
case info // = 1
|
||||
|
||||
/// groupPublicKey, chainKeys
|
||||
case chainKey // = 2
|
||||
/// groupPublicKey, senderKeys
|
||||
case senderKey // = 2
|
||||
|
||||
init() {
|
||||
self = .new
|
||||
|
@ -1563,7 +1563,7 @@ struct SignalServiceProtos_DataMessage {
|
|||
switch rawValue {
|
||||
case 0: self = .new
|
||||
case 1: self = .info
|
||||
case 2: self = .chainKey
|
||||
case 2: self = .senderKey
|
||||
default: return nil
|
||||
}
|
||||
}
|
||||
|
@ -1572,7 +1572,7 @@ struct SignalServiceProtos_DataMessage {
|
|||
switch self {
|
||||
case .new: return 0
|
||||
case .info: return 1
|
||||
case .chainKey: return 2
|
||||
case .senderKey: return 2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1603,12 +1603,23 @@ struct SignalServiceProtos_DataMessage {
|
|||
/// Clears the value of `keyIndex`. Subsequent reads from it will return its default value.
|
||||
mutating func clearKeyIndex() {self._keyIndex = nil}
|
||||
|
||||
/// @required
|
||||
var senderPublicKey: String {
|
||||
get {return _senderPublicKey ?? String()}
|
||||
set {_senderPublicKey = newValue}
|
||||
}
|
||||
/// Returns true if `senderPublicKey` has been explicitly set.
|
||||
var hasSenderPublicKey: Bool {return self._senderPublicKey != nil}
|
||||
/// Clears the value of `senderPublicKey`. Subsequent reads from it will return its default value.
|
||||
mutating func clearSenderPublicKey() {self._senderPublicKey = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _chainKey: Data? = nil
|
||||
fileprivate var _keyIndex: UInt32? = nil
|
||||
fileprivate var _senderPublicKey: String? = nil
|
||||
}
|
||||
|
||||
init() {}
|
||||
|
@ -4083,7 +4094,7 @@ extension SignalServiceProtos_DataMessage.ClosedGroupUpdate.TypeEnum: SwiftProto
|
|||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
0: .same(proto: "NEW"),
|
||||
1: .same(proto: "INFO"),
|
||||
2: .same(proto: "CHAIN_KEY"),
|
||||
2: .same(proto: "SENDER_KEY"),
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -4092,6 +4103,7 @@ extension SignalServiceProtos_DataMessage.ClosedGroupUpdate.SenderKey: SwiftProt
|
|||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "chainKey"),
|
||||
2: .same(proto: "keyIndex"),
|
||||
3: .same(proto: "senderPublicKey"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
|
@ -4099,6 +4111,7 @@ extension SignalServiceProtos_DataMessage.ClosedGroupUpdate.SenderKey: SwiftProt
|
|||
switch fieldNumber {
|
||||
case 1: try decoder.decodeSingularBytesField(value: &self._chainKey)
|
||||
case 2: try decoder.decodeSingularUInt32Field(value: &self._keyIndex)
|
||||
case 3: try decoder.decodeSingularStringField(value: &self._senderPublicKey)
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
@ -4111,12 +4124,16 @@ extension SignalServiceProtos_DataMessage.ClosedGroupUpdate.SenderKey: SwiftProt
|
|||
if let v = self._keyIndex {
|
||||
try visitor.visitSingularUInt32Field(value: v, fieldNumber: 2)
|
||||
}
|
||||
if let v = self._senderPublicKey {
|
||||
try visitor.visitSingularStringField(value: v, fieldNumber: 3)
|
||||
}
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: SignalServiceProtos_DataMessage.ClosedGroupUpdate.SenderKey, rhs: SignalServiceProtos_DataMessage.ClosedGroupUpdate.SenderKey) -> Bool {
|
||||
if lhs._chainKey != rhs._chainKey {return false}
|
||||
if lhs._keyIndex != rhs._keyIndex {return false}
|
||||
if lhs._senderPublicKey != rhs._senderPublicKey {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue