diff --git a/SessionMessagingKit/File Server/FileServerAPIV2.swift b/SessionMessagingKit/File Server/FileServerAPIV2.swift index 8b6eafda5..8fcb24663 100644 --- a/SessionMessagingKit/File Server/FileServerAPIV2.swift +++ b/SessionMessagingKit/File Server/FileServerAPIV2.swift @@ -1,10 +1,14 @@ import PromiseKit import SessionSnodeKit -public enum FileServerAPIV2 { +@objc(SNFileServerAPIV2) +public final class FileServerAPIV2 : NSObject { public static let server = "http://88.99.175.227" public static let serverPublicKey = "7cb31905b55cd5580c686911debf672577b3fb0bff81df4ce2d5c4cb3a7aaa69" + public static let useV2FileServer = true + + private override init() { } // MARK: Error public enum Error : LocalizedError { diff --git a/SessionMessagingKit/Jobs/AttachmentUploadJob.swift b/SessionMessagingKit/Jobs/AttachmentUploadJob.swift index e433330b9..918bb11f6 100644 --- a/SessionMessagingKit/Jobs/AttachmentUploadJob.swift +++ b/SessionMessagingKit/Jobs/AttachmentUploadJob.swift @@ -1,3 +1,4 @@ +import PromiseKit import SessionUtilitiesKit public final class AttachmentUploadJob : NSObject, Job, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility @@ -11,10 +12,12 @@ public final class AttachmentUploadJob : NSObject, Job, NSCoding { // NSObject/N public enum Error : LocalizedError { case noAttachment + case encryptionFailed public var errorDescription: String? { switch self { case .noAttachment: return "No such attachment." + case .encryptionFailed: return "Couldn't encrypt file." } } } @@ -63,30 +66,10 @@ public final class AttachmentUploadJob : NSObject, Job, NSCoding { // NSObject/N guard !stream.isUploaded else { return handleSuccess() } // Should never occur let storage = SNMessagingKitConfiguration.shared.storage if let v2OpenGroup = storage.getV2OpenGroup(for: threadID) { - // Get the attachment - guard let data = try? stream.readDataFromFile() else { - SNLog("Couldn't read attachment from disk.") - return handleFailure(error: Error.noAttachment) - } - // Check the file size - SNLog("File size: \(data.count) bytes.") - if Double(data.count) > Double(FileServerAPI.maxFileSize) / FileServerAPI.fileSizeORMultiplier { - return handleFailure(error: FileServerAPI.Error.maxFileSizeExceeded) - } - // Send the request - stream.isUploaded = false - stream.save() - OpenGroupAPIV2.upload(data, to: v2OpenGroup.room, on: v2OpenGroup.server).done(on: DispatchQueue.global(qos: .userInitiated)) { fileID in - let downloadURL = "\(v2OpenGroup.server)/files/\(fileID)" - stream.serverId = fileID - stream.isUploaded = true - stream.downloadURL = downloadURL - stream.save() - self.handleSuccess() - }.catch { error in - self.handleFailure(error: error) - } - } else { + upload(stream, using: { data in return OpenGroupAPIV2.upload(data, to: v2OpenGroup.room, on: v2OpenGroup.server) }, encrypt: false) + } else if FileServerAPIV2.useV2FileServer && storage.getOpenGroup(for: threadID) == nil { + upload(stream, using: FileServerAPIV2.upload, encrypt: true) + } else { // Legacy let openGroup = storage.getOpenGroup(for: threadID) let server = openGroup?.server ?? FileServerAPI.server // FIXME: A lot of what's currently happening in FileServerAPI should really be happening here @@ -103,6 +86,44 @@ public final class AttachmentUploadJob : NSObject, Job, NSCoding { // NSObject/N } } } + + private func upload(_ stream: TSAttachmentStream, using upload: (Data) -> Promise, encrypt: Bool) { + // Get the attachment + guard var data = try? stream.readDataFromFile() else { + SNLog("Couldn't read attachment from disk.") + return handleFailure(error: Error.noAttachment) + } + // Encrypt the attachment if needed + if encrypt { + var encryptionKey = NSData() + var digest = NSData() + guard let ciphertext = Cryptography.encryptAttachmentData(data, shouldPad: false, outKey: &encryptionKey, outDigest: &digest) else { + SNLog("Couldn't encrypt attachment.") + return handleFailure(error: Error.encryptionFailed) + } + stream.encryptionKey = encryptionKey as Data + stream.digest = digest as Data + data = ciphertext + } + // Check the file size + SNLog("File size: \(data.count) bytes.") + if Double(data.count) > Double(FileServerAPI.maxFileSize) / FileServerAPI.fileSizeORMultiplier { + return handleFailure(error: FileServerAPI.Error.maxFileSizeExceeded) + } + // Send the request + stream.isUploaded = false + stream.save() + upload(data).done(on: DispatchQueue.global(qos: .userInitiated)) { fileID in + let downloadURL = "\(FileServerAPIV2.server)/files/\(fileID)" + stream.serverId = fileID + stream.isUploaded = true + stream.downloadURL = downloadURL + stream.save() + self.handleSuccess() + }.catch { error in + self.handleFailure(error: error) + } + } private func handleSuccess() { SNLog("Attachment uploaded successfully.")