|
|
|
@ -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<UInt64>, 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.")
|
|
|
|
|