diff --git a/Signal/Signal-Info.plist b/Signal/Signal-Info.plist index 6eef4af7b..bed6edaf5 100644 --- a/Signal/Signal-Info.plist +++ b/Signal/Signal-Info.plist @@ -5,7 +5,7 @@ BuildDetails CarthageVersion - 0.33.0 + 0.34.0 OSXVersion 10.15.2 WebRTCCommit diff --git a/SignalServiceKit/src/Loki/API/LokiDotNetAPI.swift b/SignalServiceKit/src/Loki/API/LokiDotNetAPI.swift index 1b1fc4492..e39e6601c 100644 --- a/SignalServiceKit/src/Loki/API/LokiDotNetAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiDotNetAPI.swift @@ -74,37 +74,56 @@ public class LokiDotNetAPI : NSObject { throw error } // Send the request - let task = AFURLSessionManager(sessionConfiguration: .default).uploadTask(withStreamedRequest: request as URLRequest, progress: { rawProgress in - // Broadcast progress updates - let progress = max(0.1, rawProgress.fractionCompleted) - let userInfo: [String:Any] = [ kAttachmentUploadProgressKey : progress, kAttachmentUploadAttachmentIDKey : attachmentID ] - DispatchQueue.main.async { - NotificationCenter.default.post(name: .attachmentUploadProgress, object: nil, userInfo: userInfo) + let isLokiFileServer = server.contains("file.lokinet.org") || server.contains("file-dev.lokinet.org") + if isLokiFileServer { + LokiFileServerProxy(for: server).performLokiFileServerNSURLRequest(request as NSURLRequest).done { responseObject in + // Parse the server ID & download URL + guard let json = responseObject as? JSON, let data = json["data"] as? JSON, let serverID = data["id"] as? UInt64, let downloadURL = data["url"] as? String else { + print("[Loki] Couldn't parse attachment from: \(responseObject).") + return seal.reject(Error.parsingFailed) + } + // Update the attachment + attachment.serverId = serverID + attachment.isUploaded = true + attachment.downloadURL = downloadURL + attachment.save() + seal.fulfill(()) + }.catch { error in + seal.reject(error) } - }, completionHandler: { response, responseObject, error in - if let error = error { - print("[Loki] Couldn't upload attachment due to error: \(error).") - return seal.reject(error) - } - let statusCode = (response as! HTTPURLResponse).statusCode - let isSuccessful = (200...299) ~= statusCode - guard isSuccessful else { - print("[Loki] Couldn't upload attachment.") - return seal.reject(Error.generic) - } - // Parse the server ID & download URL - guard let json = responseObject as? JSON, let data = json["data"] as? JSON, let serverID = data["id"] as? UInt64, let downloadURL = data["url"] as? String else { - print("[Loki] Couldn't parse attachment from: \(responseObject).") - return seal.reject(Error.parsingFailed) - } - // Update the attachment - attachment.serverId = serverID - attachment.isUploaded = true - attachment.downloadURL = downloadURL - attachment.save() - return seal.fulfill(()) - }) - task.resume() + } else { + let task = AFURLSessionManager(sessionConfiguration: .default).uploadTask(withStreamedRequest: request as URLRequest, progress: { rawProgress in + // Broadcast progress updates + let progress = max(0.1, rawProgress.fractionCompleted) + let userInfo: [String:Any] = [ kAttachmentUploadProgressKey : progress, kAttachmentUploadAttachmentIDKey : attachmentID ] + DispatchQueue.main.async { + NotificationCenter.default.post(name: .attachmentUploadProgress, object: nil, userInfo: userInfo) + } + }, completionHandler: { response, responseObject, error in + if let error = error { + print("[Loki] Couldn't upload attachment due to error: \(error).") + return seal.reject(error) + } + let statusCode = (response as! HTTPURLResponse).statusCode + let isSuccessful = (200...299) ~= statusCode + guard isSuccessful else { + print("[Loki] Couldn't upload attachment.") + return seal.reject(Error.generic) + } + // Parse the server ID & download URL + guard let json = responseObject as? JSON, let data = json["data"] as? JSON, let serverID = data["id"] as? UInt64, let downloadURL = data["url"] as? String else { + print("[Loki] Couldn't parse attachment from: \(responseObject).") + return seal.reject(Error.parsingFailed) + } + // Update the attachment + attachment.serverId = serverID + attachment.isUploaded = true + attachment.downloadURL = downloadURL + attachment.save() + return seal.fulfill(()) + }) + task.resume() + } }.catch(on: DispatchQueue.global()) { error in print("[Loki] Couldn't upload attachment.") seal.reject(error) diff --git a/SignalServiceKit/src/Loki/API/LokiFileServerProxy.swift b/SignalServiceKit/src/Loki/API/LokiFileServerProxy.swift index cd2f6f69e..b6a0aa90a 100644 --- a/SignalServiceKit/src/Loki/API/LokiFileServerProxy.swift +++ b/SignalServiceKit/src/Loki/API/LokiFileServerProxy.swift @@ -39,6 +39,10 @@ internal class LokiFileServerProxy : LokiHTTPClient { override internal func perform(_ request: TSRequest, withCompletionQueue queue: DispatchQueue = DispatchQueue.main) -> LokiAPI.RawResponsePromise { let isLokiFileServer = server.contains("file.lokinet.org") || server.contains("file-dev.lokinet.org") guard isLokiFileServer else { return super.perform(request, withCompletionQueue: queue) } // Don't proxy open group requests for now + return performLokiFileServerNSURLRequest(request, withCompletionQueue: queue) + } + + internal func performLokiFileServerNSURLRequest(_ request: NSURLRequest, withCompletionQueue queue: DispatchQueue = DispatchQueue.main) -> LokiAPI.RawResponsePromise { let uncheckedSymmetricKey = try? Curve25519.generateSharedSecret(fromPublicKey: LokiFileServerProxy.fileServerPublicKey, privateKey: keyPair.privateKey) guard let symmetricKey = uncheckedSymmetricKey else { return Promise(error: Error.symmetricKeyGenerationFailed) } var headers = getCanonicalHeaders(for: request) @@ -50,8 +54,17 @@ internal class LokiFileServerProxy : LokiHTTPClient { serverURLEndIndex < urlAsString.endIndex else { throw Error.endpointParsingFailed } let endpointStartIndex = urlAsString.index(after: serverURLEndIndex) let endpoint = String(urlAsString[endpointStartIndex.. [String: Any] { + internal func getCanonicalHeaders(for request: NSURLRequest) -> [String:Any] { guard let headers = request.allHTTPHeaderFields else { return [:] } return headers.mapValues { value in switch value.lowercased() {