From b064f8f5d73045d142b667d79d7e6c95a26a7936 Mon Sep 17 00:00:00 2001 From: Brice-W Date: Fri, 23 Apr 2021 14:07:10 +1000 Subject: [PATCH] implementation of the zombie members handling logic --- .../securesms/database/GroupDatabase.java | 48 +++++++++++++--- .../securesms/database/Storage.kt | 8 +++ .../database/helpers/SQLCipherOpenHelper.java | 7 ++- .../activities/EditClosedGroupActivity.kt | 57 +++++++++++-------- .../loki/activities/EditClosedGroupLoader.kt | 19 +++++-- .../EditClosedGroupMembersAdapter.kt | 10 ++++ .../libsession/messaging/StorageProtocol.kt | 2 + .../MessageReceiverHandler.kt | 48 ++++++++++++---- .../MessageSenderClosedGroup.kt | 30 +++++++--- 9 files changed, 169 insertions(+), 60 deletions(-) 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 790b215003..2a41b3c901 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java @@ -28,7 +28,6 @@ import org.session.libsignal.service.api.messages.SignalServiceAttachmentPointer import org.session.libsignal.service.loki.database.LokiOpenGroupDatabaseProtocol; import java.io.Closeable; -import java.io.IOException; import java.security.SecureRandom; import java.util.Collections; import java.util.LinkedList; @@ -44,6 +43,7 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt static final String GROUP_ID = "group_id"; private static final String TITLE = "title"; private static final String MEMBERS = "members"; + private static final String ZOMBIE_MEMBERS = "zombie_members"; private static final String AVATAR = "avatar"; private static final String AVATAR_ID = "avatar_id"; private static final String AVATAR_KEY = "avatar_key"; @@ -64,6 +64,7 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt GROUP_ID + " TEXT, " + TITLE + " TEXT, " + MEMBERS + " TEXT, " + + ZOMBIE_MEMBERS + " TEXT, " + AVATAR + " BLOB, " + AVATAR_ID + " INTEGER, " + AVATAR_KEY + " BLOB, " + @@ -81,7 +82,7 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt }; private static final String[] GROUP_PROJECTION = { - GROUP_ID, TITLE, MEMBERS, AVATAR, AVATAR_ID, AVATAR_KEY, AVATAR_CONTENT_TYPE, AVATAR_RELAY, AVATAR_DIGEST, + GROUP_ID, TITLE, MEMBERS, ZOMBIE_MEMBERS, AVATAR, AVATAR_ID, AVATAR_KEY, AVATAR_CONTENT_TYPE, AVATAR_RELAY, AVATAR_DIGEST, TIMESTAMP, ACTIVE, MMS, AVATAR_URL, ADMINS }; @@ -162,7 +163,7 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt } public @NonNull List getGroupMembers(String groupId, boolean includeSelf) { - List
members = getCurrentMembers(groupId); + List
members = getCurrentMembers(groupId, false); List recipients = new LinkedList<>(); for (Address member : members) { @@ -177,6 +178,19 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt return recipients; } + public @NonNull List getGroupZombieMembers(String groupId) { + List
members = getCurrentZombieMembers(groupId); + List recipients = new LinkedList<>(); + + for (Address member : members) { + if (member.isContact()) { + recipients.add(Recipient.from(context, member, false)); + } + } + + return recipients; + } + public long create(@NonNull String groupId, @Nullable String title, @NonNull List
members, @Nullable SignalServiceAttachmentPointer avatar, @Nullable String relay, @Nullable List
admins, @NonNull Long formationTimestamp) { @@ -300,6 +314,16 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt }); } + public void updateZombieMembers(String groupId, List
members) { + Collections.sort(members); + + ContentValues contents = new ContentValues(); + contents.put(ZOMBIE_MEMBERS, Address.toSerializedList(members, ',')); + contents.put(ACTIVE, 1); + databaseHelper.getWritableDatabase().update(TABLE_NAME, contents, GROUP_ID + " = ?", + new String[] {groupId}); + } + public void updateAdmins(String groupId, List
admins) { Collections.sort(admins); @@ -311,7 +335,7 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt } public void removeMember(String groupId, Address source) { - List
currentMembers = getCurrentMembers(groupId); + List
currentMembers = getCurrentMembers(groupId, false); currentMembers.remove(source); ContentValues contents = new ContentValues(); @@ -329,18 +353,22 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt }); } - private List
getCurrentMembers(String groupId) { + private List
getCurrentMembers(String groupId, boolean zombieMembers) { Cursor cursor = null; + String membersColumn = MEMBERS; + if (zombieMembers) membersColumn = ZOMBIE_MEMBERS; + try { - cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, new String[] {MEMBERS}, + cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, new String[] {membersColumn}, GROUP_ID + " = ?", new String[] {groupId}, null, null, null); if (cursor != null && cursor.moveToFirst()) { - String serializedMembers = cursor.getString(cursor.getColumnIndexOrThrow(MEMBERS)); - return Address.fromSerializedList(serializedMembers, ','); + String serializedMembers = cursor.getString(cursor.getColumnIndexOrThrow(membersColumn)); + if (serializedMembers != null && !serializedMembers.isEmpty()) + return Address.fromSerializedList(serializedMembers, ','); } return new LinkedList<>(); @@ -350,6 +378,10 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt } } + private List
getCurrentZombieMembers(String groupId) { + return getCurrentMembers(groupId, true); + } + public boolean isActive(String groupId) { Optional record = getGroup(groupId); return record.isPresent() && record.get().isActive(); 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 0a58ac42fd..9279720d6b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -395,6 +395,10 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, DatabaseFactory.getGroupDatabase(context).setActive(groupID, value) } + override fun getZombieMember(groupID: String): Set { + return DatabaseFactory.getGroupDatabase(context).getGroupZombieMembers(groupID).map { it.address.serialize() }.toHashSet() + } + override fun removeMember(groupID: String, member: Address) { DatabaseFactory.getGroupDatabase(context).removeMember(groupID, member) } @@ -403,6 +407,10 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, DatabaseFactory.getGroupDatabase(context).updateMembers(groupID, members) } + override fun updateZombieMembers(groupID: String, members: List
) { + DatabaseFactory.getGroupDatabase(context).updateZombieMembers(groupID, members) + } + override fun insertIncomingInfoMessage(context: Context, senderPublicKey: String, groupID: String, type: SignalServiceGroup.Type, name: String, members: Collection, admins: Collection, sentTimestamp: Long) { val group = SignalServiceGroup(type, GroupUtil.getDecodedGroupIDAsData(groupID), SignalServiceGroup.GroupType.SIGNAL, name, members.toList(), null, admins.toList()) val m = IncomingTextMessage(Address.fromSerialized(senderPublicKey), 1, sentTimestamp, "", Optional.of(group), 0, true) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java index 88d8c679f3..82a2044884 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java @@ -54,9 +54,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { private static final int lokiV20 = 41; private static final int lokiV21 = 42; private static final int lokiV22 = 43; + private static final int lokiV23 = 44; // Loki - onUpgrade(...) must be updated to use Loki version numbers if Signal makes any database changes - private static final int DATABASE_VERSION = lokiV22; + private static final int DATABASE_VERSION = lokiV23; private static final String DATABASE_NAME = "signal.db"; private final Context context; @@ -272,6 +273,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { "SendDeliveryReceiptJob"); } + if (oldVersion < lokiV23) { + db.execSQL("ALTER TABLE groups ADD COLUMN zombie_members TEXT"); + } + db.setTransactionSuccessful(); } finally { db.endTransaction(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/EditClosedGroupActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/EditClosedGroupActivity.kt index 7ed4385ace..80f39f099a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/EditClosedGroupActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/EditClosedGroupActivity.kt @@ -37,8 +37,13 @@ import java.io.IOException class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() { private val originalMembers = HashSet() - private val members = HashSet() private val zombies = HashSet() + private val members = HashSet() + private val allMembers: Set + get() { + return if (zombies.isNotEmpty()) (members + zombies) + else members + } private var hasNameChanged = false private var isSelfAdmin = false private var isLoading = false @@ -124,31 +129,35 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() { } } - LoaderManager.getInstance(this).initLoader(loaderID, null, object : LoaderManager.LoaderCallbacks> { + LoaderManager.getInstance(this).initLoader(loaderID, null, object : LoaderManager.LoaderCallbacks { - override fun onCreateLoader(id: Int, bundle: Bundle?): Loader> { + override fun onCreateLoader(id: Int, bundle: Bundle?): Loader { return EditClosedGroupLoader(this@EditClosedGroupActivity, groupID) } - override fun onLoadFinished(loader: Loader>, members: List) { + override fun onLoadFinished(loader: Loader, groupMembers: GroupMembers) { // We no longer need any subsequent loading events // (they will occur on every activity resume). LoaderManager.getInstance(this@EditClosedGroupActivity).destroyLoader(loaderID) + members.clear() + members.addAll(groupMembers.members.toHashSet()) + zombies.clear() + zombies.addAll(groupMembers.zombieMembers.toHashSet()) originalMembers.clear() - originalMembers.addAll(members.toHashSet()) - updateMembers(originalMembers) + originalMembers.addAll(members + zombies) + updateMembers() } - override fun onLoaderReset(loader: Loader>) { - updateMembers(setOf()) + override fun onLoaderReset(loader: Loader) { + updateMembers() } }) } override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_edit_closed_group, menu) - return members.isNotEmpty() && !isLoading + return allMembers.isNotEmpty() && !isLoading } // endregion @@ -161,8 +170,8 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() { if (data == null || data.extras == null || !data.hasExtra(SelectContactsActivity.selectedContactsKey)) return val selectedContacts = data.extras!!.getStringArray(SelectContactsActivity.selectedContactsKey)!!.toSet() - val changedMembers = members + selectedContacts - updateMembers(changedMembers) + members.addAll(selectedContacts) + updateMembers() } } } @@ -181,13 +190,12 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() { } } - private fun updateMembers(members: Set) { - this.members.clear() - this.members.addAll(members) - memberListAdapter.setMembers(members) + private fun updateMembers() { + memberListAdapter.setMembers(allMembers) + memberListAdapter.setZombieMembers(zombies) - mainContentContainer.visibility = if (members.isEmpty()) View.GONE else View.VISIBLE - emptyStateContainer.visibility = if (members.isEmpty()) View.VISIBLE else View.GONE + mainContentContainer.visibility = if (allMembers.isEmpty()) View.GONE else View.VISIBLE + emptyStateContainer.visibility = if (allMembers.isEmpty()) View.VISIBLE else View.GONE invalidateOptionsMenu() } @@ -204,8 +212,9 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() { private fun onMemberClick(member: String) { val bottomSheet = ClosedGroupEditingOptionsBottomSheet() bottomSheet.onRemoveTapped = { - val changedMembers = members - member - updateMembers(changedMembers) + if (zombies.contains(member)) zombies.remove(member) + else members.remove(member) + updateMembers() bottomSheet.dismiss() } bottomSheet.show(supportFragmentManager, "GroupEditingOptionsBottomSheet") @@ -213,7 +222,7 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() { private fun onAddMembersClick() { val intent = Intent(this@EditClosedGroupActivity, SelectContactsActivity::class.java) - intent.putExtra(SelectContactsActivity.usersToExcludeKey, members.toTypedArray()) + intent.putExtra(SelectContactsActivity.usersToExcludeKey, allMembers.toTypedArray()) intent.putExtra(SelectContactsActivity.emptyStateTextKey, "No contacts to add") startActivityForResult(intent, addUsersRequestCode) } @@ -233,7 +242,7 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() { } private fun commitChanges() { - val hasMemberListChanges = (members != originalMembers) + val hasMemberListChanges = (allMembers != originalMembers) if (!hasNameChanged && !hasMemberListChanges) { return finish() @@ -241,15 +250,13 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() { val name = if (hasNameChanged) this.name else originalName - val members = this.members.map { + val members = this.allMembers.map { Recipient.from(this, Address.fromSerialized(it), false) }.toSet() val originalMembers = this.originalMembers.map { Recipient.from(this, Address.fromSerialized(it), false) }.toSet() - val admins = members.toSet() //TODO For now, consider all the users to be admins. - var isClosedGroup: Boolean var groupPublicKey: String? try { @@ -307,4 +314,6 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() { } } } + + class GroupMembers(val members: List, val zombieMembers: List) { } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/EditClosedGroupLoader.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/EditClosedGroupLoader.kt index 4f49501fc6..d2bb17a732 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/EditClosedGroupLoader.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/EditClosedGroupLoader.kt @@ -4,12 +4,19 @@ import android.content.Context import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.util.AsyncLoader -class EditClosedGroupLoader(context: Context, val groupID: String) : AsyncLoader>(context) { +class EditClosedGroupLoader(context: Context, val groupID: String) : AsyncLoader(context) { - override fun loadInBackground(): List { - val members = DatabaseFactory.getGroupDatabase(context).getGroupMembers(groupID, true) - return members.map { - it.address.toString() - } + override fun loadInBackground(): EditClosedGroupActivity.GroupMembers { + val groupDatabase = DatabaseFactory.getGroupDatabase(context) + val members = groupDatabase.getGroupMembers(groupID, true) + val zombieMembers = groupDatabase.getGroupZombieMembers(groupID) + return EditClosedGroupActivity.GroupMembers( + members.map { + it.address.toString() + }, + zombieMembers.map { + it.address.toString() + } + ) } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/EditClosedGroupMembersAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/EditClosedGroupMembersAdapter.kt index 3dc7ff162c..63f33d9aad 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/EditClosedGroupMembersAdapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/EditClosedGroupMembersAdapter.kt @@ -17,6 +17,7 @@ class EditClosedGroupMembersAdapter( ) : RecyclerView.Adapter() { private val members = ArrayList() + private val zombieMembers = ArrayList() fun setMembers(members: Collection) { this.members.clear() @@ -24,6 +25,12 @@ class EditClosedGroupMembersAdapter( notifyDataSetChanged() } + fun setZombieMembers(members: Collection) { + this.zombieMembers.clear() + this.zombieMembers.addAll(members) + notifyDataSetChanged() + } + override fun getItemCount(): Int = members.size override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { @@ -42,6 +49,9 @@ class EditClosedGroupMembersAdapter( glide, if (unlocked) UserView.ActionIndicator.Menu else UserView.ActionIndicator.None) + if (zombieMembers.contains(member)) + viewHolder.view.alpha = 0.5F + if (unlocked) { viewHolder.view.setOnClickListener { this.memberClickListener?.invoke(member) } } 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 da84c8f6e8..80012b8ec1 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt @@ -109,8 +109,10 @@ interface StorageProtocol { fun createGroup(groupID: String, title: String?, members: List
, avatar: SignalServiceAttachmentPointer?, relay: String?, admins: List
, formationTimestamp: Long) fun isGroupActive(groupPublicKey: String): Boolean fun setActive(groupID: String, value: Boolean) + fun getZombieMember(groupID: String): Set fun removeMember(groupID: String, member: Address) fun updateMembers(groupID: String, members: List
) + fun updateZombieMembers(groupID: String, members: List
) // Closed Group fun getAllClosedGroupPublicKeys(): Set fun getAllActiveClosedGroupPublicKeys(): Set 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 fc1b28e1cc..185befb9bd 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 @@ -355,7 +355,7 @@ private fun MessageReceiver.handleClosedGroupEncryptionKeyPair(message: ClosedGr return } if (!group.admins.map { it.toString() }.contains(senderPublicKey)) { - Log.d("Loki", "Ignoring closed group encryption key pair from non-member.") + Log.d("Loki", "Ignoring closed group encryption key pair from non-admin.") return } // Find our wrapper and decrypt it if possible @@ -458,6 +458,11 @@ private fun MessageReceiver.handleClosedGroupMembersAdded(message: ClosedGroupCo } } +/// Removes the given members from the group IF +/// • it wasn't the admin that was removed (that should happen through a `MEMBER_LEFT` message). +/// • the admin sent the message (only the admin can truly remove members). +/// If we're among the users that were removed, delete all encryption key pairs and the group public key, unsubscribe +/// from push notifications for this closed group, and remove the given members from the zombie list for this group. private fun MessageReceiver.handleClosedGroupMembersRemoved(message: ClosedGroupControlMessage) { val context = MessagingConfiguration.shared.context val storage = MessagingConfiguration.shared.storage @@ -471,7 +476,7 @@ private fun MessageReceiver.handleClosedGroupMembersRemoved(message: ClosedGroup return } if (!group.isActive) { - Log.d("Loki", "Ignoring closed group info message for inactive group") + Log.d("Loki", "Ignoring closed group info message for inactive group.") return } val name = group.title @@ -482,6 +487,18 @@ private fun MessageReceiver.handleClosedGroupMembersRemoved(message: ClosedGroup // Users that are part of this remove update val updateMembers = kind.members.map { it.toByteArray().toHexString() } + // Check that the admin wasn't removed + if (updateMembers.contains(admins.first())) { + Log.d("Loki", "Ignoring invalid closed group update.") + return + } + + // Check that the message was sent by the group admin + if (!admins.contains(senderPublicKey)) { + Log.d("Loki", "Ignoring invalid closed group update.") + return + } + if (!isValidGroupUpdate(group, message.sentTimestamp!!, senderPublicKey)) { return } // If admin leaves the group is disbanded val didAdminLeave = admins.any { it in updateMembers } @@ -498,12 +515,12 @@ private fun MessageReceiver.handleClosedGroupMembersRemoved(message: ClosedGroup if (didAdminLeave || wasCurrentUserRemoved) { disableLocalGroupAndUnsubscribe(groupPublicKey, groupID, userPublicKey) } else { - val isCurrentUserAdmin = admins.contains(userPublicKey) storage.updateMembers(groupID, newMembers.map { Address.fromSerialized(it) }) - if (isCurrentUserAdmin) { - MessageSender.generateAndSendNewEncryptionKeyPair(groupPublicKey, newMembers) - } } + // update zombie members + val zombies = storage.getZombieMember(groupID) + storage.updateZombieMembers(groupID, zombies.minus(updateMembers).map { Address.fromSerialized(it) }) + val type = if (senderLeft) SignalServiceGroup.Type.QUIT else SignalServiceGroup.Type.MEMBER_REMOVED @@ -517,6 +534,10 @@ private fun MessageReceiver.handleClosedGroupMembersRemoved(message: ClosedGroup } } +/// If a regular member left: +/// • Mark them as a zombie (to be removed by the admin later). +/// If the admin left: +/// • Unsubscribe from PNs, delete the group public key, etc. as the group will be disbanded. private fun MessageReceiver.handleClosedGroupMemberLeft(message: ClosedGroupControlMessage) { val context = MessagingConfiguration.shared.context val storage = MessagingConfiguration.shared.storage @@ -549,11 +570,14 @@ private fun MessageReceiver.handleClosedGroupMemberLeft(message: ClosedGroupCont // admin left the group of linked device left the group disableLocalGroupAndUnsubscribe(groupPublicKey, groupID, userPublicKey) } else { - val isCurrentUserAdmin = admins.contains(userPublicKey) + //val isCurrentUserAdmin = admins.contains(userPublicKey) storage.updateMembers(groupID, updatedMemberList.map { Address.fromSerialized(it) }) - if (isCurrentUserAdmin) { - MessageSender.generateAndSendNewEncryptionKeyPair(groupPublicKey, updatedMemberList) - } + //if (isCurrentUserAdmin) { + // MessageSender.generateAndSendNewEncryptionKeyPair(groupPublicKey, updatedMemberList) + //} + // update zombie members + val zombies = storage.getZombieMember(groupID) + storage.updateZombieMembers(groupID, zombies.plus(senderPublicKey).map { Address.fromSerialized(it) }) } // Notify the user if (userLeft) { @@ -566,7 +590,7 @@ private fun MessageReceiver.handleClosedGroupMemberLeft(message: ClosedGroupCont } private fun MessageReceiver.handleClosedGroupEncryptionKeyPairRequest(message: ClosedGroupControlMessage) { - val storage = MessagingConfiguration.shared.storage + /*val storage = MessagingConfiguration.shared.storage val senderPublicKey = message.sender ?: return val userPublicKey = storage.getUserPublicKey()!! if (message.kind!! !is ClosedGroupControlMessage.Kind.EncryptionKeyPairRequest) return @@ -587,7 +611,7 @@ private fun MessageReceiver.handleClosedGroupEncryptionKeyPairRequest(message: C Log.d("Loki", "Couldn't get encryption key pair for closed group.") } else { MessageSender.sendEncryptionKeyPair(groupPublicKey, encryptionKeyPair, setOf(senderPublicKey), targetUser = senderPublicKey, force = false) - } + }*/ } private fun isValidGroupUpdate(group: GroupRecord, diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroup.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroup.kt index 143fa7fb3f..8e3622282b 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroup.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroup.kt @@ -169,15 +169,24 @@ fun MessageSender.removeMembers(groupPublicKey: String, membersToRemove: List