import org.asamk.signal.manager.api.TypingAction;
import org.asamk.signal.manager.api.UnregisteredRecipientException;
import org.asamk.signal.manager.api.UpdateGroup;
+import org.asamk.signal.manager.api.UserStatus;
import org.asamk.signal.manager.groups.GroupId;
import org.asamk.signal.manager.groups.GroupInviteLinkUrl;
import org.asamk.signal.manager.groups.GroupNotFoundException;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
-import java.util.UUID;
public interface Manager extends Closeable {
* @return A map of numbers to canonicalized number and uuid. If a number is not registered the uuid is null.
* @throws IOException if it's unable to get the contacts to check if they're registered
*/
- Map<String, Pair<String, UUID>> areUsersRegistered(Set<String> numbers) throws IOException;
+ Map<String, UserStatus> getUserStatus(Set<String> numbers) throws IOException;
void updateAccountAttributes(String deviceName) throws IOException;
import org.asamk.signal.manager.api.TypingAction;
import org.asamk.signal.manager.api.UnregisteredRecipientException;
import org.asamk.signal.manager.api.UpdateGroup;
+import org.asamk.signal.manager.api.UserStatus;
import org.asamk.signal.manager.config.ServiceEnvironmentConfig;
import org.asamk.signal.manager.groups.GroupId;
import org.asamk.signal.manager.groups.GroupInviteLinkUrl;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
-import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
}
@Override
- public Map<String, Pair<String, UUID>> areUsersRegistered(Set<String> numbers) throws IOException {
+ public Map<String, UserStatus> getUserStatus(Set<String> numbers) throws IOException {
final var canonicalizedNumbers = numbers.stream().collect(Collectors.toMap(n -> n, n -> {
try {
final var canonicalizedNumber = PhoneNumberFormatter.formatNumber(n, account.getNumber());
return numbers.stream().collect(Collectors.toMap(n -> n, n -> {
final var number = canonicalizedNumbers.get(n);
final var aci = registeredUsers.get(number);
- return new Pair<>(number.isEmpty() ? null : number, aci == null ? null : aci.uuid());
+ final var profile = aci == null
+ ? null
+ : context.getProfileHelper().getRecipientProfile(account.getRecipientStore().resolveRecipient(aci));
+ return new UserStatus(number.isEmpty() ? null : number,
+ aci == null ? null : aci.uuid(),
+ profile != null
+ && profile.getUnidentifiedAccessMode() == Profile.UnidentifiedAccessMode.UNRESTRICTED);
}));
}
--- /dev/null
+package org.asamk.signal.manager.api;
+
+import java.util.UUID;
+
+public record UserStatus(String number, UUID uuid, boolean unrestrictedUnidentifiedAccess) {}
import org.asamk.signal.commands.exceptions.CommandException;
import org.asamk.signal.commands.exceptions.IOErrorException;
import org.asamk.signal.manager.Manager;
-import org.asamk.signal.manager.api.Pair;
+import org.asamk.signal.manager.api.UserStatus;
import org.asamk.signal.output.JsonWriter;
import org.asamk.signal.output.OutputWriter;
import org.asamk.signal.output.PlainTextWriter;
import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
-import java.util.UUID;
public class GetUserStatusCommand implements JsonRpcLocalCommand {
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
// Get a map of registration statuses
- Map<String, Pair<String, UUID>> registered;
+ Map<String, UserStatus> registered;
try {
- registered = m.areUsersRegistered(new HashSet<>(ns.getList("recipient")));
+ registered = m.getUserStatus(new HashSet<>(ns.getList("recipient")));
} catch (IOException e) {
throw new IOErrorException("Unable to check if users are registered: "
+ e.getMessage()
if (outputWriter instanceof JsonWriter jsonWriter) {
var jsonUserStatuses = registered.entrySet().stream().map(entry -> {
- final var number = entry.getValue().first();
- final var uuid = entry.getValue().second();
+ final var number = entry.getValue().number();
+ final var uuid = entry.getValue().uuid();
return new JsonUserStatus(entry.getKey(), number, uuid == null ? null : uuid.toString(), uuid != null);
}).toList();
final var writer = (PlainTextWriter) outputWriter;
for (var entry : registered.entrySet()) {
- final var uuid = entry.getValue().second();
- writer.println("{}: {}", entry.getKey(), uuid != null);
+ final var userStatus = entry.getValue();
+ writer.println("{}: {}{}",
+ entry.getKey(),
+ userStatus.uuid() != null,
+ userStatus.unrestrictedUnidentifiedAccess() ? " (unrestricted sealed sender)" : "");
}
}
}
import org.asamk.signal.manager.api.StickerPackUrl;
import org.asamk.signal.manager.api.TypingAction;
import org.asamk.signal.manager.api.UpdateGroup;
+import org.asamk.signal.manager.api.UserStatus;
import org.asamk.signal.manager.groups.GroupId;
import org.asamk.signal.manager.groups.GroupInviteLinkUrl;
import org.asamk.signal.manager.groups.GroupNotFoundException;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
-import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;
import java.util.function.Supplier;
}
@Override
- public Map<String, Pair<String, UUID>> areUsersRegistered(final Set<String> numbers) throws IOException {
+ public Map<String, UserStatus> getUserStatus(final Set<String> numbers) throws IOException {
final var numbersList = new ArrayList<>(numbers);
final var registered = signal.isRegistered(numbersList);
- final var result = new HashMap<String, Pair<String, UUID>>();
+ final var result = new HashMap<String, UserStatus>();
for (var i = 0; i < numbersList.size(); i++) {
result.put(numbersList.get(i),
- new Pair<>(numbersList.get(i), registered.get(i) ? RecipientAddress.UNKNOWN_UUID : null));
+ new UserStatus(numbersList.get(i),
+ registered.get(i) ? RecipientAddress.UNKNOWN_UUID : null,
+ false));
}
return result;
}
import org.asamk.signal.manager.api.TypingAction;
import org.asamk.signal.manager.api.UnregisteredRecipientException;
import org.asamk.signal.manager.api.UpdateGroup;
+import org.asamk.signal.manager.api.UserStatus;
import org.asamk.signal.manager.groups.GroupId;
import org.asamk.signal.manager.groups.GroupInviteLinkUrl;
import org.asamk.signal.manager.groups.GroupLinkState;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
-import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.Stream;
return List.of();
}
- Map<String, Pair<String, UUID>> registered;
+ Map<String, UserStatus> registered;
try {
- registered = m.areUsersRegistered(new HashSet<>(numbers));
+ registered = m.getUserStatus(new HashSet<>(numbers));
} catch (IOException e) {
throw new Error.Failure(e.getMessage());
}
- return numbers.stream().map(number -> {
- var uuid = registered.get(number).second();
- return uuid != null;
- }).toList();
+ return numbers.stream().map(number -> registered.get(number).uuid() != null).toList();
}
@Override