]> nmode's Git Repositories - signal-cli/blobdiff - src/main/java/org/asamk/signal/storage/SignalAccount.java
Output json when receiving messages from dbus and --json parameter is given
[signal-cli] / src / main / java / org / asamk / signal / storage / SignalAccount.java
index 6d83f78f999933ac19d498d802adb64e0ea74bd5..f03bac3a9d0bf85edc4a347a67601fe3184c1b80 100644 (file)
@@ -14,7 +14,11 @@ import org.asamk.signal.storage.contacts.ContactInfo;
 import org.asamk.signal.storage.contacts.JsonContactsStore;
 import org.asamk.signal.storage.groups.GroupInfo;
 import org.asamk.signal.storage.groups.JsonGroupStore;
+import org.asamk.signal.storage.protocol.JsonIdentityKeyStore;
 import org.asamk.signal.storage.protocol.JsonSignalProtocolStore;
+import org.asamk.signal.storage.protocol.RecipientStore;
+import org.asamk.signal.storage.protocol.SessionInfo;
+import org.asamk.signal.storage.protocol.SignalServiceAddressResolver;
 import org.asamk.signal.storage.threads.LegacyJsonThreadStore;
 import org.asamk.signal.storage.threads.ThreadInfo;
 import org.asamk.signal.util.IOUtils;
@@ -36,6 +40,7 @@ import java.nio.channels.FileChannel;
 import java.nio.channels.FileLock;
 import java.util.Collection;
 import java.util.UUID;
+import java.util.stream.Collectors;
 
 public class SignalAccount {
 
@@ -58,6 +63,7 @@ public class SignalAccount {
     private JsonSignalProtocolStore signalProtocolStore;
     private JsonGroupStore groupStore;
     private JsonContactsStore contactStore;
+    private RecipientStore recipientStore;
 
     private SignalAccount() {
         jsonProcessor.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE); // disable autodetect
@@ -87,18 +93,20 @@ public class SignalAccount {
         account.signalProtocolStore = new JsonSignalProtocolStore(identityKey, registrationId);
         account.groupStore = new JsonGroupStore();
         account.contactStore = new JsonContactsStore();
+        account.recipientStore = new RecipientStore();
         account.registered = false;
 
         return account;
     }
 
-    public static SignalAccount createLinkedAccount(String dataPath, String username, String password, int deviceId, IdentityKeyPair identityKey, int registrationId, String signalingKey, ProfileKey profileKey) throws IOException {
+    public static SignalAccount createLinkedAccount(String dataPath, String username, UUID uuid, String password, int deviceId, IdentityKeyPair identityKey, int registrationId, String signalingKey, ProfileKey profileKey) throws IOException {
         IOUtils.createPrivateDirectories(dataPath);
 
         SignalAccount account = new SignalAccount();
         account.openFileChannel(getFileName(dataPath, username));
 
         account.username = username;
+        account.uuid = uuid;
         account.password = password;
         account.profileKey = profileKey;
         account.deviceId = deviceId;
@@ -106,6 +114,7 @@ public class SignalAccount {
         account.signalProtocolStore = new JsonSignalProtocolStore(identityKey, registrationId);
         account.groupStore = new JsonGroupStore();
         account.contactStore = new JsonContactsStore();
+        account.recipientStore = new RecipientStore();
         account.registered = true;
         account.isMultiDevice = true;
 
@@ -140,6 +149,14 @@ public class SignalAccount {
             rootNode = jsonProcessor.readTree(Channels.newInputStream(fileChannel));
         }
 
+        JsonNode uuidNode = rootNode.get("uuid");
+        if (uuidNode != null && !uuidNode.isNull()) {
+            try {
+                uuid = UUID.fromString(uuidNode.asText());
+            } catch (IllegalArgumentException e) {
+                throw new IOException("Config file contains an invalid uuid, needs to be a valid UUID", e);
+            }
+        }
         JsonNode node = rootNode.get("deviceId");
         if (node != null) {
             deviceId = node.asInt();
@@ -189,11 +206,43 @@ public class SignalAccount {
         if (contactStore == null) {
             contactStore = new JsonContactsStore();
         }
+
+        JsonNode recipientStoreNode = rootNode.get("recipientStore");
+        if (recipientStoreNode != null) {
+            recipientStore = jsonProcessor.convertValue(recipientStoreNode, RecipientStore.class);
+        }
+        if (recipientStore == null) {
+            recipientStore = new RecipientStore();
+
+            recipientStore.resolveServiceAddress(getSelfAddress());
+
+            for (ContactInfo contact : contactStore.getContacts()) {
+                recipientStore.resolveServiceAddress(contact.getAddress());
+            }
+
+            for (GroupInfo group : groupStore.getGroups()) {
+                group.members = group.members.stream()
+                        .map(m -> recipientStore.resolveServiceAddress(m))
+                        .collect(Collectors.toSet());
+            }
+
+            for (SessionInfo session : signalProtocolStore.getSessions()) {
+                session.address = recipientStore.resolveServiceAddress(session.address);
+            }
+
+            for (JsonIdentityKeyStore.Identity identity : signalProtocolStore.getIdentities()) {
+                identity.setAddress(recipientStore.resolveServiceAddress(identity.getAddress()));
+            }
+        }
+
         JsonNode threadStoreNode = rootNode.get("threadStore");
         if (threadStoreNode != null) {
             LegacyJsonThreadStore threadStore = jsonProcessor.convertValue(threadStoreNode, LegacyJsonThreadStore.class);
             // Migrate thread info to group and contact store
             for (ThreadInfo thread : threadStore.getThreads()) {
+                if (thread.id == null || thread.id.isEmpty()) {
+                    continue;
+                }
                 try {
                     ContactInfo contactInfo = contactStore.getContact(new SignalServiceAddress(null, thread.id));
                     if (contactInfo != null) {
@@ -218,6 +267,7 @@ public class SignalAccount {
         }
         ObjectNode rootNode = jsonProcessor.createObjectNode();
         rootNode.put("username", username)
+                .put("uuid", uuid == null ? null : uuid.toString())
                 .put("deviceId", deviceId)
                 .put("isMultiDevice", isMultiDevice)
                 .put("password", password)
@@ -230,6 +280,7 @@ public class SignalAccount {
                 .putPOJO("axolotlStore", signalProtocolStore)
                 .putPOJO("groupStore", groupStore)
                 .putPOJO("contactStore", contactStore)
+                .putPOJO("recipientStore", recipientStore)
         ;
         try {
             synchronized (fileChannel) {
@@ -260,6 +311,10 @@ public class SignalAccount {
         }
     }
 
+    public void setResolver(final SignalServiceAddressResolver resolver) {
+        signalProtocolStore.setResolver(resolver);
+    }
+
     public void addPreKeys(Collection<PreKeyRecord> records) {
         for (PreKeyRecord record : records) {
             signalProtocolStore.storePreKey(record.getId(), record);
@@ -284,6 +339,10 @@ public class SignalAccount {
         return contactStore;
     }
 
+    public RecipientStore getRecipientStore() {
+        return recipientStore;
+    }
+
     public String getUsername() {
         return username;
     }
@@ -292,6 +351,10 @@ public class SignalAccount {
         return uuid;
     }
 
+    public void setUuid(final UUID uuid) {
+        this.uuid = uuid;
+    }
+
     public SignalServiceAddress getSelfAddress() {
         return new SignalServiceAddress(uuid, username);
     }