mirror of
https://github.com/oxen-io/session-android.git
synced 2025-05-04 21:00:51 +00:00
Handle SessionRequest messages.
This commit is contained in:
parent
538cd39d00
commit
93a9f4c1dc
@ -497,7 +497,7 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
|||||||
for (Recipient recipient : recipients) {
|
for (Recipient recipient : recipients) {
|
||||||
boolean isPush = isActiveInDirectory(recipient);
|
boolean isPush = isActiveInDirectory(recipient);
|
||||||
|
|
||||||
if (failIfNotPush && !isPush) {
|
if (failIfNotPush && !isPush && !recipient.getAddress().isPhone()) {
|
||||||
results.add(new Result(null, false, activity.getString(R.string.GroupCreateActivity_cannot_add_non_push_to_existing_group,
|
results.add(new Result(null, false, activity.getString(R.string.GroupCreateActivity_cannot_add_non_push_to_existing_group,
|
||||||
recipient.toShortString())));
|
recipient.toShortString())));
|
||||||
} else if (TextUtils.equals(TextSecurePreferences.getLocalNumber(activity), recipient.getAddress().serialize())) {
|
} else if (TextUtils.equals(TextSecurePreferences.getLocalNumber(activity), recipient.getAddress().serialize())) {
|
||||||
|
@ -8,6 +8,7 @@ import android.support.annotation.Nullable;
|
|||||||
import com.google.protobuf.ByteString;
|
import com.google.protobuf.ByteString;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.ApplicationContext;
|
import org.thoughtcrime.securesms.ApplicationContext;
|
||||||
|
import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore;
|
||||||
import org.thoughtcrime.securesms.database.Address;
|
import org.thoughtcrime.securesms.database.Address;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||||
@ -23,15 +24,18 @@ import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
|||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.sms.IncomingGroupMessage;
|
import org.thoughtcrime.securesms.sms.IncomingGroupMessage;
|
||||||
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
|
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
|
||||||
|
import org.thoughtcrime.securesms.sms.MessageSender;
|
||||||
import org.thoughtcrime.securesms.util.Base64;
|
import org.thoughtcrime.securesms.util.Base64;
|
||||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
|
import org.whispersystems.libsignal.SignalProtocolAddress;
|
||||||
import org.whispersystems.libsignal.util.guava.Optional;
|
import org.whispersystems.libsignal.util.guava.Optional;
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceContent;
|
import org.whispersystems.signalservice.api.messages.SignalServiceContent;
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceGroup;
|
import org.whispersystems.signalservice.api.messages.SignalServiceGroup;
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceGroup.Type;
|
import org.whispersystems.signalservice.api.messages.SignalServiceGroup.Type;
|
||||||
|
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||||
import org.whispersystems.signalservice.loki.api.LokiStorageAPI;
|
import org.whispersystems.signalservice.loki.api.LokiStorageAPI;
|
||||||
import org.whispersystems.signalservice.loki.utilities.PromiseUtil;
|
import org.whispersystems.signalservice.loki.utilities.PromiseUtil;
|
||||||
|
|
||||||
@ -41,6 +45,8 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import kotlin.Unit;
|
||||||
|
|
||||||
import static org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
import static org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
||||||
import static org.whispersystems.signalservice.internal.push.SignalServiceProtos.AttachmentPointer;
|
import static org.whispersystems.signalservice.internal.push.SignalServiceProtos.AttachmentPointer;
|
||||||
import static org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext;
|
import static org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext;
|
||||||
@ -114,6 +120,10 @@ public class GroupMessageProcessor {
|
|||||||
database.create(id, group.getName().orNull(), members,
|
database.create(id, group.getName().orNull(), members,
|
||||||
avatar != null && avatar.isPointer() ? avatar.asPointer() : null, null, admins);
|
avatar != null && avatar.isPointer() ? avatar.asPointer() : null, null, admins);
|
||||||
|
|
||||||
|
if (group.getMembers().isPresent()) {
|
||||||
|
establishSessionsWithMembersIfNeeded(context, group.getMembers().get());
|
||||||
|
}
|
||||||
|
|
||||||
return storeMessage(context, content, group, builder.build(), outgoing);
|
return storeMessage(context, content, group, builder.build(), outgoing);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,6 +193,10 @@ public class GroupMessageProcessor {
|
|||||||
|
|
||||||
if (!groupRecord.isActive()) database.setActive(id, true);
|
if (!groupRecord.isActive()) database.setActive(id, true);
|
||||||
|
|
||||||
|
if (group.getMembers().isPresent()) {
|
||||||
|
establishSessionsWithMembersIfNeeded(context, group.getMembers().get());
|
||||||
|
}
|
||||||
|
|
||||||
return storeMessage(context, content, group, builder.build(), outgoing);
|
return storeMessage(context, content, group, builder.build(), outgoing);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,4 +323,20 @@ public class GroupMessageProcessor {
|
|||||||
return hexEncodedPublicKey;
|
return hexEncodedPublicKey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void establishSessionsWithMembersIfNeeded(Context context, List<String> members) {
|
||||||
|
String ourNumber = TextSecurePreferences.getLocalNumber(context);
|
||||||
|
for (String member : members) {
|
||||||
|
// Make sure we have session with all of the members secondary devices
|
||||||
|
LokiStorageAPI.shared.getAllDevicePublicKeys(member).success(devices -> {
|
||||||
|
if (devices.contains(ourNumber)) { return Unit.INSTANCE; }
|
||||||
|
for (String device : devices) {
|
||||||
|
SignalProtocolAddress protocolAddress = new SignalProtocolAddress(device, SignalServiceAddress.DEFAULT_DEVICE_ID);
|
||||||
|
boolean haveSession = new TextSecureSessionStore(context).containsSession(protocolAddress);
|
||||||
|
if (!haveSession) { MessageSender.sendBackgroundSessionRequest(context, device); }
|
||||||
|
}
|
||||||
|
return Unit.INSTANCE;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,6 @@ import org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl;
|
|||||||
import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore;
|
import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore;
|
||||||
import org.thoughtcrime.securesms.database.Address;
|
import org.thoughtcrime.securesms.database.Address;
|
||||||
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||||
import org.thoughtcrime.securesms.database.Database;
|
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||||
import org.thoughtcrime.securesms.database.GroupReceiptDatabase;
|
import org.thoughtcrime.securesms.database.GroupReceiptDatabase;
|
||||||
@ -296,6 +295,9 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
// Loki - Handle friend request acceptance if needed
|
// Loki - Handle friend request acceptance if needed
|
||||||
acceptFriendRequestIfNeeded(envelope, content);
|
acceptFriendRequestIfNeeded(envelope, content);
|
||||||
|
|
||||||
|
// Loki - Session requests
|
||||||
|
handleSessionRequestIfNeeded(envelope, content);
|
||||||
|
|
||||||
// Loki - Store pre key bundle
|
// Loki - Store pre key bundle
|
||||||
// We shouldn't store it if it's a pairing message
|
// We shouldn't store it if it's a pairing message
|
||||||
if (!content.getPairingAuthorisation().isPresent()) {
|
if (!content.getPairingAuthorisation().isPresent()) {
|
||||||
@ -340,7 +342,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Loki - We shouldn't process session restore message any further
|
// Loki - We shouldn't process session restore message any further
|
||||||
if (message.isSessionRestore()) { return; }
|
if (message.isSessionRestore() || message.isSessionRequest()) { return; }
|
||||||
if (message.isEndSession()) handleEndSessionMessage(content, smsMessageId);
|
if (message.isEndSession()) handleEndSessionMessage(content, smsMessageId);
|
||||||
else if (message.isGroupUpdate()) handleGroupMessage(content, message, smsMessageId);
|
else if (message.isGroupUpdate()) handleGroupMessage(content, message, smsMessageId);
|
||||||
else if (message.isExpirationUpdate())
|
else if (message.isExpirationUpdate())
|
||||||
@ -697,7 +699,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
Log.d("Loki", "Sent friend request to " + pubKey);
|
Log.d("Loki", "Sent friend request to " + pubKey);
|
||||||
} else if (status == LokiThreadFriendRequestStatus.REQUEST_RECEIVED) {
|
} else if (status == LokiThreadFriendRequestStatus.REQUEST_RECEIVED) {
|
||||||
// Accept the incoming friend request
|
// Accept the incoming friend request
|
||||||
becomeFriendsWithContact(pubKey, false);
|
becomeFriendsWithContact(pubKey, false, false);
|
||||||
// Send them an accept message back
|
// Send them an accept message back
|
||||||
MessageSender.sendBackgroundMessage(context, pubKey);
|
MessageSender.sendBackgroundMessage(context, pubKey);
|
||||||
Log.d("Loki", "Became friends with " + deviceContact.getNumber());
|
Log.d("Loki", "Became friends with " + deviceContact.getNumber());
|
||||||
@ -1225,10 +1227,21 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
private void acceptFriendRequestIfNeeded(@NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceContent content) {
|
private void acceptFriendRequestIfNeeded(@NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceContent content) {
|
||||||
// If we get anything other than a friend request, we can assume that we have a session with the other user
|
// If we get anything other than a friend request, we can assume that we have a session with the other user
|
||||||
if (envelope.isFriendRequest() || isGroupChatMessage(content)) { return; }
|
if (envelope.isFriendRequest() || isGroupChatMessage(content)) { return; }
|
||||||
becomeFriendsWithContact(content.getSender(), true);
|
becomeFriendsWithContact(content.getSender(), true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void becomeFriendsWithContact(String pubKey, boolean syncContact) {
|
private void handleSessionRequestIfNeeded(@NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceContent content) {
|
||||||
|
if (envelope.isFriendRequest() && isSessionRequest(content)) {
|
||||||
|
// TODO: Check if member is in one of our private groups
|
||||||
|
boolean isInOneOfOurGroups = false;
|
||||||
|
if (isInOneOfOurGroups) {
|
||||||
|
// Send a background message to acknowledge session request
|
||||||
|
MessageSender.sendBackgroundMessage(context, content.getSender());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void becomeFriendsWithContact(String pubKey, boolean syncContact, boolean force) {
|
||||||
LokiThreadDatabase lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context);
|
LokiThreadDatabase lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context);
|
||||||
Recipient contactID = Recipient.from(context, Address.fromSerialized(pubKey), false);
|
Recipient contactID = Recipient.from(context, Address.fromSerialized(pubKey), false);
|
||||||
if (contactID.isGroupRecipient()) return;
|
if (contactID.isGroupRecipient()) return;
|
||||||
@ -1236,6 +1249,11 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(contactID);
|
long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(contactID);
|
||||||
LokiThreadFriendRequestStatus threadFriendRequestStatus = lokiThreadDatabase.getFriendRequestStatus(threadID);
|
LokiThreadFriendRequestStatus threadFriendRequestStatus = lokiThreadDatabase.getFriendRequestStatus(threadID);
|
||||||
if (threadFriendRequestStatus == LokiThreadFriendRequestStatus.FRIENDS) { return; }
|
if (threadFriendRequestStatus == LokiThreadFriendRequestStatus.FRIENDS) { return; }
|
||||||
|
|
||||||
|
// We shouldn't be able to skip from None -> Friends in normal circumstances.
|
||||||
|
// Multi-device is the exception to this rule because we want to automatically be friends with a secondary device
|
||||||
|
if (!force && threadFriendRequestStatus == LokiThreadFriendRequestStatus.NONE) { return; }
|
||||||
|
|
||||||
// If the thread's friend request status is not `FRIENDS`, but we're receiving a message,
|
// If the thread's friend request status is not `FRIENDS`, but we're receiving a message,
|
||||||
// it must be a friend request accepted message. Declining a friend request doesn't send a message.
|
// it must be a friend request accepted message. Declining a friend request doesn't send a message.
|
||||||
lokiThreadDatabase.setFriendRequestStatus(threadID, LokiThreadFriendRequestStatus.FRIENDS);
|
lokiThreadDatabase.setFriendRequestStatus(threadID, LokiThreadFriendRequestStatus.FRIENDS);
|
||||||
@ -1256,13 +1274,13 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateFriendRequestStatusIfNeeded(@NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message) {
|
private void updateFriendRequestStatusIfNeeded(@NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message) {
|
||||||
if (!envelope.isFriendRequest() || message.isGroupUpdate()) { return; }
|
if (!envelope.isFriendRequest() || message.isGroupUpdate() || message.isSessionRequest()) { return; }
|
||||||
// This handles the case where another user sends us a regular message without authorisation
|
// This handles the case where another user sends us a regular message without authorisation
|
||||||
Promise<Boolean, Exception> promise = PromiseUtil.timeout(MultiDeviceUtilities.shouldAutomaticallyBecomeFriendsWithDevice(content.getSender(), context), 8000);
|
Promise<Boolean, Exception> promise = PromiseUtil.timeout(MultiDeviceUtilities.shouldAutomaticallyBecomeFriendsWithDevice(content.getSender(), context), 8000);
|
||||||
boolean shouldBecomeFriends = PromiseUtil.get(promise, false);
|
boolean shouldBecomeFriends = PromiseUtil.get(promise, false);
|
||||||
if (shouldBecomeFriends) {
|
if (shouldBecomeFriends) {
|
||||||
// Become friends AND update the message they sent
|
// Become friends AND update the message they sent
|
||||||
becomeFriendsWithContact(content.getSender(), true);
|
becomeFriendsWithContact(content.getSender(), true, true);
|
||||||
// Send them an accept message back
|
// Send them an accept message back
|
||||||
MessageSender.sendBackgroundMessage(context, content.getSender());
|
MessageSender.sendBackgroundMessage(context, content.getSender());
|
||||||
} else {
|
} else {
|
||||||
@ -1843,6 +1861,10 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isSessionRequest(SignalServiceContent content) {
|
||||||
|
return content.getDataMessage().isPresent() && content.getDataMessage().get().isSessionRequest();
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isGroupChatMessage(SignalServiceContent content) {
|
private boolean isGroupChatMessage(SignalServiceContent content) {
|
||||||
return content.getDataMessage().isPresent() && content.getDataMessage().get().getGroupInfo().isPresent();
|
return content.getDataMessage().isPresent() && content.getDataMessage().get().getGroupInfo().isPresent();
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import org.thoughtcrime.securesms.ApplicationContext;
|
|||||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||||
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
|
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
|
||||||
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
|
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
|
||||||
|
import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore;
|
||||||
import org.thoughtcrime.securesms.database.Address;
|
import org.thoughtcrime.securesms.database.Address;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.GroupReceiptDatabase.GroupReceiptInfo;
|
import org.thoughtcrime.securesms.database.GroupReceiptDatabase.GroupReceiptInfo;
|
||||||
@ -30,9 +31,11 @@ import org.thoughtcrime.securesms.mms.MmsException;
|
|||||||
import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage;
|
import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage;
|
||||||
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
|
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
|
import org.thoughtcrime.securesms.sms.MessageSender;
|
||||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||||
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
|
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
|
||||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||||
|
import org.whispersystems.libsignal.SignalProtocolAddress;
|
||||||
import org.whispersystems.libsignal.util.guava.Optional;
|
import org.whispersystems.libsignal.util.guava.Optional;
|
||||||
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
||||||
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair;
|
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair;
|
||||||
@ -160,7 +163,23 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
|
|||||||
else if (!existingNetworkFailures.isEmpty()) target = Stream.of(existingNetworkFailures).map(NetworkFailure::getAddress).toList();
|
else if (!existingNetworkFailures.isEmpty()) target = Stream.of(existingNetworkFailures).map(NetworkFailure::getAddress).toList();
|
||||||
else target = getGroupMessageRecipients(message.getRecipient().getAddress().toGroupString(), messageId);
|
else target = getGroupMessageRecipients(message.getRecipient().getAddress().toGroupString(), messageId);
|
||||||
|
|
||||||
List<SendMessageResult> results = deliver(message, target);
|
// Only send messages to the contacts we have sessions with
|
||||||
|
List<Address> validTargets = Stream.of(target).filter(member -> {
|
||||||
|
SignalProtocolAddress protocolAddress = new SignalProtocolAddress(member.toPhoneString(), SignalServiceAddress.DEFAULT_DEVICE_ID);
|
||||||
|
boolean hasSession = new TextSecureSessionStore(context).containsSession(protocolAddress);
|
||||||
|
if (hasSession) { return true; }
|
||||||
|
|
||||||
|
// We should allow sending if we have a prekeybundle for the contact
|
||||||
|
return DatabaseFactory.getLokiPreKeyBundleDatabase(context).hasPreKeyBundle(member.toPhoneString());
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
// Send a session request to the other devices
|
||||||
|
List<Address> others = Stream.of(target).filter(t -> !validTargets.contains(t)).toList();
|
||||||
|
for (Address device : others) {
|
||||||
|
MessageSender.sendBackgroundSessionRequest(context, device.toPhoneString());
|
||||||
|
}
|
||||||
|
|
||||||
|
List<SendMessageResult> results = deliver(message, validTargets);
|
||||||
List<NetworkFailure> networkFailures = Stream.of(results).filter(SendMessageResult::isNetworkFailure).map(result -> new NetworkFailure(Address.fromSerialized(result.getAddress().getNumber()))).toList();
|
List<NetworkFailure> networkFailures = Stream.of(results).filter(SendMessageResult::isNetworkFailure).map(result -> new NetworkFailure(Address.fromSerialized(result.getAddress().getNumber()))).toList();
|
||||||
List<IdentityKeyMismatch> identityMismatches = Stream.of(results).filter(result -> result.getIdentityFailure() != null).map(result -> new IdentityKeyMismatch(Address.fromSerialized(result.getAddress().getNumber()), result.getIdentityFailure().getIdentityKey())).toList();
|
List<IdentityKeyMismatch> identityMismatches = Stream.of(results).filter(result -> result.getIdentityFailure() != null).map(result -> new IdentityKeyMismatch(Address.fromSerialized(result.getAddress().getNumber()), result.getIdentityFailure().getIdentityKey())).toList();
|
||||||
Set<Address> successAddresses = Stream.of(results).filter(result -> result.getSuccess() != null).map(result -> Address.fromSerialized(result.getAddress().getNumber())).collect(Collectors.toSet());
|
Set<Address> successAddresses = Stream.of(results).filter(result -> result.getSuccess() != null).map(result -> Address.fromSerialized(result.getAddress().getNumber())).collect(Collectors.toSet());
|
||||||
|
@ -13,7 +13,6 @@ import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage
|
|||||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress
|
import org.whispersystems.signalservice.api.push.SignalServiceAddress
|
||||||
import org.whispersystems.signalservice.internal.util.JsonUtil
|
import org.whispersystems.signalservice.internal.util.JsonUtil
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.lang.IllegalStateException
|
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
data class BackgroundMessage private constructor(val data: Map<String, Any>) {
|
data class BackgroundMessage private constructor(val data: Map<String, Any>) {
|
||||||
@ -37,6 +36,12 @@ data class BackgroundMessage private constructor(val data: Map<String, Any>) {
|
|||||||
"friendRequest" to true,
|
"friendRequest" to true,
|
||||||
"sessionRestore" to true
|
"sessionRestore" to true
|
||||||
))
|
))
|
||||||
|
@JvmStatic
|
||||||
|
fun createSessionRequest(recipient: String) = BackgroundMessage(mapOf(
|
||||||
|
"recipient" to recipient,
|
||||||
|
"friendRequest" to true,
|
||||||
|
"sessionRequest" to true
|
||||||
|
))
|
||||||
|
|
||||||
internal fun parse(serialized: String): BackgroundMessage {
|
internal fun parse(serialized: String): BackgroundMessage {
|
||||||
val data = JsonUtil.fromJson(serialized, Map::class.java) as? Map<String, Any> ?: throw AssertionError("JSON parsing failed")
|
val data = JsonUtil.fromJson(serialized, Map::class.java) as? Map<String, Any> ?: throw AssertionError("JSON parsing failed")
|
||||||
@ -103,6 +108,10 @@ class PushBackgroundMessageSendJob private constructor(
|
|||||||
dataMessage.asSessionRestore(true)
|
dataMessage.asSessionRestore(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (message.get("sessionRequest", false)) {
|
||||||
|
dataMessage.asSessionRequest(true)
|
||||||
|
}
|
||||||
|
|
||||||
val messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender()
|
val messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender()
|
||||||
val address = SignalServiceAddress(recipient)
|
val address = SignalServiceAddress(recipient)
|
||||||
try {
|
try {
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
package org.thoughtcrime.securesms.sms;
|
package org.thoughtcrime.securesms.sms;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.ApplicationContext;
|
import org.thoughtcrime.securesms.ApplicationContext;
|
||||||
@ -60,11 +59,7 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
|||||||
import org.thoughtcrime.securesms.util.Util;
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
import org.whispersystems.libsignal.util.guava.Optional;
|
import org.whispersystems.libsignal.util.guava.Optional;
|
||||||
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
||||||
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
|
||||||
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair;
|
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
|
||||||
import org.whispersystems.signalservice.api.push.ContactTokenDetails;
|
import org.whispersystems.signalservice.api.push.ContactTokenDetails;
|
||||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
|
||||||
import org.whispersystems.signalservice.loki.api.LokiStorageAPI;
|
import org.whispersystems.signalservice.loki.api.LokiStorageAPI;
|
||||||
import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus;
|
import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus;
|
||||||
import org.whispersystems.signalservice.loki.utilities.PromiseUtil;
|
import org.whispersystems.signalservice.loki.utilities.PromiseUtil;
|
||||||
@ -143,6 +138,10 @@ public class MessageSender {
|
|||||||
public static void sendRestoreSessionMessage(Context context, String contactHexEncodedPublicKey) {
|
public static void sendRestoreSessionMessage(Context context, String contactHexEncodedPublicKey) {
|
||||||
ApplicationContext.getInstance(context).getJobManager().add(new PushBackgroundMessageSendJob(BackgroundMessage.createSessionRestore(contactHexEncodedPublicKey)));
|
ApplicationContext.getInstance(context).getJobManager().add(new PushBackgroundMessageSendJob(BackgroundMessage.createSessionRestore(contactHexEncodedPublicKey)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void sendBackgroundSessionRequest(Context context, String contactHexEncodedPublicKey) {
|
||||||
|
ApplicationContext.getInstance(context).getJobManager().add(new PushBackgroundMessageSendJob(BackgroundMessage.createSessionRequest(contactHexEncodedPublicKey)));
|
||||||
|
}
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
public static long send(final Context context,
|
public static long send(final Context context,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user