X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/f96770df3c6602ba45cb7e1ff10faa81602988c7..6c4d272309c7f7f8e42ecf1070e561a321e6c5f0:/src/main/java/org/asamk/signal/manager/Manager.java diff --git a/src/main/java/org/asamk/signal/manager/Manager.java b/src/main/java/org/asamk/signal/manager/Manager.java index 2b561304..73c2b5c7 100644 --- a/src/main/java/org/asamk/signal/manager/Manager.java +++ b/src/main/java/org/asamk/signal/manager/Manager.java @@ -38,7 +38,6 @@ import org.signal.libsignal.metadata.ProtocolUntrustedIdentityException; import org.signal.libsignal.metadata.SelfSendException; import org.signal.libsignal.metadata.certificate.InvalidCertificateException; import org.signal.zkgroup.InvalidInputException; -import org.signal.zkgroup.VerificationFailedException; import org.signal.zkgroup.profiles.ClientZkProfileOperations; import org.signal.zkgroup.profiles.ProfileKey; import org.whispersystems.libsignal.IdentityKey; @@ -135,6 +134,8 @@ import java.util.Locale; import java.util.Objects; import java.util.Set; import java.util.UUID; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; @@ -152,6 +153,7 @@ public class Manager implements Closeable { private SignalServiceAccountManager accountManager; private SignalServiceMessagePipe messagePipe = null; private SignalServiceMessagePipe unidentifiedMessagePipe = null; + private boolean discoverableByPhoneNumber = true; public Manager(SignalAccount account, PathConfig pathConfig, SignalServiceConfiguration serviceConfiguration, String userAgent) { this.account = account; @@ -285,21 +287,13 @@ public class Manager implements Closeable { } public void updateAccountAttributes() throws IOException { - accountManager.setAccountAttributes(account.getSignalingKey(), account.getSignalProtocolStore().getLocalRegistrationId(), true, account.getRegistrationLockPin(), account.getRegistrationLock(), getSelfUnidentifiedAccessKey(), false, ServiceConfig.capabilities); + accountManager.setAccountAttributes(account.getSignalingKey(), account.getSignalProtocolStore().getLocalRegistrationId(), true, account.getRegistrationLockPin(), account.getRegistrationLock(), getSelfUnidentifiedAccessKey(), false, ServiceConfig.capabilities, discoverableByPhoneNumber); } - public void setProfileName(String name) throws IOException { - accountManager.setProfileName(account.getProfileKey(), name); - } - - public void setProfileAvatar(File avatar) throws IOException { - final StreamDetails streamDetails = Utils.createStreamDetailsFromFile(avatar); - accountManager.setProfileAvatar(account.getProfileKey(), streamDetails); - streamDetails.getStream().close(); - } - - public void removeProfileAvatar() throws IOException { - accountManager.setProfileAvatar(account.getProfileKey(), null); + public void setProfile(String name, File avatar) throws IOException { + try (final StreamDetails streamDetails = avatar == null ? null : Utils.createStreamDetailsFromFile(avatar)) { + accountManager.setVersionedProfile(account.getUuid(), account.getProfileKey(), name, streamDetails); + } } public void unregister() throws IOException { @@ -378,7 +372,7 @@ public class Manager implements Closeable { verificationCode = verificationCode.replace("-", ""); account.setSignalingKey(KeyUtils.createSignalingKey()); // TODO make unrestricted unidentified access configurable - VerifyAccountResponse response = accountManager.verifyAccountWithCode(verificationCode, account.getSignalingKey(), account.getSignalProtocolStore().getLocalRegistrationId(), true, pin, null, getSelfUnidentifiedAccessKey(), false, ServiceConfig.capabilities); + VerifyAccountResponse response = accountManager.verifyAccountWithCode(verificationCode, account.getSignalingKey(), account.getSignalProtocolStore().getLocalRegistrationId(), true, pin, null, getSelfUnidentifiedAccessKey(), false, ServiceConfig.capabilities, discoverableByPhoneNumber); UUID uuid = UuidUtil.parseOrNull(response.getUuid()); // TODO response.isStorageCapable() @@ -421,8 +415,9 @@ public class Manager implements Closeable { // TODO implement ZkGroup support final ClientZkProfileOperations clientZkProfileOperations = null; final boolean attachmentsV3 = false; + final ExecutorService executor = null; return new SignalServiceMessageSender(serviceConfiguration, account.getUuid(), account.getUsername(), account.getPassword(), - account.getDeviceId(), account.getSignalProtocolStore(), userAgent, account.isMultiDevice(), attachmentsV3, Optional.fromNullable(messagePipe), Optional.fromNullable(unidentifiedMessagePipe), Optional.absent(), clientZkProfileOperations); + account.getDeviceId(), account.getSignalProtocolStore(), userAgent, account.isMultiDevice(), attachmentsV3, Optional.fromNullable(messagePipe), Optional.fromNullable(unidentifiedMessagePipe), Optional.absent(), clientZkProfileOperations, executor); } private SignalServiceProfile getEncryptedRecipientProfile(SignalServiceAddress address, Optional unidentifiedAccess) throws IOException { @@ -431,16 +426,16 @@ public class Manager implements Closeable { if (pipe != null) { try { - return pipe.getProfile(address, Optional.absent(), unidentifiedAccess, SignalServiceProfile.RequestType.PROFILE).getProfile(); - } catch (IOException ignored) { + return pipe.getProfile(address, Optional.absent(), unidentifiedAccess, SignalServiceProfile.RequestType.PROFILE).get(10, TimeUnit.SECONDS).getProfile(); + } catch (IOException | InterruptedException | ExecutionException | TimeoutException ignored) { } } SignalServiceMessageReceiver receiver = getMessageReceiver(); try { - return receiver.retrieveProfile(address, Optional.absent(), unidentifiedAccess, SignalServiceProfile.RequestType.PROFILE).getProfile(); - } catch (VerificationFailedException e) { - throw new AssertionError(e); + return receiver.retrieveProfile(address, Optional.absent(), unidentifiedAccess, SignalServiceProfile.RequestType.PROFILE).get(10, TimeUnit.SECONDS).getProfile(); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + throw new IOException("Failed to retrieve profile", e); } } @@ -562,9 +557,7 @@ public class Manager implements Closeable { for (ContactTokenDetails contact : contacts) { newE164Members.remove(contact.getNumber()); } - System.err.println("Failed to add members " + Util.join(", ", newE164Members) + " to group: Not registered on Signal"); - System.err.println("Aborting…"); - System.exit(1); + throw new IOException("Failed to add members " + Util.join(", ", newE164Members) + " to group: Not registered on Signal"); } g.addMembers(members); @@ -705,9 +698,6 @@ public class Manager implements Closeable { ContactInfo contact = account.getContactStore().getContact(address); if (contact == null) { contact = new ContactInfo(address); - System.err.println("Add contact " + contact.number + " named " + name); - } else { - System.err.println("Updating contact " + contact.number + " name " + contact.name + " -> " + name); } contact.name = name; account.getContactStore().updateContact(contact); @@ -722,9 +712,6 @@ public class Manager implements Closeable { ContactInfo contact = account.getContactStore().getContact(address); if (contact == null) { contact = new ContactInfo(address); - System.err.println("Adding and " + (blocked ? "blocking" : "unblocking") + " contact " + address.getNumber().orNull()); - } else { - System.err.println((blocked ? "Blocking" : "Unblocking") + " contact " + address.getNumber().orNull()); } contact.blocked = blocked; account.getContactStore().updateContact(contact); @@ -735,12 +722,11 @@ public class Manager implements Closeable { GroupInfo group = getGroup(groupId); if (group == null) { throw new GroupNotFoundException(groupId); - } else { - System.err.println((blocked ? "Blocking" : "Unblocking") + " group " + Base64.encodeBytes(groupId)); - group.blocked = blocked; - account.getGroupStore().updateGroup(group); - account.save(); } + + group.blocked = blocked; + account.getGroupStore().updateGroup(group); + account.save(); } public byte[] updateGroup(byte[] groupId, String name, List members, String avatar) throws IOException, EncapsulatedExceptions, GroupNotFoundException, AttachmentInvalidException, InvalidNumberException, NotAGroupMemberException { @@ -851,7 +837,8 @@ public class Manager implements Closeable { throw new StickerPackInvalidException("Could not find find " + sticker.file); } - StickerInfo stickerInfo = new StickerInfo(data.first(), data.second(), Optional.fromNullable(sticker.emoji).or("")); + String contentType = Utils.getFileMimeType(new File(sticker.file), null); + StickerInfo stickerInfo = new StickerInfo(data.first(), data.second(), Optional.fromNullable(sticker.emoji).or(""), contentType); stickers.add(stickerInfo); } @@ -868,7 +855,8 @@ public class Manager implements Closeable { throw new StickerPackInvalidException("Could not find find " + pack.cover.file); } - cover = new StickerInfo(data.first(), data.second(), Optional.fromNullable(pack.cover.emoji).or("")); + String contentType = Utils.getFileMimeType(new File(pack.cover.file), null); + cover = new StickerInfo(data.first(), data.second(), Optional.fromNullable(pack.cover.emoji).or(""), contentType); } return new SignalServiceStickerManifestUpload( @@ -940,10 +928,10 @@ public class Manager implements Closeable { private byte[] getSenderCertificate() { // TODO support UUID capable sender certificates - // byte[] certificate = accountManager.getSenderCertificate(); + // byte[] certificate = accountManager.getSenderCertificateForPhoneNumberPrivacy(); byte[] certificate; try { - certificate = accountManager.getSenderCertificateLegacy(); + certificate = accountManager.getSenderCertificate(); } catch (IOException e) { System.err.println("Failed to get sender certificate: " + e); return null;