X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/de273586b4106171a3940ce5ec2c2b3712430c8c..3ad3b2c966102ea26cc80cab3d4107a13f2fcc87:/lib/src/main/java/org/asamk/signal/manager/Manager.java diff --git a/lib/src/main/java/org/asamk/signal/manager/Manager.java b/lib/src/main/java/org/asamk/signal/manager/Manager.java index caedf2f1..5d0e7d3d 100644 --- a/lib/src/main/java/org/asamk/signal/manager/Manager.java +++ b/lib/src/main/java/org/asamk/signal/manager/Manager.java @@ -156,6 +156,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.function.Function; import java.util.stream.Collectors; import static org.asamk.signal.manager.config.ServiceConfig.capabilities; @@ -528,7 +529,7 @@ public class Manager implements Closeable { ServiceConfig.AUTOMATIC_NETWORK_RETRY); } - private SignalProfile getRecipientProfile( + public SignalProfile getRecipientProfile( SignalServiceAddress address ) { return getRecipientProfile(address, false); @@ -991,6 +992,22 @@ public class Manager implements Closeable { return sendSelfMessage(messageBuilder); } + public Pair> sendRemoteDeleteMessage( + long targetSentTimestamp, List recipients + ) throws IOException, InvalidNumberException { + var delete = new SignalServiceDataMessage.RemoteDelete(targetSentTimestamp); + final var messageBuilder = SignalServiceDataMessage.newBuilder().withRemoteDelete(delete); + return sendMessage(messageBuilder, getSignalServiceAddresses(recipients)); + } + + public Pair> sendGroupRemoteDeleteMessage( + long targetSentTimestamp, GroupId groupId + ) throws IOException, NotAGroupMemberException, GroupNotFoundException { + var delete = new SignalServiceDataMessage.RemoteDelete(targetSentTimestamp); + final var messageBuilder = SignalServiceDataMessage.newBuilder().withRemoteDelete(delete); + return sendGroupMessage(messageBuilder, groupId); + } + public Pair> sendMessageReaction( String emoji, boolean remove, String targetAuthor, long targetSentTimestamp, List recipients ) throws IOException, InvalidNumberException { @@ -1211,10 +1228,12 @@ public class Manager implements Closeable { try { messageSender.sendMessage(message, unidentifiedAccessHelper.getAccessForSync()); } catch (UntrustedIdentityException e) { - account.getSignalProtocolStore() - .saveIdentity(resolveSignalServiceAddress(e.getIdentifier()), - e.getIdentityKey(), - TrustLevel.UNTRUSTED); + if (e.getIdentityKey() != null) { + account.getSignalProtocolStore() + .saveIdentity(resolveSignalServiceAddress(e.getIdentifier()), + e.getIdentityKey(), + TrustLevel.UNTRUSTED); + } throw e; } } @@ -1296,10 +1315,12 @@ public class Manager implements Closeable { } return new Pair<>(timestamp, result); } catch (UntrustedIdentityException e) { - account.getSignalProtocolStore() - .saveIdentity(resolveSignalServiceAddress(e.getIdentifier()), - e.getIdentityKey(), - TrustLevel.UNTRUSTED); + if (e.getIdentityKey() != null) { + account.getSignalProtocolStore() + .saveIdentity(resolveSignalServiceAddress(e.getIdentifier()), + e.getIdentityKey(), + TrustLevel.UNTRUSTED); + } return new Pair<>(timestamp, List.of()); } } else { @@ -1369,10 +1390,12 @@ public class Manager implements Closeable { false, System.currentTimeMillis() - startTime); } catch (UntrustedIdentityException e) { - account.getSignalProtocolStore() - .saveIdentity(resolveSignalServiceAddress(e.getIdentifier()), - e.getIdentityKey(), - TrustLevel.UNTRUSTED); + if (e.getIdentityKey() != null) { + account.getSignalProtocolStore() + .saveIdentity(resolveSignalServiceAddress(e.getIdentifier()), + e.getIdentityKey(), + TrustLevel.UNTRUSTED); + } return SendMessageResult.identityFailure(recipient, e.getIdentityKey()); } } @@ -1385,10 +1408,12 @@ public class Manager implements Closeable { try { return messageSender.sendMessage(address, unidentifiedAccessHelper.getAccessFor(address), message); } catch (UntrustedIdentityException e) { - account.getSignalProtocolStore() - .saveIdentity(resolveSignalServiceAddress(e.getIdentifier()), - e.getIdentityKey(), - TrustLevel.UNTRUSTED); + if (e.getIdentityKey() != null) { + account.getSignalProtocolStore() + .saveIdentity(resolveSignalServiceAddress(e.getIdentifier()), + e.getIdentityKey(), + TrustLevel.UNTRUSTED); + } return SendMessageResult.identityFailure(address, e.getIdentityKey()); } } @@ -2356,9 +2381,8 @@ public class Manager implements Closeable { final var profileEntry = account.getProfileStore().getProfileEntry(address); if (profileEntry != null && profileEntry.getProfile() != null) { - return profileEntry.getProfile().getName(); + return profileEntry.getProfile().getDisplayName(); } - return null; } @@ -2388,26 +2412,7 @@ public class Manager implements Closeable { */ public boolean trustIdentityVerified(String name, byte[] fingerprint) throws InvalidNumberException { var address = canonicalizeAndResolveSignalServiceAddress(name); - var ids = account.getSignalProtocolStore().getIdentities(address); - if (ids == null) { - return false; - } - for (var id : ids) { - if (!Arrays.equals(id.getIdentityKey().serialize(), fingerprint)) { - continue; - } - - account.getSignalProtocolStore() - .setIdentityTrustLevel(address, id.getIdentityKey(), TrustLevel.TRUSTED_VERIFIED); - try { - sendVerifiedMessage(address, id.getIdentityKey(), TrustLevel.TRUSTED_VERIFIED); - } catch (IOException | UntrustedIdentityException e) { - logger.warn("Failed to send verification sync message: {}", e.getMessage()); - } - account.save(); - return true; - } - return false; + return trustIdentity(address, (identityKey) -> Arrays.equals(identityKey.serialize(), fingerprint)); } /** @@ -2418,26 +2423,46 @@ public class Manager implements Closeable { */ public boolean trustIdentityVerifiedSafetyNumber(String name, String safetyNumber) throws InvalidNumberException { var address = canonicalizeAndResolveSignalServiceAddress(name); + return trustIdentity(address, (identityKey) -> safetyNumber.equals(computeSafetyNumber(address, identityKey))); + } + + private boolean trustIdentity(SignalServiceAddress address, Function verifier) { var ids = account.getSignalProtocolStore().getIdentities(address); if (ids == null) { return false; } + + IdentityInfo foundIdentity = null; + for (var id : ids) { - if (!safetyNumber.equals(computeSafetyNumber(address, id.getIdentityKey()))) { - continue; + if (verifier.apply(id.getIdentityKey())) { + foundIdentity = id; + break; } + } - account.getSignalProtocolStore() - .setIdentityTrustLevel(address, id.getIdentityKey(), TrustLevel.TRUSTED_VERIFIED); - try { - sendVerifiedMessage(address, id.getIdentityKey(), TrustLevel.TRUSTED_VERIFIED); - } catch (IOException | UntrustedIdentityException e) { - logger.warn("Failed to send verification sync message: {}", e.getMessage()); + if (foundIdentity == null) { + return false; + } + + account.getSignalProtocolStore() + .setIdentityTrustLevel(address, foundIdentity.getIdentityKey(), TrustLevel.TRUSTED_VERIFIED); + try { + sendVerifiedMessage(address, foundIdentity.getIdentityKey(), TrustLevel.TRUSTED_VERIFIED); + } catch (IOException | UntrustedIdentityException e) { + logger.warn("Failed to send verification sync message: {}", e.getMessage()); + } + + // Successfully trusted the new identity, now remove all other identities for that number + for (var id : ids) { + if (id == foundIdentity) { + continue; } - account.save(); - return true; + account.getSignalProtocolStore().removeIdentity(address, id.getIdentityKey()); } - return false; + + account.save(); + return true; } /**