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(
46 final Namespace ns
, final Manager m
, final OutputWriter outputWriter
47 ) throws CommandException
{
48 // Get a map of registration statuses
49 Map
<String
, UserStatus
> registered
;
51 final var recipient
= ns
.<String
>getList("recipient");
52 registered
= m
.getUserStatus(recipient
== null ? Set
.of() : new HashSet
<>(recipient
));
53 } catch (RateLimitException e
) {
54 final var message
= CommandUtil
.getRateLimitMessage(e
);
55 throw new RateLimitErrorException(message
, e
);
56 } catch (IOException e
) {
57 throw new IOErrorException("Unable to check if users are registered: "
60 + e
.getClass().getSimpleName()
64 final var usernames
= ns
.<String
>getList("username");
65 final var registeredUsernames
= usernames
== null
66 ? Map
.<String
, UsernameStatus
>of()
67 : m
.getUsernameStatus(new HashSet
<>(usernames
));
70 switch (outputWriter
) {
71 case JsonWriter writer
-> {
72 var jsonUserStatuses
= Stream
.concat(registered
.entrySet().stream().map(entry
-> {
73 final var number
= entry
.getValue().number();
74 final var uuid
= entry
.getValue().uuid();
75 return new JsonUserStatus(entry
.getKey(),
78 uuid
== null ?
null : uuid
.toString(),
80 }), registeredUsernames
.entrySet().stream().map(entry
-> {
81 final var username
= entry
.getValue().username();
82 final var uuid
= entry
.getValue().uuid();
83 return new JsonUserStatus(entry
.getKey(),
86 uuid
== null ?
null : uuid
.toString(),
89 writer
.write(jsonUserStatuses
);
91 case PlainTextWriter writer
-> {
92 for (var entry
: registered
.entrySet()) {
93 final var userStatus
= entry
.getValue();
94 writer
.println("{}: {}{}",
96 userStatus
.uuid() != null,
97 userStatus
.unrestrictedUnidentifiedAccess() ?
" (unrestricted sealed sender)" : "");
99 for (var entry
: registeredUsernames
.entrySet()) {
100 final var userStatus
= entry
.getValue();
101 writer
.println("{}: {}{}",
103 userStatus
.uuid() != null,
104 userStatus
.unrestrictedUnidentifiedAccess() ?
" (unrestricted sealed sender)" : "");
110 private record JsonUserStatus(
112 @JsonInclude(JsonInclude
.Include
.NON_NULL
) String number
,
113 @JsonInclude(JsonInclude
.Include
.NON_NULL
) String username
,