mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-25 17:27:45 +00:00
Simplify PushDecryptJob a bit
This commit is contained in:
parent
27fdfe4ee8
commit
9c71a4c3cd
@ -290,13 +290,14 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Loki - Handle friend request acceptance if needed
|
// Loki - Handle friend request acceptance if needed
|
||||||
acceptFriendRequestIfNeeded(content);
|
if (!content.isFriendRequest() && !isGroupChatMessage(content)) {
|
||||||
|
becomeFriendsWithContactIfNeeded(content.getSender(), true, false);
|
||||||
|
}
|
||||||
|
|
||||||
// Loki - Session requests
|
// Loki - Handle session request if needed
|
||||||
handleSessionRequestIfNeeded(content);
|
handleSessionRequestIfNeeded(content);
|
||||||
|
|
||||||
// Loki - Store pre key bundle
|
// Loki - Store pre key bundle if needed
|
||||||
// We shouldn't store it if it's a pairing message
|
|
||||||
if (!content.getDeviceLink().isPresent()) {
|
if (!content.getDeviceLink().isPresent()) {
|
||||||
storePreKeyBundleIfNeeded(content);
|
storePreKeyBundleIfNeeded(content);
|
||||||
}
|
}
|
||||||
@ -311,29 +312,29 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
// Loki - Store the sender display name if needed
|
// Loki - Store the sender display name if needed
|
||||||
Optional<String> rawSenderDisplayName = content.senderDisplayName;
|
Optional<String> rawSenderDisplayName = content.senderDisplayName;
|
||||||
if (rawSenderDisplayName.isPresent() && rawSenderDisplayName.get().length() > 0) {
|
if (rawSenderDisplayName.isPresent() && rawSenderDisplayName.get().length() > 0) {
|
||||||
// If we got a name from our primary device then we set our profile name to match it
|
// If we got a name from our master device then set our display name to match
|
||||||
String ourPrimaryDevice = TextSecurePreferences.getMasterHexEncodedPublicKey(context);
|
String ourMasterDevice = TextSecurePreferences.getMasterHexEncodedPublicKey(context);
|
||||||
if (ourPrimaryDevice != null && content.getSender().equals(ourPrimaryDevice)) {
|
if (ourMasterDevice != null && content.getSender().equals(ourMasterDevice)) {
|
||||||
TextSecurePreferences.setProfileName(context, rawSenderDisplayName.get());
|
TextSecurePreferences.setProfileName(context, rawSenderDisplayName.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we receive a message from our device then don't set the display name in the database (as we probably have a alias set for them)
|
// If we receive a message from our device then don't set the display name in the database (as we probably have a alias set for them)
|
||||||
MultiDeviceUtilities.isOneOfOurDevices(context, Address.fromSerialized(content.getSender())).success(isOneOfOurDevice -> {
|
MultiDeviceUtilities.isOneOfOurDevices(context, Address.fromSerialized(content.getSender())).success( isOneOfOurDevices -> {
|
||||||
if (!isOneOfOurDevice) { setDisplayName(content.getSender(), rawSenderDisplayName.get()); }
|
if (!isOneOfOurDevices) { setDisplayName(content.getSender(), rawSenderDisplayName.get()); }
|
||||||
return Unit.INSTANCE;
|
return Unit.INSTANCE;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (content.getDeviceLink().isPresent()) {
|
if (content.getDeviceLink().isPresent()) {
|
||||||
handlePairingMessage(content.getDeviceLink().get(), content);
|
handleDeviceLinkMessage(content.getDeviceLink().get(), content);
|
||||||
} else if (content.getDataMessage().isPresent()) {
|
} else if (content.getDataMessage().isPresent()) {
|
||||||
SignalServiceDataMessage message = content.getDataMessage().get();
|
SignalServiceDataMessage message = content.getDataMessage().get();
|
||||||
boolean isMediaMessage = message.getAttachments().isPresent() || message.getQuote().isPresent() || message.getSharedContacts().isPresent() || message.getPreviews().isPresent() || message.getSticker().isPresent();
|
boolean isMediaMessage = message.getAttachments().isPresent() || message.getQuote().isPresent() || message.getSharedContacts().isPresent() || message.getPreviews().isPresent() || message.getSticker().isPresent();
|
||||||
|
|
||||||
if (!content.isFriendRequest() && message.isUnlinkingRequest()) {
|
if (!content.isFriendRequest() && message.isUnlinkingRequest()) {
|
||||||
// Make sure we got the request from our primary device
|
// Make sure we got the request from our master device
|
||||||
String ourPrimaryDevice = TextSecurePreferences.getMasterHexEncodedPublicKey(context);
|
String ourMasterDevice = TextSecurePreferences.getMasterHexEncodedPublicKey(context);
|
||||||
if (ourPrimaryDevice != null && ourPrimaryDevice.equals(content.getSender())) {
|
if (ourMasterDevice != null && ourMasterDevice.equals(content.getSender())) {
|
||||||
TextSecurePreferences.setDatabaseResetFromUnpair(context, true);
|
TextSecurePreferences.setDatabaseResetFromUnpair(context, true);
|
||||||
MultiDeviceUtilities.checkForRevocation(context);
|
MultiDeviceUtilities.checkForRevocation(context);
|
||||||
}
|
}
|
||||||
@ -376,7 +377,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
else if (syncMessage.getRead().isPresent()) handleSynchronizeReadMessage(syncMessage.getRead().get(), content.getTimestamp());
|
else if (syncMessage.getRead().isPresent()) handleSynchronizeReadMessage(syncMessage.getRead().get(), content.getTimestamp());
|
||||||
else if (syncMessage.getVerified().isPresent()) handleSynchronizeVerifiedMessage(syncMessage.getVerified().get());
|
else if (syncMessage.getVerified().isPresent()) handleSynchronizeVerifiedMessage(syncMessage.getVerified().get());
|
||||||
else if (syncMessage.getStickerPackOperations().isPresent()) handleSynchronizeStickerPackOperation(syncMessage.getStickerPackOperations().get());
|
else if (syncMessage.getStickerPackOperations().isPresent()) handleSynchronizeStickerPackOperation(syncMessage.getStickerPackOperations().get());
|
||||||
else if (syncMessage.getContacts().isPresent()) handleSynchronizeContactMessage(syncMessage.getContacts().get());
|
else if (syncMessage.getContacts().isPresent()) handleContactSyncMessage(syncMessage.getContacts().get());
|
||||||
else Log.w(TAG, "Contains no known sync types...");
|
else Log.w(TAG, "Contains no known sync types...");
|
||||||
} else if (content.getCallMessage().isPresent()) {
|
} else if (content.getCallMessage().isPresent()) {
|
||||||
Log.i(TAG, "Got call message...");
|
Log.i(TAG, "Got call message...");
|
||||||
@ -594,7 +595,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
{
|
{
|
||||||
GroupMessageProcessor.process(context, content, message, false);
|
GroupMessageProcessor.process(context, content, message, false);
|
||||||
|
|
||||||
if (message.getExpiresInSeconds() != 0 && message.getExpiresInSeconds() != getMessageDestination(content, message).getExpireMessages()) {
|
if (message.getExpiresInSeconds() != 0 && message.getExpiresInSeconds() != getRecipientForMessage(content, message).getExpireMessages()) {
|
||||||
handleExpirationUpdate(content, message, Optional.absent());
|
handleExpirationUpdate(content, message, Optional.absent());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -620,7 +621,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
|
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
|
||||||
Recipient recipient = getMessageDestination(content, message);
|
Recipient recipient = getRecipientForMessage(content, message);
|
||||||
IncomingMediaMessage mediaMessage = new IncomingMediaMessage(Address.fromSerialized(content.getSender()),
|
IncomingMediaMessage mediaMessage = new IncomingMediaMessage(Address.fromSerialized(content.getSender()),
|
||||||
message.getTimestamp(), -1,
|
message.getTimestamp(), -1,
|
||||||
message.getExpiresInSeconds() * 1000L, true,
|
message.getExpiresInSeconds() * 1000L, true,
|
||||||
@ -671,45 +672,44 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleSynchronizeContactMessage(@NonNull ContactsMessage contactsMessage) {
|
private void handleContactSyncMessage(@NonNull ContactsMessage contactsMessage) {
|
||||||
if (contactsMessage.getContactsStream().isStream()) {
|
if (!contactsMessage.getContactsStream().isStream()) { return; }
|
||||||
Log.d("Loki", "Received contact sync message");
|
Log.d("Loki", "Received contact sync message.");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
InputStream in = contactsMessage.getContactsStream().asStream().getInputStream();
|
InputStream in = contactsMessage.getContactsStream().asStream().getInputStream();
|
||||||
DeviceContactsInputStream contactsInputStream = new DeviceContactsInputStream(in);
|
DeviceContactsInputStream contactsInputStream = new DeviceContactsInputStream(in);
|
||||||
List<DeviceContact> devices = contactsInputStream.readAll();
|
List<DeviceContact> deviceContacts = contactsInputStream.readAll();
|
||||||
for (DeviceContact deviceContact : devices) {
|
for (DeviceContact deviceContact : deviceContacts) {
|
||||||
// Check if we have the contact as a friend and that we're not trying to sync our own device
|
// Check if we have the contact as a friend and that we're not trying to sync our own device
|
||||||
String pubKey = deviceContact.getNumber();
|
String hexEncodedPublicKey = deviceContact.getNumber();
|
||||||
Address address = Address.fromSerialized(pubKey);
|
Address address = Address.fromSerialized(hexEncodedPublicKey);
|
||||||
if (!address.isPhone() || address.toPhoneString().equals(TextSecurePreferences.getLocalNumber(context))) { continue; }
|
if (!address.isPhone() || address.toPhoneString().equals(TextSecurePreferences.getLocalNumber(context))) { continue; }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If we're not friends with the contact we received or our friend request expired then we should send them a friend request
|
If we're not friends with the contact we received or our friend request expired then we should send them a friend request.
|
||||||
otherwise if we have received a friend request with from them then we should automatically accept the friend request
|
Otherwise, if we have received a friend request from them, automatically accept the friend request.
|
||||||
*/
|
*/
|
||||||
Recipient recipient = Recipient.from(context, address, false);
|
Recipient recipient = Recipient.from(context, address, false);
|
||||||
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient);
|
long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient);
|
||||||
LokiThreadFriendRequestStatus status = DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadId);
|
LokiThreadFriendRequestStatus status = DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadID);
|
||||||
if (status == LokiThreadFriendRequestStatus.NONE || status == LokiThreadFriendRequestStatus.REQUEST_EXPIRED) {
|
if (status == LokiThreadFriendRequestStatus.NONE || status == LokiThreadFriendRequestStatus.REQUEST_EXPIRED) {
|
||||||
MessageSender.sendBackgroundFriendRequest(context, pubKey, "Please accept to enable messages to be synced across devices");
|
MessageSender.sendBackgroundFriendRequest(context, hexEncodedPublicKey, "Please accept to enable messages to be synced across devices");
|
||||||
Log.d("Loki", "Sent friend request to " + pubKey);
|
Log.d("Loki", "Sent friend request to " + hexEncodedPublicKey);
|
||||||
} 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, false);
|
becomeFriendsWithContactIfNeeded(hexEncodedPublicKey, false, false);
|
||||||
// Send them an accept message back
|
// Send them an accept message back
|
||||||
MessageSender.sendBackgroundMessage(context, pubKey);
|
MessageSender.sendBackgroundMessage(context, hexEncodedPublicKey);
|
||||||
Log.d("Loki", "Became friends with " + deviceContact.getNumber());
|
Log.d("Loki", "Became friends with " + deviceContact.getNumber());
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Handle blocked - If user is not blocked then we should do the friend request logic otherwise add them to our block list
|
|
||||||
// TODO: Handle expiration timer - Update expiration timer?
|
|
||||||
// TODO: Handle avatar - Download and set avatar?
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
Log.d("Loki", "Failed to sync contact: " + e);
|
// TODO: Handle blocked - If user is not blocked then we should do the friend request logic otherwise add them to our block list
|
||||||
|
// TODO: Handle expiration timer - Update expiration timer?
|
||||||
|
// TODO: Handle avatar - Download and set avatar?
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.d("Loki", "Failed to sync contact: " + e + ".");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -752,7 +752,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient, true);
|
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loki - If we received a sync message from our master device then we need to extract the avatar url
|
// Loki - If we received a sync message from our master device then we need to extract the profile picture url
|
||||||
if (isSenderMasterDevice) {
|
if (isSenderMasterDevice) {
|
||||||
handleProfileKey(content, message.getMessage());
|
handleProfileKey(content, message.getMessage());
|
||||||
}
|
}
|
||||||
@ -842,21 +842,21 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
@NonNull Optional<Long> messageServerIDOrNull)
|
@NonNull Optional<Long> messageServerIDOrNull)
|
||||||
throws StorageFailedException
|
throws StorageFailedException
|
||||||
{
|
{
|
||||||
Recipient originalRecipient = getMessageDestination(content, message);
|
Recipient originalRecipient = getRecipientForMessage(content, message);
|
||||||
Recipient primaryDeviceRecipient = getMessagePrimaryDestination(content, message);
|
Recipient masterRecipient = getMasterRecipientForMessage(content, message);
|
||||||
|
|
||||||
notifyTypingStoppedFromIncomingMessage(primaryDeviceRecipient, content.getSender(), content.getSenderDevice());
|
notifyTypingStoppedFromIncomingMessage(masterRecipient, content.getSender(), content.getSenderDevice());
|
||||||
|
|
||||||
Optional<QuoteModel> quote = getValidatedQuote(message.getQuote());
|
Optional<QuoteModel> quote = getValidatedQuote(message.getQuote());
|
||||||
Optional<List<Contact>> sharedContacts = getContacts(message.getSharedContacts());
|
Optional<List<Contact>> sharedContacts = getContacts(message.getSharedContacts());
|
||||||
Optional<List<LinkPreview>> linkPreviews = getLinkPreviews(message.getPreviews(), message.getBody().or(""));
|
Optional<List<LinkPreview>> linkPreviews = getLinkPreviews(message.getPreviews(), message.getBody().or(""));
|
||||||
Optional<Attachment> sticker = getStickerAttachment(message.getSticker());
|
Optional<Attachment> sticker = getStickerAttachment(message.getSticker());
|
||||||
|
|
||||||
Address sender = primaryDeviceRecipient.getAddress();
|
Address sender = masterRecipient.getAddress();
|
||||||
|
|
||||||
// If message is from group then we need to map it to get the sender of the message
|
// If message is from group then we need to map it to get the sender of the message
|
||||||
if (message.isGroupMessage()) {
|
if (message.isGroupMessage()) {
|
||||||
sender = getPrimaryDeviceRecipient(content.getSender()).getAddress();
|
sender = getMasterRecipient(content.getSender()).getAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore messages from ourselves
|
// Ignore messages from ourselves
|
||||||
@ -1031,8 +1031,8 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
{
|
{
|
||||||
SmsDatabase database = DatabaseFactory.getSmsDatabase(context);
|
SmsDatabase database = DatabaseFactory.getSmsDatabase(context);
|
||||||
String body = message.getBody().isPresent() ? message.getBody().get() : "";
|
String body = message.getBody().isPresent() ? message.getBody().get() : "";
|
||||||
Recipient originalRecipient = getMessageDestination(content, message);
|
Recipient originalRecipient = getRecipientForMessage(content, message);
|
||||||
Recipient primaryDeviceRecipient = getMessagePrimaryDestination(content, message);
|
Recipient masterRecipient = getMasterRecipientForMessage(content, message);
|
||||||
|
|
||||||
if (message.getExpiresInSeconds() != originalRecipient.getExpireMessages()) {
|
if (message.getExpiresInSeconds() != originalRecipient.getExpireMessages()) {
|
||||||
handleExpirationUpdate(content, message, Optional.absent());
|
handleExpirationUpdate(content, message, Optional.absent());
|
||||||
@ -1043,13 +1043,13 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
if (smsMessageId.isPresent() && !message.getGroupInfo().isPresent()) {
|
if (smsMessageId.isPresent() && !message.getGroupInfo().isPresent()) {
|
||||||
threadId = database.updateBundleMessageBody(smsMessageId.get(), body).second;
|
threadId = database.updateBundleMessageBody(smsMessageId.get(), body).second;
|
||||||
} else {
|
} else {
|
||||||
notifyTypingStoppedFromIncomingMessage(primaryDeviceRecipient, content.getSender(), content.getSenderDevice());
|
notifyTypingStoppedFromIncomingMessage(masterRecipient, content.getSender(), content.getSenderDevice());
|
||||||
|
|
||||||
Address sender = primaryDeviceRecipient.getAddress();
|
Address sender = masterRecipient.getAddress();
|
||||||
|
|
||||||
// If message is from group then we need to map it to get the sender of the message
|
// If message is from group then we need to map it to get the sender of the message
|
||||||
if (message.isGroupMessage()) {
|
if (message.isGroupMessage()) {
|
||||||
sender = getPrimaryDeviceRecipient(content.getSender()).getAddress();
|
sender = getMasterRecipient(content.getSender()).getAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore messages from ourselves
|
// Ignore messages from ourselves
|
||||||
@ -1103,7 +1103,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isValidPairingMessage(@NonNull DeviceLink authorisation) {
|
private boolean isValidDeviceLinkMessage(@NonNull DeviceLink authorisation) {
|
||||||
boolean isSecondaryDevice = TextSecurePreferences.getMasterHexEncodedPublicKey(context) != null;
|
boolean isSecondaryDevice = TextSecurePreferences.getMasterHexEncodedPublicKey(context) != null;
|
||||||
String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context);
|
String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context);
|
||||||
boolean isRequest = (authorisation.getType() == DeviceLink.Type.REQUEST);
|
boolean isRequest = (authorisation.getType() == DeviceLink.Type.REQUEST);
|
||||||
@ -1123,74 +1123,66 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
return authorisation.verify();
|
return authorisation.verify();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleProfileAvatar(SignalServiceContent content, String url) {
|
private void handleDeviceLinkMessage(@NonNull DeviceLink deviceLink, @NonNull SignalServiceContent content) {
|
||||||
Recipient primaryDevice = getPrimaryDeviceRecipient(content.getSender());
|
|
||||||
ApplicationContext.getInstance(context).getJobManager().add(new RetrieveProfileAvatarJob(primaryDevice, url));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handlePairingMessage(@NonNull DeviceLink authorisation, @NonNull SignalServiceContent content) {
|
|
||||||
String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context);
|
String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context);
|
||||||
if (authorisation.getType() == DeviceLink.Type.REQUEST) {
|
if (deviceLink.getType() == DeviceLink.Type.REQUEST) {
|
||||||
handlePairingRequestMessage(authorisation, content);
|
handleDeviceLinkRequestMessage(deviceLink, content);
|
||||||
} else if (authorisation.getSlaveHexEncodedPublicKey().equals(userHexEncodedPublicKey)) {
|
} else if (deviceLink.getSlaveHexEncodedPublicKey().equals(userHexEncodedPublicKey)) {
|
||||||
handlePairingAuthorisationMessage(authorisation, content);
|
handleDeviceLinkAuthorizedMessage(deviceLink, content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handlePairingRequestMessage(@NonNull DeviceLink authorisation, @NonNull SignalServiceContent content) {
|
private void handleDeviceLinkRequestMessage(@NonNull DeviceLink deviceLink, @NonNull SignalServiceContent content) {
|
||||||
boolean isValid = isValidPairingMessage(authorisation);
|
boolean isValid = isValidDeviceLinkMessage(deviceLink);
|
||||||
DeviceLinkingSession linkingSession = DeviceLinkingSession.Companion.getShared();
|
DeviceLinkingSession linkingSession = DeviceLinkingSession.Companion.getShared();
|
||||||
if (isValid && linkingSession.isListeningForLinkingRequests()) {
|
if (!isValid || !linkingSession.isListeningForLinkingRequests()) { return; }
|
||||||
// Loki - If we successfully received a request then we should store the PreKeyBundle
|
storePreKeyBundleIfNeeded(content);
|
||||||
storePreKeyBundleIfNeeded(content);
|
linkingSession.processLinkingRequest(deviceLink);
|
||||||
linkingSession.processLinkingRequest(authorisation);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handlePairingAuthorisationMessage(@NonNull DeviceLink authorisation, @NonNull SignalServiceContent content) {
|
private void handleDeviceLinkAuthorizedMessage(@NonNull DeviceLink deviceLink, @NonNull SignalServiceContent content) {
|
||||||
// Prepare
|
// Check preconditions
|
||||||
boolean isSecondaryDevice = TextSecurePreferences.getMasterHexEncodedPublicKey(context) != null;
|
boolean hasExistingDeviceLink = TextSecurePreferences.getMasterHexEncodedPublicKey(context) != null;
|
||||||
if (isSecondaryDevice) {
|
if (hasExistingDeviceLink) {
|
||||||
Log.d("Loki", "Ignoring unexpected pairing authorisation message (the device is already paired as a secondary device).");
|
Log.d("Loki", "Ignoring unexpected device link message (the device is already linked as a slave device).");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean isValid = isValidPairingMessage(authorisation);
|
boolean isValid = isValidDeviceLinkMessage(deviceLink);
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
Log.d("Loki", "Ignoring invalid pairing authorisation message.");
|
Log.d("Loki", "Ignoring invalid device link message.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!DeviceLinkingSession.Companion.getShared().isListeningForLinkingRequests()) {
|
if (!DeviceLinkingSession.Companion.getShared().isListeningForLinkingRequests()) {
|
||||||
Log.d("Loki", "Ignoring pairing authorisation message.");
|
Log.d("Loki", "Ignoring device link message.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (authorisation.getType() != DeviceLink.Type.AUTHORIZATION) { return; }
|
if (deviceLink.getType() != DeviceLink.Type.AUTHORIZATION) { return; }
|
||||||
Log.d("Loki", "Received pairing authorisation message from: " + authorisation.getMasterHexEncodedPublicKey() + ".");
|
Log.d("Loki", "Received device link authorized message from: " + deviceLink.getMasterHexEncodedPublicKey() + ".");
|
||||||
// Save PreKeyBundle if for whatever reason we got one
|
// Save pre key bundle if we somehow got one
|
||||||
storePreKeyBundleIfNeeded(content);
|
storePreKeyBundleIfNeeded(content);
|
||||||
// Process
|
// Process
|
||||||
DeviceLinkingSession.Companion.getShared().processLinkingAuthorization(authorisation);
|
DeviceLinkingSession.Companion.getShared().processLinkingAuthorization(deviceLink);
|
||||||
// Store the primary device's public key
|
// Store the master device's ID
|
||||||
String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context);
|
String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context);
|
||||||
DatabaseFactory.getLokiAPIDatabase(context).clearDeviceLinks(userHexEncodedPublicKey);
|
DatabaseFactory.getLokiAPIDatabase(context).clearDeviceLinks(userHexEncodedPublicKey);
|
||||||
DatabaseFactory.getLokiAPIDatabase(context).addDeviceLink(authorisation);
|
DatabaseFactory.getLokiAPIDatabase(context).addDeviceLink(deviceLink);
|
||||||
TextSecurePreferences.setMasterHexEncodedPublicKey(context, authorisation.getMasterHexEncodedPublicKey());
|
TextSecurePreferences.setMasterHexEncodedPublicKey(context, deviceLink.getMasterHexEncodedPublicKey());
|
||||||
TextSecurePreferences.setMultiDevice(context, true);
|
TextSecurePreferences.setMultiDevice(context, true);
|
||||||
// Send a background message to the primary device
|
// Send a background message to the master device
|
||||||
MessageSender.sendBackgroundMessage(context, authorisation.getMasterHexEncodedPublicKey());
|
MessageSender.sendBackgroundMessage(context, deviceLink.getMasterHexEncodedPublicKey());
|
||||||
// Propagate the updates to the file server
|
// Propagate the updates to the file server
|
||||||
LokiFileServerAPI storageAPI = LokiFileServerAPI.Companion.getShared();
|
LokiFileServerAPI.Companion.getShared().updateUserDeviceLinks();
|
||||||
storageAPI.updateUserDeviceLinks();
|
// Update display name if needed
|
||||||
// Update display names
|
|
||||||
if (content.senderDisplayName.isPresent() && content.senderDisplayName.get().length() > 0) {
|
if (content.senderDisplayName.isPresent() && content.senderDisplayName.get().length() > 0) {
|
||||||
TextSecurePreferences.setProfileName(context, content.senderDisplayName.get());
|
TextSecurePreferences.setProfileName(context, content.senderDisplayName.get());
|
||||||
}
|
}
|
||||||
// Profile avatar updates
|
// Update profile picture if needed
|
||||||
if (content.getDataMessage().isPresent()) {
|
if (content.getDataMessage().isPresent()) {
|
||||||
handleProfileKey(content, content.getDataMessage().get());
|
handleProfileKey(content, content.getDataMessage().get());
|
||||||
}
|
}
|
||||||
// Contact sync
|
// Handle contact sync if needed
|
||||||
if (content.getSyncMessage().isPresent() && content.getSyncMessage().get().getContacts().isPresent()) {
|
if (content.getSyncMessage().isPresent() && content.getSyncMessage().get().getContacts().isPresent()) {
|
||||||
handleSynchronizeContactMessage(content.getSyncMessage().get().getContacts().get());
|
handleContactSyncMessage(content.getSyncMessage().get().getContacts().get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1200,95 +1192,79 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateGroupChatMessageServerID(Optional<Long> messageServerIDOrNull, Optional<InsertResult> insertResult) {
|
private void updateGroupChatMessageServerID(Optional<Long> messageServerIDOrNull, Optional<InsertResult> insertResult) {
|
||||||
if (insertResult.isPresent() && messageServerIDOrNull.isPresent()) {
|
if (!insertResult.isPresent() || !messageServerIDOrNull.isPresent()) { return; }
|
||||||
long messageID = insertResult.get().getMessageId();
|
long messageID = insertResult.get().getMessageId();
|
||||||
long messageServerID = messageServerIDOrNull.get();
|
long messageServerID = messageServerIDOrNull.get();
|
||||||
DatabaseFactory.getLokiMessageDatabase(context).setServerID(messageID, messageServerID);
|
DatabaseFactory.getLokiMessageDatabase(context).setServerID(messageID, messageServerID);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void storePreKeyBundleIfNeeded(@NonNull SignalServiceContent content) {
|
private void storePreKeyBundleIfNeeded(@NonNull SignalServiceContent content) {
|
||||||
Recipient sender = Recipient.from(context, Address.fromSerialized(content.getSender()), false);
|
Recipient sender = Recipient.from(context, Address.fromSerialized(content.getSender()), false);
|
||||||
if (!sender.isGroupRecipient() && content.lokiServiceMessage.isPresent()) {
|
if (sender.isGroupRecipient() || !content.lokiServiceMessage.isPresent()) { return; }
|
||||||
LokiServiceMessage lokiMessage = content.lokiServiceMessage.get();
|
LokiServiceMessage lokiMessage = content.lokiServiceMessage.get();
|
||||||
if (lokiMessage.getPreKeyBundleMessage() != null) {
|
if (lokiMessage.getPreKeyBundleMessage() == null) { return; }
|
||||||
int registrationID = TextSecurePreferences.getLocalRegistrationId(context);
|
int registrationID = TextSecurePreferences.getLocalRegistrationId(context);
|
||||||
LokiPreKeyBundleDatabase lokiPreKeyBundleDatabase = DatabaseFactory.getLokiPreKeyBundleDatabase(context);
|
LokiPreKeyBundleDatabase lokiPreKeyBundleDatabase = DatabaseFactory.getLokiPreKeyBundleDatabase(context);
|
||||||
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context);
|
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context);
|
||||||
LokiThreadDatabase lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context);
|
LokiThreadDatabase lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context);
|
||||||
|
if (registrationID <= 0) { return; }
|
||||||
// Loki - Store the latest pre key bundle
|
Log.d("Loki", "Received a pre key bundle from: " + content.getSender() + ".");
|
||||||
if (registrationID > 0) {
|
PreKeyBundle preKeyBundle = lokiMessage.getPreKeyBundleMessage().getPreKeyBundle(registrationID);
|
||||||
Log.d("Loki", "Received a pre key bundle from: " + content.getSender() + ".");
|
lokiPreKeyBundleDatabase.setPreKeyBundle(content.getSender(), preKeyBundle);
|
||||||
PreKeyBundle preKeyBundle = lokiMessage.getPreKeyBundleMessage().getPreKeyBundle(registrationID);
|
// If we received a friend request, but we were already friends with the user, reset the session
|
||||||
lokiPreKeyBundleDatabase.setPreKeyBundle(content.getSender(), preKeyBundle);
|
if (content.isFriendRequest()) {
|
||||||
|
long threadID = threadDatabase.getThreadIdIfExistsFor(sender);
|
||||||
// Loki - If we received a friend request, but we were already friends with this user, then reset the session
|
if (lokiThreadDatabase.getFriendRequestStatus(threadID) == LokiThreadFriendRequestStatus.FRIENDS) {
|
||||||
if (content.isFriendRequest()) {
|
resetSession(content.getSender(), threadID);
|
||||||
long threadID = threadDatabase.getThreadIdIfExistsFor(sender);
|
// Let our other devices know that we have reset the session
|
||||||
if (lokiThreadDatabase.getFriendRequestStatus(threadID) == LokiThreadFriendRequestStatus.FRIENDS) {
|
MessageSender.syncContact(context, sender.getAddress());
|
||||||
resetSession(content.getSender(), threadID);
|
|
||||||
// Let our other devices know that we have reset the session
|
|
||||||
MessageSender.syncContact(context, sender.getAddress());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void acceptFriendRequestIfNeeded(@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 (content.isFriendRequest() || isGroupChatMessage(content)) { return; }
|
|
||||||
becomeFriendsWithContact(content.getSender(), true, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleSessionRequestIfNeeded(@NonNull SignalServiceContent content) {
|
private void handleSessionRequestIfNeeded(@NonNull SignalServiceContent content) {
|
||||||
if (content.isFriendRequest() && isSessionRequest(content)) {
|
if (!content.isFriendRequest() || !isSessionRequest(content)) { return; }
|
||||||
// Check if the session request from a member in one of our groups or our friend
|
// Check if the session request came from a member in one of our groups or one of our friends
|
||||||
LokiDeviceLinkUtilities.INSTANCE.getMasterHexEncodedPublicKey(content.getSender()).success(primaryDevicePublicKey -> {
|
LokiDeviceLinkUtilities.INSTANCE.getMasterHexEncodedPublicKey(content.getSender()).success( masterHexEncodedPublicKey -> {
|
||||||
String sender = primaryDevicePublicKey != null ? primaryDevicePublicKey : content.getSender();
|
String sender = masterHexEncodedPublicKey != null ? masterHexEncodedPublicKey : content.getSender();
|
||||||
long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(Recipient.from(context, Address.fromSerialized(sender), false));
|
long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(Recipient.from(context, Address.fromSerialized(sender), false));
|
||||||
LokiThreadFriendRequestStatus threadFriendRequestStatus = DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadID);
|
LokiThreadFriendRequestStatus threadFriendRequestStatus = DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadID);
|
||||||
boolean isOurFriend = threadFriendRequestStatus == LokiThreadFriendRequestStatus.FRIENDS;
|
boolean isOurFriend = threadFriendRequestStatus == LokiThreadFriendRequestStatus.FRIENDS;
|
||||||
boolean isInOneOfOurGroups = DatabaseFactory.getGroupDatabase(context).signalGroupsHaveMember(sender);
|
boolean isInOneOfOurGroups = DatabaseFactory.getGroupDatabase(context).signalGroupsHaveMember(sender);
|
||||||
boolean shouldAcceptSessionRequest = isOurFriend || isInOneOfOurGroups;
|
boolean shouldAcceptSessionRequest = isOurFriend || isInOneOfOurGroups;
|
||||||
if (shouldAcceptSessionRequest) {
|
if (shouldAcceptSessionRequest) {
|
||||||
// Send a background message to acknowledge session request
|
MessageSender.sendBackgroundMessage(context, content.getSender()); // Send a background message to acknowledge
|
||||||
MessageSender.sendBackgroundMessage(context, content.getSender());
|
}
|
||||||
}
|
return Unit.INSTANCE;
|
||||||
return Unit.INSTANCE;
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void becomeFriendsWithContact(String pubKey, boolean syncContact, boolean force) {
|
private void becomeFriendsWithContactIfNeeded(String hexEncodedPublicKey, boolean requiresContactSync, boolean canSkip) {
|
||||||
|
// Ignore friend requests to group recipients
|
||||||
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(hexEncodedPublicKey), false);
|
||||||
if (contactID.isGroupRecipient()) return;
|
if (contactID.isGroupRecipient()) return;
|
||||||
|
// Ignore friend requests to recipients we're already friends with
|
||||||
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 to FRIENDS under normal circumstances.
|
||||||
// We shouldn't be able to skip from None -> Friends in normal circumstances.
|
// Multi-device is the one exception to this rule because we want to automatically become friends with slave devices.
|
||||||
// Multi-device is the exception to this rule because we want to automatically be friends with a secondary device
|
if (!canSkip && threadFriendRequestStatus == LokiThreadFriendRequestStatus.NONE) { return; }
|
||||||
if (!force && threadFriendRequestStatus == LokiThreadFriendRequestStatus.NONE) { return; }
|
// If the thread's friend request status is not `FRIENDS` or `NONE`, 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);
|
||||||
// Send out a contact sync message
|
// Send out a contact sync message if needed
|
||||||
if (syncContact) {
|
if (requiresContactSync) {
|
||||||
MessageSender.syncContact(context, contactID.getAddress());
|
MessageSender.syncContact(context, contactID.getAddress());
|
||||||
}
|
}
|
||||||
// Allow profile sharing with contact
|
// Enable profile sharing with the recipient
|
||||||
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(contactID, true);
|
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(contactID, true);
|
||||||
// Update the last message if needed
|
// Update the last message if needed
|
||||||
LokiDeviceLinkUtilities.INSTANCE.getMasterHexEncodedPublicKey(pubKey).success(primaryDevice -> {
|
LokiDeviceLinkUtilities.INSTANCE.getMasterHexEncodedPublicKey(hexEncodedPublicKey).success( masterHexEncodedPublicKey -> {
|
||||||
Util.runOnMain(() -> {
|
Util.runOnMain(() -> {
|
||||||
long primaryDeviceThreadID = primaryDevice == null ? threadID : DatabaseFactory.getThreadDatabase(context).getThreadIdFor(Recipient.from(context, Address.fromSerialized(primaryDevice), false));
|
long masterThreadID = (masterHexEncodedPublicKey == null) ? threadID : DatabaseFactory.getThreadDatabase(context).getThreadIdFor(Recipient.from(context, Address.fromSerialized(masterHexEncodedPublicKey), false));
|
||||||
FriendRequestHandler.updateLastFriendRequestMessage(context, primaryDeviceThreadID, LokiMessageFriendRequestStatus.REQUEST_ACCEPTED);
|
FriendRequestHandler.updateLastFriendRequestMessage(context, masterThreadID, LokiMessageFriendRequestStatus.REQUEST_ACCEPTED);
|
||||||
});
|
});
|
||||||
return Unit.INSTANCE;
|
return Unit.INSTANCE;
|
||||||
});
|
});
|
||||||
@ -1296,25 +1272,24 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
|
|
||||||
private void updateFriendRequestStatusIfNeeded(@NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message) {
|
private void updateFriendRequestStatusIfNeeded(@NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message) {
|
||||||
if (!content.isFriendRequest() || message.isGroupMessage() || message.isSessionRequest()) { return; }
|
if (!content.isFriendRequest() || message.isGroupMessage() || message.isSessionRequest()) { return; }
|
||||||
// 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, true);
|
becomeFriendsWithContactIfNeeded(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 {
|
||||||
// Do regular friend request logic checks
|
// Do regular friend request logic checks
|
||||||
Recipient originalRecipient = getMessageDestination(content, message);
|
Recipient originalRecipient = getRecipientForMessage(content, message);
|
||||||
Recipient primaryDeviceRecipient = getMessagePrimaryDestination(content, message);
|
Recipient masterRecipient = getMasterRecipientForMessage(content, message);
|
||||||
LokiThreadDatabase lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context);
|
LokiThreadDatabase lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context);
|
||||||
|
|
||||||
// Loki - Friend requests only work in direct chats
|
// Loki - Friend requests only work in direct chats
|
||||||
if (!originalRecipient.getAddress().isPhone()) { return; }
|
if (!originalRecipient.getAddress().isPhone()) { return; }
|
||||||
|
|
||||||
long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(originalRecipient);
|
long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(originalRecipient);
|
||||||
long primaryDeviceThreadID = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(primaryDeviceRecipient);
|
long primaryDeviceThreadID = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(masterRecipient);
|
||||||
LokiThreadFriendRequestStatus threadFriendRequestStatus = lokiThreadDatabase.getFriendRequestStatus(threadID);
|
LokiThreadFriendRequestStatus threadFriendRequestStatus = lokiThreadDatabase.getFriendRequestStatus(threadID);
|
||||||
|
|
||||||
if (threadFriendRequestStatus == LokiThreadFriendRequestStatus.REQUEST_SENT) {
|
if (threadFriendRequestStatus == LokiThreadFriendRequestStatus.REQUEST_SENT) {
|
||||||
@ -1483,7 +1458,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void triggerSessionRestorePrompt(@NonNull String sender) {
|
private void triggerSessionRestorePrompt(@NonNull String sender) {
|
||||||
Recipient primaryRecipient = getPrimaryDeviceRecipient(sender);
|
Recipient primaryRecipient = getMasterRecipient(sender);
|
||||||
if (!primaryRecipient.isGroupRecipient()) {
|
if (!primaryRecipient.isGroupRecipient()) {
|
||||||
long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(primaryRecipient);
|
long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(primaryRecipient);
|
||||||
DatabaseFactory.getLokiThreadDatabase(context).addSessionRestoreDevice(threadID, sender);
|
DatabaseFactory.getLokiThreadDatabase(context).addSessionRestoreDevice(threadID, sender);
|
||||||
@ -1560,11 +1535,11 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
private void handleDeliveryReceipt(@NonNull SignalServiceContent content,
|
private void handleDeliveryReceipt(@NonNull SignalServiceContent content,
|
||||||
@NonNull SignalServiceReceiptMessage message)
|
@NonNull SignalServiceReceiptMessage message)
|
||||||
{
|
{
|
||||||
// Redirect message to primary device conversation
|
// Redirect message to master device conversation
|
||||||
Address sender = Address.fromSerialized(content.getSender());
|
Address sender = Address.fromSerialized(content.getSender());
|
||||||
if (sender.isPhone()) {
|
if (sender.isPhone()) {
|
||||||
Recipient primaryDevice = getPrimaryDeviceRecipient(content.getSender());
|
Recipient masterDevice = getMasterRecipient(content.getSender());
|
||||||
sender = primaryDevice.getAddress();
|
sender = masterDevice.getAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (long timestamp : message.getTimestamps()) {
|
for (long timestamp : message.getTimestamps()) {
|
||||||
@ -1580,11 +1555,11 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
{
|
{
|
||||||
if (TextSecurePreferences.isReadReceiptsEnabled(context)) {
|
if (TextSecurePreferences.isReadReceiptsEnabled(context)) {
|
||||||
|
|
||||||
// Redirect message to primary device conversation
|
// Redirect message to master device conversation
|
||||||
Address sender = Address.fromSerialized(content.getSender());
|
Address sender = Address.fromSerialized(content.getSender());
|
||||||
if (sender.isPhone()) {
|
if (sender.isPhone()) {
|
||||||
Recipient primaryDevice = getPrimaryDeviceRecipient(content.getSender());
|
Recipient masterDevice = getMasterRecipient(content.getSender());
|
||||||
sender = primaryDevice.getAddress();
|
sender = masterDevice.getAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (long timestamp : message.getTimestamps()) {
|
for (long timestamp : message.getTimestamps()) {
|
||||||
@ -1615,7 +1590,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(groupRecipient);
|
threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(groupRecipient);
|
||||||
} else {
|
} else {
|
||||||
// See if we need to redirect the message
|
// See if we need to redirect the message
|
||||||
author = getPrimaryDeviceRecipient(content.getSender());
|
author = getMasterRecipient(content.getSender());
|
||||||
threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(author);
|
threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(author);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1749,9 +1724,9 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Optional<InsertResult> insertPlaceholder(@NonNull String sender, int senderDevice, long timestamp) {
|
private Optional<InsertResult> insertPlaceholder(@NonNull String sender, int senderDevice, long timestamp) {
|
||||||
Recipient primaryDevice = getPrimaryDeviceRecipient(sender);
|
Recipient masterDevice = getMasterRecipient(sender);
|
||||||
SmsDatabase database = DatabaseFactory.getSmsDatabase(context);
|
SmsDatabase database = DatabaseFactory.getSmsDatabase(context);
|
||||||
IncomingTextMessage textMessage = new IncomingTextMessage(primaryDevice.getAddress(),
|
IncomingTextMessage textMessage = new IncomingTextMessage(masterDevice.getAddress(),
|
||||||
senderDevice, timestamp, "",
|
senderDevice, timestamp, "",
|
||||||
Optional.absent(), 0, false);
|
Optional.absent(), 0, false);
|
||||||
|
|
||||||
@ -1771,11 +1746,11 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
if (message.getMessage().isGroupMessage()) {
|
if (message.getMessage().isGroupMessage()) {
|
||||||
return getSyncMessageDestination(message);
|
return getSyncMessageDestination(message);
|
||||||
} else {
|
} else {
|
||||||
return getPrimaryDeviceRecipient(message.getDestination().get());
|
return getMasterRecipient(message.getDestination().get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Recipient getMessageDestination(SignalServiceContent content, SignalServiceDataMessage message) {
|
private Recipient getRecipientForMessage(SignalServiceContent content, SignalServiceDataMessage message) {
|
||||||
if (message.isGroupMessage()) {
|
if (message.isGroupMessage()) {
|
||||||
return Recipient.from(context, Address.fromSerialized(GroupUtil.getEncodedId(message.getGroupInfo().get())), false);
|
return Recipient.from(context, Address.fromSerialized(GroupUtil.getEncodedId(message.getGroupInfo().get())), false);
|
||||||
} else {
|
} else {
|
||||||
@ -1783,34 +1758,34 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Recipient getMessagePrimaryDestination(SignalServiceContent content, SignalServiceDataMessage message) {
|
private Recipient getMasterRecipientForMessage(SignalServiceContent content, SignalServiceDataMessage message) {
|
||||||
if (message.isGroupMessage()) {
|
if (message.isGroupMessage()) {
|
||||||
return getMessageDestination(content, message);
|
return getRecipientForMessage(content, message);
|
||||||
} else {
|
} else {
|
||||||
return getPrimaryDeviceRecipient(content.getSender());
|
return getMasterRecipient(content.getSender());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the primary device recipient of the passed in device.
|
* Get the master device recipient of the provided device.
|
||||||
*
|
*
|
||||||
* If the device doesn't have a primary device then it will return the same device.
|
* If the device doesn't have a master device this will return the same device.
|
||||||
* If the device is our primary device then it will return our current device.
|
* If the device is our master device then it will return our current device.
|
||||||
* Otherwise it will return the primary device.
|
* Otherwise it will return the master device.
|
||||||
*/
|
*/
|
||||||
private Recipient getPrimaryDeviceRecipient(String pubKey) {
|
private Recipient getMasterRecipient(String hexEncodedPublicKey) {
|
||||||
try {
|
try {
|
||||||
String primaryDevice = PromiseUtil.timeout(LokiDeviceLinkUtilities.INSTANCE.getMasterHexEncodedPublicKey(pubKey), 5000).get();
|
String masterHexEncodedPublicKey = PromiseUtil.timeout(LokiDeviceLinkUtilities.INSTANCE.getMasterHexEncodedPublicKey(hexEncodedPublicKey), 5000).get();
|
||||||
String publicKey = (primaryDevice != null) ? primaryDevice : pubKey;
|
String targetHexEncodedPublicKey = (masterHexEncodedPublicKey != null) ? masterHexEncodedPublicKey : hexEncodedPublicKey;
|
||||||
// If the public key matches our primary device then we need to forward the message to ourselves (Note to self)
|
// If the public key matches our master device then we need to forward the message to ourselves (note to self)
|
||||||
String ourPrimaryDevice = TextSecurePreferences.getMasterHexEncodedPublicKey(context);
|
String ourMasterHexEncodedPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(context);
|
||||||
if (ourPrimaryDevice != null && ourPrimaryDevice.equals(publicKey)) {
|
if (ourMasterHexEncodedPublicKey != null && ourMasterHexEncodedPublicKey.equals(targetHexEncodedPublicKey)) {
|
||||||
publicKey = TextSecurePreferences.getLocalNumber(context);
|
targetHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context);
|
||||||
}
|
}
|
||||||
return Recipient.from(context, Address.fromSerialized(publicKey), false);
|
return Recipient.from(context, Address.fromSerialized(targetHexEncodedPublicKey), false);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.d("Loki", "Failed to get primary device public key for " + pubKey + ". " + e.getMessage());
|
Log.d("Loki", "Failed to get master device for: " + hexEncodedPublicKey + ". " + e.getMessage());
|
||||||
return Recipient.from(context, Address.fromSerialized(pubKey), false);
|
return Recipient.from(context, Address.fromSerialized(hexEncodedPublicKey), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1836,7 +1811,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
return false;
|
return false;
|
||||||
} else if (content.getDataMessage().isPresent()) {
|
} else if (content.getDataMessage().isPresent()) {
|
||||||
SignalServiceDataMessage message = content.getDataMessage().get();
|
SignalServiceDataMessage message = content.getDataMessage().get();
|
||||||
Recipient conversation = getMessageDestination(content, message);
|
Recipient conversation = getRecipientForMessage(content, message);
|
||||||
|
|
||||||
if (conversation.isGroupRecipient() && conversation.isBlocked()) {
|
if (conversation.isGroupRecipient() && conversation.isBlocked()) {
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user