import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage;
import org.whispersystems.signalservice.api.profiles.ProfileAndCredential;
import org.whispersystems.signalservice.api.profiles.SignalServiceProfile;
-import org.whispersystems.signalservice.api.push.ContactTokenDetails;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.push.exceptions.MissingConfigurationException;
import org.whispersystems.signalservice.api.util.InvalidNumberException;
import org.whispersystems.signalservice.internal.push.UnsupportedDataMessageException;
import org.whispersystems.signalservice.internal.util.DynamicCredentialsProvider;
import org.whispersystems.signalservice.internal.util.Hex;
+import org.whispersystems.signalservice.internal.util.Util;
import java.io.Closeable;
import java.io.File;
*/
public Map<String, Boolean> areUsersRegistered(Set<String> numbers) throws IOException {
// Note "contactDetails" has no optionals. It only gives us info on users who are registered
- List<ContactTokenDetails> contactDetails = this.accountManager.getContacts(numbers);
+ Map<String, UUID> contactDetails = getRegisteredUsers(numbers);
- Set<String> registeredUsers = contactDetails.stream()
- .map(ContactTokenDetails::getNumber)
- .collect(Collectors.toSet());
+ Set<String> registeredUsers = contactDetails.keySet();
return numbers.stream().collect(Collectors.toMap(x -> x, registeredUsers::contains));
}
avatarStore.deleteProfileAvatar(getSelfAddress());
}
}
+
+ try {
+ sendSyncMessage(SignalServiceSyncMessage.forFetchLatest(SignalServiceSyncMessage.FetchType.LOCAL_PROFILE));
+ } catch (UntrustedIdentityException ignored) {
+ }
}
public void unregister() throws IOException {
}
public void setRegistrationLockPin(Optional<String> pin) throws IOException, UnauthenticatedResponseException {
+ if (!account.isMasterDevice()) {
+ throw new RuntimeException("Only master device can set a PIN");
+ }
if (pin.isPresent()) {
final MasterKey masterKey = account.getPinMasterKey() != null
? account.getPinMasterKey()
private SignalProfile getRecipientProfile(
SignalServiceAddress address
+ ) {
+ return getRecipientProfile(address, false);
+ }
+
+ private SignalProfile getRecipientProfile(
+ SignalServiceAddress address, boolean force
) {
SignalProfileEntry profileEntry = account.getProfileStore().getProfileEntry(address);
if (profileEntry == null) {
long now = new Date().getTime();
// Profiles are cached for 24h before retrieving them again
if (!profileEntry.isRequestPending() && (
- profileEntry.getProfile() == null || now - profileEntry.getLastUpdateTimestamp() > 24 * 60 * 60 * 1000
+ force
+ || profileEntry.getProfile() == null
+ || now - profileEntry.getLastUpdateTimestamp() > 24 * 60 * 60 * 1000
)) {
profileEntry.setRequestPending(true);
final SignalServiceProfile encryptedProfile;
newE164Members.add(member.getNumber().get());
}
- final List<ContactTokenDetails> contacts = accountManager.getContacts(newE164Members);
- if (contacts.size() != newE164Members.size()) {
+ final Map<String, UUID> registeredUsers = getRegisteredUsers(newE164Members);
+ if (registeredUsers.size() != newE164Members.size()) {
// Some of the new members are not registered on Signal
- for (ContactTokenDetails contact : contacts) {
- newE164Members.remove(contact.getNumber());
- }
+ newE164Members.removeAll(registeredUsers.keySet());
throw new IOException("Failed to add members "
+ String.join(", ", newE164Members)
+ " to group: Not registered on Signal");
private Collection<SignalServiceAddress> getSignalServiceAddresses(Collection<String> numbers) throws InvalidNumberException {
final Set<SignalServiceAddress> signalServiceAddresses = new HashSet<>(numbers.size());
- final Set<SignalServiceAddress> missingUuids = new HashSet<>();
+ final Set<SignalServiceAddress> addressesMissingUuid = new HashSet<>();
for (String number : numbers) {
final SignalServiceAddress resolvedAddress = canonicalizeAndResolveSignalServiceAddress(number);
if (resolvedAddress.getUuid().isPresent()) {
signalServiceAddresses.add(resolvedAddress);
} else {
- missingUuids.add(resolvedAddress);
+ addressesMissingUuid.add(resolvedAddress);
}
}
+ final Set<String> numbersMissingUuid = addressesMissingUuid.stream()
+ .map(a -> a.getNumber().get())
+ .collect(Collectors.toSet());
Map<String, UUID> registeredUsers;
try {
- registeredUsers = accountManager.getRegisteredUsers(getIasKeyStore(),
- missingUuids.stream().map(a -> a.getNumber().get()).collect(Collectors.toSet()),
- CDS_MRENCLAVE);
- } catch (IOException | Quote.InvalidQuoteFormatException | UnauthenticatedQuoteException | SignatureException | UnauthenticatedResponseException e) {
+ registeredUsers = getRegisteredUsers(numbersMissingUuid);
+ } catch (IOException e) {
logger.warn("Failed to resolve uuids from server, ignoring: {}", e.getMessage());
- registeredUsers = new HashMap<>();
+ registeredUsers = Map.of();
}
- for (SignalServiceAddress address : missingUuids) {
+ for (SignalServiceAddress address : addressesMissingUuid) {
final String number = address.getNumber().get();
if (registeredUsers.containsKey(number)) {
final SignalServiceAddress newAddress = resolveSignalServiceAddress(new SignalServiceAddress(
return signalServiceAddresses;
}
+ private Map<String, UUID> getRegisteredUsers(final Set<String> numbersMissingUuid) throws IOException {
+ try {
+ return accountManager.getRegisteredUsers(getIasKeyStore(), numbersMissingUuid, CDS_MRENCLAVE);
+ } catch (Quote.InvalidQuoteFormatException | UnauthenticatedQuoteException | SignatureException | UnauthenticatedResponseException e) {
+ throw new IOException(e);
+ }
+ }
+
private Pair<Long, List<SendMessageResult>> sendMessage(
SignalServiceDataMessage.Builder messageBuilder, Collection<SignalServiceAddress> recipients
) throws IOException {
account.getStickerStore().updateSticker(sticker);
}
}
+ if (syncMessage.getFetchType().isPresent()) {
+ switch (syncMessage.getFetchType().get()) {
+ case LOCAL_PROFILE:
+ getRecipientProfile(getSelfAddress(), true);
+ case STORAGE_MANIFEST:
+ // TODO
+ }
+ }
if (syncMessage.getConfiguration().isPresent()) {
// TODO
}
return account.getContactStore().getContacts();
}
- public ContactInfo getContact(String number) {
- return account.getContactStore().getContact(Utils.getSignalServiceAddressFromIdentifier(number));
+ public String getContactOrProfileName(String number) {
+ final SignalServiceAddress address = Utils.getSignalServiceAddressFromIdentifier(number);
+
+ final ContactInfo contact = account.getContactStore().getContact(address);
+ if (contact != null && !Util.isEmpty(contact.name)) {
+ return contact.name;
+ }
+
+ final SignalProfileEntry profileEntry = account.getProfileStore().getProfileEntry(address);
+ if (profileEntry != null && profileEntry.getProfile() != null) {
+ return profileEntry.getProfile().getName();
+ }
+
+ return null;
}
public GroupInfo getGroup(GroupId groupId) {