From 5c9ddef19bef09e7a5eeb5f7b7973f9e2d070be6 Mon Sep 17 00:00:00 2001 From: Brice-W Date: Wed, 21 Apr 2021 14:45:42 +1000 Subject: [PATCH 01/15] clean proto --- libsignal/protobuf/SignalService.proto | 6 - .../internal/push/SignalServiceProtos.java | 513 +----------------- 2 files changed, 20 insertions(+), 499 deletions(-) diff --git a/libsignal/protobuf/SignalService.proto b/libsignal/protobuf/SignalService.proto index 614b5e65f2..17379e82fd 100644 --- a/libsignal/protobuf/SignalService.proto +++ b/libsignal/protobuf/SignalService.proto @@ -304,12 +304,6 @@ message GroupContext { repeated string members = 4; optional AttachmentPointer avatar = 5; repeated string admins = 6; - - // Loki - These fields are only used internally for the Android code base. - // This is so that we can differentiate adding/kicking. - // DO NOT USE WHEN SENDING MESSAGES. - repeated string newMembers = 998; - repeated string removedMembers = 999; } message ContactDetails { diff --git a/libsignal/src/main/java/org/session/libsignal/service/internal/push/SignalServiceProtos.java b/libsignal/src/main/java/org/session/libsignal/service/internal/push/SignalServiceProtos.java index 0e4feba1ed..bd6b30747f 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/internal/push/SignalServiceProtos.java +++ b/libsignal/src/main/java/org/session/libsignal/service/internal/push/SignalServiceProtos.java @@ -26967,70 +26967,6 @@ public final class SignalServiceProtos { */ com.google.protobuf.ByteString getAdminsBytes(int index); - - // repeated string newMembers = 998; - /** - * repeated string newMembers = 998; - * - *
-     * Loki - These fields are only used internally for the Android code base.
-     * This is so that we can differentiate adding/kicking.
-     * DO NOT USE WHEN SENDING MESSAGES.
-     * 
- */ - java.util.List - getNewMembersList(); - /** - * repeated string newMembers = 998; - * - *
-     * Loki - These fields are only used internally for the Android code base.
-     * This is so that we can differentiate adding/kicking.
-     * DO NOT USE WHEN SENDING MESSAGES.
-     * 
- */ - int getNewMembersCount(); - /** - * repeated string newMembers = 998; - * - *
-     * Loki - These fields are only used internally for the Android code base.
-     * This is so that we can differentiate adding/kicking.
-     * DO NOT USE WHEN SENDING MESSAGES.
-     * 
- */ - java.lang.String getNewMembers(int index); - /** - * repeated string newMembers = 998; - * - *
-     * Loki - These fields are only used internally for the Android code base.
-     * This is so that we can differentiate adding/kicking.
-     * DO NOT USE WHEN SENDING MESSAGES.
-     * 
- */ - com.google.protobuf.ByteString - getNewMembersBytes(int index); - - // repeated string removedMembers = 999; - /** - * repeated string removedMembers = 999; - */ - java.util.List - getRemovedMembersList(); - /** - * repeated string removedMembers = 999; - */ - int getRemovedMembersCount(); - /** - * repeated string removedMembers = 999; - */ - java.lang.String getRemovedMembers(int index); - /** - * repeated string removedMembers = 999; - */ - com.google.protobuf.ByteString - getRemovedMembersBytes(int index); } /** * Protobuf type {@code signalservice.GroupContext} @@ -27133,22 +27069,6 @@ public final class SignalServiceProtos { admins_.add(input.readBytes()); break; } - case 7986: { - if (!((mutable_bitField0_ & 0x00000040) == 0x00000040)) { - newMembers_ = new com.google.protobuf.LazyStringArrayList(); - mutable_bitField0_ |= 0x00000040; - } - newMembers_.add(input.readBytes()); - break; - } - case 7994: { - if (!((mutable_bitField0_ & 0x00000080) == 0x00000080)) { - removedMembers_ = new com.google.protobuf.LazyStringArrayList(); - mutable_bitField0_ |= 0x00000080; - } - removedMembers_.add(input.readBytes()); - break; - } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { @@ -27163,12 +27083,6 @@ public final class SignalServiceProtos { if (((mutable_bitField0_ & 0x00000020) == 0x00000020)) { admins_ = new com.google.protobuf.UnmodifiableLazyStringList(admins_); } - if (((mutable_bitField0_ & 0x00000040) == 0x00000040)) { - newMembers_ = new com.google.protobuf.UnmodifiableLazyStringList(newMembers_); - } - if (((mutable_bitField0_ & 0x00000080) == 0x00000080)) { - removedMembers_ = new com.google.protobuf.UnmodifiableLazyStringList(removedMembers_); - } this.unknownFields = unknownFields.build(); makeExtensionsImmutable(); } @@ -27483,90 +27397,6 @@ public final class SignalServiceProtos { return admins_.getByteString(index); } - // repeated string newMembers = 998; - public static final int NEWMEMBERS_FIELD_NUMBER = 998; - private com.google.protobuf.LazyStringList newMembers_; - /** - * repeated string newMembers = 998; - * - *
-     * Loki - These fields are only used internally for the Android code base.
-     * This is so that we can differentiate adding/kicking.
-     * DO NOT USE WHEN SENDING MESSAGES.
-     * 
- */ - public java.util.List - getNewMembersList() { - return newMembers_; - } - /** - * repeated string newMembers = 998; - * - *
-     * Loki - These fields are only used internally for the Android code base.
-     * This is so that we can differentiate adding/kicking.
-     * DO NOT USE WHEN SENDING MESSAGES.
-     * 
- */ - public int getNewMembersCount() { - return newMembers_.size(); - } - /** - * repeated string newMembers = 998; - * - *
-     * Loki - These fields are only used internally for the Android code base.
-     * This is so that we can differentiate adding/kicking.
-     * DO NOT USE WHEN SENDING MESSAGES.
-     * 
- */ - public java.lang.String getNewMembers(int index) { - return newMembers_.get(index); - } - /** - * repeated string newMembers = 998; - * - *
-     * Loki - These fields are only used internally for the Android code base.
-     * This is so that we can differentiate adding/kicking.
-     * DO NOT USE WHEN SENDING MESSAGES.
-     * 
- */ - public com.google.protobuf.ByteString - getNewMembersBytes(int index) { - return newMembers_.getByteString(index); - } - - // repeated string removedMembers = 999; - public static final int REMOVEDMEMBERS_FIELD_NUMBER = 999; - private com.google.protobuf.LazyStringList removedMembers_; - /** - * repeated string removedMembers = 999; - */ - public java.util.List - getRemovedMembersList() { - return removedMembers_; - } - /** - * repeated string removedMembers = 999; - */ - public int getRemovedMembersCount() { - return removedMembers_.size(); - } - /** - * repeated string removedMembers = 999; - */ - public java.lang.String getRemovedMembers(int index) { - return removedMembers_.get(index); - } - /** - * repeated string removedMembers = 999; - */ - public com.google.protobuf.ByteString - getRemovedMembersBytes(int index) { - return removedMembers_.getByteString(index); - } - private void initFields() { id_ = com.google.protobuf.ByteString.EMPTY; type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.GroupContext.Type.UNKNOWN; @@ -27574,8 +27404,6 @@ public final class SignalServiceProtos { members_ = com.google.protobuf.LazyStringArrayList.EMPTY; avatar_ = org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer.getDefaultInstance(); admins_ = com.google.protobuf.LazyStringArrayList.EMPTY; - newMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; - removedMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { @@ -27607,12 +27435,6 @@ public final class SignalServiceProtos { for (int i = 0; i < admins_.size(); i++) { output.writeBytes(6, admins_.getByteString(i)); } - for (int i = 0; i < newMembers_.size(); i++) { - output.writeBytes(998, newMembers_.getByteString(i)); - } - for (int i = 0; i < removedMembers_.size(); i++) { - output.writeBytes(999, removedMembers_.getByteString(i)); - } getUnknownFields().writeTo(output); } @@ -27656,24 +27478,6 @@ public final class SignalServiceProtos { size += dataSize; size += 1 * getAdminsList().size(); } - { - int dataSize = 0; - for (int i = 0; i < newMembers_.size(); i++) { - dataSize += com.google.protobuf.CodedOutputStream - .computeBytesSizeNoTag(newMembers_.getByteString(i)); - } - size += dataSize; - size += 2 * getNewMembersList().size(); - } - { - int dataSize = 0; - for (int i = 0; i < removedMembers_.size(); i++) { - dataSize += com.google.protobuf.CodedOutputStream - .computeBytesSizeNoTag(removedMembers_.getByteString(i)); - } - size += dataSize; - size += 2 * getRemovedMembersList().size(); - } size += getUnknownFields().getSerializedSize(); memoizedSerializedSize = size; return size; @@ -27807,10 +27611,6 @@ public final class SignalServiceProtos { bitField0_ = (bitField0_ & ~0x00000010); admins_ = com.google.protobuf.LazyStringArrayList.EMPTY; bitField0_ = (bitField0_ & ~0x00000020); - newMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; - bitField0_ = (bitField0_ & ~0x00000040); - removedMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; - bitField0_ = (bitField0_ & ~0x00000080); return this; } @@ -27871,18 +27671,6 @@ public final class SignalServiceProtos { bitField0_ = (bitField0_ & ~0x00000020); } result.admins_ = admins_; - if (((bitField0_ & 0x00000040) == 0x00000040)) { - newMembers_ = new com.google.protobuf.UnmodifiableLazyStringList( - newMembers_); - bitField0_ = (bitField0_ & ~0x00000040); - } - result.newMembers_ = newMembers_; - if (((bitField0_ & 0x00000080) == 0x00000080)) { - removedMembers_ = new com.google.protobuf.UnmodifiableLazyStringList( - removedMembers_); - bitField0_ = (bitField0_ & ~0x00000080); - } - result.removedMembers_ = removedMembers_; result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -27933,26 +27721,6 @@ public final class SignalServiceProtos { } onChanged(); } - if (!other.newMembers_.isEmpty()) { - if (newMembers_.isEmpty()) { - newMembers_ = other.newMembers_; - bitField0_ = (bitField0_ & ~0x00000040); - } else { - ensureNewMembersIsMutable(); - newMembers_.addAll(other.newMembers_); - } - onChanged(); - } - if (!other.removedMembers_.isEmpty()) { - if (removedMembers_.isEmpty()) { - removedMembers_ = other.removedMembers_; - bitField0_ = (bitField0_ & ~0x00000080); - } else { - ensureRemovedMembersIsMutable(); - removedMembers_.addAll(other.removedMembers_); - } - onChanged(); - } this.mergeUnknownFields(other.getUnknownFields()); return this; } @@ -28461,246 +28229,6 @@ public final class SignalServiceProtos { return this; } - // repeated string newMembers = 998; - private com.google.protobuf.LazyStringList newMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; - private void ensureNewMembersIsMutable() { - if (!((bitField0_ & 0x00000040) == 0x00000040)) { - newMembers_ = new com.google.protobuf.LazyStringArrayList(newMembers_); - bitField0_ |= 0x00000040; - } - } - /** - * repeated string newMembers = 998; - * - *
-       * Loki - These fields are only used internally for the Android code base.
-       * This is so that we can differentiate adding/kicking.
-       * DO NOT USE WHEN SENDING MESSAGES.
-       * 
- */ - public java.util.List - getNewMembersList() { - return java.util.Collections.unmodifiableList(newMembers_); - } - /** - * repeated string newMembers = 998; - * - *
-       * Loki - These fields are only used internally for the Android code base.
-       * This is so that we can differentiate adding/kicking.
-       * DO NOT USE WHEN SENDING MESSAGES.
-       * 
- */ - public int getNewMembersCount() { - return newMembers_.size(); - } - /** - * repeated string newMembers = 998; - * - *
-       * Loki - These fields are only used internally for the Android code base.
-       * This is so that we can differentiate adding/kicking.
-       * DO NOT USE WHEN SENDING MESSAGES.
-       * 
- */ - public java.lang.String getNewMembers(int index) { - return newMembers_.get(index); - } - /** - * repeated string newMembers = 998; - * - *
-       * Loki - These fields are only used internally for the Android code base.
-       * This is so that we can differentiate adding/kicking.
-       * DO NOT USE WHEN SENDING MESSAGES.
-       * 
- */ - public com.google.protobuf.ByteString - getNewMembersBytes(int index) { - return newMembers_.getByteString(index); - } - /** - * repeated string newMembers = 998; - * - *
-       * Loki - These fields are only used internally for the Android code base.
-       * This is so that we can differentiate adding/kicking.
-       * DO NOT USE WHEN SENDING MESSAGES.
-       * 
- */ - public Builder setNewMembers( - int index, java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - ensureNewMembersIsMutable(); - newMembers_.set(index, value); - onChanged(); - return this; - } - /** - * repeated string newMembers = 998; - * - *
-       * Loki - These fields are only used internally for the Android code base.
-       * This is so that we can differentiate adding/kicking.
-       * DO NOT USE WHEN SENDING MESSAGES.
-       * 
- */ - public Builder addNewMembers( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - ensureNewMembersIsMutable(); - newMembers_.add(value); - onChanged(); - return this; - } - /** - * repeated string newMembers = 998; - * - *
-       * Loki - These fields are only used internally for the Android code base.
-       * This is so that we can differentiate adding/kicking.
-       * DO NOT USE WHEN SENDING MESSAGES.
-       * 
- */ - public Builder addAllNewMembers( - java.lang.Iterable values) { - ensureNewMembersIsMutable(); - super.addAll(values, newMembers_); - onChanged(); - return this; - } - /** - * repeated string newMembers = 998; - * - *
-       * Loki - These fields are only used internally for the Android code base.
-       * This is so that we can differentiate adding/kicking.
-       * DO NOT USE WHEN SENDING MESSAGES.
-       * 
- */ - public Builder clearNewMembers() { - newMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; - bitField0_ = (bitField0_ & ~0x00000040); - onChanged(); - return this; - } - /** - * repeated string newMembers = 998; - * - *
-       * Loki - These fields are only used internally for the Android code base.
-       * This is so that we can differentiate adding/kicking.
-       * DO NOT USE WHEN SENDING MESSAGES.
-       * 
- */ - public Builder addNewMembersBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - ensureNewMembersIsMutable(); - newMembers_.add(value); - onChanged(); - return this; - } - - // repeated string removedMembers = 999; - private com.google.protobuf.LazyStringList removedMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; - private void ensureRemovedMembersIsMutable() { - if (!((bitField0_ & 0x00000080) == 0x00000080)) { - removedMembers_ = new com.google.protobuf.LazyStringArrayList(removedMembers_); - bitField0_ |= 0x00000080; - } - } - /** - * repeated string removedMembers = 999; - */ - public java.util.List - getRemovedMembersList() { - return java.util.Collections.unmodifiableList(removedMembers_); - } - /** - * repeated string removedMembers = 999; - */ - public int getRemovedMembersCount() { - return removedMembers_.size(); - } - /** - * repeated string removedMembers = 999; - */ - public java.lang.String getRemovedMembers(int index) { - return removedMembers_.get(index); - } - /** - * repeated string removedMembers = 999; - */ - public com.google.protobuf.ByteString - getRemovedMembersBytes(int index) { - return removedMembers_.getByteString(index); - } - /** - * repeated string removedMembers = 999; - */ - public Builder setRemovedMembers( - int index, java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - ensureRemovedMembersIsMutable(); - removedMembers_.set(index, value); - onChanged(); - return this; - } - /** - * repeated string removedMembers = 999; - */ - public Builder addRemovedMembers( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - ensureRemovedMembersIsMutable(); - removedMembers_.add(value); - onChanged(); - return this; - } - /** - * repeated string removedMembers = 999; - */ - public Builder addAllRemovedMembers( - java.lang.Iterable values) { - ensureRemovedMembersIsMutable(); - super.addAll(values, removedMembers_); - onChanged(); - return this; - } - /** - * repeated string removedMembers = 999; - */ - public Builder clearRemovedMembers() { - removedMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; - bitField0_ = (bitField0_ & ~0x00000080); - onChanged(); - return this; - } - /** - * repeated string removedMembers = 999; - */ - public Builder addRemovedMembersBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - ensureRemovedMembersIsMutable(); - removedMembers_.add(value); - onChanged(); - return this; - } - // @@protoc_insertion_point(builder_scope:signalservice.GroupContext) } @@ -33464,29 +32992,28 @@ public final class SignalServiceProtos { "\020\n\010fileName\030\007 \001(\t\022\r\n\005flags\030\010 \001(\r\022\r\n\005widt", "h\030\t \001(\r\022\016\n\006height\030\n \001(\r\022\017\n\007caption\030\013 \001(\t" + "\022\013\n\003url\030e \001(\t\"\032\n\005Flags\022\021\n\rVOICE_MESSAGE\020" + - "\001\"\243\002\n\014GroupContext\022\n\n\002id\030\001 \001(\014\022.\n\004type\030\002" + + "\001\"\365\001\n\014GroupContext\022\n\n\002id\030\001 \001(\014\022.\n\004type\030\002" + " \001(\0162 .signalservice.GroupContext.Type\022\014" + "\n\004name\030\003 \001(\t\022\017\n\007members\030\004 \003(\t\0220\n\006avatar\030" + "\005 \001(\0132 .signalservice.AttachmentPointer\022" + - "\016\n\006admins\030\006 \003(\t\022\023\n\nnewMembers\030\346\007 \003(\t\022\027\n\016" + - "removedMembers\030\347\007 \003(\t\"H\n\004Type\022\013\n\007UNKNOWN" + - "\020\000\022\n\n\006UPDATE\020\001\022\013\n\007DELIVER\020\002\022\010\n\004QUIT\020\003\022\020\n" + - "\014REQUEST_INFO\020\004\"\356\001\n\016ContactDetails\022\016\n\006nu", - "mber\030\001 \001(\t\022\014\n\004name\030\002 \001(\t\0224\n\006avatar\030\003 \001(\013" + - "2$.signalservice.ContactDetails.Avatar\022\r" + - "\n\005color\030\004 \001(\t\022\022\n\nprofileKey\030\006 \001(\014\022\017\n\007blo" + - "cked\030\007 \001(\010\022\023\n\013expireTimer\030\010 \001(\r\022\020\n\010nickn" + - "ame\030e \001(\t\032-\n\006Avatar\022\023\n\013contentType\030\001 \001(\t" + - "\022\016\n\006length\030\002 \001(\r\"\367\001\n\014GroupDetails\022\n\n\002id\030" + - "\001 \001(\014\022\014\n\004name\030\002 \001(\t\022\017\n\007members\030\003 \003(\t\0222\n\006" + - "avatar\030\004 \001(\0132\".signalservice.GroupDetail" + - "s.Avatar\022\024\n\006active\030\005 \001(\010:\004true\022\023\n\013expire" + - "Timer\030\006 \001(\r\022\r\n\005color\030\007 \001(\t\022\017\n\007blocked\030\010 ", - "\001(\010\022\016\n\006admins\030\t \003(\t\032-\n\006Avatar\022\023\n\013content" + - "Type\030\001 \001(\t\022\016\n\006length\030\002 \001(\r\"\"\n\016PublicChat" + - "Info\022\020\n\010serverID\030\001 \001(\004BB\n+org.session.li" + - "bsignal.service.internal.pushB\023SignalSer" + - "viceProtos" + "\016\n\006admins\030\006 \003(\t\"H\n\004Type\022\013\n\007UNKNOWN\020\000\022\n\n\006" + + "UPDATE\020\001\022\013\n\007DELIVER\020\002\022\010\n\004QUIT\020\003\022\020\n\014REQUE" + + "ST_INFO\020\004\"\356\001\n\016ContactDetails\022\016\n\006number\030\001" + + " \001(\t\022\014\n\004name\030\002 \001(\t\0224\n\006avatar\030\003 \001(\0132$.sig", + "nalservice.ContactDetails.Avatar\022\r\n\005colo" + + "r\030\004 \001(\t\022\022\n\nprofileKey\030\006 \001(\014\022\017\n\007blocked\030\007" + + " \001(\010\022\023\n\013expireTimer\030\010 \001(\r\022\020\n\010nickname\030e " + + "\001(\t\032-\n\006Avatar\022\023\n\013contentType\030\001 \001(\t\022\016\n\006le" + + "ngth\030\002 \001(\r\"\367\001\n\014GroupDetails\022\n\n\002id\030\001 \001(\014\022" + + "\014\n\004name\030\002 \001(\t\022\017\n\007members\030\003 \003(\t\0222\n\006avatar" + + "\030\004 \001(\0132\".signalservice.GroupDetails.Avat" + + "ar\022\024\n\006active\030\005 \001(\010:\004true\022\023\n\013expireTimer\030" + + "\006 \001(\r\022\r\n\005color\030\007 \001(\t\022\017\n\007blocked\030\010 \001(\010\022\016\n" + + "\006admins\030\t \003(\t\032-\n\006Avatar\022\023\n\013contentType\030\001", + " \001(\t\022\016\n\006length\030\002 \001(\r\"\"\n\016PublicChatInfo\022\020" + + "\n\010serverID\030\001 \001(\004BB\n+org.session.libsigna" + + "l.service.internal.pushB\023SignalServicePr" + + "otos" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { @@ -33642,7 +33169,7 @@ public final class SignalServiceProtos { internal_static_signalservice_GroupContext_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_signalservice_GroupContext_descriptor, - new java.lang.String[] { "Id", "Type", "Name", "Members", "Avatar", "Admins", "NewMembers", "RemovedMembers", }); + new java.lang.String[] { "Id", "Type", "Name", "Members", "Avatar", "Admins", }); internal_static_signalservice_ContactDetails_descriptor = getDescriptor().getMessageTypes().get(11); internal_static_signalservice_ContactDetails_fieldAccessorTable = new From 0653b2c2d3a96d2b20265a6cbd95c7272a1683b8 Mon Sep 17 00:00:00 2001 From: Brice-W Date: Wed, 21 Apr 2021 16:34:22 +1000 Subject: [PATCH 02/15] only admin can delete members --- .../loki/activities/EditClosedGroupActivity.kt | 16 ++++++++++------ .../activities/EditClosedGroupMembersAdapter.kt | 15 +++++---------- 2 files changed, 15 insertions(+), 16 deletions(-) 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 e969819d07..7ed4385ace 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 @@ -38,7 +38,9 @@ import java.io.IOException class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() { private val originalMembers = HashSet() private val members = HashSet() + private val zombies = HashSet() private var hasNameChanged = false + private var isSelfAdmin = false private var isLoading = false set(newValue) { field = newValue; invalidateOptionsMenu() } @@ -54,7 +56,10 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() { } private val memberListAdapter by lazy { - EditClosedGroupMembersAdapter(this, GlideApp.with(this), this::onMemberClick) + if (isSelfAdmin) + EditClosedGroupMembersAdapter(this, GlideApp.with(this), isSelfAdmin, this::onMemberClick) + else + EditClosedGroupMembersAdapter(this, GlideApp.with(this), isSelfAdmin) } private lateinit var mainContentContainer: LinearLayout @@ -81,7 +86,10 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() { ThemeUtil.getThemedDrawableResId(this, R.attr.actionModeCloseDrawable)) groupID = intent.getStringExtra(groupIDKey)!! - originalName = DatabaseFactory.getGroupDatabase(this).getGroup(groupID).get().title + val groupInfo = DatabaseFactory.getGroupDatabase(this).getGroup(groupID).get() + originalName = groupInfo.title + isSelfAdmin = groupInfo.admins.any{ it.serialize() == TextSecurePreferences.getLocalNumber(this) } + name = originalName mainContentContainer = findViewById(R.id.mainContentContainer) @@ -178,10 +186,6 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() { this.members.addAll(members) memberListAdapter.setMembers(members) - val admins = DatabaseFactory.getGroupDatabase(this).getGroup(groupID).get().admins.map { it.toString() }.toMutableSet() - admins.remove(TextSecurePreferences.getLocalNumber(this)) - memberListAdapter.setLockedMembers(admins) - mainContentContainer.visibility = if (members.isEmpty()) View.GONE else View.VISIBLE emptyStateContainer.visibility = if (members.isEmpty()) View.VISIBLE else View.GONE 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 3c07136f1a..3dc7ff162c 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 @@ -7,15 +7,16 @@ import org.session.libsession.messaging.threads.Address import org.thoughtcrime.securesms.loki.views.UserView import org.thoughtcrime.securesms.mms.GlideRequests import org.session.libsession.messaging.threads.recipients.Recipient +import org.session.libsession.utilities.TextSecurePreferences class EditClosedGroupMembersAdapter( private val context: Context, private val glide: GlideRequests, + private val admin: Boolean, private val memberClickListener: ((String) -> Unit)? = null ) : RecyclerView.Adapter() { private val members = ArrayList() - private val lockedMembers = HashSet() fun setMembers(members: Collection) { this.members.clear() @@ -23,12 +24,6 @@ class EditClosedGroupMembersAdapter( notifyDataSetChanged() } - fun setLockedMembers(members: Collection) { - this.lockedMembers.clear() - this.lockedMembers.addAll(members) - notifyDataSetChanged() - } - override fun getItemCount(): Int = members.size override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { @@ -39,15 +34,15 @@ class EditClosedGroupMembersAdapter( override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) { val member = members[position] - val lockedMember = lockedMembers.contains(member) + val unlocked = admin && member != TextSecurePreferences.getLocalNumber(context) viewHolder.view.bind(Recipient.from( context, Address.fromSerialized(member), false), glide, - if (lockedMember) UserView.ActionIndicator.None else UserView.ActionIndicator.Menu) + if (unlocked) UserView.ActionIndicator.Menu else UserView.ActionIndicator.None) - if (!lockedMember) { + if (unlocked) { viewHolder.view.setOnClickListener { this.memberClickListener?.invoke(member) } } } From b064f8f5d73045d142b667d79d7e6c95a26a7936 Mon Sep 17 00:00:00 2001 From: Brice-W Date: Fri, 23 Apr 2021 14:07:10 +1000 Subject: [PATCH 03/15] 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 Date: Fri, 23 Apr 2021 16:35:24 +1000 Subject: [PATCH 04/15] fix encryption key pair handling --- .../messaging/sending_receiving/MessageReceiverHandler.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 185befb9bd..8c08b879fb 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 @@ -341,7 +341,8 @@ private fun MessageReceiver.handleClosedGroupEncryptionKeyPair(message: ClosedGr val storage = MessagingConfiguration.shared.storage val senderPublicKey = message.sender ?: return val kind = message.kind!! as? ClosedGroupControlMessage.Kind.EncryptionKeyPair ?: return - val groupPublicKey = kind.publicKey?.toByteArray()?.toHexString() ?: message.groupPublicKey ?: return + var groupPublicKey = kind.publicKey?.toByteArray()?.toHexString() + if (groupPublicKey.isNullOrEmpty()) groupPublicKey = message.groupPublicKey ?: return val userPublicKey = storage.getUserPublicKey()!! val userKeyPair = storage.getUserX25519KeyPair() // Unwrap the message From 7c6475d9ee5de4326a94caca909c241e8ab3aa7c Mon Sep 17 00:00:00 2001 From: Brice-W Date: Mon, 26 Apr 2021 11:51:11 +1000 Subject: [PATCH 05/15] EncryptionKeyPair: only set a public key for 1-1 message case --- .../messaging/messages/control/ClosedGroupControlMessage.kt | 2 +- .../messaging/sending_receiving/MessageSenderClosedGroup.kt | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupControlMessage.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupControlMessage.kt index fa6544fc2a..e823560ea5 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupControlMessage.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupControlMessage.kt @@ -170,7 +170,7 @@ class ClosedGroupControlMessage() : ControlMessage() { } is Kind.EncryptionKeyPair -> { closedGroupControlMessage.type = DataMessage.ClosedGroupControlMessage.Type.ENCRYPTION_KEY_PAIR - closedGroupControlMessage.publicKey = kind.publicKey + closedGroupControlMessage.publicKey = kind.publicKey ?: ByteString.EMPTY closedGroupControlMessage.addAllWrappers(kind.wrappers.map { it.toProto() }) } is Kind.NameChange -> { 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 8e3622282b..36104265cb 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 @@ -277,7 +277,9 @@ fun MessageSender.sendEncryptionKeyPair(groupPublicKey: String, newKeyPair: ECKe val ciphertext = MessageSenderEncryption.encryptWithSessionProtocol(plaintext, publicKey) ClosedGroupControlMessage.KeyPairWrapper(publicKey, ByteString.copyFrom(ciphertext)) } - val kind = ClosedGroupControlMessage.Kind.EncryptionKeyPair(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), wrappers) + // we only set public key of EncryptionKeyPair if we send the message to a one-on-one contact, otherwise if sent to a group it is set tu null as we use the one of the envelope + val kind = if (targetUser != null) ClosedGroupControlMessage.Kind.EncryptionKeyPair(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), wrappers) + else ClosedGroupControlMessage.Kind.EncryptionKeyPair(null, wrappers) val sentTime = System.currentTimeMillis() val closedGroupControlMessage = ClosedGroupControlMessage(kind) closedGroupControlMessage.sentTimestamp = sentTime From f0394fb908f631c954ec367151937311d50d4d4c Mon Sep 17 00:00:00 2001 From: Brice-W Date: Mon, 26 Apr 2021 14:14:39 +1000 Subject: [PATCH 06/15] fix avatar display issues --- .../loki/activities/EditClosedGroupMembersAdapter.kt | 2 ++ .../thoughtcrime/securesms/loki/views/ProfilePictureView.kt | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) 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 63f33d9aad..7d5ed34086 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 @@ -51,6 +51,8 @@ class EditClosedGroupMembersAdapter( if (zombieMembers.contains(member)) viewHolder.view.alpha = 0.5F + else + viewHolder.view.alpha = 1F if (unlocked) { viewHolder.view.setOnClickListener { this.memberClickListener?.invoke(member) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/views/ProfilePictureView.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/views/ProfilePictureView.kt index a092841633..3008c9cd9e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/views/ProfilePictureView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/views/ProfilePictureView.kt @@ -146,13 +146,13 @@ class ProfilePictureView : RelativeLayout { private fun setProfilePictureIfNeeded(imageView: ImageView, publicKey: String, displayName: String?, @DimenRes sizeResId: Int) { if (publicKey.isNotEmpty()) { val recipient = Recipient.from(context, Address.fromSerialized(publicKey), false) - if (imagesCached.contains(recipient.profileAvatar.orEmpty())) return + if (imagesCached.contains(publicKey)) return val signalProfilePicture = recipient.contactPhoto if (signalProfilePicture != null && (signalProfilePicture as? ProfileContactPhoto)?.avatarObject != "0" && (signalProfilePicture as? ProfileContactPhoto)?.avatarObject != "") { glide.clear(imageView) glide.load(signalProfilePicture).diskCacheStrategy(DiskCacheStrategy.AUTOMATIC).circleCrop().into(imageView) - imagesCached.add(recipient.profileAvatar.orEmpty()) + imagesCached.add(publicKey) } else { val sizeInPX = resources.getDimensionPixelSize(sizeResId) glide.clear(imageView) @@ -162,7 +162,7 @@ class ProfilePictureView : RelativeLayout { publicKey, displayName )).diskCacheStrategy(DiskCacheStrategy.ALL).circleCrop().into(imageView) - imagesCached.add(recipient.profileAvatar.orEmpty()) + imagesCached.add(publicKey) } } else { imageView.setImageDrawable(null) From 572f262b6df21c0ce9872e2c980d855b7306cebc Mon Sep 17 00:00:00 2001 From: jubb Date: Mon, 26 Apr 2021 15:18:12 +1000 Subject: [PATCH 07/15] fix: don't update the profiles if the values are empty --- .../loki/protocol/MultiDeviceProtocol.kt | 89 ------------------- .../MessageReceiverHandler.kt | 26 +++--- 2 files changed, 13 insertions(+), 102 deletions(-) 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 41b3de72f8..b58f608502 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 @@ -1,25 +1,12 @@ package org.thoughtcrime.securesms.loki.protocol import android.content.Context -import com.google.protobuf.ByteString -import org.session.libsession.messaging.MessagingConfiguration import org.session.libsession.messaging.messages.Destination import org.session.libsession.messaging.messages.control.ConfigurationMessage import org.session.libsession.messaging.sending_receiving.MessageSender import org.session.libsession.messaging.threads.Address -import org.session.libsession.messaging.threads.recipients.Recipient import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsession.utilities.preferences.ProfileKeyUtil -import org.session.libsignal.service.internal.push.SignalServiceProtos -import org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage -import org.session.libsignal.service.loki.utilities.removing05PrefixIfNeeded -import org.session.libsignal.utilities.Base64 -import org.session.libsignal.utilities.Hex -import org.thoughtcrime.securesms.ApplicationContext -import org.thoughtcrime.securesms.database.DatabaseFactory -import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob import org.thoughtcrime.securesms.loki.utilities.ContactUtilities -import org.thoughtcrime.securesms.loki.utilities.OpenGroupUtilities object MultiDeviceProtocol { @@ -51,80 +38,4 @@ object MultiDeviceProtocol { TextSecurePreferences.setLastConfigurationSyncTime(context, System.currentTimeMillis()) } - // TODO: remove this after we migrate to new message receiving pipeline - @JvmStatic - fun handleConfigurationMessage(context: Context, content: SignalServiceProtos.Content, senderPublicKey: String, timestamp: Long) { - synchronized(this) { - val userPublicKey = TextSecurePreferences.getLocalNumber(context) ?: return - if (TextSecurePreferences.getConfigurationMessageSynced(context) && !TextSecurePreferences.shouldUpdateProfile(context, timestamp)) return - if (senderPublicKey != userPublicKey) return - TextSecurePreferences.setConfigurationMessageSynced(context, true) - TextSecurePreferences.setLastProfileUpdateTime(context, timestamp) - - val configurationMessage = ConfigurationMessage.fromProto(content) ?: return - - val storage = MessagingConfiguration.shared.storage - val allClosedGroupPublicKeys = storage.getAllClosedGroupPublicKeys() - - val threadDatabase = DatabaseFactory.getThreadDatabase(context) - val recipientDatabase = DatabaseFactory.getRecipientDatabase(context) - - val ourRecipient = Recipient.from(context, Address.fromSerialized(userPublicKey),false) - - for (closedGroup in configurationMessage.closedGroups) { - if (allClosedGroupPublicKeys.contains(closedGroup.publicKey)) continue - - val closedGroupUpdate = DataMessage.ClosedGroupControlMessage.newBuilder() - closedGroupUpdate.type = DataMessage.ClosedGroupControlMessage.Type.NEW - closedGroupUpdate.publicKey = ByteString.copyFrom(Hex.fromStringCondensed(closedGroup.publicKey)) - closedGroupUpdate.name = closedGroup.name - val encryptionKeyPair = SignalServiceProtos.KeyPair.newBuilder() - encryptionKeyPair.publicKey = ByteString.copyFrom(closedGroup.encryptionKeyPair!!.publicKey.serialize().removing05PrefixIfNeeded()) - encryptionKeyPair.privateKey = ByteString.copyFrom(closedGroup.encryptionKeyPair!!.privateKey.serialize()) - closedGroupUpdate.encryptionKeyPair = encryptionKeyPair.build() - closedGroupUpdate.addAllMembers(closedGroup.members.map { ByteString.copyFrom(Hex.fromStringCondensed(it)) }) - closedGroupUpdate.addAllAdmins(closedGroup.admins.map { ByteString.copyFrom(Hex.fromStringCondensed(it)) }) - - ClosedGroupsProtocolV2.handleNewClosedGroup(context, closedGroupUpdate.build(), userPublicKey, timestamp) - } - val allOpenGroups = storage.getAllOpenGroups().map { it.value.server } - for (openGroup in configurationMessage.openGroups) { - if (allOpenGroups.contains(openGroup)) continue - OpenGroupUtilities.addGroup(context, openGroup, 1) - } - if (configurationMessage.displayName.isNotEmpty()) { - TextSecurePreferences.setProfileName(context, configurationMessage.displayName) - recipientDatabase.setProfileName(ourRecipient, configurationMessage.displayName) - } - if (configurationMessage.profileKey.isNotEmpty()) { - val profileKey = Base64.encodeBytes(configurationMessage.profileKey) - ProfileKeyUtil.setEncodedProfileKey(context, profileKey) - recipientDatabase.setProfileKey(ourRecipient, configurationMessage.profileKey) - if (!configurationMessage.profilePicture.isNullOrEmpty() && TextSecurePreferences.getProfilePictureURL(context) != configurationMessage.profilePicture) { - TextSecurePreferences.setProfilePictureURL(context, configurationMessage.profilePicture) - ApplicationContext.getInstance(context).jobManager.add(RetrieveProfileAvatarJob(ourRecipient, configurationMessage.profilePicture)) - } - } - for (contact in configurationMessage.contacts) { - val address = Address.fromSerialized(contact.publicKey) - val recipient = Recipient.from(context, address, true) - if (!contact.profilePicture.isNullOrEmpty()) { - recipientDatabase.setProfileAvatar(recipient, contact.profilePicture) - } - if (contact.profileKey?.isNotEmpty() == true) { - recipientDatabase.setProfileKey(recipient, contact.profileKey) - } - if (contact.name.isNotEmpty()) { - recipientDatabase.setProfileName(recipient, contact.name) - } - recipientDatabase.setProfileSharing(recipient, true) - recipientDatabase.setRegistered(recipient, Recipient.RegisteredState.REGISTERED) - // create Thread if needed - threadDatabase.getOrCreateThreadIdFor(recipient) - } - if (configurationMessage.contacts.isNotEmpty()) { - threadDatabase.notifyUpdatedFromConfig() - } - } - } } \ No newline at end of file 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..d8d136ca2d 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 @@ -111,7 +111,7 @@ private fun MessageReceiver.handleDataExtractionNotification(message: DataExtrac // Configuration message handling -private fun MessageReceiver.handleConfigurationMessage(message: ConfigurationMessage) { +private fun handleConfigurationMessage(message: ConfigurationMessage) { val context = MessagingConfiguration.shared.context val storage = MessagingConfiguration.shared.storage if (TextSecurePreferences.getConfigurationMessageSynced(context) && !TextSecurePreferences.shouldUpdateProfile(context, message.sentTimestamp!!)) return @@ -150,25 +150,25 @@ fun MessageReceiver.handleVisibleMessage(message: VisibleMessage, proto: SignalS val context = MessagingConfiguration.shared.context // Update profile if needed val newProfile = message.profile - if (newProfile != null) { + if (newProfile != null && openGroupID.isNullOrEmpty()) { val profileManager = SSKEnvironment.shared.profileManager val recipient = Recipient.from(context, Address.fromSerialized(message.sender!!), false) val displayName = newProfile.displayName!! val userPublicKey = storage.getUserPublicKey() - if (openGroupID == null) { - if (userPublicKey == message.sender) { - // Update the user's local name if the message came from their master device - TextSecurePreferences.setProfileName(context, displayName) - } - profileManager.setDisplayName(context, recipient, displayName) + if (userPublicKey == message.sender && displayName.isNotEmpty()) { + // Update the user's local name if the message came from their master device + TextSecurePreferences.setProfileName(context, displayName) } - if (recipient.profileKey == null || !MessageDigest.isEqual(recipient.profileKey, newProfile.profileKey)) { + profileManager.setDisplayName(context, recipient, displayName) + if (recipient.profileKey?.isNotEmpty() == true && !MessageDigest.isEqual(recipient.profileKey, newProfile.profileKey)) { profileManager.setProfileKey(context, recipient, newProfile.profileKey!!) profileManager.setUnidentifiedAccessMode(context, recipient, Recipient.UnidentifiedAccessMode.UNKNOWN) - val url = newProfile.profilePictureURL.orEmpty() - profileManager.setProfilePictureURL(context, recipient, url) - if (userPublicKey == message.sender) { - profileManager.updateOpenGroupProfilePicturesIfNeeded(context) + val newUrl = newProfile.profilePictureURL + if (!newUrl.isNullOrEmpty()) { + profileManager.setProfilePictureURL(context, recipient, newUrl) + if (userPublicKey == message.sender) { + profileManager.updateOpenGroupProfilePicturesIfNeeded(context) + } } } } From 6a32fabda5e0a9139a088d44e049dc49f78e0c59 Mon Sep 17 00:00:00 2001 From: Brice-W Date: Mon, 26 Apr 2021 15:38:26 +1000 Subject: [PATCH 08/15] revert change of commit 7c6475d9ee5de4326a94caca909c241e8ab3aa7c --- .../messaging/sending_receiving/MessageSenderClosedGroup.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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 36104265cb..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 @@ -277,9 +277,7 @@ fun MessageSender.sendEncryptionKeyPair(groupPublicKey: String, newKeyPair: ECKe val ciphertext = MessageSenderEncryption.encryptWithSessionProtocol(plaintext, publicKey) ClosedGroupControlMessage.KeyPairWrapper(publicKey, ByteString.copyFrom(ciphertext)) } - // we only set public key of EncryptionKeyPair if we send the message to a one-on-one contact, otherwise if sent to a group it is set tu null as we use the one of the envelope - val kind = if (targetUser != null) ClosedGroupControlMessage.Kind.EncryptionKeyPair(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), wrappers) - else ClosedGroupControlMessage.Kind.EncryptionKeyPair(null, wrappers) + val kind = ClosedGroupControlMessage.Kind.EncryptionKeyPair(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), wrappers) val sentTime = System.currentTimeMillis() val closedGroupControlMessage = ClosedGroupControlMessage(kind) closedGroupControlMessage.sentTimestamp = sentTime From 42ca1332ec9035481ce88b94d1c15cf340795a4d Mon Sep 17 00:00:00 2001 From: jubb Date: Mon, 26 Apr 2021 15:44:31 +1000 Subject: [PATCH 09/15] fix: update prof pic and name and use new profile instead of existing recipient --- .../messaging/sending_receiving/MessageReceiverHandler.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 d8d136ca2d..cabb92b8c7 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 @@ -158,9 +158,10 @@ fun MessageReceiver.handleVisibleMessage(message: VisibleMessage, proto: SignalS if (userPublicKey == message.sender && displayName.isNotEmpty()) { // Update the user's local name if the message came from their master device TextSecurePreferences.setProfileName(context, displayName) + } else if (displayName.isNotEmpty()) { + profileManager.setDisplayName(context, recipient, displayName) } - profileManager.setDisplayName(context, recipient, displayName) - if (recipient.profileKey?.isNotEmpty() == true && !MessageDigest.isEqual(recipient.profileKey, newProfile.profileKey)) { + if (newProfile.profileKey?.isNotEmpty() == true && !MessageDigest.isEqual(recipient.profileKey, newProfile.profileKey)) { profileManager.setProfileKey(context, recipient, newProfile.profileKey!!) profileManager.setUnidentifiedAccessMode(context, recipient, Recipient.UnidentifiedAccessMode.UNKNOWN) val newUrl = newProfile.profilePictureURL From 96cc8675129b962e28256fe133c7b3d33fe572ad Mon Sep 17 00:00:00 2001 From: jubb Date: Mon, 26 Apr 2021 15:55:13 +1000 Subject: [PATCH 10/15] fix: BackgroundPollWorker.kt new instance instead of null instance --- .../thoughtcrime/securesms/loki/api/BackgroundPollWorker.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/api/BackgroundPollWorker.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/api/BackgroundPollWorker.kt index 8476fae3e1..15d84db459 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/api/BackgroundPollWorker.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/api/BackgroundPollWorker.kt @@ -9,11 +9,11 @@ import nl.komponents.kovenant.all import nl.komponents.kovenant.functional.map import org.session.libsession.messaging.jobs.MessageReceiveJob import org.session.libsession.messaging.opengroups.OpenGroup +import org.session.libsession.messaging.sending_receiving.pollers.ClosedGroupPoller import org.session.libsession.messaging.sending_receiving.pollers.OpenGroupPoller import org.session.libsession.utilities.TextSecurePreferences import org.session.libsignal.service.loki.api.SnodeAPI import org.session.libsignal.utilities.logging.Log -import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.database.DatabaseFactory import java.util.concurrent.TimeUnit @@ -78,7 +78,7 @@ class BackgroundPollWorker(val context: Context, params: WorkerParameters) : Wor promises.addAll(privateChatsPromise.get()) // Closed groups - promises.addAll(ApplicationContext.getInstance(context).closedGroupPoller.pollOnce()) + promises.addAll(ClosedGroupPoller().pollOnce()) // Open Groups val openGroups = DatabaseFactory.getLokiThreadDatabase(context).getAllPublicChats().map { (_,chat)-> From d4aaebd0a93c05918331694593335b83fe6b9ad7 Mon Sep 17 00:00:00 2001 From: Brice-W Date: Mon, 26 Apr 2021 16:33:54 +1000 Subject: [PATCH 11/15] don't show zombie members in group remove updates --- .../MessageReceiverHandler.kt | 18 ++++++++++++------ .../MessageSenderClosedGroup.kt | 11 ++++++++--- 2 files changed, 20 insertions(+), 9 deletions(-) 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 8c08b879fb..38c4978038 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 @@ -437,6 +437,7 @@ private fun MessageReceiver.handleClosedGroupMembersAdded(message: ClosedGroupCo val updateMembers = kind.members.map { it.toByteArray().toHexString() } val newMembers = members + updateMembers storage.updateMembers(groupID, newMembers.map { Address.fromSerialized(it) }) + // Notify the user if (userPublicKey == senderPublicKey) { // sender is a linked device @@ -526,12 +527,17 @@ private fun MessageReceiver.handleClosedGroupMembersRemoved(message: ClosedGroup else SignalServiceGroup.Type.MEMBER_REMOVED // Notify the user - if (userPublicKey == senderPublicKey) { - // sender is a linked device - val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID)) - storage.insertOutgoingInfoMessage(context, groupID, type, name, updateMembers, admins, threadID, message.sentTimestamp!!) - } else { - storage.insertIncomingInfoMessage(context, senderPublicKey, groupID, type, name, updateMembers, admins, message.sentTimestamp!!) + // we don't display zombie members in the notification as users have already been notified when those members left + val notificationMembers = updateMembers.minus(zombies) + if (notificationMembers.isNotEmpty()) { + // no notification to display when only zombies have been removed + if (userPublicKey == senderPublicKey) { + // sender is a linked device + val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID)) + storage.insertOutgoingInfoMessage(context, groupID, type, name, notificationMembers, admins, threadID, message.sentTimestamp!!) + } else { + storage.insertIncomingInfoMessage(context, senderPublicKey, groupID, type, name, notificationMembers, admins, message.sentTimestamp!!) + } } } 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 8e3622282b..57d2dcc2e4 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 @@ -201,9 +201,14 @@ fun MessageSender.removeMembers(groupPublicKey: String, membersToRemove: List { From 11aed5daff8b9b2a54df32fdea9b06fbd75680c4 Mon Sep 17 00:00:00 2001 From: jubb Date: Tue, 27 Apr 2021 09:38:07 +1000 Subject: [PATCH 12/15] refactor: don't update profile if it is user's at all in visible message handling, leave it to config updates --- .../sending_receiving/MessageReceiverHandler.kt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) 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 cabb92b8c7..5781079830 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 @@ -148,17 +148,14 @@ private fun handleConfigurationMessage(message: ConfigurationMessage) { fun MessageReceiver.handleVisibleMessage(message: VisibleMessage, proto: SignalServiceProtos.Content, openGroupID: String?) { val storage = MessagingConfiguration.shared.storage val context = MessagingConfiguration.shared.context + val userPublicKey = storage.getUserPublicKey() // Update profile if needed val newProfile = message.profile - if (newProfile != null && openGroupID.isNullOrEmpty()) { + if (newProfile != null && openGroupID.isNullOrEmpty() && userPublicKey != message.sender) { val profileManager = SSKEnvironment.shared.profileManager val recipient = Recipient.from(context, Address.fromSerialized(message.sender!!), false) val displayName = newProfile.displayName!! - val userPublicKey = storage.getUserPublicKey() - if (userPublicKey == message.sender && displayName.isNotEmpty()) { - // Update the user's local name if the message came from their master device - TextSecurePreferences.setProfileName(context, displayName) - } else if (displayName.isNotEmpty()) { + if (displayName.isNotEmpty()) { profileManager.setDisplayName(context, recipient, displayName) } if (newProfile.profileKey?.isNotEmpty() == true && !MessageDigest.isEqual(recipient.profileKey, newProfile.profileKey)) { From ab68001b1520b512f557e10fa7bdc292ab3005ff Mon Sep 17 00:00:00 2001 From: Brice-W Date: Wed, 28 Apr 2021 16:00:13 +1000 Subject: [PATCH 13/15] clean --- .../org/thoughtcrime/securesms/database/GroupDatabase.java | 2 -- .../securesms/loki/activities/EditClosedGroupActivity.kt | 3 +-- .../messaging/sending_receiving/ReceivedMessageHandler.kt | 4 ---- 3 files changed, 1 insertion(+), 8 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 2a41b3c901..fb1fbd6d28 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java @@ -183,9 +183,7 @@ public class GroupDatabase extends Database implements LokiOpenGroupDatabaseProt List recipients = new LinkedList<>(); for (Address member : members) { - if (member.isContact()) { recipients.add(Recipient.from(context, member, false)); - } } return recipients; 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 80f39f099a..88c89f7319 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 @@ -41,8 +41,7 @@ class EditClosedGroupActivity : PassphraseRequiredActionBarActivity() { private val members = HashSet() private val allMembers: Set get() { - return if (zombies.isNotEmpty()) (members + zombies) - else members + return members + zombies } private var hasNameChanged = false private var isSelfAdmin = false diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt index b46c6d405f..81c7387b74 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt @@ -522,11 +522,7 @@ 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) storage.updateMembers(groupID, updatedMemberList.map { Address.fromSerialized(it) }) - //if (isCurrentUserAdmin) { - // MessageSender.generateAndSendNewEncryptionKeyPair(groupPublicKey, updatedMemberList) - //} // update zombie members val zombies = storage.getZombieMember(groupID) storage.updateZombieMembers(groupID, zombies.plus(senderPublicKey).map { Address.fromSerialized(it) }) From 761c12addd234dd6c8e26df352375a0342be6598 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Thu, 29 Apr 2021 10:02:07 +1000 Subject: [PATCH 14/15] Clean --- .../securesms/ApplicationContext.java | 3 +- .../conversation/ConversationActivity.java | 2 +- .../securesms/database/GroupDatabase.java | 2 +- .../loki/activities/LinkDeviceActivity.kt | 2 +- .../RecoveryPhraseRestoreActivity.kt | 2 +- .../securesms/loki/activities/SeedActivity.kt | 2 +- .../loki/database/LokiAPIDatabase.kt | 2 +- .../loki/database/LokiMessageDatabase.kt | 3 +- .../loki/database/LokiUserDatabase.kt | 2 +- .../securesms/loki/dialogs/SeedDialog.kt | 2 +- .../securesms/loki/utilities/Broadcaster.kt | 3 +- .../loki/utilities/MnemonicUtilities.kt | 4 -- .../views/MentionCandidateSelectionView.kt | 2 +- .../loki/views/MentionCandidateView.kt | 2 +- .../messaging/file_server/FileServerAPI.kt | 2 +- .../messaging/jobs/AttachmentUploadJob.kt | 2 +- .../messaging/mentions/MentionsManager.kt | 4 +- .../messaging/open_groups/OpenGroupAPI.kt | 13 +++-- .../messaging/utilities/DotNetAPI.kt | 2 +- .../libsession/snode/OnionRequestAPI.kt | 6 ++- .../org/session/libsession/snode/SnodeAPI.kt | 6 +-- .../session/libsession/snode/SnodeModule.kt | 4 +- .../api/crypto/SignalServiceCipher.java | 3 +- .../api/messages/shared/SharedContact.java | 1 - .../loki/{utilities => }/Broadcaster.kt | 2 +- .../service/loki/{api/utilities => }/HTTP.kt | 2 +- .../loki/{utilities => }/HexEncoding.kt | 0 .../{database => }/LokiAPIDatabaseProtocol.kt | 2 +- .../LokiMessageDatabaseProtocol.kt | 2 +- .../LokiOpenGroupDatabaseProtocol.kt | 2 +- .../LokiUserDatabaseProtocol.kt | 2 +- .../loki/{utilities/mentions => }/Mention.kt | 2 +- .../loki/{crypto => }/MnemonicCodec.kt | 15 +++--- .../PlaintextOutputStreamFactory.kt | 2 +- .../{utilities => }/PrettifiedDescription.kt | 0 .../service/loki/{utilities => }/Random.kt | 0 .../loki/{utilities => }/Reflection.kt | 0 .../service/loki/{utilities => }/Retrying.kt | 0 .../loki/{api/crypto => }/SessionProtocol.kt | 2 +- .../loki/{api => }/SignalMessageInfo.kt | 2 +- .../service/loki/{utilities => }/Trimming.kt | 0 .../loki/{utilities => }/Validation.kt | 0 .../loki/api/utilities/OKHTTPUtilities.kt | 49 ------------------- .../session/libsignal/utilities/JsonUtil.java | 23 +-------- .../libsignal/utilities/PromiseUtilities.kt | 14 ------ .../libsignal/utilities/ThreadUtils.kt | 5 +- 46 files changed, 56 insertions(+), 146 deletions(-) rename libsignal/src/main/java/org/session/libsignal/service/loki/{utilities => }/Broadcaster.kt (66%) rename libsignal/src/main/java/org/session/libsignal/service/loki/{api/utilities => }/HTTP.kt (98%) rename libsignal/src/main/java/org/session/libsignal/service/loki/{utilities => }/HexEncoding.kt (100%) rename libsignal/src/main/java/org/session/libsignal/service/loki/{database => }/LokiAPIDatabaseProtocol.kt (97%) rename libsignal/src/main/java/org/session/libsignal/service/loki/{database => }/LokiMessageDatabaseProtocol.kt (76%) rename libsignal/src/main/java/org/session/libsignal/service/loki/{database => }/LokiOpenGroupDatabaseProtocol.kt (76%) rename libsignal/src/main/java/org/session/libsignal/service/loki/{database => }/LokiUserDatabaseProtocol.kt (81%) rename libsignal/src/main/java/org/session/libsignal/service/loki/{utilities/mentions => }/Mention.kt (52%) rename libsignal/src/main/java/org/session/libsignal/service/loki/{crypto => }/MnemonicCodec.kt (97%) rename libsignal/src/main/java/org/session/libsignal/service/loki/{utilities => }/PlaintextOutputStreamFactory.kt (92%) rename libsignal/src/main/java/org/session/libsignal/service/loki/{utilities => }/PrettifiedDescription.kt (100%) rename libsignal/src/main/java/org/session/libsignal/service/loki/{utilities => }/Random.kt (100%) rename libsignal/src/main/java/org/session/libsignal/service/loki/{utilities => }/Reflection.kt (100%) rename libsignal/src/main/java/org/session/libsignal/service/loki/{utilities => }/Retrying.kt (100%) rename libsignal/src/main/java/org/session/libsignal/service/loki/{api/crypto => }/SessionProtocol.kt (97%) rename libsignal/src/main/java/org/session/libsignal/service/loki/{api => }/SignalMessageInfo.kt (88%) rename libsignal/src/main/java/org/session/libsignal/service/loki/{utilities => }/Trimming.kt (100%) rename libsignal/src/main/java/org/session/libsignal/service/loki/{utilities => }/Validation.kt (100%) delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/api/utilities/OKHTTPUtilities.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index e5b8b7fd5a..00a2c4f01f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -49,7 +49,7 @@ import org.session.libsession.utilities.dynamiclanguage.DynamicLanguageContextWr import org.session.libsession.utilities.dynamiclanguage.LocaleParser; import org.session.libsession.utilities.preferences.ProfileKeyUtil; import org.session.libsignal.service.api.util.StreamDetails; -import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol; +import org.session.libsignal.service.loki.LokiAPIDatabaseProtocol; import org.session.libsignal.utilities.logging.Log; import org.signal.aesgcmprovider.AesGcmProvider; import org.thoughtcrime.securesms.components.TypingStatusSender; @@ -93,7 +93,6 @@ import org.webrtc.voiceengine.WebRtcAudioUtils; import java.io.File; import java.io.FileInputStream; -import java.io.IOException; import java.security.SecureRandom; import java.security.Security; import java.util.Date; diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java index 80a6ffb5d8..56e44d6b25 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java @@ -95,7 +95,7 @@ import org.session.libsession.utilities.GroupUtil; import org.session.libsession.utilities.MediaTypes; import org.session.libsignal.libsignal.InvalidMessageException; import org.session.libsignal.libsignal.util.guava.Optional; -import org.session.libsignal.service.loki.utilities.mentions.Mention; +import org.session.libsignal.service.loki.Mention; import org.session.libsignal.service.loki.utilities.HexEncodingKt; import org.session.libsignal.service.loki.utilities.PublicKeyValidation; import org.thoughtcrime.securesms.ApplicationContext; 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 fb1fbd6d28..7f3d0cd97f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/GroupDatabase.java @@ -25,7 +25,7 @@ import org.session.libsession.utilities.Util; import org.session.libsignal.libsignal.util.guava.Optional; import org.session.libsignal.service.api.messages.SignalServiceAttachmentPointer; -import org.session.libsignal.service.loki.database.LokiOpenGroupDatabaseProtocol; +import org.session.libsignal.service.loki.LokiOpenGroupDatabaseProtocol; import java.io.Closeable; import java.security.SecureRandom; diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/LinkDeviceActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/LinkDeviceActivity.kt index 6f3ef464bc..cc878e4beb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/LinkDeviceActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/LinkDeviceActivity.kt @@ -27,7 +27,7 @@ import kotlinx.coroutines.launch import network.loki.messenger.R import org.session.libsession.utilities.TextSecurePreferences import org.session.libsignal.libsignal.util.KeyHelper -import org.session.libsignal.service.loki.crypto.MnemonicCodec +import org.session.libsignal.service.loki.MnemonicCodec import org.session.libsignal.service.loki.utilities.hexEncodedPublicKey import org.session.libsignal.utilities.Hex import org.session.libsignal.utilities.logging.Log diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/RecoveryPhraseRestoreActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/RecoveryPhraseRestoreActivity.kt index 24d160f880..0ee7e0f574 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/RecoveryPhraseRestoreActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/RecoveryPhraseRestoreActivity.kt @@ -15,7 +15,7 @@ import kotlinx.android.synthetic.main.activity_recovery_phrase_restore.* import network.loki.messenger.R import org.session.libsession.utilities.TextSecurePreferences import org.session.libsignal.libsignal.util.KeyHelper -import org.session.libsignal.service.loki.crypto.MnemonicCodec +import org.session.libsignal.service.loki.MnemonicCodec import org.session.libsignal.service.loki.utilities.hexEncodedPublicKey import org.session.libsignal.utilities.Hex import org.thoughtcrime.securesms.BaseActionBarActivity diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/SeedActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/SeedActivity.kt index 2c79b4fc87..9ee8025335 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/SeedActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/SeedActivity.kt @@ -16,7 +16,7 @@ import org.session.libsession.utilities.IdentityKeyUtil import org.thoughtcrime.securesms.loki.utilities.MnemonicUtilities import org.thoughtcrime.securesms.loki.utilities.getColorWithID import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsignal.service.loki.crypto.MnemonicCodec +import org.session.libsignal.service.loki.MnemonicCodec import org.session.libsignal.service.loki.utilities.hexEncodedPrivateKey class SeedActivity : BaseActionBarActivity() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiAPIDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiAPIDatabase.kt index 58b9aeeec7..06da1f0676 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiAPIDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiAPIDatabase.kt @@ -8,7 +8,7 @@ import org.session.libsignal.libsignal.ecc.DjbECPrivateKey import org.session.libsignal.libsignal.ecc.DjbECPublicKey import org.session.libsignal.libsignal.ecc.ECKeyPair import org.session.libsignal.service.loki.Snode -import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol +import org.session.libsignal.service.loki.LokiAPIDatabaseProtocol import org.session.libsignal.service.loki.utilities.PublicKeyValidation import org.session.libsignal.service.loki.utilities.removing05PrefixIfNeeded import org.session.libsignal.service.loki.utilities.toHexString diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiMessageDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiMessageDatabase.kt index 66c1907405..1da93f7ec3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiMessageDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiMessageDatabase.kt @@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.loki.database import android.content.ContentValues import android.content.Context -import org.session.libsession.messaging.threads.Address import org.thoughtcrime.securesms.database.Database import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper @@ -10,7 +9,7 @@ import org.thoughtcrime.securesms.loki.utilities.get import org.thoughtcrime.securesms.loki.utilities.getInt import org.thoughtcrime.securesms.loki.utilities.getString import org.thoughtcrime.securesms.loki.utilities.insertOrUpdate -import org.session.libsignal.service.loki.database.LokiMessageDatabaseProtocol +import org.session.libsignal.service.loki.LokiMessageDatabaseProtocol class LokiMessageDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), LokiMessageDatabaseProtocol { diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiUserDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiUserDatabase.kt index 05e5f666db..cea0f52d9f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiUserDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiUserDatabase.kt @@ -11,7 +11,7 @@ import org.thoughtcrime.securesms.loki.utilities.get import org.thoughtcrime.securesms.loki.utilities.insertOrUpdate import org.session.libsession.messaging.threads.recipients.Recipient import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsignal.service.loki.database.LokiUserDatabaseProtocol +import org.session.libsignal.service.loki.LokiUserDatabaseProtocol class LokiUserDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), LokiUserDatabaseProtocol { diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/dialogs/SeedDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/dialogs/SeedDialog.kt index 12446cf57b..d327efe973 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/dialogs/SeedDialog.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/dialogs/SeedDialog.kt @@ -15,7 +15,7 @@ import kotlinx.android.synthetic.main.dialog_seed.view.* import network.loki.messenger.R import org.session.libsession.utilities.IdentityKeyUtil import org.thoughtcrime.securesms.loki.utilities.MnemonicUtilities -import org.session.libsignal.service.loki.crypto.MnemonicCodec +import org.session.libsignal.service.loki.MnemonicCodec import org.session.libsignal.service.loki.utilities.hexEncodedPrivateKey diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/Broadcaster.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/Broadcaster.kt index 5156ff2572..dfc42c9340 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/Broadcaster.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/Broadcaster.kt @@ -3,8 +3,9 @@ package org.thoughtcrime.securesms.loki.utilities import android.content.Context import android.content.Intent import androidx.localbroadcastmanager.content.LocalBroadcastManager +import org.session.libsignal.service.loki.Broadcaster -class Broadcaster(private val context: Context) : org.session.libsignal.service.loki.utilities.Broadcaster { +class Broadcaster(private val context: Context) : Broadcaster { override fun broadcast(event: String) { val intent = Intent(event) diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MnemonicUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MnemonicUtilities.kt index 27a2a78cfc..226bb1abfd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MnemonicUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MnemonicUtilities.kt @@ -1,10 +1,6 @@ package org.thoughtcrime.securesms.loki.utilities import android.content.Context -import org.session.libsignal.service.loki.crypto.MnemonicCodec -import org.session.libsignal.service.loki.utilities.removing05PrefixIfNeeded -import java.io.File -import java.io.FileOutputStream object MnemonicUtilities { diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/views/MentionCandidateSelectionView.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/views/MentionCandidateSelectionView.kt index ddda015d77..2da55501cf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/views/MentionCandidateSelectionView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/views/MentionCandidateSelectionView.kt @@ -10,7 +10,7 @@ import android.widget.ListView import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.loki.utilities.toPx import org.thoughtcrime.securesms.mms.GlideRequests -import org.session.libsignal.service.loki.utilities.mentions.Mention +import org.session.libsignal.service.loki.Mention class MentionCandidateSelectionView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : ListView(context, attrs, defStyleAttr) { private var mentionCandidates = listOf() diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/views/MentionCandidateView.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/views/MentionCandidateView.kt index f7af85ed13..f353402806 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/views/MentionCandidateView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/views/MentionCandidateView.kt @@ -9,7 +9,7 @@ import android.widget.LinearLayout import kotlinx.android.synthetic.main.view_mention_candidate.view.* import network.loki.messenger.R import org.session.libsession.messaging.open_groups.OpenGroupAPI -import org.session.libsignal.service.loki.utilities.mentions.Mention +import org.session.libsignal.service.loki.Mention import org.thoughtcrime.securesms.mms.GlideRequests class MentionCandidateView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : LinearLayout(context, attrs, defStyleAttr) { diff --git a/libsession/src/main/java/org/session/libsession/messaging/file_server/FileServerAPI.kt b/libsession/src/main/java/org/session/libsession/messaging/file_server/FileServerAPI.kt index 5e78caf6f0..b4a1861875 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/file_server/FileServerAPI.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/file_server/FileServerAPI.kt @@ -8,7 +8,7 @@ import org.session.libsession.snode.OnionRequestAPI import org.session.libsignal.utilities.logging.Log import org.session.libsignal.utilities.Base64 import org.session.libsignal.utilities.JsonUtil -import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol +import org.session.libsignal.service.loki.LokiAPIDatabaseProtocol import org.session.libsignal.service.loki.utilities.* import java.net.URL diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentUploadJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentUploadJob.kt index ffdf459693..2d16b7b9b9 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentUploadJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentUploadJob.kt @@ -14,7 +14,7 @@ import org.session.libsignal.service.internal.crypto.PaddingInputStream import org.session.libsignal.service.internal.push.PushAttachmentData import org.session.libsignal.service.internal.push.http.AttachmentCipherOutputStreamFactory import org.session.libsignal.service.internal.util.Util -import org.session.libsignal.service.loki.utilities.PlaintextOutputStreamFactory +import org.session.libsignal.service.loki.PlaintextOutputStreamFactory import org.session.libsignal.utilities.logging.Log class AttachmentUploadJob(val attachmentID: Long, val threadID: String, val message: Message, val messageSendJobID: String) : Job { diff --git a/libsession/src/main/java/org/session/libsession/messaging/mentions/MentionsManager.kt b/libsession/src/main/java/org/session/libsession/messaging/mentions/MentionsManager.kt index 715204825a..e421489b19 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/mentions/MentionsManager.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/mentions/MentionsManager.kt @@ -1,9 +1,9 @@ package org.session.libsession.messaging.mentions import org.session.libsession.messaging.MessagingModuleConfiguration -import org.session.libsignal.service.loki.utilities.mentions.Mention +import org.session.libsignal.service.loki.Mention -import org.session.libsignal.service.loki.database.LokiUserDatabaseProtocol +import org.session.libsignal.service.loki.LokiUserDatabaseProtocol class MentionsManager(private val userPublicKey: String, private val userDatabase: LokiUserDatabaseProtocol) { var userPublicKeyCache = mutableMapOf>() // Thread ID to set of user hex encoded public keys diff --git a/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPI.kt b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPI.kt index bd70118abd..0aba366d9f 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPI.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPI.kt @@ -21,7 +21,6 @@ import java.util.* object OpenGroupAPI: DotNetAPI() { private val moderators: HashMap>> = hashMapOf() // Server URL to (channel ID to set of moderator IDs) - val sharedContext = Kovenant.createContext() // region Settings private val fallbackBatchCount = 64 @@ -61,7 +60,7 @@ object OpenGroupAPI: DotNetAPI() { parameters["count"] = fallbackBatchCount parameters["include_deleted"] = 0 } - return execute(HTTPVerb.GET, server, "channels/$channel/messages", parameters = parameters).then(sharedContext) { json -> + return execute(HTTPVerb.GET, server, "channels/$channel/messages", parameters = parameters).then { json -> try { val data = json["data"] as List> val messages = data.mapNotNull { message -> @@ -166,7 +165,7 @@ object OpenGroupAPI: DotNetAPI() { } else { parameters["count"] = fallbackBatchCount } - return execute(HTTPVerb.GET, server, "loki/v1/channel/$channel/deletes", parameters = parameters).then(sharedContext) { json -> + return execute(HTTPVerb.GET, server, "loki/v1/channel/$channel/deletes", parameters = parameters).then { json -> try { val deletedMessageServerIDs = (json["data"] as List>).mapNotNull { deletion -> try { @@ -202,7 +201,7 @@ object OpenGroupAPI: DotNetAPI() { retryIfNeeded(maxRetryCount) { Log.d("Loki", "Sending message to open group with ID: $channel on server: $server.") val parameters = signedMessage.toJSON() - execute(HTTPVerb.POST, server, "channels/$channel/messages", parameters = parameters).then(sharedContext) { json -> + execute(HTTPVerb.POST, server, "channels/$channel/messages", parameters = parameters).then { json -> try { val data = json["data"] as Map<*, *> val serverID = (data["id"] as? Long) ?: (data["id"] as? Int)?.toLong() ?: (data["id"] as String).toLong() @@ -255,7 +254,7 @@ object OpenGroupAPI: DotNetAPI() { @JvmStatic fun getModerators(channel: Long, server: String): Promise, Exception> { - return execute(HTTPVerb.GET, server, "loki/v1/channel/$channel/get_moderators").then(sharedContext) { json -> + return execute(HTTPVerb.GET, server, "loki/v1/channel/$channel/get_moderators").then { json -> try { @Suppress("UNCHECKED_CAST") val moderators = json["moderators"] as? List val moderatorsAsSet = moderators.orEmpty().toSet() @@ -276,7 +275,7 @@ object OpenGroupAPI: DotNetAPI() { fun getChannelInfo(channel: Long, server: String): Promise { return retryIfNeeded(maxRetryCount) { val parameters = mapOf( "include_annotations" to 1 ) - execute(HTTPVerb.GET, server, "/channels/$channel", parameters = parameters).then(sharedContext) { json -> + execute(HTTPVerb.GET, server, "/channels/$channel", parameters = parameters).then { json -> try { val data = json["data"] as Map<*, *> val annotations = data["annotations"] as List> @@ -357,7 +356,7 @@ object OpenGroupAPI: DotNetAPI() { @JvmStatic fun getDisplayNames(publicKeys: Set, server: String): Promise, Exception> { - return getUserProfiles(publicKeys, server, false).map(sharedContext) { json -> + return getUserProfiles(publicKeys, server, false).map { json -> val mapping = mutableMapOf() for (user in json) { if (user["username"] != null) { diff --git a/libsession/src/main/java/org/session/libsession/messaging/utilities/DotNetAPI.kt b/libsession/src/main/java/org/session/libsession/messaging/utilities/DotNetAPI.kt index 562715a90a..1fac9ca922 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/utilities/DotNetAPI.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/utilities/DotNetAPI.kt @@ -23,7 +23,7 @@ import org.session.libsignal.service.internal.push.http.DigestingRequestBody import org.session.libsignal.service.internal.push.http.ProfileCipherOutputStreamFactory import org.session.libsignal.utilities.Hex import org.session.libsignal.utilities.JsonUtil -import org.session.libsignal.service.loki.api.utilities.HTTP +import org.session.libsignal.service.loki.HTTP import org.session.libsignal.service.loki.utilities.* import org.session.libsignal.utilities.* import org.session.libsignal.utilities.Base64 diff --git a/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt b/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt index 6a9bd70fdf..ba103ee42c 100644 --- a/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt +++ b/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt @@ -12,12 +12,14 @@ import org.session.libsignal.utilities.logging.Log import org.session.libsignal.utilities.Base64 import org.session.libsignal.utilities.* import org.session.libsignal.service.loki.Snode -import org.session.libsignal.service.loki.api.utilities.* +import org.session.libsignal.service.loki.* import org.session.libsession.utilities.AESGCM.EncryptionResult import org.session.libsignal.utilities.ThreadUtils import org.session.libsession.utilities.getBodyForOnionRequest import org.session.libsession.utilities.getHeadersForOnionRequest -import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol +import org.session.libsignal.service.loki.Broadcaster +import org.session.libsignal.service.loki.HTTP +import org.session.libsignal.service.loki.LokiAPIDatabaseProtocol import org.session.libsignal.service.loki.utilities.* private typealias Path = List diff --git a/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt b/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt index afb3050d99..b4209f6ff5 100644 --- a/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt +++ b/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt @@ -10,9 +10,9 @@ import org.session.libsession.messaging.utilities.MessageWrapper import org.session.libsession.snode.utilities.getRandomElement import org.session.libsignal.service.internal.push.SignalServiceProtos import org.session.libsignal.service.loki.Snode -import org.session.libsignal.service.loki.api.utilities.HTTP -import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol -import org.session.libsignal.service.loki.utilities.Broadcaster +import org.session.libsignal.service.loki.HTTP +import org.session.libsignal.service.loki.LokiAPIDatabaseProtocol +import org.session.libsignal.service.loki.Broadcaster import org.session.libsignal.service.loki.utilities.prettifiedDescription import org.session.libsignal.service.loki.utilities.removing05PrefixIfNeeded import org.session.libsignal.service.loki.utilities.retryIfNeeded diff --git a/libsession/src/main/java/org/session/libsession/snode/SnodeModule.kt b/libsession/src/main/java/org/session/libsession/snode/SnodeModule.kt index 95613ffda2..0d9381ab95 100644 --- a/libsession/src/main/java/org/session/libsession/snode/SnodeModule.kt +++ b/libsession/src/main/java/org/session/libsession/snode/SnodeModule.kt @@ -1,7 +1,7 @@ package org.session.libsession.snode -import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol -import org.session.libsignal.service.loki.utilities.Broadcaster +import org.session.libsignal.service.loki.LokiAPIDatabaseProtocol +import org.session.libsignal.service.loki.Broadcaster class SnodeModule(val storage: LokiAPIDatabaseProtocol, val broadcaster: Broadcaster) { diff --git a/libsignal/src/main/java/org/session/libsignal/service/api/crypto/SignalServiceCipher.java b/libsignal/src/main/java/org/session/libsignal/service/api/crypto/SignalServiceCipher.java index a8c2ca0bd9..5e425464ea 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/api/crypto/SignalServiceCipher.java +++ b/libsignal/src/main/java/org/session/libsignal/service/api/crypto/SignalServiceCipher.java @@ -22,7 +22,6 @@ import org.session.libsignal.service.api.messages.SignalServiceEnvelope; import org.session.libsignal.service.api.messages.SignalServiceGroup; import org.session.libsignal.service.api.messages.SignalServiceReceiptMessage; import org.session.libsignal.service.api.messages.SignalServiceTypingMessage; -import org.session.libsignal.service.api.messages.shared.SharedContact; import org.session.libsignal.service.api.push.SignalServiceAddress; import org.session.libsignal.service.internal.push.PushTransportDetails; import org.session.libsignal.service.internal.push.SignalServiceProtos; @@ -34,7 +33,7 @@ import org.session.libsignal.service.internal.push.SignalServiceProtos.ReceiptMe import org.session.libsignal.service.internal.push.SignalServiceProtos.TypingMessage; import org.session.libsignal.service.loki.api.crypto.SessionProtocol; import org.session.libsignal.service.loki.api.crypto.SessionProtocolUtilities; -import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol; +import org.session.libsignal.service.loki.LokiAPIDatabaseProtocol; import java.util.ArrayList; import java.util.LinkedList; diff --git a/libsignal/src/main/java/org/session/libsignal/service/api/messages/shared/SharedContact.java b/libsignal/src/main/java/org/session/libsignal/service/api/messages/shared/SharedContact.java index 75ee56835d..6993eb8189 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/api/messages/shared/SharedContact.java +++ b/libsignal/src/main/java/org/session/libsignal/service/api/messages/shared/SharedContact.java @@ -1,6 +1,5 @@ package org.session.libsignal.service.api.messages.shared; - import org.session.libsignal.libsignal.util.guava.Optional; import org.session.libsignal.service.api.messages.SignalServiceAttachment; diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/Broadcaster.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/Broadcaster.kt similarity index 66% rename from libsignal/src/main/java/org/session/libsignal/service/loki/utilities/Broadcaster.kt rename to libsignal/src/main/java/org/session/libsignal/service/loki/Broadcaster.kt index 17106c00b8..a251b89459 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/Broadcaster.kt +++ b/libsignal/src/main/java/org/session/libsignal/service/loki/Broadcaster.kt @@ -1,4 +1,4 @@ -package org.session.libsignal.service.loki.utilities +package org.session.libsignal.service.loki interface Broadcaster { diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/utilities/HTTP.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/HTTP.kt similarity index 98% rename from libsignal/src/main/java/org/session/libsignal/service/loki/api/utilities/HTTP.kt rename to libsignal/src/main/java/org/session/libsignal/service/loki/HTTP.kt index 29d1cddb6e..11e7ed6154 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/utilities/HTTP.kt +++ b/libsignal/src/main/java/org/session/libsignal/service/loki/HTTP.kt @@ -1,4 +1,4 @@ -package org.session.libsignal.service.loki.api.utilities +package org.session.libsignal.service.loki import okhttp3.* import org.session.libsignal.utilities.logging.Log diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/HexEncoding.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/HexEncoding.kt similarity index 100% rename from libsignal/src/main/java/org/session/libsignal/service/loki/utilities/HexEncoding.kt rename to libsignal/src/main/java/org/session/libsignal/service/loki/HexEncoding.kt diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/database/LokiAPIDatabaseProtocol.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/LokiAPIDatabaseProtocol.kt similarity index 97% rename from libsignal/src/main/java/org/session/libsignal/service/loki/database/LokiAPIDatabaseProtocol.kt rename to libsignal/src/main/java/org/session/libsignal/service/loki/LokiAPIDatabaseProtocol.kt index d564706ee8..a771b38ef9 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/database/LokiAPIDatabaseProtocol.kt +++ b/libsignal/src/main/java/org/session/libsignal/service/loki/LokiAPIDatabaseProtocol.kt @@ -1,4 +1,4 @@ -package org.session.libsignal.service.loki.database +package org.session.libsignal.service.loki import org.session.libsignal.libsignal.ecc.ECKeyPair import org.session.libsignal.service.loki.Snode diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/database/LokiMessageDatabaseProtocol.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/LokiMessageDatabaseProtocol.kt similarity index 76% rename from libsignal/src/main/java/org/session/libsignal/service/loki/database/LokiMessageDatabaseProtocol.kt rename to libsignal/src/main/java/org/session/libsignal/service/loki/LokiMessageDatabaseProtocol.kt index 45f162de63..694d989af7 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/database/LokiMessageDatabaseProtocol.kt +++ b/libsignal/src/main/java/org/session/libsignal/service/loki/LokiMessageDatabaseProtocol.kt @@ -1,4 +1,4 @@ -package org.session.libsignal.service.loki.database +package org.session.libsignal.service.loki interface LokiMessageDatabaseProtocol { diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/database/LokiOpenGroupDatabaseProtocol.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/LokiOpenGroupDatabaseProtocol.kt similarity index 76% rename from libsignal/src/main/java/org/session/libsignal/service/loki/database/LokiOpenGroupDatabaseProtocol.kt rename to libsignal/src/main/java/org/session/libsignal/service/loki/LokiOpenGroupDatabaseProtocol.kt index 5380c1a8fe..4c983e33fc 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/database/LokiOpenGroupDatabaseProtocol.kt +++ b/libsignal/src/main/java/org/session/libsignal/service/loki/LokiOpenGroupDatabaseProtocol.kt @@ -1,4 +1,4 @@ -package org.session.libsignal.service.loki.database +package org.session.libsignal.service.loki interface LokiOpenGroupDatabaseProtocol { diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/database/LokiUserDatabaseProtocol.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/LokiUserDatabaseProtocol.kt similarity index 81% rename from libsignal/src/main/java/org/session/libsignal/service/loki/database/LokiUserDatabaseProtocol.kt rename to libsignal/src/main/java/org/session/libsignal/service/loki/LokiUserDatabaseProtocol.kt index 6879ee893a..b4428a4edf 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/database/LokiUserDatabaseProtocol.kt +++ b/libsignal/src/main/java/org/session/libsignal/service/loki/LokiUserDatabaseProtocol.kt @@ -1,4 +1,4 @@ -package org.session.libsignal.service.loki.database +package org.session.libsignal.service.loki interface LokiUserDatabaseProtocol { diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/mentions/Mention.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/Mention.kt similarity index 52% rename from libsignal/src/main/java/org/session/libsignal/service/loki/utilities/mentions/Mention.kt rename to libsignal/src/main/java/org/session/libsignal/service/loki/Mention.kt index 8d97c45268..0dd2165854 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/mentions/Mention.kt +++ b/libsignal/src/main/java/org/session/libsignal/service/loki/Mention.kt @@ -1,3 +1,3 @@ -package org.session.libsignal.service.loki.utilities.mentions +package org.session.libsignal.service.loki data class Mention(val publicKey: String, val displayName: String) diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/crypto/MnemonicCodec.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/MnemonicCodec.kt similarity index 97% rename from libsignal/src/main/java/org/session/libsignal/service/loki/crypto/MnemonicCodec.kt rename to libsignal/src/main/java/org/session/libsignal/service/loki/MnemonicCodec.kt index b3c15dd132..122354f33d 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/crypto/MnemonicCodec.kt +++ b/libsignal/src/main/java/org/session/libsignal/service/loki/MnemonicCodec.kt @@ -1,6 +1,5 @@ -package org.session.libsignal.service.loki.crypto +package org.session.libsignal.service.loki -import java.io.File import java.util.zip.CRC32 /** @@ -95,8 +94,10 @@ class MnemonicCodec(private val loadFileContents: (String) -> String) { var result = "" val n = truncatedWordSet.size.toLong() // Check preconditions - if (words.size < 12) { throw DecodingError.InputTooShort } - if (words.size % 3 == 0) { throw DecodingError.MissingLastWord } + if (words.size < 12) { throw DecodingError.InputTooShort + } + if (words.size % 3 == 0) { throw DecodingError.MissingLastWord + } // Get checksum word val checksumWord = words.removeAt(words.lastIndex) // Decode @@ -106,7 +107,8 @@ class MnemonicCodec(private val loadFileContents: (String) -> String) { val w2 = truncatedWordSet.indexOf(words[chunkStartIndex + 1].substring(0 until prefixLength)) val w3 = truncatedWordSet.indexOf(words[chunkStartIndex + 2].substring(0 until prefixLength)) val x = w1 + n * ((n - w1 + w2) % n) + n * n * ((n - w2 + w3) % n) - if (x % n != w1.toLong()) { throw DecodingError.Generic } + if (x % n != w1.toLong()) { throw DecodingError.Generic + } val string = "0000000" + x.toString(16) result += swap(string.substring(string.length - 8 until string.length)) } catch (e: Exception) { @@ -116,7 +118,8 @@ class MnemonicCodec(private val loadFileContents: (String) -> String) { // Verify checksum val checksumIndex = determineChecksumIndex(words, prefixLength) val expectedChecksumWord = words[checksumIndex] - if (expectedChecksumWord.substring(0 until prefixLength) != checksumWord.substring(0 until prefixLength)) { throw DecodingError.VerificationFailed } + if (expectedChecksumWord.substring(0 until prefixLength) != checksumWord.substring(0 until prefixLength)) { throw DecodingError.VerificationFailed + } // Return return result } diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/PlaintextOutputStreamFactory.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/PlaintextOutputStreamFactory.kt similarity index 92% rename from libsignal/src/main/java/org/session/libsignal/service/loki/utilities/PlaintextOutputStreamFactory.kt rename to libsignal/src/main/java/org/session/libsignal/service/loki/PlaintextOutputStreamFactory.kt index b913289b08..412f66458f 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/PlaintextOutputStreamFactory.kt +++ b/libsignal/src/main/java/org/session/libsignal/service/loki/PlaintextOutputStreamFactory.kt @@ -1,4 +1,4 @@ -package org.session.libsignal.service.loki.utilities +package org.session.libsignal.service.loki import org.session.libsignal.service.api.crypto.DigestingOutputStream import org.session.libsignal.service.internal.push.http.OutputStreamFactory diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/PrettifiedDescription.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/PrettifiedDescription.kt similarity index 100% rename from libsignal/src/main/java/org/session/libsignal/service/loki/utilities/PrettifiedDescription.kt rename to libsignal/src/main/java/org/session/libsignal/service/loki/PrettifiedDescription.kt diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/Random.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/Random.kt similarity index 100% rename from libsignal/src/main/java/org/session/libsignal/service/loki/utilities/Random.kt rename to libsignal/src/main/java/org/session/libsignal/service/loki/Random.kt diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/Reflection.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/Reflection.kt similarity index 100% rename from libsignal/src/main/java/org/session/libsignal/service/loki/utilities/Reflection.kt rename to libsignal/src/main/java/org/session/libsignal/service/loki/Reflection.kt diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/Retrying.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/Retrying.kt similarity index 100% rename from libsignal/src/main/java/org/session/libsignal/service/loki/utilities/Retrying.kt rename to libsignal/src/main/java/org/session/libsignal/service/loki/Retrying.kt diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/crypto/SessionProtocol.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/SessionProtocol.kt similarity index 97% rename from libsignal/src/main/java/org/session/libsignal/service/loki/api/crypto/SessionProtocol.kt rename to libsignal/src/main/java/org/session/libsignal/service/loki/SessionProtocol.kt index 3851919052..201ad4e85d 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/crypto/SessionProtocol.kt +++ b/libsignal/src/main/java/org/session/libsignal/service/loki/SessionProtocol.kt @@ -1,7 +1,7 @@ package org.session.libsignal.service.loki.api.crypto import org.session.libsignal.libsignal.ecc.ECKeyPair -import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol +import org.session.libsignal.service.loki.LokiAPIDatabaseProtocol interface SessionProtocol { diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/SignalMessageInfo.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/SignalMessageInfo.kt similarity index 88% rename from libsignal/src/main/java/org/session/libsignal/service/loki/api/SignalMessageInfo.kt rename to libsignal/src/main/java/org/session/libsignal/service/loki/SignalMessageInfo.kt index 5b41d26a5f..f5e20f4168 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/SignalMessageInfo.kt +++ b/libsignal/src/main/java/org/session/libsignal/service/loki/SignalMessageInfo.kt @@ -1,4 +1,4 @@ -package org.session.libsignal.service.loki.api +package org.session.libsignal.service.loki import org.session.libsignal.service.internal.push.SignalServiceProtos diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/Trimming.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/Trimming.kt similarity index 100% rename from libsignal/src/main/java/org/session/libsignal/service/loki/utilities/Trimming.kt rename to libsignal/src/main/java/org/session/libsignal/service/loki/Trimming.kt diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/Validation.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/Validation.kt similarity index 100% rename from libsignal/src/main/java/org/session/libsignal/service/loki/utilities/Validation.kt rename to libsignal/src/main/java/org/session/libsignal/service/loki/Validation.kt diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/utilities/OKHTTPUtilities.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/api/utilities/OKHTTPUtilities.kt deleted file mode 100644 index 442edc5549..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/utilities/OKHTTPUtilities.kt +++ /dev/null @@ -1,49 +0,0 @@ -package org.session.libsignal.service.loki.api.utilities - -import okhttp3.MultipartBody -import okhttp3.Request -import okio.Buffer -import org.session.libsignal.utilities.Base64 -import java.io.IOException -import java.util.* - -internal fun Request.getHeadersForOnionRequest(): Map { - val result = mutableMapOf() - val contentType = body()?.contentType() - if (contentType != null) { - result["content-type"] = contentType.toString() - } - val headers = headers() - for (name in headers.names()) { - val value = headers.get(name) - if (value != null) { - if (value.toLowerCase(Locale.US) == "true" || value.toLowerCase(Locale.US) == "false") { - result[name] = value.toBoolean() - } else if (value.toIntOrNull() != null) { - result[name] = value.toInt() - } else { - result[name] = value - } - } - } - return result -} - -internal fun Request.getBodyForOnionRequest(): Any? { - try { - val copyOfThis = newBuilder().build() - val buffer = Buffer() - val body = copyOfThis.body() ?: return null - body.writeTo(buffer) - val bodyAsData = buffer.readByteArray() - if (body is MultipartBody) { - val base64EncodedBody: String = Base64.encodeBytes(bodyAsData) - return mapOf( "fileUpload" to base64EncodedBody ) - } else { - val charset = body.contentType()?.charset() ?: Charsets.UTF_8 - return bodyAsData?.toString(charset) - } - } catch (e: IOException) { - return null - } -} diff --git a/libsignal/src/main/java/org/session/libsignal/utilities/JsonUtil.java b/libsignal/src/main/java/org/session/libsignal/utilities/JsonUtil.java index b20a870d10..f5767a8da2 100644 --- a/libsignal/src/main/java/org/session/libsignal/utilities/JsonUtil.java +++ b/libsignal/src/main/java/org/session/libsignal/utilities/JsonUtil.java @@ -58,7 +58,7 @@ public class JsonUtil { return objectMapper.writeValueAsString(object); } - public static String toJson(Object object) { + public static String toJson(Object object) { try { return objectMapper.writeValueAsString(object); } catch (JsonProcessingException e) { @@ -67,32 +67,11 @@ public class JsonUtil { } } - public static class IdentityKeySerializer extends JsonSerializer { - @Override - public void serialize(IdentityKey value, JsonGenerator gen, SerializerProvider serializers) - throws IOException - { - gen.writeString(Base64.encodeBytesWithoutPadding(value.serialize())); - } - } - - public static class IdentityKeyDeserializer extends JsonDeserializer { - @Override - public IdentityKey deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { - try { - return new IdentityKey(Base64.decodeWithoutPadding(p.getValueAsString()), 0); - } catch (InvalidKeyException e) { - throw new IOException(e); - } - } - } - public static ObjectMapper getMapper() { return objectMapper; } public static class SaneJSONObject { - private final JSONObject delegate; public SaneJSONObject(JSONObject delegate) { diff --git a/libsignal/src/main/java/org/session/libsignal/utilities/PromiseUtilities.kt b/libsignal/src/main/java/org/session/libsignal/utilities/PromiseUtilities.kt index 8fe7ce7355..530d432d57 100644 --- a/libsignal/src/main/java/org/session/libsignal/utilities/PromiseUtilities.kt +++ b/libsignal/src/main/java/org/session/libsignal/utilities/PromiseUtilities.kt @@ -1,25 +1,11 @@ @file:JvmName("PromiseUtilities") package org.session.libsignal.utilities -import nl.komponents.kovenant.Context -import nl.komponents.kovenant.Kovenant import nl.komponents.kovenant.Promise import nl.komponents.kovenant.deferred -import nl.komponents.kovenant.jvm.asDispatcher import org.session.libsignal.utilities.logging.Log -import java.util.concurrent.Executors import java.util.concurrent.TimeoutException -fun Kovenant.createContext(): Context { - return createContext { - callbackContext.dispatcher = Executors.newSingleThreadExecutor().asDispatcher() - workerContext.dispatcher = ThreadUtils.executorPool.asDispatcher() - multipleCompletion = { v1, v2 -> - Log.d("Loki", "Promise resolved more than once (first with $v1, then with $v2); ignoring $v2.") - } - } -} - fun Promise.get(defaultValue: V): V { return try { get() diff --git a/libsignal/src/main/java/org/session/libsignal/utilities/ThreadUtils.kt b/libsignal/src/main/java/org/session/libsignal/utilities/ThreadUtils.kt index 1ad277f345..9436a54832 100644 --- a/libsignal/src/main/java/org/session/libsignal/utilities/ThreadUtils.kt +++ b/libsignal/src/main/java/org/session/libsignal/utilities/ThreadUtils.kt @@ -3,7 +3,6 @@ package org.session.libsignal.utilities import java.util.concurrent.* object ThreadUtils { - val executorPool = Executors.newCachedThreadPool() @JvmStatic @@ -17,10 +16,8 @@ object ThreadUtils { @JvmStatic fun newDynamicSingleThreadedExecutor(): ExecutorService { - val executor = ThreadPoolExecutor(1, 1, 60, TimeUnit.SECONDS, - LinkedBlockingQueue()) + val executor = ThreadPoolExecutor(1, 1, 60, TimeUnit.SECONDS, LinkedBlockingQueue()) executor.allowCoreThreadTimeOut(true) return executor } - } \ No newline at end of file From a822c74ecc70e932e3989c9ea8a8401ef6dd1dfb Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Thu, 29 Apr 2021 10:10:41 +1000 Subject: [PATCH 15/15] Use global Kovenant config --- .../org/thoughtcrime/securesms/AppContext.kt | 20 +++++++++++++++++++ .../securesms/ApplicationContext.java | 2 ++ 2 files changed, 22 insertions(+) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/AppContext.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/AppContext.kt b/app/src/main/java/org/thoughtcrime/securesms/AppContext.kt new file mode 100644 index 0000000000..206e794605 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/AppContext.kt @@ -0,0 +1,20 @@ +package org.thoughtcrime.securesms + +import android.util.Log +import nl.komponents.kovenant.Kovenant +import nl.komponents.kovenant.jvm.asDispatcher +import org.session.libsignal.utilities.ThreadUtils +import java.util.concurrent.Executors + +object AppContext { + + fun configureKovenant() { + Kovenant.context { + callbackContext.dispatcher = Executors.newSingleThreadExecutor().asDispatcher() + workerContext.dispatcher = ThreadUtils.executorPool.asDispatcher() + multipleCompletion = { v1, v2 -> + Log.d("Loki", "Promise resolved more than once (first with $v1, then with $v2); ignoring $v2.") + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index 00a2c4f01f..33e55e18d3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -103,6 +103,7 @@ import dagger.ObjectGraph; import kotlin.Unit; import kotlinx.coroutines.Job; import network.loki.messenger.BuildConfig; +import nl.komponents.kovenant.Kovenant; import static nl.komponents.kovenant.android.KovenantAndroid.startKovenant; import static nl.komponents.kovenant.android.KovenantAndroid.stopKovenant; @@ -163,6 +164,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc ProcessLifecycleOwner.get().getLifecycle().addObserver(this); // Loki // ======== + AppContext.INSTANCE.configureKovenant(); messageNotifier = new OptimizedMessageNotifier(new DefaultMessageNotifier()); broadcaster = new Broadcaster(this); threadNotificationHandler = new Handler(Looper.getMainLooper());