Always use sealed sender when sending stories.

This commit is contained in:
Greyson Parrelli
2022-10-05 16:25:33 -04:00
parent a9a64a3f60
commit 3895578d51
18 changed files with 184 additions and 122 deletions

View File

@@ -195,15 +195,11 @@ public class SignalServiceMessageReceiver {
return new SignalServiceStickerManifest(pack.getTitle(), pack.getAuthor(), cover, stickers);
}
public List<SignalServiceEnvelope> retrieveMessages() throws IOException {
return retrieveMessages(new NullMessageReceivedCallback());
}
public List<SignalServiceEnvelope> retrieveMessages(MessageReceivedCallback callback)
public List<SignalServiceEnvelope> retrieveMessages(boolean allowStories, MessageReceivedCallback callback)
throws IOException
{
List<SignalServiceEnvelope> results = new LinkedList<>();
SignalServiceMessagesResult messageResult = socket.getMessages();
SignalServiceMessagesResult messageResult = socket.getMessages(allowStories);
for (SignalServiceEnvelopeEntity entity : messageResult.getEnvelopes()) {
SignalServiceEnvelope envelope;

View File

@@ -221,7 +221,7 @@ public class SignalServiceMessageSender {
EnvelopeContent envelopeContent = EnvelopeContent.encrypted(content, ContentHint.IMPLICIT, Optional.empty());
return sendMessage(recipient, getTargetUnidentifiedAccess(unidentifiedAccess), message.getWhen(), envelopeContent, false, null, false);
return sendMessage(recipient, getTargetUnidentifiedAccess(unidentifiedAccess), message.getWhen(), envelopeContent, false, null, false, false);
}
/**
@@ -237,7 +237,7 @@ public class SignalServiceMessageSender {
PlaintextContent content = new PlaintextContent(errorMessage);
EnvelopeContent envelopeContent = EnvelopeContent.plaintext(content, groupId);
sendMessage(recipient, getTargetUnidentifiedAccess(unidentifiedAccess), System.currentTimeMillis(), envelopeContent, false, null, false);
sendMessage(recipient, getTargetUnidentifiedAccess(unidentifiedAccess), System.currentTimeMillis(), envelopeContent, false, null, false, false);
}
/**
@@ -252,7 +252,7 @@ public class SignalServiceMessageSender {
Content content = createTypingContent(message);
EnvelopeContent envelopeContent = EnvelopeContent.encrypted(content, ContentHint.IMPLICIT, Optional.empty());
sendMessage(recipients, getTargetUnidentifiedAccess(unidentifiedAccess), message.getTimestamp(), envelopeContent, true, null, cancelationSignal, false);
sendMessage(recipients, getTargetUnidentifiedAccess(unidentifiedAccess), message.getTimestamp(), envelopeContent, true, null, cancelationSignal, false, false);
}
/**
@@ -265,31 +265,12 @@ public class SignalServiceMessageSender {
throws IOException, UntrustedIdentityException, InvalidKeyException, NoSessionException, InvalidRegistrationIdException
{
Content content = createTypingContent(message);
sendGroupMessage(distributionId, recipients, unidentifiedAccess, message.getTimestamp(), content, ContentHint.IMPLICIT, message.getGroupId(), true, SenderKeyGroupEvents.EMPTY, false);
}
public List<SendMessageResult> sendStory(List<SignalServiceAddress> recipients,
List<Optional<UnidentifiedAccessPair>> unidentifiedAccess,
boolean isRecipientUpdate,
SignalServiceStoryMessage message,
long timestamp,
Set<SignalServiceStoryMessageRecipient> manifest)
throws IOException, UntrustedIdentityException
{
Content content = createStoryContent(message);
EnvelopeContent envelopeContent = EnvelopeContent.encrypted(content, ContentHint.IMPLICIT, Optional.empty());
List<SendMessageResult> sendMessageResults = sendMessage(recipients, getTargetUnidentifiedAccess(unidentifiedAccess), timestamp, envelopeContent, false, null, null, false);
if (aciStore.isMultiDevice()) {
SignalServiceSyncMessage syncMessage = createSelfSendSyncMessageForStory(message, timestamp, isRecipientUpdate, manifest);
sendSyncMessage(syncMessage, Optional.empty());
}
return sendMessageResults;
sendGroupMessage(distributionId, recipients, unidentifiedAccess, message.getTimestamp(), content, ContentHint.IMPLICIT, message.getGroupId(), true, SenderKeyGroupEvents.EMPTY, false, false);
}
/**
* Send a story using sender key.
* Send a story using sender key. Note: This is not just for group stories -- it's for any story. Just following the naming convention of making sender key
* method named "sendGroup*"
*/
public List<SendMessageResult> sendGroupStory(DistributionId distributionId,
Optional<byte[]> groupId,
@@ -302,7 +283,7 @@ public class SignalServiceMessageSender {
throws IOException, UntrustedIdentityException, InvalidKeyException, NoSessionException, InvalidRegistrationIdException
{
Content content = createStoryContent(message);
List<SendMessageResult> sendMessageResults = sendGroupMessage(distributionId, recipients, unidentifiedAccess, timestamp, content, ContentHint.IMPLICIT, groupId, false, SenderKeyGroupEvents.EMPTY, false);
List<SendMessageResult> sendMessageResults = sendGroupMessage(distributionId, recipients, unidentifiedAccess, timestamp, content, ContentHint.IMPLICIT, groupId, false, SenderKeyGroupEvents.EMPTY, false, true);
if (aciStore.isMultiDevice()) {
SignalServiceSyncMessage syncMessage = createSelfSendSyncMessageForStory(message, timestamp, isRecipientUpdate, manifest);
@@ -328,7 +309,7 @@ public class SignalServiceMessageSender {
Content content = createCallContent(message);
EnvelopeContent envelopeContent = EnvelopeContent.encrypted(content, ContentHint.DEFAULT, Optional.empty());
sendMessage(recipient, getTargetUnidentifiedAccess(unidentifiedAccess), System.currentTimeMillis(), envelopeContent, false, null, message.isUrgent());
sendMessage(recipient, getTargetUnidentifiedAccess(unidentifiedAccess), System.currentTimeMillis(), envelopeContent, false, null, message.isUrgent(), false);
}
public List<SendMessageResult> sendCallMessage(List<SignalServiceAddress> recipients,
@@ -339,7 +320,7 @@ public class SignalServiceMessageSender {
Content content = createCallContent(message);
EnvelopeContent envelopeContent = EnvelopeContent.encrypted(content, ContentHint.DEFAULT, Optional.empty());
return sendMessage(recipients, getTargetUnidentifiedAccess(unidentifiedAccess), System.currentTimeMillis(), envelopeContent, false, null, null, message.isUrgent());
return sendMessage(recipients, getTargetUnidentifiedAccess(unidentifiedAccess), System.currentTimeMillis(), envelopeContent, false, null, null, message.isUrgent(), false);
}
public List<SendMessageResult> sendCallMessage(DistributionId distributionId,
@@ -349,7 +330,7 @@ public class SignalServiceMessageSender {
throws IOException, UntrustedIdentityException, InvalidKeyException, NoSessionException, InvalidRegistrationIdException
{
Content content = createCallContent(message);
return sendGroupMessage(distributionId, recipients, unidentifiedAccess, message.getTimestamp().get(), content, ContentHint.IMPLICIT, message.getGroupId(), false, SenderKeyGroupEvents.EMPTY, message.isUrgent());
return sendGroupMessage(distributionId, recipients, unidentifiedAccess, message.getTimestamp().get(), content, ContentHint.IMPLICIT, message.getGroupId(), false, SenderKeyGroupEvents.EMPTY, message.isUrgent(), false);
}
/**
@@ -399,7 +380,7 @@ public class SignalServiceMessageSender {
sendEvents.onMessageEncrypted();
long timestamp = message.getTimestamp();
SendMessageResult result = sendMessage(recipient, getTargetUnidentifiedAccess(unidentifiedAccess), timestamp, envelopeContent, false, null, urgent);
SendMessageResult result = sendMessage(recipient, getTargetUnidentifiedAccess(unidentifiedAccess), timestamp, envelopeContent, false, null, urgent, false);
sendEvents.onMessageSent();
@@ -407,7 +388,7 @@ public class SignalServiceMessageSender {
Content syncMessage = createMultiDeviceSentTranscriptContent(content, Optional.of(recipient), timestamp, Collections.singletonList(result), false, Collections.emptySet());
EnvelopeContent syncMessageContent = EnvelopeContent.encrypted(syncMessage, ContentHint.IMPLICIT, Optional.empty());
sendMessage(localAddress, Optional.empty(), timestamp, syncMessageContent, false, null, false);
sendMessage(localAddress, Optional.empty(), timestamp, syncMessageContent, false, null, false, false);
}
sendEvents.onSyncMessageSent();
@@ -432,7 +413,8 @@ public class SignalServiceMessageSender {
List<Optional<UnidentifiedAccessPair>> unidentifiedAccess,
SenderKeyDistributionMessage message,
Optional<byte[]> groupId,
boolean urgent)
boolean urgent,
boolean story)
throws IOException
{
ByteString distributionBytes = ByteString.copyFrom(message.serialize());
@@ -441,7 +423,7 @@ public class SignalServiceMessageSender {
long timestamp = System.currentTimeMillis();
Log.d(TAG, "[" + timestamp + "] Sending SKDM to " + recipients.size() + " recipients for DistributionId " + distributionId);
return sendMessage(recipients, getTargetUnidentifiedAccess(unidentifiedAccess), timestamp, envelopeContent, false, null, null, urgent);
return sendMessage(recipients, getTargetUnidentifiedAccess(unidentifiedAccess), timestamp, envelopeContent, false, null, null, urgent, story);
}
/**
@@ -466,7 +448,7 @@ public class SignalServiceMessageSender {
EnvelopeContent envelopeContent = EnvelopeContent.encrypted(content, contentHint, groupId);
Optional<UnidentifiedAccess> access = unidentifiedAccess.isPresent() ? unidentifiedAccess.get().getTargetUnidentifiedAccess() : Optional.empty();
return sendMessage(address, access, timestamp, envelopeContent, false, null, urgent);
return sendMessage(address, access, timestamp, envelopeContent, false, null, urgent, false);
}
/**
@@ -486,7 +468,7 @@ public class SignalServiceMessageSender {
Content content = createMessageContent(message);
Optional<byte[]> groupId = message.getGroupId();
List<SendMessageResult> results = sendGroupMessage(distributionId, recipients, unidentifiedAccess, message.getTimestamp(), content, contentHint, groupId, false, sendEvents, urgent);
List<SendMessageResult> results = sendGroupMessage(distributionId, recipients, unidentifiedAccess, message.getTimestamp(), content, contentHint, groupId, false, sendEvents, urgent, false);
sendEvents.onMessageSent();
@@ -494,7 +476,7 @@ public class SignalServiceMessageSender {
Content syncMessage = createMultiDeviceSentTranscriptContent(content, Optional.empty(), message.getTimestamp(), results, isRecipientUpdate, Collections.emptySet());
EnvelopeContent syncMessageContent = EnvelopeContent.encrypted(syncMessage, ContentHint.IMPLICIT, Optional.empty());
sendMessage(localAddress, Optional.empty(), message.getTimestamp(), syncMessageContent, false, null, false);
sendMessage(localAddress, Optional.empty(), message.getTimestamp(), syncMessageContent, false, null, false, false);
}
sendEvents.onSyncMessageSent();
@@ -524,7 +506,7 @@ public class SignalServiceMessageSender {
Content content = createMessageContent(message);
EnvelopeContent envelopeContent = EnvelopeContent.encrypted(content, contentHint, message.getGroupId());
long timestamp = message.getTimestamp();
List<SendMessageResult> results = sendMessage(recipients, getTargetUnidentifiedAccess(unidentifiedAccess), timestamp, envelopeContent, false, partialListener, cancelationSignal, urgent);
List<SendMessageResult> results = sendMessage(recipients, getTargetUnidentifiedAccess(unidentifiedAccess), timestamp, envelopeContent, false, partialListener, cancelationSignal, urgent, false);
boolean needsSyncInResults = false;
sendEvents.onMessageSent();
@@ -545,7 +527,7 @@ public class SignalServiceMessageSender {
Content syncMessage = createMultiDeviceSentTranscriptContent(content, recipient, timestamp, results, isRecipientUpdate, Collections.emptySet());
EnvelopeContent syncMessageContent = EnvelopeContent.encrypted(syncMessage, ContentHint.IMPLICIT, Optional.empty());
sendMessage(localAddress, Optional.empty(), timestamp, syncMessageContent, false, null, false);
sendMessage(localAddress, Optional.empty(), timestamp, syncMessageContent, false, null, false, false);
}
sendEvents.onSyncMessageSent();
@@ -608,7 +590,7 @@ public class SignalServiceMessageSender {
EnvelopeContent envelopeContent = EnvelopeContent.encrypted(content, ContentHint.IMPLICIT, Optional.empty());
return sendMessage(localAddress, Optional.empty(), timestamp, envelopeContent, false, null, urgent);
return sendMessage(localAddress, Optional.empty(), timestamp, envelopeContent, false, null, urgent, false);
}
/**
@@ -626,11 +608,7 @@ public class SignalServiceMessageSender {
Content.Builder content = Content.newBuilder().setSyncMessage(syncMessage);
EnvelopeContent envelopeContent = EnvelopeContent.encrypted(content.build(), ContentHint.IMPLICIT, Optional.empty());
return getEncryptedMessage(socket, localAddress, Optional.empty(), deviceId, envelopeContent);
}
public void setSoTimeoutMillis(long soTimeoutMillis) {
socket.setSoTimeoutMillis(soTimeoutMillis);
return getEncryptedMessage(localAddress, Optional.empty(), deviceId, envelopeContent, false);
}
public void cancelInFlightRequests() {
@@ -763,13 +741,13 @@ public class SignalServiceMessageSender {
EnvelopeContent envelopeContent = EnvelopeContent.encrypted(content, ContentHint.IMPLICIT, Optional.empty());
SendMessageResult result = sendMessage(message.getDestination(), Optional.empty(), message.getTimestamp(), envelopeContent, false, null, false);
SendMessageResult result = sendMessage(message.getDestination(), Optional.empty(), message.getTimestamp(), envelopeContent, false, null, false, false);
if (result.getSuccess().isNeedsSync()) {
Content syncMessage = createMultiDeviceVerifiedContent(message, nullMessage.toByteArray());
EnvelopeContent syncMessageContent = EnvelopeContent.encrypted(syncMessage, ContentHint.IMPLICIT, Optional.empty());
sendMessage(localAddress, Optional.empty(), message.getTimestamp(), syncMessageContent, false, null, false);
sendMessage(localAddress, Optional.empty(), message.getTimestamp(), syncMessageContent, false, null, false, false);
}
return result;
@@ -793,7 +771,7 @@ public class SignalServiceMessageSender {
EnvelopeContent envelopeContent = EnvelopeContent.encrypted(content, ContentHint.IMPLICIT, Optional.empty());
return sendMessage(address, getTargetUnidentifiedAccess(unidentifiedAccess), System.currentTimeMillis(), envelopeContent, false, null, false);
return sendMessage(address, getTargetUnidentifiedAccess(unidentifiedAccess), System.currentTimeMillis(), envelopeContent, false, null, false, false);
}
private SignalServiceProtos.PniSignatureMessage createPniSignatureMessage() {
@@ -1678,7 +1656,8 @@ public class SignalServiceMessageSender {
boolean online,
PartialSendCompleteListener partialListener,
CancelationSignal cancelationSignal,
boolean urgent)
boolean urgent,
boolean story)
throws IOException
{
Log.d(TAG, "[" + timestamp + "] Sending to " + recipients.size() + " recipients.");
@@ -1693,7 +1672,7 @@ public class SignalServiceMessageSender {
SignalServiceAddress recipient = recipientIterator.next();
Optional<UnidentifiedAccess> access = unidentifiedAccessIterator.next();
futureResults.add(executor.submit(() -> {
SendMessageResult result = sendMessage(recipient, access, timestamp, content, online, cancelationSignal, urgent);
SendMessageResult result = sendMessage(recipient, access, timestamp, content, online, cancelationSignal, urgent, story);
if (partialListener != null) {
partialListener.onPartialSendComplete(result);
}
@@ -1761,7 +1740,8 @@ public class SignalServiceMessageSender {
EnvelopeContent content,
boolean online,
CancelationSignal cancelationSignal,
boolean urgent)
boolean urgent,
boolean story)
throws UntrustedIdentityException, IOException
{
enforceMaxContentSize(content);
@@ -1774,7 +1754,7 @@ public class SignalServiceMessageSender {
}
try {
OutgoingPushMessageList messages = getEncryptedMessages(socket, recipient, unidentifiedAccess, timestamp, content, online, urgent);
OutgoingPushMessageList messages = getEncryptedMessages(recipient, unidentifiedAccess, timestamp, content, online, urgent, story);
if (content.getContent().isPresent() && content.getContent().get().getSyncMessage() != null && content.getContent().get().getSyncMessage().hasSent()) {
Log.d(TAG, "[sendMessage][" + timestamp + "] Sending a sent sync message to devices: " + messages.getDevices());
@@ -1788,7 +1768,7 @@ public class SignalServiceMessageSender {
if (!unidentifiedAccess.isPresent()) {
try {
SendMessageResponse response = new MessagingService.SendResponseProcessor<>(messagingService.send(messages, Optional.empty()).blockingGet()).getResultOrThrow();
SendMessageResponse response = new MessagingService.SendResponseProcessor<>(messagingService.send(messages, Optional.empty(), story).blockingGet()).getResultOrThrow();
return SendMessageResult.success(recipient, messages.getDevices(), response.sentUnidentified(), response.getNeedsSync() || aciStore.isMultiDevice(), System.currentTimeMillis() - startTime, content.getContent());
} catch (InvalidUnidentifiedAccessHeaderException | UnregisteredUserException | MismatchedDevicesException | StaleDevicesException e) {
// Non-technical failures shouldn't be retried with socket
@@ -1801,7 +1781,7 @@ public class SignalServiceMessageSender {
}
} else if (unidentifiedAccess.isPresent()) {
try {
SendMessageResponse response = new MessagingService.SendResponseProcessor<>(messagingService.send(messages, unidentifiedAccess).blockingGet()).getResultOrThrow();
SendMessageResponse response = new MessagingService.SendResponseProcessor<>(messagingService.send(messages, unidentifiedAccess, story).blockingGet()).getResultOrThrow();
return SendMessageResult.success(recipient, messages.getDevices(), response.sentUnidentified(), response.getNeedsSync() || aciStore.isMultiDevice(), System.currentTimeMillis() - startTime, content.getContent());
} catch (InvalidUnidentifiedAccessHeaderException | UnregisteredUserException | MismatchedDevicesException | StaleDevicesException e) {
// Non-technical failures shouldn't be retried with socket
@@ -1821,7 +1801,7 @@ public class SignalServiceMessageSender {
throw new CancelationException();
}
SendMessageResponse response = socket.sendMessage(messages, unidentifiedAccess);
SendMessageResponse response = socket.sendMessage(messages, unidentifiedAccess, story);
return SendMessageResult.success(recipient, messages.getDevices(), response.sentUnidentified(), response.getNeedsSync() || aciStore.isMultiDevice(), System.currentTimeMillis() - startTime, content.getContent());
@@ -1863,7 +1843,8 @@ public class SignalServiceMessageSender {
Optional<byte[]> groupId,
boolean online,
SenderKeyGroupEvents sendEvents,
boolean urgent)
boolean urgent,
boolean story)
throws IOException, UntrustedIdentityException, NoSessionException, InvalidKeyException, InvalidRegistrationIdException
{
if (recipients.isEmpty()) {
@@ -1900,7 +1881,7 @@ public class SignalServiceMessageSender {
})
.collect(Collectors.toList());
List<SendMessageResult> results = sendSenderKeyDistributionMessage(distributionId, needsSenderKey, access, message, groupId, urgent);
List<SendMessageResult> results = sendSenderKeyDistributionMessage(distributionId, needsSenderKey, access, message, groupId, urgent, story);
List<SignalServiceAddress> successes = results.stream()
.filter(SendMessageResult::isSuccess)
@@ -1962,7 +1943,7 @@ public class SignalServiceMessageSender {
try {
try {
SendGroupMessageResponse response = new MessagingService.SendResponseProcessor<>(messagingService.sendToGroup(ciphertext, joinedUnidentifiedAccess, timestamp, online, urgent).blockingGet()).getResultOrThrow();
SendGroupMessageResponse response = new MessagingService.SendResponseProcessor<>(messagingService.sendToGroup(ciphertext, joinedUnidentifiedAccess, timestamp, online, urgent, story).blockingGet()).getResultOrThrow();
return transformGroupResponseToMessageResults(targetInfo.devices, response, content);
} catch (InvalidUnidentifiedAccessHeaderException | NotFoundException | GroupMismatchedDevicesException | GroupStaleDevicesException e) {
// Non-technical failures shouldn't be retried with socket
@@ -1973,7 +1954,7 @@ public class SignalServiceMessageSender {
Log.w(TAG, "[sendGroupMessage][" + timestamp + "] Pipe failed, falling back... (" + e.getClass().getSimpleName() + ": " + e.getMessage() + ")");
}
SendGroupMessageResponse response = socket.sendGroupMessage(ciphertext, joinedUnidentifiedAccess, timestamp, online, urgent);
SendGroupMessageResponse response = socket.sendGroupMessage(ciphertext, joinedUnidentifiedAccess, timestamp, online, urgent, true);
return transformGroupResponseToMessageResults(targetInfo.devices, response, content);
} catch (GroupMismatchedDevicesException e) {
Log.w(TAG, "[sendGroupMessage][" + timestamp + "] Handling mismatched devices. (" + e.getMessage() + ")");
@@ -2138,13 +2119,13 @@ public class SignalServiceMessageSender {
return builder.build();
}
private OutgoingPushMessageList getEncryptedMessages(PushServiceSocket socket,
SignalServiceAddress recipient,
private OutgoingPushMessageList getEncryptedMessages(SignalServiceAddress recipient,
Optional<UnidentifiedAccess> unidentifiedAccess,
long timestamp,
EnvelopeContent plaintext,
boolean online,
boolean urgent)
boolean urgent,
boolean story)
throws IOException, InvalidKeyException, UntrustedIdentityException
{
List<OutgoingPushMessage> messages = new LinkedList<>();
@@ -2161,18 +2142,18 @@ public class SignalServiceMessageSender {
for (int deviceId : deviceIds) {
if (deviceId == SignalServiceAddress.DEFAULT_DEVICE_ID || aciStore.containsSession(new SignalProtocolAddress(recipient.getIdentifier(), deviceId))) {
messages.add(getEncryptedMessage(socket, recipient, unidentifiedAccess, deviceId, plaintext));
messages.add(getEncryptedMessage(recipient, unidentifiedAccess, deviceId, plaintext, story));
}
}
return new OutgoingPushMessageList(recipient.getIdentifier(), timestamp, messages, online, urgent);
}
private OutgoingPushMessage getEncryptedMessage(PushServiceSocket socket,
SignalServiceAddress recipient,
private OutgoingPushMessage getEncryptedMessage(SignalServiceAddress recipient,
Optional<UnidentifiedAccess> unidentifiedAccess,
int deviceId,
EnvelopeContent plaintext)
EnvelopeContent plaintext,
boolean story)
throws IOException, InvalidKeyException, UntrustedIdentityException
{
SignalProtocolAddress signalProtocolAddress = new SignalProtocolAddress(recipient.getIdentifier(), deviceId);
@@ -2180,7 +2161,7 @@ public class SignalServiceMessageSender {
if (!aciStore.containsSession(signalProtocolAddress)) {
try {
List<PreKeyBundle> preKeys = socket.getPreKeys(recipient, unidentifiedAccess, deviceId);
List<PreKeyBundle> preKeys = getPreKeys(recipient, unidentifiedAccess, deviceId, story);
for (PreKeyBundle preKey : preKeys) {
try {
@@ -2207,6 +2188,19 @@ public class SignalServiceMessageSender {
}
}
private List<PreKeyBundle> getPreKeys(SignalServiceAddress recipient, Optional<UnidentifiedAccess> unidentifiedAccess, int deviceId, boolean story) throws IOException {
try {
return socket.getPreKeys(recipient, unidentifiedAccess, deviceId);
} catch (NonSuccessfulResponseCodeException e) {
if (e.getCode() == 401 && story) {
return socket.getPreKeys(recipient, Optional.empty(), deviceId);
} else {
throw e;
}
}
}
private void handleMismatchedDevices(PushServiceSocket socket, SignalServiceAddress recipient,
MismatchedDevices mismatchedDevices)
throws IOException, UntrustedIdentityException

View File

@@ -43,7 +43,7 @@ public class MessagingService {
this.signalWebSocket = signalWebSocket;
}
public Single<ServiceResponse<SendMessageResponse>> send(OutgoingPushMessageList list, Optional<UnidentifiedAccess> unidentifiedAccess) {
public Single<ServiceResponse<SendMessageResponse>> send(OutgoingPushMessageList list, Optional<UnidentifiedAccess> unidentifiedAccess, boolean story) {
List<String> headers = new LinkedList<String>() {{
add("content-type:application/json");
}};
@@ -51,7 +51,7 @@ public class MessagingService {
WebSocketRequestMessage requestMessage = WebSocketRequestMessage.newBuilder()
.setId(new SecureRandom().nextLong())
.setVerb("PUT")
.setPath(String.format("/v1/messages/%s", list.getDestination()))
.setPath(String.format("/v1/messages/%s?story=%s", list.getDestination(), story ? "true" : "false"))
.addAllHeaders(headers)
.setBody(ByteString.copyFrom(JsonUtil.toJson(list).getBytes()))
.build();
@@ -72,13 +72,13 @@ public class MessagingService {
.onErrorReturn(ServiceResponse::forUnknownError);
}
public Single<ServiceResponse<SendGroupMessageResponse>> sendToGroup(byte[] body, byte[] joinedUnidentifiedAccess, long timestamp, boolean online, boolean urgent) {
public Single<ServiceResponse<SendGroupMessageResponse>> sendToGroup(byte[] body, byte[] joinedUnidentifiedAccess, long timestamp, boolean online, boolean urgent, boolean story) {
List<String> headers = new LinkedList<String>() {{
add("content-type:application/vnd.signal-messenger.mrm");
add("Unidentified-Access-Key:" + Base64.encodeBytes(joinedUnidentifiedAccess));
}};
String path = String.format(Locale.US, "/v1/messages/multi_recipient?ts=%s&online=%s&urgent=%s", timestamp, online, urgent);
String path = String.format(Locale.US, "/v1/messages/multi_recipient?ts=%s&online=%s&urgent=%s&story=%s", timestamp, online, urgent, story);
WebSocketRequestMessage requestMessage = WebSocketRequestMessage.newBuilder()
.setId(new SecureRandom().nextLong())

View File

@@ -220,8 +220,8 @@ public class PushServiceSocket {
private static final String DEVICE_PATH = "/v1/devices/%s";
private static final String DIRECTORY_AUTH_PATH = "/v1/directory/auth";
private static final String MESSAGE_PATH = "/v1/messages/%s";
private static final String GROUP_MESSAGE_PATH = "/v1/messages/multi_recipient?ts=%s&online=%s&urgent=%s";
private static final String MESSAGE_PATH = "/v1/messages/%s?story=%s";
private static final String GROUP_MESSAGE_PATH = "/v1/messages/multi_recipient?ts=%s&online=%s&urgent=%s&story=%s";
private static final String SENDER_ACK_MESSAGE_PATH = "/v1/messages/%s/%d";
private static final String UUID_ACK_MESSAGE_PATH = "/v1/messages/uuid/%s";
private static final String ATTACHMENT_V2_PATH = "/v2/attachments/form/upload";
@@ -486,12 +486,12 @@ public class PushServiceSocket {
return JsonUtil.fromJson(responseText, SenderCertificate.class).getCertificate();
}
public SendGroupMessageResponse sendGroupMessage(byte[] body, byte[] joinedUnidentifiedAccess, long timestamp, boolean online, boolean urgent)
public SendGroupMessageResponse sendGroupMessage(byte[] body, byte[] joinedUnidentifiedAccess, long timestamp, boolean online, boolean urgent, boolean story)
throws IOException
{
ServiceConnectionHolder connectionHolder = (ServiceConnectionHolder) getRandom(serviceClients, random);
String path = String.format(Locale.US, GROUP_MESSAGE_PATH, timestamp, online, urgent);
String path = String.format(Locale.US, GROUP_MESSAGE_PATH, timestamp, online, urgent, story);
Request.Builder requestBuilder = new Request.Builder();
requestBuilder.url(String.format("%s%s", connectionHolder.getUrl(), path));
@@ -544,11 +544,11 @@ public class PushServiceSocket {
}
}
public SendMessageResponse sendMessage(OutgoingPushMessageList bundle, Optional<UnidentifiedAccess> unidentifiedAccess)
public SendMessageResponse sendMessage(OutgoingPushMessageList bundle, Optional<UnidentifiedAccess> unidentifiedAccess, boolean story)
throws IOException
{
try {
String responseText = makeServiceRequest(String.format(MESSAGE_PATH, bundle.getDestination()), "PUT", JsonUtil.toJson(bundle), NO_HEADERS, unidentifiedAccess);
String responseText = makeServiceRequest(String.format(MESSAGE_PATH, bundle.getDestination(), story ? "true" : "false"), "PUT", JsonUtil.toJson(bundle), NO_HEADERS, unidentifiedAccess);
SendMessageResponse response = JsonUtil.fromJson(responseText, SendMessageResponse.class);
response.setSentUnidentfied(unidentifiedAccess.isPresent());
@@ -559,8 +559,10 @@ public class PushServiceSocket {
}
}
public SignalServiceMessagesResult getMessages() throws IOException {
try (Response response = makeServiceRequest(String.format(MESSAGE_PATH, ""), "GET", (RequestBody) null, NO_HEADERS, NO_HANDLER, Optional.empty())) {
public SignalServiceMessagesResult getMessages(boolean allowStories) throws IOException {
Map<String, String> headers = Collections.singletonMap("X-Signal-Receive-Stories", allowStories ? "true" : "false");
try (Response response = makeServiceRequest(String.format(MESSAGE_PATH, ""), "GET", (RequestBody) null, headers, NO_HANDLER, Optional.empty())) {
validateServiceResponse(response);
List<SignalServiceEnvelopeEntity> envelopes = readBodyJson(response.body(), SignalServiceEnvelopeEntityList.class).getMessages();

View File

@@ -18,9 +18,10 @@ public class SendGroupMessageResponse {
public SendGroupMessageResponse() {}
public Set<ServiceId> getUnsentTargets() {
Set<ServiceId> serviceIds = new HashSet<>(uuids404.length);
String[] uuids = uuids404 != null ? uuids404 : new String[0];
Set<ServiceId> serviceIds = new HashSet<>(uuids.length);
for (String raw : uuids404) {
for (String raw : uuids) {
ServiceId parsed = ServiceId.parseOrNull(raw);
if (parsed != null) {
serviceIds.add(parsed);

View File

@@ -66,14 +66,15 @@ public class WebSocketConnection extends WebSocketListener {
private final String name;
private final String wsUri;
private final TrustStore trustStore;
private final Optional<CredentialsProvider> credentialsProvider;
private final String signalAgent;
private final TrustStore trustStore;
private final Optional<CredentialsProvider> credentialsProvider;
private final String signalAgent;
private final HealthMonitor healthMonitor;
private final List<Interceptor> interceptors;
private final Optional<Dns> dns;
private final Optional<SignalProxy> signalProxy;
private final BehaviorSubject<WebSocketConnectionState> webSocketState;
private final boolean allowStories;
private WebSocket client;
@@ -81,8 +82,9 @@ public class WebSocketConnection extends WebSocketListener {
SignalServiceConfiguration serviceConfiguration,
Optional<CredentialsProvider> credentialsProvider,
String signalAgent,
HealthMonitor healthMonitor) {
this(name, serviceConfiguration, credentialsProvider, signalAgent, healthMonitor, "");
HealthMonitor healthMonitor,
boolean allowStories) {
this(name, serviceConfiguration, credentialsProvider, signalAgent, healthMonitor, "", allowStories);
}
public WebSocketConnection(String name,
@@ -90,7 +92,8 @@ public class WebSocketConnection extends WebSocketListener {
Optional<CredentialsProvider> credentialsProvider,
String signalAgent,
HealthMonitor healthMonitor,
String extraPathUri)
String extraPathUri,
boolean allowStories)
{
this.name = "[" + name + ":" + System.identityHashCode(this) + "]";
this.trustStore = serviceConfiguration.getSignalServiceUrls()[0].getTrustStore();
@@ -101,6 +104,7 @@ public class WebSocketConnection extends WebSocketListener {
this.signalProxy = serviceConfiguration.getSignalProxy();
this.healthMonitor = healthMonitor;
this.webSocketState = BehaviorSubject.createDefault(WebSocketConnectionState.DISCONNECTED);
this.allowStories = allowStories;
String uri = serviceConfiguration.getSignalServiceUrls()[0].getUrl().replace("https://", "wss://").replace("http://", "ws://");
@@ -156,6 +160,8 @@ public class WebSocketConnection extends WebSocketListener {
requestBuilder.addHeader("X-Signal-Agent", signalAgent);
}
requestBuilder.addHeader("X-Signal-Receive-Stories", allowStories ? "true" : "false");
webSocketState.onNext(WebSocketConnectionState.CONNECTING);
this.client = okHttpClient.newWebSocket(requestBuilder.build(), this);