]> nmode's Git Repositories - signal-cli/commitdiff
implement Dbus updateAccount and listDevices (#730)
authorJohn Freed <okgithub@johnfreed.com>
Sun, 26 Sep 2021 07:26:12 +0000 (09:26 +0200)
committerGitHub <noreply@github.com>
Sun, 26 Sep 2021 07:26:12 +0000 (09:26 +0200)
* implement Dbus updateAccount and listDevices

implement updateAccount(deviceName<s>) 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 <asamk@gmx.de>
man/signal-cli-dbus.5.adoc
src/main/java/org/asamk/Signal.java
src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java

index 12b87d2b546847adb55154322a856c10f00d64ab..5d65c48fc64b77e7825b544cc231c8cc11c2f937 100755 (executable)
@@ -44,6 +44,64 @@ Phone numbers always have the format +<countrycode><regional number>
 
 == 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<s>::
+link(newDeviceName<s>) -> deviceLinkUri<s>::
+* 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<as>::
+* accountList : Array of all attached accounts in DBus object path form
+
+Exceptions: None
+
+register(number<s>, voiceVerification<b>) -> <>::
+* number            : Phone number
+* voiceVerification : true = use voice verification; false = use SMS verification
+
+Exceptions: Failure, InvalidNumber, RequiresCaptcha
+
+registerWithCaptcha(number<s>, voiceVerification<b>, captcha<s>) -> <>::
+* number            : Phone number
+* voiceVerification : true = use voice verification; false = use SMS verification
+* captcha           : Captcha string
+
+Exceptions: Failure, InvalidNumber, RequiresCaptcha
+
+verify(number<s>, verificationCode<s>) -> <>::
+* 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<s>, verificationCode<s>, pin<s>) -> <>::
+* 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<s>::
+* version : Version string of signal-cli
+
+Exceptions: None
+
+=== Other methods
+
 updateGroup(groupId<ay>, newName<s>, members<as>, avatar<s>) -> groupId<ay>::
 * groupId  : Byte array representing the internal group identifier
 * newName  : New name of group (empty if unchanged)
@@ -267,6 +325,28 @@ version() -> version<s>::
 isRegistred -> result<b>::
 * result : Currently always returns 1=true
 
+addDevice(deviceUri<s>) -> <>::
+* deviceUri : URI in the form of tsdevice:/?uuid=... Normally received from Signal desktop or smartphone app
+
+Exception: InvalidUri
+
+listDevices() -> devices<as>::
+* devices  : String array of linked devices
+
+Exception: Failure
+
+removeDevice(deviceId<i>) -> <>::
+* deviceId : Device ID to remove, obtained from listDevices() command
+
+Exception: Failure
+
+updateDeviceName(deviceName<s>) -> <>::
+* deviceName : New name 
+
+Set a new name for this device (main or linked).
+
+Exception: Failure
+
 uploadStickerPack(stickerPackPath<s>) -> url<s>::
 * stickerPackPath : Path to the manifest.json file or a zip file in the same directory
 * url             : URL of sticker pack after successful upload
index c5839d1498fd5aecdb58aba2967698bf2483a171..55585c0d829697d0deb5dce1df20f4eca9c756af 100644 (file)
@@ -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<String> 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) {
index dfd55f62a5985e7e8c61021bebc99126384fe1fa..768f6e8970021edc7e9b0f0802bc7587475007d0 100644 (file)
@@ -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<String> listDevices() {
+        List<Device> devices;
+        List<String> results = new ArrayList<String>();
+
+        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<String> attachments, final String recipient) {
         var recipients = new ArrayList<String>(1);