1 package org
.asamk
.signal
.commands
;
3 import com
.fasterxml
.jackson
.annotation
.JsonInclude
;
5 import net
.sourceforge
.argparse4j
.inf
.Namespace
;
6 import net
.sourceforge
.argparse4j
.inf
.Subparser
;
8 import org
.asamk
.signal
.commands
.exceptions
.CommandException
;
9 import org
.asamk
.signal
.commands
.exceptions
.IOErrorException
;
10 import org
.asamk
.signal
.commands
.exceptions
.RateLimitErrorException
;
11 import org
.asamk
.signal
.manager
.Manager
;
12 import org
.asamk
.signal
.manager
.api
.RateLimitException
;
13 import org
.asamk
.signal
.manager
.api
.UserStatus
;
14 import org
.asamk
.signal
.manager
.api
.UsernameStatus
;
15 import org
.asamk
.signal
.output
.JsonWriter
;
16 import org
.asamk
.signal
.output
.OutputWriter
;
17 import org
.asamk
.signal
.output
.PlainTextWriter
;
18 import org
.asamk
.signal
.util
.CommandUtil
;
19 import org
.slf4j
.Logger
;
20 import org
.slf4j
.LoggerFactory
;
22 import java
.io
.IOException
;
23 import java
.util
.HashSet
;
26 import java
.util
.stream
.Stream
;
28 public class GetUserStatusCommand
implements JsonRpcLocalCommand
{
30 private static final Logger logger
= LoggerFactory
.getLogger(GetUserStatusCommand
.class);
33 public String
getName() {
34 return "getUserStatus";
38 public void attachToSubparser(final Subparser subparser
) {
39 subparser
.help("Check if the specified phone number/s have been registered");
40 subparser
.addArgument("recipient").help("Phone number").nargs("*");
41 subparser
.addArgument("--username").help("Specify the recipient username or username link.").nargs("*");
45 public void handleCommand(
48 final OutputWriter outputWriter
49 ) throws CommandException
{
50 // Get a map of registration statuses
51 Map
<String
, UserStatus
> registered
;
53 final var recipient
= ns
.<String
>getList("recipient");
54 registered
= m
.getUserStatus(recipient
== null ? Set
.of() : new HashSet
<>(recipient
));
55 } catch (RateLimitException e
) {
56 final var message
= CommandUtil
.getRateLimitMessage(e
);
57 throw new RateLimitErrorException(message
, e
);
58 } catch (IOException e
) {
59 throw new IOErrorException("Unable to check if users are registered: "
62 + e
.getClass().getSimpleName()
66 final var usernames
= ns
.<String
>getList("username");
67 final var registeredUsernames
= usernames
== null
68 ? Map
.<String
, UsernameStatus
>of()
69 : m
.getUsernameStatus(new HashSet
<>(usernames
));
72 switch (outputWriter
) {
73 case JsonWriter writer
-> {
74 var jsonUserStatuses
= Stream
.concat(registered
.entrySet().stream().map(entry
-> {
75 final var number
= entry
.getValue().number();
76 final var uuid
= entry
.getValue().uuid();
77 return new JsonUserStatus(entry
.getKey(),
80 uuid
== null ?
null : uuid
.toString(),
82 }), registeredUsernames
.entrySet().stream().map(entry
-> {
83 final var username
= entry
.getValue().username();
84 final var uuid
= entry
.getValue().uuid();
85 return new JsonUserStatus(entry
.getKey(),
88 uuid
== null ?
null : uuid
.toString(),
91 writer
.write(jsonUserStatuses
);
93 case PlainTextWriter writer
-> {
94 for (var entry
: registered
.entrySet()) {
95 final var userStatus
= entry
.getValue();
96 writer
.println("{}: {}{}",
98 userStatus
.uuid() != null,
99 userStatus
.unrestrictedUnidentifiedAccess() ?
" (unrestricted sealed sender)" : "");
101 for (var entry
: registeredUsernames
.entrySet()) {
102 final var userStatus
= entry
.getValue();
103 writer
.println("{}: {}{}",
105 userStatus
.uuid() != null,
106 userStatus
.unrestrictedUnidentifiedAccess() ?
" (unrestricted sealed sender)" : "");
112 private record JsonUserStatus(
114 @JsonInclude(JsonInclude
.Include
.NON_NULL
) String number
,
115 @JsonInclude(JsonInclude
.Include
.NON_NULL
) String username
,