mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Merge pull request #431 from Brice-W/exp-timer-config-message
Add Closed Group Expiration Timer Setting to Configuration Message
This commit is contained in:
commit
4a0a66533d
|
@ -250,14 +250,6 @@ public final class ClosedGroupControlMessage : ControlMessage {
|
||||||
dataMessageProto.setClosedGroupControlMessage(try closedGroupControlMessage.build())
|
dataMessageProto.setClosedGroupControlMessage(try closedGroupControlMessage.build())
|
||||||
// Group context
|
// Group context
|
||||||
try setGroupContextIfNeeded(on: dataMessageProto, using: transaction)
|
try setGroupContextIfNeeded(on: dataMessageProto, using: transaction)
|
||||||
// Expiration timer
|
|
||||||
// TODO: We * want * expiration timer updates to be explicit. But currently Android will disable the expiration timer for a conversation
|
|
||||||
// if it receives a message without the current expiration timer value attached to it...
|
|
||||||
var expiration: UInt32 = 0
|
|
||||||
if let disappearingMessagesConfiguration = OWSDisappearingMessagesConfiguration.fetch(uniqueId: threadID!, transaction: transaction) {
|
|
||||||
expiration = disappearingMessagesConfiguration.isEnabled ? disappearingMessagesConfiguration.durationSeconds : 0
|
|
||||||
}
|
|
||||||
dataMessageProto.setExpireTimer(expiration)
|
|
||||||
contentProto.setDataMessage(try dataMessageProto.build())
|
contentProto.setDataMessage(try dataMessageProto.build())
|
||||||
return try contentProto.build()
|
return try contentProto.build()
|
||||||
} catch {
|
} catch {
|
||||||
|
|
|
@ -101,15 +101,17 @@ extension ConfigurationMessage {
|
||||||
public let encryptionKeyPair: ECKeyPair
|
public let encryptionKeyPair: ECKeyPair
|
||||||
public let members: Set<String>
|
public let members: Set<String>
|
||||||
public let admins: Set<String>
|
public let admins: Set<String>
|
||||||
|
public let expirationTimer: UInt32
|
||||||
|
|
||||||
public var isValid: Bool { !members.isEmpty && !admins.isEmpty }
|
public var isValid: Bool { !members.isEmpty && !admins.isEmpty }
|
||||||
|
|
||||||
public init(publicKey: String, name: String, encryptionKeyPair: ECKeyPair, members: Set<String>, admins: Set<String>) {
|
public init(publicKey: String, name: String, encryptionKeyPair: ECKeyPair, members: Set<String>, admins: Set<String>, expirationTimer: UInt32) {
|
||||||
self.publicKey = publicKey
|
self.publicKey = publicKey
|
||||||
self.name = name
|
self.name = name
|
||||||
self.encryptionKeyPair = encryptionKeyPair
|
self.encryptionKeyPair = encryptionKeyPair
|
||||||
self.members = members
|
self.members = members
|
||||||
self.admins = admins
|
self.admins = admins
|
||||||
|
self.expirationTimer = expirationTimer
|
||||||
}
|
}
|
||||||
|
|
||||||
public required init?(coder: NSCoder) {
|
public required init?(coder: NSCoder) {
|
||||||
|
@ -118,11 +120,13 @@ extension ConfigurationMessage {
|
||||||
let encryptionKeyPair = coder.decodeObject(forKey: "encryptionKeyPair") as! ECKeyPair?,
|
let encryptionKeyPair = coder.decodeObject(forKey: "encryptionKeyPair") as! ECKeyPair?,
|
||||||
let members = coder.decodeObject(forKey: "members") as! Set<String>?,
|
let members = coder.decodeObject(forKey: "members") as! Set<String>?,
|
||||||
let admins = coder.decodeObject(forKey: "admins") as! Set<String>? else { return nil }
|
let admins = coder.decodeObject(forKey: "admins") as! Set<String>? else { return nil }
|
||||||
|
let expirationTimer = coder.decodeObject(forKey: "expirationTimer") as? UInt32 ?? 0
|
||||||
self.publicKey = publicKey
|
self.publicKey = publicKey
|
||||||
self.name = name
|
self.name = name
|
||||||
self.encryptionKeyPair = encryptionKeyPair
|
self.encryptionKeyPair = encryptionKeyPair
|
||||||
self.members = members
|
self.members = members
|
||||||
self.admins = admins
|
self.admins = admins
|
||||||
|
self.expirationTimer = expirationTimer
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(with coder: NSCoder) {
|
public func encode(with coder: NSCoder) {
|
||||||
|
@ -131,6 +135,7 @@ extension ConfigurationMessage {
|
||||||
coder.encode(encryptionKeyPair, forKey: "encryptionKeyPair")
|
coder.encode(encryptionKeyPair, forKey: "encryptionKeyPair")
|
||||||
coder.encode(members, forKey: "members")
|
coder.encode(members, forKey: "members")
|
||||||
coder.encode(admins, forKey: "admins")
|
coder.encode(admins, forKey: "admins")
|
||||||
|
coder.encode(expirationTimer, forKey: "expirationTimer")
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func fromProto(_ proto: SNProtoConfigurationMessageClosedGroup) -> ClosedGroup? {
|
public static func fromProto(_ proto: SNProtoConfigurationMessageClosedGroup) -> ClosedGroup? {
|
||||||
|
@ -146,7 +151,8 @@ extension ConfigurationMessage {
|
||||||
}
|
}
|
||||||
let members = Set(proto.members.map { $0.toHexString() })
|
let members = Set(proto.members.map { $0.toHexString() })
|
||||||
let admins = Set(proto.admins.map { $0.toHexString() })
|
let admins = Set(proto.admins.map { $0.toHexString() })
|
||||||
let result = ClosedGroup(publicKey: publicKey, name: name, encryptionKeyPair: encryptionKeyPair, members: members, admins: admins)
|
let expirationTimer = proto.expirationTimer
|
||||||
|
let result = ClosedGroup(publicKey: publicKey, name: name, encryptionKeyPair: encryptionKeyPair, members: members, admins: admins, expirationTimer: expirationTimer)
|
||||||
guard result.isValid else { return nil }
|
guard result.isValid else { return nil }
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
@ -165,6 +171,7 @@ extension ConfigurationMessage {
|
||||||
}
|
}
|
||||||
result.setMembers(members.map { Data(hex: $0) })
|
result.setMembers(members.map { Data(hex: $0) })
|
||||||
result.setAdmins(admins.map { Data(hex: $0) })
|
result.setAdmins(admins.map { Data(hex: $0) })
|
||||||
|
result.setExpirationTimer(expirationTimer)
|
||||||
do {
|
do {
|
||||||
return try result.build()
|
return try result.build()
|
||||||
} catch {
|
} catch {
|
||||||
|
|
|
@ -2100,6 +2100,9 @@ extension SNProtoDataMessage.SNProtoDataMessageBuilder {
|
||||||
}
|
}
|
||||||
builder.setMembers(members)
|
builder.setMembers(members)
|
||||||
builder.setAdmins(admins)
|
builder.setAdmins(admins)
|
||||||
|
if hasExpirationTimer {
|
||||||
|
builder.setExpirationTimer(expirationTimer)
|
||||||
|
}
|
||||||
return builder
|
return builder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2141,6 +2144,10 @@ extension SNProtoDataMessage.SNProtoDataMessageBuilder {
|
||||||
proto.admins = wrappedItems
|
proto.admins = wrappedItems
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc public func setExpirationTimer(_ valueParam: UInt32) {
|
||||||
|
proto.expirationTimer = valueParam
|
||||||
|
}
|
||||||
|
|
||||||
@objc public func build() throws -> SNProtoConfigurationMessageClosedGroup {
|
@objc public func build() throws -> SNProtoConfigurationMessageClosedGroup {
|
||||||
return try SNProtoConfigurationMessageClosedGroup.parseProto(proto)
|
return try SNProtoConfigurationMessageClosedGroup.parseProto(proto)
|
||||||
}
|
}
|
||||||
|
@ -2182,6 +2189,13 @@ extension SNProtoDataMessage.SNProtoDataMessageBuilder {
|
||||||
return proto.admins
|
return proto.admins
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc public var expirationTimer: UInt32 {
|
||||||
|
return proto.expirationTimer
|
||||||
|
}
|
||||||
|
@objc public var hasExpirationTimer: Bool {
|
||||||
|
return proto.hasExpirationTimer
|
||||||
|
}
|
||||||
|
|
||||||
private init(proto: SessionProtos_ConfigurationMessage.ClosedGroup,
|
private init(proto: SessionProtos_ConfigurationMessage.ClosedGroup,
|
||||||
encryptionKeyPair: SNProtoKeyPair?) {
|
encryptionKeyPair: SNProtoKeyPair?) {
|
||||||
self.proto = proto
|
self.proto = proto
|
||||||
|
|
|
@ -971,6 +971,15 @@ struct SessionProtos_ConfigurationMessage {
|
||||||
|
|
||||||
var admins: [Data] = []
|
var admins: [Data] = []
|
||||||
|
|
||||||
|
var expirationTimer: UInt32 {
|
||||||
|
get {return _expirationTimer ?? 0}
|
||||||
|
set {_expirationTimer = newValue}
|
||||||
|
}
|
||||||
|
/// Returns true if `expirationTimer` has been explicitly set.
|
||||||
|
var hasExpirationTimer: Bool {return self._expirationTimer != nil}
|
||||||
|
/// Clears the value of `expirationTimer`. Subsequent reads from it will return its default value.
|
||||||
|
mutating func clearExpirationTimer() {self._expirationTimer = nil}
|
||||||
|
|
||||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||||
|
|
||||||
init() {}
|
init() {}
|
||||||
|
@ -978,6 +987,7 @@ struct SessionProtos_ConfigurationMessage {
|
||||||
fileprivate var _publicKey: Data? = nil
|
fileprivate var _publicKey: Data? = nil
|
||||||
fileprivate var _name: String? = nil
|
fileprivate var _name: String? = nil
|
||||||
fileprivate var _encryptionKeyPair: SessionProtos_KeyPair? = nil
|
fileprivate var _encryptionKeyPair: SessionProtos_KeyPair? = nil
|
||||||
|
fileprivate var _expirationTimer: UInt32? = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Contact {
|
struct Contact {
|
||||||
|
@ -2294,6 +2304,7 @@ extension SessionProtos_ConfigurationMessage.ClosedGroup: SwiftProtobuf.Message,
|
||||||
3: .same(proto: "encryptionKeyPair"),
|
3: .same(proto: "encryptionKeyPair"),
|
||||||
4: .same(proto: "members"),
|
4: .same(proto: "members"),
|
||||||
5: .same(proto: "admins"),
|
5: .same(proto: "admins"),
|
||||||
|
6: .same(proto: "expirationTimer"),
|
||||||
]
|
]
|
||||||
|
|
||||||
public var isInitialized: Bool {
|
public var isInitialized: Bool {
|
||||||
|
@ -2312,6 +2323,7 @@ extension SessionProtos_ConfigurationMessage.ClosedGroup: SwiftProtobuf.Message,
|
||||||
case 3: try { try decoder.decodeSingularMessageField(value: &self._encryptionKeyPair) }()
|
case 3: try { try decoder.decodeSingularMessageField(value: &self._encryptionKeyPair) }()
|
||||||
case 4: try { try decoder.decodeRepeatedBytesField(value: &self.members) }()
|
case 4: try { try decoder.decodeRepeatedBytesField(value: &self.members) }()
|
||||||
case 5: try { try decoder.decodeRepeatedBytesField(value: &self.admins) }()
|
case 5: try { try decoder.decodeRepeatedBytesField(value: &self.admins) }()
|
||||||
|
case 6: try { try decoder.decodeSingularUInt32Field(value: &self._expirationTimer) }()
|
||||||
default: break
|
default: break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2333,6 +2345,9 @@ extension SessionProtos_ConfigurationMessage.ClosedGroup: SwiftProtobuf.Message,
|
||||||
if !self.admins.isEmpty {
|
if !self.admins.isEmpty {
|
||||||
try visitor.visitRepeatedBytesField(value: self.admins, fieldNumber: 5)
|
try visitor.visitRepeatedBytesField(value: self.admins, fieldNumber: 5)
|
||||||
}
|
}
|
||||||
|
if let v = self._expirationTimer {
|
||||||
|
try visitor.visitSingularUInt32Field(value: v, fieldNumber: 6)
|
||||||
|
}
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
try unknownFields.traverse(visitor: &visitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2342,6 +2357,7 @@ extension SessionProtos_ConfigurationMessage.ClosedGroup: SwiftProtobuf.Message,
|
||||||
if lhs._encryptionKeyPair != rhs._encryptionKeyPair {return false}
|
if lhs._encryptionKeyPair != rhs._encryptionKeyPair {return false}
|
||||||
if lhs.members != rhs.members {return false}
|
if lhs.members != rhs.members {return false}
|
||||||
if lhs.admins != rhs.admins {return false}
|
if lhs.admins != rhs.admins {return false}
|
||||||
|
if lhs._expirationTimer != rhs._expirationTimer {return false}
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,6 +161,7 @@ message ConfigurationMessage {
|
||||||
optional KeyPair encryptionKeyPair = 3;
|
optional KeyPair encryptionKeyPair = 3;
|
||||||
repeated bytes members = 4;
|
repeated bytes members = 4;
|
||||||
repeated bytes admins = 5;
|
repeated bytes admins = 5;
|
||||||
|
optional uint32 expirationTimer = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Contact {
|
message Contact {
|
||||||
|
|
|
@ -207,8 +207,7 @@ extension MessageReceiver {
|
||||||
let allClosedGroupPublicKeys = storage.getUserClosedGroupPublicKeys()
|
let allClosedGroupPublicKeys = storage.getUserClosedGroupPublicKeys()
|
||||||
for closedGroup in message.closedGroups {
|
for closedGroup in message.closedGroups {
|
||||||
guard !allClosedGroupPublicKeys.contains(closedGroup.publicKey) else { continue }
|
guard !allClosedGroupPublicKeys.contains(closedGroup.publicKey) else { continue }
|
||||||
handleNewClosedGroup(groupPublicKey: closedGroup.publicKey, name: closedGroup.name, encryptionKeyPair: closedGroup.encryptionKeyPair,
|
handleNewClosedGroup(groupPublicKey: closedGroup.publicKey, name: closedGroup.name, encryptionKeyPair: closedGroup.encryptionKeyPair, members: [String](closedGroup.members), admins: [String](closedGroup.admins), expirationTimer: closedGroup.expirationTimer, messageSentTimestamp: message.sentTimestamp!, using: transaction)
|
||||||
members: [String](closedGroup.members), admins: [String](closedGroup.admins), expirationTimer: 0, messageSentTimestamp: message.sentTimestamp!, using: transaction)
|
|
||||||
}
|
}
|
||||||
// Open groups
|
// Open groups
|
||||||
for openGroupURL in message.openGroups {
|
for openGroupURL in message.openGroups {
|
||||||
|
|
|
@ -22,7 +22,7 @@ extension ConfigurationMessage {
|
||||||
guard storage.isClosedGroup(groupPublicKey),
|
guard storage.isClosedGroup(groupPublicKey),
|
||||||
let encryptionKeyPair = storage.getLatestClosedGroupEncryptionKeyPair(for: groupPublicKey) else { return }
|
let encryptionKeyPair = storage.getLatestClosedGroupEncryptionKeyPair(for: groupPublicKey) else { return }
|
||||||
let closedGroup = ClosedGroup(publicKey: groupPublicKey, name: thread.groupModel.groupName!, encryptionKeyPair: encryptionKeyPair,
|
let closedGroup = ClosedGroup(publicKey: groupPublicKey, name: thread.groupModel.groupName!, encryptionKeyPair: encryptionKeyPair,
|
||||||
members: Set(thread.groupModel.groupMemberIds), admins: Set(thread.groupModel.groupAdminIds))
|
members: Set(thread.groupModel.groupMemberIds), admins: Set(thread.groupModel.groupAdminIds), expirationTimer: thread.disappearingMessagesDuration(with: transaction))
|
||||||
closedGroups.insert(closedGroup)
|
closedGroups.insert(closedGroup)
|
||||||
case .openGroup:
|
case .openGroup:
|
||||||
if let v2OpenGroup = storage.getV2OpenGroup(for: thread.uniqueId!) {
|
if let v2OpenGroup = storage.getV2OpenGroup(for: thread.uniqueId!) {
|
||||||
|
|
Loading…
Reference in a new issue