diff --git a/SignalMessaging/utils/ThreadUtil.h b/SignalMessaging/utils/ThreadUtil.h index 843758b2f..ec5070d1f 100644 --- a/SignalMessaging/utils/ThreadUtil.h +++ b/SignalMessaging/utils/ThreadUtil.h @@ -46,9 +46,7 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - Durable Message Enqueue -+ (TSOutgoingMessage *)enqueueFriendRequestAcceptanceMessageInThread:(TSThread *)thread; + (void)enqueueDeviceLinkMessage:(LKDeviceLinkMessage *)message; -+ (void)enqueueUnlinkDeviceMessage:(LKUnlinkDeviceMessage *)message; + (TSOutgoingMessage *)enqueueMessageWithText:(NSString *)fullMessageText inThread:(TSThread *)thread diff --git a/SignalMessaging/utils/ThreadUtil.m b/SignalMessaging/utils/ThreadUtil.m index bd0510f6a..33b3795c5 100644 --- a/SignalMessaging/utils/ThreadUtil.m +++ b/SignalMessaging/utils/ThreadUtil.m @@ -85,15 +85,6 @@ typedef void (^BuildOutgoingMessageCompletionBlock)(TSOutgoingMessage *savedMess #pragma mark - Durable Message Enqueue -+ (LKEphemeralMessage *)enqueueFriendRequestAcceptanceMessageInThread:(TSThread *)thread -{ - LKEphemeralMessage *message = [[LKEphemeralMessage alloc] initInThread:thread]; - [self.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [self.messageSenderJobQueue addMessage:message transaction:transaction]; - }]; - return message; -} - + (void)enqueueDeviceLinkMessage:(LKDeviceLinkMessage *)message { [self.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { @@ -101,13 +92,6 @@ typedef void (^BuildOutgoingMessageCompletionBlock)(TSOutgoingMessage *savedMess }]; } -+ (void)enqueueUnlinkDeviceMessage:(LKUnlinkDeviceMessage *)message -{ - [self.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [self.messageSenderJobQueue addMessage:message transaction:transaction]; - }]; -} - + (TSOutgoingMessage *)enqueueMessageWithText:(NSString *)fullMessageText inThread:(TSThread *)thread quotedReplyModel:(nullable OWSQuotedReplyModel *)quotedReplyModel diff --git a/SignalServiceKit/src/Account/PreKeyRefreshOperation.swift b/SignalServiceKit/src/Account/PreKeyRefreshOperation.swift index d859dfa7a..6a2be9e71 100644 --- a/SignalServiceKit/src/Account/PreKeyRefreshOperation.swift +++ b/SignalServiceKit/src/Account/PreKeyRefreshOperation.swift @@ -38,20 +38,7 @@ public class RefreshPreKeysOperation: OWSOperation { // Loki: Doing this on the global queue to match Signal DispatchQueue.global().async { - guard self.primaryStorage.currentSignedPrekeyId() == nil else { - print("[Loki] Skipping pre key refresh; using existing signed pre key.") - return self.reportSuccess() - } - - let signedPreKeyRecord = self.primaryStorage.generateRandomSignedRecord() - signedPreKeyRecord.markAsAcceptedByService() - self.primaryStorage.storeSignedPreKey(signedPreKeyRecord.id, signedPreKeyRecord: signedPreKeyRecord) - self.primaryStorage.setCurrentSignedPrekeyId(signedPreKeyRecord.id) - - TSPreKeyManager.clearPreKeyUpdateFailureCount() - TSPreKeyManager.clearSignedPreKeyRecords() - - print("[Loki] Pre keys refreshed successfully.") + SessionProtocol.refreshPreKeys() self.reportSuccess() } diff --git a/SignalServiceKit/src/Account/RotateSignedKeyOperation.swift b/SignalServiceKit/src/Account/RotateSignedKeyOperation.swift index c99cb3733..fbbc97de7 100644 --- a/SignalServiceKit/src/Account/RotateSignedKeyOperation.swift +++ b/SignalServiceKit/src/Account/RotateSignedKeyOperation.swift @@ -29,15 +29,7 @@ public class RotateSignedPreKeyOperation: OWSOperation { // Loki: Doing this on the global queue to match Signal DispatchQueue.global().async { - let signedPreKeyRecord = self.primaryStorage.generateRandomSignedRecord() - signedPreKeyRecord.markAsAcceptedByService() - self.primaryStorage.storeSignedPreKey(signedPreKeyRecord.id, signedPreKeyRecord: signedPreKeyRecord) - self.primaryStorage.setCurrentSignedPrekeyId(signedPreKeyRecord.id) - - TSPreKeyManager.clearPreKeyUpdateFailureCount() - TSPreKeyManager.clearSignedPreKeyRecords() - - print("[Loki] Pre keys rotated successfully.") + SessionProtocol.rotatePreKeys() self.reportSuccess() } diff --git a/SignalServiceKit/src/Contacts/TSThread.m b/SignalServiceKit/src/Contacts/TSThread.m index 59860ed44..8aebd14af 100644 --- a/SignalServiceKit/src/Contacts/TSThread.m +++ b/SignalServiceKit/src/Contacts/TSThread.m @@ -216,10 +216,7 @@ ConversationColorName const kConversationColorName_Default = ConversationColorNa if (!IsNoteToSelfEnabled()) { return NO; } - NSString *localNumber = self.tsAccountManager.localNumber; - NSString *masterDeviceHexEncodedPublicKey = [NSUserDefaults.standardUserDefaults stringForKey:@"masterDeviceHexEncodedPublicKey"]; - bool isOurNumber = [self.contactIdentifier isEqualToString:localNumber] || (masterDeviceHexEncodedPublicKey != nil && [self.contactIdentifier isEqualToString:masterDeviceHexEncodedPublicKey]); - return (!self.isGroupThread && self.contactIdentifier != nil && isOurNumber); + return [SessionProtocol isMessageNoteToSelf:self]; } #pragma mark - To be subclassed. diff --git a/SignalServiceKit/src/Loki/Messaging/SessionProtocol+Receiving.swift b/SignalServiceKit/src/Loki/Messaging/SessionProtocol+Receiving.swift index 6fa4cf4c0..bd7f27135 100644 --- a/SignalServiceKit/src/Loki/Messaging/SessionProtocol+Receiving.swift +++ b/SignalServiceKit/src/Loki/Messaging/SessionProtocol+Receiving.swift @@ -27,7 +27,29 @@ public extension SessionProtocol { /// Only ever modified from the message processing queue (`OWSBatchMessageProcessor.processingQueue`). private static var syncMessageTimestamps: [String:Set<UInt64>] = [:] + // MARK: - General + @objc(shouldSkipMessageDecryptResult:) + public static func shouldSkipMessageDecryptResult(_ result: OWSMessageDecryptResult) -> Bool { + // Called from OWSMessageReceiver to prevent messages from even being added to the processing queue for some reason + return result.source == getUserHexEncodedPublicKey() // NOTE: This doesn't take into account multi device + } + // MARK: - Session Handling + @objc(handleDecryptionError:forHexEncodedPublicKey:using:) + public static func handleDecryptionError(_ rawValue: Int32, for hexEncodedPublicKey: String, using transaction: YapDatabaseReadWriteTransaction) { + let type = TSErrorMessageType(rawValue: rawValue) + let masterHexEncodedPublicKey = storage.getMasterHexEncodedPublicKey(for: hexEncodedPublicKey, in: transaction) ?? hexEncodedPublicKey + let thread = TSContactThread.getOrCreateThread(withContactId: masterHexEncodedPublicKey, transaction: transaction) + // Show the session reset prompt upon certain errors + switch type { + case .noSession, .invalidMessage, .invalidKeyException: + // Store the source device's public key in case it was a secondary device + thread.addSessionRestoreDevice(hexEncodedPublicKey, transaction: transaction) + default: break + } + + } + @objc(isSessionRestoreMessage:) public static func isSessionRestoreMessage(_ dataMessage: SSKProtoDataMessage) -> Bool { let sessionRestoreFlag = SSKProtoDataMessage.SSKProtoDataMessageFlags.sessionRestore diff --git a/SignalServiceKit/src/Loki/Messaging/SessionProtocol+Sending.swift b/SignalServiceKit/src/Loki/Messaging/SessionProtocol+Sending.swift index 4200fa699..1dd9380bf 100644 --- a/SignalServiceKit/src/Loki/Messaging/SessionProtocol+Sending.swift +++ b/SignalServiceKit/src/Loki/Messaging/SessionProtocol+Sending.swift @@ -54,6 +54,16 @@ public extension SessionProtocol { // TODO: Check that the behaviors described above make sense + @objc(isMessageNoteToSelf:) + public static func isMessageNoteToSelf(_ thread: TSThread) -> Bool { + guard let thread = thread as? TSContactThread else { return false } + var isNoteToSelf = false + storage.dbReadConnection.read { transaction in + isNoteToSelf = LokiDatabaseUtilities.isUserLinkedDevice(thread.contactIdentifier(), transaction: transaction) + } + return isNoteToSelf + } + @objc(isMessageNoteToSelf:inThread:) public static func isMessageNoteToSelf(_ message: TSOutgoingMessage, in thread: TSThread) -> Bool { guard let thread = thread as? TSContactThread, !(message is OWSOutgoingSyncMessage) && !(message is DeviceLinkMessage) else { return false } @@ -314,6 +324,30 @@ public extension SessionProtocol { + // MARK: - Typing Indicators + public static func shouldSendTypingIndicator(for thread: TSThread) -> Bool { + return !thread.isGroupThread() && !isMessageNoteToSelf(thread) + } + + + + // MARK: - Receipts + // Used from OWSReadReceiptManager + @objc(shouldSendReadReceiptForThread:) + public static func shouldSendReadReceipt(for thread: TSThread) -> Bool { + return !isMessageNoteToSelf(thread) && !thread.isGroupThread() + } + + // TODO: Not sure how these two relate + + // Used from OWSOutgoingReceiptManager + @objc(shouldSendReceiptForThread:) + public static func shouldSendReceipt(for thread: TSThread) -> Bool { + return thread.friendRequestStatus == .friends && !thread.isGroupThread() + } + + + // MARK: - Sessions // BEHAVIOR NOTE: OWSMessageSender.throws_encryptedMessageForMessageSend:recipientId:plaintext:transaction: sets // isFriendRequest to true if the message in question is a friend request or a device linking request, but NOT if @@ -321,6 +355,42 @@ public extension SessionProtocol { // TODO: Does the above make sense? + public static func createPreKeys() { + // We don't generate PreKeyRecords here. + // This is because we need the records to be linked to a contact since we don't have a central server. + // It's done automatically when we generate a pre key bundle to send to a contact (`generatePreKeyBundleForContact:`). + // You can use `getOrCreatePreKeyForContact:` to generate one if needed. + let signedPreKeyRecord = storage.generateRandomSignedRecord() + signedPreKeyRecord.markAsAcceptedByService() + storage.storeSignedPreKey(signedPreKeyRecord.id, signedPreKeyRecord: signedPreKeyRecord) + storage.setCurrentSignedPrekeyId(signedPreKeyRecord.id) + print("[Loki] Pre keys created successfully.") + } + + public static func refreshPreKeys() { + guard storage.currentSignedPrekeyId() == nil else { + print("[Loki] Skipping pre key refresh; using existing signed pre key.") + return + } + let signedPreKeyRecord = storage.generateRandomSignedRecord() + signedPreKeyRecord.markAsAcceptedByService() + storage.storeSignedPreKey(signedPreKeyRecord.id, signedPreKeyRecord: signedPreKeyRecord) + storage.setCurrentSignedPrekeyId(signedPreKeyRecord.id) + TSPreKeyManager.clearPreKeyUpdateFailureCount() + TSPreKeyManager.clearSignedPreKeyRecords() + print("[Loki] Pre keys refreshed successfully.") + } + + public static func rotatePreKeys() { + let signedPreKeyRecord = storage.generateRandomSignedRecord() + signedPreKeyRecord.markAsAcceptedByService() + storage.storeSignedPreKey(signedPreKeyRecord.id, signedPreKeyRecord: signedPreKeyRecord) + storage.setCurrentSignedPrekeyId(signedPreKeyRecord.id) + TSPreKeyManager.clearPreKeyUpdateFailureCount() + TSPreKeyManager.clearSignedPreKeyRecords() + print("[Loki] Pre keys rotated successfully.") + } + public static func shouldUseFallbackEncryption(_ message: TSOutgoingMessage) -> Bool { return !isSessionRequired(for: message) } diff --git a/SignalServiceKit/src/Messages/Interactions/OWSLinkPreview.swift b/SignalServiceKit/src/Messages/Interactions/OWSLinkPreview.swift index 5a865f5b9..15e75f922 100644 --- a/SignalServiceKit/src/Messages/Interactions/OWSLinkPreview.swift +++ b/SignalServiceKit/src/Messages/Interactions/OWSLinkPreview.swift @@ -696,65 +696,6 @@ public class OWSLinkPreview: MTLModel { }) return promise } - - public class func getImagePreview(from url: String, in transaction: YapDatabaseReadWriteTransaction) -> Promise<OWSLinkPreview> { - // Get the MIME type - guard let imageFileExtension = fileExtension(forImageUrl: url), let imageMIMEType = mimetype(forImageFileExtension: imageFileExtension) else { - return Promise(error: LinkPreviewError.invalidInput) - } - - return downloadImage(url: url).map { data in - // Make sure the downloaded image has the correct MIME type - guard let newImageMIMEType = NSData(data: data).ows_guessMimeType() else { - throw LinkPreviewError.invalidContent - } - - // Save the attachment - guard let attachmentId = saveAttachmentIfPossible(imageData: data, mimeType: newImageMIMEType, transaction: transaction) else { - Logger.verbose("Failed to save attachment for: \(url).") - throw LinkPreviewError.attachmentFailedToSave - } - - // If it's a GIF and the data we have is not a GIF then we need to render a link preview without attachments - if (imageMIMEType == OWSMimeTypeImageGif && newImageMIMEType != OWSMimeTypeImageGif) { - return OWSLinkPreview(urlString: url, title: nil, imageAttachmentId: attachmentId) - } - - return OWSLinkPreview(urlString: url, title: nil, imageAttachmentId: attachmentId, isDirectAttachment: true) - } - } - - @objc(getImagePreviewWithURL:transaction:) - public class func objc_getImagePreview(url: String, in transaction: YapDatabaseReadWriteTransaction) -> AnyPromise { - return AnyPromise.from(getImagePreview(from: url, in: transaction)) - } - - public class func downloadImage(url imageUrl: String) -> Promise<Data> { - guard OWSLinkPreview.featureEnabled else { - return Promise(error: LinkPreviewError.featureDisabled) - } - - guard SSKPreferences.areLinkPreviewsEnabled else { - return Promise(error: LinkPreviewError.featureDisabled) - } - - guard isValidMediaUrl(imageUrl) else { - Logger.error("Invalid image URL.") - return Promise.init(error: LinkPreviewError.invalidInput) - } - - guard let imageFileExtension = fileExtension(forImageUrl: imageUrl) else { - Logger.error("Image URL has unknown or invalid file extension: \(imageUrl).") - return Promise.init(error: LinkPreviewError.invalidInput) - } - - guard let imageMimeType = mimetype(forImageFileExtension: imageFileExtension) else { - Logger.error("Image URL has unknown or invalid content type: \(imageUrl).") - return Promise.init(error: LinkPreviewError.invalidInput) - } - - return downloadImage(url: imageUrl, imageMimeType: imageMimeType) - } private class func downloadImage(url urlString: String, imageMimeType: String) -> Promise<Data> { diff --git a/SignalServiceKit/src/Messages/Interactions/TSMessage.h b/SignalServiceKit/src/Messages/Interactions/TSMessage.h index 2d12315e1..5b54d0437 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSMessage.h +++ b/SignalServiceKit/src/Messages/Interactions/TSMessage.h @@ -100,10 +100,6 @@ typedef NS_ENUM(NSInteger, LKMessageFriendRequestStatus) { - (void)saveOpenGroupServerMessageID:(uint64_t)serverMessageID in:(YapDatabaseReadWriteTransaction *_Nullable)transaction; -#pragma mark - Link Preview - -- (void)generateLinkPreviewIfNeededFromURL:(NSString *)url; - @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Messages/Interactions/TSMessage.m b/SignalServiceKit/src/Messages/Interactions/TSMessage.m index 586826a0d..baadfd461 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSMessage.m @@ -511,44 +511,6 @@ static const NSUInteger OWSMessageSchemaVersion = 4; } } -#pragma mark - Link Previews - -- (void)generateLinkPreviewIfNeededFromURL:(NSString *)url { - [OWSLinkPreview tryToBuildPreviewInfoObjcWithPreviewUrl:url] - .thenOn(dispatch_get_main_queue(), ^(OWSLinkPreviewDraft *linkPreviewDraft) { - [self.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - OWSLinkPreview *linkPreview = [OWSLinkPreview buildValidatedLinkPreviewFromInfo:linkPreviewDraft transaction:transaction error:nil]; - self.linkPreview = linkPreview; - [self saveWithTransaction:transaction]; - }]; - }) - .catchOn(dispatch_get_main_queue(), ^(NSError *error) { - // If we failed to get a link preview due to an invalid content type error then this could be a direct image link - if ([OWSLinkPreview isInvalidContentError:error]) { - __block AnyPromise *promise; - [self.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - promise = [OWSLinkPreview getImagePreviewWithURL:url transaction:transaction] - .thenOn(dispatch_get_main_queue(), ^(OWSLinkPreview *linkPreview) { - // If we managed to get a direct image preview then render it - [self.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - if (linkPreview.isDirectAttachment) { - [self addAttachmentWithID:linkPreview.imageAttachmentId in:transaction]; - TSAttachmentStream *attachment = [TSAttachmentStream fetchObjectWithUniqueID:linkPreview.imageAttachmentId transaction:transaction]; - attachment.albumMessageId = self.uniqueId; - attachment.isUploaded = true; - [attachment saveWithTransaction:transaction]; - } else { - // Do nothing - } - }]; - }); - }]; - return promise; - } - @throw error; - }); -} - @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Messages/OWSMessageDecrypter.m b/SignalServiceKit/src/Messages/OWSMessageDecrypter.m index aba11134a..15b1943a4 100644 --- a/SignalServiceKit/src/Messages/OWSMessageDecrypter.m +++ b/SignalServiceKit/src/Messages/OWSMessageDecrypter.m @@ -673,28 +673,12 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes OWSAssertDebug(errorMessage); if (errorMessage != nil) { [errorMessage saveWithTransaction:transaction]; - [self handleSessionRestoreForErrorMessage:errorMessage envelope:envelope transaction:transaction]; + [SessionProtocol handleDecryptionError:errorMessage.errorType forHexEncodedPublicKey:envelope.source using:transaction]; [self notifyUserForErrorMessage:errorMessage envelope:envelope transaction:transaction]; } }]; } -- (void)handleSessionRestoreForErrorMessage:(TSErrorMessage *)errorMessage - envelope:(SSKProtoEnvelope *)envelope - transaction:(YapDatabaseReadWriteTransaction *)transaction -{ - NSString *hexEncodedPublicKey = [LKDatabaseUtilities getMasterHexEncodedPublicKeyFor:envelope.source in:transaction] ?: envelope.source; - TSThread *contactThread = [TSContactThread getOrCreateThreadWithContactId:hexEncodedPublicKey transaction:transaction]; - - // Trigger a session restore prompt if we get specific errors - if (errorMessage.errorType == TSErrorMessageNoSession || - errorMessage.errorType == TSErrorMessageInvalidMessage || - errorMessage.errorType == TSErrorMessageInvalidKeyException) { - // We want to store the source device's public key into the session restore in case it's a secondary device message - [((TSContactThread *)contactThread) addSessionRestoreDevice:envelope.source transaction:transaction]; - } -} - - (void)notifyUserForErrorMessage:(TSErrorMessage *)errorMessage envelope:(SSKProtoEnvelope *)envelope transaction:(YapDatabaseReadWriteTransaction *)transaction diff --git a/SignalServiceKit/src/Messages/OWSMessageReceiver.m b/SignalServiceKit/src/Messages/OWSMessageReceiver.m index d39208cde..be638dd24 100644 --- a/SignalServiceKit/src/Messages/OWSMessageReceiver.m +++ b/SignalServiceKit/src/Messages/OWSMessageReceiver.m @@ -398,8 +398,7 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin OWSAssertDebug(transaction); // Loki: Don't process any messages from ourself - ECKeyPair *_Nullable userKeyPair = OWSIdentityManager.sharedManager.identityKeyPair; - if (userKeyPair && [result.source isEqualToString:userKeyPair.hexEncodedPublicKey]) { + if ([SessionProtocol shouldSkipMessageDecryptResult:result]) { dispatch_async(self.serialQueue, ^{ completion(YES); }); diff --git a/SignalServiceKit/src/Messages/OWSOutgoingReceiptManager.m b/SignalServiceKit/src/Messages/OWSOutgoingReceiptManager.m index 35b330d3b..d248e7460 100644 --- a/SignalServiceKit/src/Messages/OWSOutgoingReceiptManager.m +++ b/SignalServiceKit/src/Messages/OWSOutgoingReceiptManager.m @@ -173,12 +173,10 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa } TSThread *thread = [TSContactThread getOrCreateThreadWithContactId:recipientId]; - - // If we aren't friends with the user then don't send out any receipts - if (thread.friendRequestStatus != LKThreadFriendRequestStatusFriends) { continue; } - - // Don't send any receipts for groups - if (thread.isGroupThread) { continue; } + + if (![SessionProtocol shouldSendReceiptForThread:thread]) { + continue; + } OWSReceiptsForSenderMessage *message; NSString *receiptName; diff --git a/SignalServiceKit/src/Messages/OWSReadReceiptManager.m b/SignalServiceKit/src/Messages/OWSReadReceiptManager.m index 3d51b8f38..17d86049a 100644 --- a/SignalServiceKit/src/Messages/OWSReadReceiptManager.m +++ b/SignalServiceKit/src/Messages/OWSReadReceiptManager.m @@ -286,19 +286,10 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE self.toLinkedDevicesReadReceiptMap[threadUniqueId] = newReadReceipt; } - __block BOOL isNoteToSelf; - [OWSPrimaryStorage.sharedManager.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { - isNoteToSelf = [LKDatabaseUtilities isUserLinkedDevice:message.authorId in:transaction]; - }]; - - if (isNoteToSelf) { - OWSLogVerbose(@"Ignoring read receipt for self-sender."); + if (![SessionProtocol shouldSendReadReceiptForThread:message.thread]) { return; } - // Don't send any receipts for groups - if (message.thread.isGroupThread) { return; } - if ([self areReadReceiptsEnabled]) { OWSLogVerbose(@"Enqueuing read receipt for sender."); [self.outgoingReceiptManager enqueueReadReceiptForEnvelope:messageAuthorId timestamp:message.timestamp]; diff --git a/SignalServiceKit/src/Messages/TSGroupModel.m b/SignalServiceKit/src/Messages/TSGroupModel.m index ba34114e1..4815594be 100644 --- a/SignalServiceKit/src/Messages/TSGroupModel.m +++ b/SignalServiceKit/src/Messages/TSGroupModel.m @@ -153,6 +153,7 @@ const int32_t kGroupIdLength = 16; stringByAppendingString:NSLocalizedString(@"YOU_WERE_REMOVED", @"")]; } else { NSArray *removedMemberNames = [[newModel.removedMembers allObjects] map:^NSString*(NSString* item) { + // TODO: Shouldn't this use DisplayNameUtilities? return [contactsManager displayNameForPhoneIdentifier:item]; }]; if ([removedMemberNames count] > 1) { diff --git a/SignalServiceKit/src/Messages/UD/OWSUDManager.swift b/SignalServiceKit/src/Messages/UD/OWSUDManager.swift index 30a7b9c04..8649decc5 100644 --- a/SignalServiceKit/src/Messages/UD/OWSUDManager.swift +++ b/SignalServiceKit/src/Messages/UD/OWSUDManager.swift @@ -425,9 +425,9 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager { private func generateSenderCertificate() -> Promise<(certificateData: Data, certificate: SMKSenderCertificate)> { return Promise<(certificateData: Data, certificate: SMKSenderCertificate)> { seal in - // Loki: Generate a sender certifate locally - let sender = OWSIdentityManager.shared().identityKeyPair()?.hexEncodedPublicKey - let certificate = SMKSenderCertificate(senderDeviceId: OWSDevicePrimaryDeviceId, senderRecipientId: sender!) + // Loki: Generate a sender certificate locally + let sender = OWSIdentityManager.shared().identityKeyPair()!.hexEncodedPublicKey + let certificate = SMKSenderCertificate(senderDeviceId: OWSDevicePrimaryDeviceId, senderRecipientId: sender) let certificateAsData = try certificate.serialized() guard isValidCertificate(certificate) else { throw OWSUDError.invalidData(description: "Invalid sender certificate.") @@ -439,14 +439,14 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager { @objc public func getSenderCertificate() -> SMKSenderCertificate? { do { - let sender = OWSIdentityManager.shared().identityKeyPair()?.hexEncodedPublicKey - let certificate = SMKSenderCertificate(senderDeviceId: OWSDevicePrimaryDeviceId, senderRecipientId: sender!) + let sender = OWSIdentityManager.shared().identityKeyPair()!.hexEncodedPublicKey + let certificate = SMKSenderCertificate(senderDeviceId: OWSDevicePrimaryDeviceId, senderRecipientId: sender) guard self.isValidCertificate(certificate) else { throw OWSUDError.invalidData(description: "Invalid sender certificate returned by server") } return certificate } catch { - Logger.error("\(error)") + print("[Loki] Couldn't get UD sender certificate due to error: \(error).") return nil } } diff --git a/SignalServiceKit/src/Util/TypingIndicators.swift b/SignalServiceKit/src/Util/TypingIndicators.swift index 14e1e8993..58cff90ac 100644 --- a/SignalServiceKit/src/Util/TypingIndicators.swift +++ b/SignalServiceKit/src/Util/TypingIndicators.swift @@ -324,15 +324,7 @@ public class TypingIndicatorsImpl: NSObject, TypingIndicators { } // Loki: Don't send typing indicators in group or note to self threads - if (thread.isGroupThread()) { - return - } else { - var isNoteToSelf = false - OWSPrimaryStorage.shared().dbReadConnection.read { transaction in - isNoteToSelf = LokiDatabaseUtilities.isUserLinkedDevice(thread.contactIdentifier()!, transaction: transaction) - } - if isNoteToSelf { return } - } + if !SessionProtocol.shouldSendTypingIndicator(for: thread) { return } let message = TypingIndicatorMessage(thread: thread, action: action) messageSender.sendPromise(message: message).retainUntilComplete()