set expiration timer for new group members
This commit is contained in:
parent
0b5c1a68ee
commit
1f9cd92bce
|
@ -14,7 +14,7 @@ public final class ClosedGroupControlMessage : ControlMessage {
|
|||
|
||||
// MARK: Kind
|
||||
public enum Kind : CustomStringConvertible {
|
||||
case new(publicKey: Data, name: String, encryptionKeyPair: ECKeyPair, members: [Data], admins: [Data])
|
||||
case new(publicKey: Data, name: String, encryptionKeyPair: ECKeyPair, members: [Data], admins: [Data], expireTimer: UInt32)
|
||||
/// An encryption key pair encrypted for each member individually.
|
||||
///
|
||||
/// - Note: `publicKey` is only set when an encryption key pair is sent in a one-to-one context (i.e. not in a group).
|
||||
|
@ -89,9 +89,9 @@ public final class ClosedGroupControlMessage : ControlMessage {
|
|||
public override var isValid: Bool {
|
||||
guard super.isValid, let kind = kind else { return false }
|
||||
switch kind {
|
||||
case .new(let publicKey, let name, let encryptionKeyPair, let members, let admins):
|
||||
case .new(let publicKey, let name, let encryptionKeyPair, let members, let admins, let expireTimer):
|
||||
return !publicKey.isEmpty && !name.isEmpty && !encryptionKeyPair.publicKey.isEmpty
|
||||
&& !encryptionKeyPair.privateKey.isEmpty && !members.isEmpty && !admins.isEmpty
|
||||
&& !encryptionKeyPair.privateKey.isEmpty && !members.isEmpty && !admins.isEmpty && expireTimer >= 0
|
||||
case .encryptionKeyPair: return true
|
||||
case .nameChange(let name): return !name.isEmpty
|
||||
case .membersAdded(let members): return !members.isEmpty
|
||||
|
@ -112,7 +112,8 @@ public final class ClosedGroupControlMessage : ControlMessage {
|
|||
let encryptionKeyPair = coder.decodeObject(forKey: "encryptionKeyPair") as? ECKeyPair,
|
||||
let members = coder.decodeObject(forKey: "members") as? [Data],
|
||||
let admins = coder.decodeObject(forKey: "admins") as? [Data] else { return nil }
|
||||
self.kind = .new(publicKey: publicKey, name: name, encryptionKeyPair: encryptionKeyPair, members: members, admins: admins)
|
||||
let expireTimer = coder.decodeObject(forKey: "expireTimer") as! UInt32
|
||||
self.kind = .new(publicKey: publicKey, name: name, encryptionKeyPair: encryptionKeyPair, members: members, admins: admins, expireTimer: expireTimer)
|
||||
case "encryptionKeyPair":
|
||||
let publicKey = coder.decodeObject(forKey: "publicKey") as? Data
|
||||
guard let wrappers = coder.decodeObject(forKey: "wrappers") as? [KeyPairWrapper] else { return nil }
|
||||
|
@ -138,13 +139,14 @@ public final class ClosedGroupControlMessage : ControlMessage {
|
|||
super.encode(with: coder)
|
||||
guard let kind = kind else { return }
|
||||
switch kind {
|
||||
case .new(let publicKey, let name, let encryptionKeyPair, let members, let admins):
|
||||
case .new(let publicKey, let name, let encryptionKeyPair, let members, let admins, let expireTimer):
|
||||
coder.encode("new", forKey: "kind")
|
||||
coder.encode(publicKey, forKey: "publicKey")
|
||||
coder.encode(name, forKey: "name")
|
||||
coder.encode(encryptionKeyPair, forKey: "encryptionKeyPair")
|
||||
coder.encode(members, forKey: "members")
|
||||
coder.encode(admins, forKey: "admins")
|
||||
coder.encode(expireTimer, forKey: "expireTimer")
|
||||
case .encryptionKeyPair(let publicKey, let wrappers):
|
||||
coder.encode("encryptionKeyPair", forKey: "kind")
|
||||
coder.encode(publicKey, forKey: "publicKey")
|
||||
|
@ -174,9 +176,10 @@ public final class ClosedGroupControlMessage : ControlMessage {
|
|||
guard let publicKey = closedGroupControlMessageProto.publicKey, let name = closedGroupControlMessageProto.name,
|
||||
let encryptionKeyPairAsProto = closedGroupControlMessageProto.encryptionKeyPair else { return nil }
|
||||
do {
|
||||
let expireTimer = closedGroupControlMessageProto.expireTimer
|
||||
let encryptionKeyPair = try ECKeyPair(publicKeyData: encryptionKeyPairAsProto.publicKey.removing05PrefixIfNeeded(), privateKeyData: encryptionKeyPairAsProto.privateKey)
|
||||
kind = .new(publicKey: publicKey, name: name, encryptionKeyPair: encryptionKeyPair,
|
||||
members: closedGroupControlMessageProto.members, admins: closedGroupControlMessageProto.admins)
|
||||
members: closedGroupControlMessageProto.members, admins: closedGroupControlMessageProto.admins, expireTimer: expireTimer)
|
||||
} catch {
|
||||
SNLog("Couldn't parse key pair.")
|
||||
return nil
|
||||
|
@ -208,7 +211,7 @@ public final class ClosedGroupControlMessage : ControlMessage {
|
|||
do {
|
||||
let closedGroupControlMessage: SNProtoDataMessageClosedGroupControlMessage.SNProtoDataMessageClosedGroupControlMessageBuilder
|
||||
switch kind {
|
||||
case .new(let publicKey, let name, let encryptionKeyPair, let members, let admins):
|
||||
case .new(let publicKey, let name, let encryptionKeyPair, let members, let admins, let expireTimer):
|
||||
closedGroupControlMessage = SNProtoDataMessageClosedGroupControlMessage.builder(type: .new)
|
||||
closedGroupControlMessage.setPublicKey(publicKey)
|
||||
closedGroupControlMessage.setName(name)
|
||||
|
@ -221,6 +224,7 @@ public final class ClosedGroupControlMessage : ControlMessage {
|
|||
}
|
||||
closedGroupControlMessage.setMembers(members)
|
||||
closedGroupControlMessage.setAdmins(admins)
|
||||
closedGroupControlMessage.setExpireTimer(expireTimer)
|
||||
case .encryptionKeyPair(let publicKey, let wrappers):
|
||||
closedGroupControlMessage = SNProtoDataMessageClosedGroupControlMessage.builder(type: .encryptionKeyPair)
|
||||
if let publicKey = publicKey {
|
||||
|
|
|
@ -208,7 +208,7 @@ extension MessageReceiver {
|
|||
for closedGroup in message.closedGroups {
|
||||
guard !allClosedGroupPublicKeys.contains(closedGroup.publicKey) else { continue }
|
||||
handleNewClosedGroup(groupPublicKey: closedGroup.publicKey, name: closedGroup.name, encryptionKeyPair: closedGroup.encryptionKeyPair,
|
||||
members: [String](closedGroup.members), admins: [String](closedGroup.admins), messageSentTimestamp: message.sentTimestamp!, using: transaction)
|
||||
members: [String](closedGroup.members), admins: [String](closedGroup.admins), expireTimer: 0, messageSentTimestamp: message.sentTimestamp!, using: transaction)
|
||||
}
|
||||
// Open groups
|
||||
for openGroupURL in message.openGroups {
|
||||
|
@ -368,15 +368,15 @@ extension MessageReceiver {
|
|||
}
|
||||
|
||||
private static func handleNewClosedGroup(_ message: ClosedGroupControlMessage, using transaction: Any) {
|
||||
guard case let .new(publicKeyAsData, name, encryptionKeyPair, membersAsData, adminsAsData) = message.kind else { return }
|
||||
guard case let .new(publicKeyAsData, name, encryptionKeyPair, membersAsData, adminsAsData, expireTimer) = message.kind else { return }
|
||||
let groupPublicKey = publicKeyAsData.toHexString()
|
||||
let members = membersAsData.map { $0.toHexString() }
|
||||
let admins = adminsAsData.map { $0.toHexString() }
|
||||
handleNewClosedGroup(groupPublicKey: groupPublicKey, name: name, encryptionKeyPair: encryptionKeyPair,
|
||||
members: members, admins: admins, messageSentTimestamp: message.sentTimestamp!, using: transaction)
|
||||
members: members, admins: admins, expireTimer: expireTimer, messageSentTimestamp: message.sentTimestamp!, using: transaction)
|
||||
}
|
||||
|
||||
private static func handleNewClosedGroup(groupPublicKey: String, name: String, encryptionKeyPair: ECKeyPair, members: [String], admins: [String], messageSentTimestamp: UInt64, using transaction: Any) {
|
||||
private static func handleNewClosedGroup(groupPublicKey: String, name: String, encryptionKeyPair: ECKeyPair, members: [String], admins: [String], expireTimer: UInt32, messageSentTimestamp: UInt64, using transaction: Any) {
|
||||
let transaction = transaction as! YapDatabaseReadWriteTransaction
|
||||
// Create the group
|
||||
let groupID = LKGroupUtilities.getEncodedClosedGroupIDAsData(groupPublicKey)
|
||||
|
@ -397,6 +397,13 @@ extension MessageReceiver {
|
|||
let infoMessage = TSInfoMessage(timestamp: messageSentTimestamp, in: thread, messageType: .groupCreated)
|
||||
infoMessage.save(with: transaction)
|
||||
}
|
||||
var configuration: OWSDisappearingMessagesConfiguration
|
||||
if (expireTimer > 0) {
|
||||
configuration = OWSDisappearingMessagesConfiguration(threadId: thread.uniqueId!, enabled: true, durationSeconds: expireTimer)
|
||||
} else {
|
||||
configuration = OWSDisappearingMessagesConfiguration(threadId: thread.uniqueId!, enabled: false, durationSeconds: 24 * 60 * 60)
|
||||
}
|
||||
configuration.save(with: transaction)
|
||||
// Add the group to the user's set of public keys to poll for
|
||||
Storage.shared.addClosedGroupPublicKey(groupPublicKey, using: transaction)
|
||||
// Store the key pair
|
||||
|
|
|
@ -27,7 +27,7 @@ extension MessageSender {
|
|||
let thread = TSContactThread.getOrCreateThread(withContactSessionID: member, transaction: transaction)
|
||||
thread.save(with: transaction)
|
||||
let closedGroupControlMessageKind = ClosedGroupControlMessage.Kind.new(publicKey: Data(hex: groupPublicKey), name: name,
|
||||
encryptionKeyPair: encryptionKeyPair, members: membersAsData, admins: adminsAsData)
|
||||
encryptionKeyPair: encryptionKeyPair, members: membersAsData, admins: adminsAsData, expireTimer: 0)
|
||||
let closedGroupControlMessage = ClosedGroupControlMessage(kind: closedGroupControlMessageKind)
|
||||
// Sending this non-durably is okay because we show a loader to the user. If they close the app while the
|
||||
// loader is still showing, it's within expectation that the group creation might be incomplete.
|
||||
|
@ -163,6 +163,8 @@ extension MessageSender {
|
|||
let members = [String](Set(group.groupMemberIds).union(newMembers))
|
||||
let membersAsData = members.map { Data(hex: $0) }
|
||||
let adminsAsData = group.groupAdminIds.map { Data(hex: $0) }
|
||||
// Get expiration timer value for the group
|
||||
let expireTimer = thread.disappearingMessagesDuration(with: transaction)
|
||||
guard let encryptionKeyPair = Storage.shared.getLatestClosedGroupEncryptionKeyPair(for: groupPublicKey) else {
|
||||
SNLog("Couldn't find encryption key pair for closed group: \(groupPublicKey).")
|
||||
return Promise(error: Error.noKeyPair)
|
||||
|
@ -175,7 +177,7 @@ extension MessageSender {
|
|||
let thread = TSContactThread.getOrCreateThread(withContactSessionID: member, transaction: transaction)
|
||||
thread.save(with: transaction)
|
||||
let closedGroupControlMessageKind = ClosedGroupControlMessage.Kind.new(publicKey: Data(hex: groupPublicKey), name: group.groupName!,
|
||||
encryptionKeyPair: encryptionKeyPair, members: membersAsData, admins: adminsAsData)
|
||||
encryptionKeyPair: encryptionKeyPair, members: membersAsData, admins: adminsAsData, expireTimer: expireTimer)
|
||||
let closedGroupControlMessage = ClosedGroupControlMessage(kind: closedGroupControlMessageKind)
|
||||
MessageSender.send(closedGroupControlMessage, in: thread, using: transaction)
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension
|
|||
// 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 closedGroupControlMessage.kind {
|
||||
case .new(_, let name, _, _, _): snippet = "\(senderDisplayName) added you to \(name)"
|
||||
case .new(_, let name, _, _, _, _): snippet = "\(senderDisplayName) added you to \(name)"
|
||||
default: return self.completeSilenty()
|
||||
}
|
||||
default: return self.completeSilenty()
|
||||
|
|
Loading…
Reference in New Issue