mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-17 13:28:26 +00:00
Merge branch 'dev' into ui
This commit is contained in:
commit
2188200717
@ -308,6 +308,13 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt
|
|||||||
databaseHelper.getWritableDatabase().update(TABLE_NAME, contents, GROUP_ID + " = ?", new String[] {groupId});
|
databaseHelper.getWritableDatabase().update(TABLE_NAME, contents, GROUP_ID + " = ?", new String[] {groupId});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateFormationTimestamp(String groupId, Long formationTimestamp) {
|
||||||
|
ContentValues contents = new ContentValues();
|
||||||
|
contents.put(TIMESTAMP, formationTimestamp);
|
||||||
|
|
||||||
|
databaseHelper.getWritableDatabase().update(TABLE_NAME, contents, GROUP_ID + " = ?", new String[] {groupId});
|
||||||
|
}
|
||||||
|
|
||||||
public void removeMember(String groupId, Address source) {
|
public void removeMember(String groupId, Address source) {
|
||||||
List<Address> currentMembers = getCurrentMembers(groupId, false);
|
List<Address> currentMembers = getCurrentMembers(groupId, false);
|
||||||
currentMembers.remove(source);
|
currentMembers.remove(source);
|
||||||
|
@ -428,6 +428,11 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
|||||||
DatabaseFactory.getLokiAPIDatabase(context).removeAllClosedGroupEncryptionKeyPairs(groupPublicKey)
|
DatabaseFactory.getLokiAPIDatabase(context).removeAllClosedGroupEncryptionKeyPairs(groupPublicKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun updateFormationTimestamp(groupID: String, formationTimestamp: Long) {
|
||||||
|
DatabaseFactory.getGroupDatabase(context)
|
||||||
|
.updateFormationTimestamp(groupID, formationTimestamp)
|
||||||
|
}
|
||||||
|
|
||||||
override fun setExpirationTimer(groupID: String, duration: Int) {
|
override fun setExpirationTimer(groupID: String, duration: Int) {
|
||||||
val recipient = Recipient.from(context, fromSerialized(groupID), false)
|
val recipient = Recipient.from(context, fromSerialized(groupID), false)
|
||||||
DatabaseFactory.getRecipientDatabase(context).setExpireMessages(recipient, duration);
|
DatabaseFactory.getRecipientDatabase(context).setExpireMessages(recipient, duration);
|
||||||
|
@ -56,6 +56,8 @@ class EditClosedGroupMembersAdapter(
|
|||||||
|
|
||||||
if (unlocked) {
|
if (unlocked) {
|
||||||
viewHolder.view.setOnClickListener { this.memberClickListener?.invoke(member) }
|
viewHolder.view.setOnClickListener { this.memberClickListener?.invoke(member) }
|
||||||
|
} else {
|
||||||
|
viewHolder.view.setOnClickListener(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +115,7 @@ interface StorageProtocol {
|
|||||||
fun isClosedGroup(publicKey: String): Boolean
|
fun isClosedGroup(publicKey: String): Boolean
|
||||||
fun getClosedGroupEncryptionKeyPairs(groupPublicKey: String): MutableList<ECKeyPair>
|
fun getClosedGroupEncryptionKeyPairs(groupPublicKey: String): MutableList<ECKeyPair>
|
||||||
fun getLatestClosedGroupEncryptionKeyPair(groupPublicKey: String): ECKeyPair?
|
fun getLatestClosedGroupEncryptionKeyPair(groupPublicKey: String): ECKeyPair?
|
||||||
|
fun updateFormationTimestamp(groupID: String, formationTimestamp: Long)
|
||||||
fun setExpirationTimer(groupID: String, duration: Int)
|
fun setExpirationTimer(groupID: String, duration: Int)
|
||||||
|
|
||||||
// Groups
|
// Groups
|
||||||
|
@ -161,7 +161,13 @@ fun MessageSender.addMembers(groupPublicKey: String, membersToAdd: List<String>)
|
|||||||
for (member in membersToAdd) {
|
for (member in membersToAdd) {
|
||||||
val closedGroupNewKind = ClosedGroupControlMessage.Kind.New(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), name, encryptionKeyPair, membersAsData, adminsAsData, expireTimer)
|
val closedGroupNewKind = ClosedGroupControlMessage.Kind.New(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), name, encryptionKeyPair, membersAsData, adminsAsData, expireTimer)
|
||||||
val closedGroupControlMessage = ClosedGroupControlMessage(closedGroupNewKind)
|
val closedGroupControlMessage = ClosedGroupControlMessage(closedGroupNewKind)
|
||||||
closedGroupControlMessage.sentTimestamp = sentTime
|
// It's important that the sent timestamp of this message is greater than the sent timestamp
|
||||||
|
// of the `MembersAdded` message above. The reason is that upon receiving this `New` message,
|
||||||
|
// the recipient will update the closed group formation timestamp and ignore any closed group
|
||||||
|
// updates from before that timestamp. By setting the timestamp of the message below to a value
|
||||||
|
// greater than that of the `MembersAdded` message, we ensure that newly added members ignore
|
||||||
|
// the `MembersAdded` message.
|
||||||
|
closedGroupControlMessage.sentTimestamp = System.currentTimeMillis()
|
||||||
send(closedGroupControlMessage, Address.fromSerialized(member))
|
send(closedGroupControlMessage, Address.fromSerialized(member))
|
||||||
}
|
}
|
||||||
// Notify the user
|
// Notify the user
|
||||||
|
@ -263,27 +263,22 @@ private fun MessageReceiver.handleNewClosedGroup(message: ClosedGroupControlMess
|
|||||||
private fun handleNewClosedGroup(sender: String, sentTimestamp: Long, groupPublicKey: String, name: String, encryptionKeyPair: ECKeyPair, members: List<String>, admins: List<String>, formationTimestamp: Long, expireTimer: Int) {
|
private fun handleNewClosedGroup(sender: String, sentTimestamp: Long, groupPublicKey: String, name: String, encryptionKeyPair: ECKeyPair, members: List<String>, admins: List<String>, formationTimestamp: Long, expireTimer: Int) {
|
||||||
val context = MessagingModuleConfiguration.shared.context
|
val context = MessagingModuleConfiguration.shared.context
|
||||||
val storage = MessagingModuleConfiguration.shared.storage
|
val storage = MessagingModuleConfiguration.shared.storage
|
||||||
|
val userPublicKey = TextSecurePreferences.getLocalNumber(context)
|
||||||
// Create the group
|
// Create the group
|
||||||
val groupID = GroupUtil.doubleEncodeGroupID(groupPublicKey)
|
val groupID = GroupUtil.doubleEncodeGroupID(groupPublicKey)
|
||||||
if (storage.getGroup(groupID) != null) {
|
if (storage.getGroup(groupID) != null) {
|
||||||
// Update the group
|
// Update the group
|
||||||
// Clear zombie list if the group wasn't active
|
|
||||||
if (!storage.isGroupActive(groupPublicKey)) {
|
if (!storage.isGroupActive(groupPublicKey)) {
|
||||||
|
// Clear zombie list if the group wasn't active
|
||||||
storage.setZombieMembers(groupID, listOf())
|
storage.setZombieMembers(groupID, listOf())
|
||||||
|
// Update the formation timestamp
|
||||||
|
storage.updateFormationTimestamp(groupID, formationTimestamp)
|
||||||
}
|
}
|
||||||
storage.updateTitle(groupID, name)
|
storage.updateTitle(groupID, name)
|
||||||
storage.updateMembers(groupID, members.map { Address.fromSerialized(it) })
|
storage.updateMembers(groupID, members.map { Address.fromSerialized(it) })
|
||||||
} else {
|
} else {
|
||||||
storage.createGroup(groupID, name, LinkedList(members.map { Address.fromSerialized(it) }),
|
storage.createGroup(groupID, name, LinkedList(members.map { Address.fromSerialized(it) }),
|
||||||
null, null, LinkedList(admins.map { Address.fromSerialized(it) }), formationTimestamp)
|
null, null, LinkedList(admins.map { Address.fromSerialized(it) }), formationTimestamp)
|
||||||
val userPublicKey = TextSecurePreferences.getLocalNumber(context)
|
|
||||||
// Notify the user
|
|
||||||
if (userPublicKey == sender) {
|
|
||||||
val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID))
|
|
||||||
storage.insertOutgoingInfoMessage(context, groupID, SignalServiceGroup.Type.CREATION, name, members, admins, threadID, sentTimestamp)
|
|
||||||
} else {
|
|
||||||
storage.insertIncomingInfoMessage(context, sender, groupID, SignalServiceGroup.Type.CREATION, name, members, admins, sentTimestamp)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
storage.setProfileSharing(Address.fromSerialized(groupID), true)
|
storage.setProfileSharing(Address.fromSerialized(groupID), true)
|
||||||
// Add the group to the user's set of public keys to poll for
|
// Add the group to the user's set of public keys to poll for
|
||||||
@ -294,6 +289,13 @@ private fun handleNewClosedGroup(sender: String, sentTimestamp: Long, groupPubli
|
|||||||
storage.setExpirationTimer(groupID, expireTimer)
|
storage.setExpirationTimer(groupID, expireTimer)
|
||||||
// Notify the PN server
|
// Notify the PN server
|
||||||
PushNotificationAPI.performOperation(PushNotificationAPI.ClosedGroupOperation.Subscribe, groupPublicKey, storage.getUserPublicKey()!!)
|
PushNotificationAPI.performOperation(PushNotificationAPI.ClosedGroupOperation.Subscribe, groupPublicKey, storage.getUserPublicKey()!!)
|
||||||
|
// Notify the user
|
||||||
|
if (userPublicKey == sender) {
|
||||||
|
val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID))
|
||||||
|
storage.insertOutgoingInfoMessage(context, groupID, SignalServiceGroup.Type.CREATION, name, members, admins, threadID, sentTimestamp)
|
||||||
|
} else {
|
||||||
|
storage.insertIncomingInfoMessage(context, sender, groupID, SignalServiceGroup.Type.CREATION, name, members, admins, sentTimestamp)
|
||||||
|
}
|
||||||
// Start polling
|
// Start polling
|
||||||
ClosedGroupPollerV2.shared.startPolling(groupPublicKey)
|
ClosedGroupPollerV2.shared.startPolling(groupPublicKey)
|
||||||
}
|
}
|
||||||
@ -427,7 +429,7 @@ private fun MessageReceiver.handleClosedGroupMembersAdded(message: ClosedGroupCo
|
|||||||
val encryptionKeyPair = pendingKeyPairs[groupPublicKey]?.orNull()
|
val encryptionKeyPair = pendingKeyPairs[groupPublicKey]?.orNull()
|
||||||
?: storage.getLatestClosedGroupEncryptionKeyPair(groupPublicKey)
|
?: storage.getLatestClosedGroupEncryptionKeyPair(groupPublicKey)
|
||||||
if (encryptionKeyPair == null) {
|
if (encryptionKeyPair == null) {
|
||||||
android.util.Log.d("Loki", "Couldn't get encryption key pair for closed group.")
|
Log.d("Loki", "Couldn't get encryption key pair for closed group.")
|
||||||
} else {
|
} else {
|
||||||
for (user in updateMembers) {
|
for (user in updateMembers) {
|
||||||
MessageSender.sendEncryptionKeyPair(groupPublicKey, encryptionKeyPair, setOf(user), targetUser = user, force = false)
|
MessageSender.sendEncryptionKeyPair(groupPublicKey, encryptionKeyPair, setOf(user), targetUser = user, force = false)
|
||||||
@ -559,12 +561,12 @@ private fun isValidGroupUpdate(group: GroupRecord, sentTimestamp: Long, senderPu
|
|||||||
val oldMembers = group.members.map { it.serialize() }
|
val oldMembers = group.members.map { it.serialize() }
|
||||||
// Check that the message isn't from before the group was created
|
// Check that the message isn't from before the group was created
|
||||||
if (group.formationTimestamp > sentTimestamp) {
|
if (group.formationTimestamp > sentTimestamp) {
|
||||||
android.util.Log.d("Loki", "Ignoring closed group update from before thread was created.")
|
Log.d("Loki", "Ignoring closed group update from before thread was created.")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// Check that the sender is a member of the group (before the update)
|
// Check that the sender is a member of the group (before the update)
|
||||||
if (senderPublicKey !in oldMembers) {
|
if (senderPublicKey !in oldMembers) {
|
||||||
android.util.Log.d("Loki", "Ignoring closed group info message from non-member.")
|
Log.d("Loki", "Ignoring closed group info message from non-member.")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user