]> nmode's Git Repositories - signal-cli/blobdiff - src/main/java/org/asamk/signal/manager/Manager.java
Use getRegisteredUsers instead of getContacts for updating v1 group
[signal-cli] / src / main / java / org / asamk / signal / manager / Manager.java
index a0f6aa532a1ef2313eb4deaf1fdf5b3a3eb3c1a3..ec427ce39ecfa8dea405581ce1200163d7dfa09d 100644 (file)
@@ -121,7 +121,6 @@ import org.whispersystems.signalservice.api.messages.multidevice.StickerPackOper
 import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage;
 import org.whispersystems.signalservice.api.profiles.ProfileAndCredential;
 import org.whispersystems.signalservice.api.profiles.SignalServiceProfile;
-import org.whispersystems.signalservice.api.push.ContactTokenDetails;
 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
 import org.whispersystems.signalservice.api.push.exceptions.MissingConfigurationException;
 import org.whispersystems.signalservice.api.util.InvalidNumberException;
@@ -288,6 +287,22 @@ public class Manager implements Closeable {
         return new Manager(account, pathConfig, serviceConfiguration, userAgent);
     }
 
+    public static List<String> getAllLocalUsernames(File settingsPath) {
+        PathConfig pathConfig = PathConfig.createDefault(settingsPath);
+        final File dataPath = pathConfig.getDataPath();
+        final File[] files = dataPath.listFiles();
+
+        if (files == null) {
+            return List.of();
+        }
+
+        return Arrays.stream(files)
+                .filter(File::isFile)
+                .map(File::getName)
+                .filter(file -> PhoneNumberFormatter.isValidNumber(file, null))
+                .collect(Collectors.toList());
+    }
+
     public void checkAccountState() throws IOException {
         if (accountManager.getPreKeysCount() < ServiceConfig.PREKEY_MINIMUM_COUNT) {
             refreshPreKeys();
@@ -309,11 +324,9 @@ public class Manager implements Closeable {
      */
     public Map<String, Boolean> areUsersRegistered(Set<String> numbers) throws IOException {
         // Note "contactDetails" has no optionals. It only gives us info on users who are registered
-        List<ContactTokenDetails> contactDetails = this.accountManager.getContacts(numbers);
+        Map<String, UUID> contactDetails = getRegisteredUsers(numbers);
 
-        Set<String> registeredUsers = contactDetails.stream()
-                .map(ContactTokenDetails::getNumber)
-                .collect(Collectors.toSet());
+        Set<String> registeredUsers = contactDetails.keySet();
 
         return numbers.stream().collect(Collectors.toMap(x -> x, registeredUsers::contains));
     }
@@ -759,12 +772,10 @@ public class Manager implements Closeable {
                 newE164Members.add(member.getNumber().get());
             }
 
-            final List<ContactTokenDetails> contacts = accountManager.getContacts(newE164Members);
-            if (contacts.size() != newE164Members.size()) {
+            final Map<String, UUID> registeredUsers = getRegisteredUsers(newE164Members);
+            if (registeredUsers.size() != newE164Members.size()) {
                 // Some of the new members are not registered on Signal
-                for (ContactTokenDetails contact : contacts) {
-                    newE164Members.remove(contact.getNumber());
-                }
+                newE164Members.removeAll(registeredUsers.keySet());
                 throw new IOException("Failed to add members "
                         + String.join(", ", newE164Members)
                         + " to group: Not registered on Signal");
@@ -937,6 +948,17 @@ public class Manager implements Closeable {
         return sendMessage(messageBuilder, getSignalServiceAddresses(recipients));
     }
 
+    public Pair<Long, SendMessageResult> sendSelfMessage(
+            String messageText, List<String> attachments
+    ) throws IOException, AttachmentInvalidException {
+        final SignalServiceDataMessage.Builder messageBuilder = SignalServiceDataMessage.newBuilder()
+                .withBody(messageText);
+        if (attachments != null) {
+            messageBuilder.withAttachments(AttachmentUtils.getSignalServiceAttachments(attachments));
+        }
+        return sendSelfMessage(messageBuilder);
+    }
+
     public Pair<Long, List<SendMessageResult>> sendMessageReaction(
             String emoji, boolean remove, String targetAuthor, long targetSentTimestamp, List<String> recipients
     ) throws IOException, InvalidNumberException {
@@ -1157,28 +1179,29 @@ public class Manager implements Closeable {
 
     private Collection<SignalServiceAddress> getSignalServiceAddresses(Collection<String> numbers) throws InvalidNumberException {
         final Set<SignalServiceAddress> signalServiceAddresses = new HashSet<>(numbers.size());
-        final Set<SignalServiceAddress> missingUuids = new HashSet<>();
+        final Set<SignalServiceAddress> addressesMissingUuid = new HashSet<>();
 
         for (String number : numbers) {
             final SignalServiceAddress resolvedAddress = canonicalizeAndResolveSignalServiceAddress(number);
             if (resolvedAddress.getUuid().isPresent()) {
                 signalServiceAddresses.add(resolvedAddress);
             } else {
-                missingUuids.add(resolvedAddress);
+                addressesMissingUuid.add(resolvedAddress);
             }
         }
 
+        final Set<String> numbersMissingUuid = addressesMissingUuid.stream()
+                .map(a -> a.getNumber().get())
+                .collect(Collectors.toSet());
         Map<String, UUID> registeredUsers;
         try {
-            registeredUsers = accountManager.getRegisteredUsers(getIasKeyStore(),
-                    missingUuids.stream().map(a -> a.getNumber().get()).collect(Collectors.toSet()),
-                    CDS_MRENCLAVE);
-        } catch (IOException | Quote.InvalidQuoteFormatException | UnauthenticatedQuoteException | SignatureException | UnauthenticatedResponseException e) {
+            registeredUsers = getRegisteredUsers(numbersMissingUuid);
+        } catch (IOException e) {
             logger.warn("Failed to resolve uuids from server, ignoring: {}", e.getMessage());
-            registeredUsers = new HashMap<>();
+            registeredUsers = Map.of();
         }
 
-        for (SignalServiceAddress address : missingUuids) {
+        for (SignalServiceAddress address : addressesMissingUuid) {
             final String number = address.getNumber().get();
             if (registeredUsers.containsKey(number)) {
                 final SignalServiceAddress newAddress = resolveSignalServiceAddress(new SignalServiceAddress(
@@ -1193,6 +1216,14 @@ public class Manager implements Closeable {
         return signalServiceAddresses;
     }
 
+    private Map<String, UUID> getRegisteredUsers(final Set<String> numbersMissingUuid) throws IOException {
+        try {
+            return accountManager.getRegisteredUsers(getIasKeyStore(), numbersMissingUuid, CDS_MRENCLAVE);
+        } catch (Quote.InvalidQuoteFormatException | UnauthenticatedQuoteException | SignatureException | UnauthenticatedResponseException e) {
+            throw new IOException(e);
+        }
+    }
+
     private Pair<Long, List<SendMessageResult>> sendMessage(
             SignalServiceDataMessage.Builder messageBuilder, Collection<SignalServiceAddress> recipients
     ) throws IOException {
@@ -1237,11 +1268,7 @@ public class Manager implements Closeable {
                     final int expirationTime = contact != null ? contact.messageExpirationTime : 0;
                     messageBuilder.withExpiration(expirationTime);
                     message = messageBuilder.build();
-                    if (address.matches(account.getSelfAddress())) {
-                        results.add(sendSelfMessage(message));
-                    } else {
-                        results.add(sendMessage(address, message));
-                    }
+                    results.add(sendMessage(address, message));
                 }
                 return new Pair<>(timestamp, results);
             }
@@ -1255,6 +1282,28 @@ public class Manager implements Closeable {
         }
     }
 
+    private Pair<Long, SendMessageResult> sendSelfMessage(
+            SignalServiceDataMessage.Builder messageBuilder
+    ) throws IOException {
+        final long timestamp = System.currentTimeMillis();
+        messageBuilder.withTimestamp(timestamp);
+        getOrCreateMessagePipe();
+        getOrCreateUnidentifiedMessagePipe();
+        try {
+            final SignalServiceAddress address = getSelfAddress();
+
+            final ContactInfo contact = account.getContactStore().getContact(address);
+            final int expirationTime = contact != null ? contact.messageExpirationTime : 0;
+            messageBuilder.withExpiration(expirationTime);
+
+            SignalServiceDataMessage message = messageBuilder.build();
+            final SendMessageResult result = sendSelfMessage(message);
+            return new Pair<>(timestamp, result);
+        } finally {
+            account.save();
+        }
+    }
+
     private SendMessageResult sendSelfMessage(SignalServiceDataMessage message) throws IOException {
         SignalServiceMessageSender messageSender = createMessageSender();