1 package org
.asamk
.signal
.commands
;
3 import com
.fasterxml
.jackson
.annotation
.JsonInclude
;
5 import net
.sourceforge
.argparse4j
.impl
.Arguments
;
6 import net
.sourceforge
.argparse4j
.inf
.Namespace
;
7 import net
.sourceforge
.argparse4j
.inf
.Subparser
;
9 import org
.asamk
.signal
.commands
.exceptions
.CommandException
;
10 import org
.asamk
.signal
.commands
.exceptions
.IOErrorException
;
11 import org
.asamk
.signal
.commands
.exceptions
.UserErrorException
;
12 import org
.asamk
.signal
.manager
.Manager
;
13 import org
.asamk
.signal
.manager
.api
.InvalidUsernameException
;
14 import org
.asamk
.signal
.output
.JsonWriter
;
15 import org
.asamk
.signal
.output
.OutputWriter
;
16 import org
.asamk
.signal
.output
.PlainTextWriter
;
18 import java
.io
.IOException
;
20 public class UpdateAccountCommand
implements JsonRpcLocalCommand
{
23 public String
getName() {
24 return "updateAccount";
28 public void attachToSubparser(final Subparser subparser
) {
29 subparser
.help("Update the account attributes on the signal server.");
30 subparser
.addArgument("-n", "--device-name").help("Specify a name to describe this device.");
31 subparser
.addArgument("--unrestricted-unidentified-sender")
33 .help("Enable if anyone should be able to send you unidentified sender messages.");
34 subparser
.addArgument("--discoverable-by-number")
36 .help("Enable/disable if the account should be discoverable by phone number");
37 subparser
.addArgument("--number-sharing")
39 .help("Indicates if Signal should share its phone number when sending a message.");
41 var mut
= subparser
.addMutuallyExclusiveGroup();
42 mut
.addArgument("-u", "--username").help("Specify a username that can then be used to contact this account.");
43 mut
.addArgument("--delete-username")
44 .action(Arguments
.storeTrue())
45 .help("Delete the username associated with this account.");
49 public void handleCommand(
50 final Namespace ns
, final Manager m
, final OutputWriter outputWriter
51 ) throws CommandException
{
52 final var deviceName
= ns
.getString("device-name");
53 final var unrestrictedUnidentifiedSender
= ns
.getBoolean("unrestricted-unidentified-sender");
54 final var discoverableByNumber
= ns
.getBoolean("discoverable-by-number");
55 final var numberSharing
= ns
.getBoolean("number-sharing");
57 m
.updateAccountAttributes(deviceName
, unrestrictedUnidentifiedSender
, discoverableByNumber
, numberSharing
);
58 } catch (IOException e
) {
59 throw new IOErrorException("UpdateAccount error: " + e
.getMessage(), e
);
62 final var username
= ns
.getString("username");
63 if (username
!= null) {
65 m
.setUsername(username
);
66 final var newUsername
= m
.getUsername();
67 final var newUsernameLink
= m
.getUsernameLink();
68 switch (outputWriter
) {
69 case PlainTextWriter w
-> w
.println("Your new username: {} ({})",
71 newUsernameLink
== null ?
"-" : newUsernameLink
.getUrl());
72 case JsonWriter w
-> w
.write(new JsonAccountResponse(newUsername
,
73 newUsernameLink
== null ?
null : newUsernameLink
.getUrl()));
75 } catch (IOException e
) {
76 throw new IOErrorException("Failed to set username: " + e
.getMessage(), e
);
77 } catch (InvalidUsernameException e
) {
78 throw new UserErrorException("Invalid username: " + e
.getMessage(), e
);
82 final var deleteUsername
= Boolean
.TRUE
.equals(ns
.getBoolean("delete-username"));
86 } catch (IOException e
) {
87 throw new IOErrorException("Failed to delete username: " + e
.getMessage(), e
);
92 private record JsonAccountResponse(
93 @JsonInclude(JsonInclude
.Include
.NON_NULL
) String username
,
94 @JsonInclude(JsonInclude
.Include
.NON_NULL
) String usernameLink