From fc44b1c19108d436970b2c8dfca8ef2708fcb05f Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Fri, 15 Nov 2019 11:13:55 +1100 Subject: [PATCH] Debug --- .../ConversationView/ConversationViewItem.m | 6 ++-- .../src/Loki/API/LokiStorageAPI.swift | 7 +++-- .../API/Public Chat/LokiPublicChatAPI.swift | 28 +++++++++++++++++++ .../Public Chat/LokiPublicChatPoller.swift | 22 ++++++++++++++- .../src/Messages/OWSMessageSender.m | 5 +++- 5 files changed, 60 insertions(+), 8 deletions(-) diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m b/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m index 6100ec5eb..2a4387478 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m @@ -1272,10 +1272,10 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType) if (interationType == OWSInteractionType_IncomingMessage) { // Only allow deletion on incoming messages if the user has moderation permission return [LKPublicChatAPI isUserModerator:self.userHexEncodedPublicKey forGroup:publicChat.channel onServer:publicChat.server]; - } else { - // Only allow deletion on outgoing messages if the user was the sender (i.e. it was not sent from another linked device) - return [self.interaction.actualSenderHexEncodedPublicKey isEqual:self.userHexEncodedPublicKey]; } + + // Only allow deletion on outgoing messages if the user was the sender (i.e. it was not sent from another linked device) + return [self.interaction.actualSenderHexEncodedPublicKey isEqual:self.userHexEncodedPublicKey]; } @end diff --git a/SignalServiceKit/src/Loki/API/LokiStorageAPI.swift b/SignalServiceKit/src/Loki/API/LokiStorageAPI.swift index eeb137968..2a099edcb 100644 --- a/SignalServiceKit/src/Loki/API/LokiStorageAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiStorageAPI.swift @@ -35,10 +35,11 @@ public final class LokiStorageAPI : LokiDotNetAPI { throw Error.parsingFailed } return Set(data.flatMap { data -> [DeviceLink] in - guard let annotations = data["annotations"] as? [JSON], !annotations.isEmpty, let hexEncodedPublicKey = data["username"] as? String else { return [] } + guard let annotations = data["annotations"] as? [JSON], !annotations.isEmpty else { return [] } guard let annotation = annotations.first(where: { $0["type"] as? String == deviceLinkType }), - let value = annotation["value"] as? JSON, let rawDeviceLinks = value["authorisations"] as? [JSON] else { - print("[Loki] Couldn't parse device links for user: \(hexEncodedPublicKey) from: \(rawResponse).") + let value = annotation["value"] as? JSON, let rawDeviceLinks = value["authorisations"] as? [JSON], + let user = data["user"] as? JSON, let hexEncodedPublicKey = user["username"] as? String else { + print("[Loki] Couldn't parse device links from: \(rawResponse).") return [] } return rawDeviceLinks.compactMap { rawDeviceLink in diff --git a/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatAPI.swift b/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatAPI.swift index 8359925b0..51044b96e 100644 --- a/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatAPI.swift +++ b/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatAPI.swift @@ -3,6 +3,7 @@ import PromiseKit @objc(LKPublicChatAPI) public final class LokiPublicChatAPI : LokiDotNetAPI { private static var moderators: [String:[UInt64:Set]] = [:] // Server URL to (channel ID to set of moderator IDs) + public static var displayNameUpdatees: [String:Set] = [:] // MARK: Settings private static let fallbackBatchCount = 64 @@ -229,6 +230,33 @@ public final class LokiPublicChatAPI : LokiDotNetAPI { } } + public static func getDisplayNames(for channel: UInt64, on server: String) -> Promise { + let publicChatID = "\(server).\(channel)" + guard let hexEncodedPublicKeys = displayNameUpdatees[publicChatID] else { return Promise.value(()) } + displayNameUpdatees[publicChatID] = [] + print("[Loki] Getting display names for: \(hexEncodedPublicKeys).") + return getAuthToken(for: server).then(on: DispatchQueue.global()) { token -> Promise in + let queryParameters = "ids=\(hexEncodedPublicKeys.map { "@\($0)" }.joined(separator: ","))&include_user_annotations=1" + let url = URL(string: "\(server)/users?\(queryParameters)")! + let request = TSRequest(url: url) + return TSNetworkManager.shared().perform(request, withCompletionQueue: DispatchQueue.global()).map { $0.responseObject }.map { rawResponse in + guard let json = rawResponse as? JSON, let data = json["data"] as? [JSON] else { + print("[Loki] Couldn't parse display names for users: \(hexEncodedPublicKeys) from: \(rawResponse).") + throw Error.parsingFailed + } + storage.dbReadWriteConnection.readWrite { transaction in + data.forEach { data in + guard let user = data["user"] as? JSON, let hexEncodedPublicKey = user["username"] as? String, let rawDisplayName = user["name"] as? String else { return } + let endIndex = hexEncodedPublicKey.endIndex + let cutoffIndex = hexEncodedPublicKey.index(endIndex, offsetBy: -8) + let displayName = "\(rawDisplayName) (...\(hexEncodedPublicKey[cutoffIndex.. Bool { return moderators[server]?[channel]?.contains(hexEncodedPublicString) ?? false diff --git a/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatPoller.swift b/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatPoller.swift index bfe443192..1e2da8a55 100644 --- a/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatPoller.swift +++ b/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatPoller.swift @@ -1,10 +1,13 @@ +// TODO: Move away from polling + @objc(LKPublicChatPoller) public final class LokiPublicChatPoller : NSObject { private let publicChat: LokiPublicChat private var pollForNewMessagesTimer: Timer? = nil private var pollForDeletedMessagesTimer: Timer? = nil private var pollForModeratorsTimer: Timer? = nil + private var pollForDisplayNamesTimer: Timer? = nil private var hasStarted = false private let userHexEncodedPublicKey = OWSIdentityManager.shared().identityKeyPair()!.hexEncodedPublicKey @@ -12,6 +15,7 @@ public final class LokiPublicChatPoller : NSObject { private let pollForNewMessagesInterval: TimeInterval = 4 private let pollForDeletedMessagesInterval: TimeInterval = 20 private let pollForModeratorsInterval: TimeInterval = 10 * 60 + private let pollForDisplayNamesInterval: TimeInterval = 60 // MARK: Lifecycle @objc(initForPublicChat:) @@ -25,10 +29,12 @@ public final class LokiPublicChatPoller : NSObject { pollForNewMessagesTimer = Timer.scheduledTimer(withTimeInterval: pollForNewMessagesInterval, repeats: true) { [weak self] _ in self?.pollForNewMessages() } pollForDeletedMessagesTimer = Timer.scheduledTimer(withTimeInterval: pollForDeletedMessagesInterval, repeats: true) { [weak self] _ in self?.pollForDeletedMessages() } pollForModeratorsTimer = Timer.scheduledTimer(withTimeInterval: pollForModeratorsInterval, repeats: true) { [weak self] _ in self?.pollForModerators() } + pollForDisplayNamesTimer = Timer.scheduledTimer(withTimeInterval: pollForDisplayNamesInterval, repeats: true) { [weak self] _ in self?.pollForDisplayNames() } // Perform initial updates pollForNewMessages() pollForDeletedMessages() pollForModerators() + pollForDisplayNames() hasStarted = true } @@ -36,6 +42,7 @@ public final class LokiPublicChatPoller : NSObject { pollForNewMessagesTimer?.invalidate() pollForDeletedMessagesTimer?.invalidate() pollForModeratorsTimer?.invalidate() + pollForDisplayNamesTimer?.invalidate() hasStarted = false } @@ -171,7 +178,17 @@ public final class LokiPublicChatPoller : NSObject { } // Poll let _ = LokiPublicChatAPI.getMessages(for: publicChat.channel, on: publicChat.server).done(on: DispatchQueue.global()) { messages in + let uniqueHexEncodedPublicKeys = Set(messages.map { $0.hexEncodedPublicKey }) func proceed() { + let storage = OWSPrimaryStorage.shared() + var newDisplayNameUpdatees: Set = [] + storage.dbReadConnection.read { transaction in + newDisplayNameUpdatees = Set(uniqueHexEncodedPublicKeys.filter { storage.getMasterHexEncodedPublicKey(for: $0, in: transaction) != $0 }.compactMap { storage.getMasterHexEncodedPublicKey(for: $0, in: transaction) }) + } + if !newDisplayNameUpdatees.isEmpty { + let displayNameUpdatees = LokiPublicChatAPI.displayNameUpdatees[publicChat.id] ?? [] + LokiPublicChatAPI.displayNameUpdatees[publicChat.id] = displayNameUpdatees.union(newDisplayNameUpdatees) + } messages.forEach { message in var wasSentByCurrentUser = false OWSPrimaryStorage.shared().dbReadConnection.read { transaction in @@ -184,7 +201,6 @@ public final class LokiPublicChatPoller : NSObject { } } } - let uniqueHexEncodedPublicKeys = Set(messages.map { $0.hexEncodedPublicKey }) let hexEncodedPublicKeysToUpdate = uniqueHexEncodedPublicKeys.filter { hexEncodedPublicKey in let timeSinceLastUpdate: TimeInterval if let lastDeviceLinkUpdate = LokiAPI.lastDeviceLinkUpdate[hexEncodedPublicKey] { @@ -234,4 +250,8 @@ public final class LokiPublicChatPoller : NSObject { private func pollForModerators() { let _ = LokiPublicChatAPI.getModerators(for: publicChat.channel, on: publicChat.server) } + + private func pollForDisplayNames() { + let _ = LokiPublicChatAPI.getDisplayNames(for: publicChat.channel, on: publicChat.server) + } } diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index 286f9ab69..cfc01bc27 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -1227,6 +1227,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; NSUInteger height = attachment.shouldHaveImageSize ? @(attachment.imageSize.height).unsignedIntegerValue : 0; [groupMessage addAttachmentWithKind:@"attachment" server:publicChat.server serverID:attachment.serverId contentType:attachment.contentType size:attachment.byteCount fileName:attachment.sourceFilename flags:0 width:width height:height caption:attachment.caption url:attachment.downloadURL linkPreviewURL:nil linkPreviewTitle:nil]; } + message.actualSenderHexEncodedPublicKey = userHexEncodedPublicKey; [[LKPublicChatAPI sendMessage:groupMessage toGroup:publicChat.channel onServer:publicChat.server] .thenOn(OWSDispatch.sendingQueue, ^(LKGroupMessage *groupMessage) { [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { @@ -1574,7 +1575,9 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; } }]; - BOOL shouldSendTranscript = (AreRecipientUpdatesEnabled() || !message.hasSyncedTranscript) && !isNoteToSelf; + BOOL isPublicChatMessage = message.isGroupChatMessage; + + BOOL shouldSendTranscript = (AreRecipientUpdatesEnabled() || !message.hasSyncedTranscript) && !isNoteToSelf && !isPublicChatMessage; if (!shouldSendTranscript) { return success(); }