Don't send profile in a contact sync message.

This is because both android and desktop first check to see if a sent sync message exists before the check for contact sync. This causes contact sync messages to be ignored.
pull/69/head
Mikunj 5 years ago
parent b2a2cd8d20
commit 3c3d185bec

@ -318,7 +318,12 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId";
- (void)updateWithProfileName:(nullable NSString *)profileName transaction:(YapDatabaseReadWriteTransaction*)transaction
{
[self updateWithProfileName:profileName avatarUrlPath:self.avatarUrlPath avatarFileName:self.avatarFileName transaction:transaction completion:nil];
[self applyChanges:^(OWSUserProfile *userProfile) {
[userProfile setProfileName:profileName];
}
functionName:__PRETTY_FUNCTION__
transaction:transaction
completion:nil];
}
- (void)updateWithAvatarUrlPath:(NSString *)avatarUrlPath transaction:(YapDatabaseReadWriteTransaction*)transaction completion:(nullable OWSUserProfileCompletion)completion {

@ -1,6 +1,9 @@
#import "LKDeviceLinkMessage.h"
#import "OWSIdentityManager.h"
#import "OWSPrimaryStorage+Loki.h"
#import "ProfileManagerProtocol.h"
#import "ProtoUtils.h"
#import "SSKEnvironment.h"
#import "SignalRecipient.h"
#import <SignalCoreKit/NSData+OWS.h>
#import <SignalCoreKit/NSDate+OWS.h>
@ -45,6 +48,18 @@
} else {
[contentBuilder setPrekeyBundleMessage:preKeyBundleMessage];
}
} else {
// Loki: Set display name & profile picture
id<ProfileManagerProtocol> profileManager = SSKEnvironment.shared.profileManager;
NSString *displayName = profileManager.localProfileName;
NSString *profilePictureURL = profileManager.profilePictureURL;
SSKProtoDataMessageLokiProfileBuilder *profileBuilder = [SSKProtoDataMessageLokiProfile builder];
[profileBuilder setDisplayName:displayName];
[profileBuilder setProfilePicture:profilePictureURL ?: @""];
SSKProtoDataMessageBuilder *messageBuilder = [SSKProtoDataMessage builder];
[messageBuilder setProfile:[profileBuilder buildAndReturnError:nil]];
[ProtoUtils addLocalProfileKeyToDataMessageBuilder:messageBuilder];
[contentBuilder setDataMessage:messageBuilder];
}
// Build the device link message
SSKProtoLokiDeviceLinkMessageBuilder *deviceLinkMessageBuilder = [SSKProtoLokiDeviceLinkMessage builder];

@ -103,21 +103,6 @@ NS_ASSUME_NONNULL_BEGIN
SSKProtoSyncMessageBuilder *syncMessageBuilder = [SSKProtoSyncMessage builder];
[syncMessageBuilder setContacts:contactsProto];
// Loki: Set display name & profile picture
id<ProfileManagerProtocol> profileManager = SSKEnvironment.shared.profileManager;
NSString *displayName = profileManager.localProfileName;
NSString *profilePictureURL = profileManager.profilePictureURL;
SSKProtoDataMessageLokiProfileBuilder *profileBuilder = [SSKProtoDataMessageLokiProfile builder];
[profileBuilder setDisplayName:displayName];
[profileBuilder setProfilePicture:profilePictureURL ?: @""];
SSKProtoDataMessageBuilder *messageBuilder = [SSKProtoDataMessage builder];
[messageBuilder setProfile:[profileBuilder buildAndReturnError:nil]];
[ProtoUtils addLocalProfileKeyToDataMessageBuilder:messageBuilder];
SSKProtoSyncMessageSentBuilder *transcriptBuilder = [SSKProtoSyncMessageSent builder];
[transcriptBuilder setMessage:[messageBuilder buildAndReturnError:nil]];
[syncMessageBuilder setSent:[transcriptBuilder buildAndReturnError:nil]];
return syncMessageBuilder;
}

@ -438,22 +438,7 @@ NS_ASSUME_NONNULL_BEGIN
BOOL isDuplicate = [LKAPI isDuplicateSyncMessage:contentProto.syncMessage.sent from:envelope.source];
if (isDuplicate) { return; }
}
// Loki: Handle device linking message if needed
if (contentProto.lokiDeviceLinkMessage != nil) {
NSString *masterHexEncodedPublicKey = contentProto.lokiDeviceLinkMessage.masterHexEncodedPublicKey;
NSString *slaveHexEncodedPublicKey = contentProto.lokiDeviceLinkMessage.slaveHexEncodedPublicKey;
NSData *masterSignature = contentProto.lokiDeviceLinkMessage.masterSignature;
NSData *slaveSignature = contentProto.lokiDeviceLinkMessage.slaveSignature;
if (masterSignature != nil) { // Authorization
OWSLogInfo(@"[Loki] Received a device linking authorization from: %@", envelope.source); // Not masterHexEncodedPublicKey
[LKDeviceLinkingSession.current processLinkingAuthorizationFrom:masterHexEncodedPublicKey for:slaveHexEncodedPublicKey masterSignature:masterSignature slaveSignature:slaveSignature];
} else if (slaveSignature != nil) { // Request
OWSLogInfo(@"[Loki] Received a device linking request from: %@", envelope.source); // Not slaveHexEncodedPublicKey
[LKDeviceLinkingSession.current processLinkingRequestFrom:slaveHexEncodedPublicKey to:masterHexEncodedPublicKey with:slaveSignature];
}
}
// Loki: Handle pre key bundle message if needed
if (contentProto.prekeyBundleMessage != nil) {
OWSLogInfo(@"[Loki] Received a pre key bundle message from: %@.", envelope.source);
@ -471,7 +456,25 @@ NS_ASSUME_NONNULL_BEGIN
[LKP2PAPI didReceiveLokiAddressMessageForContact:envelope.source address:address port:port receivedThroughP2P:envelope.isPtpMessage];
}
if (contentProto.syncMessage) {
// Loki: Handle device linking message if needed
if (contentProto.lokiDeviceLinkMessage != nil) {
NSString *masterHexEncodedPublicKey = contentProto.lokiDeviceLinkMessage.masterHexEncodedPublicKey;
NSString *slaveHexEncodedPublicKey = contentProto.lokiDeviceLinkMessage.slaveHexEncodedPublicKey;
NSData *masterSignature = contentProto.lokiDeviceLinkMessage.masterSignature;
NSData *slaveSignature = contentProto.lokiDeviceLinkMessage.slaveSignature;
if (masterSignature != nil) { // Authorization
OWSLogInfo(@"[Loki] Received a device linking authorization from: %@", envelope.source); // Not masterHexEncodedPublicKey
[LKDeviceLinkingSession.current processLinkingAuthorizationFrom:masterHexEncodedPublicKey for:slaveHexEncodedPublicKey masterSignature:masterSignature slaveSignature:slaveSignature];
// Set any profile information
if (contentProto.dataMessage) {
[self handleLokiProfileForUserIfNeeded:contentProto.dataMessage transaction:transaction];
}
} else if (slaveSignature != nil) { // Request
OWSLogInfo(@"[Loki] Received a device linking request from: %@", envelope.source); // Not slaveHexEncodedPublicKey
[LKDeviceLinkingSession.current processLinkingRequestFrom:slaveHexEncodedPublicKey to:masterHexEncodedPublicKey with:slaveSignature];
}
} else if (contentProto.syncMessage) {
[self throws_handleIncomingEnvelope:envelope
withSyncMessage:contentProto.syncMessage
transaction:transaction
@ -915,109 +918,66 @@ NS_ASSUME_NONNULL_BEGIN
OWSProdErrorWEnvelope([OWSAnalyticsEvents messageManagerErrorSyncMessageFromUnknownSource], envelope);
return;
}
NSString *masterHexEncodedPublicKey = [LKDatabaseUtilities getMasterHexEncodedPublicKeyFor:userHexEncodedPublicKey in:transaction];
BOOL wasSentByMasterDevice = [masterHexEncodedPublicKey isEqual:envelope.source];
if (syncMessage.sent) {
NSString *userHexEncodedPublicKey = OWSIdentityManager.sharedManager.identityKeyPair.hexEncodedPublicKey;
NSString *masterHexEncodedPublicKey = [LKDatabaseUtilities getMasterHexEncodedPublicKeyFor:userHexEncodedPublicKey in:transaction];
BOOL wasSentByMasterDevice = [masterHexEncodedPublicKey isEqual:envelope.source];
// Loki: Try to update using the provided profile
if (wasSentByMasterDevice) {
dispatch_async(dispatch_get_main_queue(), ^{
SSKProtoDataMessage *dataMessage = syncMessage.sent.message;
SSKProtoDataMessageLokiProfile *profile = dataMessage.profile;
NSString *displayName = profile.displayName;
NSString *profilePictureURL = profile.profilePicture;
[self.profileManager updateUserProfileWithDisplayName:displayName transaction:transaction];
if ([dataMessage hasProfileKey]) {
[self.profileManager updateUserProfileKeyData:dataMessage.profileKey avatarURL:profilePictureURL transaction:transaction];
}
});
[self handleLokiProfileForUserIfNeeded:syncMessage.sent.message transaction:transaction];
}
// Loki: Handle contact sync if needed
if (syncMessage.contacts != nil) {
if (wasSentByMasterDevice) {
NSLog(@"[Loki] Received contact sync message.");
NSData *data = syncMessage.contacts.data;
ContactParser *parser = [[ContactParser alloc] initWithData:data];
NSArray<NSString *> *hexEncodedPublicKeys = [parser parseHexEncodedPublicKeys];
// Try to establish sessions
for (NSString *hexEncodedPublicKey in hexEncodedPublicKeys) {
TSContactThread *thread = [TSContactThread getOrCreateThreadWithContactId:hexEncodedPublicKey transaction:transaction];
LKThreadFriendRequestStatus friendRequestStatus = thread.friendRequestStatus;
switch (friendRequestStatus) {
case LKThreadFriendRequestStatusNone: {
OWSMessageSender *messageSender = SSKEnvironment.shared.messageSender;
OWSMessageSend *automatedFriendRequestMessage = [messageSender getMultiDeviceFriendRequestMessageForHexEncodedPublicKey:hexEncodedPublicKey];
dispatch_async(OWSDispatch.sendingQueue, ^{
[messageSender sendMessage:automatedFriendRequestMessage];
});
break;
}
case LKThreadFriendRequestStatusRequestReceived: {
[thread saveFriendRequestStatus:LKThreadFriendRequestStatusFriends withTransaction:transaction];
// The two lines below are equivalent to calling [ThreadUtil enqueueFriendRequestAcceptanceMessageInThread:thread]
LKEphemeralMessage *backgroundMessage = [[LKEphemeralMessage alloc] initInThread:thread];
[self.messageSenderJobQueue addMessage:backgroundMessage transaction:transaction];
break;
}
default: break; // Do nothing
OWSIncomingSentMessageTranscript *transcript =
[[OWSIncomingSentMessageTranscript alloc] initWithProto:syncMessage.sent transaction:transaction];
SSKProtoDataMessage *_Nullable dataMessage = syncMessage.sent.message;
if (!dataMessage) {
OWSFailDebug(@"Missing dataMessage.");
return;
}
NSString *destination = syncMessage.sent.destination;
if (dataMessage && destination.length > 0 && dataMessage.hasProfileKey) {
// If we observe a linked device sending our profile key to another
// user, we can infer that that user belongs in our profile whitelist.
if (dataMessage.group) {
[self.profileManager addGroupIdToProfileWhitelist:dataMessage.group.id];
} else {
[self.profileManager addUserToProfileWhitelist:destination];
}
}
if ([self isDataMessageGroupAvatarUpdate:syncMessage.sent.message] && !syncMessage.sent.isRecipientUpdate) {
[OWSRecordTranscriptJob
processIncomingSentMessageTranscript:transcript
serverID:0
attachmentHandler:^(NSArray<TSAttachmentStream *> *attachmentStreams) {
OWSAssertDebug(attachmentStreams.count == 1);
TSAttachmentStream *attachmentStream = attachmentStreams.firstObject;
[self.dbConnection readWriteWithBlock:^(
YapDatabaseReadWriteTransaction *transaction) {
TSGroupThread *_Nullable groupThread =
[TSGroupThread threadWithGroupId:dataMessage.group.id
transaction:transaction];
if (!groupThread) {
OWSFailDebug(@"ignoring sync group avatar update for unknown group.");
return;
}
}
[groupThread updateAvatarWithAttachmentStream:attachmentStream
transaction:transaction];
}];
}
transaction:transaction];
} else {
OWSIncomingSentMessageTranscript *transcript =
[[OWSIncomingSentMessageTranscript alloc] initWithProto:syncMessage.sent transaction:transaction];
SSKProtoDataMessage *_Nullable dataMessage = syncMessage.sent.message;
if (!dataMessage) {
OWSFailDebug(@"Missing dataMessage.");
return;
}
NSString *destination = syncMessage.sent.destination;
if (dataMessage && destination.length > 0 && dataMessage.hasProfileKey) {
// If we observe a linked device sending our profile key to another
// user, we can infer that that user belongs in our profile whitelist.
if (dataMessage.group) {
[self.profileManager addGroupIdToProfileWhitelist:dataMessage.group.id];
} else {
[self.profileManager addUserToProfileWhitelist:destination];
}
}
if ([self isDataMessageGroupAvatarUpdate:syncMessage.sent.message] && !syncMessage.sent.isRecipientUpdate) {
[OWSRecordTranscriptJob
processIncomingSentMessageTranscript:transcript
serverID:0
attachmentHandler:^(NSArray<TSAttachmentStream *> *attachmentStreams) {
OWSAssertDebug(attachmentStreams.count == 1);
TSAttachmentStream *attachmentStream = attachmentStreams.firstObject;
[self.dbConnection readWriteWithBlock:^(
YapDatabaseReadWriteTransaction *transaction) {
TSGroupThread *_Nullable groupThread =
[TSGroupThread threadWithGroupId:dataMessage.group.id
transaction:transaction];
if (!groupThread) {
OWSFailDebug(@"ignoring sync group avatar update for unknown group.");
return;
}
[groupThread updateAvatarWithAttachmentStream:attachmentStream
transaction:transaction];
}];
}
transaction:transaction];
} else {
[OWSRecordTranscriptJob
processIncomingSentMessageTranscript:transcript
serverID:serverID
attachmentHandler:^(NSArray<TSAttachmentStream *> *attachmentStreams) {
OWSLogDebug(@"successfully fetched transcript attachments: %lu",
(unsigned long)attachmentStreams.count);
}
transaction:transaction];
[OWSRecordTranscriptJob
processIncomingSentMessageTranscript:transcript
serverID:serverID
attachmentHandler:^(NSArray<TSAttachmentStream *> *attachmentStreams) {
OWSLogDebug(@"successfully fetched transcript attachments: %lu",
(unsigned long)attachmentStreams.count);
}
transaction:transaction];
}
} else if (syncMessage.request) {
if (syncMessage.request.type == SSKProtoSyncMessageRequestTypeContacts) {
@ -1066,11 +1026,53 @@ NS_ASSUME_NONNULL_BEGIN
} else if (syncMessage.verified) {
OWSLogInfo(@"Received verification state for %@", syncMessage.verified.destination);
[self.identityManager throws_processIncomingSyncMessage:syncMessage.verified transaction:transaction];
} else if (syncMessage.contacts != nil) {
if (false && wasSentByMasterDevice && syncMessage.contacts.data.length > 0) {
NSLog(@"[Loki] Received contact sync message.");
NSData *data = syncMessage.contacts.data;
ContactParser *parser = [[ContactParser alloc] initWithData:data];
NSArray<NSString *> *hexEncodedPublicKeys = [parser parseHexEncodedPublicKeys];
// Try to establish sessions
for (NSString *hexEncodedPublicKey in hexEncodedPublicKeys) {
TSContactThread *thread = [TSContactThread getOrCreateThreadWithContactId:hexEncodedPublicKey transaction:transaction];
LKThreadFriendRequestStatus friendRequestStatus = thread.friendRequestStatus;
switch (friendRequestStatus) {
case LKThreadFriendRequestStatusNone: {
OWSMessageSender *messageSender = SSKEnvironment.shared.messageSender;
OWSMessageSend *automatedFriendRequestMessage = [messageSender getMultiDeviceFriendRequestMessageForHexEncodedPublicKey:hexEncodedPublicKey];
dispatch_async(OWSDispatch.sendingQueue, ^{
[messageSender sendMessage:automatedFriendRequestMessage];
});
break;
}
case LKThreadFriendRequestStatusRequestReceived: {
[thread saveFriendRequestStatus:LKThreadFriendRequestStatusFriends withTransaction:transaction];
// The two lines below are equivalent to calling [ThreadUtil enqueueFriendRequestAcceptanceMessageInThread:thread]
LKEphemeralMessage *backgroundMessage = [[LKEphemeralMessage alloc] initInThread:thread];
[self.messageSenderJobQueue addMessage:backgroundMessage transaction:transaction];
break;
}
default: break; // Do nothing
}
}
}
} else {
OWSLogWarn(@"Ignoring unsupported sync message.");
}
}
- (void)handleLokiProfileForUserIfNeeded:(SSKProtoDataMessage *)dataMessage transaction:(YapDatabaseReadWriteTransaction *)transaction {
if (dataMessage.profile != nil) {
SSKProtoDataMessageLokiProfile *profile = dataMessage.profile;
NSString *displayName = profile.displayName;
NSString *profilePictureURL = profile.profilePicture;
[self.profileManager updateUserProfileWithDisplayName:displayName transaction:transaction];
if ([dataMessage hasProfileKey]) {
[self.profileManager updateUserProfileKeyData:dataMessage.profileKey avatarURL:profilePictureURL transaction:transaction];
}
}
}
- (void)handleEndSessionMessageWithEnvelope:(SSKProtoEnvelope *)envelope
dataMessage:(SSKProtoDataMessage *)dataMessage
transaction:(YapDatabaseReadWriteTransaction *)transaction

Loading…
Cancel
Save