]> nmode's Git Repositories - signal-cli/blobdiff - src/main/java/org/asamk/signal/manager/Manager.java
Use base64 group id for protobuf group file to match avatar files
[signal-cli] / src / main / java / org / asamk / signal / manager / Manager.java
index b5d425d8d4b8881e63a55091139f3badfcb5cbaa..2553a416ce02bf297d0533b60d47c391825ddecf 100644 (file)
@@ -816,7 +816,10 @@ public class Manager implements Closeable {
 
                 if (members != null) {
                     final Set<SignalServiceAddress> newMembers = new HashSet<>(members);
-                    newMembers.removeAll(group.getMembers());
+                    newMembers.removeAll(group.getMembers()
+                            .stream()
+                            .map(this::resolveSignalServiceAddress)
+                            .collect(Collectors.toSet()));
                     if (newMembers.size() > 0) {
                         Pair<DecryptedGroup, GroupChange> groupGroupChangePair = groupHelper.updateGroupV2(groupInfoV2,
                                 newMembers);
@@ -1621,7 +1624,7 @@ public class Manager implements Closeable {
         }
 
         final SignalServiceAddress conversationPartnerAddress = isSync ? destination : source;
-        if (message.isEndSession()) {
+        if (conversationPartnerAddress != null && message.isEndSession()) {
             handleEndSession(conversationPartnerAddress);
         }
         if (message.isExpirationUpdate() || message.getBody().isPresent()) {
@@ -1638,7 +1641,7 @@ public class Manager implements Closeable {
                 } else if (message.getGroupContext().get().getGroupV2().isPresent()) {
                     // disappearing message timer already stored in the DecryptedGroup
                 }
-            } else {
+            } else if (conversationPartnerAddress != null) {
                 ContactInfo contact = account.getContactStore().getContact(conversationPartnerAddress);
                 if (contact == null) {
                     contact = new ContactInfo(conversationPartnerAddress);
@@ -1754,6 +1757,11 @@ public class Manager implements Closeable {
             }
             if (group != null) {
                 storeProfileKeysFromMembers(group);
+                try {
+                    retrieveGroupAvatar(groupId, groupSecretParams, group.getAvatar());
+                } catch (IOException e) {
+                    System.err.println("Failed to download group avatar, ignoring ...");
+                }
             }
             groupInfoV2.setGroup(group);
             account.getGroupStore().updateGroup(groupInfoV2);
@@ -2020,13 +2028,11 @@ public class Manager implements Closeable {
                 if (syncMessage.getSent().isPresent()) {
                     SentTranscriptMessage message = syncMessage.getSent().get();
                     final SignalServiceAddress destination = message.getDestination().orNull();
-                    if (destination != null) {
-                        actions.addAll(handleSignalServiceDataMessage(message.getMessage(),
-                                true,
-                                sender,
-                                destination,
-                                ignoreAttachments));
-                    }
+                    actions.addAll(handleSignalServiceDataMessage(message.getMessage(),
+                            true,
+                            sender,
+                            destination,
+                            ignoreAttachments));
                 }
                 if (syncMessage.getRequest().isPresent()) {
                     RequestMessage rm = syncMessage.getRequest().get();
@@ -2246,6 +2252,35 @@ public class Manager implements Closeable {
         }
     }
 
+    private File retrieveGroupAvatar(
+            GroupId groupId, GroupSecretParams groupSecretParams, String cdnKey
+    ) throws IOException {
+        IOUtils.createPrivateDirectories(pathConfig.getAvatarsPath());
+        SignalServiceMessageReceiver receiver = getOrCreateMessageReceiver();
+        File outputFile = getGroupAvatarFile(groupId);
+        GroupsV2Operations.GroupOperations groupOperations = groupsV2Operations.forGroup(groupSecretParams);
+
+        File tmpFile = IOUtils.createTempFile();
+        tmpFile.deleteOnExit();
+        try (InputStream input = receiver.retrieveGroupsV2ProfileAvatar(cdnKey,
+                tmpFile,
+                ServiceConfig.AVATAR_DOWNLOAD_FAILSAFE_MAX_SIZE)) {
+            byte[] encryptedData = IOUtils.readFully(input);
+
+            byte[] decryptedData = groupOperations.decryptAvatar(encryptedData);
+            try (OutputStream output = new FileOutputStream(outputFile)) {
+                output.write(decryptedData);
+            }
+        } finally {
+            try {
+                Files.delete(tmpFile.toPath());
+            } catch (IOException e) {
+                System.err.println("Failed to delete received avatar temp file “" + tmpFile + "”: " + e.getMessage());
+            }
+        }
+        return outputFile;
+    }
+
     private File getProfileAvatarFile(SignalServiceAddress address) {
         return new File(pathConfig.getAvatarsPath(), "profile-" + address.getLegacyIdentifier());
     }