diff --git a/SignalServiceKit/src/Loki/API/DotNetAPI.swift b/SignalServiceKit/src/Loki/API/DotNetAPI.swift index 643338995..6f574985c 100644 --- a/SignalServiceKit/src/Loki/API/DotNetAPI.swift +++ b/SignalServiceKit/src/Loki/API/DotNetAPI.swift @@ -101,6 +101,39 @@ public class DotNetAPI : NSObject { } // MARK: Public API + @objc(downloadAttachmentFrom:) + public static func objc_downloadAttachment(from url: String) -> AnyPromise { + return AnyPromise.from(downloadAttachment(from: url)) + } + + public static func downloadAttachment(from url: String) -> Promise { + var error: NSError? + var host = "https://\(URL(string: url)!.host!)" + let sanitizedURL: String + if FileServerAPI.fileStorageBucketURL.contains(host) { + sanitizedURL = url.replacingOccurrences(of: FileServerAPI.fileStorageBucketURL, with: "\(FileServerAPI.server)/loki/v1") + host = FileServerAPI.server + } else { + sanitizedURL = url.replacingOccurrences(of: host, with: "\(host)/loki/v1") + } + let request = AFHTTPRequestSerializer().request(withMethod: "GET", urlString: sanitizedURL, parameters: nil, error: &error) + if let error = error { + print("[Loki] Couldn't download attachment due to error: \(error).") + return Promise(error: error) + } + let serverPublicKeyPromise = FileServerAPI.server.contains(host) ? Promise.value(FileServerAPI.fileServerPublicKey) + : PublicChatAPI.getOpenGroupServerPublicKey(for: host) + return serverPublicKeyPromise.then2 { serverPublicKey in + return OnionRequestAPI.sendOnionRequest(request, to: host, using: serverPublicKey, isJSONRequired: false).map2 { json in + guard let body = json["body"] as? JSON, let data = body["data"] as? [UInt8] else { + print("[Loki] Couldn't parse attachment from: \(json).") + throw DotNetAPIError.parsingFailed + } + return Data(data) + } + } + } + @objc(uploadAttachment:withID:toServer:) public static func objc_uploadAttachment(_ attachment: TSAttachmentStream, with attachmentID: String, to server: String) -> AnyPromise { return AnyPromise.from(uploadAttachment(attachment, with: attachmentID, to: server)) diff --git a/SignalServiceKit/src/Loki/API/FileServerAPI.swift b/SignalServiceKit/src/Loki/API/FileServerAPI.swift index 69ae71d67..c9eb1d222 100644 --- a/SignalServiceKit/src/Loki/API/FileServerAPI.swift +++ b/SignalServiceKit/src/Loki/API/FileServerAPI.swift @@ -53,29 +53,6 @@ public final class FileServerAPI : DotNetAPI { } } - // MARK: Attachments - @objc(downloadAttachmentFrom:) - public static func objc_downloadAttachment(from url: String) -> AnyPromise { - return AnyPromise.from(downloadAttachment(from: url)) - } - - public static func downloadAttachment(from url: String) -> Promise { - var error: NSError? - let url = url.replacingOccurrences(of: fileStorageBucketURL, with: "\(server)/loki/v1") - let request = AFHTTPRequestSerializer().request(withMethod: "GET", urlString: url, parameters: nil, error: &error) - if let error = error { - print("[Loki] Couldn't download attachment due to error: \(error).") - return Promise(error: error) - } - return OnionRequestAPI.sendOnionRequest(request, to: server, using: fileServerPublicKey, isJSONRequired: false).map2 { json in - guard let body = json["body"] as? JSON, let data = body["data"] as? [UInt8] else { - print("[Loki] Couldn't parse attachment from: \(json).") - throw DotNetAPIError.parsingFailed - } - return Data(data) - } - } - // MARK: Open Group Server Public Key public static func getPublicKey(for openGroupServer: String) -> Promise { let url = URL(string: "\(server)/loki/v1/getOpenGroupKey/\(URL(string: openGroupServer)!.host!)")! diff --git a/SignalServiceKit/src/Loki/API/Open Groups/PublicChatAPI.swift b/SignalServiceKit/src/Loki/API/Open Groups/PublicChatAPI.swift index d5d1b3be6..24c553ef7 100644 --- a/SignalServiceKit/src/Loki/API/Open Groups/PublicChatAPI.swift +++ b/SignalServiceKit/src/Loki/API/Open Groups/PublicChatAPI.swift @@ -369,7 +369,7 @@ public final class PublicChatAPI : DotNetAPI { } } - static func updateProfileIfNeeded(for channel: UInt64, on server: String, from info: PublicChatInfo, token: String, serverPublicKey: String) { + static func updateProfileIfNeeded(for channel: UInt64, on server: String, from info: PublicChatInfo) { let storage = OWSPrimaryStorage.shared() let publicChatID = "\(server).\(channel)" try! Storage.writeSync { transaction in @@ -388,23 +388,9 @@ public final class PublicChatAPI : DotNetAPI { if oldProfilePictureURL != info.profilePictureURL || groupModel.groupImage == nil { storage.setProfilePictureURL(info.profilePictureURL, forPublicChatWithID: publicChatID, in: transaction) if let profilePictureURL = info.profilePictureURL { - var error: NSError? - let url = "\(server)/loki/v1\(profilePictureURL)" - let request = AFHTTPRequestSerializer().request(withMethod: "GET", urlString: url, parameters: nil, error: &error) - request.allHTTPHeaderFields = [ "Content-Type" : "application/json", "Authorization" : "Bearer \(token)" ] - if let error = error { - print("[Loki] Couldn't download open group avatar due to error: \(error).") - return - } - OnionRequestAPI.sendOnionRequest(request, to: server, using: serverPublicKey, isJSONRequired: false).map(on: DispatchQueue.global(qos: .default)) { json in - guard let body = json["body"] as? JSON, let data = body["data"] as? [UInt8] else { - print("[Loki] Couldn't parse open group profile picture from: \(json).") - return - } - let profilePicture = Data(data) - let attachmentStream = TSAttachmentStream(contentType: OWSMimeTypeImageJpeg, byteCount: UInt32(profilePicture.count), - sourceFilename: nil, caption: nil, albumMessageId: nil) - try! attachmentStream.write(profilePicture) + FileServerAPI.downloadAttachment(from: "\(server)\(profilePictureURL)").map2 { data in + let attachmentStream = TSAttachmentStream(contentType: OWSMimeTypeImageJpeg, byteCount: UInt32(data.count), sourceFilename: nil, caption: nil, albumMessageId: nil) + try attachmentStream.write(data) groupThread.updateAvatar(with: attachmentStream) } } @@ -442,7 +428,7 @@ public final class PublicChatAPI : DotNetAPI { storage.setUserCount(memberCount, forPublicChatWithID: "\(server).\(channel)", in: transaction) } let publicChatInfo = PublicChatInfo(displayName: displayName, profilePictureURL: profilePictureURL, memberCount: memberCount) - updateProfileIfNeeded(for: channel, on: server, from: publicChatInfo, token: token, serverPublicKey: serverPublicKey) + updateProfileIfNeeded(for: channel, on: server, from: publicChatInfo) return publicChatInfo } }