X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/cf1626ea315ba3d7d76fc8f9ec0acc1c7597d631..b178c7c67aea7bf334cbf0d54a4666af0a65b5d9:/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java diff --git a/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java b/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java index b3e6a0ae..b5dcb5e0 100644 --- a/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java @@ -25,7 +25,7 @@ import org.asamk.signal.manager.api.InactiveGroupLinkException; import org.asamk.signal.manager.api.InvalidDeviceLinkException; import org.asamk.signal.manager.api.InvalidStickerException; import org.asamk.signal.manager.api.Message; -import org.asamk.signal.manager.api.NotMasterDeviceException; +import org.asamk.signal.manager.api.NotPrimaryDeviceException; import org.asamk.signal.manager.api.Pair; import org.asamk.signal.manager.api.RecipientIdentifier; import org.asamk.signal.manager.api.SendGroupMessageResults; @@ -38,6 +38,7 @@ import org.asamk.signal.manager.api.StickerPackUrl; 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.UpdateProfile; import org.asamk.signal.manager.api.UserStatus; import org.asamk.signal.manager.config.ServiceEnvironmentConfig; import org.asamk.signal.manager.groups.GroupId; @@ -51,9 +52,8 @@ import org.asamk.signal.manager.helper.Context; import org.asamk.signal.manager.storage.SignalAccount; import org.asamk.signal.manager.storage.groups.GroupInfo; import org.asamk.signal.manager.storage.identities.IdentityInfo; -import org.asamk.signal.manager.storage.recipients.Contact; import org.asamk.signal.manager.storage.recipients.Profile; -import org.asamk.signal.manager.storage.recipients.RecipientAddress; +import org.asamk.signal.manager.storage.recipients.Recipient; import org.asamk.signal.manager.storage.recipients.RecipientId; import org.asamk.signal.manager.storage.stickerPacks.JsonStickerPack; import org.asamk.signal.manager.storage.stickerPacks.StickerPackStore; @@ -65,6 +65,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.whispersystems.signalservice.api.SignalSessionLock; import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage; +import org.whispersystems.signalservice.api.messages.SignalServicePreview; import org.whispersystems.signalservice.api.messages.SignalServiceReceiptMessage; import org.whispersystems.signalservice.api.messages.SignalServiceTypingMessage; import org.whispersystems.signalservice.api.push.ACI; @@ -84,6 +85,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.concurrent.ExecutorService; @@ -101,7 +103,6 @@ class ManagerImpl implements Manager { private final static Logger logger = LoggerFactory.getLogger(ManagerImpl.class); private SignalAccount account; - private AccountFileUpdater accountFileUpdater; private final SignalDependencies dependencies; private final Context context; @@ -123,7 +124,6 @@ class ManagerImpl implements Manager { String userAgent ) { this.account = account; - this.accountFileUpdater = accountFileUpdater; final var sessionLock = new SignalSessionLock() { private final ReentrantLock LEGACY_LOCK = new ReentrantLock(); @@ -169,9 +169,9 @@ class ManagerImpl implements Manager { logger.trace("Archiving old sessions for {}", recipientId); account.getSessionStore().archiveSessions(recipientId); account.getSenderKeyStore().deleteSharedWith(recipientId); - final var profile = account.getRecipientStore().getProfile(recipientId); + final var profile = account.getProfileStore().getProfile(recipientId); if (profile != null) { - account.getRecipientStore() + account.getProfileStore() .storeProfile(recipientId, Profile.newBuilder(profile) .withUnidentifiedAccessMode(Profile.UnidentifiedAccessMode.UNKNOWN) @@ -216,7 +216,8 @@ class ManagerImpl implements Manager { final var aci = registeredUsers.get(number); final var profile = aci == null ? null - : context.getProfileHelper().getRecipientProfile(account.getRecipientStore().resolveRecipient(aci)); + : context.getProfileHelper() + .getRecipientProfile(account.getRecipientResolver().resolveRecipient(aci)); return new UserStatus(number.isEmpty() ? null : number, aci == null ? null : aci.uuid(), profile != null @@ -241,9 +242,9 @@ class ManagerImpl implements Manager { @Override public void updateConfiguration( Configuration configuration - ) throws NotMasterDeviceException { - if (!account.isMasterDevice()) { - throw new NotMasterDeviceException(); + ) throws NotPrimaryDeviceException { + if (!account.isPrimaryDevice()) { + throw new NotPrimaryDeviceException(); } final var configurationStore = account.getConfigurationStore(); @@ -263,10 +264,16 @@ class ManagerImpl implements Manager { } @Override - public void setProfile( - String givenName, final String familyName, String about, String aboutEmoji, Optional avatar - ) throws IOException { - context.getProfileHelper().setProfile(givenName, familyName, about, aboutEmoji, avatar); + public void updateProfile(UpdateProfile updateProfile) throws IOException { + context.getProfileHelper() + .setProfile(updateProfile.getGivenName(), + updateProfile.getFamilyName(), + updateProfile.getAbout(), + updateProfile.getAboutEmoji(), + updateProfile.isDeleteAvatar() + ? Optional.empty() + : updateProfile.getAvatar() == null ? null : Optional.of(updateProfile.getAvatar()), + updateProfile.getMobileCoinAddress()); context.getSyncHelper().sendSyncFetchProfileMessage(); } @@ -321,9 +328,9 @@ class ManagerImpl implements Manager { } @Override - public void setRegistrationLockPin(Optional pin) throws IOException, NotMasterDeviceException { - if (!account.isMasterDevice()) { - throw new NotMasterDeviceException(); + public void setRegistrationLockPin(Optional pin) throws IOException, NotPrimaryDeviceException { + if (!account.isPrimaryDevice()) { + throw new NotPrimaryDeviceException(); } if (pin.isPresent()) { context.getAccountHelper().setRegistrationPin(pin.get()); @@ -337,7 +344,7 @@ class ManagerImpl implements Manager { } @Override - public Profile getRecipientProfile(RecipientIdentifier.Single recipient) throws IOException, UnregisteredRecipientException { + public Profile getRecipientProfile(RecipientIdentifier.Single recipient) throws UnregisteredRecipientException { return context.getProfileHelper().getRecipientProfile(context.getRecipientHelper().resolveRecipient(recipient)); } @@ -351,9 +358,7 @@ class ManagerImpl implements Manager { return null; } - return Group.from(groupInfo, - account.getRecipientStore()::resolveRecipientAddress, - account.getSelfRecipientId()); + return Group.from(groupInfo, account.getRecipientAddressResolver(), account.getSelfRecipientId()); } @Override @@ -454,9 +459,7 @@ class ManagerImpl implements Manager { } private SendMessageResult toSendMessageResult(final org.whispersystems.signalservice.api.messages.SendMessageResult result) { - return SendMessageResult.from(result, - account.getRecipientStore(), - account.getRecipientStore()::resolveRecipientAddress); + return SendMessageResult.from(result, account.getRecipientResolver(), account.getRecipientAddressResolver()); } private SendMessageResults sendTypingMessage( @@ -495,7 +498,7 @@ class ManagerImpl implements Manager { @Override public SendMessageResults sendReadReceipt( RecipientIdentifier.Single sender, List messageIds - ) throws IOException { + ) { final var timestamp = System.currentTimeMillis(); var receiptMessage = new SignalServiceReceiptMessage(SignalServiceReceiptMessage.Type.READ, messageIds, @@ -507,7 +510,7 @@ class ManagerImpl implements Manager { @Override public SendMessageResults sendViewedReceipt( RecipientIdentifier.Single sender, List messageIds - ) throws IOException { + ) { final var timestamp = System.currentTimeMillis(); var receiptMessage = new SignalServiceReceiptMessage(SignalServiceReceiptMessage.Type.VIEWED, messageIds, @@ -520,7 +523,7 @@ class ManagerImpl implements Manager { final RecipientIdentifier.Single sender, final long timestamp, final SignalServiceReceiptMessage receiptMessage - ) throws IOException { + ) { try { final var result = context.getSendHelper() .sendReceiptMessage(receiptMessage, context.getRecipientHelper().resolveRecipient(sender)); @@ -549,9 +552,8 @@ class ManagerImpl implements Manager { final SignalServiceDataMessage.Builder messageBuilder, final Message message ) throws AttachmentInvalidException, IOException, UnregisteredRecipientException, InvalidStickerException { messageBuilder.withBody(message.messageText()); - final var attachments = message.attachments(); - if (attachments != null) { - messageBuilder.withAttachments(context.getAttachmentHelper().uploadAttachments(attachments)); + if (message.attachments().size() > 0) { + messageBuilder.withAttachments(context.getAttachmentHelper().uploadAttachments(message.attachments())); } if (message.mentions().size() > 0) { messageBuilder.withMentions(resolveMentions(message.mentions())); @@ -588,11 +590,24 @@ class ManagerImpl implements Manager { stickerPack.getPackKey(), stickerId, manifestSticker.emoji(), - AttachmentUtils.createAttachment(streamDetails, Optional.empty()))); + AttachmentUtils.createAttachmentStream(streamDetails, Optional.empty()))); + } + if (message.previews().size() > 0) { + final var previews = new ArrayList(message.previews().size()); + for (final var p : message.previews()) { + final var image = p.image().isPresent() ? context.getAttachmentHelper() + .uploadAttachment(p.image().get()) : null; + previews.add(new SignalServicePreview(p.url(), + p.title(), + p.description(), + 0, + Optional.ofNullable(image))); + } + messageBuilder.withPreviews(previews); } } - private ArrayList resolveMentions(final List mentionList) throws IOException, UnregisteredRecipientException { + private ArrayList resolveMentions(final List mentionList) throws UnregisteredRecipientException { final var mentions = new ArrayList(); for (final var m : mentionList) { final var recipientId = context.getRecipientHelper().resolveRecipient(m.recipient()); @@ -640,6 +655,20 @@ class ManagerImpl implements Manager { return sendMessage(messageBuilder, recipients); } + @Override + public SendMessageResults sendPaymentNotificationMessage( + byte[] receipt, String note, RecipientIdentifier.Single recipient + ) throws IOException { + final var paymentNotification = new SignalServiceDataMessage.PaymentNotification(receipt, note); + final var payment = new SignalServiceDataMessage.Payment(paymentNotification); + final var messageBuilder = SignalServiceDataMessage.newBuilder().withPayment(payment); + try { + return sendMessage(messageBuilder, Set.of(recipient)); + } catch (NotAGroupMemberException | GroupNotFoundException | GroupSendingNotAllowedException e) { + throw new AssertionError(e); + } + } + @Override public SendMessageResults sendEndSessionMessage(Set recipients) throws IOException { var messageBuilder = SignalServiceDataMessage.newBuilder().asEndSessionMessage(); @@ -664,21 +693,21 @@ class ManagerImpl implements Manager { @Override public void deleteRecipient(final RecipientIdentifier.Single recipient) { - account.removeRecipient(account.getRecipientStore().resolveRecipient(recipient.toPartialRecipientAddress())); + account.removeRecipient(account.getRecipientResolver().resolveRecipient(recipient.toPartialRecipientAddress())); } @Override public void deleteContact(final RecipientIdentifier.Single recipient) { account.getContactStore() - .deleteContact(account.getRecipientStore().resolveRecipient(recipient.toPartialRecipientAddress())); + .deleteContact(account.getRecipientResolver().resolveRecipient(recipient.toPartialRecipientAddress())); } @Override public void setContactName( RecipientIdentifier.Single recipient, String name - ) throws NotMasterDeviceException, IOException, UnregisteredRecipientException { - if (!account.isMasterDevice()) { - throw new NotMasterDeviceException(); + ) throws NotPrimaryDeviceException, UnregisteredRecipientException { + if (!account.isPrimaryDevice()) { + throw new NotPrimaryDeviceException(); } context.getContactHelper().setContactName(context.getRecipientHelper().resolveRecipient(recipient), name); } @@ -686,9 +715,9 @@ class ManagerImpl implements Manager { @Override public void setContactsBlocked( Collection recipients, boolean blocked - ) throws NotMasterDeviceException, IOException, UnregisteredRecipientException { - if (!account.isMasterDevice()) { - throw new NotMasterDeviceException(); + ) throws NotPrimaryDeviceException, IOException, UnregisteredRecipientException { + if (!account.isPrimaryDevice()) { + throw new NotPrimaryDeviceException(); } if (recipients.size() == 0) { return; @@ -718,9 +747,9 @@ class ManagerImpl implements Manager { @Override public void setGroupsBlocked( final Collection groupIds, final boolean blocked - ) throws GroupNotFoundException, NotMasterDeviceException, IOException { - if (!account.isMasterDevice()) { - throw new NotMasterDeviceException(); + ) throws GroupNotFoundException, NotPrimaryDeviceException, IOException { + if (!account.isPrimaryDevice()) { + throw new NotPrimaryDeviceException(); } if (groupIds.size() == 0) { return; @@ -932,7 +961,7 @@ class ManagerImpl implements Manager { final RecipientId recipientId; try { recipientId = context.getRecipientHelper().resolveRecipient(recipient); - } catch (IOException | UnregisteredRecipientException e) { + } catch (UnregisteredRecipientException e) { return false; } return context.getContactHelper().isContactBlocked(recipientId); @@ -944,12 +973,22 @@ class ManagerImpl implements Manager { } @Override - public List> getContacts() { - return account.getContactStore() - .getContacts() - .stream() - .map(p -> new Pair<>(account.getRecipientStore().resolveRecipientAddress(p.first()), p.second())) - .toList(); + public List getRecipients( + boolean onlyContacts, + Optional blocked, + Collection recipients, + Optional name + ) { + final var recipientIds = recipients.stream().map(a -> { + try { + return context.getRecipientHelper().resolveRecipient(a); + } catch (UnregisteredRecipientException e) { + return null; + } + }).filter(Objects::nonNull).collect(Collectors.toSet()); + // refresh profiles of explicitly given recipients + context.getProfileHelper().refreshRecipientProfiles(recipientIds); + return account.getRecipientStore().getRecipients(onlyContacts, blocked, recipientIds, name); } @Override @@ -957,7 +996,7 @@ class ManagerImpl implements Manager { final RecipientId recipientId; try { recipientId = context.getRecipientHelper().resolveRecipient(recipient); - } catch (IOException | UnregisteredRecipientException e) { + } catch (UnregisteredRecipientException e) { return null; } @@ -989,7 +1028,8 @@ class ManagerImpl implements Manager { return null; } - final var address = account.getRecipientStore().resolveRecipientAddress(identityInfo.getRecipientId()); + final var address = account.getRecipientAddressResolver() + .resolveRecipientAddress(identityInfo.getRecipientId()); final var scannableFingerprint = context.getIdentityHelper() .computeSafetyNumberForScanning(identityInfo.getRecipientId(), identityInfo.getIdentityKey()); return new Identity(address, @@ -1007,7 +1047,7 @@ class ManagerImpl implements Manager { try { identity = account.getIdentityKeyStore() .getIdentity(context.getRecipientHelper().resolveRecipient(recipient)); - } catch (IOException | UnregisteredRecipientException e) { + } catch (UnregisteredRecipientException e) { identity = null; } return identity == null ? List.of() : List.of(toIdentity(identity)); @@ -1044,12 +1084,7 @@ class ManagerImpl implements Manager { private boolean trustIdentity( RecipientIdentifier.Single recipient, Function trustMethod ) throws UnregisteredRecipientException { - RecipientId recipientId; - try { - recipientId = context.getRecipientHelper().resolveRecipient(recipient); - } catch (IOException e) { - return false; - } + final var recipientId = context.getRecipientHelper().resolveRecipient(recipient); final var updated = trustMethod.apply(recipientId); if (updated && this.isReceiving()) { context.getReceiveHelper().setNeedsToRetryFailedMessages(true);