diff --git a/Nextcloud.xcodeproj/project.pbxproj b/Nextcloud.xcodeproj/project.pbxproj index 1ba23daec8..239704ee85 100644 --- a/Nextcloud.xcodeproj/project.pbxproj +++ b/Nextcloud.xcodeproj/project.pbxproj @@ -289,8 +289,8 @@ F7245926289BB59300474787 /* ThreadSafeDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7245923289BB50B00474787 /* ThreadSafeDictionary.swift */; }; F7245927289BB59300474787 /* ThreadSafeDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7245923289BB50B00474787 /* ThreadSafeDictionary.swift */; }; F72685E727C78E490019EF5E /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = F72685E927C78E490019EF5E /* InfoPlist.strings */; }; - F72944F22A84246400246839 /* NCEndToEndMetadataV20.swift in Sources */ = {isa = PBXBuildFile; fileRef = F72944F12A84246400246839 /* NCEndToEndMetadataV20.swift */; }; - F72944F32A84246400246839 /* NCEndToEndMetadataV20.swift in Sources */ = {isa = PBXBuildFile; fileRef = F72944F12A84246400246839 /* NCEndToEndMetadataV20.swift */; }; + F72944F22A84246400246839 /* NCEndToEndMetadataV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = F72944F12A84246400246839 /* NCEndToEndMetadataV2.swift */; }; + F72944F32A84246400246839 /* NCEndToEndMetadataV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = F72944F12A84246400246839 /* NCEndToEndMetadataV2.swift */; }; F72944F52A8424F800246839 /* NCEndToEndMetadataV1.swift in Sources */ = {isa = PBXBuildFile; fileRef = F72944F42A8424F800246839 /* NCEndToEndMetadataV1.swift */; }; F72944F62A8424F800246839 /* NCEndToEndMetadataV1.swift in Sources */ = {isa = PBXBuildFile; fileRef = F72944F42A8424F800246839 /* NCEndToEndMetadataV1.swift */; }; F72A17D828B221E300F3F159 /* DashboardWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F72A17D728B221E300F3F159 /* DashboardWidgetView.swift */; }; @@ -1361,7 +1361,7 @@ F724377A2C10B83E00C7C68D /* NCSharePermissions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCSharePermissions.swift; sourceTree = ""; }; F7245923289BB50B00474787 /* ThreadSafeDictionary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThreadSafeDictionary.swift; sourceTree = ""; }; F72685E827C78E490019EF5E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; - F72944F12A84246400246839 /* NCEndToEndMetadataV20.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCEndToEndMetadataV20.swift; sourceTree = ""; }; + F72944F12A84246400246839 /* NCEndToEndMetadataV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCEndToEndMetadataV2.swift; sourceTree = ""; }; F72944F42A8424F800246839 /* NCEndToEndMetadataV1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCEndToEndMetadataV1.swift; sourceTree = ""; }; F72A17D728B221E300F3F159 /* DashboardWidgetView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DashboardWidgetView.swift; sourceTree = ""; }; F72CA0562F5048C3002E2F06 /* UIApplication+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIApplication+Extension.swift"; sourceTree = ""; }; @@ -3025,7 +3025,7 @@ F70CAE381F8CF31A008125FD /* NCEndToEndEncryption.h */, F70CAE391F8CF31A008125FD /* NCEndToEndEncryption.m */, F7F878AD1FB9E3B900599E4F /* NCEndToEndMetadata.swift */, - F72944F12A84246400246839 /* NCEndToEndMetadataV20.swift */, + F72944F12A84246400246839 /* NCEndToEndMetadataV2.swift */, F72944F42A8424F800246839 /* NCEndToEndMetadataV1.swift */, F785EE9C246196DF00B3F945 /* NCNetworkingE2EE.swift */, F7C30DF9291BCF790017149B /* NCNetworkingE2EECreateFolder.swift */, @@ -4324,7 +4324,7 @@ F7148041262EBE4000693E51 /* NCShareExtension.swift in Sources */, F71FA7992F3508C600E86192 /* NCNetworking+WebDAV.swift in Sources */, F76B3CCF1EAE01BD00921AC9 /* NCBrand.swift in Sources */, - F72944F32A84246400246839 /* NCEndToEndMetadataV20.swift in Sources */, + F72944F32A84246400246839 /* NCEndToEndMetadataV2.swift in Sources */, F7BAADCC1ED5A87C00B7EAD4 /* NCManageDatabase.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -4633,7 +4633,7 @@ F3DDFE232F1FB4C300A784C8 /* NCAssistantChatModel.swift in Sources */, F7501C332212E57500FB1415 /* NCMedia.swift in Sources */, F7411C552D7B26D700F57358 /* NCNetworking+ServerError.swift in Sources */, - F72944F22A84246400246839 /* NCEndToEndMetadataV20.swift in Sources */, + F72944F22A84246400246839 /* NCEndToEndMetadataV2.swift in Sources */, F78026122E9CFA6300B63436 /* NCTransfersModel.swift in Sources */, F7EF2AEB2E43157B0081B2C9 /* NCNotification.swift in Sources */, F70BFC7420E0FA7D00C67599 /* NCUtility.swift in Sources */, diff --git a/iOSClient/Data/NCManageDatabase+LocalFile.swift b/iOSClient/Data/NCManageDatabase+LocalFile.swift index a4308b0ec3..2146dec1ad 100644 --- a/iOSClient/Data/NCManageDatabase+LocalFile.swift +++ b/iOSClient/Data/NCManageDatabase+LocalFile.swift @@ -90,6 +90,14 @@ extension NCManageDatabase { } } + func deleteLocalFileAsync(predicate: NSPredicate) async { + await core.performRealmWriteAsync { realm in + let result = realm.objects(tableLocalFile.self) + .filter(predicate) + realm.delete(result) + } + } + func deleteLocalFileAsync(id: String?) async { guard let id else { return } diff --git a/iOSClient/Extensions/UIAlertController+Extension.swift b/iOSClient/Extensions/UIAlertController+Extension.swift index e973b459f6..35b5487bfa 100644 --- a/iOSClient/Extensions/UIAlertController+Extension.swift +++ b/iOSClient/Extensions/UIAlertController+Extension.swift @@ -70,7 +70,7 @@ extension UIAlertController { } } if createFolderResults.error == .success { - let error = await NCNetworkingE2EEMarkFolder().markFolderE2ee(account: session.account, serverUrlFileName: serverUrlFileName, userId: session.userId) + let error = await NCNetworkingE2EEMarkFolder().markFolderE2ee(account: session.account, serverUrlFileName: serverUrlFileName, userId: session.userId, sceneIdentifier: sceneIdentifier) if let banner, let token { if error == .success { completeHudIndeterminateBannerSuccess(token: token, banner: banner) @@ -80,7 +80,7 @@ extension UIAlertController { } completion?(error) } else { - if let banner, let token { + if let banner { banner.dismiss() } completion?(NKError(errorCode: createFolderResults.error.errorCode, errorDescription: createFolderResults.error.errorDescription)) diff --git a/iOSClient/Files/NCFiles.swift b/iOSClient/Files/NCFiles.swift index 3fd411eed0..68c13890b2 100644 --- a/iOSClient/Files/NCFiles.swift +++ b/iOSClient/Files/NCFiles.swift @@ -330,7 +330,7 @@ class NCFiles: NCCollectionViewCommon { if error == .success { let capabilities = await NKCapabilities.shared.getCapabilities(for: self.session.account) - if version == "v1", NCGlobal.shared.isE2eeVersion2(capabilities.e2EEApiVersion) { + if version == "v1", capabilities.e2EEApiVersion.hasPrefix("2.") { await showInfoBanner(windowScene: windowScene, text: "Conversion metadata v1 to v2 required, please wait...") nkLog(tag: self.global.logTagE2EE, message: "Conversion v1 to v2") NCActivityIndicator.shared.start() diff --git a/iOSClient/GUI/Lucid Banner/AlertActionBannerView.swift b/iOSClient/GUI/Lucid Banner/AlertActionBannerView.swift index 2428235c37..31120dc8e3 100644 --- a/iOSClient/GUI/Lucid Banner/AlertActionBannerView.swift +++ b/iOSClient/GUI/Lucid Banner/AlertActionBannerView.swift @@ -66,7 +66,7 @@ struct AlertActionBannerView: View { // Title if let title = state.payload.title, !title.isEmpty { Text(title) - .cappedFont(.title3, maxDynamicType: .accessibility2) + .cappedFont(.headline, maxDynamicType: .accessibility2) .fontWeight(.semibold) .foregroundStyle(state.payload.textColor) .multilineTextAlignment(.center) diff --git a/iOSClient/GUI/Lucid Banner/ErrorBannerView.swift b/iOSClient/GUI/Lucid Banner/ErrorBannerView.swift index ccd1d7c99c..1934371411 100644 --- a/iOSClient/GUI/Lucid Banner/ErrorBannerView.swift +++ b/iOSClient/GUI/Lucid Banner/ErrorBannerView.swift @@ -87,7 +87,7 @@ struct ErrorBannerView: View { VStack(alignment: .leading, spacing: 7) { if showTitle, let title = state.payload.title { Text(title) - .cappedFont(.title3, maxDynamicType: .accessibility2) + .cappedFont(.headline, maxDynamicType: .accessibility2) .fontWeight(.semibold) .multilineTextAlignment(.leading) .truncationMode(.tail) diff --git a/iOSClient/GUI/Lucid Banner/HudBannerView.swift b/iOSClient/GUI/Lucid Banner/HudBannerView.swift index 49c8464cb8..40ab5a83d2 100644 --- a/iOSClient/GUI/Lucid Banner/HudBannerView.swift +++ b/iOSClient/GUI/Lucid Banner/HudBannerView.swift @@ -111,7 +111,7 @@ struct HudBannerView: View { // TITLE if let title = state.payload.title, !title.isEmpty { Text(title) - .cappedFont(.title3, maxDynamicType: .accessibility2) + .cappedFont(.headline, maxDynamicType: .accessibility2) .fontWeight(.semibold) .foregroundStyle(textColor) .multilineTextAlignment(.center) diff --git a/iOSClient/GUI/Lucid Banner/HudIndeterminateBannerView.swift b/iOSClient/GUI/Lucid Banner/HudIndeterminateBannerView.swift index dce0a9b5bc..8d12494170 100644 --- a/iOSClient/GUI/Lucid Banner/HudIndeterminateBannerView.swift +++ b/iOSClient/GUI/Lucid Banner/HudIndeterminateBannerView.swift @@ -99,7 +99,7 @@ struct HudBannerViewIndeterminate: View { // TITLE if let title = state.payload.title, !title.isEmpty { Text(title) - .cappedFont(.title3, maxDynamicType: .accessibility2) + .cappedFont(.headline, maxDynamicType: .accessibility2) .fontWeight(.semibold) .foregroundStyle(textColor) .multilineTextAlignment(.center) diff --git a/iOSClient/GUI/Lucid Banner/InfoBannerView.swift b/iOSClient/GUI/Lucid Banner/InfoBannerView.swift index f0b74d27d7..bba3e11f3a 100644 --- a/iOSClient/GUI/Lucid Banner/InfoBannerView.swift +++ b/iOSClient/GUI/Lucid Banner/InfoBannerView.swift @@ -75,7 +75,7 @@ struct InfoBannerView: View { VStack(alignment: .leading, spacing: 7) { if showTitle, let title = state.payload.title { Text(title) - .cappedFont(.title3, maxDynamicType: .accessibility2) + .cappedFont(.headline, maxDynamicType: .accessibility2) .fontWeight(.semibold) .multilineTextAlignment(.leading) .truncationMode(.tail) diff --git a/iOSClient/GUI/Lucid Banner/ShowBanner.swift b/iOSClient/GUI/Lucid Banner/ShowBanner.swift index 68b38ab0db..6c5cdc3bac 100644 --- a/iOSClient/GUI/Lucid Banner/ShowBanner.swift +++ b/iOSClient/GUI/Lucid Banner/ShowBanner.swift @@ -90,7 +90,7 @@ struct BannerView: View { VStack(alignment: .leading, spacing: 7) { if showTitle, let title = state.payload.title { Text(title) - .cappedFont(.title3, maxDynamicType: .accessibility2) + .cappedFont(.headline, maxDynamicType: .accessibility2) .fontWeight(.semibold) .multilineTextAlignment(.leading) .truncationMode(.tail) @@ -178,4 +178,3 @@ struct BannerView: View { .padding() } } - diff --git a/iOSClient/GUI/Lucid Banner/UploadBannerView.swift b/iOSClient/GUI/Lucid Banner/UploadBannerView.swift index c999bf5d1a..5420664ce7 100644 --- a/iOSClient/GUI/Lucid Banner/UploadBannerView.swift +++ b/iOSClient/GUI/Lucid Banner/UploadBannerView.swift @@ -151,7 +151,7 @@ struct UploadBannerView: View { VStack(alignment: .leading, spacing: 7) { if showTitle, let title = state.payload.title { Text(title) - .cappedFont(.title3, maxDynamicType: .accessibility2) + .cappedFont(.headline, maxDynamicType: .accessibility2) .fontWeight(.semibold) .multilineTextAlignment(.leading) .truncationMode(.tail) diff --git a/iOSClient/GUI/Lucid Banner/WarningBannerView.swift b/iOSClient/GUI/Lucid Banner/WarningBannerView.swift index fb44f43367..adfc69b3a5 100644 --- a/iOSClient/GUI/Lucid Banner/WarningBannerView.swift +++ b/iOSClient/GUI/Lucid Banner/WarningBannerView.swift @@ -77,7 +77,7 @@ struct WarningBannerView: View { VStack(alignment: .leading, spacing: 7) { if showTitle, let title = state.payload.title { Text(title) - .cappedFont(.title3, maxDynamicType: .accessibility2) + .cappedFont(.headline, maxDynamicType: .accessibility2) .fontWeight(.semibold) .multilineTextAlignment(.leading) .truncationMode(.tail) diff --git a/iOSClient/Main/Collection Common/NCCollectionViewCommon.swift b/iOSClient/Main/Collection Common/NCCollectionViewCommon.swift index f9ed7b7056..13c4b9584d 100644 --- a/iOSClient/Main/Collection Common/NCCollectionViewCommon.swift +++ b/iOSClient/Main/Collection Common/NCCollectionViewCommon.swift @@ -863,6 +863,8 @@ extension NCCollectionViewCommon: NCSectionFooterDelegate { } } +// MARK: - Transfer Delegate + extension NCCollectionViewCommon: NCTransferDelegate { func transferProgressDidUpdate(progress: Float, totalBytes: Int64, totalBytesExpected: Int64, fileName: String, serverUrl: String) { } @@ -887,11 +889,20 @@ extension NCCollectionViewCommon: NCTransferDelegate { error.errorCode != global.errorResourceNotFound { await showErrorBanner(windowScene: windowScene, text: error.errorDescription, errorCode: error.errorCode) } + guard session.account == account else { return } - if status == self.global.networkingStatusCreateFolder { + if self.isSearchingMode { + await self.debouncerNetworkSearch.call { + await self.search() + } + return + } + + switch status { + case self.global.networkingStatusCreateFolder: if error == .success, serverUrl == self.serverUrl, selector != self.global.selectorUploadAutoUpload, @@ -902,16 +913,11 @@ extension NCCollectionViewCommon: NCTransferDelegate { self.pushMetadata(metadata) } } - return - } - - if self.isSearchingMode { - await self.debouncerNetworkSearch.call { - await self.search() - } - } else if self.serverUrl == serverUrl || destination == self.serverUrl || self.serverUrl.isEmpty { - await self.debouncerReloadDataSource.call { - await self.reloadDataSource() + default: + if self.serverUrl == serverUrl || destination == self.serverUrl || self.serverUrl.isEmpty { + await self.debouncerReloadDataSource.call { + await self.reloadDataSource() + } } } } diff --git a/iOSClient/Menu/NCContextMenuMain.swift b/iOSClient/Menu/NCContextMenuMain.swift index 33822fa698..e6d9b3088b 100644 --- a/iOSClient/Menu/NCContextMenuMain.swift +++ b/iOSClient/Menu/NCContextMenuMain.swift @@ -241,7 +241,8 @@ class NCContextMenuMain: NSObject { let error = await NCNetworkingE2EEMarkFolder().markFolderE2ee( account: metadata.account, serverUrlFileName: metadata.serverUrlFileName, - userId: metadata.userId + userId: metadata.userId, + sceneIdentifier: self.sceneIdentifier ) if error != .success { await showErrorBanner(windowScene: self.windowScene, text: error.errorDescription, errorCode: error.errorCode) @@ -363,7 +364,7 @@ class NCContextMenuMain: NSObject { return } - let error = await NCNetworking.shared.setStatusWaitRename(metadata, fileNameNew: fileNameNew) + let error = await NCNetworking.shared.setStatusWaitRename(metadata, fileNameNew: fileNameNew, windowScene: self.windowScene) if error != .success { await showErrorBanner(windowScene: self.windowScene, error: error) } diff --git a/iOSClient/Menu/NCContextMenuShare.swift b/iOSClient/Menu/NCContextMenuShare.swift index 7699063069..22ec66240a 100644 --- a/iOSClient/Menu/NCContextMenuShare.swift +++ b/iOSClient/Menu/NCContextMenuShare.swift @@ -157,7 +157,7 @@ class NCContextMenuShare: NSObject { if share.shareType != NKShare.ShareType.publicLink.rawValue, let metadata = shareController.metadata, - metadata.e2eEncrypted && NCGlobal.shared.isE2eeVersion2(capabilities.e2EEApiVersion) { + metadata.e2eEncrypted && capabilities.e2EEApiVersion.hasPrefix("2.") { if await NCNetworkingE2EE().isInUpload(account: metadata.account, serverUrl: metadata.serverUrlFileName) { Task { await showErrorBanner(windowScene: self.windowScene, diff --git a/iOSClient/NCGlobal.swift b/iOSClient/NCGlobal.swift index a74da16f90..cd2eee1ef7 100644 --- a/iOSClient/NCGlobal.swift +++ b/iOSClient/NCGlobal.swift @@ -98,14 +98,6 @@ final class NCGlobal: Sendable { // E2EE // let e2eePassphraseTest = "more over television factory tendency independence international intellectual impress interest sentence pony" - let e2eeCompatibleVersions = ["1.1", "1.2", "2.0", "2.1", "2.2"] - - func isE2eeVersion2(_ version: String) -> Bool { - if version.hasPrefix("2.") { - return true - } - return false - } // CHUNK let chunkSizeMBCellular = 10000000 diff --git a/iOSClient/Networking/E2EE/NCEndToEndMetadata.swift b/iOSClient/Networking/E2EE/NCEndToEndMetadata.swift index 80f73f7954..72ad17a38e 100644 --- a/iOSClient/Networking/E2EE/NCEndToEndMetadata.swift +++ b/iOSClient/Networking/E2EE/NCEndToEndMetadata.swift @@ -21,10 +21,10 @@ class NCEndToEndMetadata: NSObject { } let capabilities = await NKCapabilities.shared.getCapabilities(for: session.account) - if capabilities.e2EEApiVersion == "1.2" { - return await encodeMetadataV12(account: session.account, serverUrl: serverUrl, ocIdServerUrl: directory.ocId) - } else if NCGlobal.shared.isE2eeVersion2(capabilities.e2EEApiVersion) { - return await encodeMetadataV20(serverUrl: serverUrl, ocIdServerUrl: directory.ocId, addUserId: addUserId, addCertificate: addCertificate, removeUserId: removeUserId, session: session) + if capabilities.e2EEApiVersion.hasPrefix("1.") { + return await encodeMetadataV1(account: session.account, serverUrl: serverUrl, ocIdServerUrl: directory.ocId) + } else if capabilities.e2EEApiVersion.hasPrefix("2.") { + return await encodeMetadataV2(serverUrl: serverUrl, ocIdServerUrl: directory.ocId, addUserId: addUserId, addCertificate: addCertificate, removeUserId: removeUserId, session: session) } else { return (nil, nil, 0, NKError(errorCode: NCGlobal.shared.errorE2EEVersion, errorDescription: "Server E2EE version " + capabilities.e2EEApiVersion + ", not compatible")) } diff --git a/iOSClient/Networking/E2EE/NCEndToEndMetadataV1.swift b/iOSClient/Networking/E2EE/NCEndToEndMetadataV1.swift index 1841eb1946..d84a5c760d 100644 --- a/iOSClient/Networking/E2EE/NCEndToEndMetadataV1.swift +++ b/iOSClient/Networking/E2EE/NCEndToEndMetadataV1.swift @@ -70,7 +70,7 @@ extension NCEndToEndMetadata { // MARK: Ecode JSON Metadata V1.2 // -------------------------------------------------------------------------------------------- - func encodeMetadataV12(account: String, serverUrl: String, ocIdServerUrl: String) async -> (metadata: String?, signature: String?, counter: Int, error: NKError) { + func encodeMetadataV1(account: String, serverUrl: String, ocIdServerUrl: String) async -> (metadata: String?, signature: String?, counter: Int, error: NKError) { let encoder = JSONEncoder() var metadataKey: String = "" diff --git a/iOSClient/Networking/E2EE/NCEndToEndMetadataV20.swift b/iOSClient/Networking/E2EE/NCEndToEndMetadataV2.swift similarity index 99% rename from iOSClient/Networking/E2EE/NCEndToEndMetadataV20.swift rename to iOSClient/Networking/E2EE/NCEndToEndMetadataV2.swift index ce86e5bdaa..79d7471fb8 100644 --- a/iOSClient/Networking/E2EE/NCEndToEndMetadataV20.swift +++ b/iOSClient/Networking/E2EE/NCEndToEndMetadataV2.swift @@ -79,7 +79,7 @@ extension NCEndToEndMetadata { // MARK: Encode JSON Metadata V2 // -------------------------------------------------------------------------------------------- - func encodeMetadataV20(serverUrl: String, ocIdServerUrl: String, addUserId: String?, addCertificate: String?, removeUserId: String?, session: NCSession.Session) async -> (metadata: String?, signature: String?, counter: Int, error: NKError) { + func encodeMetadataV2(serverUrl: String, ocIdServerUrl: String, addUserId: String?, addCertificate: String?, removeUserId: String?, session: NCSession.Session) async -> (metadata: String?, signature: String?, counter: Int, error: NKError) { guard let directoryTop = await utilityFileSystem.getMetadataE2EETopAsync(serverUrl: serverUrl, session: session) else { return (nil, nil, 0, NKError(errorCode: NCGlobal.shared.errorE2EEKeyDirectoryTop, errorDescription: NSLocalizedString("_e2ee_no_dir_", comment: ""))) diff --git a/iOSClient/Networking/E2EE/NCNetworkingE2EE.swift b/iOSClient/Networking/E2EE/NCNetworkingE2EE.swift index 79e2f58184..1a3a6be724 100644 --- a/iOSClient/Networking/E2EE/NCNetworkingE2EE.swift +++ b/iOSClient/Networking/E2EE/NCNetworkingE2EE.swift @@ -30,7 +30,7 @@ class NCNetworkingE2EE: NSObject { func getOptions(account: String, capabilities: NKCapabilities.Capabilities) -> NKRequestOptions { var version = e2EEApiVersion1 - if NCGlobal.shared.isE2eeVersion2(capabilities.e2EEApiVersion) { + if capabilities.e2EEApiVersion.hasPrefix("2.") { version = e2EEApiVersion2 } return NKRequestOptions(version: version) @@ -209,9 +209,7 @@ class NCNetworkingE2EE: NSObject { // COUNTER // - if NCGlobal.shared.isE2eeVersion2(capabilities.e2EEApiVersion) { - await self.database.updateCounterE2eMetadataAsync(account: session.account, ocIdServerUrl: ocIdServerUrl, counter: resultsEncodeMetadata.counter) - } + await self.database.updateCounterE2eMetadataAsync(account: session.account, ocIdServerUrl: ocIdServerUrl, counter: resultsEncodeMetadata.counter) return NKError() } @@ -253,8 +251,7 @@ class NCNetworkingE2EE: NSObject { e2eToken = tableLock.e2eToken } - if NCGlobal.shared.isE2eeVersion2(capabilities.e2EEApiVersion), - var counter = await self.database.getCounterE2eMetadataAsync(account: account, ocIdServerUrl: directory.ocId) { + if var counter = await self.database.getCounterE2eMetadataAsync(account: account, ocIdServerUrl: directory.ocId) { counter += 1 e2eCounter = "\(counter)" } diff --git a/iOSClient/Networking/E2EE/NCNetworkingE2EECreateFolder.swift b/iOSClient/Networking/E2EE/NCNetworkingE2EECreateFolder.swift index 960c0cb2ed..0a98fc9d7d 100644 --- a/iOSClient/Networking/E2EE/NCNetworkingE2EECreateFolder.swift +++ b/iOSClient/Networking/E2EE/NCNetworkingE2EECreateFolder.swift @@ -51,6 +51,8 @@ class NCNetworkingE2EECreateFolder: NSObject { return error } + // BANNER + // #if !EXTENSION if let windowScene = SceneManager.shared.getWindow(sceneIdentifier: sceneIdentifier)?.windowScene { (banner, token) = showHudIndeterminateBanner(windowScene: windowScene, title: "_e2ee_create_folder_") diff --git a/iOSClient/Networking/E2EE/NCNetworkingE2EEMarkFolder.swift b/iOSClient/Networking/E2EE/NCNetworkingE2EEMarkFolder.swift index ae7e31f648..1f2fc2e72e 100644 --- a/iOSClient/Networking/E2EE/NCNetworkingE2EEMarkFolder.swift +++ b/iOSClient/Networking/E2EE/NCNetworkingE2EEMarkFolder.swift @@ -5,11 +5,35 @@ import Foundation import UIKit import NextcloudKit +import LucidBanner +@MainActor class NCNetworkingE2EEMarkFolder: NSObject { let database = NCManageDatabase.shared - func markFolderE2ee(account: String, serverUrlFileName: String, userId: String) async -> NKError { + func markFolderE2ee(account: String, serverUrlFileName: String, userId: String, sceneIdentifier: String?) async -> NKError { + var banner: LucidBanner? + var token: Int? + var error = NKError() + + defer { + if let banner, let token { + if error == .success { + completeHudIndeterminateBannerSuccess(token: token, banner: banner) + } else { + banner.dismiss() + } + } + } + + // BANNER + // +#if !EXTENSION + if let windowScene = SceneManager.shared.getWindow(sceneIdentifier: sceneIdentifier)?.windowScene { + (banner, token) = showHudIndeterminateBanner(windowScene: windowScene, title: "_e2ee_encrypt_folder_") + } +#endif + let resultsReadFileOrFolder = await NextcloudKit.shared.readFileOrFolderAsync(serverUrlFileName: serverUrlFileName, depth: "0", account: account) { task in Task { let identifier = await NCNetworking.shared.networkingTasks.createIdentifier(account: account, @@ -20,7 +44,8 @@ class NCNetworkingE2EEMarkFolder: NSObject { } guard resultsReadFileOrFolder.error == .success, var file = resultsReadFileOrFolder.files?.first else { - return resultsReadFileOrFolder.error + error = resultsReadFileOrFolder.error + return error } let capabilities = await NKCapabilities.shared.getCapabilities(for: account) let resultsMarkE2EEFolder = await NextcloudKit.shared.markE2EEFolderAsync(fileId: file.fileId, delete: false, account: account, options: NCNetworkingE2EE().getOptions(account: account, capabilities: capabilities)) { task in @@ -32,7 +57,8 @@ class NCNetworkingE2EEMarkFolder: NSObject { } } guard resultsMarkE2EEFolder.error == .success else { - return resultsMarkE2EEFolder.error + error = resultsMarkE2EEFolder.error + return error } file.e2eEncrypted = true @@ -41,14 +67,12 @@ class NCNetworkingE2EEMarkFolder: NSObject { await self.database.createDirectory(metadata: metadata) await self.database.deleteE2eEncryptionAsync(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", metadata.account, serverUrlFileName)) - if NCGlobal.shared.isE2eeVersion2(capabilities.e2EEApiVersion) { - await self.database.updateCounterE2eMetadataAsync(account: account, ocIdServerUrl: metadata.ocId, counter: 0) - } + await self.database.updateCounterE2eMetadataAsync(account: account, ocIdServerUrl: metadata.ocId, counter: 0) // upload e2ee metadata - let errorUploadMetadata = await NCNetworkingE2EE().uploadMetadata(serverUrl: serverUrlFileName, account: account) - guard errorUploadMetadata == .success else { - return errorUploadMetadata + error = await NCNetworkingE2EE().uploadMetadata(serverUrl: serverUrlFileName, account: account) + guard error == .success else { + return error } await NCNetworking.shared.transferDispatcher.notifyAllDelegates { delegate in @@ -62,6 +86,6 @@ class NCNetworkingE2EEMarkFolder: NSObject { error: .success) } - return NKError() + return error } } diff --git a/iOSClient/Networking/E2EE/NCNetworkingE2EERename.swift b/iOSClient/Networking/E2EE/NCNetworkingE2EERename.swift index 438ab02069..217deafcb0 100644 --- a/iOSClient/Networking/E2EE/NCNetworkingE2EERename.swift +++ b/iOSClient/Networking/E2EE/NCNetworkingE2EERename.swift @@ -5,40 +5,70 @@ import NextcloudKit import UIKit import Foundation +import LucidBanner class NCNetworkingE2EERename: NSObject { let database = NCManageDatabase.shared let networkingE2EE = NCNetworkingE2EE() let utilityFileSystem = NCUtilityFileSystem() - func rename(metadata: tableMetadata, fileNameNew: String) async -> NKError { + @MainActor + func rename(metadata: tableMetadata, fileNameNew: String, windowScene: UIWindowScene?) async -> NKError { let session = NCSession.shared.getSession(account: metadata.account) + var error = NKError() + var banner: LucidBanner? + var token: Int? + + defer { + if let banner, let token { + if error == .success { + completeHudIndeterminateBannerSuccess(token: token, banner: banner) + } else { + banner.dismiss() + } + } + } + // verify if exists the new fileName if await self.database.getE2eEncryptionAsync(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileName == %@", metadata.account, metadata.serverUrl, fileNameNew)) != nil { - return NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: "_file_already_exists_") + error = NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: "_file_already_exists_") + return error } guard let directory = await self.database.getTableDirectoryAsync(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", metadata.account, metadata.serverUrl)) else { - return NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, + error = NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: NSLocalizedString("_e2ee_no_dir_", comment: "")) + return error } // TEST UPLOAD IN PROGRESS // if await networkingE2EE.isInUpload(account: metadata.account, serverUrl: metadata.serverUrl) { - return NKError(errorCode: NCGlobal.shared.errorE2EEUploadInProgress, errorDescription: NSLocalizedString("_e2e_in_upload_", comment: "")) + error = NKError(errorCode: NCGlobal.shared.errorE2EEUploadInProgress, errorDescription: NSLocalizedString("_e2e_in_upload_", comment: "")) + return error } + // BANNER + // +#if !EXTENSION + if let windowScene { + (banner, token) = showHudIndeterminateBanner(windowScene: windowScene, title: "_e2ee_rename_file_") + } +#endif + // LOCK // let resultsLock = await networkingE2EE.lock(account: metadata.account, serverUrl: metadata.serverUrl) - guard resultsLock.error == .success, let e2eToken = resultsLock.e2eToken, let fileId = resultsLock.fileId else { return resultsLock.error } + guard resultsLock.error == .success, let e2eToken = resultsLock.e2eToken, let fileId = resultsLock.fileId else { + error = resultsLock.error + return error + } // DOWNLOAD METADATA // - let errorDownloadMetadata = await networkingE2EE.downloadMetadata(serverUrl: metadata.serverUrl, fileId: fileId, e2eToken: e2eToken, session: session) - guard errorDownloadMetadata == .success else { + error = await networkingE2EE.downloadMetadata(serverUrl: metadata.serverUrl, fileId: fileId, e2eToken: e2eToken, session: session) + guard error == .success else { await networkingE2EE.unlock(account: metadata.account, serverUrl: metadata.serverUrl) - return errorDownloadMetadata + return error } // DB RENAME @@ -48,15 +78,15 @@ class NCNetworkingE2EERename: NSObject { // UPLOAD METADATA // - let uploadMetadataError = await networkingE2EE.uploadMetadata(serverUrl: metadata.serverUrl, - ocIdServerUrl: directory.ocId, - fileId: fileId, - e2eToken: e2eToken, - method: "PUT", - session: session) - guard uploadMetadataError == .success else { + error = await networkingE2EE.uploadMetadata(serverUrl: metadata.serverUrl, + ocIdServerUrl: directory.ocId, + fileId: fileId, + e2eToken: e2eToken, + method: "PUT", + session: session) + guard error == .success else { await networkingE2EE.unlock(account: metadata.account, serverUrl: metadata.serverUrl) - return uploadMetadataError + return error } // UPDATE DB @@ -83,9 +113,9 @@ class NCNetworkingE2EERename: NSObject { selector: metadata.sessionSelector, ocId: metadata.ocId, destination: nil, - error: uploadMetadataError) + error: error) } - return NKError() + return error } } diff --git a/iOSClient/Networking/E2EE/NCNetworkingE2EEUpload.swift b/iOSClient/Networking/E2EE/NCNetworkingE2EEUpload.swift index 5f153016bb..aa64cea15a 100644 --- a/iOSClient/Networking/E2EE/NCNetworkingE2EEUpload.swift +++ b/iOSClient/Networking/E2EE/NCNetworkingE2EEUpload.swift @@ -202,8 +202,15 @@ class NCNetworkingE2EEUpload: NSObject { metadata.sessionError = "" metadata.status = NCGlobal.shared.metadataStatusNormal + // Remove if exists same file name view + if let metadataExists = await self.database.getMetadataAsync(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileNameView == %@ ", metadata.account, metadata.serverUrl, metadata.fileNameView)) { + await self.database.deleteMetadataAsync(ocId: metadataExists.ocId) + await self.database.deleteLocalFileAsync(id: metadataExists.ocId) + } + await self.database.addMetadataAsync(metadata) await self.database.addLocalFilesAsync(metadatas: [metadata]) + utility.createImageFileFrom(metadata: metadata) await NCNetworking.shared.transferDispatcher.notifyAllDelegates { delegate in diff --git a/iOSClient/Networking/NCNetworking+WebDAV.swift b/iOSClient/Networking/NCNetworking+WebDAV.swift index 854cffc920..1b58acc0a1 100644 --- a/iOSClient/Networking/NCNetworking+WebDAV.swift +++ b/iOSClient/Networking/NCNetworking+WebDAV.swift @@ -447,7 +447,7 @@ extension NCNetworking { // MARK: - Rename - func setStatusWaitRename(_ metadata: tableMetadata, fileNameNew: String) async -> NKError { + func setStatusWaitRename(_ metadata: tableMetadata, fileNameNew: String, windowScene: UIWindowScene?) async -> NKError { let permission = NCMetadataPermissions.permissionsContainsString(metadata.permissions, permissions: NCMetadataPermissions.permissionCanRename) if (!metadata.permissions.isEmpty && permission == false) || (metadata.status != global.metadataStatusNormal && metadata.status != global.metadataStatusWaitRename) { @@ -459,7 +459,7 @@ extension NCNetworking { return NKError(errorCode: global.errorOfflineNotAllowed, errorDescription: "_offline_not_allowed_") } - let error = await NCNetworkingE2EERename().rename(metadata: metadata, fileNameNew: fileNameNew) + let error = await NCNetworkingE2EERename().rename(metadata: metadata, fileNameNew: fileNameNew, windowScene: windowScene) if error != .success { return NKError(errorCode: error.errorCode, errorDescription: error.errorDescription) } diff --git a/iOSClient/Networking/NCNetworkingProcess.swift b/iOSClient/Networking/NCNetworkingProcess.swift index 44a8c8cf81..0de3a169e6 100644 --- a/iOSClient/Networking/NCNetworkingProcess.swift +++ b/iOSClient/Networking/NCNetworkingProcess.swift @@ -318,6 +318,16 @@ actor NCNetworkingProcess { let countUploading = metadatas.filter { $0.status == self.global.metadataStatusUploading }.count - countTransferSuccess var availableProcess = NCBrandOptions.shared.numMaximumProcess - (countDownloading + countUploading) let isWiFi = self.networking.networkReachability == NKTypeReachability.reachableEthernetOrWiFi + // Banner + var banner: LucidBanner? + var token: Int? + defer { + if let banner { + Task { @MainActor in + banner.dismiss() + } + } + } // WEBDAV // @@ -434,20 +444,22 @@ actor NCNetworkingProcess { let controller = await getController(account: metadata.account, sceneIdentifier: metadata.sceneIdentifier) let payload = LucidBannerPayload(blocksTouches: true, draggable: false) - let bannerResults = await showUploadBanner(windowScene: windowScene, - payload: payload, - allowMinimizeOnTap: false, - onButtonTap: { - Task { - await self.cancelCurrentUpload() - } - }) + if banner == nil { + (banner, token) = await showUploadBanner(windowScene: windowScene, + payload: payload, + allowMinimizeOnTap: false, + onButtonTap: { + Task { + await self.cancelCurrentUpload() + } + }) + } await NCNetworkingE2EEUpload().upload(metadata: metadata, controller: controller, - banner: bannerResults.banner, + banner: banner, stageBanner: .button, - tokenBanner: bannerResults.token) { uploadRequest in + tokenBanner: token) { uploadRequest in Task {@MainActor in self.currentUploadRequest = uploadRequest } @@ -457,11 +469,6 @@ actor NCNetworkingProcess { } } - // wait dismiss banner before open another (loop) - if let banner = bannerResults.banner { - await banner.dismiss() - } - // UPLOAD CHUNK // } else if metadata.chunk > 0 { diff --git a/iOSClient/Settings/E2EE/NCManageE2EEModel.swift b/iOSClient/Settings/E2EE/NCManageE2EEModel.swift index e264ad7c09..f26f5bc9bd 100644 --- a/iOSClient/Settings/E2EE/NCManageE2EEModel.swift +++ b/iOSClient/Settings/E2EE/NCManageE2EEModel.swift @@ -38,7 +38,7 @@ class NCManageE2EE: NSObject, ObservableObject, ViewOnAppearHandling, NCEndToEnd /// Triggered when the view appears. func onViewAppear() { - if capabilities.e2EEEnabled && NCGlobal.shared.e2eeCompatibleVersions.contains(capabilities.e2EEApiVersion) { + if capabilities.e2EEEnabled { isEndToEndEnabled = NCPreferences().isEndToEndEnabled(account: session.account) if isEndToEndEnabled { statusOfService = NSLocalizedString("_status_e2ee_configured_", comment: "") diff --git a/iOSClient/Settings/NCPreferences.swift b/iOSClient/Settings/NCPreferences.swift index 87810b4f66..387fb10bfd 100644 --- a/iOSClient/Settings/NCPreferences.swift +++ b/iOSClient/Settings/NCPreferences.swift @@ -445,12 +445,10 @@ final class NCPreferences: NSObject { } func isEndToEndEnabled(account: String) -> Bool { - guard let capabilities = NCNetworking.shared.capabilities[account], - let certificate = getEndToEndCertificate(account: account), !certificate.isEmpty, + guard let certificate = getEndToEndCertificate(account: account), !certificate.isEmpty, let publicKey = getEndToEndPublicKey(account: account), !publicKey.isEmpty, let privateKey = getEndToEndPrivateKey(account: account), !privateKey.isEmpty, - let passphrase = getEndToEndPassphrase(account: account), !passphrase.isEmpty, - NCGlobal.shared.e2eeCompatibleVersions.contains(capabilities.e2EEApiVersion) else { + let passphrase = getEndToEndPassphrase(account: account), !passphrase.isEmpty else { return false } return true diff --git a/iOSClient/Settings/Settings/NCSettingsView.swift b/iOSClient/Settings/Settings/NCSettingsView.swift index c977da6abb..dbe221edac 100644 --- a/iOSClient/Settings/Settings/NCSettingsView.swift +++ b/iOSClient/Settings/Settings/NCSettingsView.swift @@ -197,7 +197,7 @@ struct NCSettingsView: View { .font(.footnote) }) // E2EEncryption` Section - if capabilities.e2EEEnabled && NCGlobal.shared.e2eeCompatibleVersions.contains(capabilities.e2EEApiVersion) { + if capabilities.e2EEEnabled { E2EESection(model: model) } // `Advanced` Section diff --git a/iOSClient/Share/Advanced/NCShareAdvancePermission.swift b/iOSClient/Share/Advanced/NCShareAdvancePermission.swift index a12198e3eb..1e458774c8 100644 --- a/iOSClient/Share/Advanced/NCShareAdvancePermission.swift +++ b/iOSClient/Share/Advanced/NCShareAdvancePermission.swift @@ -248,8 +248,7 @@ class NCShareAdvancePermission: UITableViewController, NCShareAdvanceFooterDeleg if isNewShare { let capabilities = await NKCapabilities.shared.getCapabilities(for: metadata.account) - if share.shareType != NKShare.ShareType.publicLink.rawValue, metadata.e2eEncrypted, - NCGlobal.shared.isE2eeVersion2(capabilities.e2EEApiVersion) { + if share.shareType != NKShare.ShareType.publicLink.rawValue, metadata.e2eEncrypted { if await NCNetworkingE2EE().isInUpload(account: metadata.account, serverUrl: metadata.serverUrlFileName) { await showErrorBanner(windowScene: windowScene, diff --git a/iOSClient/Share/Advanced/NCShareCells.swift b/iOSClient/Share/Advanced/NCShareCells.swift index f7071219cb..e6d3f38e31 100644 --- a/iOSClient/Share/Advanced/NCShareCells.swift +++ b/iOSClient/Share/Advanced/NCShareCells.swift @@ -83,7 +83,7 @@ enum NCUserPermission: CaseIterable, NCPermission { static func forDirectoryE2EE(account: String) -> [NCPermission] { let capabilities = NCNetworking.shared.capabilities[account] ?? NKCapabilities.Capabilities() - if NCGlobal.shared.isE2eeVersion2(capabilities.e2EEApiVersion) { + if capabilities.e2EEApiVersion.hasPrefix("2.") { return NCUserPermission.allCases } return [] @@ -107,7 +107,7 @@ enum NCUserPermission: CaseIterable, NCPermission { enum NCLinkEmailPermission: CaseIterable, NCPermission { static func forDirectoryE2EE(account: String) -> [any NCPermission] { let capabilities = NCNetworking.shared.capabilities[account] ?? NKCapabilities.Capabilities() - if NCGlobal.shared.isE2eeVersion2(capabilities.e2EEApiVersion) { + if capabilities.e2EEApiVersion.hasPrefix("2.") { return NCUserPermission.allCases } return [] diff --git a/iOSClient/Share/NCShare.swift b/iOSClient/Share/NCShare.swift index 8b0f109127..37729a443a 100644 --- a/iOSClient/Share/NCShare.swift +++ b/iOSClient/Share/NCShare.swift @@ -100,7 +100,7 @@ class NCShare: UIViewController, NCSharePagingContent { if metadata.e2eEncrypted { let metadataDirectory = await self.database.getMetadataDirectoryAsync(serverUrl: metadata.serverUrl, account: metadata.account) if capabilities.e2EEApiVersion == "1.2" || - (NCGlobal.shared.isE2eeVersion2(capabilities.e2EEApiVersion) && metadataDirectory?.e2eEncrypted ?? false) { + (capabilities.e2EEApiVersion.hasPrefix("2.") && metadataDirectory?.e2eEncrypted ?? false) { searchFieldTopConstraint.constant = -50 searchField.alpha = 0 btnContact.alpha = 0 diff --git a/iOSClient/Supporting Files/en.lproj/Localizable.strings b/iOSClient/Supporting Files/en.lproj/Localizable.strings index 1b9656f19a..3716a040e4 100644 --- a/iOSClient/Supporting Files/en.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/en.lproj/Localizable.strings @@ -788,3 +788,5 @@ You can stop it at any time, adjust the settings, and enable it again."; "_e2ee_no_enc_key_" = "End-to-end encryption error, cannot get encoded key"; "_e2ee_no_match_checksum_" = "End-to-end encryption error, checksum does not match"; "_e2ee_create_folder_" = "End-to-end encryption directory creation in progress, please wait …"; +"_e2ee_rename_file_" = "End-to-end encryption rename in progress, please wait …"; +"_e2ee_encrypt_folder_" = "End-to-end encryption folder in progress, please wait …"; diff --git a/iOSClient/Trash/Cell/NCTrashCellProtocol.swift b/iOSClient/Trash/Cell/NCTrashCellProtocol.swift index 5ba0cb2497..61f5e78321 100644 --- a/iOSClient/Trash/Cell/NCTrashCellProtocol.swift +++ b/iOSClient/Trash/Cell/NCTrashCellProtocol.swift @@ -38,7 +38,7 @@ extension NCTrashCellProtocol where Self: UICollectionViewCell { self.imageItem.image = image self.labelInfo?.text = (self.labelInfo?.text ?? "") + " · " + NCUtilityFileSystem().transformedSize(tableTrash.size) } - + self.accessibilityLabel = tableTrash.trashbinFileName + ", " + (self.labelInfo?.text ?? "") if self is NCTrashGridCell {