From 11b3758416ea395d04b8538a28be07c240749767 Mon Sep 17 00:00:00 2001 From: JtheSaw <21310929+JtheSaw@users.noreply.github.com> Date: Mon, 13 Sep 2021 17:01:26 +0200 Subject: [PATCH 01/13] Add sendTyping and sendReceipt to dbus interface (#718) * Add sendTyping and sendReceipt to dbus interface * Resolve requested changes * Adapt documentation --- man/signal-cli-dbus.5.adoc | 14 ++++++++ src/main/java/org/asamk/Signal.java | 8 +++++ .../org/asamk/signal/dbus/DbusSignalImpl.java | 35 +++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/man/signal-cli-dbus.5.adoc b/man/signal-cli-dbus.5.adoc index ece2460f..4ff5e994 100755 --- a/man/signal-cli-dbus.5.adoc +++ b/man/signal-cli-dbus.5.adoc @@ -33,6 +33,7 @@ Where is according to DBus specification: * : Byte Array * : Array of Byte Arrays * : String Array +* : Array of signed 64 bit integer * : Boolean (0|1) * : Signed 64 bit integer * <> : no return value @@ -125,6 +126,19 @@ Depending on the type of the recipient field this sends a message to one or mult Exceptions: AttachmentInvalid, Failure, InvalidNumber, UntrustedIdentity +sendTyping(recipient, stop) -> <>:: +* recipient : Phone number of a single recipient +* targetSentTimestamp : True, if typing state should be stopped + +Exceptions: Failure, GroupNotFound, UntrustedIdentity + + +sendReadReceipt(recipient, targetSentTimestamp) -> <>:: +* recipient : Phone number of a single recipient +* targetSentTimestamp : Array of Longs to identify the corresponding signal messages + +Exceptions: Failure, UntrustedIdentity + sendGroupMessageReaction(emoji, remove, targetAuthor, targetSentTimestamp, groupId) -> timestamp:: * emoji : Unicode grapheme cluster of the emoji * remove : Boolean, whether a previously sent reaction (emoji) should be removed diff --git a/src/main/java/org/asamk/Signal.java b/src/main/java/org/asamk/Signal.java index cd101929..868de02b 100644 --- a/src/main/java/org/asamk/Signal.java +++ b/src/main/java/org/asamk/Signal.java @@ -21,6 +21,14 @@ public interface Signal extends DBusInterface { String message, List attachments, List recipients ) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber, Error.UntrustedIdentity; + void sendTyping( + String recipient, boolean stop + ) throws Error.Failure, Error.GroupNotFound, Error.UntrustedIdentity; + + void sendReadReceipt( + String recipient, List targetSentTimestamp + ) throws Error.Failure, Error.UntrustedIdentity; + long sendRemoteDeleteMessage( long targetSentTimestamp, String recipient ) throws Error.Failure, Error.InvalidNumber; diff --git a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java index 0bb0c435..5e8fd432 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java @@ -5,8 +5,10 @@ import org.asamk.signal.BaseConfig; import org.asamk.signal.manager.AttachmentInvalidException; import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.NotMasterDeviceException; +import org.asamk.signal.manager.UntrustedIdentityException; import org.asamk.signal.manager.api.Message; import org.asamk.signal.manager.api.RecipientIdentifier; +import org.asamk.signal.manager.api.TypingAction; import org.asamk.signal.manager.groups.GroupId; import org.asamk.signal.manager.groups.GroupInviteLinkUrl; import org.asamk.signal.manager.groups.GroupNotFoundException; @@ -165,6 +167,39 @@ public class DbusSignalImpl implements Signal { } } + @Override + public void sendTyping( + final String recipient, final boolean stop + ) throws Error.Failure, Error.GroupNotFound, Error.UntrustedIdentity { + try { + var recipients = new ArrayList(1); + recipients.add(recipient); + m.sendTypingMessage(stop ? TypingAction.STOP : TypingAction.START, + getSingleRecipientIdentifiers(recipients, m.getUsername()).stream() + .map(RecipientIdentifier.class::cast) + .collect(Collectors.toSet())); + } catch (IOException e) { + throw new Error.Failure(e.getMessage()); + } catch (GroupNotFoundException | NotAGroupMemberException | GroupSendingNotAllowedException e) { + throw new Error.GroupNotFound(e.getMessage()); + } catch (UntrustedIdentityException e) { + throw new Error.UntrustedIdentity(e.getMessage()); + } + } + + @Override + public void sendReadReceipt( + final String recipient, final List timestamps + ) throws Error.Failure, Error.UntrustedIdentity { + try { + m.sendReadReceipt(getSingleRecipientIdentifier(recipient, m.getUsername()), timestamps); + } catch (IOException e) { + throw new Error.Failure(e.getMessage()); + } catch (UntrustedIdentityException e) { + throw new Error.UntrustedIdentity(e.getMessage()); + } + } + @Override public long sendNoteToSelfMessage( final String message, final List attachments From 8e2bb1d393414572fc7d996319b2bcd7ae135a16 Mon Sep 17 00:00:00 2001 From: AsamK Date: Wed, 15 Sep 2021 21:25:46 +0200 Subject: [PATCH 02/13] Update FUNDING.yml --- FUNDING.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/FUNDING.yml b/FUNDING.yml index 308e2dd5..9d269f9a 100644 --- a/FUNDING.yml +++ b/FUNDING.yml @@ -1,2 +1,3 @@ liberapay: asamk +ko_fi: asamk bitcoin: bc1qykae53fry8a8ycgdzgv0rlxfc959hmmllvz698 From e562daa1f332f22f13c9856c623f1b830744f70d Mon Sep 17 00:00:00 2001 From: AsamK Date: Wed, 15 Sep 2021 21:34:05 +0200 Subject: [PATCH 03/13] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9a11ee6e..fe435849 100644 --- a/README.md +++ b/README.md @@ -81,15 +81,15 @@ dependencies. If you have a recent gradle version installed, you can replace `./ ./gradlew build -3. Create shell wrapper in *build/install/signal-cli/bin*: + 3a. Create shell wrapper in *build/install/signal-cli/bin*: ./gradlew installDist -4. Create tar file in *build/distributions*: + 3b. Create tar file in *build/distributions*: ./gradlew distTar -5. Compile and run signal-cli: + 3c. Compile and run signal-cli: ./gradlew run --args="--help" From 6c29d90503f7bfcde9fa5a4ae70b617cd041555c Mon Sep 17 00:00:00 2001 From: AsamK Date: Wed, 15 Sep 2021 21:34:46 +0200 Subject: [PATCH 04/13] Adapt visibility --- .../main/java/org/asamk/signal/manager/RegistrationManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/java/org/asamk/signal/manager/RegistrationManager.java b/lib/src/main/java/org/asamk/signal/manager/RegistrationManager.java index 1b00e562..443a7969 100644 --- a/lib/src/main/java/org/asamk/signal/manager/RegistrationManager.java +++ b/lib/src/main/java/org/asamk/signal/manager/RegistrationManager.java @@ -58,7 +58,7 @@ public class RegistrationManager implements Closeable { private final SignalServiceAccountManager accountManager; private final PinHelper pinHelper; - public RegistrationManager( + private RegistrationManager( SignalAccount account, PathConfig pathConfig, ServiceEnvironmentConfig serviceEnvironmentConfig, From d622967192ce03d3650f2cbc582c6555ab0ca23c Mon Sep 17 00:00:00 2001 From: John Freed Date: Tue, 21 Sep 2021 22:26:26 +0200 Subject: [PATCH 05/13] Implement Dbus setPin and removePin (#733) and update documentation --- .gitignore | 1 + man/signal-cli-dbus.5.adoc | 13 ++++++++++ src/main/java/org/asamk/Signal.java | 7 ++++++ .../org/asamk/signal/dbus/DbusSignalImpl.java | 24 +++++++++++++++++++ 4 files changed, 45 insertions(+) diff --git a/.gitignore b/.gitignore index 8fa9c8bd..e41d1e40 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ local.properties .settings/ out/ .DS_Store +/bin/ diff --git a/man/signal-cli-dbus.5.adoc b/man/signal-cli-dbus.5.adoc index 4ff5e994..d562d064 100755 --- a/man/signal-cli-dbus.5.adoc +++ b/man/signal-cli-dbus.5.adoc @@ -229,6 +229,19 @@ isGroupBlocked(groupId) -> state:: Exceptions: None, for unknown groups 0 (false) is returned +removePin() -> <>:: + +Removes registration PIN protection. + +Exception: Failure + +setPin(pin) -> <>:: +* pin : PIN you set after registration (resets after 7 days of inactivity) + +Sets a registration lock PIN, to prevent others from registering your number. + +Exception: Failure + version() -> version:: * version : Version string of signal-cli diff --git a/src/main/java/org/asamk/Signal.java b/src/main/java/org/asamk/Signal.java index 868de02b..a30f8f3b 100644 --- a/src/main/java/org/asamk/Signal.java +++ b/src/main/java/org/asamk/Signal.java @@ -1,10 +1,13 @@ package org.asamk; +import org.asamk.Signal.Error; import org.freedesktop.dbus.exceptions.DBusException; import org.freedesktop.dbus.exceptions.DBusExecutionException; import org.freedesktop.dbus.interfaces.DBusInterface; import org.freedesktop.dbus.messages.DBusSignal; +import org.whispersystems.libsignal.util.guava.Optional; +import java.io.IOException; import java.util.List; /** @@ -87,6 +90,10 @@ public interface Signal extends DBusInterface { String name, String about, String aboutEmoji, String avatarPath, boolean removeAvatar ) throws Error.Failure; + void removePin(); + + void setPin(String registrationLockPin); + String version(); List listNumbers(); diff --git a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java index 5e8fd432..44250d5b 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java @@ -18,6 +18,7 @@ import org.asamk.signal.manager.groups.NotAGroupMemberException; import org.asamk.signal.manager.storage.identities.IdentityInfo; import org.asamk.signal.util.ErrorUtils; import org.asamk.signal.util.Util; + import org.freedesktop.dbus.exceptions.DBusExecutionException; import org.whispersystems.libsignal.util.Pair; import org.whispersystems.libsignal.util.guava.Optional; @@ -25,6 +26,7 @@ import org.whispersystems.signalservice.api.groupsv2.GroupLinkNotActiveException import org.whispersystems.signalservice.api.messages.SendMessageResult; import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException; import org.whispersystems.signalservice.api.util.InvalidNumberException; +import org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedResponseException; import java.io.File; import java.io.IOException; @@ -413,6 +415,28 @@ public class DbusSignalImpl implements Signal { } } + @Override + public void removePin() { + try { + m.setRegistrationLockPin(Optional.absent()); + } catch (UnauthenticatedResponseException e) { + throw new Error.Failure("Remove pin failed with unauthenticated response: " + e.getMessage()); + } catch (IOException e) { + throw new Error.Failure("Remove pin error: " + e.getMessage()); + } + } + + @Override + public void setPin(String registrationLockPin) { + try { + m.setRegistrationLockPin(Optional.of(registrationLockPin)); + } catch (UnauthenticatedResponseException e) { + throw new Error.Failure("Set pin error failed with unauthenticated response: " + e.getMessage()); + } catch (IOException e) { + throw new Error.Failure("Set pin error: " + e.getMessage()); + } + } + // Provide option to query a version string in order to react on potential // future interface changes @Override From 982e887c9ffaa58cc018fdcdb8ffc5f0251ba04f Mon Sep 17 00:00:00 2001 From: AsamK Date: Tue, 21 Sep 2021 22:30:27 +0200 Subject: [PATCH 06/13] Reformat code --- src/main/java/org/asamk/Signal.java | 3 --- src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/org/asamk/Signal.java b/src/main/java/org/asamk/Signal.java index a30f8f3b..821e04d9 100644 --- a/src/main/java/org/asamk/Signal.java +++ b/src/main/java/org/asamk/Signal.java @@ -1,13 +1,10 @@ package org.asamk; -import org.asamk.Signal.Error; import org.freedesktop.dbus.exceptions.DBusException; import org.freedesktop.dbus.exceptions.DBusExecutionException; import org.freedesktop.dbus.interfaces.DBusInterface; import org.freedesktop.dbus.messages.DBusSignal; -import org.whispersystems.libsignal.util.guava.Optional; -import java.io.IOException; import java.util.List; /** diff --git a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java index 44250d5b..89703387 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java @@ -18,7 +18,6 @@ import org.asamk.signal.manager.groups.NotAGroupMemberException; import org.asamk.signal.manager.storage.identities.IdentityInfo; import org.asamk.signal.util.ErrorUtils; import org.asamk.signal.util.Util; - import org.freedesktop.dbus.exceptions.DBusExecutionException; import org.whispersystems.libsignal.util.Pair; import org.whispersystems.libsignal.util.guava.Optional; @@ -427,7 +426,7 @@ public class DbusSignalImpl implements Signal { } @Override - public void setPin(String registrationLockPin) { + public void setPin(String registrationLockPin) { try { m.setRegistrationLockPin(Optional.of(registrationLockPin)); } catch (UnauthenticatedResponseException e) { From 1ca0e75ef185a5f690162ff82e22732052e9ef57 Mon Sep 17 00:00:00 2001 From: John Freed Date: Sun, 26 Sep 2021 08:59:38 +0200 Subject: [PATCH 07/13] implement Dbus stickerpack method (#740) implement uploadStickerPack update documentation --- man/signal-cli-dbus.5.adoc | 6 ++++++ src/main/java/org/asamk/Signal.java | 2 ++ .../java/org/asamk/signal/dbus/DbusSignalImpl.java | 13 +++++++++++++ 3 files changed, 21 insertions(+) diff --git a/man/signal-cli-dbus.5.adoc b/man/signal-cli-dbus.5.adoc index d562d064..b7dfcfe1 100755 --- a/man/signal-cli-dbus.5.adoc +++ b/man/signal-cli-dbus.5.adoc @@ -248,6 +248,12 @@ version() -> version:: isRegistred -> result:: * result : Currently always returns 1=true +uploadStickerPack(stickerPackPath) -> url:: +* stickerPackPath : Path to the manifest.json file or a zip file in the same directory +* url : URL of sticker pack after successful upload + +Exception: Failure + == Signals SyncMessageReceived (timestamp, sender, destination, groupId,message, attachments):: diff --git a/src/main/java/org/asamk/Signal.java b/src/main/java/org/asamk/Signal.java index 821e04d9..1eb96510 100644 --- a/src/main/java/org/asamk/Signal.java +++ b/src/main/java/org/asamk/Signal.java @@ -107,6 +107,8 @@ public interface Signal extends DBusInterface { byte[] joinGroup(final String groupLink) throws Error.Failure; + String uploadStickerPack(String stickerPackPath) throws Error.Failure; + class MessageReceived extends DBusSignal { private final long timestamp; diff --git a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java index 89703387..0fde767d 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java @@ -5,6 +5,7 @@ import org.asamk.signal.BaseConfig; import org.asamk.signal.manager.AttachmentInvalidException; import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.NotMasterDeviceException; +import org.asamk.signal.manager.StickerPackInvalidException; import org.asamk.signal.manager.UntrustedIdentityException; import org.asamk.signal.manager.api.Message; import org.asamk.signal.manager.api.RecipientIdentifier; @@ -536,6 +537,18 @@ public class DbusSignalImpl implements Signal { } } + @Override + public String uploadStickerPack(String stickerPackPath) { + File path = new File(stickerPackPath); + try { + return m.uploadStickerPack(path).toString(); + } catch (IOException e) { + throw new Error.Failure("Upload error (maybe image size is too large):" + e.getMessage()); + } catch (StickerPackInvalidException e) { + throw new Error.Failure("Invalid sticker pack: " + e.getMessage()); + } + } + private static void checkSendMessageResult(long timestamp, SendMessageResult result) throws DBusExecutionException { var error = ErrorUtils.getErrorMessageFromSendMessageResult(result); From 8bee08fd96571f0f08ffa713b7bd20a2b251d277 Mon Sep 17 00:00:00 2001 From: John Freed Date: Sun, 26 Sep 2021 09:00:26 +0200 Subject: [PATCH 08/13] implement Dbus sync methods (#737) implement two Dbus methods: - sendContacts - sendSyncRequest update documentation --- man/signal-cli-dbus.5.adoc | 12 ++++++++++++ src/main/java/org/asamk/Signal.java | 4 ++++ .../org/asamk/signal/dbus/DbusSignalImpl.java | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/man/signal-cli-dbus.5.adoc b/man/signal-cli-dbus.5.adoc index b7dfcfe1..8cc234bc 100755 --- a/man/signal-cli-dbus.5.adoc +++ b/man/signal-cli-dbus.5.adoc @@ -107,6 +107,18 @@ sendGroupMessage(message, attachments, groupId) -> timestamp:: Exceptions: GroupNotFound, Failure, AttachmentInvalid +sendContacts() -> <>:: + +Sends a synchronization message with the local contacts list to all linked devices. This command should only be used if this is the primary device. + +Exceptions: Failure + +sendSyncRequest() -> <>:: + +Sends a synchronization request to the primary device (for group, contacts, ...). Only works if sent from a secondary device. + +Exception: Failure + sendNoteToSelfMessage(message, attachments) -> timestamp:: * message : Text to send (can be UTF8) * attachments : String array of filenames to send as attachments (passed as filename, so need to be readable by the user signal-cli is running under) diff --git a/src/main/java/org/asamk/Signal.java b/src/main/java/org/asamk/Signal.java index 1eb96510..d981e024 100644 --- a/src/main/java/org/asamk/Signal.java +++ b/src/main/java/org/asamk/Signal.java @@ -49,6 +49,10 @@ public interface Signal extends DBusInterface { String emoji, boolean remove, String targetAuthor, long targetSentTimestamp, List recipients ) throws Error.InvalidNumber, Error.Failure; + void sendContacts() throws Error.Failure; + + void sendSyncRequest() throws Error.Failure; + long sendNoteToSelfMessage( String message, List attachments ) throws Error.AttachmentInvalid, Error.Failure; diff --git a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java index 0fde767d..4a478f13 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java @@ -202,6 +202,24 @@ public class DbusSignalImpl implements Signal { } } + @Override + public void sendContacts() { + try { + m.sendContacts(); + } 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 long sendNoteToSelfMessage( final String message, final List attachments From d47574351e0e27cf308ddacac2b3abf597d34fcb Mon Sep 17 00:00:00 2001 From: John Freed Date: Sun, 26 Sep 2021 09:04:40 +0200 Subject: [PATCH 09/13] implement Dbus setExpirationTimer (#735) implement method update documentation --- man/signal-cli-dbus.5.adoc | 7 +++++++ src/main/java/org/asamk/Signal.java | 2 ++ src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java | 9 +++++++++ 3 files changed, 18 insertions(+) diff --git a/man/signal-cli-dbus.5.adoc b/man/signal-cli-dbus.5.adoc index 8cc234bc..12b87d2b 100755 --- a/man/signal-cli-dbus.5.adoc +++ b/man/signal-cli-dbus.5.adoc @@ -61,6 +61,13 @@ updateProfile(newName, about , aboutEmoji , avatar, remove) -> <> Exceptions: Failure + +setExpirationTimer(number, expiration) -> <>:: +* number : Phone number of recipient +* expiration : int32 for the number of seconds before messages to this recipient disappear. Set to 0 to disable expiration. + +Exceptions: Failure + setContactBlocked(number, block) -> <>:: * number : Phone number affected by method * block : 0=remove block , 1=blocked diff --git a/src/main/java/org/asamk/Signal.java b/src/main/java/org/asamk/Signal.java index d981e024..c5839d14 100644 --- a/src/main/java/org/asamk/Signal.java +++ b/src/main/java/org/asamk/Signal.java @@ -71,6 +71,8 @@ public interface Signal extends DBusInterface { void setContactName(String number, String name) throws Error.InvalidNumber; + void setExpirationTimer(final String number, final int expiration) throws Error.Failure; + void setContactBlocked(String number, boolean blocked) throws Error.InvalidNumber; void setGroupBlocked(byte[] groupId, boolean blocked) throws Error.GroupNotFound, Error.InvalidGroupId; diff --git a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java index 4a478f13..dfd55f62 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java @@ -305,6 +305,15 @@ public class DbusSignalImpl implements Signal { } } + @Override + public void setExpirationTimer(final String number, final int expiration) { + try { + m.setExpirationTimer(getSingleRecipientIdentifier(number, m.getUsername()), expiration); + } catch (IOException e) { + throw new Error.Failure(e.getMessage()); + } + } + @Override public void setContactBlocked(final String number, final boolean blocked) { try { From e78463ea0a81ef326b6adf85a50887de5192fcf7 Mon Sep 17 00:00:00 2001 From: John Freed Date: Sun, 26 Sep 2021 09:26:12 +0200 Subject: [PATCH 10/13] implement Dbus updateAccount and listDevices (#730) * implement Dbus updateAccount and listDevices implement updateAccount(deviceName) to change device name implement listDevices update documentation * implement Dbus addDevice and removeDevice update documentation as well * Dbus add/remove/list/update devices modifications responding to requests by AsamK * Dbus incorporating InvalidUri error Co-authored-by: AsamK --- man/signal-cli-dbus.5.adoc | 80 +++++++++++++++++++ src/main/java/org/asamk/Signal.java | 15 ++++ .../org/asamk/signal/dbus/DbusSignalImpl.java | 49 ++++++++++++ 3 files changed, 144 insertions(+) diff --git a/man/signal-cli-dbus.5.adoc b/man/signal-cli-dbus.5.adoc index 12b87d2b..5d65c48f 100755 --- a/man/signal-cli-dbus.5.adoc +++ b/man/signal-cli-dbus.5.adoc @@ -44,6 +44,64 @@ Phone numbers always have the format + == Methods +=== Control methods +These methods are available if the daemon is started anonymously (without an explicit `-u USERNAME`). +Requests are sent to `/org/asamk/Signal`; requests related to individual accounts are sent to +`/org/asamk/Signal/_441234567890` where the + dialing code is replaced by an underscore (_). +Only `version()` is activated in single-user mode; the rest are disabled. + +link() -> deviceLinkUri:: +link(newDeviceName) -> deviceLinkUri:: +* newDeviceName : Name to give new device (defaults to "cli" if no name is given) +* deviceLinkUri : URI of newly linked device + +Returns a URI of the form "tsdevice:/?uuid=...". This can be piped to a QR encoder to create a display that +can be captured by a Signal smartphone client. For example: + +`dbus-send --session --dest=org.asamk.Signal --type=method_call --print-reply /org/asamk/Signal org.asamk.Signal.link string:"My secondary client"|tr '\n' '\0'|sed 's/.*string //g'|sed 's/\"//g'|qrencode -s10 -tANSI256` + +Exception: Failure + +listAccounts() -> accountList:: +* accountList : Array of all attached accounts in DBus object path form + +Exceptions: None + +register(number, voiceVerification) -> <>:: +* number : Phone number +* voiceVerification : true = use voice verification; false = use SMS verification + +Exceptions: Failure, InvalidNumber, RequiresCaptcha + +registerWithCaptcha(number, voiceVerification, captcha) -> <>:: +* number : Phone number +* voiceVerification : true = use voice verification; false = use SMS verification +* captcha : Captcha string + +Exceptions: Failure, InvalidNumber, RequiresCaptcha + +verify(number, verificationCode) -> <>:: +* number : Phone number +* verificationCode : Code received from Signal after successful registration request + +Command fails if PIN was set after previous registration; use verifyWithPin instead. + +Exception: Failure, InvalidNumber + +verifyWithPin(number, verificationCode, pin) -> <>:: +* number : Phone number +* verificationCode : Code received from Signal after successful registration request +* pin : PIN you set with setPin command after verifying previous registration + +Exception: Failure, InvalidNumber + +version() -> version:: +* version : Version string of signal-cli + +Exceptions: None + +=== Other methods + updateGroup(groupId, newName, members, avatar) -> groupId:: * groupId : Byte array representing the internal group identifier * newName : New name of group (empty if unchanged) @@ -267,6 +325,28 @@ version() -> version:: isRegistred -> result:: * result : Currently always returns 1=true +addDevice(deviceUri) -> <>:: +* deviceUri : URI in the form of tsdevice:/?uuid=... Normally received from Signal desktop or smartphone app + +Exception: InvalidUri + +listDevices() -> devices:: +* devices : String array of linked devices + +Exception: Failure + +removeDevice(deviceId) -> <>:: +* deviceId : Device ID to remove, obtained from listDevices() command + +Exception: Failure + +updateDeviceName(deviceName) -> <>:: +* deviceName : New name + +Set a new name for this device (main or linked). + +Exception: Failure + uploadStickerPack(stickerPackPath) -> url:: * stickerPackPath : Path to the manifest.json file or a zip file in the same directory * url : URL of sticker pack after successful upload diff --git a/src/main/java/org/asamk/Signal.java b/src/main/java/org/asamk/Signal.java index c5839d14..55585c0d 100644 --- a/src/main/java/org/asamk/Signal.java +++ b/src/main/java/org/asamk/Signal.java @@ -89,6 +89,14 @@ public interface Signal extends DBusInterface { boolean isRegistered(); + void addDevice(String uri) throws Error.InvalidUri; + + void removeDevice(int deviceId) throws Error.Failure; + + List listDevices() throws Error.Failure; + + void updateDeviceName(String deviceName) throws Error.Failure; + void updateProfile( String name, String about, String aboutEmoji, String avatarPath, boolean removeAvatar ) throws Error.Failure; @@ -241,6 +249,13 @@ public interface Signal extends DBusInterface { } } + class InvalidUri extends DBusExecutionException { + + public InvalidUri(final String message) { + super(message); + } + } + class Failure extends DBusExecutionException { public Failure(final String message) { diff --git a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java index dfd55f62..768f6e89 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java @@ -7,6 +7,7 @@ import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.NotMasterDeviceException; import org.asamk.signal.manager.StickerPackInvalidException; import org.asamk.signal.manager.UntrustedIdentityException; +import org.asamk.signal.manager.api.Device; import org.asamk.signal.manager.api.Message; import org.asamk.signal.manager.api.RecipientIdentifier; import org.asamk.signal.manager.api.TypingAction; @@ -20,6 +21,7 @@ import org.asamk.signal.manager.storage.identities.IdentityInfo; import org.asamk.signal.util.ErrorUtils; import org.asamk.signal.util.Util; import org.freedesktop.dbus.exceptions.DBusExecutionException; +import org.whispersystems.libsignal.InvalidKeyException; import org.whispersystems.libsignal.util.Pair; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.groupsv2.GroupLinkNotActiveException; @@ -30,6 +32,8 @@ import org.whispersystems.signalservice.internal.contacts.crypto.Unauthenticated import java.io.File; import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; @@ -62,6 +66,51 @@ public class DbusSignalImpl implements Signal { return objectPath; } + @Override + public void addDevice(String uri) { + try { + m.addDeviceLink(new URI(uri)); + } catch (IOException | InvalidKeyException e) { + throw new Error.Failure(e.getClass().getSimpleName() + " Add device link failed. " + e.getMessage()); + } catch (URISyntaxException e) { + throw new Error.InvalidUri(e.getClass().getSimpleName() + " Device link uri has invalid format: " + e.getMessage()); + } + } + + @Override + public void removeDevice(int deviceId) { + try { + m.removeLinkedDevices(deviceId); + } catch (IOException e) { + throw new Error.Failure(e.getClass().getSimpleName() + ": Error while removing device: " + e.getMessage()); + } + } + + @Override + public List listDevices() { + List devices; + List results = new ArrayList(); + + try { + devices = m.getLinkedDevices(); + } catch (IOException | Error.Failure e) { + throw new Error.Failure("Failed to get linked devices: " + e.getMessage()); + } + + return devices.stream() + .map(d -> d.getName() == null ? "" : d.getName()) + .collect(Collectors.toList()); + } + + @Override + public void updateDeviceName(String deviceName) { + try { + m.updateAccountAttributes(deviceName); + } catch (IOException | Signal.Error.Failure e) { + throw new Error.Failure("UpdateAccount error: " + e.getMessage()); + } + } + @Override public long sendMessage(final String message, final List attachments, final String recipient) { var recipients = new ArrayList(1); From df8dd54791090b0d9fae82a94af5554f79a7d71d Mon Sep 17 00:00:00 2001 From: AsamK Date: Sun, 26 Sep 2021 09:27:55 +0200 Subject: [PATCH 11/13] Reformat code --- src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java index 768f6e89..7e78d85b 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java @@ -73,7 +73,9 @@ public class DbusSignalImpl implements Signal { } catch (IOException | InvalidKeyException e) { throw new Error.Failure(e.getClass().getSimpleName() + " Add device link failed. " + e.getMessage()); } catch (URISyntaxException e) { - throw new Error.InvalidUri(e.getClass().getSimpleName() + " Device link uri has invalid format: " + e.getMessage()); + throw new Error.InvalidUri(e.getClass().getSimpleName() + + " Device link uri has invalid format: " + + e.getMessage()); } } @@ -97,9 +99,7 @@ public class DbusSignalImpl implements Signal { throw new Error.Failure("Failed to get linked devices: " + e.getMessage()); } - return devices.stream() - .map(d -> d.getName() == null ? "" : d.getName()) - .collect(Collectors.toList()); + return devices.stream().map(d -> d.getName() == null ? "" : d.getName()).collect(Collectors.toList()); } @Override From 1c4a32fef4a3273099f0bfdd1b0dea72d32324ae Mon Sep 17 00:00:00 2001 From: John Freed Date: Sun, 26 Sep 2021 20:09:57 +0200 Subject: [PATCH 12/13] implement Dbus isRegistered() methods (#729) * implement Dbus isRegistered() methods isRegistered(number) returns a boolean isRegistered(numbers) returns an array of Booleans * Dbus isRegistered() methods restore isRegistered() and respond to other requests by AsamK --- man/signal-cli-dbus.5.adoc | 11 +++++-- src/main/java/org/asamk/Signal.java | 6 +++- .../org/asamk/signal/dbus/DbusSignalImpl.java | 29 ++++++++++++++++++- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/man/signal-cli-dbus.5.adoc b/man/signal-cli-dbus.5.adoc index 5d65c48f..6b5d1a86 100755 --- a/man/signal-cli-dbus.5.adoc +++ b/man/signal-cli-dbus.5.adoc @@ -322,8 +322,15 @@ Exception: Failure version() -> version:: * version : Version string of signal-cli -isRegistred -> result:: -* result : Currently always returns 1=true +isRegistered() -> result:: +isRegistered(number) -> result:: +isRegistered(numbers) -> results:: +* number : Phone number +* numbers : String array of phone numbers +* result : true=number is registered, false=number is not registered +* results : Boolean array of results + +Exception: InvalidNumber for an incorrectly formatted phone number. For unknown numbers, false is returned, but no exception is raised. If no number is given, returns whether you are registered (presumably true). addDevice(deviceUri) -> <>:: * deviceUri : URI in the form of tsdevice:/?uuid=... Normally received from Signal desktop or smartphone app diff --git a/src/main/java/org/asamk/Signal.java b/src/main/java/org/asamk/Signal.java index 55585c0d..3bfeb5bd 100644 --- a/src/main/java/org/asamk/Signal.java +++ b/src/main/java/org/asamk/Signal.java @@ -87,7 +87,11 @@ public interface Signal extends DBusInterface { byte[] groupId, String name, List members, String avatar ) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber, Error.GroupNotFound, Error.InvalidGroupId; - boolean isRegistered(); + boolean isRegistered() throws Error.Failure, Error.InvalidNumber; + + boolean isRegistered(String number) throws Error.Failure, Error.InvalidNumber; + + List isRegistered(List numbers) throws Error.Failure, Error.InvalidNumber; void addDevice(String uri) throws Error.InvalidUri; diff --git a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java index 7e78d85b..82cd8f8d 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java @@ -41,6 +41,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.UUID; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -467,7 +468,33 @@ public class DbusSignalImpl implements Signal { @Override public boolean isRegistered() { - return true; + var result = isRegistered(List.of(m.getUsername())); + return result.get(0); + } + + @Override + public boolean isRegistered(String number) { + var result = isRegistered(List.of(number)); + return result.get(0); + } + + @Override + public List isRegistered(List numbers) { + var results = new ArrayList (); + Map> registered; + if (numbers.isEmpty()) { + return results; + } + try { + registered = m.areUsersRegistered(new HashSet(numbers)); + } catch (IOException e) { + throw new Error.Failure(e.getMessage()); + } + for (String number : numbers) { + UUID uuid = registered.get(number).second(); + results.add(uuid != null); + } + return results; } @Override From 375c9d60cf27d10882bd1a4fd5d5f7ca90eca8ed Mon Sep 17 00:00:00 2001 From: AsamK Date: Sun, 26 Sep 2021 20:16:27 +0200 Subject: [PATCH 13/13] Refactor isRegistered --- .../org/asamk/signal/dbus/DbusSignalImpl.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java index 82cd8f8d..63764a2f 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java @@ -468,8 +468,7 @@ public class DbusSignalImpl implements Signal { @Override public boolean isRegistered() { - var result = isRegistered(List.of(m.getUsername())); - return result.get(0); + return true; } @Override @@ -480,21 +479,22 @@ public class DbusSignalImpl implements Signal { @Override public List isRegistered(List numbers) { - var results = new ArrayList (); - Map> registered; + var results = new ArrayList(); if (numbers.isEmpty()) { return results; } + + Map> registered; try { - registered = m.areUsersRegistered(new HashSet(numbers)); + registered = m.areUsersRegistered(new HashSet<>(numbers)); } catch (IOException e) { throw new Error.Failure(e.getMessage()); } - for (String number : numbers) { - UUID uuid = registered.get(number).second(); - results.add(uuid != null); - } - return results; + + return numbers.stream().map(number -> { + var uuid = registered.get(number).second(); + return uuid != null; + }).collect(Collectors.toList()); } @Override