diff --git a/man/signal-cli-dbus.5.adoc b/man/signal-cli-dbus.5.adoc index b9279416..76b9f541 100755 --- a/man/signal-cli-dbus.5.adoc +++ b/man/signal-cli-dbus.5.adoc @@ -195,6 +195,24 @@ Depending on the type of the recipient(s) field this deletes a message with one Exceptions: Failure, InvalidNumber +sendContacts() -> <> + +Sends a synchronization message with the local contacts list to all linked devices. + +Exceptions: Failure, UntrustedIdentity + +sendSyncRequest() -> <> + +Sends a synchronization request to the primary device (for group, contacts, ...). Only works if a secondary device is running the daemon. + +Exception: Failure + +trust(number, safetyNumber) -> <>:: +* number : Phone number +* safetyNumber : Verify the safety number associated with the phone number. + +Exceptions: Failure, InvalidNumber; + sendTyping(typingAction, base64GroupId, recipients) -> <> * typingAction : true = start typing, false = stop typing * base64GroupId : String representing the internal group identifier in Base64 format diff --git a/src/main/java/org/asamk/Signal.java b/src/main/java/org/asamk/Signal.java index 7a5aaea1..3f20648e 100644 --- a/src/main/java/org/asamk/Signal.java +++ b/src/main/java/org/asamk/Signal.java @@ -1,6 +1,7 @@ package org.asamk; import org.asamk.SignalControl; +import org.asamk.Signal.Error; import org.asamk.signal.commands.exceptions.IOErrorException; import org.asamk.signal.commands.exceptions.UnexpectedErrorException; import org.asamk.signal.commands.exceptions.UserErrorException; @@ -79,6 +80,12 @@ public interface Signal extends DBusInterface { String emoji, boolean remove, String targetAuthor, long targetSentTimestamp, byte[] groupId ) throws Error.GroupNotFound, Error.Failure, Error.InvalidNumber; + void sendContacts() throws Error.Failure, Error.UntrustedIdentity; + + void sendSyncRequest() throws Error.Failure; + + void trust(String number, String safetyNumber) throws Error.Failure, Error.InvalidNumber; + void sendTyping(boolean typingAction, String base64GroupId, Listrecipients) throws Error.Failure, Error.UntrustedIdentity; String getContactName(String number) throws Error.InvalidNumber; @@ -151,10 +158,10 @@ public interface Signal extends DBusInterface { void updateProfile( String name, String about, String aboutEmoji, String avatarPath, boolean removeAvatar ) throws Error.Failure; - - void removePin() throws Error.Failure; - void setPin(String registrationLockPin) throws Error.Failure; + void removePin() throws Error.Failure; + + void setPin(String registrationLockPin) throws Error.Failure; String version(); diff --git a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java index 9c88e266..177ffcc6 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java @@ -13,6 +13,7 @@ import org.asamk.signal.OutputWriter; import org.asamk.signal.commands.exceptions.CommandException; import org.asamk.signal.commands.exceptions.IOErrorException; import org.asamk.signal.commands.exceptions.UnexpectedErrorException; +import org.asamk.signal.commands.exceptions.UntrustedKeyErrorException; import org.asamk.signal.commands.exceptions.UserErrorException; import org.asamk.signal.manager.AttachmentInvalidException; import org.asamk.signal.manager.AvatarStore; @@ -56,6 +57,7 @@ import java.util.ArrayList; import java.util.Base64; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Set; @@ -349,6 +351,69 @@ public class DbusSignalImpl implements Signal { return sendGroupMessageReaction(emoji, remove, targetAuthor, targetSentTimestamp, groupId); } + @Override + public void sendContacts() { + try { + m.sendContacts(); + } catch (UntrustedIdentityException e) { + throw new Error.UntrustedIdentity("SendContacts error: " + e.getMessage()); + } catch (IOException e) { + throw new Error.Failure("SendContacts error: " + e.getMessage()); + } + } + + @Override + public void sendSyncRequest() { + try { + m.requestAllSyncData(); + } catch (IOException e) { + throw new Error.Failure("Request sync data error: " + e.getMessage()); + } + } + + @Override + public void trust(String number, String safetyNumber){ + if (safetyNumber != null) { + safetyNumber = safetyNumber.replaceAll(" ", ""); + if (safetyNumber.length() == 66) { + byte[] fingerprintBytes; + try { + fingerprintBytes = Hex.toByteArray(safetyNumber.toLowerCase(Locale.ROOT)); + } catch (Exception e) { + throw new Error.Failure( + "Failed to parse the fingerprint, make sure the fingerprint is a correctly encoded hex string without additional characters."); + } + boolean res; + try { + res = m.trustIdentityVerified(number, fingerprintBytes); + } catch (InvalidNumberException e) { + throw new Error.Failure("Failed to parse recipient: " + e.getMessage()); + } + if (!res) { + throw new Error.Failure( + "Failed to set the trust for the fingerprint of this number, make sure the number and the fingerprint are correct."); + } + } else if (safetyNumber.length() == 60) { + boolean res; + try { + res = m.trustIdentityVerifiedSafetyNumber(number, safetyNumber); + } catch (InvalidNumberException e) { + throw new Error.InvalidNumber("Failed to parse recipient: " + e.getMessage()); + } + if (!res) { + throw new Error.Failure( + "Failed to set the trust for the safety number of this phone number, make sure the phone number and the safety number are correct."); + } + } else { + throw new Error.Failure( + "Safety number has invalid format, either specify the old hex fingerprint or the new safety number"); + } + } else { + throw new Error.Failure( + "You need to specify the fingerprint/safety number you have verified with -v SAFETY_NUMBER"); + } + } + @Override public void sendTyping(boolean typingAction, String base64GroupId, Listrecipients) { final var noRecipients = recipients == null || recipients.isEmpty();