This commit is contained in:
Niels Andriesse 2019-11-27 16:26:15 +11:00
parent 4d3954be19
commit ba8c3b1859
7 changed files with 126 additions and 78 deletions

View File

@ -165,6 +165,11 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate {
let deviceLink = self.deviceLink!
let linkingAuthorizationMessage = DeviceLinkingUtilities.getLinkingAuthorizationMessage(for: deviceLink)
ThreadUtil.enqueue(linkingAuthorizationMessage)
SSKEnvironment.shared.messageSender.send(linkingAuthorizationMessage, success: {
let _ = SSKEnvironment.shared.syncManager.syncAllContacts()
}) { _ in
print("[Loki] Failed to send device link authorization message.")
}
let session = DeviceLinkingSession.current!
session.stopListeningForLinkingRequests()
session.markLinkingRequestAsProcessed()
@ -176,9 +181,6 @@ final class DeviceLinkingModal : Modal, DeviceLinkingSessionDelegate {
}.catch { error in
print("[Loki] Failed to add device link due to error: \(error).")
}
Timer.scheduledTimer(withTimeInterval: 8, repeats: false) { _ in
let _ = SSKEnvironment.shared.syncManager.syncAllContacts()
}
}
func handleDeviceLinkAuthorized(_ deviceLink: DeviceLink) {

View File

@ -340,6 +340,11 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error);
}
}
- (void)updateUserProfileWithDisplayName:(nullable NSString*)displayName profilePictureURL:(nullable NSString*)profilePictureURL transaction:(YapDatabaseReadWriteTransaction *)transaction
{
[self updateLocalProfileName:displayName avatarImage:nil success:^{ } failure:^{ }];
}
- (nullable NSString *)profilePictureURL
{
return self.localUserProfile.avatarUrlPath;

View File

@ -266,6 +266,8 @@ public final class LokiAPI : NSObject {
@objc public static func isDuplicateSyncMessage(_ syncMessage: SSKProtoSyncMessageSent, from hexEncodedPublicKey: String) -> Bool {
var timestamps: Set<UInt64> = syncMessageTimestamps[hexEncodedPublicKey] ?? []
let hasTimestamp = syncMessage.timestamp != 0
guard hasTimestamp else { return false }
let result = timestamps.contains(syncMessage.timestamp)
timestamps.insert(syncMessage.timestamp)
syncMessageTimestamps[hexEncodedPublicKey] = timestamps

View File

@ -101,6 +101,20 @@ 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]];
SSKProtoSyncMessageSentBuilder *transcriptBuilder = [SSKProtoSyncMessageSent builder];
[transcriptBuilder setMessage:[messageBuilder buildAndReturnError:nil]];
[syncMessageBuilder setSent:[transcriptBuilder buildAndReturnError:nil]];
return syncMessageBuilder;
}

View File

@ -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 *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];
});
}
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];
// 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
}
}
}
}
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];
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.");
}

View File

@ -17,6 +17,7 @@ NS_ASSUME_NONNULL_BEGIN
- (nullable NSString *)profilePictureURL;
- (nullable NSData *)profileKeyDataForRecipientId:(NSString *)recipientId;
- (void)updateUserProfileWithDisplayName:(nullable NSString*)displayName profilePictureURL:(nullable NSString*)profilePictureURL transaction:(YapDatabaseReadWriteTransaction *)transaction;
- (void)setProfileKeyData:(NSData *)profileKeyData forRecipientId:(NSString *)recipientId;
- (BOOL)isUserInProfileWhitelist:(NSString *)recipientId;

View File

@ -48,6 +48,11 @@ NS_ASSUME_NONNULL_BEGIN
return _localProfileKey;
}
- (void)updateUserProfileWithDisplayName:(nullable NSString*)displayName profilePictureURL:(nullable NSString*)profilePictureURL transaction:(YapDatabaseReadWriteTransaction *)transaction
{
// Do nothing
}
- (void)setProfileKeyData:(NSData *)profileKey forRecipientId:(NSString *)recipientId
{
OWSAES256Key *_Nullable key = [OWSAES256Key keyWithData:profileKey];