import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser;
+import org.asamk.signal.commands.exceptions.CommandException;
import org.asamk.signal.manager.Manager;
-import org.asamk.signal.storage.protocol.JsonIdentityKeyStore;
+import org.asamk.signal.manager.api.Identity;
+import org.asamk.signal.output.JsonWriter;
+import org.asamk.signal.output.OutputWriter;
+import org.asamk.signal.output.PlainTextWriter;
+import org.asamk.signal.util.CommandUtil;
+import org.asamk.signal.util.DateUtils;
import org.asamk.signal.util.Hex;
import org.asamk.signal.util.Util;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.Base64;
import java.util.List;
-import java.util.Map;
+import java.util.UUID;
-public class ListIdentitiesCommand implements LocalCommand {
+public class ListIdentitiesCommand implements JsonRpcLocalCommand {
- private static void printIdentityFingerprint(Manager m, String theirUsername, JsonIdentityKeyStore.Identity theirId) {
- String digits = Util.formatSafetyNumber(m.computeSafetyNumber(theirUsername, theirId.getIdentityKey()));
- System.out.println(String.format("%s: %s Added: %s Fingerprint: %s Safety Number: %s", theirUsername,
- theirId.getTrustLevel(), theirId.getDateAdded(), Hex.toStringCondensed(theirId.getFingerprint()), digits));
+ private static final Logger logger = LoggerFactory.getLogger(ListIdentitiesCommand.class);
+
+ @Override
+ public String getName() {
+ return "listIdentities";
+ }
+
+ private static void printIdentityFingerprint(PlainTextWriter writer, Identity theirId) {
+ writer.println("{}: {} Added: {} Fingerprint: {} Safety Number: {}",
+ theirId.recipient().getLegacyIdentifier(),
+ theirId.trustLevel(),
+ DateUtils.formatTimestamp(theirId.dateAddedTimestamp()),
+ Hex.toString(theirId.fingerprint()),
+ Util.formatSafetyNumber(theirId.safetyNumber()));
}
@Override
public void attachToSubparser(final Subparser subparser) {
- subparser.addArgument("-n", "--number")
- .help("Only show identity keys for the given phone number.");
+ subparser.help("List all known identity keys and their trust status, fingerprint and safety number.");
+ subparser.addArgument("-n", "--number").help("Only show identity keys for the given phone number.");
}
@Override
- public int handleCommand(final Namespace ns, final Manager m) {
- if (!m.isRegistered()) {
- System.err.println("User is not registered.");
- return 1;
+ public void handleCommand(
+ final Namespace ns, final Manager m, final OutputWriter outputWriter
+ ) throws CommandException {
+ var number = ns.getString("number");
+
+ List<Identity> identities;
+ if (number == null) {
+ identities = m.getIdentities();
+ } else {
+ identities = m.getIdentities(CommandUtil.getSingleRecipientIdentifier(number, m.getSelfNumber()));
}
- if (ns.get("number") == null) {
- for (Map.Entry<String, List<JsonIdentityKeyStore.Identity>> keys : m.getIdentities().entrySet()) {
- for (JsonIdentityKeyStore.Identity id : keys.getValue()) {
- printIdentityFingerprint(m, keys.getKey(), id);
+
+ switch (outputWriter) {
+ case PlainTextWriter writer -> {
+ for (var id : identities) {
+ printIdentityFingerprint(writer, id);
}
}
- } else {
- String number = ns.getString("number");
- for (JsonIdentityKeyStore.Identity id : m.getIdentities(number)) {
- printIdentityFingerprint(m, number, id);
+ case JsonWriter writer -> {
+ final var jsonIdentities = identities.stream().map(id -> {
+ final var address = id.recipient();
+ var safetyNumber = Util.formatSafetyNumber(id.safetyNumber());
+ var scannableSafetyNumber = id.scannableSafetyNumber();
+ return new JsonIdentity(address.number().orElse(null),
+ address.uuid().map(UUID::toString).orElse(null),
+ Hex.toString(id.fingerprint()),
+ safetyNumber,
+ scannableSafetyNumber == null
+ ? null
+ : Base64.getEncoder().encodeToString(scannableSafetyNumber),
+ id.trustLevel().name(),
+ id.dateAddedTimestamp());
+ }).toList();
+ writer.write(jsonIdentities);
}
}
- return 0;
}
+
+ private record JsonIdentity(
+ String number,
+ String uuid,
+ String fingerprint,
+ String safetyNumber,
+ String scannableSafetyNumber,
+ String trustLevel,
+ long addedTimestamp
+ ) {}
}