diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java index 90dfedeea4..b0252aab78 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java @@ -136,7 +136,7 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt return cursor.getString(cursor.getColumnIndexOrThrow(GROUP_ID)); } else { String groupId = GroupUtil.getEncodedMMSGroupID(allocateGroupId()); - create(groupId, null, members, null, null, admins); + create(groupId, null, members, null, null, admins, System.currentTimeMillis()); return groupId; } } finally { @@ -196,7 +196,7 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt } public long create(@NonNull String groupId, @Nullable String title, @NonNull List
members, - @Nullable SignalServiceAttachmentPointer avatar, @Nullable String relay, @Nullable List admins) + @Nullable SignalServiceAttachmentPointer avatar, @Nullable String relay, @Nullable List admins, @NonNull Long formationTimestamp) { Collections.sort(members); @@ -214,7 +214,7 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt } contentValues.put(AVATAR_RELAY, relay); - contentValues.put(TIMESTAMP, System.currentTimeMillis()); + contentValues.put(TIMESTAMP, formationTimestamp); contentValues.put(ACTIVE, 1); contentValues.put(MMS, GroupUtil.isMmsGroup(groupId)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index d2cce48aa6..60d5ca84b2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -362,8 +362,8 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, return if (group.isPresent) { group.get() } else null } - override fun createGroup(groupId: String, title: String?, members: List, avatar: SignalServiceAttachmentPointer?, relay: String?, admins: List) { - DatabaseFactory.getGroupDatabase(context).create(groupId, title, members, avatar, relay, admins) + override fun createGroup(groupId: String, title: String?, members: List, avatar: SignalServiceAttachmentPointer?, relay: String?, admins: List, formationTimestamp: Long) { + DatabaseFactory.getGroupDatabase(context).create(groupId, title, members, avatar, relay, admins, formationTimestamp) } override fun setActive(groupID: String, value: Boolean) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManager.java b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManager.java index af11e476c4..3606954a89 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManager.java @@ -77,7 +77,7 @@ public class GroupManager { String masterPublicKey = masterPublicKeyOrNull != null ? masterPublicKeyOrNull : TextSecurePreferences.getLocalNumber(context); memberAddresses.add(Address.Companion.fromSerialized(masterPublicKey)); - groupDatabase.create(groupId, name, new LinkedList<>(memberAddresses), null, null, new LinkedList<>(adminAddresses)); + groupDatabase.create(groupId, name, new LinkedList<>(memberAddresses), null, null, new LinkedList<>(adminAddresses), System.currentTimeMillis()); groupDatabase.updateProfilePicture(groupId, avatarBytes); DatabaseFactory.getRecipientDatabase(context).setProfileSharing(groupRecipient, true); @@ -104,7 +104,7 @@ public class GroupManager { final Set memberAddresses = new HashSet<>(); memberAddresses.add(Address.Companion.fromSerialized(Objects.requireNonNull(TextSecurePreferences.getLocalNumber(context)))); - groupDatabase.create(groupId, name, new LinkedList<>(memberAddresses), null, null, new LinkedList<>()); + groupDatabase.create(groupId, name, new LinkedList<>(memberAddresses), null, null, new LinkedList<>(), System.currentTimeMillis()); groupDatabase.updateProfilePicture(groupId, avatarBytes); diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocolV2.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocolV2.kt index bf12e073e0..5ec16023c6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocolV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocolV2.kt @@ -69,7 +69,7 @@ object ClosedGroupsProtocolV2 { val admins = setOf( userPublicKey ) val adminsAsData = admins.map { Hex.fromStringCondensed(it) } DatabaseFactory.getGroupDatabase(context).create(groupID, name, LinkedList(members.map { Address.fromSerialized(it) }), - null, null, LinkedList(admins.map { Address.fromSerialized(it!!) })) + null, null, LinkedList(admins.map { Address.fromSerialized(it!!) }), System.currentTimeMillis()) DatabaseFactory.getRecipientDatabase(context).setProfileSharing(Recipient.from(context, Address.fromSerialized(groupID), false), true) // Send a closed group update message to all members individually // Add the group to the user's set of public keys to poll for @@ -463,7 +463,7 @@ object ClosedGroupsProtocolV2 { groupDB.updateMembers(groupID, members.map { Address.fromSerialized(it) }) } else { groupDB.create(groupID, name, LinkedList(members.map { Address.fromSerialized(it) }), - null, null, LinkedList(admins.map { Address.fromSerialized(it) })) + null, null, LinkedList(admins.map { Address.fromSerialized(it) }), sentTimestamp) } DatabaseFactory.getRecipientDatabase(context).setProfileSharing(Recipient.from(context, Address.fromSerialized(groupID), false), true) // Add the group to the user's set of public keys to poll for @@ -714,7 +714,7 @@ object ClosedGroupsProtocolV2 { senderPublicKey: String): Boolean { val oldMembers = group.members.map { it.serialize() } // Check that the message isn't from before the group was created - if (group.createdAt > sentTimestamp) { + if (group.formationTimestamp > sentTimestamp) { Log.d("Loki", "Ignoring closed group update from before thread was created.") return false } diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/MultiDeviceProtocol.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/MultiDeviceProtocol.kt index 475d842d98..5e1923a5f8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/MultiDeviceProtocol.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/MultiDeviceProtocol.kt @@ -60,7 +60,7 @@ object MultiDeviceProtocol { } } - // TODO: remove this after we migrate to new message sending pipeline + // TODO: remove this after we migrate to new message receiving pipeline @JvmStatic fun handleConfigurationMessage(context: Context, content: SignalServiceProtos.Content, senderPublicKey: String, timestamp: Long) { if (TextSecurePreferences.getConfigurationMessageSynced(context)) return diff --git a/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt b/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt index eca1e13985..484cb61c72 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt @@ -100,7 +100,7 @@ interface StorageProtocol { // Closed Groups fun getGroup(groupID: String): GroupRecord? - fun createGroup(groupID: String, title: String?, members: List, avatar: SignalServiceAttachmentPointer?, relay: String?, admins: List) + fun createGroup(groupID: String, title: String?, members: List, avatar: SignalServiceAttachmentPointer?, relay: String?, admins: List, formationTimestamp: Long) fun setActive(groupID: String, value: Boolean) fun removeMember(groupID: String, member: Address) fun updateMembers(groupID: String, members: List) diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt index fe62511562..b37c2eafe7 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt @@ -110,7 +110,7 @@ private fun MessageReceiver.handleConfigurationMessage(message: ConfigurationMes val allClosedGroupPublicKeys = storage.getAllClosedGroupPublicKeys() for (closeGroup in message.closedGroups) { if (allClosedGroupPublicKeys.contains(closeGroup.publicKey)) continue - handleNewClosedGroup(message.sender!!, closeGroup.publicKey, closeGroup.name, closeGroup.encryptionKeyPair, closeGroup.members, closeGroup.admins) + handleNewClosedGroup(message.sender!!, closeGroup.publicKey, closeGroup.name, closeGroup.encryptionKeyPair, closeGroup.members, closeGroup.admins, message.sentTimestamp!!) } val allOpenGroups = storage.getAllOpenGroups().map { it.value.server } for (openGroup in message.openGroups) { @@ -221,11 +221,11 @@ private fun MessageReceiver.handleNewClosedGroup(message: ClosedGroupControlMess val groupPublicKey = kind.publicKey.toByteArray().toHexString() val members = kind.members.map { it.toByteArray().toHexString() } val admins = kind.admins.map { it.toByteArray().toHexString() } - handleNewClosedGroup(message.sender!!, groupPublicKey, kind.name, kind.encryptionKeyPair, members, admins) + handleNewClosedGroup(message.sender!!, groupPublicKey, kind.name, kind.encryptionKeyPair, members, admins, message.sentTimestamp!!) } // Parameter @sender:String is just for inserting incoming info message -private fun handleNewClosedGroup(sender: String, groupPublicKey: String, name: String, encryptionKeyPair: ECKeyPair, members: List