فهرست منبع

E2ee step3 (#2586)

* improvements

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* counter only message mode

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* no subfolder android compatibility

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* improvements

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* filedrop

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* clean code

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* schema db +1

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* cleaning

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* Revert "cleaning"

This reverts commit 00cfb73e7694ed3dc64f73cbb08a196277d1b981.

* cleaning

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* cleaning

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* cleaning

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* coding

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* fix share

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* fix

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* fix

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* lint

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* fix

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* fix

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* add route

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* add route

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* add route

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* enable subfolder

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* add route

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* cleaning

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* cleaning

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* cleaning

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* cleaning DB

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* cleaning DB

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* cleaning DB

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* cleaning

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* cleaning

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* send new metadata when create a new folder e2ee

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* send new metadata when create a new folder e2ee

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* fix

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* lint

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* fix

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* fix GUI share

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* cleaning

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* cleaning

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* cleaning

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* cleaning

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* coding

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

---------

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>
Marino Faggiana 1 سال پیش
والد
کامیت
6fd88c97d1

+ 1 - 1
Brand/Database.swift

@@ -26,4 +26,4 @@ import Foundation
 // Database Realm
 //
 let databaseName                    = "nextcloud.realm"
-let databaseSchemaVersion: UInt64   = 312
+let databaseSchemaVersion: UInt64   = 317

+ 33 - 25
iOSClient/Data/NCManageDatabase+E2EE.swift

@@ -116,12 +116,27 @@ class tableE2eUsersV2: Object {
     @Persisted(primaryKey: true) var primaryKey = ""
     @Persisted var account = ""
     @Persisted var certificate = ""
-    @Persisted var encryptedFiledropKey: String?
     @Persisted var encryptedMetadataKey: String?
-    @Persisted var decryptedFiledropKey: Data?
-    @Persisted var decryptedMetadataKey: Data?
-    @Persisted var filedropKey: String?
-    @Persisted var metadataKey: String?
+    @Persisted var metadataKey: Data?
+    @Persisted var ocIdServerUrl: String = ""
+    @Persisted var serverUrl: String = ""
+    @Persisted var userId = ""
+
+    convenience init(account: String, ocIdServerUrl: String, userId: String) {
+        self.init()
+        self.primaryKey = account + ocIdServerUrl + userId
+        self.account = account
+        self.ocIdServerUrl = ocIdServerUrl
+        self.userId = userId
+     }
+}
+
+class tableE2eUsersFiledropV2: Object {
+
+    @Persisted(primaryKey: true) var primaryKey = ""
+    @Persisted var account = ""
+    @Persisted var certificate = ""
+    @Persisted var encryptedFiledropKey: String?
     @Persisted var ocIdServerUrl: String = ""
     @Persisted var serverUrl: String = ""
     @Persisted var userId = ""
@@ -169,7 +184,6 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
-            realm.refresh()
             guard let result = realm.objects(tableE2eEncryption.self).filter(predicate).sorted(byKeyPath: "metadataKeyIndex", ascending: false).first else { return nil }
             return tableE2eEncryption.init(value: result)
         } catch let error as NSError {
@@ -183,7 +197,6 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
-            realm.refresh()
             let results: Results<tableE2eEncryption>
             results = realm.objects(tableE2eEncryption.self).filter(predicate)
             return Array(results.map { tableE2eEncryption.init(value: $0) })
@@ -198,7 +211,6 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
-            realm.refresh()
             try realm.write {
                 guard let result = realm.objects(tableE2eEncryption.self).filter("account == %@ AND serverUrl == %@ AND fileNameIdentifier == %@", account, serverUrl, fileNameIdentifier).first else { return }
                 result.fileName = newFileName
@@ -216,7 +228,6 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
-            realm.refresh()
             guard let result = realm.objects(tableE2eEncryptionLock.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first else { return nil }
             return tableE2eEncryptionLock.init(value: result)
         } catch let error as NSError {
@@ -230,7 +241,6 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
-            realm.refresh()
             let results = realm.objects(tableE2eEncryptionLock.self).filter("account == %@", account)
             if results.isEmpty {
                 return []
@@ -282,7 +292,6 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
-            realm.refresh()
             guard let result = realm.objects(tableE2eMetadata.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first else { return nil }
             return tableE2eMetadata.init(value: result)
         } catch let error as NSError {
@@ -317,23 +326,15 @@ extension NCManageDatabase {
                        ocIdServerUrl: String,
                        userId: String,
                        certificate: String,
-                       encryptedFiledropKey: String?,
                        encryptedMetadataKey: String?,
-                       decryptedFiledropKey: Data?,
-                       decryptedMetadataKey: Data?,
-                       filedropKey: String?,
-                       metadataKey: String?) {
+                       metadataKey: Data?) {
 
         do {
             let realm = try Realm()
             try realm.write {
                 let object = tableE2eUsersV2.init(account: account, ocIdServerUrl: ocIdServerUrl, userId: userId)
                 object.certificate = certificate
-                object.encryptedFiledropKey = encryptedFiledropKey
                 object.encryptedMetadataKey = encryptedMetadataKey
-                object.decryptedFiledropKey = decryptedFiledropKey
-                object.decryptedMetadataKey = decryptedMetadataKey
-                object.filedropKey = filedropKey
                 object.metadataKey = metadataKey
                 object.serverUrl = serverUrl
                 realm.add(object, update: .all)
@@ -361,7 +362,6 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
-            realm.refresh()
             return realm.objects(tableE2eUsersV2.self).filter("account == %@ AND ocIdServerUrl == %@", account, ocIdServerUrl)
         } catch let error as NSError {
             NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
@@ -374,7 +374,6 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
-            realm.refresh()
             return realm.objects(tableE2eUsersV2.self).filter("account == %@ && ocIdServerUrl == %@ AND userId == %@", account, ocIdServerUrl, userId).first
         } catch let error as NSError {
             NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
@@ -383,11 +382,22 @@ extension NCManageDatabase {
         return nil
     }
 
+    func getE2EUsersFiledropV2(account: String, ocIdServerUrl: String, userId: String) -> tableE2eUsersFiledropV2? {
+
+        do {
+            let realm = try Realm()
+            return realm.objects(tableE2eUsersFiledropV2.self).filter("account == %@ && ocIdServerUrl == %@ AND userId == %@", account, ocIdServerUrl, userId).first
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
+        }
+
+        return nil
+    }
+
     func getE2eMetadataV2(account: String, ocIdServerUrl: String) -> tableE2eMetadataV2? {
 
         do {
             let realm = try Realm()
-            realm.refresh()
             return realm.objects(tableE2eMetadataV2.self).filter("account == %@ && ocIdServerUrl == %@", account, ocIdServerUrl).first
         } catch let error as NSError {
             NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
@@ -425,7 +435,6 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
-            realm.refresh()
             try realm.write {
                 let object = tableE2eCounterV2.init(account: account, ocIdServerUrl: ocIdServerUrl, counter: counter)
                 realm.add(object, update: .all)
@@ -439,7 +448,6 @@ extension NCManageDatabase {
 
         do {
             let realm = try Realm()
-            realm.refresh()
             return realm.objects(tableE2eCounterV2.self).filter("account == %@ && ocIdServerUrl == %@", account, ocIdServerUrl).first?.counter
         } catch let error as NSError {
             NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")

+ 1 - 2
iOSClient/Data/NCManageDatabase+Metadata.swift

@@ -253,11 +253,10 @@ extension tableMetadata {
         guard NCGlobal.shared.capabilityFileSharingApiEnabled else { return false }
 
         if NCGlobal.shared.capabilityE2EEApiVersion == NCGlobal.shared.e2eeVersionV20, isDirectoryE2EE {
-            return !isDirectoryE2EETop
+            return e2eEncrypted
         } else if !e2eEncrypted && !isDirectoryE2EE {
             return true
         } else if NCGlobal.shared.capabilityServerVersionMajor >= NCGlobal.shared.nextcloudVersion26 && directory {
-            // E2EE DIRECTORY SECURE FILE DROP (SHARE AVAILABLE)
             return true
         } else {
             return false

+ 1 - 1
iOSClient/Extensions/UIAlertController+Extension.swift

@@ -41,7 +41,7 @@ extension UIAlertController {
 
                     let createFolderResults = await NextcloudKit.shared.createFolder(serverUrlFileName: serverUrl + "/" + fileNameFolder)
                     if createFolderResults.error == .success {
-                        let error = await NCNetworkingE2EEMarkFolder().markFolderE2ee(account: urlBase.account, fileName: fileNameFolder, serverUrl: serverUrl, userId: urlBase.userId, withPush: true)
+                        let error = await NCNetworkingE2EEMarkFolder().markFolderE2ee(account: urlBase.account, fileName: fileNameFolder, serverUrl: serverUrl, userId: urlBase.userId)
                         if error != .success {
                             NCContentPresenter.shared.showError(error: error)
                         }

+ 19 - 10
iOSClient/Main/Collection Common/NCCollectionViewCommon.swift

@@ -517,7 +517,6 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
     @objc func uploadedFile(_ notification: NSNotification) {
 
         guard let userInfo = notification.userInfo as NSDictionary?,
-              let ocId = userInfo["ocId"] as? String,
               let ocIdTemp = userInfo["ocIdTemp"] as? String,
               let serverUrl = userInfo["serverUrl"] as? String,
               let account = userInfo["account"] as? String
@@ -528,12 +527,8 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
             self.collectionView?.reloadData()
         }
 
-        if account == appDelegate.account, serverUrl == self.serverUrl, let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) {
-            if metadata.e2eEncrypted {
-                reloadDataSourceNetwork(isForced: true)
-            } else {
-                reloadDataSource()
-            }
+        if account == appDelegate.account, serverUrl == self.serverUrl {
+            reloadDataSource()
         }
     }
 
@@ -1072,8 +1067,12 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
                     }
                     self.metadataFolder = metadataFolder
                     // E2EE
-                    if let metadataFolder = metadataFolder, metadataFolder.e2eEncrypted, CCUtility.isEnd(toEndEnabled: self.appDelegate.account) {
-                        NextcloudKit.shared.getE2EEMetadata(fileId: metadataFolder.ocId, e2eToken: nil) { _, e2eMetadata, signature, _, error in
+                    if let metadataFolder = metadataFolder,
+                        metadataFolder.e2eEncrypted,
+                        CCUtility.isEnd(toEndEnabled: self.appDelegate.account),
+                       !NCNetworkingE2EE.shared.isInUpload(account: self.appDelegate.account, serverUrl: self.serverUrl) {
+                        let lock = NCManageDatabase.shared.getE2ETokenLock(account: self.appDelegate.account, serverUrl: self.serverUrl)
+                        NextcloudKit.shared.getE2EEMetadata(fileId: metadataFolder.ocId, e2eToken: lock?.e2eToken, route: NCNetworkingE2EE.shared.getRoute()) { _, e2eMetadata, signature, _, error in
                             if error == .success, let e2eMetadata = e2eMetadata {
                                 let error = NCEndToEndMetadata().decodeMetadata(e2eMetadata, signature: signature, serverUrl: self.serverUrl, account: self.appDelegate.account, urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId)
                                 if error == .success {
@@ -1081,7 +1080,16 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
                                 } else {
                                     NCContentPresenter.shared.showError(error: error)
                                 }
-                            } else if error.errorCode != NCGlobal.shared.errorResourceNotFound {
+                            } else if error.errorCode == NCGlobal.shared.errorResourceNotFound {
+                                // no metadata found, send a new metadata
+                                Task {
+                                    let serverUrl = metadataFolder.serverUrl + "/" + metadataFolder.fileName
+                                    let error = await NCNetworkingE2EE.shared.uploadMetadata(account: metadataFolder.account, serverUrl: serverUrl, userId: metadataFolder.userId)
+                                    if error != .success {
+                                        NCContentPresenter.shared.showError(error: error)
+                                    }
+                                }
+                            } else {
                                 NCContentPresenter.shared.showError(error: NKError(errorCode: NCGlobal.shared.errorE2EEKeyDecodeMetadata, errorDescription: "_e2e_error_"))
                             }
                             completion(tableDirectory, metadatas, metadatasUpdate, metadatasDelete, error)
@@ -1109,6 +1117,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
             if let viewController = appDelegate.listFilesVC[serverUrlPush] {
 
                 if viewController.isViewLoaded {
+                    viewController.titleCurrentFolder = metadata.fileNameView
                     pushViewController(viewController: viewController)
                 }
 

+ 7 - 8
iOSClient/Menu/AppDelegate+Menu.swift

@@ -118,16 +118,15 @@ extension AppDelegate {
         let imageCreateFolder = isDirectoryE2EE ? UIImage(named: "folderEncrypted")! : UIImage(named: "folder")!
         actions.append(
             NCMenuAction(title: titleCreateFolder,
-                icon: imageCreateFolder.image(color: NCBrandColor.shared.brandElement, size: 50), action: { _ in
-                    guard !appDelegate.activeServerUrl.isEmpty else { return }
-                    let alertController = UIAlertController.createFolder(serverUrl: appDelegate.activeServerUrl, urlBase: appDelegate)
-                    appDelegate.window?.rootViewController?.present(alertController, animated: true, completion: nil)
-                }
-            )
+                         icon: imageCreateFolder.image(color: NCBrandColor.shared.brandElement, size: 50), action: { _ in
+                             guard !appDelegate.activeServerUrl.isEmpty else { return }
+                             let alertController = UIAlertController.createFolder(serverUrl: appDelegate.activeServerUrl, urlBase: appDelegate)
+                             appDelegate.window?.rootViewController?.present(alertController, animated: true, completion: nil)
+                         }
+                        )
         )
 
-        // Folder encrypted (ONLY ROOT)
-        // if NCUtilityFileSystem.shared.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId) == appDelegate.activeServerUrl && CCUtility.isEnd(toEndEnabled: appDelegate.account) {
+        // Folder encrypted
         if !isDirectoryE2EE && CCUtility.isEnd(toEndEnabled: appDelegate.account) {
             actions.append(
                 NCMenuAction(title: NSLocalizedString("_create_folder_e2ee_", comment: ""),

+ 1 - 1
iOSClient/Menu/NCCollectionViewCommon+Menu.swift

@@ -155,7 +155,7 @@ extension NCCollectionViewCommon {
                     order: 30,
                     action: { _ in
                         Task {
-                            let error = await NCNetworkingE2EEMarkFolder().markFolderE2ee(account: metadata.account, fileName: metadata.fileName, serverUrl: metadata.serverUrl, userId: metadata.userId, withPush: false)
+                            let error = await NCNetworkingE2EEMarkFolder().markFolderE2ee(account: metadata.account, fileName: metadata.fileName, serverUrl: metadata.serverUrl, userId: metadata.userId)
                             if error != .success {
                                 NCContentPresenter.shared.showError(error: error)
                             }

+ 7 - 3
iOSClient/Menu/NCShare+Menu.swift

@@ -22,6 +22,7 @@
 //
 
 import Foundation
+import NextcloudKit
 
 extension NCShare {
     func toggleShareMenu(for share: tableShare) {
@@ -63,12 +64,15 @@ extension NCShare {
                 icon: NCUtility.shared.loadImage(named: "trash"),
                 action: { _ in
                     Task {
-                        if let metadata = self.metadata, metadata.e2eEncrypted && NCGlobal.shared.capabilityE2EEApiVersion == NCGlobal.shared.e2eeVersionV20 {
+                        if share.shareType != NCShareCommon.shared.SHARE_TYPE_LINK, let metadata = self.metadata, metadata.e2eEncrypted && NCGlobal.shared.capabilityE2EEApiVersion == NCGlobal.shared.e2eeVersionV20 {
                             let serverUrl = metadata.serverUrl + "/" + metadata.fileName
+                            if NCNetworkingE2EE.shared.isInUpload(account: metadata.account, serverUrl: serverUrl) {
+                                let error = NKError(errorCode: NCGlobal.shared.errorE2EEUploadInProgress, errorDescription: NSLocalizedString("_e2e_in_upload_", comment: ""))
+                                return NCContentPresenter.shared.showInfo(error: error)
+                            }
                             let error = await NCNetworkingE2EE().uploadMetadata(account: metadata.account, serverUrl: serverUrl, userId: metadata.userId, addUserId: nil, removeUserId: share.shareWith)
                             if error != .success {
-                                NCContentPresenter.shared.showError(error: error)
-                                return
+                                return NCContentPresenter.shared.showError(error: error)
                             }
                         }
                         self.networking?.unShare(idShare: share.idShare)

+ 11 - 7
iOSClient/NCGlobal.swift

@@ -232,13 +232,17 @@ class NCGlobal: NSObject {
     @objc let errorE2EEKeyDecodeMetadata: Int       = -98004
     @objc let errorE2EEKeyVerifySignature: Int      = -98005
     @objc let errorE2EEKeyCiphertext: Int           = -98006
-    @objc let errorE2EEJSon: Int                    = -98007
-    @objc let errorE2EELock: Int                    = -98008
-    @objc let errorE2EEEncryptFile: Int             = -98009
-    @objc let errorE2EEEncryptPayloadFile: Int      = -98010
-    @objc let errorE2EECounter: Int                 = -98011
-    @objc let errorE2EEGenerateKey: Int             = -98012
-    @objc let errorE2EEEncodedKey: Int              = -98013
+    @objc let errorE2EEKeyFiledropCiphertext: Int   = -98007
+    @objc let errorE2EEJSon: Int                    = -98008
+    @objc let errorE2EELock: Int                    = -98009
+    @objc let errorE2EEEncryptFile: Int             = -98010
+    @objc let errorE2EEEncryptPayloadFile: Int      = -98011
+    @objc let errorE2EECounter: Int                 = -98012
+    @objc let errorE2EEGenerateKey: Int             = -98013
+    @objc let errorE2EEEncodedKey: Int              = -98014
+    @objc let errorE2EENoUserFound: Int             = -98015
+    @objc let errorE2EEUploadInProgress: Int        = -98016
+
 
     // Constants to identify the different permissions of a file
     //

+ 177 - 128
iOSClient/Networking/E2EE/NCEndToEndMetadataV20.swift

@@ -55,14 +55,13 @@ extension NCEndToEndMetadata {
             let userId: String
             let certificate: String
             let encryptedMetadataKey: String?
-            let encryptedFiledropKey: String?
         }
 
         struct Filedrop: Codable {
             let ciphertext: String?
             let nonce: String?
             let authenticationTag: String?
-            let users: [String: UsersFiledrop]?
+            let users: [UsersFiledrop]?
 
             struct UsersFiledrop: Codable {
                 let userId: String?
@@ -72,7 +71,7 @@ extension NCEndToEndMetadata {
 
         let metadata: Metadata
         let users: [Users]?
-        let filedrop: [String: Filedrop]?
+        let filedrop: [Filedrop]?
         let version: String
     }
 
@@ -101,8 +100,7 @@ extension NCEndToEndMetadata {
 
     func encodeMetadataV20(account: String, serverUrl: String, ocIdServerUrl: String, userId: String, addUserId: String?, addCertificate: String?, removeUserId: String?) -> (metadata: String?, signature: String?, counter: Int, error: NKError) {
 
-        guard let keyGenerated = NCEndToEndEncryption.sharedManager()?.generateKey() as? Data,
-              let directoryTop = NCUtility.shared.getDirectoryE2EETop(serverUrl: serverUrl, account: account) else {
+        guard let directoryTop = NCUtility.shared.getDirectoryE2EETop(serverUrl: serverUrl, account: account) else {
             return (nil, nil, 0, NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: "_e2e_error_"))
         }
 
@@ -110,62 +108,84 @@ extension NCEndToEndMetadata {
         var metadataKey: String?
         var keyChecksums: [String] = []
         var usersCodable: [E2eeV20.Users] = []
-        var filedropCodable: [String: E2eeV20.Filedrop] = [:]
+        var usersFileDropCodable: [E2eeV20.Filedrop.UsersFiledrop] = []
+        var filesCodable: [String: E2eeV20.Files] = [:]
+        var filedropCodable: [E2eeV20.Filedrop] = []
         var folders: [String: String] = [:]
         var counter: Int = 1
 
-        func addUser(userId: String?, certificate: String?) {
+        func addUser(userId: String?, certificate: String?, key: Data) {
 
             guard let userId, let certificate else { return }
-            let decryptedMetadataKey = keyGenerated
-            let metadataKey = keyGenerated.base64EncodedString()
-
-            if let metadataKeyEncrypted = NCEndToEndEncryption.sharedManager().encryptAsymmetricData(keyGenerated, certificate: certificate) {
 
+            if let metadataKeyEncrypted = NCEndToEndEncryption.sharedManager().encryptAsymmetricData(key, certificate: certificate) {
                 let encryptedMetadataKey = metadataKeyEncrypted.base64EncodedString()
-                NCManageDatabase.shared.addE2EUsersV2(account: account, serverUrl: serverUrl, ocIdServerUrl: ocIdServerUrl, userId: userId, certificate: certificate, encryptedFiledropKey: nil, encryptedMetadataKey: encryptedMetadataKey, decryptedFiledropKey: nil, decryptedMetadataKey: decryptedMetadataKey, filedropKey: nil, metadataKey: metadataKey)
+
+                NCManageDatabase.shared.addE2EUsersV2(account: account, serverUrl: serverUrl, ocIdServerUrl: ocIdServerUrl, userId: userId, certificate: certificate, encryptedMetadataKey: encryptedMetadataKey, metadataKey: key)
             }
         }
 
         if isDirectoryTop {
 
-            addUser(userId: userId, certificate: CCUtility.getEndToEndCertificate(account))
-            addUser(userId: addUserId, certificate: addCertificate)
-
+            guard var key = NCEndToEndEncryption.sharedManager()?.generateKey() as? Data else {
+                return (nil, nil, 0, NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: "_e2e_error_"))
+            }
+            if let tableUserId = NCManageDatabase.shared.getE2EUsersV2(account: account, ocIdServerUrl: directoryTop.ocId, userId: userId),
+               let metadataKey = tableUserId.metadataKey {
+                key = metadataKey
+            } else {
+                addUser(userId: userId, certificate: CCUtility.getEndToEndCertificate(account), key: key)
+            }
+            // ADDUSERID
+            if let addUserId {
+                addUser(userId: addUserId, certificate: addCertificate, key: key)
+            }
+            // REMOVEUSERID
             if let removeUserId {
                 NCManageDatabase.shared.deleteE2EUsersV2(account: account, ocIdServerUrl: ocIdServerUrl, userId: removeUserId)
             }
-
+            // FOR SECURITY recreate all users with key
             if let users = NCManageDatabase.shared.getE2EUsersV2(account: account, ocIdServerUrl: ocIdServerUrl) {
                 for user in users {
-                    addUser(userId: user.userId, certificate: user.certificate)
+                    addUser(userId: user.userId, certificate: user.certificate, key: key)
                 }
             }
+
+            metadataKey = key.base64EncodedString()
+
+        } else {
+
+            guard let tableUserId = NCManageDatabase.shared.getE2EUsersV2(account: account, ocIdServerUrl: directoryTop.ocId, userId: userId), let key = tableUserId.metadataKey else {
+                return (nil, nil, 0, NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: "_e2e_error_"))
+            }
+
+            metadataKey = key.base64EncodedString()
         }
 
-        if let e2eUsers = NCManageDatabase.shared.getE2EUsersV2(account: account, ocIdServerUrl: directoryTop.ocId) {
-            for user in e2eUsers {
+        // USERS
+        // CHECKSUM
+        //
+        if let users = NCManageDatabase.shared.getE2EUsersV2(account: account, ocIdServerUrl: directoryTop.ocId) {
+            for user in users {
                 if isDirectoryTop {
-                    usersCodable.append(E2eeV20.Users(userId: user.userId, certificate: user.certificate, encryptedMetadataKey: user.encryptedMetadataKey, encryptedFiledropKey: user.encryptedFiledropKey))
+                    usersCodable.append(E2eeV20.Users(userId: user.userId, certificate: user.certificate, encryptedMetadataKey: user.encryptedMetadataKey))
+                    // usersFileDropCodable.append(E2eeV20.Filedrop.UsersFiledrop(userId: user.userId, encryptedFiledropKey: user.encryptedFiledropKey))
                 }
-                if let hash = NCEndToEndEncryption.sharedManager().createSHA256(user.decryptedMetadataKey) {
+                if let hash = NCEndToEndEncryption.sharedManager().createSHA256(user.metadataKey) {
                     keyChecksums.append(hash)
                 }
-                if let addUserId, user.userId == addUserId {
-                    metadataKey = user.metadataKey
-                } else if user.userId == userId {
-                    metadataKey = user.metadataKey
-                }
             }
         }
 
+        // COUNTER + 1
+        //
         if let resultCounter = NCManageDatabase.shared.getCounterE2eMetadataV2(account: account, ocIdServerUrl: ocIdServerUrl) {
             counter = resultCounter + 1
         }
 
-        // Create ciphertext
+        // CIPERTEXT
+        //
         let e2eEncryptions = NCManageDatabase.shared.getE2eEncryptions(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl))
-        var filesCodable: [String: E2eeV20.Files] = [:]
 
         for e2eEncryption in e2eEncryptions {
             if e2eEncryption.blob == "files" {
@@ -173,26 +193,45 @@ extension NCEndToEndMetadata {
                 filesCodable.updateValue(file, forKey: e2eEncryption.fileNameIdentifier)
             } else if e2eEncryption.blob == "folders" {
                 folders[e2eEncryption.fileNameIdentifier] = e2eEncryption.fileName
+            } else if e2eEncryption.blob == "filedrop" {
+                let filedrop = E2eeV20.Files(authenticationTag: e2eEncryption.authenticationTag, filename: e2eEncryption.fileName, key: e2eEncryption.key, mimetype: e2eEncryption.mimeType, nonce: e2eEncryption.initializationVector)
+                var authenticationTag: NSString?
+                var initializationVector: NSString?
+                do {
+                    let json = try JSONEncoder().encode(filedrop)
+                    let jsonZip = try json.gzipped()
+                    let ciphertext = NCEndToEndEncryption.sharedManager().encryptPayloadFile(jsonZip, key: metadataKey, initializationVector: &initializationVector, authenticationTag: &authenticationTag)
+
+                    guard var ciphertext, let initializationVector = initializationVector as? String, let authenticationTag = authenticationTag as? String else {
+                        return (nil, nil, counter, NKError(errorCode: NCGlobal.shared.errorE2EEEncryptPayloadFile, errorDescription: "_e2e_error_"))
+                    }
+
+                    // Add initializationVector [ANDROID]
+                    ciphertext = ciphertext + "|" + initializationVector
+
+                    let filedrop = E2eeV20.Filedrop(ciphertext: ciphertext, nonce: initializationVector, authenticationTag: authenticationTag, users: usersFileDropCodable)
+                    filedropCodable.append(filedrop)
+
+                } catch let error {
+                    return (nil, nil, counter, NKError(errorCode: NCGlobal.shared.errorE2EEJSon, errorDescription: error.localizedDescription))
+                }
             }
         }
 
-        let ciphertext = E2eeV20.ciphertext(counter: counter, deleted: false, keyChecksums: keyChecksums, files: filesCodable, folders: folders)
-        var authenticationTag: NSString?
-        var initializationVector: NSString?
-
         do {
-            let json = try JSONEncoder().encode(ciphertext)
+            var authenticationTag: NSString?
+            var initializationVector: NSString?
+            let json = try JSONEncoder().encode(E2eeV20.ciphertext(counter: counter, deleted: false, keyChecksums: keyChecksums, files: filesCodable, folders: folders))
             let jsonZip = try json.gzipped()
-            let ciphertext = NCEndToEndEncryption.sharedManager().encryptPayloadFile(jsonZip, key: metadataKey, initializationVector: &initializationVector, authenticationTag: &authenticationTag)
-
-            guard var ciphertext, let initializationVector = initializationVector as? String, let authenticationTag = authenticationTag as? String else {
+            let ciphertextMetadata = NCEndToEndEncryption.sharedManager().encryptPayloadFile(jsonZip, key: metadataKey, initializationVector: &initializationVector, authenticationTag: &authenticationTag)
+            guard var ciphertextMetadata, let initializationVector = initializationVector as? String, let authenticationTag = authenticationTag as? String else {
                 return (nil, nil, counter, NKError(errorCode: NCGlobal.shared.errorE2EEEncryptPayloadFile, errorDescription: "_e2e_error_"))
             }
 
             // Add initializationVector [ANDROID]
-            ciphertext = ciphertext + "|" + initializationVector
+            ciphertextMetadata = ciphertextMetadata + "|" + initializationVector
 
-            let metadataCodable = E2eeV20.Metadata(ciphertext: ciphertext, nonce: initializationVector, authenticationTag: authenticationTag)
+            let metadataCodable = E2eeV20.Metadata(ciphertext: ciphertextMetadata, nonce: initializationVector, authenticationTag: authenticationTag)
             let e2eeCodable = E2eeV20(metadata: metadataCodable, users: usersCodable, filedrop: filedropCodable, version: NCGlobal.shared.e2eeVersionV20)
             let e2eeData = try JSONEncoder().encode(e2eeCodable)
             e2eeData.printJson()
@@ -254,124 +293,134 @@ extension NCEndToEndMetadata {
 
             let metadata = json.metadata
             let users = json.users
-            let filedrop = json.filedrop
+            let filesdrop = json.filedrop
             let version = json.version as String? ?? NCGlobal.shared.e2eeVersionV20
 
+            // SAVE IN DB ALL USER
+            //
             if let users {
                 for user in users {
-
-                    var decryptedMetadataKey: Data?
-                    var decryptedFiledropKey: Data?
-                    var metadataKey: String?
-                    var filedropKey: String?
-
+                    var metadataKey: Data?
                     if let encryptedMetadataKey = user.encryptedMetadataKey {
                         let data = Data(base64Encoded: encryptedMetadataKey)
                         if let decrypted = NCEndToEndEncryption.sharedManager().decryptAsymmetricData(data, privateKey: CCUtility.getEndToEndPrivateKey(account)) {
-                            decryptedMetadataKey = decrypted
-                            metadataKey = decrypted.base64EncodedString()
-                        }
-                    }
-
-                    if let encryptedFiledropKey = user.encryptedFiledropKey {
-                        let data = Data(base64Encoded: encryptedFiledropKey)
-                        if let decrypted = NCEndToEndEncryption.sharedManager().decryptAsymmetricData(data, privateKey: CCUtility.getEndToEndPrivateKey(account)) {
-                            decryptedFiledropKey = decrypted
-                            filedropKey = decrypted.base64EncodedString()
+                            metadataKey = decrypted
                         }
                     }
-
-                    NCManageDatabase.shared.addE2EUsersV2(account: account,
-                                                          serverUrl: serverUrl,
-                                                          ocIdServerUrl: ocIdServerUrl,
-                                                          userId: user.userId,
-                                                          certificate: user.certificate,
-                                                          encryptedFiledropKey: user.encryptedFiledropKey,
-                                                          encryptedMetadataKey: user.encryptedMetadataKey,
-                                                          decryptedFiledropKey: decryptedFiledropKey,
-                                                          decryptedMetadataKey: decryptedMetadataKey,
-                                                          filedropKey: filedropKey,
-                                                          metadataKey: metadataKey)
+                    NCManageDatabase.shared.addE2EUsersV2(account: account, serverUrl: serverUrl, ocIdServerUrl: ocIdServerUrl, userId: user.userId, certificate: user.certificate, encryptedMetadataKey: user.encryptedMetadataKey, metadataKey: metadataKey)
                 }
             }
 
-            if let tableE2eUsersV2 = NCManageDatabase.shared.getE2EUsersV2(account: account, ocIdServerUrl: directoryTop.ocId, userId: userId),
-               let metadataKey = tableE2eUsersV2.metadataKey,
-               let decryptedMetadataKey = tableE2eUsersV2.decryptedMetadataKey {
-
-                // SIGNATURE CHECK
-                guard let signature,
-                      verifySignature(account: account, signature: signature, userId: tableE2eUsersV2.userId, metadata: metadata, users: users, version: version, certificate: tableE2eUsersV2.certificate) else {
-                    return NKError(errorCode: NCGlobal.shared.errorE2EEKeyVerifySignature, errorDescription: "_e2e_error_")
+            // GET metadataKey, decryptedMetadataKey
+            //
+            guard let tableE2eUsersV2 = NCManageDatabase.shared.getE2EUsersV2(account: account, ocIdServerUrl: directoryTop.ocId, userId: userId),
+                  let metadataKey = tableE2eUsersV2.metadataKey?.base64EncodedString(),
+                  let decryptedMetadataKey = tableE2eUsersV2.metadataKey else {
+                return NKError(errorCode: NCGlobal.shared.errorE2EENoUserFound, errorDescription: "_e2e_error_")
+            }
 
-                }
+            // SIGNATURE CHECK
+            //
+            guard let signature,
+                  verifySignature(account: account, signature: signature, userId: tableE2eUsersV2.userId, metadata: metadata, users: users, version: version, certificate: tableE2eUsersV2.certificate) else {
+                return NKError(errorCode: NCGlobal.shared.errorE2EEKeyVerifySignature, errorDescription: "_e2e_error_")
 
-                // CIPHERTEXT
-                guard let decrypted = NCEndToEndEncryption.sharedManager().decryptPayloadFile(metadata.ciphertext, key: metadataKey, initializationVector: metadata.nonce, authenticationTag: metadata.authenticationTag),
-                      decrypted.isGzipped else {
-                    return NKError(errorCode: NCGlobal.shared.errorE2EEKeyCiphertext, errorDescription: "_e2e_error_")
-                }
+            }
 
-                let data = try decrypted.gunzipped()
-                if let jsonText = String(data: data, encoding: .utf8) {
-                    print(jsonText)
+            // FILEDROP
+            /*
+            if let filesdrop, let filedropKey = tableE2eUsersV2.filedropKey?.base64EncodedString() {
+                for filedrop in filesdrop {
+                    guard let decryptedFiledrop = NCEndToEndEncryption.sharedManager().decryptPayloadFile(filedrop.ciphertext, key: filedropKey, initializationVector: filedrop.nonce, authenticationTag: filedrop.authenticationTag),
+                          decryptedFiledrop.isGzipped else {
+                        return NKError(errorCode: NCGlobal.shared.errorE2EEKeyFiledropCiphertext, errorDescription: "_e2e_error_")
+                    }
+                    let data = try decryptedFiledrop.gunzipped()
+                    if let jsonText = String(data: data, encoding: .utf8) { print(jsonText) }
+                    let file = try JSONDecoder().decode(E2eeV20.Files.self, from: data)
+                    print(file)
+                    addE2eEncryption(fileNameIdentifier: file.key, filename: file.filename, authenticationTag: file.authenticationTag, key: file.key, initializationVector: file.nonce, metadataKey: filedropKey, mimetype: file.mimetype, blob: "filedrop")
                 }
+            }
+            */
 
-                let json = try JSONDecoder().decode(E2eeV20.ciphertext.self, from: data)
-
-                // Check "checksums"
-                guard let keyChecksums = json.keyChecksums,
-                      let hash = NCEndToEndEncryption.sharedManager().createSHA256(decryptedMetadataKey),
-                      keyChecksums.contains(hash) else {
-                    return NKError(errorCode: NCGlobal.shared.errorE2EEKeyChecksums, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))
-                }
+            // CIPHERTEXT METADATA
+            //
+            guard let decryptedMetadata = NCEndToEndEncryption.sharedManager().decryptPayloadFile(metadata.ciphertext, key: metadataKey, initializationVector: metadata.nonce, authenticationTag: metadata.authenticationTag),
+                  decryptedMetadata.isGzipped else {
+                return NKError(errorCode: NCGlobal.shared.errorE2EEKeyCiphertext, errorDescription: "_e2e_error_")
+            }
 
-                print("\n\nCOUNTER -------------------------------")
-                print("Counter: \(json.counter)")
+            let data = try decryptedMetadata.gunzipped()
+            if let jsonText = String(data: data, encoding: .utf8) { print(jsonText) }
+            let jsonCiphertextMetadata = try JSONDecoder().decode(E2eeV20.ciphertext.self, from: data)
 
-                // Check "counter"
-                if let resultCounter = NCManageDatabase.shared.getCounterE2eMetadataV2(account: account, ocIdServerUrl: ocIdServerUrl) {
-                    print("Counter saved: \(resultCounter)")
-                    if json.counter > resultCounter {
-                        return NKError(errorCode: NCGlobal.shared.errorE2EECounter, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))
-                    }
-                } else {
-                    print("Counter RESET")
-                    NCManageDatabase.shared.updateCounterE2eMetadataV2(account: account, ocIdServerUrl: ocIdServerUrl, counter: json.counter)
-                }
+            // CHECKSUM CHECK
+            //
+            guard let keyChecksums = jsonCiphertextMetadata.keyChecksums,
+                  let hash = NCEndToEndEncryption.sharedManager().createSHA256(decryptedMetadataKey),
+                  keyChecksums.contains(hash) else {
+                return NKError(errorCode: NCGlobal.shared.errorE2EEKeyChecksums, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))
+            }
 
-                // Check "deleted"
-                if let deleted = json.deleted, deleted {
-                    // TODO: We need to check deleted, id yes ???
+            print("\n\nCOUNTER -------------------------------")
+            print("Counter: \(jsonCiphertextMetadata.counter)")
+
+            // COUNTER CHECK
+            //
+            if let resultCounter = NCManageDatabase.shared.getCounterE2eMetadataV2(account: account, ocIdServerUrl: ocIdServerUrl) {
+                print("Counter saved: \(resultCounter)")
+                if jsonCiphertextMetadata.counter < resultCounter {
+                    // TODO: whats happen with < ?
+                    NCContentPresenter.shared.showError(error: NKError(errorCode: NCGlobal.shared.errorE2EECounter, errorDescription: NSLocalizedString("_e2e_error_", comment: "")))
+                } else if jsonCiphertextMetadata.counter > resultCounter {
+                    print("Counter UPDATED: \(jsonCiphertextMetadata.counter)")
+                    NCManageDatabase.shared.updateCounterE2eMetadataV2(account: account, ocIdServerUrl: ocIdServerUrl, counter: jsonCiphertextMetadata.counter)
                 }
+            } else {
+                print("Counter RESET: \(jsonCiphertextMetadata.counter)")
+                NCManageDatabase.shared.updateCounterE2eMetadataV2(account: account, ocIdServerUrl: ocIdServerUrl, counter: jsonCiphertextMetadata.counter)
+            }
 
-                NCManageDatabase.shared.addE2eMetadataV2(account: account, serverUrl: serverUrl, ocIdServerUrl: ocIdServerUrl, keyChecksums: json.keyChecksums, deleted: json.deleted ?? false, folders: json.folders, version: version)
-
-                if let files = json.files {
-                    print("\nFILES ---------------------------------\n")
-                    for file in files {
-                        addE2eEncryption(fileNameIdentifier: file.key, filename: file.value.filename, authenticationTag: file.value.authenticationTag, key: file.value.key, initializationVector: file.value.nonce, metadataKey: metadataKey, mimetype: file.value.mimetype, blob: "files")
+            // DELETE CHECK
+            //
+            if let deleted = jsonCiphertextMetadata.deleted, deleted {
+                // TODO: We need to check deleted, id yes ???
+            }
 
-                        print("filename: \(file.value.filename)")
-                        print("fileNameIdentifier: \(file.key)")
-                        print("mimetype: \(file.value.mimetype)")
-                        print("\n")
-                    }
+            NCManageDatabase.shared.addE2eMetadataV2(account: account,
+                                                     serverUrl: serverUrl,
+                                                     ocIdServerUrl: ocIdServerUrl,
+                                                     keyChecksums: jsonCiphertextMetadata.keyChecksums,
+                                                     deleted: jsonCiphertextMetadata.deleted ?? false,
+                                                     folders: jsonCiphertextMetadata.folders,
+                                                     version: version)
+
+            if let files = jsonCiphertextMetadata.files {
+                print("\nFILES ---------------------------------\n")
+                for file in files {
+                    addE2eEncryption(fileNameIdentifier: file.key, filename: file.value.filename, authenticationTag: file.value.authenticationTag, key: file.value.key, initializationVector: file.value.nonce, metadataKey: metadataKey, mimetype: file.value.mimetype, blob: "files")
+
+                    print("filename: \(file.value.filename)")
+                    print("fileNameIdentifier: \(file.key)")
+                    print("mimetype: \(file.value.mimetype)")
+                    print("\n")
                 }
+            }
 
-                if let folders = json.folders {
-                    print("FOLDERS--------------------------------\n")
-                    for folder in folders {
-                        addE2eEncryption(fileNameIdentifier: folder.key, filename: folder.value, authenticationTag: metadata.authenticationTag, key: metadataKey, initializationVector: metadata.nonce, metadataKey: metadataKey, mimetype: "httpd/unix-directory", blob: "folders")
+            if let folders = jsonCiphertextMetadata.folders {
+                print("FOLDERS--------------------------------\n")
+                for folder in folders {
+                    addE2eEncryption(fileNameIdentifier: folder.key, filename: folder.value, authenticationTag: metadata.authenticationTag, key: metadataKey, initializationVector: metadata.nonce, metadataKey: metadataKey, mimetype: "httpd/unix-directory", blob: "folders")
 
-                        print("filename: \(folder.value)")
-                        print("fileNameIdentifier: \(folder.key)")
-                        print("\n")
-                    }
+                    print("filename: \(folder.value)")
+                    print("fileNameIdentifier: \(folder.key)")
+                    print("\n")
                 }
-
-                print("---------------------------------------\n\n")
             }
+
+            print("---------------------------------------\n\n")
+
         } catch let error {
             return NKError(errorCode: NCGlobal.shared.errorE2EEJSon, errorDescription: error.localizedDescription)
         }

+ 26 - 8
iOSClient/Networking/E2EE/NCNetworkingE2EE.swift

@@ -23,6 +23,23 @@ import Foundation
 import NextcloudKit
 
 class NCNetworkingE2EE: NSObject {
+    public static let shared: NCNetworkingE2EE = {
+        let instance = NCNetworkingE2EE()
+        return instance
+    }()
+
+    func getRoute() -> String {
+        let e2eeRouteV1 = "v1"
+        let e2eeRouteV2 = "v2"
+        return (NCGlobal.shared.capabilityE2EEApiVersion == NCGlobal.shared.e2eeVersionV20) ? e2eeRouteV1 : e2eeRouteV1
+    }
+
+    func isInUpload(account: String, serverUrl: String) -> Bool {
+
+        let counter = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (status == %d OR status == %d OR status == %d)", account, serverUrl, NCGlobal.shared.metadataStatusWaitUpload, NCGlobal.shared.metadataStatusInUpload, NCGlobal.shared.metadataStatusUploading)).count
+
+        return counter > 0 ? true : false
+    }
 
     func generateRandomIdentifier() -> String {
 
@@ -31,7 +48,7 @@ class NCNetworkingE2EE: NSObject {
         return UUID
     }
 
-    func uploadMetadata(account: String, serverUrl: String, userId: String, addUserId: String?, removeUserId: String?) async -> NKError {
+    func uploadMetadata(account: String, serverUrl: String, userId: String, addUserId: String? = nil, removeUserId: String? = nil) async -> NKError {
 
         var addCertificate: String?
         var method = "POST"
@@ -57,7 +74,7 @@ class NCNetworkingE2EE: NSObject {
 
         // METHOD
         //
-        let resultsGetE2EEMetadata = await NextcloudKit.shared.getE2EEMetadata(fileId: fileId, e2eToken: e2eToken)
+        let resultsGetE2EEMetadata = await NextcloudKit.shared.getE2EEMetadata(fileId: fileId, e2eToken: e2eToken, route: getRoute())
         if resultsGetE2EEMetadata.error == .success {
             method = "PUT"
         } else if resultsGetE2EEMetadata.error.errorCode != NCGlobal.shared.errorResourceNotFound {
@@ -95,7 +112,7 @@ class NCNetworkingE2EE: NSObject {
                           fileId: String,
                           e2eToken: String) async -> NKError {
 
-        let resultsGetE2EEMetadata = await NextcloudKit.shared.getE2EEMetadata(fileId: fileId, e2eToken: e2eToken)
+        let resultsGetE2EEMetadata = await NextcloudKit.shared.getE2EEMetadata(fileId: fileId, e2eToken: e2eToken, route: getRoute())
         guard resultsGetE2EEMetadata.error == .success, let e2eMetadata = resultsGetE2EEMetadata.e2eMetadata else {
             return resultsGetE2EEMetadata.error
         }
@@ -119,12 +136,12 @@ class NCNetworkingE2EE: NSObject {
                         addCertificate: String? = nil,
                         removeUserId: String? = nil) async -> NKError {
 
-        let resultsEncodeMetadata = NCEndToEndMetadata().encodeMetadata(account: account, serverUrl: serverUrl, userId: userId, addCertificate: addCertificate, removeUserId: removeUserId)
+        let resultsEncodeMetadata = NCEndToEndMetadata().encodeMetadata(account: account, serverUrl: serverUrl, userId: userId, addUserId: addUserId, addCertificate: addCertificate, removeUserId: removeUserId)
         guard resultsEncodeMetadata.error == .success, let e2eMetadata = resultsEncodeMetadata.metadata else {
             return resultsEncodeMetadata.error
         }
 
-        let putE2EEMetadataResults = await NextcloudKit.shared.putE2EEMetadata(fileId: fileId, e2eToken: e2eToken, e2eMetadata: e2eMetadata, signature: resultsEncodeMetadata.signature, method: method)
+        let putE2EEMetadataResults = await NextcloudKit.shared.putE2EEMetadata(fileId: fileId, e2eToken: e2eToken, e2eMetadata: e2eMetadata, signature: resultsEncodeMetadata.signature, method: method, route: getRoute())
         guard putE2EEMetadataResults.error == .success else {
             return putE2EEMetadataResults.error
         }
@@ -156,7 +173,7 @@ class NCNetworkingE2EE: NSObject {
             e2eCounter = "\(counter)"
         }
 
-        let resultsLockE2EEFolder = await NextcloudKit.shared.lockE2EEFolder(fileId: directory.fileId, e2eToken: e2eToken, e2eCounter: e2eCounter, method: "POST")
+        let resultsLockE2EEFolder = await NextcloudKit.shared.lockE2EEFolder(fileId: directory.fileId, e2eToken: e2eToken, e2eCounter: e2eCounter, method: "POST", route: getRoute())
         if resultsLockE2EEFolder.error == .success, let e2eToken = resultsLockE2EEFolder.e2eToken {
             NCManageDatabase.shared.setE2ETokenLock(account: account, serverUrl: serverUrl, fileId: directory.fileId, e2eToken: e2eToken)
         }
@@ -170,7 +187,7 @@ class NCNetworkingE2EE: NSObject {
             return
         }
 
-        let resultsLockE2EEFolder = await NextcloudKit.shared.lockE2EEFolder(fileId: tableLock.fileId, e2eToken: tableLock.e2eToken, e2eCounter: nil, method: "DELETE")
+        let resultsLockE2EEFolder = await NextcloudKit.shared.lockE2EEFolder(fileId: tableLock.fileId, e2eToken: tableLock.e2eToken, e2eCounter: nil, method: "DELETE", route: getRoute())
         if resultsLockE2EEFolder.error == .success {
             NCManageDatabase.shared.deleteE2ETokenLock(account: account, serverUrl: serverUrl)
         }
@@ -179,11 +196,12 @@ class NCNetworkingE2EE: NSObject {
     }
 
     func unlockAll(account: String) {
+
         guard CCUtility.isEnd(toEndEnabled: account) else { return }
 
         Task {
             for result in NCManageDatabase.shared.getE2EAllTokenLock(account: account) {
-                let resultsLockE2EEFolder = await NextcloudKit.shared.lockE2EEFolder(fileId: result.fileId, e2eToken: result.e2eToken, e2eCounter: nil, method: "DELETE")
+                let resultsLockE2EEFolder = await NextcloudKit.shared.lockE2EEFolder(fileId: result.fileId, e2eToken: result.e2eToken, e2eCounter: nil, method: "DELETE", route: getRoute())
                 if resultsLockE2EEFolder.error == .success {
                     NCManageDatabase.shared.deleteE2ETokenLock(account: account, serverUrl: result.serverUrl)
                 }

+ 23 - 20
iOSClient/Networking/E2EE/NCNetworkingE2EECreateFolder.swift

@@ -28,21 +28,24 @@ import Foundation
 
 class NCNetworkingE2EECreateFolder: NSObject {
 
-    let networkingE2EE = NCNetworkingE2EE()
-
     func createFolder(fileName: String, serverUrl: String, account: String, urlBase: String, userId: String, withPush: Bool) async -> NKError {
 
-        let fileNameIdentifier = networkingE2EE.generateRandomIdentifier()
+        let fileNameIdentifier = NCNetworkingE2EE.shared.generateRandomIdentifier()
         let serverUrlFileName = serverUrl + "/" + fileNameIdentifier
         let fileNameFolder = NCUtilityFileSystem.shared.createFileName(CCUtility.removeForbiddenCharactersServer(fileName)!, serverUrl: serverUrl, account: account)
         if fileNameFolder.isEmpty {
             return NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))
         }
-
         guard let directory = NCManageDatabase.shared.getTableDirectory(predicate:  NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl)) else {
             return NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))
         }
 
+        // TEST UPLOAD IN PROGRESS
+        //
+        if NCNetworkingE2EE.shared.isInUpload(account: account, serverUrl: serverUrl) {
+            return NKError(errorCode: NCGlobal.shared.errorE2EEUploadInProgress, errorDescription: NSLocalizedString("_e2e_in_upload_", comment: ""))
+        }
+
         func sendE2ee(e2eToken: String, fileId: String) async -> NKError {
 
             var key: NSString?
@@ -51,7 +54,7 @@ class NCNetworkingE2EECreateFolder: NSObject {
 
             // DOWNLOAD METADATA
             //
-            let errorDownloadMetadata = await networkingE2EE.downloadMetadata(account: account, serverUrl: serverUrl, urlBase: urlBase, userId: userId, fileId: fileId, e2eToken: e2eToken)
+            let errorDownloadMetadata = await NCNetworkingE2EE.shared.downloadMetadata(account: account, serverUrl: serverUrl, urlBase: urlBase, userId: userId, fileId: fileId, e2eToken: e2eToken)
             if errorDownloadMetadata == .success {
                 method = "PUT"
             } else if errorDownloadMetadata.errorCode != NCGlobal.shared.errorResourceNotFound {
@@ -85,20 +88,20 @@ class NCNetworkingE2EECreateFolder: NSObject {
 
             // UPLOAD METADATA
             //
-            let uploadMetadataError = await networkingE2EE.uploadMetadata(account: account,
-                                                                          serverUrl: serverUrl,
-                                                                          ocIdServerUrl: directory.ocId,
-                                                                          fileId: fileId,
-                                                                          userId: userId,
-                                                                          e2eToken: e2eToken,
-                                                                          method: method)
+            let uploadMetadataError = await NCNetworkingE2EE.shared.uploadMetadata(account: account,
+                                                                                   serverUrl: serverUrl,
+                                                                                   ocIdServerUrl: directory.ocId,
+                                                                                   fileId: fileId,
+                                                                                   userId: userId,
+                                                                                   e2eToken: e2eToken,
+                                                                                   method: method)
 
             return uploadMetadataError
         }
 
         // LOCK
         //
-        let resultsLock = await networkingE2EE.lock(account: account, serverUrl: serverUrl)
+        let resultsLock = await NCNetworkingE2EE.shared.lock(account: account, serverUrl: serverUrl)
         guard let e2eToken = resultsLock.e2eToken, let fileId = resultsLock.fileId, resultsLock.error == .success else {
             return NKError(errorCode: NCGlobal.shared.errorE2EELock, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))
         }
@@ -107,7 +110,7 @@ class NCNetworkingE2EECreateFolder: NSObject {
         //
         let sendE2eeError = await sendE2ee(e2eToken: e2eToken, fileId: fileId)
         guard sendE2eeError == .success else {
-            await networkingE2EE.unlock(account: account, serverUrl: serverUrl)
+            await NCNetworkingE2EE.shared.unlock(account: account, serverUrl: serverUrl)
             return sendE2eeError
         }
 
@@ -115,27 +118,27 @@ class NCNetworkingE2EECreateFolder: NSObject {
         //
         let resultsCreateFolder = await NextcloudKit.shared.createFolder(serverUrlFileName: serverUrlFileName, options: NKRequestOptions(customHeader: ["e2e-token": e2eToken]))
         guard resultsCreateFolder.error == .success, let ocId = resultsCreateFolder.ocId, let fileId = NCUtility.shared.ocIdToFileId(ocId: ocId) else {
-            await networkingE2EE.unlock(account: account, serverUrl: serverUrl)
+            await NCNetworkingE2EE.shared.unlock(account: account, serverUrl: serverUrl)
             return resultsCreateFolder.error
         }
 
         // MARK FOLDER AS E2EE
         //
-        let resultsMarkE2EEFolder = await NextcloudKit.shared.markE2EEFolder(fileId: fileId, delete: false)
+        let resultsMarkE2EEFolder = await NextcloudKit.shared.markE2EEFolder(fileId: fileId, delete: false, route: NCNetworkingE2EE.shared.getRoute())
         guard resultsMarkE2EEFolder.error == .success  else {
-            await networkingE2EE.unlock(account: account, serverUrl: serverUrl)
+            await NCNetworkingE2EE.shared.unlock(account: account, serverUrl: serverUrl)
             return resultsMarkE2EEFolder.error
         }
 
         // UNLOCK
         //
-        await networkingE2EE.unlock(account: account, serverUrl: serverUrl)
+        await NCNetworkingE2EE.shared.unlock(account: account, serverUrl: serverUrl)
 
-        //
+        // WRITE DB (DIRECTORY - METADATA)
         //
         let resultsReadFileOrFolder = await NextcloudKit.shared.readFileOrFolder(serverUrlFileName: serverUrlFileName, depth: "0")
         guard resultsReadFileOrFolder.error == .success, let file = resultsReadFileOrFolder.files.first else {
-            await networkingE2EE.unlock(account: account, serverUrl: serverUrl)
+            await NCNetworkingE2EE.shared.unlock(account: account, serverUrl: serverUrl)
             return resultsReadFileOrFolder.error
         }
         let metadata = NCManageDatabase.shared.convertFileToMetadata(file, isDirectoryE2EE: true)

+ 19 - 15
iOSClient/Networking/E2EE/NCNetworkingE2EEDelete.swift

@@ -24,32 +24,36 @@ import NextcloudKit
 
 class NCNetworkingE2EEDelete: NSObject {
 
-    let networkingE2EE = NCNetworkingE2EE()
-
     func delete(metadata: tableMetadata) async -> NKError {
 
         guard let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", metadata.account, metadata.serverUrl)) else {
             return NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: "_e2e_error_")
         }
 
+        // TEST UPLOAD IN PROGRESS
+        //
+        if NCNetworkingE2EE.shared.isInUpload(account: metadata.account, serverUrl: metadata.serverUrl) {
+            return NKError(errorCode: NCGlobal.shared.errorE2EEUploadInProgress, errorDescription: NSLocalizedString("_e2e_in_upload_", comment: ""))
+        }
+
         // LOCK
         //
-        let resultsLock = await networkingE2EE.lock(account: metadata.account, serverUrl: metadata.serverUrl)
+        let resultsLock = await NCNetworkingE2EE.shared.lock(account: metadata.account, serverUrl: metadata.serverUrl)
         guard resultsLock.error == .success, let e2eToken = resultsLock.e2eToken, let fileId = resultsLock.fileId else { return resultsLock.error }
 
         // DELETE FILE
         //
         let deleteMetadataPlainError = await NCNetworking.shared.deleteMetadataPlain(metadata, customHeader: ["e2e-token": e2eToken])
         guard deleteMetadataPlainError == .success else {
-            await networkingE2EE.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
+            await NCNetworkingE2EE.shared.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
             return deleteMetadataPlainError
         }
 
         // DOWNLOAD METADATA
         //
-        let errorDownloadMetadata = await networkingE2EE.downloadMetadata(account: metadata.account, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId, fileId: fileId, e2eToken: e2eToken)
+        let errorDownloadMetadata = await NCNetworkingE2EE.shared.downloadMetadata(account: metadata.account, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId, fileId: fileId, e2eToken: e2eToken)
         guard errorDownloadMetadata == .success else {
-            await networkingE2EE.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
+            await NCNetworkingE2EE.shared.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
             return errorDownloadMetadata
         }
 
@@ -59,21 +63,21 @@ class NCNetworkingE2EEDelete: NSObject {
 
         // UPLOAD METADATA
         //
-        let uploadMetadataError = await networkingE2EE.uploadMetadata(account: metadata.account,
-                                                                      serverUrl: metadata.serverUrl,
-                                                                      ocIdServerUrl: directory.ocId,
-                                                                      fileId: fileId,
-                                                                      userId: metadata.userId,
-                                                                      e2eToken: e2eToken,
-                                                                      method: "PUT")
+        let uploadMetadataError = await NCNetworkingE2EE.shared.uploadMetadata(account: metadata.account,
+                                                                               serverUrl: metadata.serverUrl,
+                                                                               ocIdServerUrl: directory.ocId,
+                                                                               fileId: fileId,
+                                                                               userId: metadata.userId,
+                                                                               e2eToken: e2eToken,
+                                                                               method: "PUT")
         guard uploadMetadataError == .success else {
-            await networkingE2EE.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
+            await NCNetworkingE2EE.shared.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
             return uploadMetadataError
         }
 
         // UNLOCK
         //
-        await networkingE2EE.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
+        await NCNetworkingE2EE.shared.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
 
         return NKError()
     }

+ 3 - 7
iOSClient/Networking/E2EE/NCNetworkingE2EEMarkFolder.swift

@@ -24,14 +24,14 @@ import NextcloudKit
 
 class NCNetworkingE2EEMarkFolder: NSObject {
 
-    func markFolderE2ee(account: String, fileName: String, serverUrl: String, userId: String, withPush: Bool) async -> NKError {
+    func markFolderE2ee(account: String, fileName: String, serverUrl: String, userId: String) async -> NKError {
 
         let serverUrlFileName = serverUrl + "/" + fileName
 
         let resultsReadFileOrFolder = await NextcloudKit.shared.readFileOrFolder(serverUrlFileName: serverUrlFileName, depth: "0")
         guard resultsReadFileOrFolder.error == .success, let file = resultsReadFileOrFolder.files.first else { return resultsReadFileOrFolder.error }
 
-        let resultsMarkE2EEFolder = await NextcloudKit.shared.markE2EEFolder(fileId: file.fileId, delete: false)
+        let resultsMarkE2EEFolder = await NextcloudKit.shared.markE2EEFolder(fileId: file.fileId, delete: false, route: NCNetworkingE2EE.shared.getRoute())
         guard resultsMarkE2EEFolder.error == .success else { return resultsMarkE2EEFolder.error }
 
         file.e2eEncrypted = true
@@ -44,11 +44,7 @@ class NCNetworkingE2EEMarkFolder: NSObject {
             NCManageDatabase.shared.updateCounterE2eMetadataV2(account: account, ocIdServerUrl: metadata.ocId, counter: 0)
         }
 
-        if withPush {
-            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterCreateFolder, userInfo: ["ocId": metadata.ocId, "serverUrl": serverUrl, "account": account, "withPush": withPush])
-        } else {
-            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterChangeStatusFolderE2EE, userInfo: ["serverUrl": serverUrl])
-        }
+        NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterCreateFolder, userInfo: ["ocId": metadata.ocId, "serverUrl": serverUrl, "account": account, "withPush": true])
 
         return NKError()
     }

+ 18 - 15
iOSClient/Networking/E2EE/NCNetworkingE2EERename.swift

@@ -24,8 +24,6 @@ import Foundation
 
 class NCNetworkingE2EERename: NSObject {
 
-    let networkingE2EE = NCNetworkingE2EE()
-    
     func rename(metadata: tableMetadata, fileNameNew: String, indexPath: IndexPath) async -> NKError {
 
         // verify if exists the new fileName
@@ -36,16 +34,22 @@ class NCNetworkingE2EERename: NSObject {
             return NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: "_e2e_error_")
         }
 
+        // TEST UPLOAD IN PROGRESS
+        //
+        if NCNetworkingE2EE.shared.isInUpload(account: metadata.account, serverUrl: metadata.serverUrl) {
+            return NKError(errorCode: NCGlobal.shared.errorE2EEUploadInProgress, errorDescription: NSLocalizedString("_e2e_in_upload_", comment: ""))
+        }
+
         // LOCK
         //
-        let resultsLock = await networkingE2EE.lock(account: metadata.account, serverUrl: metadata.serverUrl)
+        let resultsLock = await NCNetworkingE2EE.shared.lock(account: metadata.account, serverUrl: metadata.serverUrl)
         guard resultsLock.error == .success, let e2eToken = resultsLock.e2eToken, let fileId = resultsLock.fileId else { return resultsLock.error }
 
         // DOWNLOAD METADATA
         //
-        let errorDownloadMetadata = await networkingE2EE.downloadMetadata(account: metadata.account, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId, fileId: fileId, e2eToken: e2eToken)
+        let errorDownloadMetadata = await NCNetworkingE2EE.shared.downloadMetadata(account: metadata.account, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId, fileId: fileId, e2eToken: e2eToken)
         guard errorDownloadMetadata == .success else {
-            await networkingE2EE.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
+            await NCNetworkingE2EE.shared.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
             return errorDownloadMetadata
         }
 
@@ -53,18 +57,17 @@ class NCNetworkingE2EERename: NSObject {
         //
         NCManageDatabase.shared.renameFileE2eEncryption(account: metadata.account, serverUrl: metadata.serverUrl, fileNameIdentifier: metadata.fileName, newFileName: fileNameNew, newFileNamePath: CCUtility.returnFileNamePath(fromFileName: fileNameNew, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId, account: metadata.account))
 
-
         // UPLOAD METADATA
         //
-        let uploadMetadataError = await networkingE2EE.uploadMetadata(account: metadata.account,
-                                                                      serverUrl: metadata.serverUrl,
-                                                                      ocIdServerUrl: directory.ocId,
-                                                                      fileId: fileId,
-                                                                      userId: metadata.userId,
-                                                                      e2eToken: e2eToken,
-                                                                      method: "PUT")
+        let uploadMetadataError = await NCNetworkingE2EE.shared.uploadMetadata(account: metadata.account,
+                                                                               serverUrl: metadata.serverUrl,
+                                                                               ocIdServerUrl: directory.ocId,
+                                                                               fileId: fileId,
+                                                                               userId: metadata.userId,
+                                                                               e2eToken: e2eToken,
+                                                                               method: "PUT")
         guard uploadMetadataError == .success else {
-            await networkingE2EE.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
+            await NCNetworkingE2EE.shared.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
             return uploadMetadataError
         }
 
@@ -82,7 +85,7 @@ class NCNetworkingE2EERename: NSObject {
 
         // UNLOCK
         //
-        await networkingE2EE.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
+        await NCNetworkingE2EE.shared.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
         
         NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterRenameFile, userInfo: ["ocId": metadata.ocId, "account": metadata.account, "indexPath": indexPath])
 

+ 14 - 14
iOSClient/Networking/E2EE/NCNetworkingE2EEUpload.swift

@@ -38,8 +38,6 @@ extension uploadE2EEDelegate {
 
 class NCNetworkingE2EEUpload: NSObject {
 
-    let networkingE2EE = NCNetworkingE2EE()
-
     func upload(metadata: tableMetadata, uploadE2EEDelegate: uploadE2EEDelegate? = nil) async -> NKError {
 
         var metadata = metadata
@@ -48,7 +46,7 @@ class NCNetworkingE2EEUpload: NSObject {
         if let result = NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "serverUrl == %@ AND fileNameView == %@ AND ocId != %@", metadata.serverUrl, metadata.fileNameView, metadata.ocId)) {
             metadata.fileName = result.fileName
         } else {
-            metadata.fileName = networkingE2EE.generateRandomIdentifier()
+            metadata.fileName = NCNetworkingE2EE.shared.generateRandomIdentifier()
         }
         metadata.session = NextcloudKit.shared.nkCommonInstance.sessionIdentifierUpload
         metadata.sessionError = ""
@@ -75,7 +73,7 @@ class NCNetworkingE2EEUpload: NSObject {
 
             // DOWNLOAD METADATA
             //
-            let errorDownloadMetadata = await networkingE2EE.downloadMetadata(account: metadata.account, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId, fileId: fileId, e2eToken: e2eToken)
+            let errorDownloadMetadata = await NCNetworkingE2EE.shared.downloadMetadata(account: metadata.account, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId, fileId: fileId, e2eToken: e2eToken)
             if errorDownloadMetadata == .success {
                 method = "PUT"
             } else if errorDownloadMetadata.errorCode != NCGlobal.shared.errorResourceNotFound {
@@ -106,13 +104,13 @@ class NCNetworkingE2EEUpload: NSObject {
 
             // UPLOAD METADATA
             //
-            let uploadMetadataError = await networkingE2EE.uploadMetadata(account: metadata.account,
-                                                                          serverUrl: metadata.serverUrl,
-                                                                          ocIdServerUrl: directory.ocId,
-                                                                          fileId: fileId,
-                                                                          userId: metadata.userId,
-                                                                          e2eToken: e2eToken,
-                                                                          method: method)
+            let uploadMetadataError = await NCNetworkingE2EE.shared.uploadMetadata(account: metadata.account,
+                                                                                   serverUrl: metadata.serverUrl,
+                                                                                   ocIdServerUrl: directory.ocId,
+                                                                                   fileId: fileId,
+                                                                                   userId: metadata.userId,
+                                                                                   e2eToken: e2eToken,
+                                                                                   method: method)
 
             return uploadMetadataError
         }
@@ -120,7 +118,7 @@ class NCNetworkingE2EEUpload: NSObject {
 
         // LOCK
         //
-        let resultsLock = await networkingE2EE.lock(account: metadata.account, serverUrl: metadata.serverUrl)
+        let resultsLock = await NCNetworkingE2EE.shared.lock(account: metadata.account, serverUrl: metadata.serverUrl)
         guard let e2eToken = resultsLock.e2eToken, let fileId = resultsLock.fileId, resultsLock.error == .success else {
             NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", ocIdTemp))
             NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterUploadedFile, userInfo: ["ocId": metadata.ocId, "serverUrl": metadata.serverUrl, "account": metadata.account, "fileName": metadata.fileName, "ocIdTemp": ocIdTemp, "error": NKError(errorCode: NCGlobal.shared.errorE2EELock, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))])
@@ -133,7 +131,7 @@ class NCNetworkingE2EEUpload: NSObject {
         guard sendE2eeError == .success else {
             NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", ocIdTemp))
             NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterUploadedFile, userInfo: ["ocId": metadata.ocId, "serverUrl": metadata.serverUrl, "account": metadata.account, "fileName": metadata.fileName, "ocIdTemp": ocIdTemp, "error": sendE2eeError])
-            await networkingE2EE.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
+            await NCNetworkingE2EE.shared.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
             return sendE2eeError
         }
 
@@ -143,7 +141,7 @@ class NCNetworkingE2EEUpload: NSObject {
 
         // UNLOCK
         //
-        await networkingE2EE.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
+        await NCNetworkingE2EE.shared.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
         
         if let afError = resultsSendFile.afError, afError.isExplicitlyCancelledError {
 
@@ -180,6 +178,8 @@ class NCNetworkingE2EEUpload: NSObject {
         return (resultsSendFile.error)
     }
 
+    // BRIDGE for chunk
+    //
     private func sendFile(metadata: tableMetadata, e2eToken: String, uploadE2EEDelegate: uploadE2EEDelegate? = nil) async -> (ocId: String?, etag: String?, date: NSDate? ,afError: AFError?, error: NKError) {
 
         if metadata.chunk > 0 {

+ 7 - 2
iOSClient/Share/Advanced/NCShareAdvancePermission.swift

@@ -47,8 +47,13 @@ class NCShareAdvancePermission: UITableViewController, NCShareAdvanceFotterDeleg
         }
         Task {
             if isNewShare {
-                if metadata.e2eEncrypted && NCGlobal.shared.capabilityE2EEApiVersion == NCGlobal.shared.e2eeVersionV20 {
-                    let serverUrl = metadata.serverUrl + "/" + metadata.fileName
+                let serverUrl = metadata.serverUrl + "/" + metadata.fileName
+                if share.shareType != NCShareCommon.shared.SHARE_TYPE_LINK, metadata.e2eEncrypted,
+                   NCGlobal.shared.capabilityE2EEApiVersion == NCGlobal.shared.e2eeVersionV20 {
+                    if NCNetworkingE2EE.shared.isInUpload(account: metadata.account, serverUrl: serverUrl) {
+                        let error = NKError(errorCode: NCGlobal.shared.errorE2EEUploadInProgress, errorDescription: NSLocalizedString("_e2e_in_upload_", comment: ""))
+                        return NCContentPresenter.shared.showInfo(error: error)
+                    }
                     let error = await NCNetworkingE2EE().uploadMetadata(account: metadata.account, serverUrl: serverUrl, userId: metadata.userId, addUserId: share.shareWith, removeUserId: nil)
                     if error != .success {
                         NCContentPresenter.shared.showError(error: error)

+ 10 - 5
iOSClient/Share/NCShare.swift

@@ -84,12 +84,17 @@ class NCShare: UIViewController, NCShareNetworkingDelegate, NCSharePagingContent
 
         guard let metadata = metadata else { return }
 
-        if metadata.e2eEncrypted && NCGlobal.shared.capabilityE2EEApiVersion == NCGlobal.shared.e2eeVersionV12 {
-            searchFieldTopConstraint.constant = -50
-            searchField.isHidden = true
-         } else {
+        if metadata.e2eEncrypted {
+            let direcrory = NCManageDatabase.shared.getTableDirectory(account: metadata.account, serverUrl: metadata.serverUrl)
+            if NCGlobal.shared.capabilityE2EEApiVersion == NCGlobal.shared.e2eeVersionV12 ||
+                (NCGlobal.shared.capabilityE2EEApiVersion == NCGlobal.shared.e2eeVersionV20 && direcrory?.e2eEncrypted ?? false) {
+                // searchField.isEnabled = false
+                searchFieldTopConstraint.constant = -50
+                searchField.isHidden = true
+            }
+        } else {
             checkSharedWithYou()
-         }
+        }
 
         reloadData()
 

+ 1 - 0
iOSClient/Supporting Files/en.lproj/Localizable.strings

@@ -709,6 +709,7 @@
 "_e2e_remove_folder_encrypted_"     = "Decrypt";
 "_e2e_goto_settings_for_enable_"    = "This is an encrypted directory, go to \"Settings\" and enable end-to-end encryption";
 "_e2e_error_"                       = "Serious internal error end-to-end encryption";
+"_e2e_in_upload_"                   = "Upload in progress, please wait for all files to be transferred";
 "_scans_document_"                  = "Scan document";
 "_scanned_images_"                  = "Scanned images";
 "_scan_document_pdf_page_"          = "Page";

+ 6 - 0
iOSClient/Utility/NCContentPresenter.swift

@@ -103,6 +103,12 @@ class NCContentPresenter: NSObject {
         // No notification message for:
         if error.errorCode == NSURLErrorCancelled || error.errorCode == NCGlobal.shared.errorRequestExplicityCancelled { return } else if error == .success && type == messageType.error { return }
 
+        // Hardcode change type
+        var type = type
+        if error.errorCode == NCGlobal.shared.errorE2EEUploadInProgress {
+            type = .info
+        }
+
         DispatchQueue.main.async {
             switch error.errorCode {
             case Int(CFNetworkErrors.cfurlErrorNotConnectedToInternet.rawValue):

+ 1 - 1
iOSClient/Utility/NCUtility.swift

@@ -766,7 +766,7 @@ class NCUtility: NSObject {
 
     func isDirectoryE2EETop(account: String, serverUrl: String) -> Bool {
 
-        guard var serverUrl = serverUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else { return false }
+        guard let serverUrl = serverUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else { return false }
 
         if let url = URL(string: serverUrl)?.deletingLastPathComponent(),
            let serverUrl = String(url.absoluteString.dropLast()).removingPercentEncoding {