]> nmode's Git Repositories - signal-cli/commitdiff
Archive old sessions when an identity key has changed
authorAsamK <asamk@gmx.de>
Sat, 22 Jan 2022 12:21:56 +0000 (13:21 +0100)
committerAsamK <asamk@gmx.de>
Sat, 22 Jan 2022 12:21:56 +0000 (13:21 +0100)
lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java
lib/src/main/java/org/asamk/signal/manager/helper/IdentityHelper.java
lib/src/main/java/org/asamk/signal/manager/helper/ProfileHelper.java
lib/src/main/java/org/asamk/signal/manager/storage/identities/IdentityKeyStore.java

index aab5d2304105d12fc4979f7172cdb47d1109dfc0..a080b1851871c6b20065e0f3945b43649f4a15f6 100644 (file)
@@ -86,6 +86,8 @@ import java.util.function.Function;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
+import io.reactivex.rxjava3.disposables.CompositeDisposable;
+
 public class ManagerImpl implements Manager {
 
     private final static Logger logger = LoggerFactory.getLogger(ManagerImpl.class);
@@ -101,6 +103,7 @@ public class ManagerImpl implements Manager {
     private final Set<ReceiveMessageHandler> weakHandlers = new HashSet<>();
     private final Set<ReceiveMessageHandler> messageHandlers = new HashSet<>();
     private final List<Runnable> closedListeners = new ArrayList<>();
+    private final CompositeDisposable disposable = new CompositeDisposable();
 
     ManagerImpl(
             SignalAccount account,
@@ -141,6 +144,20 @@ public class ManagerImpl implements Manager {
                 this.notifyAll();
             }
         });
+        disposable.add(account.getIdentityKeyStore().getIdentityChanges().subscribe(recipientId -> {
+            logger.trace("Archiving old sessions");
+            account.getSessionStore().archiveSessions(recipientId);
+            account.getSenderKeyStore().deleteSharedWith(recipientId);
+            final var profile = account.getRecipientStore().getProfile(recipientId);
+            if (profile != null) {
+                account.getRecipientStore()
+                        .storeProfile(recipientId,
+                                Profile.newBuilder(profile)
+                                        .withUnidentifiedAccessMode(Profile.UnidentifiedAccessMode.UNKNOWN)
+                                        .withLastUpdateTimestamp(0)
+                                        .build());
+            }
+        }));
     }
 
     @Override
@@ -982,6 +999,7 @@ public class ManagerImpl implements Manager {
         executor.shutdown();
 
         dependencies.getSignalWebSocket().disconnect();
+        disposable.dispose();
 
         synchronized (closedListeners) {
             closedListeners.forEach(Runnable::run);
index f7ec4167feaa92f683ac4cfd398be26aeaeb33c5..025971a995cfb8093d21907eeb9175f4fc04bfce 100644 (file)
@@ -110,11 +110,7 @@ public class IdentityHelper {
     ) {
         final var identityKey = identityFailure.getIdentityKey();
         if (identityKey != null) {
-            final var newIdentity = account.getIdentityKeyStore().saveIdentity(recipientId, identityKey, new Date());
-            if (newIdentity) {
-                account.getSessionStore().archiveSessions(recipientId);
-                account.getSenderKeyStore().deleteSharedWith(recipientId);
-            }
+            account.getIdentityKeyStore().saveIdentity(recipientId, identityKey, new Date());
         } else {
             // Retrieve profile to get the current identity key from the server
             context.getProfileHelper().refreshRecipientProfile(recipientId);
index 20a81f7f66fc1b630a6455e884e35f03ee9c81e3..f1f5d1de875e99b1aae99dd6351dfe4807c85a12 100644 (file)
@@ -279,25 +279,18 @@ public final class ProfileHelper {
                         .build();
             }
 
-            logger.trace("Storing profile");
-            account.getProfileStore().storeProfile(recipientId, newProfile);
-
             try {
                 logger.trace("Storing identity");
-                var newIdentity = account.getIdentityKeyStore()
-                        .saveIdentity(recipientId,
-                                new IdentityKey(Base64.getDecoder().decode(encryptedProfile.getIdentityKey())),
-                                new Date());
-
-                if (newIdentity) {
-                    logger.trace("Archiving old sessions");
-                    account.getSessionStore().archiveSessions(recipientId);
-                    account.getSenderKeyStore().deleteSharedWith(recipientId);
-                }
+                final var identityKey = new IdentityKey(Base64.getDecoder().decode(encryptedProfile.getIdentityKey()));
+                account.getIdentityKeyStore().saveIdentity(recipientId, identityKey, new Date());
             } catch (InvalidKeyException ignored) {
                 logger.warn("Got invalid identity key in profile for {}",
                         context.getRecipientHelper().resolveSignalServiceAddress(recipientId).getIdentifier());
             }
+
+            logger.trace("Storing profile");
+            account.getProfileStore().storeProfile(recipientId, newProfile);
+
             logger.trace("Done handling retrieved profile");
         }).doOnError(e -> {
             logger.warn("Failed to retrieve profile, ignoring: {}", e.getMessage());
index 31b717cde215bc81c04392313179f904e04e876e..2bc8307b7f8127f66c4f8907bf097c5adda86d2c 100644 (file)
@@ -29,6 +29,9 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.regex.Pattern;
 
+import io.reactivex.rxjava3.subjects.PublishSubject;
+import io.reactivex.rxjava3.subjects.Subject;
+
 public class IdentityKeyStore implements org.whispersystems.libsignal.state.IdentityKeyStore {
 
     private final static Logger logger = LoggerFactory.getLogger(IdentityKeyStore.class);
@@ -42,6 +45,7 @@ public class IdentityKeyStore implements org.whispersystems.libsignal.state.Iden
     private final IdentityKeyPair identityKeyPair;
     private final int localRegistrationId;
     private final TrustNewIdentity trustNewIdentity;
+    private final PublishSubject<RecipientId> identityChanges = PublishSubject.create();
 
     private boolean isRetryingDecryption = false;
 
@@ -59,6 +63,10 @@ public class IdentityKeyStore implements org.whispersystems.libsignal.state.Iden
         this.trustNewIdentity = trustNewIdentity;
     }
 
+    public Subject<RecipientId> getIdentityChanges() {
+        return identityChanges;
+    }
+
     @Override
     public IdentityKeyPair getIdentityKeyPair() {
         return identityKeyPair;
@@ -94,6 +102,7 @@ public class IdentityKeyStore implements org.whispersystems.libsignal.state.Iden
             logger.debug("Storing new identity for recipient {} with trust {}", recipientId, trustLevel);
             final var newIdentityInfo = new IdentityInfo(recipientId, identityKey, trustLevel, added);
             storeIdentityLocked(recipientId, newIdentityInfo);
+            identityChanges.onNext(recipientId);
             return true;
         }
     }