|
|
@ -62,7 +62,7 @@ fun MessageSender.create(name: String, members: Collection<String>): Promise<Str
|
|
|
|
storage.addClosedGroupEncryptionKeyPair(encryptionKeyPair, groupPublicKey)
|
|
|
|
storage.addClosedGroupEncryptionKeyPair(encryptionKeyPair, groupPublicKey)
|
|
|
|
// Notify the user
|
|
|
|
// Notify the user
|
|
|
|
val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID))
|
|
|
|
val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID))
|
|
|
|
storage.insertOutgoingInfoMessage(context, groupID, SignalServiceProtos.GroupContext.Type.UPDATE, name, members, admins, threadID)
|
|
|
|
storage.insertOutgoingInfoMessage(context, groupID, SignalServiceProtos.GroupContext.Type.UPDATE, name, members, admins, threadID, sentTime)
|
|
|
|
// Notify the PN server
|
|
|
|
// Notify the PN server
|
|
|
|
PushNotificationAPI.performOperation(PushNotificationAPI.ClosedGroupOperation.Subscribe, groupPublicKey, userPublicKey)
|
|
|
|
PushNotificationAPI.performOperation(PushNotificationAPI.ClosedGroupOperation.Subscribe, groupPublicKey, userPublicKey)
|
|
|
|
// Fulfill the promise
|
|
|
|
// Fulfill the promise
|
|
|
@ -102,14 +102,16 @@ fun MessageSender.setName(groupPublicKey: String, newName: String) {
|
|
|
|
val admins = group.admins.map { it.serialize() }
|
|
|
|
val admins = group.admins.map { it.serialize() }
|
|
|
|
// Send the update to the group
|
|
|
|
// Send the update to the group
|
|
|
|
val kind = ClosedGroupControlMessage.Kind.NameChange(newName)
|
|
|
|
val kind = ClosedGroupControlMessage.Kind.NameChange(newName)
|
|
|
|
|
|
|
|
val sentTime = System.currentTimeMillis()
|
|
|
|
val closedGroupControlMessage = ClosedGroupControlMessage(kind)
|
|
|
|
val closedGroupControlMessage = ClosedGroupControlMessage(kind)
|
|
|
|
|
|
|
|
closedGroupControlMessage.sentTimestamp = sentTime
|
|
|
|
send(closedGroupControlMessage, Address.fromSerialized(groupID))
|
|
|
|
send(closedGroupControlMessage, Address.fromSerialized(groupID))
|
|
|
|
// Update the group
|
|
|
|
// Update the group
|
|
|
|
storage.updateTitle(groupID, newName)
|
|
|
|
storage.updateTitle(groupID, newName)
|
|
|
|
// Notify the user
|
|
|
|
// Notify the user
|
|
|
|
val infoType = SignalServiceProtos.GroupContext.Type.UPDATE
|
|
|
|
val infoType = SignalServiceProtos.GroupContext.Type.UPDATE
|
|
|
|
val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID))
|
|
|
|
val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID))
|
|
|
|
storage.insertOutgoingInfoMessage(context, groupID, infoType, newName, members, admins, threadID)
|
|
|
|
storage.insertOutgoingInfoMessage(context, groupID, infoType, newName, members, admins, threadID, sentTime)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fun MessageSender.addMembers(groupPublicKey: String, membersToAdd: List<String>) {
|
|
|
|
fun MessageSender.addMembers(groupPublicKey: String, membersToAdd: List<String>) {
|
|
|
@ -138,18 +140,21 @@ fun MessageSender.addMembers(groupPublicKey: String, membersToAdd: List<String>)
|
|
|
|
val name = group.title
|
|
|
|
val name = group.title
|
|
|
|
// Send the update to the group
|
|
|
|
// Send the update to the group
|
|
|
|
val memberUpdateKind = ClosedGroupControlMessage.Kind.MembersAdded(newMembersAsData)
|
|
|
|
val memberUpdateKind = ClosedGroupControlMessage.Kind.MembersAdded(newMembersAsData)
|
|
|
|
|
|
|
|
val sentTime = System.currentTimeMillis()
|
|
|
|
val closedGroupControlMessage = ClosedGroupControlMessage(memberUpdateKind)
|
|
|
|
val closedGroupControlMessage = ClosedGroupControlMessage(memberUpdateKind)
|
|
|
|
|
|
|
|
closedGroupControlMessage.sentTimestamp = sentTime
|
|
|
|
send(closedGroupControlMessage, Address.fromSerialized(groupID))
|
|
|
|
send(closedGroupControlMessage, Address.fromSerialized(groupID))
|
|
|
|
// Send closed group update messages to any new members individually
|
|
|
|
// Send closed group update messages to any new members individually
|
|
|
|
for (member in membersToAdd) {
|
|
|
|
for (member in membersToAdd) {
|
|
|
|
val closedGroupNewKind = ClosedGroupControlMessage.Kind.New(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), name, encryptionKeyPair, membersAsData, adminsAsData)
|
|
|
|
val closedGroupNewKind = ClosedGroupControlMessage.Kind.New(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), name, encryptionKeyPair, membersAsData, adminsAsData)
|
|
|
|
val closedGroupControlMessage = ClosedGroupControlMessage(closedGroupNewKind)
|
|
|
|
val closedGroupControlMessage = ClosedGroupControlMessage(closedGroupNewKind)
|
|
|
|
|
|
|
|
closedGroupControlMessage.sentTimestamp = sentTime
|
|
|
|
send(closedGroupControlMessage, Address.fromSerialized(member))
|
|
|
|
send(closedGroupControlMessage, Address.fromSerialized(member))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Notify the user
|
|
|
|
// Notify the user
|
|
|
|
val infoType = SignalServiceProtos.GroupContext.Type.UPDATE
|
|
|
|
val infoType = SignalServiceProtos.GroupContext.Type.UPDATE
|
|
|
|
val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID))
|
|
|
|
val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID))
|
|
|
|
storage.insertOutgoingInfoMessage(context, groupID, infoType, name, updatedMembers, admins, threadID)
|
|
|
|
storage.insertOutgoingInfoMessage(context, groupID, infoType, name, updatedMembers, admins, threadID, sentTime)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fun MessageSender.removeMembers(groupPublicKey: String, membersToRemove: List<String>) {
|
|
|
|
fun MessageSender.removeMembers(groupPublicKey: String, membersToRemove: List<String>) {
|
|
|
@ -177,7 +182,9 @@ fun MessageSender.removeMembers(groupPublicKey: String, membersToRemove: List<St
|
|
|
|
val name = group.title
|
|
|
|
val name = group.title
|
|
|
|
// Send the update to the group
|
|
|
|
// Send the update to the group
|
|
|
|
val memberUpdateKind = ClosedGroupControlMessage.Kind.MembersRemoved(removeMembersAsData)
|
|
|
|
val memberUpdateKind = ClosedGroupControlMessage.Kind.MembersRemoved(removeMembersAsData)
|
|
|
|
|
|
|
|
val sentTime = System.currentTimeMillis()
|
|
|
|
val closedGroupControlMessage = ClosedGroupControlMessage(memberUpdateKind)
|
|
|
|
val closedGroupControlMessage = ClosedGroupControlMessage(memberUpdateKind)
|
|
|
|
|
|
|
|
closedGroupControlMessage.sentTimestamp = sentTime
|
|
|
|
send(closedGroupControlMessage, Address.fromSerialized(groupID))
|
|
|
|
send(closedGroupControlMessage, Address.fromSerialized(groupID))
|
|
|
|
val isCurrentUserAdmin = admins.contains(userPublicKey)
|
|
|
|
val isCurrentUserAdmin = admins.contains(userPublicKey)
|
|
|
|
if (isCurrentUserAdmin) {
|
|
|
|
if (isCurrentUserAdmin) {
|
|
|
@ -186,7 +193,7 @@ fun MessageSender.removeMembers(groupPublicKey: String, membersToRemove: List<St
|
|
|
|
// Notify the user
|
|
|
|
// Notify the user
|
|
|
|
val infoType = SignalServiceProtos.GroupContext.Type.UPDATE
|
|
|
|
val infoType = SignalServiceProtos.GroupContext.Type.UPDATE
|
|
|
|
val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID))
|
|
|
|
val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID))
|
|
|
|
storage.insertOutgoingInfoMessage(context, groupID, infoType, name, updatedMembers, admins, threadID)
|
|
|
|
storage.insertOutgoingInfoMessage(context, groupID, infoType, name, updatedMembers, admins, threadID, sentTime)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fun MessageSender.leave(groupPublicKey: String, notifyUser: Boolean = true): Promise<Unit, Exception> {
|
|
|
|
fun MessageSender.leave(groupPublicKey: String, notifyUser: Boolean = true): Promise<Unit, Exception> {
|
|
|
@ -202,13 +209,14 @@ fun MessageSender.leave(groupPublicKey: String, notifyUser: Boolean = true): Pro
|
|
|
|
val name = group.title
|
|
|
|
val name = group.title
|
|
|
|
// Send the update to the group
|
|
|
|
// Send the update to the group
|
|
|
|
val closedGroupControlMessage = ClosedGroupControlMessage(ClosedGroupControlMessage.Kind.MemberLeft())
|
|
|
|
val closedGroupControlMessage = ClosedGroupControlMessage(ClosedGroupControlMessage.Kind.MemberLeft())
|
|
|
|
closedGroupControlMessage.sentTimestamp = System.currentTimeMillis()
|
|
|
|
val sentTime = System.currentTimeMillis()
|
|
|
|
|
|
|
|
closedGroupControlMessage.sentTimestamp = sentTime
|
|
|
|
sendNonDurably(closedGroupControlMessage, Address.fromSerialized(groupID)).success {
|
|
|
|
sendNonDurably(closedGroupControlMessage, Address.fromSerialized(groupID)).success {
|
|
|
|
// Notify the user
|
|
|
|
// Notify the user
|
|
|
|
val infoType = SignalServiceProtos.GroupContext.Type.QUIT
|
|
|
|
val infoType = SignalServiceProtos.GroupContext.Type.QUIT
|
|
|
|
val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID))
|
|
|
|
val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID))
|
|
|
|
if (notifyUser) {
|
|
|
|
if (notifyUser) {
|
|
|
|
storage.insertOutgoingInfoMessage(context, groupID, infoType, name, updatedMembers, admins, threadID)
|
|
|
|
storage.insertOutgoingInfoMessage(context, groupID, infoType, name, updatedMembers, admins, threadID, sentTime)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Remove the group private key and unsubscribe from PNs
|
|
|
|
// Remove the group private key and unsubscribe from PNs
|
|
|
|
MessageReceiver.disableLocalGroupAndUnsubscribe(groupPublicKey, groupID, userPublicKey)
|
|
|
|
MessageReceiver.disableLocalGroupAndUnsubscribe(groupPublicKey, groupID, userPublicKey)
|
|
|
@ -248,7 +256,9 @@ fun MessageSender.generateAndSendNewEncryptionKeyPair(groupPublicKey: String, ta
|
|
|
|
ClosedGroupControlMessage.KeyPairWrapper(publicKey, ByteString.copyFrom(ciphertext))
|
|
|
|
ClosedGroupControlMessage.KeyPairWrapper(publicKey, ByteString.copyFrom(ciphertext))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
val kind = ClosedGroupControlMessage.Kind.EncryptionKeyPair(null, wrappers)
|
|
|
|
val kind = ClosedGroupControlMessage.Kind.EncryptionKeyPair(null, wrappers)
|
|
|
|
|
|
|
|
val sentTime = System.currentTimeMillis()
|
|
|
|
val closedGroupControlMessage = ClosedGroupControlMessage(kind)
|
|
|
|
val closedGroupControlMessage = ClosedGroupControlMessage(kind)
|
|
|
|
|
|
|
|
closedGroupControlMessage.sentTimestamp = sentTime
|
|
|
|
sendNonDurably(closedGroupControlMessage, Address.fromSerialized(groupID)).success {
|
|
|
|
sendNonDurably(closedGroupControlMessage, Address.fromSerialized(groupID)).success {
|
|
|
|
// Store it * after * having sent out the message to the group
|
|
|
|
// Store it * after * having sent out the message to the group
|
|
|
|
storage.addClosedGroupEncryptionKeyPair(newKeyPair, groupPublicKey)
|
|
|
|
storage.addClosedGroupEncryptionKeyPair(newKeyPair, groupPublicKey)
|
|
|
@ -267,7 +277,9 @@ fun MessageSender.requestEncryptionKeyPair(groupPublicKey: String) {
|
|
|
|
val members = group.members.map { it.serialize() }.toSet()
|
|
|
|
val members = group.members.map { it.serialize() }.toSet()
|
|
|
|
if (!members.contains(storage.getUserPublicKey()!!)) return
|
|
|
|
if (!members.contains(storage.getUserPublicKey()!!)) return
|
|
|
|
// Send the request to the group
|
|
|
|
// Send the request to the group
|
|
|
|
|
|
|
|
val sentTime = System.currentTimeMillis()
|
|
|
|
val closedGroupControlMessage = ClosedGroupControlMessage(ClosedGroupControlMessage.Kind.EncryptionKeyPairRequest())
|
|
|
|
val closedGroupControlMessage = ClosedGroupControlMessage(ClosedGroupControlMessage.Kind.EncryptionKeyPairRequest())
|
|
|
|
|
|
|
|
closedGroupControlMessage.sentTimestamp = sentTime
|
|
|
|
send(closedGroupControlMessage, Address.fromSerialized(groupID))
|
|
|
|
send(closedGroupControlMessage, Address.fromSerialized(groupID))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -295,6 +307,8 @@ fun MessageSender.sendLatestEncryptionKeyPair(publicKey: String, groupPublicKey:
|
|
|
|
Log.d("Loki", "Sending latest encryption key pair to: $publicKey.")
|
|
|
|
Log.d("Loki", "Sending latest encryption key pair to: $publicKey.")
|
|
|
|
val wrapper = ClosedGroupControlMessage.KeyPairWrapper(publicKey, ByteString.copyFrom(ciphertext))
|
|
|
|
val wrapper = ClosedGroupControlMessage.KeyPairWrapper(publicKey, ByteString.copyFrom(ciphertext))
|
|
|
|
val kind = ClosedGroupControlMessage.Kind.EncryptionKeyPair(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), listOf(wrapper))
|
|
|
|
val kind = ClosedGroupControlMessage.Kind.EncryptionKeyPair(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), listOf(wrapper))
|
|
|
|
|
|
|
|
val sentTime = System.currentTimeMillis()
|
|
|
|
val closedGroupControlMessage = ClosedGroupControlMessage(kind)
|
|
|
|
val closedGroupControlMessage = ClosedGroupControlMessage(kind)
|
|
|
|
|
|
|
|
closedGroupControlMessage.sentTimestamp = sentTime
|
|
|
|
MessageSender.send(closedGroupControlMessage, Address.fromSerialized(publicKey))
|
|
|
|
MessageSender.send(closedGroupControlMessage, Address.fromSerialized(publicKey))
|
|
|
|
}
|
|
|
|
}
|