]> nmode's Git Repositories - signal-cli/commitdiff
Add hint that messages must be regularly received
authorAsamK <asamk@gmx.de>
Mon, 24 May 2021 10:14:44 +0000 (12:14 +0200)
committerAsamK <asamk@gmx.de>
Mon, 24 May 2021 10:18:33 +0000 (12:18 +0200)
README.md
lib/src/main/java/org/asamk/signal/manager/Manager.java
lib/src/main/java/org/asamk/signal/manager/storage/SignalAccount.java
src/main/java/org/asamk/signal/util/DateUtils.java

index 4bd49c17442defff73afcb692ac5995bd24ea743..fa2c40f7e9e0267d0cccd953ee91dd67c8384d35 100644 (file)
--- a/README.md
+++ b/README.md
@@ -57,6 +57,8 @@ Important: The USERNAME is your phone number in international format and must in
 
         signal-cli -u USERNAME receive
 
+**Hint**: The Signal protocol expects that incoming messages are regularly received (using `daemon` or `receive` command).
+This is required for the encryption to work efficiently and for getting updates to groups, expiration timer and other features.
 
 ## Storage
 
index 2f38c0c7928fc59b870749ff1214a94d02950f30..87b0f30afa24c24bedd2fe189c9fbd4677d282ca 100644 (file)
@@ -330,6 +330,17 @@ public class Manager implements Closeable {
     }
 
     public void checkAccountState() throws IOException {
+        if (account.getLastReceiveTimestamp() == 0) {
+            logger.warn("The Signal protocol expects that incoming messages are regularly received.");
+        } else {
+            var diffInMilliseconds = new Date().getTime() - account.getLastReceiveTimestamp();
+            long days = TimeUnit.DAYS.convert(diffInMilliseconds, TimeUnit.MILLISECONDS);
+            if (days > 7) {
+                logger.warn(
+                        "Messages have been last received {} days ago. The Signal protocol expects that incoming messages are regularly received.",
+                        days);
+            }
+        }
         if (accountManager.getPreKeysCount() < ServiceConfig.PREKEY_MINIMUM_COUNT) {
             refreshPreKeys();
         }
@@ -1982,6 +1993,7 @@ public class Manager implements Closeable {
             SignalServiceContent content = null;
             Exception exception = null;
             final CachedMessage[] cachedMessage = {null};
+            account.setLastReceiveTimestamp(new Date().getTime());
             try {
                 var result = messagePipe.readOrEmpty(timeout, unit, envelope1 -> {
                     final var recipientId = envelope1.hasSource()
index 386d2287df14513f4b325f552b9bae8d19fff878..a19459c0faae6c9ac8cc023db4ac64e1e7731cff 100644 (file)
@@ -84,6 +84,7 @@ public class SignalAccount implements Closeable {
     private ProfileKey profileKey;
     private int preKeyIdOffset;
     private int nextSignedPreKeyId;
+    private long lastReceiveTimestamp = 0;
 
     private boolean registered = false;
 
@@ -261,6 +262,7 @@ public class SignalAccount implements Closeable {
         this.deviceId = deviceId;
         this.registered = true;
         this.isMultiDevice = true;
+        this.lastReceiveTimestamp = 0;
     }
 
     private void migrateLegacyConfigs() {
@@ -368,6 +370,9 @@ public class SignalAccount implements Closeable {
         if (rootNode.hasNonNull("isMultiDevice")) {
             isMultiDevice = rootNode.get("isMultiDevice").asBoolean();
         }
+        if (rootNode.hasNonNull("lastReceiveTimestamp")) {
+            lastReceiveTimestamp = rootNode.get("lastReceiveTimestamp").asLong();
+        }
         int registrationId = 0;
         if (rootNode.hasNonNull("registrationId")) {
             registrationId = rootNode.get("registrationId").asInt();
@@ -637,6 +642,7 @@ public class SignalAccount implements Closeable {
                     .put("deviceName", encryptedDeviceName)
                     .put("deviceId", deviceId)
                     .put("isMultiDevice", isMultiDevice)
+                    .put("lastReceiveTimestamp", lastReceiveTimestamp)
                     .put("password", password)
                     .put("registrationId", identityKeyStore.getLocalRegistrationId())
                     .put("identityPrivateKey",
@@ -870,6 +876,15 @@ public class SignalAccount implements Closeable {
         save();
     }
 
+    public long getLastReceiveTimestamp() {
+        return lastReceiveTimestamp;
+    }
+
+    public void setLastReceiveTimestamp(final long lastReceiveTimestamp) {
+        this.lastReceiveTimestamp = lastReceiveTimestamp;
+        save();
+    }
+
     public boolean isUnrestrictedUnidentifiedAccess() {
         // TODO make configurable
         return false;
@@ -893,6 +908,7 @@ public class SignalAccount implements Closeable {
         this.registered = true;
         this.uuid = uuid;
         this.registrationLockPin = pin;
+        this.lastReceiveTimestamp = 0;
         save();
 
         getSessionStore().archiveAllSessions();
index 7f2974ae31613944aede7c6bd1c2a68cda2ce545..e421c849ce1536ee0f85751855b93fadccbdaab2 100644 (file)
@@ -14,7 +14,7 @@ public class DateUtils {
 
     public static String formatTimestamp(long timestamp) {
         var date = new Date(timestamp);
-        final DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX"); // Quoted "Z" to indicate UTC, no timezone offset
+        final DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
         df.setTimeZone(tzUTC);
         return timestamp + " (" + df.format(date) + ")";
     }