|
|
|
@ -925,56 +925,103 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (syncMessage.sent) {
|
|
|
|
|
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];
|
|
|
|
|
}
|
|
|
|
|
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(), ^{
|
|
|
|
|
SSKProtoDataMessageLokiProfile *profile = syncMessage.sent.message.profile;
|
|
|
|
|
NSString *displayName = profile.displayName;
|
|
|
|
|
NSString *profilePictureURL = profile.profilePicture;
|
|
|
|
|
[self.profileManager updateUserProfileWithDisplayName:displayName profilePictureURL:profilePictureURL transaction:transaction];
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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];
|
|
|
|
|
// 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
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
[OWSRecordTranscriptJob
|
|
|
|
|
processIncomingSentMessageTranscript:transcript
|
|
|
|
|
serverID:serverID
|
|
|
|
|
attachmentHandler:^(NSArray<TSAttachmentStream *> *attachmentStreams) {
|
|
|
|
|
OWSLogDebug(@"successfully fetched transcript attachments: %lu",
|
|
|
|
|
(unsigned long)attachmentStreams.count);
|
|
|
|
|
}
|
|
|
|
|
transaction:transaction];
|
|
|
|
|
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];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (syncMessage.request) {
|
|
|
|
|
if (syncMessage.request.type == SSKProtoSyncMessageRequestTypeContacts) {
|
|
|
|
@ -1023,34 +1070,6 @@ 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) {
|
|
|
|
|
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.");
|
|
|
|
|
}
|
|
|
|
|