X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/a4e22539a3d87262f43d399fbd79823c4dc2fde0..1bae3ba6f04e608724ea55feb65d3909c3536b79:/src/main/java/org/asamk/signal/Manager.java diff --git a/src/main/java/org/asamk/signal/Manager.java b/src/main/java/org/asamk/signal/Manager.java index 42f5ba85..1aefc252 100644 --- a/src/main/java/org/asamk/signal/Manager.java +++ b/src/main/java/org/asamk/signal/Manager.java @@ -107,6 +107,7 @@ class Manager implements Signal { private SignalServiceAccountManager accountManager; private JsonGroupStore groupStore; private JsonContactsStore contactStore; + private JsonThreadStore threadStore; public Manager(String username, String settingsPath) { this.username = username; @@ -267,6 +268,13 @@ class Manager implements Signal { if (contactStore == null) { contactStore = new JsonContactsStore(); } + JsonNode threadStoreNode = rootNode.get("threadStore"); + if (threadStoreNode != null) { + threadStore = jsonProcessor.convertValue(threadStoreNode, JsonThreadStore.class); + } + if (threadStore == null) { + threadStore = new JsonThreadStore(); + } } private void migrateLegacyConfigs() { @@ -305,6 +313,7 @@ class Manager implements Signal { .putPOJO("axolotlStore", signalProtocolStore) .putPOJO("groupStore", groupStore) .putPOJO("contactStore", contactStore) + .putPOJO("threadStore", threadStore) ; try { openFileChannel(); @@ -572,14 +581,17 @@ class Manager implements Signal { .build(); messageBuilder.asGroupMessage(group); } - SignalServiceDataMessage message = messageBuilder.build(); + ThreadInfo thread = threadStore.getThread(Base64.encodeBytes(groupId)); + if (thread != null) { + messageBuilder.withExpiration(thread.messageExpirationTime); + } final GroupInfo g = getGroupForSending(groupId); // Don't send group message to ourself final List membersSend = new ArrayList<>(g.members); membersSend.remove(this.username); - sendMessage(message, membersSend); + sendMessage(messageBuilder, membersSend); } public void sendQuitGroupMessage(byte[] groupId) throws GroupNotFoundException, IOException, EncapsulatedExceptions { @@ -587,15 +599,14 @@ class Manager implements Signal { .withId(groupId) .build(); - SignalServiceDataMessage message = SignalServiceDataMessage.newBuilder() - .asGroupMessage(group) - .build(); + SignalServiceDataMessage.Builder messageBuilder = SignalServiceDataMessage.newBuilder() + .asGroupMessage(group); final GroupInfo g = getGroupForSending(groupId); g.members.remove(this.username); groupStore.updateGroup(g); - sendMessage(message, g.members); + sendMessage(messageBuilder, g.members); } private static String join(CharSequence separator, Iterable list) { @@ -672,14 +683,13 @@ class Manager implements Signal { groupStore.updateGroup(g); - SignalServiceDataMessage message = SignalServiceDataMessage.newBuilder() - .asGroupMessage(group.build()) - .build(); + SignalServiceDataMessage.Builder messageBuilder = SignalServiceDataMessage.newBuilder() + .asGroupMessage(group.build()); // Don't send group message to ourself final List membersSend = new ArrayList<>(g.members); membersSend.remove(this.username); - sendMessage(message, membersSend); + sendMessage(messageBuilder, membersSend); return g.groupId; } @@ -699,25 +709,22 @@ class Manager implements Signal { if (attachments != null) { messageBuilder.withAttachments(getSignalServiceAttachments(attachments)); } - SignalServiceDataMessage message = messageBuilder.build(); - - sendMessage(message, recipients); + sendMessage(messageBuilder, recipients); } @Override public void sendEndSessionMessage(List recipients) throws IOException, EncapsulatedExceptions { - SignalServiceDataMessage message = SignalServiceDataMessage.newBuilder() - .asEndSessionMessage() - .build(); + SignalServiceDataMessage.Builder messageBuilder = SignalServiceDataMessage.newBuilder() + .asEndSessionMessage(); - sendMessage(message, recipients); + sendMessage(messageBuilder, recipients); } private void requestSyncGroups() throws IOException { SignalServiceProtos.SyncMessage.Request r = SignalServiceProtos.SyncMessage.Request.newBuilder().setType(SignalServiceProtos.SyncMessage.Request.Type.GROUPS).build(); SignalServiceSyncMessage message = SignalServiceSyncMessage.forRequest(new RequestMessage(r)); try { - sendMessage(message); + sendSyncMessage(message); } catch (UntrustedIdentityException e) { e.printStackTrace(); } @@ -727,13 +734,13 @@ class Manager implements Signal { SignalServiceProtos.SyncMessage.Request r = SignalServiceProtos.SyncMessage.Request.newBuilder().setType(SignalServiceProtos.SyncMessage.Request.Type.CONTACTS).build(); SignalServiceSyncMessage message = SignalServiceSyncMessage.forRequest(new RequestMessage(r)); try { - sendMessage(message); + sendSyncMessage(message); } catch (UntrustedIdentityException e) { e.printStackTrace(); } } - private void sendMessage(SignalServiceSyncMessage message) + private void sendSyncMessage(SignalServiceSyncMessage message) throws IOException, UntrustedIdentityException { SignalServiceMessageSender messageSender = new SignalServiceMessageSender(URL, TRUST_STORE, username, password, deviceId, signalProtocolStore, USER_AGENT, Optional.absent()); @@ -745,24 +752,17 @@ class Manager implements Signal { } } - private void sendMessage(SignalServiceDataMessage message, Collection recipients) + private void sendMessage(SignalServiceDataMessage.Builder messageBuilder, Collection recipients) throws EncapsulatedExceptions, IOException { - Set recipientsTS = new HashSet<>(recipients.size()); - for (String recipient : recipients) { - try { - recipientsTS.add(getPushAddress(recipient)); - } catch (InvalidNumberException e) { - System.err.println("Failed to add recipient \"" + recipient + "\": " + e.getMessage()); - System.err.println("Aborting sending."); - save(); - return; - } - } + Set recipientsTS = getSignalServiceAddresses(recipients); + if (recipientsTS == null) return; + SignalServiceDataMessage message = null; try { SignalServiceMessageSender messageSender = new SignalServiceMessageSender(URL, TRUST_STORE, username, password, deviceId, signalProtocolStore, USER_AGENT, Optional.absent()); + message = messageBuilder.build(); if (message.getGroupInfo().isPresent()) { try { messageSender.sendMessage(new ArrayList<>(recipientsTS), message); @@ -777,6 +777,13 @@ class Manager implements Signal { List unregisteredUsers = new LinkedList<>(); List networkExceptions = new LinkedList<>(); for (SignalServiceAddress address : recipientsTS) { + ThreadInfo thread = threadStore.getThread(address.getNumber()); + if (thread != null) { + messageBuilder.withExpiration(thread.messageExpirationTime); + } else { + messageBuilder.withExpiration(0); + } + message = messageBuilder.build(); try { messageSender.sendMessage(address, message); } catch (UntrustedIdentityException e) { @@ -793,7 +800,7 @@ class Manager implements Signal { } } } finally { - if (message.isEndSession()) { + if (message != null && message.isEndSession()) { for (SignalServiceAddress recipient : recipientsTS) { handleEndSession(recipient.getNumber()); } @@ -802,6 +809,21 @@ class Manager implements Signal { } } + private Set getSignalServiceAddresses(Collection recipients) { + Set recipientsTS = new HashSet<>(recipients.size()); + for (String recipient : recipients) { + try { + recipientsTS.add(getPushAddress(recipient)); + } catch (InvalidNumberException e) { + System.err.println("Failed to add recipient \"" + recipient + "\": " + e.getMessage()); + System.err.println("Aborting sending."); + save(); + return null; + } + } + return recipientsTS; + } + private SignalServiceContent decryptMessage(SignalServiceEnvelope envelope) throws NoSessionException, LegacyMessageException, InvalidVersionException, InvalidMessageException, DuplicateMessageException, InvalidKeyException, InvalidKeyIdException, org.whispersystems.libsignal.UntrustedIdentityException { SignalServiceCipher cipher = new SignalServiceCipher(new SignalServiceAddress(username), signalProtocolStore); try { @@ -821,8 +843,10 @@ class Manager implements Signal { } private void handleSignalServiceDataMessage(SignalServiceDataMessage message, boolean isSync, String source, String destination) { + String threadId; if (message.getGroupInfo().isPresent()) { SignalServiceGroup groupInfo = message.getGroupInfo().get(); + threadId = Base64.encodeBytes(groupInfo.getGroupId()); switch (groupInfo.getType()) { case UPDATE: GroupInfo group; @@ -862,10 +886,27 @@ class Manager implements Signal { } break; } + } else { + if (isSync) { + threadId = destination; + } else { + threadId = source; + } } if (message.isEndSession()) { handleEndSession(isSync ? destination : source); } + if (message.isExpirationUpdate() || message.getBody().isPresent()) { + ThreadInfo thread = threadStore.getThread(threadId); + if (thread == null) { + thread = new ThreadInfo(); + thread.id = threadId; + } + if (thread.messageExpirationTime != message.getExpiresInSeconds()) { + thread.messageExpirationTime = message.getExpiresInSeconds(); + threadStore.updateThread(thread); + } + } if (message.getAttachments().isPresent()) { for (SignalServiceAttachment attachment : message.getAttachments().get()) { if (attachment.isPointer()) { @@ -1273,7 +1314,7 @@ class Manager implements Signal { .withLength(groupsFile.length()) .build(); - sendMessage(SignalServiceSyncMessage.forGroups(attachmentStream)); + sendSyncMessage(SignalServiceSyncMessage.forGroups(attachmentStream)); } } finally { groupsFile.delete(); @@ -1302,7 +1343,7 @@ class Manager implements Signal { .withLength(contactsFile.length()) .build(); - sendMessage(SignalServiceSyncMessage.forContacts(attachmentStream)); + sendSyncMessage(SignalServiceSyncMessage.forContacts(attachmentStream)); } } finally { contactsFile.delete();