diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java index 170a140d..5ea52e4c 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java @@ -368,7 +368,8 @@ public class SendHelper { timestamp, storyMessageRecipients, null); - } catch (UntrustedIdentityException | InvalidKeyException | NoSessionException | InvalidRegistrationIdException e) { + } catch (UntrustedIdentityException | InvalidKeyException | NoSessionException | + InvalidRegistrationIdException e) { throw new IOException(e); } @@ -391,84 +392,29 @@ public class SendHelper { final var messageSender = dependencies.getMessageSender(); final var allRecipientIds = groupInfo.getMembersWithout(account.getSelfRecipientId()); - final var skippedResults = new ArrayList(); - final var unregisteredRecipientIds = account.getRecipientStore().getUnregisteredRecipientIds(allRecipientIds); - final Set recipientIds; - if (unregisteredRecipientIds.isEmpty()) { - recipientIds = allRecipientIds; - } else { - logger.debug("Skipping {} known-unregistered recipient(s) in group story send.", - unregisteredRecipientIds.size()); - recipientIds = new HashSet<>(allRecipientIds); - recipientIds.removeAll(unregisteredRecipientIds); - for (final var recipientId : unregisteredRecipientIds) { - skippedResults.add(SendMessageResult.unregisteredFailure(context.getRecipientHelper() - .resolveSignalServiceAddress(recipientId))); - } - } - final var recipientIdList = List.copyOf(recipientIds); - final var addressesMap = recipientIdList.stream() - .collect(Collectors.toMap(id -> id, context.getRecipientHelper()::resolveSignalServiceAddress)); - final var unidentifiedAccessesMap = context.getUnidentifiedAccessHelper().getAccessFor(recipientIds); - - final var groupSendEndorsementsResult = getGroupSendEndorsements(groupInfo); - if (groupSendEndorsementsResult == null) { - throw new IOException("Group send endorsements unavailable; try again after group state refreshes"); - } - final var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupInfo.getMasterKey()); - final var senderCertificate = context.getUnidentifiedAccessHelper().getSenderCertificateFor(null); - final var endorsementMap = groupSendEndorsementsResult.second(); - final var eligibleRecipientIds = recipientIdList.stream() - .filter(id -> addressesMap.get(id).getServiceId() instanceof ACI) - .filter(id -> endorsementMap.containsKey(id) && endorsementMap.get(id) != null) - .toList(); - if (eligibleRecipientIds.size() < recipientIdList.size()) { - logger.debug("Filtered {}/{} recipients for group story (missing ACI or endorsement)", - recipientIdList.size() - eligibleRecipientIds.size(), - recipientIdList.size()); - } - if (eligibleRecipientIds.isEmpty()) { - throw new IOException("No group members eligible for story delivery (missing endorsements or ACI)"); - } - final var groupSendEndorsements = new GroupSendEndorsements(groupSendEndorsementsResult.first(), - eligibleRecipientIds.stream() - .collect(Collectors.toMap(id -> (ACI) addressesMap.get(id).getServiceId(), - endorsementMap::get)), - senderCertificate, - groupSecretParams); - - final var addresses = eligibleRecipientIds.stream().map(addressesMap::get).toList(); - final var unidentifiedAccesses = eligibleRecipientIds.stream().map(unidentifiedAccessesMap::get).toList(); - final var storyMessageRecipients = eligibleRecipientIds.stream() - .map(id -> new SignalServiceStoryMessageRecipient(addressesMap.get(id), - List.of(groupInfo.getDistributionId().asUuid().toString()), - allowsReplies)) - .collect(Collectors.toSet()); - - final List results; - try { - results = messageSender.sendGroupStory(groupInfo.getDistributionId(), - Optional.of(groupInfo.getMasterKey().serialize()), - addresses, - unidentifiedAccesses, - groupSendEndorsements, - false, - storyMessage, - timestamp, - storyMessageRecipients, - null); - } catch (UntrustedIdentityException | InvalidKeyException | NoSessionException | InvalidRegistrationIdException e) { - throw new IOException(e); - } + final SenderKeySenderHandler senderKeySender = (distId, recipients, unidentifiedAccess, groupSendEndorsements, isRecipientUpdate) -> messageSender.sendGroupStory( + distId, + Optional.of(groupInfo.getMasterKey().serialize()), + recipients, + unidentifiedAccess, + groupSendEndorsements, + isRecipientUpdate, + storyMessage, + timestamp, + recipients.stream() + .map(address -> new SignalServiceStoryMessageRecipient(address, + List.of(groupInfo.getDistributionId().asUuid().toString()), + allowsReplies)) + .collect(Collectors.toSet()), + null); + final var results = sendGroupMessageInternal(null, senderKeySender, allRecipientIds, groupInfo, false); for (var r : results) { handleSendMessageResult(r); } - final var allResults = new ArrayList<>(results); - allResults.addAll(skippedResults); - return allResults; + return results; } private List sendAsGroupMessage( @@ -738,7 +684,7 @@ public class SendHelper { legacyTargets.removeAll(senderKeyTargets); final boolean onlyTargetIsSelfWithLinkedDevice = targetRecipientIds.isEmpty() && account.isMultiDevice(); - if (!legacyTargets.isEmpty() || onlyTargetIsSelfWithLinkedDevice) { + if (legacySender != null && (!legacyTargets.isEmpty() || onlyTargetIsSelfWithLinkedDevice)) { if (!legacyTargets.isEmpty()) { logger.debug("Need to do {} legacy sends.", legacyTargets.size()); } else { diff --git a/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java b/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java index 24040d78..a067ecca 100644 --- a/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java @@ -113,7 +113,6 @@ import org.whispersystems.signalservice.api.messages.SignalServiceGroupV2; import org.whispersystems.signalservice.api.messages.SignalServicePreview; import org.whispersystems.signalservice.api.messages.SignalServiceReceiptMessage; import org.whispersystems.signalservice.api.messages.SignalServiceStoryMessage; -import org.whispersystems.signalservice.api.messages.SignalServiceStoryMessageRecipient; import org.whispersystems.signalservice.api.messages.SignalServiceTypingMessage; import org.whispersystems.signalservice.api.messages.calls.AnswerMessage; import org.whispersystems.signalservice.api.messages.calls.BusyMessage; @@ -909,10 +908,6 @@ public class ManagerImpl implements Manager { throw new IOException("Stories are only supported for V2 groups"); } - if (groupInfoV2.getMembersWithout(account.getSelfRecipientId()).isEmpty()) { - throw new IOException("No other members in group for story delivery"); - } - final var uploadedAttachment = context.getAttachmentHelper().uploadAttachment(attachment); final var groupContext = SignalServiceGroupV2.newBuilder(groupInfoV2.getMasterKey()) .withRevision(groupInfoV2.getGroup() == null ? 0 : groupInfoV2.getGroup().revision) @@ -927,18 +922,6 @@ public class ManagerImpl implements Manager { final var sendResults = context.getSendHelper() .sendGroupStoryMessage(storyMessage, timestamp, groupInfoV2, allowsReplies); - final var storyMessageRecipients = sendResults.stream() - .filter(org.whispersystems.signalservice.api.messages.SendMessageResult::isSuccess) - .map(r -> new SignalServiceStoryMessageRecipient(r.getAddress(), - List.of(groupInfoV2.getDistributionId().asUuid().toString()), - allowsReplies)) - .collect(Collectors.toSet()); - try { - dependencies.getMessageSender().sendStorySyncMessage(storyMessage, timestamp, false, storyMessageRecipients); - } catch (UntrustedIdentityException | NoSessionException e) { - throw new IOException(e); - } - final var results = new HashMap>(); for (final var sendResult : sendResults) { final var result = toSendMessageResult(sendResult);