浏览代码

Merge branch 'develop'

Marino Faggiana 7 年之前
父节点
当前提交
62dfb11b73
共有 100 个文件被更改,包括 1638 次插入1371 次删除
  1. 35 20
      Nextcloud.xcodeproj/project.pbxproj
  2. 1 1
      Picker/DocumentPickerViewController.swift
  3. 1 1
      Share/ShareViewController.m
  4. 7 7
      iOSClient/.tx/config
  5. 78 19
      iOSClient/Actions/CCActions.swift
  6. 0 2
      iOSClient/AppDelegate.h
  7. 121 41
      iOSClient/AppDelegate.m
  8. 6 4
      iOSClient/AutoUpload/NCAutoUpload.m
  9. 0 2
      iOSClient/Brand/Intro/ImagesIntro.xcassets/IntroNoCryptoCloud.imageset/Contents.json
  10. 二进制
      iOSClient/Brand/Intro/ImagesIntro.xcassets/IntroNoCryptoCloud.imageset/IntroNoCryptoCloud.png
  11. 二进制
      iOSClient/Brand/Intro/ImagesIntro.xcassets/IntroNoCryptoCloud.imageset/IntroNoCryptoCloud@3x.png
  12. 0 2
      iOSClient/Brand/Intro/ImagesIntro.xcassets/intro1.imageset/Contents.json
  13. 二进制
      iOSClient/Brand/Intro/ImagesIntro.xcassets/intro1.imageset/intro1.png
  14. 二进制
      iOSClient/Brand/Intro/ImagesIntro.xcassets/intro1.imageset/intro1@3x.png
  15. 二进制
      iOSClient/Brand/Intro/ImagesIntro.xcassets/intro11.imageset/intro11@2x.png
  16. 二进制
      iOSClient/Brand/Intro/ImagesIntro.xcassets/intro2.imageset/intro2@2x.png
  17. 0 2
      iOSClient/Brand/Intro/ImagesIntro.xcassets/intro3.imageset/Contents.json
  18. 二进制
      iOSClient/Brand/Intro/ImagesIntro.xcassets/intro3.imageset/intro4.png
  19. 二进制
      iOSClient/Brand/Intro/ImagesIntro.xcassets/intro3.imageset/intro4@2x.png
  20. 二进制
      iOSClient/Brand/Intro/ImagesIntro.xcassets/intro3.imageset/intro4@3x.png
  21. 5 6
      iOSClient/Brand/NCBrand.swift
  22. 9 8
      iOSClient/CCGlobal.h
  23. 4 0
      iOSClient/CCGlobal.m
  24. 30 2
      iOSClient/Create/CCCreateCloud.swift
  25. 1 0
      iOSClient/Database/NCDatabase.swift
  26. 42 10
      iOSClient/Database/NCManageDatabase.swift
  27. 12 10
      iOSClient/Favorites/CCFavorites.m
  28. 二进制
      iOSClient/Images.xcassets/swipeDelete.imageset/swipeDelete.png
  29. 二进制
      iOSClient/Images.xcassets/swipeDelete.imageset/swipeDelete@2x.png
  30. 二进制
      iOSClient/Images.xcassets/swipeDelete.imageset/swipeDelete@3x.png
  31. 21 0
      iOSClient/Images.xcassets/titleExternal.imageset/Contents.json
  32. 二进制
      iOSClient/Images.xcassets/titleExternal.imageset/titleExternal@2x.png
  33. 21 0
      iOSClient/Images.xcassets/titlePublic.imageset/Contents.json
  34. 二进制
      iOSClient/Images.xcassets/titlePublic.imageset/titlePublic@2x.png
  35. 0 0
      iOSClient/Images.xcassets/titleShared_with_me.imageset/Contents.json
  36. 0 0
      iOSClient/Images.xcassets/titleShared_with_me.imageset/titleShare@2x.png
  37. 1 1
      iOSClient/Library/MWPhotoBrowser/MWPhotoBrowser.h
  38. 5 9
      iOSClient/Library/MWPhotoBrowser/MWPhotoBrowser.m
  39. 2 2
      iOSClient/Library/OCCommunicationLib/OCWebDavClient/OCWebDAVClient.h
  40. 15 3
      iOSClient/Library/SwiftWebVC/SwiftModalWebVC.swift
  41. 18 7
      iOSClient/Library/SwiftWebVC/SwiftWebVC.swift
  42. 1 0
      iOSClient/Library/VFR Pdf Reader/Sources/ReaderViewController.h
  43. 11 0
      iOSClient/Library/VFR Pdf Reader/Sources/ReaderViewController.m
  44. 5 1
      iOSClient/Login/CCLogin.h
  45. 223 89
      iOSClient/Login/CCLogin.m
  46. 17 3
      iOSClient/Login/CCLogin.storyboard
  47. 56 16
      iOSClient/Login/CCLoginWeb.swift
  48. 1 0
      iOSClient/Main/CCCellMain.h
  49. 2 0
      iOSClient/Main/CCCellMainTransfer.h
  50. 34 14
      iOSClient/Main/CCDetail.m
  51. 1 3
      iOSClient/Main/CCMain.h
  52. 289 209
      iOSClient/Main/CCMain.m
  53. 13 0
      iOSClient/Main/CCMainTabBarController.swift
  54. 16 3
      iOSClient/Main/CCMore.swift
  55. 6 1
      iOSClient/Main/CCSplit.m
  56. 0 12
      iOSClient/Networking/CCNetworking.h
  57. 176 440
      iOSClient/Networking/CCNetworking.m
  58. 8 2
      iOSClient/Networking/NCNetworkingSync.h
  59. 140 84
      iOSClient/Networking/NCNetworkingSync.m
  60. 4 13
      iOSClient/Networking/OCNetworking.h
  61. 9 120
      iOSClient/Networking/OCNetworking.m
  62. 5 0
      iOSClient/Notification/CCNotification.swift
  63. 9 1
      iOSClient/PeekPop/CCPeekPop.m
  64. 5 3
      iOSClient/Photos/CCPhotos.m
  65. 1 1
      iOSClient/QuickActions/CCQuickActions.m
  66. 5 3
      iOSClient/Security/NCEndToEndMetadata.swift
  67. 2 3
      iOSClient/Settings/CCAdvanced.m
  68. 65 43
      iOSClient/Settings/CCManageAccount.m
  69. 10 128
      iOSClient/Settings/NCEndToEndInitialize.swift
  70. 6 1
      iOSClient/Settings/NCManageEndToEndEncryption.h
  71. 42 8
      iOSClient/Settings/NCManageEndToEndEncryption.m
  72. 11 2
      iOSClient/Share/CCShareUserOC.m
  73. 二进制
      iOSClient/Supporting Files/cs-CZ.lproj/Error.strings
  74. 二进制
      iOSClient/Supporting Files/cs-CZ.lproj/Localizable.strings
  75. 二进制
      iOSClient/Supporting Files/de.lproj/Error.strings
  76. 二进制
      iOSClient/Supporting Files/de.lproj/Localizable.strings
  77. 二进制
      iOSClient/Supporting Files/en-GB.lproj/Error.strings
  78. 二进制
      iOSClient/Supporting Files/en-GB.lproj/Localizable.strings
  79. 4 2
      iOSClient/Supporting Files/en.lproj/Error.strings
  80. 26 7
      iOSClient/Supporting Files/en.lproj/Localizable.strings
  81. 0 0
      iOSClient/Supporting Files/es-419.lproj/BKPasscodeView.strings
  82. 0 0
      iOSClient/Supporting Files/es-419.lproj/CTAssetsPicker.strings
  83. 二进制
      iOSClient/Supporting Files/es-419.lproj/Error.strings
  84. 0 0
      iOSClient/Supporting Files/es-419.lproj/InfoPlist.strings
  85. 0 0
      iOSClient/Supporting Files/es-419.lproj/Intro.strings
  86. 二进制
      iOSClient/Supporting Files/es-419.lproj/Localizable.strings
  87. 0 0
      iOSClient/Supporting Files/es-419.lproj/SwiftWebVC.strings
  88. 二进制
      iOSClient/Supporting Files/es-CL.lproj/Error.strings
  89. 二进制
      iOSClient/Supporting Files/es-CL.lproj/Localizable.strings
  90. 二进制
      iOSClient/Supporting Files/es-CO.lproj/Error.strings
  91. 二进制
      iOSClient/Supporting Files/es-CO.lproj/Localizable.strings
  92. 二进制
      iOSClient/Supporting Files/es-CR.lproj/Error.strings
  93. 二进制
      iOSClient/Supporting Files/es-CR.lproj/Localizable.strings
  94. 二进制
      iOSClient/Supporting Files/es-DO.lproj/Error.strings
  95. 二进制
      iOSClient/Supporting Files/es-DO.lproj/Localizable.strings
  96. 二进制
      iOSClient/Supporting Files/es-EC.lproj/Error.strings
  97. 二进制
      iOSClient/Supporting Files/es-EC.lproj/Localizable.strings
  98. 二进制
      iOSClient/Supporting Files/es-GT.lproj/Error.strings
  99. 二进制
      iOSClient/Supporting Files/es-GT.lproj/Localizable.strings
  100. 二进制
      iOSClient/Supporting Files/es-HN.lproj/Error.strings

+ 35 - 20
Nextcloud.xcodeproj/project.pbxproj

@@ -123,10 +123,10 @@
 		F7169A1C1EE590930086BD69 /* NCShares.m in Sources */ = {isa = PBXBuildFile; fileRef = F7169A181EE590930086BD69 /* NCShares.m */; };
 		F7169A1D1EE590930086BD69 /* NCSharesCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F7169A1A1EE590930086BD69 /* NCSharesCell.m */; };
 		F7169A1E1EE590930086BD69 /* NCSharesCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F7169A1B1EE590930086BD69 /* NCSharesCell.xib */; };
-		F717F0001F96661400A324A5 /* NCEntoToEndInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = F717EFFF1F96661400A324A5 /* NCEntoToEndInterface.swift */; };
 		F720E01F1E48C73E001A4B9E /* CCActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F720E01E1E48C73E001A4B9E /* CCActions.swift */; };
 		F7226EDC1EE4089300EBECB1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7226EDB1EE4089300EBECB1 /* Main.storyboard */; };
 		F725437C1E12A44A009BF4C2 /* CCSection.m in Sources */ = {isa = PBXBuildFile; fileRef = F78F6FAF1CC8CCB700F4EA25 /* CCSection.m */; };
+		F726EEEC1FED1C820030B9C8 /* NCEndToEndInitialize.swift in Sources */ = {isa = PBXBuildFile; fileRef = F726EEEB1FED1C820030B9C8 /* NCEndToEndInitialize.swift */; };
 		F72AAECA1E5C60C700BB17E1 /* AHKActionSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = F72AAEC31E5C60C700BB17E1 /* AHKActionSheet.m */; };
 		F72AAECB1E5C60C700BB17E1 /* AHKActionSheetViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F72AAEC51E5C60C700BB17E1 /* AHKActionSheetViewController.m */; };
 		F732B3371E8045A1002B7D75 /* SwiftWebVC.strings in Resources */ = {isa = PBXBuildFile; fileRef = F732B3351E8045A1002B7D75 /* SwiftWebVC.strings */; };
@@ -782,10 +782,10 @@
 		F7169A4D1EE59C640086BD69 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
 		F7169A4E1EE59C640086BD69 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Intro.strings; sourceTree = "<group>"; };
 		F7169A4F1EE59C640086BD69 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Error.strings; sourceTree = "<group>"; };
-		F717EFFF1F96661400A324A5 /* NCEntoToEndInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCEntoToEndInterface.swift; sourceTree = "<group>"; };
 		F720E01E1E48C73E001A4B9E /* CCActions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = CCActions.swift; path = Actions/CCActions.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
 		F7226EDB1EE4089300EBECB1 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
 		F7229B491DF71BB300E8C4E7 /* AUTHORS */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AUTHORS; sourceTree = SOURCE_ROOT; };
+		F726EEEB1FED1C820030B9C8 /* NCEndToEndInitialize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCEndToEndInitialize.swift; sourceTree = "<group>"; };
 		F7296A661C8880ED001A7809 /* CCloadItemData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CCloadItemData.swift; sourceTree = "<group>"; };
 		F72AAEC21E5C60C700BB17E1 /* AHKActionSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AHKActionSheet.h; sourceTree = "<group>"; };
 		F72AAEC31E5C60C700BB17E1 /* AHKActionSheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AHKActionSheet.m; sourceTree = "<group>"; };
@@ -793,6 +793,20 @@
 		F72AAEC51E5C60C700BB17E1 /* AHKActionSheetViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AHKActionSheetViewController.m; sourceTree = "<group>"; };
 		F73049B81CB567F000C7C320 /* NSString+TruncateToWidth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+TruncateToWidth.h"; sourceTree = "<group>"; };
 		F73049B91CB567F000C7C320 /* NSString+TruncateToWidth.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+TruncateToWidth.m"; sourceTree = "<group>"; };
+		F7320931201B812F008A0888 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/CTAssetsPicker.strings; sourceTree = "<group>"; };
+		F7320932201B812F008A0888 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/SwiftWebVC.strings; sourceTree = "<group>"; };
+		F7320933201B812F008A0888 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/BKPasscodeView.strings; sourceTree = "<group>"; };
+		F7320934201B812F008A0888 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Localizable.strings; sourceTree = "<group>"; };
+		F7320935201B8130008A0888 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+		F7320936201B8130008A0888 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Intro.strings; sourceTree = "<group>"; };
+		F7320937201B8130008A0888 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Error.strings; sourceTree = "<group>"; };
+		F7320938201B81E4008A0888 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-419"; path = "es-419.lproj/CTAssetsPicker.strings"; sourceTree = "<group>"; };
+		F7320939201B81E4008A0888 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-419"; path = "es-419.lproj/SwiftWebVC.strings"; sourceTree = "<group>"; };
+		F732093A201B81E4008A0888 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-419"; path = "es-419.lproj/BKPasscodeView.strings"; sourceTree = "<group>"; };
+		F732093B201B81E4008A0888 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-419"; path = "es-419.lproj/Localizable.strings"; sourceTree = "<group>"; };
+		F732093C201B81E4008A0888 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-419"; path = "es-419.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
+		F732093D201B81E5008A0888 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-419"; path = "es-419.lproj/Intro.strings"; sourceTree = "<group>"; };
+		F732093E201B81E5008A0888 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-419"; path = "es-419.lproj/Error.strings"; sourceTree = "<group>"; };
 		F732B3361E8045A1002B7D75 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/SwiftWebVC.strings; sourceTree = "<group>"; };
 		F732BA031D76CE1500E9878B /* CCNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCNetworking.h; sourceTree = "<group>"; };
 		F732BA041D76CE1500E9878B /* CCNetworking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCNetworking.m; sourceTree = "<group>"; };
@@ -894,13 +908,6 @@
 		F74344911E128E96001CC831 /* PickerFileProvider.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = PickerFileProvider.appex; sourceTree = BUILT_PRODUCTS_DIR; };
 		F743B2C31C95BBE8006F5B4A /* CCShareInfoCMOC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCShareInfoCMOC.h; sourceTree = "<group>"; };
 		F743B2C41C95BBE8006F5B4A /* CCShareInfoCMOC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCShareInfoCMOC.m; sourceTree = "<group>"; };
-		F74C5D901F923E4700B7CC01 /* fi-FI */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "fi-FI"; path = "fi-FI.lproj/CTAssetsPicker.strings"; sourceTree = "<group>"; };
-		F74C5D911F923E4700B7CC01 /* fi-FI */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "fi-FI"; path = "fi-FI.lproj/SwiftWebVC.strings"; sourceTree = "<group>"; };
-		F74C5D921F923E4700B7CC01 /* fi-FI */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "fi-FI"; path = "fi-FI.lproj/BKPasscodeView.strings"; sourceTree = "<group>"; };
-		F74C5D931F923E4700B7CC01 /* fi-FI */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "fi-FI"; path = "fi-FI.lproj/Localizable.strings"; sourceTree = "<group>"; };
-		F74C5D941F923E4800B7CC01 /* fi-FI */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "fi-FI"; path = "fi-FI.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
-		F74C5D951F923E4800B7CC01 /* fi-FI */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "fi-FI"; path = "fi-FI.lproj/Intro.strings"; sourceTree = "<group>"; };
-		F74C5D961F923E4800B7CC01 /* fi-FI */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "fi-FI"; path = "fi-FI.lproj/Error.strings"; sourceTree = "<group>"; };
 		F74D3DBD1BAC1941000BAE4B /* OCNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OCNetworking.h; sourceTree = "<group>"; };
 		F74D3DBE1BAC1941000BAE4B /* OCNetworking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OCNetworking.m; sourceTree = "<group>"; };
 		F75037431DBFA91A008FB480 /* ALView+PureLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ALView+PureLayout.h"; sourceTree = "<group>"; };
@@ -2549,11 +2556,12 @@
 				F7A321AC1E9E6AD50069AD1B /* CCAdvanced.m */,
 				F7ACE42C1BAC0268006C0017 /* CCManageAccount.h */,
 				F7ACE42D1BAC0268006C0017 /* CCManageAccount.m */,
+				F75AC2421F1F62450073EC19 /* NCManageAutoUploadFileName.swift */,
 				F7ACE42E1BAC0268006C0017 /* CCManageAutoUpload.h */,
 				F7ACE42F1BAC0268006C0017 /* CCManageAutoUpload.m */,
 				F7ACE4301BAC0268006C0017 /* CCSettings.h */,
 				F7ACE4311BAC0268006C0017 /* CCSettings.m */,
-				F75AC2421F1F62450073EC19 /* NCManageAutoUploadFileName.swift */,
+				F726EEEB1FED1C820030B9C8 /* NCEndToEndInitialize.swift */,
 				F738E8401F90FFD100F95C8E /* NCManageEndToEndEncryption.h */,
 				F738E8411F90FFD100F95C8E /* NCManageEndToEndEncryption.m */,
 			);
@@ -3143,7 +3151,6 @@
 				F7FE125D1BAC03FB0041924B /* CCBKPasscode.m */,
 				F7F801001D98205A007537BC /* CCCertificate.h */,
 				F7F801011D98205A007537BC /* CCCertificate.m */,
-				F717EFFF1F96661400A324A5 /* NCEntoToEndInterface.swift */,
 				F7F878AD1FB9E3B900599E4F /* NCEndToEndMetadata.swift */,
 				F70CAE381F8CF31A008125FD /* NCEndToEndEncryption.h */,
 				F70CAE391F8CF31A008125FD /* NCEndToEndEncryption.m */,
@@ -3315,7 +3322,6 @@
 				"sk-SK",
 				"en-GB",
 				"zh-Hans",
-				"fi-FI",
 				"ka-GE",
 				hu,
 				"zh-Hant-TW",
@@ -3335,6 +3341,8 @@
 				"es-SV",
 				"es-UY",
 				"cs-CZ",
+				ko,
+				"es-419",
 			);
 			mainGroup = F7F67B9F1A24D27800EE80DA;
 			productRefGroup = F7F67B9F1A24D27800EE80DA;
@@ -3880,7 +3888,6 @@
 				F7BAADC81ED5A87C00B7EAD4 /* NCDatabase.swift in Sources */,
 				F77B0E541D118A16002130FE /* CCMove.m in Sources */,
 				F70022E61EC4C9100080073F /* OCXMLServerErrorsParser.m in Sources */,
-				F717F0001F96661400A324A5 /* NCEntoToEndInterface.swift in Sources */,
 				F762CB171EACB66200B38484 /* XLFormRegexValidator.m in Sources */,
 				F73CC0691E813DFF006E3047 /* BKPasscodeDummyViewController.m in Sources */,
 				F762CB1A1EACB66200B38484 /* XLForm.m in Sources */,
@@ -3973,6 +3980,7 @@
 				F762CB0A1EACB66200B38484 /* XLFormDescriptor.m in Sources */,
 				F7D4238C1F0596C6009C9782 /* UIXToolbarView.m in Sources */,
 				F7A321791E9E3EAF0069AD1B /* CCTransfers.m in Sources */,
+				F726EEEC1FED1C820030B9C8 /* NCEndToEndInitialize.swift in Sources */,
 				F70CAE3A1F8CF31A008125FD /* NCEndToEndEncryption.m in Sources */,
 				F73B4F0C1F470D9100BBEE4B /* nsHebrewProber.cpp in Sources */,
 				F762CAFB1EACB66200B38484 /* XLFormDatePickerCell.m in Sources */,
@@ -4071,7 +4079,6 @@
 				F7D532531F5D4155006568B1 /* sk-SK */,
 				F7D5328E1F5D443B006568B1 /* en-GB */,
 				F7D532A31F5D4461006568B1 /* zh-Hans */,
-				F74C5D921F923E4700B7CC01 /* fi-FI */,
 				F77438EA1FCD694900662C46 /* ka-GE */,
 				F77438F11FCD69D200662C46 /* hu */,
 				F77438F81FCD6A0D00662C46 /* zh-Hant-TW */,
@@ -4091,6 +4098,8 @@
 				F774395A1FCD6D8200662C46 /* es-SV */,
 				F77439611FCD6D9C00662C46 /* es-UY */,
 				F7BB04841FD58ACB00BBFD2A /* cs-CZ */,
+				F7320933201B812F008A0888 /* ko */,
+				F732093A201B81E4008A0888 /* es-419 */,
 			);
 			name = BKPasscodeView.strings;
 			path = "Supporting Files";
@@ -4116,7 +4125,6 @@
 				F7D532521F5D4155006568B1 /* sk-SK */,
 				F7D5328D1F5D443B006568B1 /* en-GB */,
 				F7D532A21F5D4461006568B1 /* zh-Hans */,
-				F74C5D911F923E4700B7CC01 /* fi-FI */,
 				F77438E91FCD694900662C46 /* ka-GE */,
 				F77438F01FCD69D200662C46 /* hu */,
 				F77438F71FCD6A0D00662C46 /* zh-Hant-TW */,
@@ -4136,6 +4144,8 @@
 				F77439591FCD6D8100662C46 /* es-SV */,
 				F77439601FCD6D9C00662C46 /* es-UY */,
 				F7BB04831FD58ACA00BBFD2A /* cs-CZ */,
+				F7320932201B812F008A0888 /* ko */,
+				F7320939201B81E4008A0888 /* es-419 */,
 			);
 			name = SwiftWebVC.strings;
 			path = "Supporting Files";
@@ -4161,7 +4171,6 @@
 				F7D532561F5D4155006568B1 /* sk-SK */,
 				F7D532911F5D443B006568B1 /* en-GB */,
 				F7D532A61F5D4462006568B1 /* zh-Hans */,
-				F74C5D951F923E4800B7CC01 /* fi-FI */,
 				F77438ED1FCD694900662C46 /* ka-GE */,
 				F77438F41FCD69D300662C46 /* hu */,
 				F77438FB1FCD6A0E00662C46 /* zh-Hant-TW */,
@@ -4181,6 +4190,8 @@
 				F774395D1FCD6D8200662C46 /* es-SV */,
 				F77439641FCD6D9D00662C46 /* es-UY */,
 				F7BB04871FD58ACB00BBFD2A /* cs-CZ */,
+				F7320936201B8130008A0888 /* ko */,
+				F732093D201B81E5008A0888 /* es-419 */,
 			);
 			name = Intro.strings;
 			path = "Supporting Files";
@@ -4206,7 +4217,6 @@
 				F7D532511F5D4155006568B1 /* sk-SK */,
 				F7D5328C1F5D443B006568B1 /* en-GB */,
 				F7D532A11F5D4461006568B1 /* zh-Hans */,
-				F74C5D901F923E4700B7CC01 /* fi-FI */,
 				F77438E81FCD694900662C46 /* ka-GE */,
 				F77438EF1FCD69D200662C46 /* hu */,
 				F77438F61FCD6A0D00662C46 /* zh-Hant-TW */,
@@ -4226,6 +4236,8 @@
 				F77439581FCD6D8100662C46 /* es-SV */,
 				F774395F1FCD6D9C00662C46 /* es-UY */,
 				F7BB04821FD58ACA00BBFD2A /* cs-CZ */,
+				F7320931201B812F008A0888 /* ko */,
+				F7320938201B81E4008A0888 /* es-419 */,
 			);
 			name = CTAssetsPicker.strings;
 			path = "Supporting Files";
@@ -4251,7 +4263,6 @@
 				F7D532571F5D4156006568B1 /* sk-SK */,
 				F7D532921F5D443B006568B1 /* en-GB */,
 				F7D532A71F5D4462006568B1 /* zh-Hans */,
-				F74C5D961F923E4800B7CC01 /* fi-FI */,
 				F77438EE1FCD694900662C46 /* ka-GE */,
 				F77438F51FCD69D300662C46 /* hu */,
 				F77438FC1FCD6A0E00662C46 /* zh-Hant-TW */,
@@ -4271,6 +4282,8 @@
 				F774395E1FCD6D8200662C46 /* es-SV */,
 				F77439651FCD6D9D00662C46 /* es-UY */,
 				F7BB04881FD58ACB00BBFD2A /* cs-CZ */,
+				F7320937201B8130008A0888 /* ko */,
+				F732093E201B81E5008A0888 /* es-419 */,
 			);
 			name = Error.strings;
 			path = "Supporting Files";
@@ -4296,7 +4309,6 @@
 				F7D532551F5D4155006568B1 /* sk-SK */,
 				F7D532901F5D443B006568B1 /* en-GB */,
 				F7D532A51F5D4461006568B1 /* zh-Hans */,
-				F74C5D941F923E4800B7CC01 /* fi-FI */,
 				F77438EC1FCD694900662C46 /* ka-GE */,
 				F77438F31FCD69D300662C46 /* hu */,
 				F77438FA1FCD6A0E00662C46 /* zh-Hant-TW */,
@@ -4316,6 +4328,8 @@
 				F774395C1FCD6D8200662C46 /* es-SV */,
 				F77439631FCD6D9C00662C46 /* es-UY */,
 				F7BB04861FD58ACB00BBFD2A /* cs-CZ */,
+				F7320935201B8130008A0888 /* ko */,
+				F732093C201B81E4008A0888 /* es-419 */,
 			);
 			name = InfoPlist.strings;
 			path = "Supporting Files";
@@ -4341,7 +4355,6 @@
 				F7D532541F5D4155006568B1 /* sk-SK */,
 				F7D5328F1F5D443B006568B1 /* en-GB */,
 				F7D532A41F5D4461006568B1 /* zh-Hans */,
-				F74C5D931F923E4700B7CC01 /* fi-FI */,
 				F77438EB1FCD694900662C46 /* ka-GE */,
 				F77438F21FCD69D300662C46 /* hu */,
 				F77438F91FCD6A0D00662C46 /* zh-Hant-TW */,
@@ -4361,6 +4374,8 @@
 				F774395B1FCD6D8200662C46 /* es-SV */,
 				F77439621FCD6D9C00662C46 /* es-UY */,
 				F7BB04851FD58ACB00BBFD2A /* cs-CZ */,
+				F7320934201B812F008A0888 /* ko */,
+				F732093B201B81E4008A0888 /* es-419 */,
 			);
 			name = Localizable.strings;
 			path = "Supporting Files";

+ 1 - 1
Picker/DocumentPickerViewController.swift

@@ -711,7 +711,7 @@ extension DocumentPickerViewController: UITableViewDataSource {
             
         } else {
             
-            // e2e DENIED
+            // E2EE DENIED
             if (metadata?.e2eEncrypted == true) {
                 return
             }

+ 1 - 1
Share/ShareViewController.m

@@ -203,7 +203,7 @@
     viewController.barTintColor = barTintColor;
     viewController.tintColorTitle = tintColor;
     viewController.networkingOperationQueue = _networkingOperationQueue;
-    // E2E
+    // E2EE
     viewController.includeDirectoryE2EEncryption = NO;
 
     [navigationController setModalPresentationStyle:UIModalPresentationFormSheet];

+ 7 - 7
iOSClient/.tx/config

@@ -6,46 +6,46 @@ file_filter = Supporting Files/<lang>.lproj/BKPasscodeView.strings
 source_file = Supporting Files/en.lproj/BKPasscodeView.strings
 source_lang = en
 type = STRINGS
-lang_map = pt_BR:pt-BR,zh_CN:zh-Hans,fi_FI:fi-FI,es_MX:es-MX,nb_NO:nb-NO,cs_CZ:cs-CZ,en_GB:en-GB,es_AR:es-AR,sk_SK:sk-SK,hu_HU:hu,ka_GE:ka-GE,zh_TW:zh-Hant-TW,es_CL:es-CL,es_CO:es-CO,es_CR:es-CR,es_DO:es-DO,es_EC:es-EC,es_GT:es-GT,es_HN:es-HN,es_NI:es-NI,es_PA:es-PA,es_PE:es-PE,es_PR:es-PR,es_PY:es-PY,es_SV:es-SV,es_UY:es-UY
+lang_map = pt_BR:pt-BR,zh_CN:zh-Hans,fi_FI:fi-FI,es_MX:es-MX,nb_NO:nb-NO,cs_CZ:cs-CZ,en_GB:en-GB,es_AR:es-AR,sk_SK:sk-SK,hu_HU:hu,ka_GE:ka-GE,zh_TW:zh-Hant-TW,es_CL:es-CL,es_CO:es-CO,es_CR:es-CR,es_DO:es-DO,es_EC:es-EC,es_GT:es-GT,es_HN:es-HN,es_NI:es-NI,es_PA:es-PA,es_PE:es-PE,es_PR:es-PR,es_PY:es-PY,es_SV:es-SV,es_UY:es-UY,es_419:es-419
 
 [nextcloud.ios-assetspicker]
 file_filter = Supporting Files/<lang>.lproj/CTAssetsPicker.strings
 source_file = Supporting Files/en.lproj/CTAssetsPicker.strings
 source_lang = en
 type = STRINGS
-lang_map = pt_BR:pt-BR,zh_CN:zh-Hans,fi_FI:fi-FI,es_MX:es-MX,nb_NO:nb-NO,cs_CZ:cs-CZ,en_GB:en-GB,es_AR:es-AR,sk_SK:sk-SK,hu_HU:hu,ka_GE:ka-GE,zh_TW:zh-Hant-TW,es_CL:es-CL,es_CO:es-CO,es_CR:es-CR,es_DO:es-DO,es_EC:es-EC,es_GT:es-GT,es_HN:es-HN,es_NI:es-NI,es_PA:es-PA,es_PE:es-PE,es_PR:es-PR,es_PY:es-PY,es_SV:es-SV,es_UY:es-UY
+lang_map = pt_BR:pt-BR,zh_CN:zh-Hans,fi_FI:fi-FI,es_MX:es-MX,nb_NO:nb-NO,cs_CZ:cs-CZ,en_GB:en-GB,es_AR:es-AR,sk_SK:sk-SK,hu_HU:hu,ka_GE:ka-GE,zh_TW:zh-Hant-TW,es_CL:es-CL,es_CO:es-CO,es_CR:es-CR,es_DO:es-DO,es_EC:es-EC,es_GT:es-GT,es_HN:es-HN,es_NI:es-NI,es_PA:es-PA,es_PE:es-PE,es_PR:es-PR,es_PY:es-PY,es_SV:es-SV,es_UY:es-UY,es_419:es-419
 
 [nextcloud.ios-error]
 file_filter = Supporting Files/<lang>.lproj/Error.strings
 source_file = Supporting Files/en.lproj/Error.strings
 source_lang = en
 type = STRINGS
-lang_map = pt_BR:pt-BR,zh_CN:zh-Hans,fi_FI:fi-FI,es_MX:es-MX,nb_NO:nb-NO,cs_CZ:cs-CZ,en_GB:en-GB,es_AR:es-AR,sk_SK:sk-SK,hu_HU:hu,ka_GE:ka-GE,zh_TW:zh-Hant-TW,es_CL:es-CL,es_CO:es-CO,es_CR:es-CR,es_DO:es-DO,es_EC:es-EC,es_GT:es-GT,es_HN:es-HN,es_NI:es-NI,es_PA:es-PA,es_PE:es-PE,es_PR:es-PR,es_PY:es-PY,es_SV:es-SV,es_UY:es-UY
+lang_map = pt_BR:pt-BR,zh_CN:zh-Hans,fi_FI:fi-FI,es_MX:es-MX,nb_NO:nb-NO,cs_CZ:cs-CZ,en_GB:en-GB,es_AR:es-AR,sk_SK:sk-SK,hu_HU:hu,ka_GE:ka-GE,zh_TW:zh-Hant-TW,es_CL:es-CL,es_CO:es-CO,es_CR:es-CR,es_DO:es-DO,es_EC:es-EC,es_GT:es-GT,es_HN:es-HN,es_NI:es-NI,es_PA:es-PA,es_PE:es-PE,es_PR:es-PR,es_PY:es-PY,es_SV:es-SV,es_UY:es-UY,es_419:es-419
 
 [nextcloud.ios-infoplist]
 file_filter = Supporting Files/<lang>.lproj/InfoPlist.strings
 source_file = Supporting Files/en.lproj/InfoPlist.strings
 source_lang = en
 type = STRINGS
-lang_map = pt_BR:pt-BR,zh_CN:zh-Hans,fi_FI:fi-FI,es_MX:es-MX,nb_NO:nb-NO,cs_CZ:cs-CZ,en_GB:en-GB,es_AR:es-AR,sk_SK:sk-SK,hu_HU:hu,ka_GE:ka-GE,zh_TW:zh-Hant-TW,es_CL:es-CL,es_CO:es-CO,es_CR:es-CR,es_DO:es-DO,es_EC:es-EC,es_GT:es-GT,es_HN:es-HN,es_NI:es-NI,es_PA:es-PA,es_PE:es-PE,es_PR:es-PR,es_PY:es-PY,es_SV:es-SV,es_UY:es-UY
+lang_map = pt_BR:pt-BR,zh_CN:zh-Hans,fi_FI:fi-FI,es_MX:es-MX,nb_NO:nb-NO,cs_CZ:cs-CZ,en_GB:en-GB,es_AR:es-AR,sk_SK:sk-SK,hu_HU:hu,ka_GE:ka-GE,zh_TW:zh-Hant-TW,es_CL:es-CL,es_CO:es-CO,es_CR:es-CR,es_DO:es-DO,es_EC:es-EC,es_GT:es-GT,es_HN:es-HN,es_NI:es-NI,es_PA:es-PA,es_PE:es-PE,es_PR:es-PR,es_PY:es-PY,es_SV:es-SV,es_UY:es-UY,es_419:es-419
 
 [nextcloud.ios-intro]
 file_filter = Supporting Files/<lang>.lproj/Intro.strings
 source_file = Supporting Files/en.lproj/Intro.strings
 source_lang = en
 type = STRINGS
-lang_map = pt_BR:pt-BR,zh_CN:zh-Hans,fi_FI:fi-FI,es_MX:es-MX,nb_NO:nb-NO,cs_CZ:cs-CZ,en_GB:en-GB,es_AR:es-AR,sk_SK:sk-SK,hu_HU:hu,ka_GE:ka-GE,zh_TW:zh-Hant-TW,es_CL:es-CL,es_CO:es-CO,es_CR:es-CR,es_DO:es-DO,es_EC:es-EC,es_GT:es-GT,es_HN:es-HN,es_NI:es-NI,es_PA:es-PA,es_PE:es-PE,es_PR:es-PR,es_PY:es-PY,es_SV:es-SV,es_UY:es-UY
+lang_map = pt_BR:pt-BR,zh_CN:zh-Hans,fi_FI:fi-FI,es_MX:es-MX,nb_NO:nb-NO,cs_CZ:cs-CZ,en_GB:en-GB,es_AR:es-AR,sk_SK:sk-SK,hu_HU:hu,ka_GE:ka-GE,zh_TW:zh-Hant-TW,es_CL:es-CL,es_CO:es-CO,es_CR:es-CR,es_DO:es-DO,es_EC:es-EC,es_GT:es-GT,es_HN:es-HN,es_NI:es-NI,es_PA:es-PA,es_PE:es-PE,es_PR:es-PR,es_PY:es-PY,es_SV:es-SV,es_UY:es-UY,es_419:es-419
 
 [nextcloud.ios-localizable]
 file_filter = Supporting Files/<lang>.lproj/Localizable.strings
 source_file = Supporting Files/en.lproj/Localizable.strings
 source_lang = en
 type = STRINGS
-lang_map = pt_BR:pt-BR,zh_CN:zh-Hans,fi_FI:fi-FI,es_MX:es-MX,nb_NO:nb-NO,cs_CZ:cs-CZ,en_GB:en-GB,es_AR:es-AR,sk_SK:sk-SK,hu_HU:hu,ka_GE:ka-GE,zh_TW:zh-Hant-TW,es_CL:es-CL,es_CO:es-CO,es_CR:es-CR,es_DO:es-DO,es_EC:es-EC,es_GT:es-GT,es_HN:es-HN,es_NI:es-NI,es_PA:es-PA,es_PE:es-PE,es_PR:es-PR,es_PY:es-PY,es_SV:es-SV,es_UY:es-UY
+lang_map = pt_BR:pt-BR,zh_CN:zh-Hans,fi_FI:fi-FI,es_MX:es-MX,nb_NO:nb-NO,cs_CZ:cs-CZ,en_GB:en-GB,es_AR:es-AR,sk_SK:sk-SK,hu_HU:hu,ka_GE:ka-GE,zh_TW:zh-Hant-TW,es_CL:es-CL,es_CO:es-CO,es_CR:es-CR,es_DO:es-DO,es_EC:es-EC,es_GT:es-GT,es_HN:es-HN,es_NI:es-NI,es_PA:es-PA,es_PE:es-PE,es_PR:es-PR,es_PY:es-PY,es_SV:es-SV,es_UY:es-UY,es_419:es-419
 
 [nextcloud.ios-swiftwebvc]
 file_filter = Supporting Files/<lang>.lproj/SwiftWebVC.strings
 source_file = Supporting Files/en.lproj/SwiftWebVC.strings
 source_lang = en
 type = STRINGS
-lang_map = pt_BR:pt-BR,zh_CN:zh-Hans,fi_FI:fi-FI,es_MX:es-MX,nb_NO:nb-NO,cs_CZ:cs-CZ,en_GB:en-GB,es_AR:es-AR,sk_SK:sk-SK,hu_HU:hu,ka_GE:ka-GE,zh_TW:zh-Hant-TW,es_CL:es-CL,es_CO:es-CO,es_CR:es-CR,es_DO:es-DO,es_EC:es-EC,es_GT:es-GT,es_HN:es-HN,es_NI:es-NI,es_PA:es-PA,es_PE:es-PE,es_PR:es-PR,es_PY:es-PY,es_SV:es-SV,es_UY:es-UY
+lang_map = pt_BR:pt-BR,zh_CN:zh-Hans,fi_FI:fi-FI,es_MX:es-MX,nb_NO:nb-NO,cs_CZ:cs-CZ,en_GB:en-GB,es_AR:es-AR,sk_SK:sk-SK,hu_HU:hu,ka_GE:ka-GE,zh_TW:zh-Hant-TW,es_CL:es-CL,es_CO:es-CO,es_CR:es-CR,es_DO:es-DO,es_EC:es-EC,es_GT:es-GT,es_HN:es-HN,es_NI:es-NI,es_PA:es-PA,es_PE:es-PE,es_PR:es-PR,es_PY:es-PY,es_SV:es-SV,es_UY:es-UY,es_419:es-419

+ 78 - 19
iOSClient/Actions/CCActions.swift

@@ -80,7 +80,9 @@ class CCActions: NSObject {
     // MARK: Delete File or Folder
     // --------------------------------------------------------------------------------------------
 
-    @objc func deleteFileOrFolder(_ metadata: tableMetadata, delegate: AnyObject) {
+    @objc func deleteFileOrFolder(_ metadata: tableMetadata,delegate: AnyObject, hud: CCHud?, hudTitled: String?) {
+        
+        var token: NSString?
         
         guard let serverUrl = NCManageDatabase.sharedInstance.getServerUrl(metadata.directoryID) else {
             return
@@ -90,26 +92,46 @@ class CCActions: NSObject {
 
         // fix CCActions.swift line 88 2.17.2 (00005)
         if (serverUrl == "") {
-            
-            print("[LOG] Server URL not found \(metadata.directoryID)")
-            
             appDelegate.messageNotification("_delete_", description: "_file_not_found_reload_", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: 0)
-            
             return
         }
         
-        metadataNet.action = actionDeleteFileDirectory
-        metadataNet.delegate = delegate
-        metadataNet.directory = metadata.directory
-        metadataNet.directoryID = metadata.directoryID
-        metadataNet.e2eEncrypted = metadata.e2eEncrypted
-        metadataNet.fileID = metadata.fileID
-        metadataNet.fileName = metadata.fileName
-        metadataNet.fileNameView = metadata.fileNameView
-        metadataNet.selector = selectorDelete
-        metadataNet.serverUrl = serverUrl
-
-        appDelegate.addNetworkingOperationQueue(appDelegate.netQueue, delegate: self, metadataNet: metadataNet)
+        guard let tableDirectory = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account = %@ AND serverUrl = %@", self.appDelegate.activeAccount, serverUrl)) else {
+            return
+        }
+        
+        DispatchQueue.global().async {
+        
+            // E2EE LOCK
+            let tableE2eEncryption = NCManageDatabase.sharedInstance.getE2eEncryption(predicate: NSPredicate(format: "account = %@ AND fileNameIdentifier = %@", self.appDelegate.activeAccount, metadata.fileName))
+            if tableE2eEncryption != nil {
+                let error = NCNetworkingSync.sharedManager().lockEnd(toEndFolderEncrypted: self.appDelegate.activeUser, userID: self.appDelegate.activeUserID, password: self.appDelegate.activePassword, url: self.appDelegate.activeUrl, fileID: tableDirectory.fileID, token: &token)
+                if error != nil {
+                    DispatchQueue.main.async {
+                        self.appDelegate.messageNotification("_delete_", description: error!.localizedDescription, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: 0)
+                    }
+                    return;
+                }
+            }
+        
+            metadataNet.action = actionDeleteFileDirectory
+            metadataNet.delegate = delegate
+            metadataNet.directory = metadata.directory
+            metadataNet.directoryID = metadata.directoryID
+            metadataNet.fileID = metadata.fileID
+            metadataNet.fileName = metadata.fileName
+            metadataNet.fileNameView = metadata.fileNameView
+            metadataNet.selector = selectorDelete
+            metadataNet.serverUrl = serverUrl
+        
+            self.appDelegate.addNetworkingOperationQueue(self.appDelegate.netQueue, delegate: self, metadataNet: metadataNet)
+            
+            if hud != nil  {
+                DispatchQueue.main.async {
+                    hud?.visibleHudTitle(hudTitled, mode: MBProgressHUDMode.indeterminate, color: nil)
+                }
+            }
+        }
     }
     
     @objc func deleteFileOrFolderSuccess(_ metadataNet: CCMetadataNet) {
@@ -120,7 +142,44 @@ class CCActions: NSObject {
             self.deleteFile(metadata: metadata, serverUrl: metadataNet.serverUrl)
         }
         
-        metadataNet.delegate?.deleteFileOrFolderSuccess(metadataNet)
+        guard let tableDirectory = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account = %@ AND serverUrl = %@", self.appDelegate.activeAccount, metadataNet.serverUrl)) else {
+            self.deleteFileOrFolderFailure(metadataNet, message: "Internal error, tableDirectory not found", errorCode: 0)
+            return
+        }
+        
+        // E2EE Rebuild and send Metadata
+        if tableDirectory.e2eEncrypted {
+            
+            DispatchQueue.global().async {
+                
+                var token = tableDirectory.e2eTokenLock as NSString?
+                
+                // Send Metadata
+                let errorRebuild = NCNetworkingSync.sharedManager().rebuildAndSendEndToEndMetadata(onServerUrl: metadataNet.serverUrl, account: self.appDelegate.activeAccount, user: self.appDelegate.activeUser, userID: self.appDelegate.activeUserID, password: self.appDelegate.activePassword, url: self.appDelegate.activeUrl, token: &token) as NSError?
+                if (errorRebuild != nil) {
+                    DispatchQueue.main.async {
+                        self.deleteFileOrFolderFailure(metadataNet, message: errorRebuild!.localizedDescription as NSString, errorCode: errorRebuild!.code)
+                    }
+                }
+                
+                // Unlock
+                let errorUnlock = NCNetworkingSync.sharedManager().unlockEnd(toEndFolderEncrypted: self.appDelegate.activeUser, userID: self.appDelegate.activeUserID, password: self.appDelegate.activePassword, url: self.appDelegate.activeUrl, fileID: tableDirectory.fileID, token: token! as String) as NSError?
+                if (errorUnlock != nil && errorRebuild == nil) {
+                    DispatchQueue.main.async {
+                        self.deleteFileOrFolderFailure(metadataNet, message: errorUnlock!.localizedDescription as NSString, errorCode: errorUnlock!.code)
+                    }
+                }
+                
+                if (errorRebuild == nil && errorUnlock == nil) {
+                    DispatchQueue.main.async {
+                        metadataNet.delegate?.deleteFileOrFolderSuccess(metadataNet)
+                    }
+                }
+            }
+            
+        } else {
+            metadataNet.delegate?.deleteFileOrFolderSuccess(metadataNet)
+        }
     }
     
     @objc func deleteFileOrFolderFailure(_ metadataNet: CCMetadataNet, message: NSString, errorCode: NSInteger) {
@@ -406,7 +465,7 @@ class CCActions: NSObject {
         
         NCManageDatabase.sharedInstance.deleteLocalFile(predicate: NSPredicate(format: "fileID == %@", metadata.fileID))
         NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "fileID == %@", metadata.fileID), clearDateReadDirectoryID: nil)
-        // E2E (if exists the record)
+        // E2EE (if exists the record)
         NCManageDatabase.sharedInstance.deleteE2eEncryption(predicate: NSPredicate(format: "account = %@ AND serverUrl = %@ AND fileNameIdentifier = %@", metadata.account, serverUrl, metadata.fileName))
     }
 }

+ 0 - 2
iOSClient/AppDelegate.h

@@ -40,7 +40,6 @@
 #import "CCFavorites.h"
 
 @class CCLoginWeb;
-@class NCEntoToEndInterface;
 
 @interface AppDelegate : UIResponder <UIApplicationDelegate, BKPasscodeLockScreenManagerDelegate, BKPasscodeViewControllerDelegate, TWMessageBarStyleSheet, CCNetworkingDelegate>
 
@@ -119,7 +118,6 @@
 @property (nonatomic, retain) CCTransfers *activeTransfers;
 @property (nonatomic, retain) CCLogin *activeLogin;
 @property (nonatomic, retain) CCLoginWeb *activeLoginWeb;
-@property (nonatomic, strong) NCEntoToEndInterface *endToEndInterface;
 
 @property (nonatomic, strong) NSMutableDictionary *listMainVC;
 @property (nonatomic, strong) NSMutableDictionary *listProgressMetadata;

+ 121 - 41
iOSClient/AppDelegate.m

@@ -208,8 +208,11 @@
             [self handleShortCutItem:shortcutItem];
     }
     
+    // Verify Lock
+    [self verifyLockOnLoadAutoUpload];
+    
     // Start Timer
-    self.timerProcessAutoDownloadUpload = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(processAutoDownloadUpload) userInfo:nil repeats:YES];
+    self.timerProcessAutoDownloadUpload = [NSTimer scheduledTimerWithTimeInterval:k_timerProcessAutoDownloadUpload target:self selector:@selector(processAutoDownloadUpload) userInfo:nil repeats:YES];
     self.timerUpdateApplicationIconBadgeNumber = [NSTimer scheduledTimerWithTimeInterval:k_timerUpdateApplicationIconBadgeNumber target:self selector:@selector(updateApplicationIconBadgeNumber) userInfo:nil repeats:YES];
 
     // Registration Push Notification
@@ -217,9 +220,6 @@
     UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
     [application registerUserNotificationSettings:notificationSettings];
     
-    // E2E Encryption
-    self.endToEndInterface = [NCEntoToEndInterface new];
-    
     // Fabric
     [Fabric with:@[[Crashlytics class]]];
     [self logUser];
@@ -257,6 +257,14 @@
     [self applicationInitialized];
 }
 
+//
+// L' applicazione entrerà in primo piano (attivo sempre)
+//
+- (void)applicationDidBecomeActive:(UIApplication *)application
+{
+   
+}
+
 //
 // L' applicazione è entrata nello sfondo
 //
@@ -311,15 +319,9 @@
     
     // Execute : after 1 sec.
     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
-    
-        // verify Download
-        [[CCNetworking sharedNetworking] verifyDownloadInProgress];
-        if (_activeMain)
-            [[CCNetworking sharedNetworking] verifyDownloadInError:self.activeMain];
         
         // verify Upload
-        [[CCNetworking sharedNetworking] verifyUploadInProgress];
-        [[CCNetworking sharedNetworking] verifyUploadInErrorOrWait];
+        [self verifyUploadInErrorOrWait];
 
         if (_activeMain) {
             NSLog(@"[LOG] Request Server Capabilities");
@@ -345,34 +347,65 @@
 
 - (void)openLoginView:(id)delegate loginType:(enumLoginType)loginType
 {
+    BOOL loginWeb = NO;
+    
     @synchronized (self) {
 
-        if ([NCBrandOptions sharedInstance].use_login_web) {
+        // only for personalized LoginWeb [customer]
+        if ([NCBrandOptions sharedInstance].use_login_web_personalized) {
+            
+            if (_activeLoginWeb == nil) {
+                
+                _activeLoginWeb = [CCLoginWeb new];
+                _activeLoginWeb.delegate = delegate;
+                _activeLoginWeb.loginType = loginType;
+                _activeLoginWeb.urlBase = [[NCBrandOptions sharedInstance] loginBaseUrl];
+                
+                dispatch_async(dispatch_get_main_queue(), ^ {
+                    [_activeLoginWeb presentModalWithDefaultTheme:delegate];
+                });
+            }
+            return;
+        }
         
-            if (!_activeLoginWeb.view.window) {
+        // ------------------- Nextcloud -------------------------
+        //
         
+        // Login flow : LoginWeb
+        if (loginType == loginModifyPasswordUser) {
+            tableAccount *account = [[NCManageDatabase sharedInstance] getAccountActive];
+            if (account.loginFlow)
+                loginWeb = YES;
+        }
+            
+        if (loginWeb) {
+            
+            if (_activeLoginWeb == nil) {
+                
                 _activeLoginWeb = [CCLoginWeb new];
                 _activeLoginWeb.delegate = delegate;
                 _activeLoginWeb.loginType = loginType;
-        
+                _activeLoginWeb.urlBase = self.activeUrl;
+
                 dispatch_async(dispatch_get_main_queue(), ^ {
                     [_activeLoginWeb presentModalWithDefaultTheme:delegate];
                 });
             }
-        
+            
         } else {
-        
+            
             if (_activeLogin == nil) {
-
+                
                 _activeLogin = [[UIStoryboard storyboardWithName:@"CCLogin" bundle:nil] instantiateViewControllerWithIdentifier:@"CCLoginNextcloud"];
                 _activeLogin.delegate = delegate;
                 _activeLogin.loginType = loginType;
-        
+                
                 dispatch_async(dispatch_get_main_queue(), ^ {
                     [delegate presentViewController:_activeLogin animated:YES completion:nil];
                 });
             }
         }
+        
     }
 }
 
@@ -801,11 +834,21 @@
     if (self.maintenanceMode)
         return;
     
+    NSInteger total = 0;
+    
     NSInteger queueDownload = [[[NCManageDatabase sharedInstance] getTableMetadataDownload] count] + [[[NCManageDatabase sharedInstance] getTableMetadataDownloadWWan] count];
-    NSInteger queueUpload = [[[NCManageDatabase sharedInstance] getTableMetadataUpload] count] + [[[NCManageDatabase sharedInstance] getTableMetadataUploadWWan] count];
+    
+    for (tableMetadata *record in [[NCManageDatabase sharedInstance] getTableMetadataUpload]) {
+        if (record.e2eEncrypted == false)
+            total++;
+    }
+    for (tableMetadata *record in [[NCManageDatabase sharedInstance] getTableMetadataUploadWWan]) {
+        if (record.e2eEncrypted == false)
+            total++;
+    }
     
     // Total
-    NSInteger total = queueDownload + queueUpload + [[NCManageDatabase sharedInstance] countQueueDownloadWithSession:nil] + [[NCManageDatabase sharedInstance] countQueueUploadWithSession:nil];
+    total = total + queueDownload + [[NCManageDatabase sharedInstance] countQueueDownloadWithSession:nil] + [[NCManageDatabase sharedInstance] countQueueUploadWithSession:nil];
     
     [UIApplication sharedApplication].applicationIconBadgeNumber = total;
     
@@ -1215,6 +1258,9 @@
 {
     NSLog(@"[LOG] Start perform Fetch With Completion Handler");
     
+    // verify Upload
+    [self verifyUploadInErrorOrWait];
+    
     // Verify new photo
     [[NCAutoUpload sharedInstance] initStateAutoUpload];
     
@@ -1377,16 +1423,16 @@
         return;
     
     // BACKGROND & FOREGROUND
-    NSLog(@"[LOG] -PROCESS-AUTO-UPLOAD-");
-    
     if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground) {
         
         // ONLY BACKGROUND
+        NSLog(@"[LOG] -PROCESS-AUTO-UPLOAD-");
         [self performSelectorOnMainThread:@selector(loadAutoDownloadUpload:) withObject:[NSNumber numberWithInt:k_maxConcurrentOperationDownloadUploadBackground] waitUntilDone:NO];
         
     } else {
         
         // ONLY FOREFROUND
+        NSLog(@"[LOG] -PROCESS-AUTO-UPLOAD-");
         [self performSelectorOnMainThread:@selector(loadAutoDownloadUpload:) withObject:[NSNumber numberWithInt:k_maxConcurrentOperationDownloadUpload] waitUntilDone:NO];
     }
 }
@@ -1395,6 +1441,16 @@
 {
     CCMetadataNet *metadataNet;
     
+    // E2EE : not in background
+    if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground) {
+        metadataNet = [[NCManageDatabase sharedInstance] getQueueUploadLock];
+        if (metadataNet) {
+            tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@ AND e2eEncrypted = 1", self.activeAccount, metadataNet.serverUrl]];
+            if (directory != nil)
+                return;
+        }
+    }
+    
     // Stop Timer
     [_timerProcessAutoDownloadUpload invalidate];
     
@@ -1438,15 +1494,17 @@
     
     // ------------------------- <selector Auto Upload All> ----------------------
     
-    // Verify num error MAX 10 after STOP
+    // Verify num error k_maxErrorAutoUploadAll after STOP (100)
     NSArray *metadatas = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND sessionSelector = %@ AND sessionTaskIdentifier = %i", _activeAccount, selectorUploadAutoUploadAll, k_taskIdentifierError] sorted:nil ascending:NO];
     
     NSInteger errorCount = [metadatas count];
     
-    if (errorCount >= 10) {
+    if (errorCount >= k_maxErrorAutoUploadAll) {
         
         [self messageNotification:@"_error_" description:@"_too_errors_automatic_all_" visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:0];
         
+        [[NCManageDatabase sharedInstance] addActivityClient:@"" fileID:@"" action:k_activityDebugActionAutoUpload selector:selectorUploadAutoUploadAll note:@"_too_errors_automatic_all_" type:k_activityTypeFailure verbose:k_activityVerboseDefault activeUrl:_activeUrl];
+
     } else {
         
         if (counterUploadInSessionAndInLock < maxConcurrentDownloadUpload && counterUploadInLock < 1) {
@@ -1478,29 +1536,51 @@
         counterUploadInSessionAndInLock = [[[NCManageDatabase sharedInstance] getTableMetadataUpload] count] + [[[NCManageDatabase sharedInstance] getTableMetadataUploadWWan] count] + [[[NCManageDatabase sharedInstance] getLockQueueUpload] count];
     }
     
-    // Verify Lock
+    // Start Timer
+    _timerProcessAutoDownloadUpload = [NSTimer scheduledTimerWithTimeInterval:k_timerProcessAutoDownloadUpload target:self selector:@selector(processAutoDownloadUpload) userInfo:nil repeats:YES];
+}
+
+#pragma --------------------------------------------------------------------------------------------
+#pragma mark ===== Process Verify =====
+#pragma --------------------------------------------------------------------------------------------
+
+- (void)verifyLockOnLoadAutoUpload
+{
+    // Test Maintenance
+    if (self.maintenanceMode || self.activeAccount.length == 0)
+        return;
+    
     NSInteger counterUploadInSession = [[[NCManageDatabase sharedInstance] getTableMetadataUpload] count] + [[[NCManageDatabase sharedInstance] getTableMetadataUploadWWan] count];
     NSArray *tableMetadatasInLock = [[NCManageDatabase sharedInstance] getLockQueueUpload];
+     
+     if (counterUploadInSession == 0 && [tableMetadatasInLock count] > 0) {
+     
+         // Unlock
+         for (tableMetadata *metadata in tableMetadatasInLock) {
+     
+             if ([[NCManageDatabase sharedInstance] isTableInvalidated:metadata] == NO)
+                 [[NCManageDatabase sharedInstance] unlockQueueUploadWithAssetLocalIdentifier:metadata.assetLocalIdentifier];
+         }
+     }
+}
+
+- (void)verifyUploadInErrorOrWait
+{
+    NSMutableSet *directoryIDs = [NSMutableSet new];
     
-    if (counterNewUpload == 0 && counterUploadInSession == 0 && [tableMetadatasInLock count] > 0) {
-        
-        // Unlock
-        for (tableMetadata *metadata in tableMetadatasInLock) {
-            
-            if ([[NCManageDatabase sharedInstance] isTableInvalidated:metadata] == NO)
-                [[NCManageDatabase sharedInstance] unlockQueueUploadWithAssetLocalIdentifier:metadata.assetLocalIdentifier];
-        }
-    }
+    NSArray *metadatas = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND session CONTAINS 'upload' AND (sessionTaskIdentifier = %i OR sessionTaskIdentifier = %i)", _activeAccount, k_taskIdentifierError, k_taskIdentifierWaitStart] sorted:nil ascending:NO];
     
-    // In background verify Upload in error
-    if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground) {
-        [[CCNetworking sharedNetworking] verifyUploadInErrorOrWait];
-    }
+    NSLog(@"[LOG] Verify re upload in error n. %lu", (unsigned long)[metadatas count]);
     
-    // Start Timer
-    _timerProcessAutoDownloadUpload = [NSTimer scheduledTimerWithTimeInterval:k_timerProcessAutoDownloadUpload target:self selector:@selector(processAutoDownloadUpload) userInfo:nil repeats:YES];
+    for (tableMetadata *metadata in metadatas) {
+        
+        [[CCNetworking sharedNetworking] uploadFileMetadata:metadata taskStatus: k_taskStatusResume];
+        
+        [directoryIDs addObject:metadata.directoryID];
+        
+        NSLog(@"[LOG] Re upload file : %@", metadata.fileName);
+    }
 }
-
 #pragma --------------------------------------------------------------------------------------------
 #pragma mark ===== Open CCUploadFromOtherUpp  =====
 #pragma --------------------------------------------------------------------------------------------

+ 6 - 4
iOSClient/AutoUpload/NCAutoUpload.m

@@ -449,17 +449,17 @@
         
         if ([[NCManageDatabase sharedInstance] addQueueUploadWithMetadataNet:metadataNet]) {
         
-            [[NCManageDatabase sharedInstance] addActivityClient:metadataNet.fileName fileID:metadataNet.assetLocalIdentifier action:k_activityDebugActionAutoUpload selector:metadataNet.selector note:@"Add Auto Upload, add new asset" type:k_activityTypeInfo verbose:k_activityVerboseHigh activeUrl:appDelegate.activeUrl];
+            [[NCManageDatabase sharedInstance] addActivityClient:metadataNet.fileNameView fileID:metadataNet.assetLocalIdentifier action:k_activityDebugActionAutoUpload selector:metadataNet.selector note:@"Add Auto Upload, add new asset" type:k_activityTypeInfo verbose:k_activityVerboseHigh activeUrl:appDelegate.activeUrl];
         
         } else {
     
-            [[NCManageDatabase sharedInstance] addActivityClient:metadataNet.fileName fileID:metadataNet.assetLocalIdentifier action:k_activityDebugActionAutoUpload selector:metadataNet.selector note:@"Add Auto Upload, asset already present or db in write transaction" type:k_activityTypeInfo verbose:k_activityVerboseHigh activeUrl:appDelegate.activeUrl];
+            [[NCManageDatabase sharedInstance] addActivityClient:metadataNet.fileNameView fileID:metadataNet.assetLocalIdentifier action:k_activityDebugActionAutoUpload selector:metadataNet.selector note:@"Add Auto Upload, asset already present or db in write transaction" type:k_activityTypeInfo verbose:k_activityVerboseHigh activeUrl:appDelegate.activeUrl];
         }
     
         // Add asset in table Photo Library
         if ([metadataNet.selector isEqualToString:selectorUploadAutoUpload]) {
             if (![[NCManageDatabase sharedInstance] addPhotoLibrary:@[asset]]) {
-                [[NCManageDatabase sharedInstance] addActivityClient:metadataNet.fileName fileID:metadataNet.assetLocalIdentifier action:k_activityDebugActionAutoUpload selector:metadataNet.selector note:@"Add Photo Library, db in write transaction" type:k_activityTypeInfo verbose:k_activityVerboseHigh activeUrl:appDelegate.activeUrl];
+                [[NCManageDatabase sharedInstance] addActivityClient:metadataNet.fileNameView fileID:metadataNet.assetLocalIdentifier action:k_activityDebugActionAutoUpload selector:metadataNet.selector note:@"Add Photo Library, db in write transaction" type:k_activityTypeInfo verbose:k_activityVerboseHigh activeUrl:appDelegate.activeUrl];
             }
         }
         
@@ -482,7 +482,9 @@
     
     if (error == nil) {
         
-        (void)[[NCManageDatabase sharedInstance] addDirectoryWithServerUrl:folderPhotos permissions:nil encrypted:false];
+        tableDirectory *tableDirectory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", appDelegate.activeAccount, folderPhotos]];
+        if (!tableDirectory)
+            (void)[[NCManageDatabase sharedInstance] addDirectoryWithServerUrl:folderPhotos permissions:nil encrypted:false];
         
     } else {
         

+ 0 - 2
iOSClient/Brand/Intro/ImagesIntro.xcassets/IntroNoCryptoCloud.imageset/Contents.json

@@ -2,7 +2,6 @@
   "images" : [
     {
       "idiom" : "universal",
-      "filename" : "IntroNoCryptoCloud.png",
       "scale" : "1x"
     },
     {
@@ -12,7 +11,6 @@
     },
     {
       "idiom" : "universal",
-      "filename" : "IntroNoCryptoCloud@3x.png",
       "scale" : "3x"
     }
   ],

二进制
iOSClient/Brand/Intro/ImagesIntro.xcassets/IntroNoCryptoCloud.imageset/IntroNoCryptoCloud.png


二进制
iOSClient/Brand/Intro/ImagesIntro.xcassets/IntroNoCryptoCloud.imageset/IntroNoCryptoCloud@3x.png


+ 0 - 2
iOSClient/Brand/Intro/ImagesIntro.xcassets/intro1.imageset/Contents.json

@@ -2,7 +2,6 @@
   "images" : [
     {
       "idiom" : "universal",
-      "filename" : "intro1.png",
       "scale" : "1x"
     },
     {
@@ -12,7 +11,6 @@
     },
     {
       "idiom" : "universal",
-      "filename" : "intro1@3x.png",
       "scale" : "3x"
     }
   ],

二进制
iOSClient/Brand/Intro/ImagesIntro.xcassets/intro1.imageset/intro1.png


二进制
iOSClient/Brand/Intro/ImagesIntro.xcassets/intro1.imageset/intro1@3x.png


二进制
iOSClient/Brand/Intro/ImagesIntro.xcassets/intro11.imageset/intro11@2x.png


二进制
iOSClient/Brand/Intro/ImagesIntro.xcassets/intro2.imageset/intro2@2x.png


+ 0 - 2
iOSClient/Brand/Intro/ImagesIntro.xcassets/intro3.imageset/Contents.json

@@ -2,7 +2,6 @@
   "images" : [
     {
       "idiom" : "universal",
-      "filename" : "intro4.png",
       "scale" : "1x"
     },
     {
@@ -12,7 +11,6 @@
     },
     {
       "idiom" : "universal",
-      "filename" : "intro4@3x.png",
       "scale" : "3x"
     }
   ],

二进制
iOSClient/Brand/Intro/ImagesIntro.xcassets/intro3.imageset/intro4.png


二进制
iOSClient/Brand/Intro/ImagesIntro.xcassets/intro3.imageset/intro4@2x.png


二进制
iOSClient/Brand/Intro/ImagesIntro.xcassets/intro3.imageset/intro4@3x.png


+ 5 - 6
iOSClient/Brand/NCBrand.swift

@@ -75,10 +75,10 @@ class NCBrandColor: NSObject {
     @objc public let linkLoginProvider:               String = "https://nextcloud.com/providers"
     @objc public let textLoginProvider:               String = "_login_bottom_label_"
     @objc public let middlewarePingUrl:               String = ""
-    @objc public let webLoginAutenticationProtocol:   String = ""                                               // example "abc://"
-    @objc public let webCloseViewProtocol:            String = ""                                               // example "abc://change/plan"
-    @objc public let folderBrandAutoUpload:           String = ""                                               // example "_auto_upload_folder_"
-    @objc public let ncFlowEndpoint:                  String = "/index.php/login/flow"
+    @objc public let webLoginAutenticationProtocol:   String = "nc://"                                          // example "abc://"
+    // Personalized
+    @objc public let webCloseViewProtocolPersonalized:String = ""                                               // example "abc://change/plan"      Don't touch me !!
+    @objc public let folderBrandAutoUpload:           String = ""                                               // example "_auto_upload_folder_"   Don't touch me !!
 
     // Auto Upload default folder
     @objc public var folderDefaultAutoUpload:         String = "Photos"
@@ -87,8 +87,7 @@ class NCBrandColor: NSObject {
     @objc public let capabilitiesGroups:              String = "group.it.twsweb.Crypto-Cloud"
     
     // Options
-    @objc public let use_login_web:                   Bool = false
-    @objc public let use_login_web_flow:              Bool = false
+    @objc public let use_login_web_personalized:      Bool = false                                              // Don't touch me !!
     @objc public let use_firebase:                    Bool = false
     @objc public let use_default_auto_upload:         Bool = false
     @objc public let use_themingColor:                Bool = true

+ 9 - 8
iOSClient/CCGlobal.h

@@ -30,6 +30,8 @@ extern NSString *const appCertificates;
 extern NSString *const webDAV;
 extern NSString *const dav;
 
+extern NSString *const flowEndpoint;
+
 #ifndef EXTENSION
 
 //AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
@@ -38,6 +40,9 @@ extern NSString *const dav;
 //dispatch_async(dispatch_get_main_queue(), ^{
 //dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void) {
 
+//DispatchQueue.main.async
+//DispatchQueue.global().async
+
 #define CALL_ORIGIN NSLog(@"Origin: [%@]", [[[[NSThread callStackSymbols] objectAtIndex:1] componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"[]"]] objectAtIndex:1])
 
 #endif
@@ -52,6 +57,8 @@ extern NSString *const dav;
 
 #define k_daysOfActivity                                7
 
+#define k_maxErrorAutoUploadAll                         100
+
 #define k_returnCreateFolderPlain                       0
 #define k_returnCreateFotoVideoPlain                    1
 #define k_returnCreateFilePlain                         2
@@ -93,8 +100,8 @@ extern NSString *const dav;
 #define k_download_session_foreground                   @"it.twsweb.Crypto-Cloud.download.sessionforeground"
 #define k_download_session_wwan                         @"it.twsweb.Crypto-Cloud.download.sessionwwan"
 #define k_upload_session                                @"it.twsweb.Crypto-Cloud.upload.session"
-#define k_upload_session_foreground                     @"it.twsweb.Crypto-Cloud.upload.sessionforeground"
 #define k_upload_session_wwan                           @"it.twsweb.Crypto-Cloud.upload.sessionwwan"
+#define k_upload_session_foreground                     @"it.twsweb.Crypto-Cloud.upload.sessionforeground"
 
 // OperationQueue
 #define k_queue                                         @"it.twsweb.Crypto-Cloud.queue"
@@ -115,7 +122,6 @@ extern NSString *const dav;
 #define k_taskIdentifierNULL                            99999
 
 // TaskStatus
-#define k_taskStatusNone                                0
 #define k_taskStatusCancel                              -1
 #define k_taskStatusResume                              -2
 #define k_taskStatusSuspend                             -3
@@ -131,7 +137,6 @@ extern NSString *const dav;
 // Error
 #define k_CCErrorTaskNil                                -9999
 #define k_CCErrorTaskDownloadNotFound                   -9998
-#define k_CCErrorFileUploadNotFound                     -9997
 #define k_CCErrorInternalError                          -9996
 #define k_CCErrorNetworkNowAvailable                    -9995
 #define k_CCErrorFileAlreadyInDownload                  -9994
@@ -157,7 +162,6 @@ extern NSString *const dav;
 #define selectorOpenIn                                  @"openIn"
 #define selectorOpenWindowShare                         @"openWindowShare"
 #define selectorReadFile                                @"readFile"
-#define selectorReadFileVerifyUpload                    @"readFileVerifyUpload"
 #define selectorReadFileWithDownload                    @"readFileWithDownload"
 #define selectorReadFileReloadFolder                    @"readFileReloadFolder"
 #define selectorReadFileFolder                          @"readFileFolder"
@@ -210,9 +214,6 @@ extern NSString *const dav;
 #define actionDeleteEndToEndPublicKey                   @"deleteEndToEndPublicKey"
 #define actionDeleteEndToEndPrivateKey                  @"deleteEndToEndPrivateKey"
 #define actionGetEndToEndServerPublicKey                @"getEndToEndServerPublicKey"
-#define actionGetEndToEndMetadata                       @"getEndToEndMetadata"
-#define actionDeleteEndToEndMetadata                    @"deleteEndToEndMetadata"
-#define actionUnlockEndToEndFolderEncrypted             @"unlockEndToEndFolderEncrypted"
 
 // Metadata : FileType
 #define k_metadataTypeFile_audio                        @"audio"
@@ -261,7 +262,7 @@ extern NSString *const dav;
 #define k_activityDebugActionCapabilities               @"Capabilities Of Server"
 #define k_activityDebugActionEndToEndEncryption         @"End To End Encryption "
 
-// E2E
+// E2EE
 #define k_max_filesize_E2E                              524288000   // 500 MB
 
 // -----------------------------------------------------------------------------------------------------------

+ 4 - 0
iOSClient/CCGlobal.m

@@ -31,3 +31,7 @@ NSString *const appCertificates = @"Library/Application Support/Certificates";
 // webDAV & DAV
 NSString *const webDAV = @"/remote.php/webdav";
 NSString *const dav = @"/remote.php/dav";
+
+// Login Flow
+NSString *const flowEndpoint = @"/index.php/login/flow";
+

+ 30 - 2
iOSClient/Create/CCCreateCloud.swift

@@ -439,7 +439,7 @@ class CreateFormUploadAssets: XLFormViewController, CCMoveDelegate {
         viewController.tintColorTitle = NCBrandColor.sharedInstance.brandText
         viewController.move.title = NSLocalizedString("_select_", comment: "");
         viewController.networkingOperationQueue =  appDelegate.netQueue
-        // E2E
+        // E2EE
         viewController.includeDirectoryE2EEncryption = true;
         
         navigationController.modalPresentationStyle = UIModalPresentationStyle.formSheet
@@ -599,6 +599,34 @@ class CreateFormUploadFile: XLFormViewController, CCMoveDelegate {
                 fileNameSave = (name as! NSString).deletingPathExtension + ".txt"
         }
         
+        guard let directoryID = NCManageDatabase.sharedInstance.getDirectoryID(self.serverUrl) else {
+            return
+        }
+        let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "account = %@ AND directoryID = %@ AND fileNameView = %@", appDelegate.activeAccount, directoryID, fileNameSave))
+        
+        if (metadata != nil) {
+            
+            let alertController = UIAlertController(title: fileNameSave, message: NSLocalizedString("_file_already_exists_", comment: ""), preferredStyle: .alert)
+            
+            let cancelAction = UIAlertAction(title: NSLocalizedString("_cancel_", comment: ""), style: .default) { (action:UIAlertAction) in
+            }
+            
+            let overwriteAction = UIAlertAction(title: NSLocalizedString("_overwrite_", comment: ""), style: .cancel) { (action:UIAlertAction) in
+                self.dismissAndUpload(fileNameSave)
+            }
+            
+            alertController.addAction(cancelAction)
+            alertController.addAction(overwriteAction)
+            
+            self.present(alertController, animated: true, completion:nil)
+        } else {
+            
+           dismissAndUpload(fileNameSave)
+        }
+    }
+    
+    func dismissAndUpload(_ fileNameSave: String) {
+        
         self.dismiss(animated: true, completion: {
             
             let data = self.text.data(using: .utf8)
@@ -631,7 +659,7 @@ class CreateFormUploadFile: XLFormViewController, CCMoveDelegate {
         viewController.tintColorTitle = NCBrandColor.sharedInstance.brandText
         viewController.move.title = NSLocalizedString("_select_", comment: "");
         viewController.networkingOperationQueue =  appDelegate.netQueue
-        // E2E
+        // E2EE
         viewController.includeDirectoryE2EEncryption = true;
         
         navigationController.modalPresentationStyle = UIModalPresentationStyle.formSheet

+ 1 - 0
iOSClient/Database/NCDatabase.swift

@@ -41,6 +41,7 @@ class tableAccount: Object {
     @objc dynamic var displayName = ""
     @objc dynamic var email = ""
     @objc dynamic var enabled: Bool = false
+    @objc dynamic var loginFlow: Bool = false
     @objc dynamic var optimization = NSDate()
     @objc dynamic var password = ""
     @objc dynamic var phone = ""

+ 42 - 10
iOSClient/Database/NCManageDatabase.swift

@@ -57,13 +57,14 @@ class NCManageDatabase: NSObject {
         let config = Realm.Configuration(
         
             fileURL: dirGroup?.appendingPathComponent("\(appDatabaseNextcloud)/\(k_databaseDefault)"),
-            schemaVersion: 14,
+            schemaVersion: 15,
             
             // 10 : Version 2.18.0
             // 11 : Version 2.18.2
             // 12 : Version 2.19.0.5
             // 13 : Version 2.19.0.14
-            // 14 : ...
+            // 14 : Version 2.19.0.xx
+            // 15 : Version 2.19.2
             
             migrationBlock: { migration, oldSchemaVersion in
                 // We haven’t migrated anything yet, so oldSchemaVersion == 0
@@ -143,7 +144,7 @@ class NCManageDatabase: NSObject {
     //MARK: -
     //MARK: Table Account
     
-    @objc func addAccount(_ account: String, url: String, user: String, password: String) {
+    @objc func addAccount(_ account: String, url: String, user: String, password: String, loginFlow: Bool) {
 
         let realm = try! Realm()
         
@@ -152,6 +153,7 @@ class NCManageDatabase: NSObject {
         let addObject = tableAccount()
             
         addObject.account = account
+        addObject.loginFlow = loginFlow
             
         // Brand
         if NCBrandOptions.sharedInstance.use_default_auto_upload {
@@ -1121,10 +1123,10 @@ class NCManageDatabase: NSObject {
         }
     }
     
-    @objc func renameFileE2eEncryption(serverUrl: String, fileNameIdentifier: String, newFileName: String, newFileNamePath: String) -> Bool {
+    @objc func renameFileE2eEncryption(serverUrl: String, fileNameIdentifier: String, newFileName: String, newFileNamePath: String) {
         
         guard let tableAccount = self.getAccountActive() else {
-            return false
+            return
         }
         
         let realm = try! Realm()
@@ -1133,7 +1135,7 @@ class NCManageDatabase: NSObject {
 
         guard let result = realm.objects(tableE2eEncryption.self).filter("account = %@ AND serverUrl = %@ AND fileNameIdentifier = %@", tableAccount.account, serverUrl, fileNameIdentifier).first else {
             realm.cancelWrite()
-            return false
+            return 
         }
         
         let object = tableE2eEncryption.init(value: result)
@@ -1149,10 +1151,10 @@ class NCManageDatabase: NSObject {
             try realm.commitWrite()
         } catch let error {
             print("[LOG] Could not write to database: ", error)
-            return false
+            return
         }
         
-        return true
+        return
     }
     
     //MARK: -
@@ -1371,7 +1373,7 @@ class NCManageDatabase: NSObject {
     //MARK: Table Metadata
     
     @objc func addMetadata(_ metadata: tableMetadata) -> tableMetadata? {
-        
+            
         guard self.getAccountActive() != nil else {
             return nil
         }
@@ -1394,6 +1396,10 @@ class NCManageDatabase: NSObject {
         
         self.setDateReadDirectory(directoryID: directoryID)
         
+        if metadata.isInvalidated {
+            return nil
+        }
+        
         return tableMetadata.init(value: metadata)
     }
     
@@ -2074,7 +2080,7 @@ class NCManageDatabase: NSObject {
         
         realm.beginWrite()
         
-        guard let result = realm.objects(tableQueueUpload.self).filter("account = %@ AND selector = %@ AND lock == false", tableAccount.account, selector).first else {
+        guard let result = realm.objects(tableQueueUpload.self).filter("account = %@ AND selector = %@ AND lock == false", tableAccount.account, selector).sorted(byKeyPath: "date", ascending: true).first else {
             realm.cancelWrite()
             return nil
         }
@@ -2103,6 +2109,32 @@ class NCManageDatabase: NSObject {
         return metadataNet
     }
     
+    @objc func getQueueUploadLock() -> CCMetadataNet? {
+        
+        guard let tableAccount = self.getAccountActive() else {
+            return nil
+        }
+        
+        let realm = try! Realm()
+        
+        guard let result = realm.objects(tableQueueUpload.self).filter("account = %@ AND lock == false", tableAccount.account).sorted(byKeyPath: "date", ascending: true).first else {
+            return nil
+        }
+        
+        let metadataNet = CCMetadataNet()
+        
+        metadataNet.account = result.account
+        metadataNet.assetLocalIdentifier = result.assetLocalIdentifier
+        metadataNet.fileName = result.fileName
+        metadataNet.selector = result.selector
+        metadataNet.selectorPost = result.selectorPost
+        metadataNet.serverUrl = result.serverUrl
+        metadataNet.session = result.session
+        metadataNet.taskStatus = Int(k_taskStatusResume)
+        
+        return metadataNet
+    }
+    
     @objc func getLockQueueUpload() -> [tableQueueUpload]? {
         
         guard let tableAccount = self.getAccountActive() else {

+ 12 - 10
iOSClient/Favorites/CCFavorites.m

@@ -172,10 +172,6 @@
 
 - (void)deleteFileOrFolderSuccess:(CCMetadataNet *)metadataNet
 {
-    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
-        [[CCNetworking sharedNetworking] rebuildAndSendEndToEndMetadataOnServerUrl:metadataNet.serverUrl];
-    });
-    
     [self reloadDatasource];
 }
 
@@ -229,10 +225,8 @@
 
 - (void)listingFavoritesSuccess:(CCMetadataNet *)metadataNet metadatas:(NSArray *)metadatas
 {
-    // verify active user
-    tableAccount *record = [[NCManageDatabase sharedInstance] getAccountActive];
-    
-    if (![record.account isEqualToString:metadataNet.account])
+    // Check Active Account
+    if (![metadataNet.account isEqualToString:appDelegate.activeAccount])
         return;
     
     NSString *father = @"";
@@ -279,6 +273,10 @@
 
 - (void)listingFavoritesFailure:(CCMetadataNet *)metadataNet message:(NSString *)message errorCode:(NSInteger)errorCode
 {
+    // Check Active Account
+    if (![metadataNet.account isEqualToString:appDelegate.activeAccount])
+        return;
+    
     NSLog(@"[LOG] Listing Favorites failure error %d, %@", (int)errorCode, message);
 }
 
@@ -288,6 +286,10 @@
 
 - (void)downloadThumbnailSuccess:(CCMetadataNet *)metadataNet
 {
+    // Check Active Account
+    if (![metadataNet.account isEqualToString:appDelegate.activeAccount])
+        return;
+    
     [self reloadDatasource];
 }
 
@@ -347,7 +349,7 @@
         
     [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_delete_", nil) style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {
         
-        [[CCActions sharedInstance] deleteFileOrFolder:metadata delegate:self];
+        [[CCActions sharedInstance] deleteFileOrFolder:metadata delegate:self hud:nil hudTitled:nil];
         [self reloadDatasource];
     }]];
         
@@ -611,7 +613,7 @@
         }
         
         // ----------------------------------------------------------------------------------------------------------
-        // E2E Image Status Encrypted
+        // E2EE Image Status Encrypted
         // ----------------------------------------------------------------------------------------------------------
         
         tableE2eEncryption *tableE2eEncryption = [[NCManageDatabase sharedInstance] getE2eEncryptionWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND fileNameIdentifier = %@", appDelegate.activeAccount, metadata.fileName]];

二进制
iOSClient/Images.xcassets/swipeDelete.imageset/swipeDelete.png


二进制
iOSClient/Images.xcassets/swipeDelete.imageset/swipeDelete@2x.png


二进制
iOSClient/Images.xcassets/swipeDelete.imageset/swipeDelete@3x.png


+ 21 - 0
iOSClient/Images.xcassets/titleExternal.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "titleExternal@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}

二进制
iOSClient/Images.xcassets/titleExternal.imageset/titleExternal@2x.png


+ 21 - 0
iOSClient/Images.xcassets/titlePublic.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "titlePublic@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}

二进制
iOSClient/Images.xcassets/titlePublic.imageset/titlePublic@2x.png


+ 0 - 0
iOSClient/Images.xcassets/titleShare.imageset/Contents.json → iOSClient/Images.xcassets/titleShared_with_me.imageset/Contents.json


+ 0 - 0
iOSClient/Images.xcassets/titleShare.imageset/titleShare@2x.png → iOSClient/Images.xcassets/titleShared_with_me.imageset/titleShare@2x.png


+ 1 - 1
iOSClient/Library/MWPhotoBrowser/MWPhotoBrowser.h

@@ -37,7 +37,7 @@
 - (void)photoBrowser:(MWPhotoBrowser *)photoBrowser deleteButtonPressedForPhotoAtIndex:(NSUInteger)index deleteButton:(UIBarButtonItem *)deleteButton;
 - (BOOL)photoBrowser:(MWPhotoBrowser *)photoBrowser isPhotoSelectedAtIndex:(NSUInteger)index;
 - (void)photoBrowser:(MWPhotoBrowser *)photoBrowser photoAtIndex:(NSUInteger)index selectedChanged:(BOOL)selected;
-- (void)photoBrowserDidFinishModalPresentation:(MWPhotoBrowser *)photoBrowser;
+- (void)photoBrowserDidFinishPresentation:(MWPhotoBrowser *)photoBrowser;
 
 - (void)setControlsHidden:(BOOL)hidden animated:(BOOL)animated permanent:(BOOL)permanent;
 

+ 5 - 9
iOSClient/Library/MWPhotoBrowser/MWPhotoBrowser.m

@@ -1373,15 +1373,11 @@ static void * MWVideoPlayerObservation = &MWVideoPlayerObservation;
 #pragma mark - Misc
 
 - (void)doneButtonPressed:(id)sender {
-    // Only if we're modal and there's a done button
-    if (_doneButton) {    
-        // Dismiss view controller
-        if ([_delegate respondsToSelector:@selector(photoBrowserDidFinishModalPresentation:)]) {
-            // Call delegate method and let them dismiss us
-            [_delegate photoBrowserDidFinishModalPresentation:self];
-        } else  {
-            [self dismissViewControllerAnimated:YES completion:nil];
-        }
+   
+    // Dismiss view controller
+    if ([_delegate respondsToSelector:@selector(photoBrowserDidFinishPresentation:)]) {
+        // Call delegate method and let them dismiss us
+        [_delegate photoBrowserDidFinishPresentation:self];
     }
 }
 

+ 2 - 2
iOSClient/Library/OCCommunicationLib/OCWebDavClient/OCWebDAVClient.h

@@ -67,9 +67,9 @@ extern NSString * _Nullable OCWebDAVModificationDateKey;
 @property (nonatomic, strong) NSString * _Nullable originalUrlServer;
 
 @property (nonatomic, strong) NSString * _Nullable postStringForShare;
-// E2E Metadata 
+// E2EE Metadata
 @property (nonatomic, strong) NSString * _Nullable postStringMetadata;
-// E2E privateKey, publicKey
+// E2EE privateKey, publicKey
 @property (nonatomic, strong) NSString * _Nullable postStringKey;
 
 /**

+ 15 - 3
iOSClient/Library/SwiftWebVC/SwiftModalWebVC.swift

@@ -12,6 +12,7 @@ public protocol SwiftModalWebVCDelegate: class {
     func didStartLoading()
     func didReceiveServerRedirectForProvisionalNavigation(url: URL)
     func didFinishLoading(success: Bool, url: URL)
+    func loginWebClose()
 }
 
 public class SwiftModalWebVC: UINavigationController {
@@ -76,7 +77,8 @@ public class SwiftModalWebVC: UINavigationController {
             doneButton.tintColor = colorText
             webViewController.buttonColor = colorText
             webViewController.titleColor = colorText
-            
+            webViewController.view.backgroundColor = color
+
             self.navigationBar.isTranslucent = false
             UINavigationBar.appearance().barTintColor = color
             
@@ -93,8 +95,6 @@ public class SwiftModalWebVC: UINavigationController {
             }
         }
         webViewController.delegate = self
-        
-        
     }
     
     override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
@@ -108,6 +108,14 @@ public class SwiftModalWebVC: UINavigationController {
     override public func viewWillAppear(_ animated: Bool) {
         super.viewWillAppear(false)
     }
+    
+    public override func viewWillDisappear(_ animated: Bool) {
+        super.viewDidDisappear(animated)
+    }
+
+    public override func viewDidDisappear(_ animated: Bool) {
+        super.viewDidDisappear(animated)
+    }
 }
 
 extension SwiftModalWebVC: SwiftWebVCDelegate {
@@ -127,4 +135,8 @@ extension SwiftModalWebVC: SwiftWebVCDelegate {
     public func didFinishLoading(success: Bool, url: URL) {
         self.delegateWeb?.didFinishLoading(success: success, url: url)
     }
+    
+    public func loginWebClose() {
+        self.delegateWeb?.loginWebClose()
+    }
 }

+ 18 - 7
iOSClient/Library/SwiftWebVC/SwiftWebVC.swift

@@ -13,6 +13,7 @@ public protocol SwiftWebVCDelegate: class {
     func didReceiveServerRedirectForProvisionalNavigation(url: URL)
     func didFinishLoading(success: Bool)
     func didFinishLoading(success: Bool, url: URL)
+    func loginWebClose()
 }
 
 public class SwiftWebVC: UIViewController {
@@ -101,6 +102,9 @@ public class SwiftWebVC: UIViewController {
     public convenience init(aRequest: URLRequest, hideToolbar: Bool) {
         self.init()
         self.request = aRequest
+        self.request.addValue("true", forHTTPHeaderField: "OCS-APIRequest")
+        let language = NSLocale.preferredLanguages[0] as String
+        self.request.addValue(language, forHTTPHeaderField: "Accept-Language")
         self.hideToolbar = hideToolbar
     }
     
@@ -108,12 +112,8 @@ public class SwiftWebVC: UIViewController {
         
         let userAgent : String = CCUtility.getUserAgent()
         
-        if #available(iOS 9.0, *) {
-            webView.customUserAgent = userAgent
-        } else {
-            // Fallback on earlier versions
-            UserDefaults.standard.register(defaults: ["UserAgent": userAgent])
-        }
+        webView.customUserAgent = userAgent
+       
         webView.load(request)
     }
     
@@ -173,6 +173,13 @@ public class SwiftWebVC: UIViewController {
         UIApplication.shared.isNetworkActivityIndicatorVisible = false
     }
     
+    override public func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
+        super.dismiss(animated: flag, completion: {
+            self.delegate!.loginWebClose()
+        })        
+    }
+    
+    
     ////////////////////////////////////////////////
     // Toolbar
     
@@ -349,5 +356,9 @@ extension SwiftWebVC: WKNavigationDelegate {
         updateToolbarItems()
     }
     
-    
+    public func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
+        
+        completionHandler(Foundation.URLSession.AuthChallengeDisposition.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
+    }
+
 }

+ 1 - 0
iOSClient/Library/VFR Pdf Reader/Sources/ReaderViewController.h

@@ -37,6 +37,7 @@
 
 //TWS
 - (void)handleSingleTapReader;
+- (void)handleSwipeUpDown;
 
 @end
 

+ 11 - 0
iOSClient/Library/VFR Pdf Reader/Sources/ReaderViewController.m

@@ -378,6 +378,10 @@
 	UITapGestureRecognizer *doubleTapTwo = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)];
 	doubleTapTwo.numberOfTouchesRequired = 2; doubleTapTwo.numberOfTapsRequired = 2; doubleTapTwo.delegate = self;
 	[self.view addGestureRecognizer:doubleTapTwo];
+    
+    UISwipeGestureRecognizer *swipeUpDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeUpDown:)];
+    swipeUpDown.direction = UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionUp;
+    [self.view addGestureRecognizer:swipeUpDown];
 
 	[singleTapOne requireGestureRecognizerToFail:doubleTapOne]; // Single tap requires double tap to fail
 
@@ -697,6 +701,13 @@
 	}
 }
 
+- (void)handleSwipeUpDown:(UITapGestureRecognizer *)recognizer
+{
+    //TWS
+    if ([self.delegate respondsToSelector:@selector(handleSwipeUpDown)])
+        [self.delegate handleSwipeUpDown];
+}
+
 #pragma mark - ReaderContentViewDelegate methods
 
 - (void)contentView:(ReaderContentView *)contentView touchesBegan:(NSSet *)touches

+ 5 - 1
iOSClient/Login/CCLogin.h

@@ -27,10 +27,12 @@
 #import "CCCertificate.h"
 #import "OCNetworking.h"
 
+@class CCLoginWeb;
+
 @protocol CCLoginDelegate <NSObject>
 
 - (void) loginSuccess:(NSInteger)loginType;
-- (void) loginDisappear;
+- (void) loginClose;
 
 @end
 
@@ -61,6 +63,8 @@ typedef enum {
 @property (nonatomic, weak) IBOutlet UIButton *login;
 @property (nonatomic, weak) IBOutlet UIButton *annulla;
 @property (nonatomic, weak) IBOutlet UIButton *toggleVisiblePassword;
+@property (nonatomic, weak) IBOutlet UIButton *loginTypeView;
+
 
 @property enumLoginType loginType;
 

+ 223 - 89
iOSClient/Login/CCLogin.m

@@ -27,10 +27,9 @@
 #import "NCBridgeSwift.h"
 #import "NCNetworkingSync.h"
 
-@interface CCLogin ()
+@interface CCLogin () <CCLoginDelegateWeb>
 {
     AppDelegate *appDelegate;
-
     UIView *rootView;
 }
 @end
@@ -43,67 +42,105 @@
     
     appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
 
-    self.imageBrand.image = [UIImage imageNamed:@"loginLogo"];
-    self.login.backgroundColor = [NCBrandColor sharedInstance].customer;
+    // Background color
+    self.view.backgroundColor = [NCBrandColor sharedInstance].customer;
+    
+    // Image Brand
+    self.imageBrand.image = [CCGraphics changeThemingColorImage:[UIImage imageNamed:@"loginLogo"] color:[NCBrandColor sharedInstance].customerText];
+    
+    // Annulla
+    [self.annulla setTitle:NSLocalizedString(@"_cancel_", nil) forState:UIControlStateNormal];
+    self.annulla.tintColor = [NCBrandColor sharedInstance].customerText;
+    
+    // Base URL
+    _imageBaseUrl.image = [CCGraphics changeThemingColorImage:[UIImage imageNamed:@"loginURL"] color:[NCBrandColor sharedInstance].customerText];
+    _baseUrl.textColor = [NCBrandColor sharedInstance].customerText;
+    _baseUrl.tintColor = [NCBrandColor sharedInstance].customerText;
+    _baseUrl.placeholder = NSLocalizedString(@"_login_url_", nil);
+    [_baseUrl setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"];
+    [self.baseUrl setFont:[UIFont systemFontOfSize:13]];
+    [self.baseUrl setDelegate:self];
+
+    // Loading Base Utl GIF
+    self.loadingBaseUrl.image = [UIImage animatedImageWithAnimatedGIFURL:[[NSBundle mainBundle] URLForResource: @"loading@2x" withExtension:@"gif"]];
+    self.loadingBaseUrl.hidden = YES;
+    
+    // User
+    _imageUser.image = [CCGraphics changeThemingColorImage:[UIImage imageNamed:@"loginUser"] color:[NCBrandColor sharedInstance].customerText];
+    _user.textColor = [NCBrandColor sharedInstance].customerText;
+    _user.tintColor = [NCBrandColor sharedInstance].customerText;
+    _user.placeholder = NSLocalizedString(@"_username_", nil);
+    [_user setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"];
+    [self.user setFont:[UIFont systemFontOfSize:13]];
+    [self.user setDelegate:self];
+
+    // Password
+    _imagePassword.image = [CCGraphics changeThemingColorImage:[UIImage imageNamed:@"loginPassword"] color:[NCBrandColor sharedInstance].customerText];
+    _password.textColor = [NCBrandColor sharedInstance].customerText;
+    _password.tintColor = [NCBrandColor sharedInstance].customerText;
+    _password.placeholder = NSLocalizedString(@"_password_", nil);
+    [_password setValue:[UIColor lightGrayColor] forKeyPath:@"_placeholderLabel.textColor"];
+    [self.password setFont:[UIFont systemFontOfSize:13]];
+    [self.password setDelegate:self];
+
+    // Login
+    [self.login setTitle:NSLocalizedString(@"_login_", nil) forState:UIControlStateNormal];
+    self.login.backgroundColor = [NCBrandColor sharedInstance].customerText;
+    self.login.tintColor = [NCBrandColor sharedInstance].customer;
     
+    // Type view
+    [self.loginTypeView setTitle:NSLocalizedString(@"_traditional_login_", nil) forState:UIControlStateNormal];
+    [self.loginTypeView setTitleColor:[NCBrandColor sharedInstance].customerText forState:UIControlStateNormal];
+
     // Bottom label
     self.bottomLabel.text = NSLocalizedString([NCBrandOptions sharedInstance].textLoginProvider, nil);
     self.bottomLabel.userInteractionEnabled = YES;
-    
     if ([NCBrandOptions sharedInstance].disable_linkLoginProvider) {
         self.bottomLabel.hidden = YES;
-    } else {
+    }
     
-        if (self.view.frame.size.width == ([[UIScreen mainScreen] bounds].size.width*([[UIScreen mainScreen] bounds].size.width<[[UIScreen mainScreen] bounds].size.height))+([[UIScreen mainScreen] bounds].size.height*([[UIScreen mainScreen] bounds].size.width>[[UIScreen mainScreen] bounds].size.height))) {
+    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tabBottomLabel)];
+    [self.bottomLabel addGestureRecognizer:tapGesture];
+    
+    if (self.view.frame.size.width == ([[UIScreen mainScreen] bounds].size.width*([[UIScreen mainScreen] bounds].size.width<[[UIScreen mainScreen] bounds].size.height))+([[UIScreen mainScreen] bounds].size.height*([[UIScreen mainScreen] bounds].size.width>[[UIScreen mainScreen] bounds].size.height))) {
         
-            // Portrait
+        // Portrait
+        if ([NCBrandOptions sharedInstance].disable_linkLoginProvider == NO)
             self.bottomLabel.hidden = NO;
+        self.loginTypeView.hidden = NO;
         
-        } else {
+    } else {
         
-            // Landscape
-            self.bottomLabel.hidden = YES;
-        }
+        // Landscape
+        self.bottomLabel.hidden = YES;
+        self.loginTypeView.hidden = YES;
     }
     
-    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tabBottomLabel)];
-    [self.bottomLabel addGestureRecognizer:tapGesture];
-    
-    self.annulla.tintColor = [NCBrandColor sharedInstance].customer;
-    
-    [self.baseUrl setDelegate:self];
-    [self.password setDelegate:self];
-    [self.user setDelegate:self];
-    
-    [self.baseUrl setFont:[UIFont systemFontOfSize:13]];
-    [self.user setFont:[UIFont systemFontOfSize:13]];
-    [self.password setFont:[UIFont systemFontOfSize:13]];
-    
-    self.imageBaseUrl.image = [CCGraphics changeThemingColorImage:[UIImage imageNamed:@"loginURL"] color:[NCBrandColor sharedInstance].customer];
-    self.imageUser.image = [CCGraphics changeThemingColorImage:[UIImage imageNamed:@"loginUser"] color:[NCBrandColor sharedInstance].customer];
-    self.imagePassword.image = [CCGraphics changeThemingColorImage:[UIImage imageNamed:@"loginPassword"] color:[NCBrandColor sharedInstance].customer];
-
-    self.loadingBaseUrl.image = [UIImage animatedImageWithAnimatedGIFURL:[[NSBundle mainBundle] URLForResource: @"loading" withExtension:@"gif"]];
-    self.loadingBaseUrl.hidden = YES;
-    
     // Brand
     if ([NCBrandOptions sharedInstance].disable_request_login_url) {
-        
         _baseUrl.text = [NCBrandOptions sharedInstance].loginBaseUrl;
         _imageBaseUrl.hidden = YES;
         _baseUrl.hidden = YES;
     }
 
     if (_loginType == loginAdd) {
-        
+        // Login Flow ?
+        _imageUser.hidden = YES;
+        _user.hidden = YES;
+        _imagePassword.hidden = YES;
+        _password.hidden = YES;
     }
     
     if (_loginType == loginAddForced) {
         _annulla.hidden = YES;
+        // Login Flow ?
+        _imageUser.hidden = YES;
+        _user.hidden = YES;
+        _imagePassword.hidden = YES;
+        _password.hidden = YES;
     }
     
     if (_loginType == loginModifyPasswordUser) {
-        
         _baseUrl.text = appDelegate.activeUrl;
         _baseUrl.userInteractionEnabled = NO;
         _baseUrl.textColor = [UIColor lightGrayColor];
@@ -111,13 +148,6 @@
         _user.userInteractionEnabled = NO;
         _user.textColor = [UIColor lightGrayColor];
     }
-    
-    self.baseUrl.placeholder = NSLocalizedString(@"_login_url_", nil);
-    self.user.placeholder = NSLocalizedString(@"_username_", nil);
-    self.password.placeholder = NSLocalizedString(@"_password_", nil);
-    
-    [self.annulla setTitle:NSLocalizedString(@"_cancel_", nil) forState:UIControlStateNormal];
-    [self.login setTitle:NSLocalizedString(@"_login_", nil) forState:UIControlStateNormal];    
 }
 
 - (void)viewWillAppear:(BOOL)animated
@@ -139,9 +169,6 @@
 - (void)viewDidDisappear:(BOOL)animated
 {
     [super viewDidDisappear:animated];
-    
-    if ([self.delegate respondsToSelector:@selector(loginDisappear)])
-        [self.delegate loginDisappear];
 }
 
 - (BOOL)textFieldShouldReturn:(UITextField *)textField
@@ -154,24 +181,35 @@
 {
     [coordinator animateAlongsideTransition:nil completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
         
-        if (![NCBrandOptions sharedInstance].disable_linkLoginProvider) {
-        
-            if (self.view.frame.size.width == ([[UIScreen mainScreen] bounds].size.width*([[UIScreen mainScreen] bounds].size.width<[[UIScreen mainScreen] bounds].size.height))+([[UIScreen mainScreen] bounds].size.height*([[UIScreen mainScreen] bounds].size.width>[[UIScreen mainScreen] bounds].size.height))) {
+        if (self.view.frame.size.width == ([[UIScreen mainScreen] bounds].size.width*([[UIScreen mainScreen] bounds].size.width<[[UIScreen mainScreen] bounds].size.height))+([[UIScreen mainScreen] bounds].size.height*([[UIScreen mainScreen] bounds].size.width>[[UIScreen mainScreen] bounds].size.height))) {
             
-                // Portrait
+            // Portrait
+            if ([NCBrandOptions sharedInstance].disable_linkLoginProvider == NO)
                 self.bottomLabel.hidden = NO;
+            self.loginTypeView.hidden = NO;
             
-            } else {
+        } else {
             
-                // Landscape
-                self.bottomLabel.hidden = YES;
-            }
+            // Landscape
+            self.bottomLabel.hidden = YES;
+            self.loginTypeView.hidden = YES;
         }
     }];
     
     [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
 }
 
+- (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion
+{
+    [super dismissViewControllerAnimated:flag completion:completion];
+ 
+    NSArray *callStack = [NSThread callStackSymbols];
+    NSString *callParent = [callStack objectAtIndex:1];
+
+    if ([callParent containsString:@"CCLogin"])
+        [self.delegate loginClose];
+}
+
 #pragma --------------------------------------------------------------------------------------------
 #pragma mark == Chech Server URL ==
 #pragma --------------------------------------------------------------------------------------------
@@ -185,44 +223,101 @@
     if(![self.baseUrl.text hasPrefix:@"https"] && ![self.baseUrl.text hasPrefix:@"http"]) {
       self.baseUrl.text = [NSString stringWithFormat:@"https://%@",self.baseUrl.text];
     }
-    NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.baseUrl.text] cachePolicy:0 timeoutInterval:20.0];
-    [request addValue:[CCUtility getUserAgent] forHTTPHeaderField:@"User-Agent"];
     
-    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
-    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
+    // Remove stored cookies
+    NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
+    for (NSHTTPCookie *cookie in [storage cookies])
+    {
+        [storage deleteCookie:cookie];
+    }
     
-    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler: ^(NSData *data, NSURLResponse *response, NSError *error) {
+    // Test Login Flow
+    if ([self.baseUrl.text length] > 0 && _user.hidden && _password.hidden) {
         
-        dispatch_async(dispatch_get_main_queue(), ^{
-            
-            self.login.enabled = YES;
-            self.loadingBaseUrl.hidden = YES;
+        NSString *urlBase = self.baseUrl.text;
+        // Remove trailing slash
+        if ([self.baseUrl.text hasSuffix:@"/"])
+            urlBase = [self.baseUrl.text substringToIndex:[self.baseUrl.text length] - 1];
         
-            if (error != nil) {
-            
-                NSLog(@"[LOG] Error: %ld - %@",(long)[error code] , [error localizedDescription]);
+        NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlBase] cachePolicy:0 timeoutInterval:20.0];
+        [request addValue:[CCUtility getUserAgent] forHTTPHeaderField:@"User-Agent"];
+        [request addValue:@"true" forHTTPHeaderField:@"OCS-APIRequest"];
+
+        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
+        NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
+        
+        NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler: ^(NSData *data, NSURLResponse *response, NSError *error) {
             
-                // self signed certificate
-                if ([error code] == NSURLErrorServerCertificateUntrusted) {
-                
-                    NSLog(@"[LOG] Error NSURLErrorServerCertificateUntrusted");
+            dispatch_async(dispatch_get_main_queue(), ^{
                 
-                    [[CCCertificate sharedManager] presentViewControllerCertificateWithTitle:[error localizedDescription] viewController:self delegate:self];
+                self.login.enabled = YES;
+                self.loadingBaseUrl.hidden = YES;
                 
+                if (error) {
+                    
+                    if ([error code] == NSURLErrorServerCertificateUntrusted) {
+                        
+                        [[CCCertificate sharedManager] presentViewControllerCertificateWithTitle:[error localizedDescription] viewController:self delegate:self];
+                        
+                    } else {
+                        
+                        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_connection_error_", nil) message:[error localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
+                        UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {}];
+                        
+                        [alertController addAction:okAction];
+                        [self presentViewController:alertController animated:YES completion:nil];
+                    }
+
                 } else {
                     
-                    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_connection_error_", nil) message:[error localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
-                    UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {}];
+                    appDelegate.activeLoginWeb = [CCLoginWeb new];
+                    appDelegate.activeLoginWeb.loginType = _loginType;
+                    appDelegate.activeLoginWeb.delegate = self;
+                    appDelegate.activeLoginWeb.urlBase = urlBase;
                     
-                    [alertController addAction:okAction];
-                    [self presentViewController:alertController animated:YES completion:nil];
+                    [appDelegate.activeLoginWeb presentModalWithDefaultTheme:self];
                 }
-            }
-        });
+            });
+        }];
         
-    }];
+        [task resume];
+        
+    } else {
+    
+        NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.baseUrl.text] cachePolicy:0 timeoutInterval:20.0];
+        [request addValue:[CCUtility getUserAgent] forHTTPHeaderField:@"User-Agent"];
+    
+        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
+        NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
+    
+        NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler: ^(NSData *data, NSURLResponse *response, NSError *error) {
+        
+            dispatch_async(dispatch_get_main_queue(), ^{
+            
+                self.login.enabled = YES;
+                self.loadingBaseUrl.hidden = YES;
+        
+                if (error != nil) {
+        
+                    // self signed certificate
+                    if ([error code] == NSURLErrorServerCertificateUntrusted) {
+                        
+                        [[CCCertificate sharedManager] presentViewControllerCertificateWithTitle:[error localizedDescription] viewController:self delegate:self];
+                
+                    } else {
+                    
+                        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_connection_error_", nil) message:[error localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
+                        UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {}];
+                    
+                        [alertController addAction:okAction];
+                        [self presentViewController:alertController animated:YES completion:nil];
+                    }
+                }
+            });
+        }];
     
-    [task resume];
+        [task resume];
+    }
 }
 
 - (void)trustedCerticateAccepted
@@ -273,16 +368,14 @@
                 // Setting appDelegate active account
                 [appDelegate settingActiveAccount:tbAccount.account activeUrl:tbAccount.url activeUser:tbAccount.user activeUserID:tbAccount.userID activePassword:tbAccount.password];
 
-                // Dismiss
-                if ([self.delegate respondsToSelector:@selector(loginSuccess:)])
-                    [self.delegate loginSuccess:_loginType];
+                [self.delegate loginSuccess:_loginType];
             
                 [self dismissViewControllerAnimated:YES completion:nil];
             
             } else {
 
                 [[NCManageDatabase sharedInstance] deleteAccount:account];
-                [[NCManageDatabase sharedInstance] addAccount:account url:url user:user password:password];
+                [[NCManageDatabase sharedInstance] addAccount:account url:url user:user password:password loginFlow:false];
             
                 // Read User Profile
                 CCMetadataNet *metadataNet = [[CCMetadataNet alloc] initWithAccount:account];
@@ -361,9 +454,7 @@
             // Setting appDelegate active account
             [appDelegate settingActiveAccount:account.account activeUrl:account.url activeUser:account.user activeUserID:account.userID activePassword:account.password];
     
-            // Ok ! Dismiss
-            if ([self.delegate respondsToSelector:@selector(loginSuccess:)])
-                [self.delegate loginSuccess:_loginType];
+            [self.delegate loginSuccess:_loginType];
         
             dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
                 [self dismissViewControllerAnimated:YES completion:nil];
@@ -380,7 +471,7 @@
 {
     if (textField == self.password) {
         self.toggleVisiblePassword.hidden = NO;
-        self.password.defaultTextAttributes = @{NSFontAttributeName: [UIFont systemFontOfSize:14.0f], NSForegroundColorAttributeName: [UIColor darkGrayColor]};
+        self.password.defaultTextAttributes = @{NSFontAttributeName: [UIFont systemFontOfSize:14.0f], NSForegroundColorAttributeName:[NCBrandColor sharedInstance].customerText};
     }
 }
 
@@ -388,10 +479,26 @@
 {
     if (textField == self.password) {
         self.toggleVisiblePassword.hidden = YES;
-        self.password.defaultTextAttributes = @{NSFontAttributeName: [UIFont systemFontOfSize:14.0f], NSForegroundColorAttributeName: [UIColor darkGrayColor]};
+        self.password.defaultTextAttributes = @{NSFontAttributeName: [UIFont systemFontOfSize:14.0f], NSForegroundColorAttributeName:[NCBrandColor sharedInstance].customerText};
     }
 }
 
+#pragma --------------------------------------------------------------------------------------------
+#pragma mark === CCLoginDelegateWeb ===
+#pragma --------------------------------------------------------------------------------------------
+
+- (void)loginSuccess:(NSInteger)loginType
+{
+    [self.delegate loginSuccess:_loginType];
+}
+
+- (void)loginWebClose
+{
+    appDelegate.activeLoginWeb = nil;
+   
+    [self dismissViewControllerAnimated:YES completion:nil];
+}
+
 #pragma --------------------------------------------------------------------------------------------
 #pragma mark == Action ==
 #pragma --------------------------------------------------------------------------------------------
@@ -403,12 +510,17 @@
 
 - (IBAction)handlebaseUrlchange:(id)sender
 {
-    if ([self.baseUrl.text length] > 0)
+    if ([self.baseUrl.text length] > 0 && !_user.hidden && !_password.hidden)
         [self performSelector:@selector(testUrl) withObject:nil];
 }
 
 - (IBAction)handleButtonLogin:(id)sender
 {
+    if ([self.baseUrl.text length] > 0 && _user.hidden && _password.hidden) {
+        [self testUrl];
+        return;
+    }
+    
     if ([self.baseUrl.text length] > 0 && [self.user.text length] && [self.password.text length]) {
         
         // remove last char if /
@@ -438,7 +550,29 @@
     
     self.password.text = @"";
     self.password.text = currentPassword;
-    self.password.defaultTextAttributes = @{NSFontAttributeName: [UIFont systemFontOfSize:14.0f], NSForegroundColorAttributeName: [UIColor darkGrayColor]};
+    self.password.defaultTextAttributes = @{NSFontAttributeName: [UIFont systemFontOfSize:14.0f], NSForegroundColorAttributeName: [NCBrandColor sharedInstance].customerText};
+}
+
+- (IBAction)handleLoginTypeView:(id)sender
+{
+    if (_user.hidden && _password.hidden) {
+        
+        _imageUser.hidden = NO;
+        _user.hidden = NO;
+        _imagePassword.hidden = NO;
+        _password.hidden = NO;
+        
+        [self.loginTypeView setTitle:NSLocalizedString(@"_web_login_", nil) forState:UIControlStateNormal];
+        
+    } else {
+        
+        _imageUser.hidden = YES;
+        _user.hidden = YES;
+        _imagePassword.hidden = YES;
+        _password.hidden = YES;
+        
+        [self.loginTypeView setTitle:NSLocalizedString(@"_traditional_login_", nil) forState:UIControlStateNormal];
+    }
 }
 
 @end

+ 17 - 3
iOSClient/Login/CCLogin.storyboard

@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13196" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
     <device id="retina4_7" orientation="portrait">
         <adaptation id="fullscreen"/>
     </device>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13173"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
         <capability name="Constraints to layout margins" minToolsVersion="6.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
@@ -122,7 +122,7 @@
                                     <constraint firstAttribute="width" constant="229" id="xwH-mh-yDU"/>
                                 </constraints>
                             </imageView>
-                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Don't have a server yet? Choose one of the providers." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="uJf-zK-g43">
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Don't have a server yet? Choose one of the providers." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="uJf-zK-g43" userLabel="choseProvider">
                                 <rect key="frame" x="0.0" y="611" width="375" height="51"/>
                                 <constraints>
                                     <constraint firstAttribute="height" constant="51" id="h7p-oO-gAz"/>
@@ -131,6 +131,16 @@
                                 <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
                                 <nil key="highlightedColor"/>
                             </label>
+                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="owR-PS-F32" userLabel="loginTypeView">
+                                <rect key="frame" x="0.0" y="573" width="375" height="30"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="30" id="PaU-7J-gkn"/>
+                                </constraints>
+                                <state key="normal" title="Login type view"/>
+                                <connections>
+                                    <action selector="handleLoginTypeView:" destination="yj9-jo-WIn" eventType="touchUpInside" id="V2I-Nr-nOu"/>
+                                </connections>
+                            </button>
                         </subviews>
                         <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                         <constraints>
@@ -138,6 +148,7 @@
                             <constraint firstItem="fhk-o9-J0l" firstAttribute="leading" secondItem="oF7-f3-D2I" secondAttribute="leading" id="11w-VB-cde"/>
                             <constraint firstItem="fhk-o9-J0l" firstAttribute="top" secondItem="7q8-rl-x2M" secondAttribute="top" id="1oU-Kw-Rqv"/>
                             <constraint firstItem="1Gf-Bw-Nim" firstAttribute="leading" secondItem="Bv6-g3-l0M" secondAttribute="leadingMargin" constant="34" id="6Be-V2-eJc"/>
+                            <constraint firstItem="owR-PS-F32" firstAttribute="leading" secondItem="Bv6-g3-l0M" secondAttribute="leading" id="7f1-2g-eiu"/>
                             <constraint firstItem="szn-G7-5sK" firstAttribute="centerY" secondItem="s9o-RX-XeS" secondAttribute="centerY" constant="-0.5" id="BR2-Vt-TiK"/>
                             <constraint firstItem="BpI-xK-1SU" firstAttribute="top" secondItem="Bv6-g3-l0M" secondAttribute="top" constant="30" id="CRD-sA-WM7"/>
                             <constraint firstItem="1Gf-Bw-Nim" firstAttribute="top" secondItem="szn-G7-5sK" secondAttribute="bottom" id="GgI-rV-AyE"/>
@@ -160,8 +171,10 @@
                             <constraint firstItem="szn-G7-5sK" firstAttribute="leading" secondItem="Bv6-g3-l0M" secondAttribute="leadingMargin" constant="34" id="fG7-68-kpN"/>
                             <constraint firstItem="jU7-Iw-XfU" firstAttribute="top" secondItem="1Gf-Bw-Nim" secondAttribute="bottom" id="iHp-sz-2Uh"/>
                             <constraint firstAttribute="trailingMargin" secondItem="oF7-f3-D2I" secondAttribute="trailing" constant="-4" id="kTO-mX-qTR"/>
+                            <constraint firstAttribute="trailing" secondItem="owR-PS-F32" secondAttribute="trailing" id="kgS-yD-ZfV"/>
                             <constraint firstItem="BpI-xK-1SU" firstAttribute="leading" secondItem="Bv6-g3-l0M" secondAttribute="leadingMargin" constant="209" id="oc7-ts-Gh2"/>
                             <constraint firstItem="szn-G7-5sK" firstAttribute="top" secondItem="3IQ-ds-9vR" secondAttribute="bottom" constant="136" id="sMw-IZ-nIE"/>
+                            <constraint firstItem="uJf-zK-g43" firstAttribute="top" secondItem="owR-PS-F32" secondAttribute="bottom" constant="8" id="uIE-dm-6V1"/>
                             <constraint firstItem="olW-Hc-7Im" firstAttribute="top" secondItem="uJf-zK-g43" secondAttribute="bottom" constant="5" id="uvx-nF-rgG"/>
                             <constraint firstItem="bSU-bn-DlO" firstAttribute="trailing" secondItem="Bv6-g3-l0M" secondAttribute="trailingMargin" constant="4" id="vFz-xR-4yV"/>
                         </constraints>
@@ -181,6 +194,7 @@
                         <outlet property="imageUser" destination="4OF-5u-Hd1" id="MJa-4H-w7m"/>
                         <outlet property="loadingBaseUrl" destination="oF7-f3-D2I" id="uel-s3-cAX"/>
                         <outlet property="login" destination="HQd-pF-3cE" id="dpI-ns-Ivh"/>
+                        <outlet property="loginTypeView" destination="owR-PS-F32" id="Rdw-tW-R0G"/>
                         <outlet property="password" destination="jU7-Iw-XfU" id="OWi-V0-Eij"/>
                         <outlet property="toggleVisiblePassword" destination="fhk-o9-J0l" id="aco-hl-Ban"/>
                         <outlet property="user" destination="1Gf-Bw-Nim" id="BUW-sz-I3f"/>

+ 56 - 16
iOSClient/Login/CCLoginWeb.swift

@@ -10,7 +10,7 @@ import UIKit
 
 @objc protocol CCLoginDelegateWeb: class {
     func loginSuccess(_: NSInteger)
-    func loginDisappear()
+    func loginWebClose()
 }
 
 public class CCLoginWeb: UIViewController {
@@ -25,6 +25,7 @@ public class CCLoginWeb: UIViewController {
     
     @objc weak var delegate: CCLoginDelegateWeb?
     @objc var loginType = loginAdd
+    @objc var urlBase = ""
     
     var viewController : UIViewController?
     let appDelegate = UIApplication.shared.delegate as! AppDelegate
@@ -32,13 +33,18 @@ public class CCLoginWeb: UIViewController {
     
     @objc func presentModalWithDefaultTheme(_ vc: UIViewController) {
         
+        var urlString = urlBase
         self.viewController = vc
         
         if (loginType == loginAdd || loginType == loginModifyPasswordUser) {
             doneButtonVisible = true
         }
         
-        let webVC = SwiftModalWebVC(urlString: NCBrandOptions.sharedInstance.loginBaseUrl, theme: .custom, color: NCBrandColor.sharedInstance.brand, colorText: NCBrandColor.sharedInstance.brandText, doneButtonVisible: doneButtonVisible, hideToolbar: true)
+        if (NCBrandOptions.sharedInstance.use_login_web_personalized == false) {
+            urlString =  urlBase+flowEndpoint
+        }
+        
+        let webVC = SwiftModalWebVC(urlString: urlString, theme: .custom, color: NCBrandColor.sharedInstance.customer, colorText: NCBrandColor.sharedInstance.customerText, doneButtonVisible: doneButtonVisible, hideToolbar: true)
         webVC.delegateWeb = self
 
         vc.present(webVC, animated: false, completion: nil)
@@ -55,7 +61,7 @@ extension CCLoginWeb: SwiftModalWebVCDelegate {
                 
         let urlString: String = url.absoluteString.lowercased()
         
-        if (urlString.contains(NCBrandOptions.sharedInstance.webLoginAutenticationProtocol) == true && urlString.contains("login") == true && (loginType == loginAdd || loginType == loginAddForced)) {
+        if (urlString.hasPrefix(NCBrandOptions.sharedInstance.webLoginAutenticationProtocol) == true && urlString.contains("login") == true) {
             
             let keyValue = url.path.components(separatedBy: "&")
             if (keyValue.count == 3) {
@@ -64,27 +70,63 @@ extension CCLoginWeb: SwiftModalWebVCDelegate {
                 
                     var serverUrl : String = keyValue[0].replacingOccurrences(of: "/server:", with: "")
                     
+                    // Login Flow NC 12
+                    if (NCBrandOptions.sharedInstance.use_login_web_personalized == false && serverUrl.hasPrefix("http://") == false && serverUrl.hasPrefix("https://") == false) {
+                        serverUrl = urlBase
+                    }
+                    
                     if (serverUrl.last == "/") {
                         serverUrl = String(serverUrl.dropLast())
                     }
-                
+            
                     let username : String = keyValue[1].replacingOccurrences(of: "user:", with: "")
                     let password : String = keyValue[2].replacingOccurrences(of: "password:", with: "")
                 
                     let account : String = "\(username) \(serverUrl)"
                 
-                    NCManageDatabase.sharedInstance.deleteAccount(account)
-                    NCManageDatabase.sharedInstance.addAccount(account, url: serverUrl, user: username, password: password)
-                                    
-                    guard let tableAccount = NCManageDatabase.sharedInstance.setAccountActive(account) else {
-                        return
+                    // Login Flow
+                    if (loginType == loginModifyPasswordUser && NCBrandOptions.sharedInstance.use_login_web_personalized == false) {
+                        
+                        // Verify if change the active account
+                        guard let activeAccount = NCManageDatabase.sharedInstance.getAccountActive() else {
+                            self.viewController?.dismiss(animated: true, completion: nil)
+                            return
+                        }
+                        if (activeAccount.account != account) {
+                            self.viewController?.dismiss(animated: true, completion: nil)
+                            return
+                        }
+                        
+                        // Change Password
+                        guard let tableAccount = NCManageDatabase.sharedInstance.setAccountPassword(account, password: password) else {
+                            self.viewController?.dismiss(animated: true, completion: nil)
+                            return
+                        }
+                        
+                        appDelegate.settingActiveAccount(account, activeUrl: serverUrl, activeUser: username, activeUserID: tableAccount.userID, activePassword: password)
+                        
+                        self.delegate?.loginSuccess(NSInteger(loginType.rawValue))
+                        self.delegate?.loginWebClose()
+
+                        self.viewController?.dismiss(animated: true, completion: nil)
                     }
-                
-                    if (tableAccount.account == account) {
                     
+                    if (loginType == loginAdd || loginType == loginAddForced) {
+                        
+                        // Add new account
+                        NCManageDatabase.sharedInstance.deleteAccount(account)
+                        NCManageDatabase.sharedInstance.addAccount(account, url: serverUrl, user: username, password: password, loginFlow: true)
+                        
+                        guard let tableAccount = NCManageDatabase.sharedInstance.setAccountActive(account) else {
+                            self.viewController?.dismiss(animated: true, completion: nil)
+                            return
+                        }
+                        
                         appDelegate.settingActiveAccount(account, activeUrl: serverUrl, activeUser: username, activeUserID: tableAccount.userID, activePassword: password)
+                        
                         self.delegate?.loginSuccess(NSInteger(loginType.rawValue))
-                
+                        self.delegate?.loginWebClose()
+
                         self.viewController?.dismiss(animated: true, completion: nil)
                     }
                 }
@@ -96,10 +138,8 @@ extension CCLoginWeb: SwiftModalWebVCDelegate {
         print("Finished loading. Success: \(success).")
     }
     
-    public override func viewDidDisappear(_ animated: Bool) {
-        super.viewDidDisappear(animated)
-        
-        self.delegate?.loginDisappear()
+    public func loginWebClose() {
+        self.delegate?.loginWebClose()
     }
 }
 

+ 1 - 0
iOSClient/Main/CCCellMain.h

@@ -40,6 +40,7 @@
 @property(nonatomic, weak) IBOutlet UIButton *reloadTaskButton;
 @property(nonatomic, weak) IBOutlet UIButton *stopTaskButton;
 
+@property(nonatomic, strong) UIImage *imageTitleSegue;
 
 //Last position of the scroll of the swipe
 @property (nonatomic, assign) CGFloat lastContentOffset;

+ 2 - 0
iOSClient/Main/CCCellMainTransfer.h

@@ -40,6 +40,8 @@
 @property(nonatomic, weak) IBOutlet UIButton *reloadTaskButton;
 @property(nonatomic, weak) IBOutlet UIButton *stopTaskButton;
 
+@property(nonatomic, strong) UIImage *imageTitleSegue;
+
 //Last position of the scroll of the swipe
 @property (nonatomic, assign) CGFloat lastContentOffset;
 

+ 34 - 14
iOSClient/Main/CCDetail.m

@@ -189,7 +189,7 @@
     if (@available(iOS 11, *)) {
         safeAreaBottom = [UIApplication sharedApplication].delegate.window.safeAreaInsets.bottom;
     }
-
+    
     _toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height - TOOLBAR_HEIGHT - safeAreaBottom, self.view.bounds.size.width, TOOLBAR_HEIGHT)];
     
     UIBarButtonItem *flexible = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
@@ -201,10 +201,17 @@
     _buttonShare  = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"actionSheetShare"] style:UIBarButtonItemStylePlain target:self action:@selector(shareButtonPressed:)];
     _buttonDelete = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(deleteButtonPressed:)];
     
-    if ([_fileNameExtension isEqualToString:@"TXT"])
-        [_toolbar setItems:[NSArray arrayWithObjects: _buttonModifyTxt, flexible, _buttonDelete, fixedSpaceMini, _buttonShare, fixedSpaceMini, _buttonAction,  nil]];
-    else
-        [_toolbar setItems:[NSArray arrayWithObjects: flexible, _buttonDelete, fixedSpaceMini, _buttonShare, fixedSpaceMini, _buttonAction,  nil]];
+    if ([_fileNameExtension isEqualToString:@"TXT"]) {
+        if ([CCUtility isFolderEncrypted:[[NCManageDatabase sharedInstance] getServerUrl:_metadataDetail.directoryID] account:appDelegate.activeAccount]) // E2EE
+            [_toolbar setItems:[NSArray arrayWithObjects: _buttonModifyTxt, flexible, _buttonDelete, fixedSpaceMini, _buttonAction,  nil]];
+        else
+            [_toolbar setItems:[NSArray arrayWithObjects: _buttonModifyTxt, flexible, _buttonDelete, fixedSpaceMini, _buttonShare, fixedSpaceMini, _buttonAction,  nil]];
+    } else {
+        if ([CCUtility isFolderEncrypted:[[NCManageDatabase sharedInstance] getServerUrl:_metadataDetail.directoryID] account:appDelegate.activeAccount]) // E2EE
+            [_toolbar setItems:[NSArray arrayWithObjects: flexible, _buttonDelete, fixedSpaceMini, _buttonAction,  nil]];
+        else
+            [_toolbar setItems:[NSArray arrayWithObjects: flexible, _buttonDelete, fixedSpaceMini, _buttonShare, fixedSpaceMini, _buttonAction,  nil]];
+    }
     
     [_toolbar setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin];
     
@@ -319,8 +326,10 @@
         [headRequest setHTTPMethod:@"HEAD"];
         
         NSURLSessionDataTask *task = [session dataTaskWithRequest:headRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
-            NSString *encodingName = [[NCUchardet sharedNUCharDet] encodingStringDetectWithData:data];
-            [self.webView loadData:[NSData dataWithContentsOfURL: url] MIMEType:response.MIMEType characterEncodingName:encodingName baseURL:url];
+            dispatch_async(dispatch_get_main_queue(), ^{
+                NSString *encodingName = [[NCUchardet sharedNUCharDet] encodingStringDetectWithData:data];
+                [self.webView loadData:[NSData dataWithContentsOfURL: url] MIMEType:response.MIMEType characterEncodingName:encodingName baseURL:url];
+            });
         }];
         
         [task resume];
@@ -366,6 +375,10 @@
     // PhotoBrowser
     self.photoBrowser.displayActionButton = YES;
     self.photoBrowser.displayDeleteButton = YES;
+    if ([CCUtility isFolderEncrypted:[[NCManageDatabase sharedInstance] getServerUrl:_metadataDetail.directoryID] account:appDelegate.activeAccount]) // E2EE
+        self.photoBrowser.displayShareButton = NO;
+    else
+        self.photoBrowser.displayShareButton = YES;
     self.photoBrowser.displayNavArrows = YES;
     self.photoBrowser.displaySelectionButtons = NO;
     self.photoBrowser.alwaysShowControls = NO;
@@ -582,7 +595,7 @@
     [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_delete_", nil)
                                                          style:UIAlertActionStyleDestructive
                                                        handler:^(UIAlertAction *action) {
-                                                           [[CCActions sharedInstance] deleteFileOrFolder:metadata delegate:self];
+                                                           [[CCActions sharedInstance] deleteFileOrFolder:metadata delegate:self hud:nil hudTitled:nil];
                                                        }]];
 
     [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_cancel_", nil)
@@ -599,6 +612,12 @@
     [self.parentViewController presentViewController:alertController animated:YES completion:NULL];
 }
 
+- (void)photoBrowserDidFinishPresentation:(MWPhotoBrowser *)photoBrowser
+{
+    [self removeAllView];
+    [self.navigationController popViewControllerAnimated:YES];
+}
+
 - (void)triggerProgressTask:(NSNotification *)notification
 {
     NSDictionary *dict = notification.userInfo;
@@ -843,6 +862,12 @@
     [self.readerPDFViewController updateContentViews];
 }
 
+- (void)handleSwipeUpDown
+{
+    [self removeAllView];
+    [self.navigationController popViewControllerAnimated:YES];
+}
+
 #pragma --------------------------------------------------------------------------------------------
 #pragma mark ===== Delete =====
 #pragma --------------------------------------------------------------------------------------------
@@ -854,11 +879,6 @@
 
 - (void)deleteFileOrFolderSuccess:(CCMetadataNet *)metadataNet
 {
-    // E2E
-    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
-        [[CCNetworking sharedNetworking] rebuildAndSendEndToEndMetadataOnServerUrl:metadataNet.serverUrl];
-    });
-    
     // reload Main
     [appDelegate.activeMain reloadDatasource];
     
@@ -962,7 +982,7 @@
     [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_delete_", nil)
                                                          style:UIAlertActionStyleDestructive
                                                        handler:^(UIAlertAction *action) {
-                                                           [[CCActions sharedInstance] deleteFileOrFolder:self.metadataDetail delegate:self];
+                                                           [[CCActions sharedInstance] deleteFileOrFolder:self.metadataDetail delegate:self hud:nil hudTitled:nil];
                                                        }]];
     
     [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_cancel_", nil)

+ 1 - 3
iOSClient/Main/CCMain.h

@@ -54,8 +54,6 @@
 
 @interface CCMain : UIViewController <UITableViewDataSource, UITableViewDelegate, UIActionSheetDelegate, UIGestureRecognizerDelegate, UIDocumentInteractionControllerDelegate, UIViewControllerPreviewingDelegate, CCMoveDelegate, CTAssetsPickerControllerDelegate, BKPasscodeViewControllerDelegate, UISplitViewControllerDelegate, UIPopoverControllerDelegate, CCNetworkingDelegate, CCShareOCDelegate, CCPeekPopDelegate, UIDocumentMenuDelegate, UIDocumentPickerDelegate, UISearchResultsUpdating, UISearchControllerDelegate, UISearchBarDelegate, UIScrollViewDelegate, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate>
 
-@property BOOL isFolderEncrypted;
-
 @property (nonatomic, weak) IBOutlet UITableView *tableView;
 @property (nonatomic, strong) UIRefreshControl *refreshControl;
 @property (nonatomic, strong) NSString *serverUrl;
@@ -66,7 +64,7 @@
 @property (nonatomic, strong) UISearchController *searchController;
 @property (nonatomic, strong) UIView *reMenuBackgroundView;
 @property (nonatomic, strong) UITapGestureRecognizer *singleFingerTap;
-
+@property (nonatomic, strong) UIImage *imageTitle;
 
 - (void)closeAllMenu;
 - (void)returnCreate:(NSInteger)type;

文件差异内容过多而无法显示
+ 289 - 209
iOSClient/Main/CCMain.m


+ 13 - 0
iOSClient/Main/CCMainTabBarController.swift

@@ -85,6 +85,19 @@ class CCMainTabBarController : UITabBarController, UITabBarControllerDelegate {
             self.view.isUserInteractionEnabled = true
         })
     }
+}
 
+//
+// https://stackoverflow.com/questions/44822558/ios-11-uitabbar-uitabbaritem-positioning-issue/46348796#46348796
+//
+extension UITabBar {
+    // Workaround for iOS 11's new UITabBar behavior where on iPad, the UITabBar inside
+    // the Master view controller shows the UITabBarItem icon next to the text
+    override open var traitCollection: UITraitCollection {
+        if UIDevice.current.userInterfaceIdiom == .pad {
+            return UITraitCollection(horizontalSizeClass: .compact)
+        }
+        return super.traitCollection
+    }
 }
 

+ 16 - 3
iOSClient/Main/CCMore.swift

@@ -207,6 +207,15 @@ class CCMore: UIViewController, UITableViewDelegate, UITableViewDataSource, CCLo
             labelUsername.text = tabAccount.displayName
         }
         
+        // Shadow labelUsername TEST BLUR
+        /*
+        labelUsername.layer.shadowColor = UIColor.black.cgColor
+        labelUsername.layer.shadowRadius = 4
+        labelUsername.layer.shadowOpacity = 0.8
+        labelUsername.layer.shadowOffset = CGSize(width: 0, height: 0)
+        labelUsername.layer.masksToBounds = false
+        */
+        
         if (tabAccount.quotaRelative > 0) {
             progressQuota.progress = Float(tabAccount.quotaRelative) / 100
         } else {
@@ -392,8 +401,12 @@ class CCMore: UIViewController, UITableViewDelegate, UITableViewDataSource, CCLo
         appDelegate.selectedTabBarController(Int(k_tabBarApplicationIndexFile))
     }
     
-    func loginDisappear() {
-        
+    func loginClose() {
+        appDelegate.activeLogin = nil
+    }
+    
+    func loginWebClose() {
+        appDelegate.activeLoginWeb = nil
     }
 }
 
@@ -408,7 +421,7 @@ extension CCMore: SwiftModalWebVCDelegate, SwiftWebVCDelegate{
         let urlString: String = url.absoluteString.lowercased()
         
         // Protocol close webVC
-        if (urlString.contains(NCBrandOptions.sharedInstance.webCloseViewProtocol) == true) {
+        if (urlString.contains(NCBrandOptions.sharedInstance.webCloseViewProtocolPersonalized) == true) {
             
             if (self.presentingViewController != nil) {
                 self.dismiss(animated: true, completion: nil)

+ 6 - 1
iOSClient/Main/CCSplit.m

@@ -196,11 +196,16 @@
     [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"initializeMain" object:nil];
 }
 
-- (void)loginDisappear
+- (void)loginClose
 {
     appDelegate.activeLogin = nil;
 }
 
+- (void)loginWebClose
+{
+    appDelegate.activeLoginWeb = nil;
+}
+
 #pragma --------------------------------------------------------------------------------------------
 #pragma mark ===== newAccount =====
 #pragma --------------------------------------------------------------------------------------------

+ 0 - 12
iOSClient/Networking/CCNetworking.h

@@ -64,16 +64,6 @@
 - (void)uploadFile:(NSString *)fileName serverUrl:(NSString *)serverUrl session:(NSString *)session taskStatus:(NSInteger)taskStatus selector:(NSString *)selector selectorPost:(NSString *)selectorPost errorCode:(NSInteger)errorCode delegate:(id)delegate;
 - (void)uploadFileMetadata:(tableMetadata *)metadata taskStatus:(NSInteger)taskStatus;
 
-// Verify Download/Upload
-- (void)verifyDownloadInProgress;
-- (void)verifyDownloadInError:(id)delegate;
-- (void)verifyUploadInProgress;
-- (void)verifyUploadInErrorOrWait;
-
-// E2E Encryption
-- (NSError *)SendEndToEndMetadataOnServerUrl:(NSString *)serverUrl;
-- (NSError *)rebuildAndSendEndToEndMetadataOnServerUrl:(NSString *)serverUrl;
-
 @end
 
 @protocol CCNetworkingDelegate <NSObject>
@@ -102,7 +92,6 @@
 @property BOOL directory;
 @property (nonatomic, strong) NSString *directoryID;
 @property (nonatomic, strong) NSString *directoryIDTo;
-@property BOOL e2eEncrypted;
 @property (nonatomic, strong) NSString *encryptedMetadata;
 @property NSInteger errorCode;
 @property NSInteger errorRetry;
@@ -129,7 +118,6 @@
 @property NSInteger sharePermission;
 @property long size;
 @property NSInteger taskStatus;
-@property (nonatomic, strong) NSString *token;
 
 - (id)initWithAccount:(NSString *)withAccount;
 - (id)copyWithZone:(NSZone *)zone;

+ 176 - 440
iOSClient/Networking/CCNetworking.m

@@ -69,8 +69,8 @@
     [self sessionWWanDownload];
 
     [self sessionUpload];
-    [self sessionUploadForeground];
     [self sessionWWanUpload];
+    [self sessionUploadForeground];
     
     [self sharedOCCommunication];
     
@@ -174,43 +174,43 @@
     return sessionUpload;
 }
 
-- (NSURLSession *)sessionUploadForeground
+- (NSURLSession *)sessionWWanUpload
 {
-    static NSURLSession *sessionUploadForeground;
+    static NSURLSession *sessionWWanUpload = nil;
     
-    if (sessionUploadForeground == nil) {
+    if (sessionWWanUpload == nil) {
         
-        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
+        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:k_upload_session_wwan];
         
-        configuration.allowsCellularAccess = YES;
+        configuration.allowsCellularAccess = NO;
+        configuration.sessionSendsLaunchEvents = YES;
         configuration.discretionary = NO;
         configuration.HTTPMaximumConnectionsPerHost = 1;
         configuration.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
         
-        sessionUploadForeground = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
-        sessionUploadForeground.sessionDescription = k_upload_session_foreground;
+        sessionWWanUpload = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
+        sessionWWanUpload.sessionDescription = k_upload_session_wwan;
     }
-    return sessionUploadForeground;
+    return sessionWWanUpload;
 }
 
-- (NSURLSession *)sessionWWanUpload
+- (NSURLSession *)sessionUploadForeground
 {
-    static NSURLSession *sessionWWanUpload = nil;
+    static NSURLSession *sessionUploadForeground;
     
-    if (sessionWWanUpload == nil) {
+    if (sessionUploadForeground == nil) {
         
-        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:k_upload_session_wwan];
+        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
         
-        configuration.allowsCellularAccess = NO;
-        configuration.sessionSendsLaunchEvents = YES;
+        configuration.allowsCellularAccess = YES;
         configuration.discretionary = NO;
         configuration.HTTPMaximumConnectionsPerHost = 1;
         configuration.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
         
-        sessionWWanUpload = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
-        sessionWWanUpload.sessionDescription = k_upload_session_wwan;
+        sessionUploadForeground = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
+        sessionUploadForeground.sessionDescription = k_upload_session_foreground;
     }
-    return sessionWWanUpload;
+    return sessionUploadForeground;
 }
 
 - (OCCommunication *)sharedOCCommunication
@@ -243,9 +243,9 @@
     if ([sessionDescription isEqualToString:k_download_session_wwan]) return [self sessionWWanDownload];
     
     if ([sessionDescription isEqualToString:k_upload_session]) return [self sessionUpload];
-    if ([sessionDescription isEqualToString:k_upload_session_foreground]) return [self sessionUploadForeground];
     if ([sessionDescription isEqualToString:k_upload_session_wwan]) return [self sessionWWanUpload];
-    
+    if ([sessionDescription isEqualToString:k_upload_session_foreground]) return [self sessionUploadForeground];
+
     return nil;
 }
 
@@ -256,8 +256,8 @@
     [[self sessionWWanDownload] invalidateAndCancel];
     
     [[self sessionUpload] invalidateAndCancel];
+    [[self sessionWWanUpload] invalidateAndCancel];
     [[self sessionUploadForeground] invalidateAndCancel];
-    [[self sessionWWanUpload] invalidateAndCancel];    
 }
 
 - (void)settingSessionsDownload:(BOOL)download upload:(BOOL)upload taskStatus:(NSInteger)taskStatus activeAccount:(NSString *)activeAccount activeUser:(NSString *)activeUser activeUrl:(NSString *)activeUrl
@@ -284,6 +284,12 @@
                 else if (taskStatus == k_taskStatusSuspend) [task suspend];
                 else if (taskStatus == k_taskStatusResume) [task resume];
         }];
+        
+        if (taskStatus == k_taskStatusCancel) {
+            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
+                [[NCManageDatabase sharedInstance] setMetadataSession:@"" sessionError:@"" sessionSelector:@"" sessionSelectorPost:@"" sessionTaskIdentifier:k_taskIdentifierDone predicate:[NSPredicate predicateWithFormat:@"account = %@ AND session CONTAINS 'download'", _activeAccount]];
+            });
+        }
     }
         
     if (upload) {
@@ -295,38 +301,27 @@
                 else if (taskStatus == k_taskStatusResume) [task resume];
         }];
         
-        [[self sessionUploadForeground] getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
+        [[self sessionWWanUpload] getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
             for (NSURLSessionTask *task in uploadTasks)
                 if (taskStatus == k_taskStatusCancel) [task cancel];
                 else if (taskStatus == k_taskStatusSuspend) [task suspend];
                 else if (taskStatus == k_taskStatusResume) [task resume];
         }];
         
-        [[self sessionWWanUpload] getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
+        [[self sessionUploadForeground] getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
             for (NSURLSessionTask *task in uploadTasks)
                 if (taskStatus == k_taskStatusCancel) [task cancel];
                 else if (taskStatus == k_taskStatusSuspend) [task suspend];
                 else if (taskStatus == k_taskStatusResume) [task resume];
         }];
-    }
-    
-    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 4 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
-        
-        if (download && taskStatus == k_taskStatusCancel) {
-        
-            [[NCManageDatabase sharedInstance] setMetadataSession:@"" sessionError:@"" sessionSelector:@"" sessionSelectorPost:@"" sessionTaskIdentifier:k_taskIdentifierDone predicate:[NSPredicate predicateWithFormat:@"account = %@ AND session CONTAINS 'download'", _activeAccount]];
-        }
-    
-        if (upload && taskStatus == k_taskStatusCancel) {
-        
-            [[NCManageDatabase sharedInstance] deleteMetadataWithPredicate:[NSPredicate predicateWithFormat:@"session CONTAINS 'upload'"] clearDateReadDirectoryID:nil];
         
-            // File System
-            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+        if (taskStatus == k_taskStatusCancel) {
+            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
+                [[NCManageDatabase sharedInstance] deleteMetadataWithPredicate:[NSPredicate predicateWithFormat:@"session CONTAINS 'upload'"] clearDateReadDirectoryID:nil];
                 [CCUtility removeAllFileID_UPLOAD_ActiveUser:activeUser activeUrl:activeUrl];
             });
         }
-    });
+    }
 }
 
 - (void)settingSession:(NSString *)sessionDescription sessionTaskIdentifier:(NSUInteger)sessionTaskIdentifier taskStatus:(NSInteger)taskStatus
@@ -697,13 +692,13 @@
         if ([metadata.typeFile isEqualToString: k_metadataTypeFile_image])
             [[CCExifGeo sharedInstance] setExifLocalTableEtag:metadata directoryUser:_directoryUser activeAccount:_activeAccount];
 
-        // E2E Decrypted
+        // E2EE Decrypted
         tableE2eEncryption *object = [[NCManageDatabase sharedInstance] getE2eEncryptionWithPredicate:[NSPredicate predicateWithFormat:@"fileNameIdentifier = %@ AND serverUrl = %@", fileName, serverUrl]];
         if (object) {
             BOOL result = [[NCEndToEndEncryption sharedManager] decryptFileID:fileID directoryUser:_directoryUser key:object.key initializationVector:object.initializationVector authenticationTag:object.authenticationTag];
             if (!result) {
                 
-                [[NCManageDatabase sharedInstance] addActivityClient:fileName fileID:fileID action:k_activityDebugActionUpload selector:@"" note:[NSString stringWithFormat:@"Serious error internal download : decrypt error %@", fileName] type:k_activityTypeFailure verbose:k_activityVerboseDefault activeUrl:_activeUrl];
+                [[NCManageDatabase sharedInstance] addActivityClient:metadata.fileNameView fileID:fileID action:k_activityDebugActionUpload selector:@"" note:[NSString stringWithFormat:@"Serious error internal download : decrypt error %@", fileName] type:k_activityTypeFailure verbose:k_activityVerboseDefault activeUrl:_activeUrl];
                 
                 [[self getDelegate:fileID] downloadFileSuccessFailure:fileName fileID:fileID serverUrl:serverUrl selector:selector selectorPost:selectorPost errorMessage:[NSString stringWithFormat:@"Serious error internal download : decrypt error %@", fileName] errorCode:k_CCErrorInternalError];
                 
@@ -715,7 +710,7 @@
         [CCGraphics createNewImageFrom:metadata.fileID directoryUser:_directoryUser fileNameTo:metadata.fileID extension:[metadata.fileNameView pathExtension] size:@"m" imageForUpload:NO typeFile:metadata.typeFile writePreview:YES optimizedFileName:[CCUtility getOptimizedPhoto]];
                 
         // Activity
-        [[NCManageDatabase sharedInstance] addActivityClient:fileName fileID:metadata.fileID action:k_activityDebugActionDownload selector:metadata.sessionSelector note:serverUrl type:k_activityTypeSuccess verbose:k_activityVerboseDefault activeUrl:_activeUrl];
+        [[NCManageDatabase sharedInstance] addActivityClient:metadata.fileNameView fileID:metadata.fileID action:k_activityDebugActionDownload selector:metadata.sessionSelector note:serverUrl type:k_activityTypeSuccess verbose:k_activityVerboseDefault activeUrl:_activeUrl];
         
         [[self getDelegate:fileID] downloadFileSuccessFailure:fileName fileID:fileID serverUrl:serverUrl selector:selector selectorPost:selectorPost errorMessage:@"" errorCode:0];
     }
@@ -745,7 +740,16 @@
         
         PHImageRequestOptions *options = [PHImageRequestOptions new];
         options.networkAccessAllowed = YES; // iCloud
+        options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
+        options.synchronous = YES;
+        options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
+            
+            NSLog(@"cacheAsset: %f", progress);
             
+            if (error)
+                [delegate uploadFileSuccessFailure:metadataNet.fileName fileID:metadataNet.fileID assetLocalIdentifier:metadataNet.assetLocalIdentifier serverUrl:metadataNet.serverUrl selector:metadataNet.selector selectorPost:metadataNet.selectorPost errorMessage:[NSString stringWithFormat:@"Image request iCloud failed [%@]", error.description] errorCode:error.code];
+        };
+        
         [[PHImageManager defaultManager] requestImageDataForAsset:asset options:options resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
                 
             NSError *error = nil;
@@ -777,7 +781,15 @@
     if (asset.mediaType == PHAssetMediaTypeVideo) {
         
         PHVideoRequestOptions *options = [PHVideoRequestOptions new];
+        options.networkAccessAllowed = YES;
         options.version = PHVideoRequestOptionsVersionOriginal;
+        options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
+            
+            NSLog(@"cacheAsset: %f", progress);
+            
+            if (error)
+                [delegate uploadFileSuccessFailure:metadataNet.fileName fileID:metadataNet.fileID assetLocalIdentifier:metadataNet.assetLocalIdentifier serverUrl:metadataNet.serverUrl selector:metadataNet.selector selectorPost:metadataNet.selectorPost errorMessage:[NSString stringWithFormat:@"Video request iCloud failed [%@]", error.description] errorCode:error.code];
+        };
         
         [[PHImageManager defaultManager] requestAVAssetForVideo:asset options:options resultHandler:^(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info) {
             
@@ -825,6 +837,7 @@
     tableMetadata *metadata = [CCUtility insertFileSystemInMetadata:fileName fileNameView:fileName directory:_directoryUser activeAccount:_activeAccount];
     
     metadata.date = [NSDate new];
+    metadata.e2eEncrypted = NO;
     metadata.fileID = uploadID;
     metadata.directoryID = directoryID;
     metadata.fileName = fileName;
@@ -835,46 +848,39 @@
     metadata.sessionSelector = selector;
     metadata.sessionSelectorPost = selectorPost;
     
-    // E2E *** IS ENCRYPTED ---> ENCRYPTED FILE ***
-    if ([CCUtility isFolderEncrypted:serverUrl account:_activeAccount]) {
+    // E2EE : ENCRYPTED FILE
+    if ([CCUtility isFolderEncrypted:serverUrl account:_activeAccount] && [CCUtility isEndToEndEnabled:_activeAccount]) {
         
-        NSString *fileNameIdentifier;
-        NSError *error;
+        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
         
-        // Verify File Size
-        NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[NSString stringWithFormat:@"%@/%@", _directoryUser, fileName] error:&error];
-        NSNumber *fileSizeNumber = [fileAttributes objectForKey:NSFileSize];
-        long long fileSize = [fileSizeNumber longLongValue];
+            NSString *errorMessage;
+            NSString *fileNameIdentifier;
+            NSString *e2eMetadata;
         
-        if (fileSize > k_max_filesize_E2E) {
-            // Error for uploadFileFailure
-            [[self getDelegate:uploadID] uploadFileSuccessFailure:fileName fileID:uploadID assetLocalIdentifier:assetLocalIdentifier serverUrl:serverUrl selector:selector selectorPost:selectorPost errorMessage:@"E2E Error file too big" errorCode:k_CCErrorInternalError];
-            return;
-        }
+            [self encryptedE2EFile:fileName serverUrl:serverUrl directoryID:directoryID account:_activeAccount user:_activeUser userID:_activeUserID password:_activePassword url:_activeUrl errorMessage:&errorMessage fileNameIdentifier:&fileNameIdentifier e2eMetadata:&e2eMetadata];
+
+            if (errorMessage != nil || fileNameIdentifier == nil) {
+                
+                [[self getDelegate:uploadID] uploadFileSuccessFailure:fileName fileID:uploadID assetLocalIdentifier:assetLocalIdentifier serverUrl:serverUrl selector:selector selectorPost:selectorPost errorMessage:errorMessage errorCode:k_CCErrorInternalError];
+                
+            } else {
         
-        // if exists overwrite file else create a new encrypted filename
-        tableMetadata *overwriteMetadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND directoryID = %@ AND fileNameView = %@", _activeAccount, directoryID, fileName]];
-        if (overwriteMetadata)
-            fileNameIdentifier = overwriteMetadata.fileName;
-        else
-            fileNameIdentifier = [CCUtility generateRandomIdentifier];
+                // Now the fileName is fileNameIdentifier && flag e2eEncrypted
+                metadata.fileName = fileNameIdentifier;
+                metadata.e2eEncrypted = YES;
             
-        if ([self newEndToEndFile:fileName fileNameIdentifier:fileNameIdentifier serverUrl:serverUrl] == false) {
-            // Error for uploadFileFailure
-            [[self getDelegate:uploadID] uploadFileSuccessFailure:fileName fileID:uploadID assetLocalIdentifier:assetLocalIdentifier serverUrl:serverUrl selector:selector selectorPost:selectorPost errorMessage:@"E2E Error to create encrypted file" errorCode:k_CCErrorInternalError];
-            return;
-        }
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    [CCGraphics createNewImageFrom:metadata.fileNameView directoryUser:_directoryUser fileNameTo:metadata.fileID extension:[metadata.fileNameView pathExtension] size:@"m" imageForUpload:YES typeFile:metadata.typeFile writePreview:YES optimizedFileName:NO];
+                    [self uploadURLSessionMetadata:[[NCManageDatabase sharedInstance] addMetadata:metadata] serverUrl:serverUrl sessionID:uploadID taskStatus:taskStatus assetLocalIdentifier:assetLocalIdentifier selector:selector];
+                });
+            }
+        });
         
-        // Now the fileName is fileNameIdentifier
-        metadata.fileName = fileNameIdentifier;
-    }
+    } else {
     
-    [CCGraphics createNewImageFrom:metadata.fileNameView directoryUser:_directoryUser fileNameTo:metadata.fileID extension:[metadata.fileNameView pathExtension] size:@"m" imageForUpload:YES typeFile:metadata.typeFile writePreview:YES optimizedFileName:NO];
-
-    metadata = [[NCManageDatabase sharedInstance] addMetadata:metadata];
-            
-    if (metadata)
-        [self uploadURLSession:metadata.fileName serverUrl:serverUrl sessionID:uploadID session:metadata.session taskStatus:taskStatus assetLocalIdentifier:assetLocalIdentifier selector:selector];
+        [CCGraphics createNewImageFrom:metadata.fileNameView directoryUser:_directoryUser fileNameTo:metadata.fileID extension:[metadata.fileNameView pathExtension] size:@"m" imageForUpload:YES typeFile:metadata.typeFile writePreview:YES optimizedFileName:NO];
+        [self uploadURLSessionMetadata:[[NCManageDatabase sharedInstance] addMetadata:metadata] serverUrl:serverUrl sessionID:uploadID taskStatus:taskStatus assetLocalIdentifier:assetLocalIdentifier selector:selector];
+    }
 }
 
 - (void)uploadFileMetadata:(tableMetadata *)metadata taskStatus:(NSInteger)taskStatus
@@ -891,7 +897,7 @@
             
         [[NCManageDatabase sharedInstance] setMetadataSession:nil sessionError:@"" sessionSelector:nil sessionSelectorPost:nil sessionTaskIdentifier:k_taskIdentifierNULL predicate:[NSPredicate predicateWithFormat:@"sessionID = %@ AND account = %@", metadata.sessionID, _activeAccount]];
             
-        [self uploadURLSession:metadata.fileName serverUrl:serverUrl sessionID:metadata.sessionID session:metadata.session taskStatus:taskStatus assetLocalIdentifier:metadata.assetLocalIdentifier selector:metadata.sessionSelector];
+        [self uploadURLSessionMetadata:metadata serverUrl:serverUrl sessionID:metadata.sessionID taskStatus:taskStatus assetLocalIdentifier:metadata.assetLocalIdentifier selector:metadata.sessionSelector];
     }
     
     if (!reSend) {
@@ -904,19 +910,17 @@
         
         [alertController addAction:okAction];
         [[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:alertController animated:YES completion:nil];
-        return;
 #endif
     }
 }
 
-- (void)uploadURLSession:(NSString *)fileName serverUrl:(NSString *)serverUrl sessionID:(NSString*)sessionID session:(NSString *)session taskStatus:(NSInteger)taskStatus assetLocalIdentifier:(NSString *)assetLocalIdentifier selector:(NSString *)selector
+- (void)uploadURLSessionMetadata:(tableMetadata *)metadata serverUrl:(NSString *)serverUrl sessionID:(NSString*)sessionID taskStatus:(NSInteger)taskStatus assetLocalIdentifier:(NSString *)assetLocalIdentifier selector:(NSString *)selector
 {
     NSURL *url;
     NSMutableURLRequest *request;
     PHAsset *asset;
-
     
-    NSString *fileNamePath = [[NSString stringWithFormat:@"%@/%@", serverUrl, fileName] encodeString:NSUTF8StringEncoding];
+    NSString *fileNamePath = [[NSString stringWithFormat:@"%@/%@", serverUrl, metadata.fileName] encodeString:NSUTF8StringEncoding];
         
     url = [NSURL URLWithString:fileNamePath];
     request = [NSMutableURLRequest requestWithURL:url];
@@ -940,7 +944,7 @@
     // Rename with the SessionID
     NSString *fileNameForUpload = sessionID;
     
-    [[NSFileManager defaultManager] moveItemAtPath:[NSString stringWithFormat:@"%@/%@", _directoryUser, fileName] toPath:[NSString stringWithFormat:@"%@/%@", _directoryUser, fileNameForUpload] error:nil];
+    [[NSFileManager defaultManager] moveItemAtPath:[NSString stringWithFormat:@"%@/%@", _directoryUser, metadata.fileName] toPath:[NSString stringWithFormat:@"%@/%@", _directoryUser, fileNameForUpload] error:nil];
     
     // file NOT exists
     if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/%@", _directoryUser, fileNameForUpload]] == NO) {
@@ -949,7 +953,7 @@
         [[NCManageDatabase sharedInstance] deleteMetadataWithPredicate:[NSPredicate predicateWithFormat:@"sessionID = %@ AND account = %@", sessionID, _activeAccount] clearDateReadDirectoryID:nil];
         
         // Error for uploadFileFailure
-        [[self getDelegate:sessionID] uploadFileSuccessFailure:fileName fileID:@"" assetLocalIdentifier:assetLocalIdentifier serverUrl:serverUrl selector:selector selectorPost:@"" errorMessage:NSLocalizedString(@"_file_not_present_", nil) errorCode:404];
+        [[self getDelegate:sessionID] uploadFileSuccessFailure:metadata.fileName fileID:@"" assetLocalIdentifier:assetLocalIdentifier serverUrl:serverUrl selector:selector selectorPost:@"" errorMessage:NSLocalizedString(@"_file_not_present_", nil) errorCode:404];
         
         return;
     }
@@ -957,70 +961,71 @@
     NSURLSession *sessionUpload;
     
     // NSURLSession
-    if ([session isEqualToString:k_upload_session]) sessionUpload = [self sessionUpload];
-    else if ([session isEqualToString:k_upload_session_foreground]) sessionUpload = [self sessionUploadForeground];
-    else if ([session isEqualToString:k_upload_session_wwan]) sessionUpload = [self sessionWWanUpload];
+    if ([metadata.session isEqualToString:k_upload_session]) sessionUpload = [self sessionUpload];
+    else if ([metadata.session isEqualToString:k_upload_session_wwan]) sessionUpload = [self sessionWWanUpload];
+    else if ([metadata.session isEqualToString:k_upload_session_foreground]) sessionUpload = [self sessionUploadForeground];
 
     NSURLSessionUploadTask *uploadTask = [sessionUpload uploadTaskWithRequest:request fromFile:[NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@", _directoryUser, fileNameForUpload]]];
     
     // Error
     if (uploadTask == nil) {
         
-        [[NCManageDatabase sharedInstance] addActivityClient:fileName fileID:@"" action:k_activityDebugActionUpload selector:selector note:@"Serious internal error uploadTask not available" type:k_activityTypeFailure verbose:k_activityVerboseHigh activeUrl:_activeUrl];
-        [[NCManageDatabase sharedInstance] setMetadataSession:session sessionError:@"Serious internal error uploadTask not available"  sessionSelector:nil sessionSelectorPost:nil sessionTaskIdentifier:k_taskIdentifierError predicate:[NSPredicate predicateWithFormat:@"sessionID = %@ AND account = %@", sessionID, _activeAccount]];
-        [[NCManageDatabase sharedInstance] deleteQueueUploadWithAssetLocalIdentifier:assetLocalIdentifier selector:selector];
-        [[self getDelegate:sessionID] uploadFileSuccessFailure:fileName fileID:@"" assetLocalIdentifier:assetLocalIdentifier serverUrl:serverUrl selector:selector selectorPost:@"" errorMessage:@"Serious internal error uploadTask not available" errorCode:k_CCErrorInternalError];
+        NSString *messageError = @"Serious internal error uploadTask not available";
+        [[NCManageDatabase sharedInstance] setMetadataSession:metadata.session sessionError:messageError sessionSelector:nil sessionSelectorPost:nil sessionTaskIdentifier:k_taskIdentifierError predicate:[NSPredicate predicateWithFormat:@"sessionID = %@ AND account = %@", sessionID, _activeAccount]];
+        [[self getDelegate:sessionID] uploadFileSuccessFailure:metadata.fileNameView fileID:@"" assetLocalIdentifier:assetLocalIdentifier serverUrl:serverUrl selector:selector selectorPost:@"" errorMessage:messageError errorCode:k_CCErrorInternalError];
         
     } else {
         
-        // E2E *** IS ENCRYPTED ---> CREATE SEND METADATA ***
-        if ([CCUtility isFolderEncrypted:serverUrl account:_activeAccount]) {
+        // E2EE : CREATE AND SEND METADATA
+        if ([CCUtility isFolderEncrypted:serverUrl account:_activeAccount] && [CCUtility isEndToEndEnabled:_activeAccount]) {
             
             dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
                 
                 // Send Metadata
-                NSError *error = [self SendEndToEndMetadataOnServerUrl:serverUrl];
-                if (error == nil) {
-                        
-                    [[NCManageDatabase sharedInstance] setMetadataSession:session sessionError:@"" sessionSelector:nil sessionSelectorPost:nil sessionTaskIdentifier:uploadTask.taskIdentifier predicate:[NSPredicate predicateWithFormat:@"sessionID = %@ AND account = %@", sessionID, _activeAccount]];
-                        
-                    // Manage uploadTask cancel,suspend,resume
-                    if (taskStatus == k_taskStatusCancel) [uploadTask cancel];
-                    else if (taskStatus == k_taskStatusSuspend) [uploadTask suspend];
-                    else if (taskStatus == k_taskStatusResume) [uploadTask resume];
-
-                    NSLog(@"[LOG] Upload file %@ TaskIdentifier %lu", fileName, (unsigned long)uploadTask.taskIdentifier);
+                NSString *token;
+               
+                NSError *error = [[NCNetworkingSync sharedManager] sendEndToEndMetadataOnServerUrl:serverUrl account:_activeAccount user:_activeUser userID:_activeUserID password:_activePassword url:_activeUrl fileNameRename:nil fileNameNewRename:nil token:&token];
+                
+                dispatch_async(dispatch_get_main_queue(), ^{
 
-                } else {
+                    if (error) {
                     
-                    NSString *message = [NSString stringWithFormat:@"%@ %d", error.localizedDescription, (int)error.code];
-                    [[NCManageDatabase sharedInstance] addActivityClient:fileName fileID:assetLocalIdentifier action:k_activityDebugActionUpload selector:selector note:message type:k_activityTypeFailure verbose:k_activityVerboseHigh activeUrl:_activeUrl];
-                    [[NCManageDatabase sharedInstance] setMetadataSession:session sessionError:message sessionSelector:nil sessionSelectorPost:nil sessionTaskIdentifier:k_taskIdentifierError predicate:[NSPredicate predicateWithFormat:@"sessionID = %@ AND account = %@", sessionID, _activeAccount]];
-                            
-                    [uploadTask cancel];
-                }
-                
-#ifndef EXTENSION
-                // Next tableQueueUpload
-                AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
+                        [uploadTask cancel];
 
-                [appDelegate performSelectorOnMainThread:@selector(loadAutoDownloadUpload:) withObject:[NSNumber numberWithInt:k_maxConcurrentOperationDownloadUpload] waitUntilDone:NO];
-#endif
+                        NSString *messageError = [NSString stringWithFormat:@"%@ (%d)", error.localizedDescription, (int)error.code];
+                        [[NCManageDatabase sharedInstance] setMetadataSession:metadata.session sessionError:messageError sessionSelector:nil sessionSelectorPost:nil sessionTaskIdentifier:k_taskIdentifierError predicate:[NSPredicate predicateWithFormat:@"sessionID = %@ AND account = %@", sessionID, _activeAccount]];
+                        [[self getDelegate:sessionID] uploadFileSuccessFailure:metadata.fileNameView fileID:@"" assetLocalIdentifier:assetLocalIdentifier serverUrl:serverUrl selector:selector selectorPost:@"" errorMessage:messageError errorCode:k_CCErrorInternalError];
+                        
+                    } else {
+                    
+                        // *** E2EE ***
+                        [[NCManageDatabase sharedInstance] setMetadataSession:metadata.session sessionError:@"" sessionSelector:nil sessionSelectorPost:nil sessionTaskIdentifier:uploadTask.taskIdentifier predicate:[NSPredicate predicateWithFormat:@"sessionID = %@ AND account = %@", sessionID, _activeAccount]];
+                        
+                        // Manage uploadTask cancel,suspend,resume
+                        if (taskStatus == k_taskStatusCancel) [uploadTask cancel];
+                        else if (taskStatus == k_taskStatusSuspend) [uploadTask suspend];
+                        else if (taskStatus == k_taskStatusResume) [uploadTask resume];
+                        
+                        NSLog(@"[LOG] Upload file %@ TaskIdentifier %lu", metadata.fileName, (unsigned long)uploadTask.taskIdentifier);
+                        
+                        // refresh main
+                        if ([self.delegate respondsToSelector:@selector(reloadDatasource:)])
+                            [self.delegate reloadDatasource:serverUrl];
+                    }
+                });
             });
             
          } else {
     
              // *** PLAIN ***
-             
-             [[NCManageDatabase sharedInstance] setMetadataSession:session sessionError:@"" sessionSelector:nil sessionSelectorPost:nil sessionTaskIdentifier:uploadTask.taskIdentifier predicate:[NSPredicate predicateWithFormat:@"sessionID = %@ AND account = %@", sessionID, _activeAccount]];
+             [[NCManageDatabase sharedInstance] setMetadataSession:metadata.session sessionError:@"" sessionSelector:nil sessionSelectorPost:nil sessionTaskIdentifier:uploadTask.taskIdentifier predicate:[NSPredicate predicateWithFormat:@"sessionID = %@ AND account = %@", sessionID, _activeAccount]];
              
              // OK remove record on tableQueueUpload
              [[NCManageDatabase sharedInstance] deleteQueueUploadWithAssetLocalIdentifier:assetLocalIdentifier selector:selector];
+             
 #ifndef EXTENSION
              // Next tableQueueUpload
-             AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
-
-             [appDelegate performSelectorOnMainThread:@selector(loadAutoDownloadUpload:) withObject:[NSNumber numberWithInt:k_maxConcurrentOperationDownloadUpload] waitUntilDone:NO];
+             [(AppDelegate *)[[UIApplication sharedApplication] delegate] performSelectorOnMainThread:@selector(loadAutoDownloadUpload:) withObject:[NSNumber numberWithInt:k_maxConcurrentOperationDownloadUpload] waitUntilDone:NO];
 #endif
              
              // Manage uploadTask cancel,suspend,resume
@@ -1028,18 +1033,17 @@
              else if (taskStatus == k_taskStatusSuspend) [uploadTask suspend];
              else if (taskStatus == k_taskStatusResume) [uploadTask resume];
              
-             NSLog(@"[LOG] Upload file %@ TaskIdentifier %lu", fileName, (unsigned long)uploadTask.taskIdentifier);
+             NSLog(@"[LOG] Upload file %@ TaskIdentifier %lu", metadata.fileName, (unsigned long)uploadTask.taskIdentifier);
+             
+             // refresh main
+             if ([self.delegate respondsToSelector:@selector(reloadDatasource:)])
+                 [self.delegate reloadDatasource:serverUrl];
          }
     }
 
-    // refresh main
-    if ([self.delegate respondsToSelector:@selector(reloadDatasource:)])
-        [self.delegate reloadDatasource:serverUrl];
-        
 #ifndef EXTENSION
     [(AppDelegate *)[[UIApplication sharedApplication] delegate] updateApplicationIconBadgeNumber];
 #endif
-    
 }
 
 - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
@@ -1110,6 +1114,7 @@
         metadata.fileID = fileID;
         metadata.etag = etag;
         metadata.date = date;
+        metadata.e2eEncrypted = false;
         metadata.sessionTaskIdentifier = k_taskIdentifierDone;
         metadata = [[NCManageDatabase sharedInstance] addMetadata:metadata];
         
@@ -1154,7 +1159,7 @@
             [CCGraphics createNewImageFrom:metadata.fileID directoryUser:_directoryUser fileNameTo:metadata.fileID extension:[metadata.fileNameView pathExtension] size:@"m" imageForUpload:NO typeFile:metadata.typeFile writePreview:YES optimizedFileName:[CCUtility getOptimizedPhoto]];
         
         // Optimization
-        if ([CCUtility getUploadAndRemovePhoto] || [metadata.sessionSelectorPost isEqualToString:selectorUploadRemovePhoto])
+        if (([CCUtility getUploadAndRemovePhoto] || [metadata.sessionSelectorPost isEqualToString:selectorUploadRemovePhoto]) && [metadata.typeFile isEqualToString:k_metadataTypeFile_document] == NO)
             [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@/%@", _directoryUser, metadata.fileID] error:nil];
         
         // Copy photo or video in the photo album for auto upload
@@ -1174,28 +1179,22 @@
         }
         
         // Actvity
-        [[NCManageDatabase sharedInstance] addActivityClient:fileName fileID:fileID action:k_activityDebugActionUpload selector:metadata.sessionSelector note:serverUrl type:k_activityTypeSuccess verbose:k_activityVerboseDefault activeUrl:_activeUrl];
+        [[NCManageDatabase sharedInstance] addActivityClient:metadata.fileNameView fileID:fileID action:k_activityDebugActionUpload selector:metadata.sessionSelector note:serverUrl type:k_activityTypeSuccess verbose:k_activityVerboseDefault activeUrl:_activeUrl];
     }
     
-    // E2E *** IS ENCRYPTED ---> UNLOCK ***
-    if ([CCUtility isFolderEncrypted:serverUrl account:_activeAccount]) {
+    // E2EE : UNLOCK
+    if ([CCUtility isFolderEncrypted:serverUrl account:_activeAccount] && [CCUtility isEndToEndEnabled:_activeAccount]) {
         
-        // OK remove record on tableQueueUpload [NEXT UPLOAD]
-        [[NCManageDatabase sharedInstance] deleteQueueUploadWithAssetLocalIdentifier:metadata.assetLocalIdentifier selector:metadata.sessionSelector];
-
         dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
             
             tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", _activeAccount, serverUrl]];
-            if (directory) {
+            if (directory.e2eTokenLock.length > 0 && directory.e2eTokenLock) {
                 NSError *error = [[NCNetworkingSync sharedManager] unlockEndToEndFolderEncrypted:_activeUser userID:_activeUserID password:_activePassword url:_activeUrl fileID:directory.fileID token:directory.e2eTokenLock];
                 if (error) {
 #ifndef EXTENSION
-                    NSString *message = [NSString stringWithFormat:@"%@ %d", error.localizedDescription, (int)error.code];
-                    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Error folder unlock", nil) message:message preferredStyle:UIAlertControllerStyleAlert];
-                    UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {}];
-                
-                    [alertController addAction:okAction];
-                    [[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:alertController animated:YES completion:nil];
+                    dispatch_async(dispatch_get_main_queue(), ^{
+                        [(AppDelegate *)[[UIApplication sharedApplication] delegate] messageNotification:@"_error_e2ee_" description:error.localizedDescription visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:error.code];
+                    });
 #endif
                 }
             }
@@ -1205,232 +1204,6 @@
     [[self getDelegate:sessionID] uploadFileSuccessFailure:metadata.fileName fileID:metadata.fileID assetLocalIdentifier:metadata.assetLocalIdentifier serverUrl:serverUrl selector:metadata.sessionSelector selectorPost:metadata.sessionSelectorPost errorMessage:errorMessage errorCode:errorCode];
 }
 
-#pragma --------------------------------------------------------------------------------------------
-#pragma mark =====  Download Verify =====
-#pragma --------------------------------------------------------------------------------------------
-
-- (void)verifyDownloadInProgress
-{
-    NSArray *dataSourceDownload = [[NCManageDatabase sharedInstance] getTableMetadataDownload];
-    NSArray *dataSourceDownloadWWan = [[NCManageDatabase sharedInstance] getTableMetadataDownloadWWan];
-    
-    NSMutableArray *dataSource = [NSMutableArray new];
-    
-    [dataSource addObjectsFromArray:dataSourceDownload];
-    [dataSource addObjectsFromArray:dataSourceDownloadWWan];
-    
-    NSLog(@"[LOG] Verify download file in progress n. %lu", (unsigned long)[dataSource count]);
-    
-    for (tableMetadata *metadata in dataSource) {
-                
-        NSURLSession *session = [self getSessionfromSessionDescription:metadata.session];
-        
-        [session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
-            
-            dispatch_async(dispatch_get_main_queue(), ^{
-            
-                BOOL findTask = NO;
-                BOOL findTaskPlist = NO;
-            
-                for (NSURLSessionDownloadTask *downloadTask in downloadTasks) {
-                
-                    NSLog(@"[LOG] Find metadata Tasks [%li] = [%lu] state : %lu", (long)metadata.sessionTaskIdentifier ,(unsigned long)downloadTask.taskIdentifier, (unsigned long)[downloadTask state]);
-                
-                    if (metadata.sessionTaskIdentifier == downloadTask.taskIdentifier) findTask = YES;
-                
-                    if (findTask == YES || findTaskPlist == YES) break; // trovati, download ancora in corso
-                }
-            
-                // DATA
-                if (findTask == NO && metadata.sessionTaskIdentifier >= 0) {
-                
-                    NSLog(@"[LOG] NOT Find metadata Task [%li] fileID : %@ - filename : %@", (long)metadata.sessionTaskIdentifier, metadata.fileID, metadata.fileName);
-                
-                    [[NCManageDatabase sharedInstance] setMetadataSession:nil sessionError:@"Serious internal error download Task Not Found]" sessionSelector:nil sessionSelectorPost:nil sessionTaskIdentifier:k_taskIdentifierError predicate:[NSPredicate predicateWithFormat:@"fileID = %@ ", metadata.fileID]];
-                
-                    if ([self.delegate respondsToSelector:@selector(reloadDatasource:)])
-                        [self.delegate reloadDatasource:[[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID]];
-                }
-            });
-        }];
-    }
-}
-
-- (void)verifyDownloadInError:(id)delegate
-{
-    NSMutableSet *serversUrl = [NSMutableSet new];
-    
-    NSArray *metadatas = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND session CONTAINS 'download' AND sessionTaskIdentifier = %i", _activeAccount, k_taskIdentifierError] sorted:nil ascending:NO];
-    
-    NSLog(@"[LOG] Verify re download in error n. %lu", (unsigned long)[metadatas count]);
-    
-    for (tableMetadata *metadata in metadatas) {
-        
-        NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
-        if (!serverUrl) continue;
-        
-        if (metadata.sessionTaskIdentifier == k_taskIdentifierError)
-            [self downloadFile:metadata.fileName fileID:metadata.fileID serverUrl:serverUrl selector:metadata.sessionSelector selectorPost:nil session:k_download_session taskStatus: k_taskStatusResume delegate:delegate];
-        
-        [serversUrl addObject:serverUrl];
-        
-        NSLog(@"[LOG] Re download file : %@ [%li]", metadata.fileName, (long)metadata.sessionTaskIdentifier);
-    }
-    
-    for (NSString *serverUrl in serversUrl) {
-        if ([self.delegate respondsToSelector:@selector(reloadDatasource:)])
-            [self.delegate reloadDatasource:serverUrl];
-    }
-}
-
-#pragma --------------------------------------------------------------------------------------------
-#pragma mark =====  Upload Verify =====
-#pragma --------------------------------------------------------------------------------------------
-
-- (void)verifyUploadInProgress
-{
-    NSArray *dataSourceUpload = [[NCManageDatabase sharedInstance] getTableMetadataUpload];
-    NSArray *dataSourceUploadWWan = [[NCManageDatabase sharedInstance] getTableMetadataUploadWWan];
-    
-    NSMutableArray *dataSource = [[NSMutableArray alloc] init];
-    
-    [dataSource addObjectsFromArray:dataSourceUpload];
-    [dataSource addObjectsFromArray:dataSourceUploadWWan];
-    
-    NSLog(@"[LOG] Verify upload file in progress n. %lu", (unsigned long)[dataSource count]);
-    
-    for (tableMetadata *metadata in dataSource) {
-        
-        __block NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
-        if (!serverUrl) continue;
-        
-        NSURLSession *session = [self getSessionfromSessionDescription:metadata.session];
-                
-        [session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
-            
-            BOOL findTask = NO;
-            
-            // cerchiamo la corrispondenza dei task
-            for (NSURLSessionUploadTask *uploadTask in uploadTasks) {
-                
-                NSLog(@"[LOG] Find metadata Tasks [%li] = [%lu] state : %lu", (long)metadata.sessionTaskIdentifier, (unsigned long)uploadTask.taskIdentifier, (unsigned long)[uploadTask state]);
-                
-                if (metadata.sessionTaskIdentifier == uploadTask.taskIdentifier) findTask = YES;
-                
-                if (findTask == YES) break;
-            }
-            
-            // se non c'è il relativo uploadTask.taskIdentifier allora chiediamolo
-            if (findTask == NO) {
-                
-                NSLog(@"[LOG] Call ReadFileVerifyUpload because this file %@ is in progress but there is no task : [%li]", metadata.fileName, (long)metadata.sessionTaskIdentifier);
-                
-                if (metadata.sessionTaskIdentifier >= 0) [self readFileVerifyUpload:metadata.fileName serverUrl:serverUrl];
-            }
-        }];
-        
-        // Notification change session
-        NSArray *object = [[NSArray alloc] initWithObjects:session, metadata, nil];
-        [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:k_networkingSessionNotification object:object];
-    }
-}
-
-- (void)verifyUploadInErrorOrWait
-{
-    NSMutableSet *directoryIDs = [NSMutableSet new];
-    
-    NSArray *metadatas = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND session CONTAINS 'upload' AND (sessionTaskIdentifier = %i OR sessionTaskIdentifier = %i)", _activeAccount, k_taskIdentifierError, k_taskIdentifierWaitStart] sorted:nil ascending:NO];
-    
-    NSLog(@"[LOG] Verify re upload in error n. %lu", (unsigned long)[metadatas count]);
-    
-    for (tableMetadata *metadata in metadatas) {
-        
-        [self uploadFileMetadata:metadata taskStatus: k_taskStatusResume];
-        
-        [directoryIDs addObject:metadata.directoryID];
-        
-        NSLog(@"[LOG] Re upload file : %@", metadata.fileName);
-    }
-    
-    dispatch_async(dispatch_get_main_queue(), ^{
-        for (NSString *directoryID in directoryIDs)
-            if ([self.delegate respondsToSelector:@selector(reloadDatasource:)])
-                [self.delegate reloadDatasource:[[NCManageDatabase sharedInstance] getServerUrl:directoryID]];
-    });
-}
-
-- (void)readFileVerifyUpload:(NSString *)fileName serverUrl:(NSString *)serverUrl
-{
-#ifndef EXTENSION
-    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
-    
-    CCMetadataNet *metadataNet = [[CCMetadataNet alloc] initWithAccount:_activeAccount];
-    
-    metadataNet.action = actionReadFile;
-    metadataNet.fileName = fileName;
-    metadataNet.serverUrl = serverUrl;
-    metadataNet.selector = selectorReadFileVerifyUpload;
-
-    [appDelegate addNetworkingOperationQueue:appDelegate.netQueue delegate:self metadataNet:metadataNet];
-#else
-    NSLog(@"[LOG] Function not available for extension.");
-#endif
-}
-
-//
-// File exists : selectorReadFileVerifyUpload
-//
-- (void)readFileSuccess:(CCMetadataNet *)metadataNet metadata:(tableMetadata *)metadata
-{
-    NSString *fileName = metadataNet.fileName;
-    
-    NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:metadataNet.serverUrl];
-    if (!directoryID)
-        [self uploadFileSuccessFailure:metadata fileName:metadataNet.fileName fileID:metadata.fileID etag:metadata.etag date:metadata.date serverUrl:metadataNet.serverUrl errorCode:k_CCErrorFileUploadNotFound];
-    
-    tableMetadata *metadataTemp = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"fileName = %@ AND directoryID = %@ AND account = %@", fileName , directoryID, _activeAccount]];
-    
-    // is completed ?
-    if (metadataTemp.sessionTaskIdentifier == k_taskIdentifierDone) {
-        
-        [CCGraphics createNewImageFrom:metadata.fileID directoryUser:_directoryUser fileNameTo:metadata.fileID extension:[metadata.fileNameView pathExtension] size:@"m" imageForUpload:NO typeFile:metadata.typeFile writePreview:YES optimizedFileName:[CCUtility getOptimizedPhoto]];
-        
-        NSLog(@"[LOG] Verify read file success, but files already processed");
-        
-        dispatch_async(dispatch_get_main_queue(), ^{
-            if ([self.delegate respondsToSelector:@selector(reloadDatasource:)])
-                [self.delegate reloadDatasource:[[NCManageDatabase sharedInstance] getServerUrl:directoryID]];
-        });
-        
-    } else {
-        
-        [self uploadFileSuccessFailure:metadataTemp fileName:metadataNet.fileName fileID:metadata.fileID etag:metadata.etag date:metadata.date serverUrl:metadataNet.serverUrl errorCode:0];
-    }
-}
-
-//
-// File do not exists : selectorReadFileVerifyUpload
-//
-- (void)readFileFailure:(CCMetadataNet *)metadataNet message:(NSString *)message errorCode:(NSInteger)errorCode
-{
-    NSString *fileName = metadataNet.fileName;
-    
-    NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:metadataNet.serverUrl];
-    if (!directoryID) return;
-    
-    tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"fileName = %@ AND directoryID = %@ AND account = %@",fileName , directoryID, _activeAccount]];
-    
-    NSInteger error;
-    if (errorCode == kOCErrorServerPathNotFound)
-        error = k_CCErrorFileUploadNotFound;
-    else
-        error = errorCode;
-    
-    // fix CCNetworking.m line 1340 2.17.2 (00005)
-    if (metadata)
-        [self uploadFileSuccessFailure:metadata fileName:metadataNet.fileName fileID:metadata.fileID etag:metadata.etag date:metadata.date serverUrl:metadataNet.serverUrl errorCode:error];
-}
-
 #pragma --------------------------------------------------------------------------------------------
 #pragma mark =====  Utility =====
 #pragma --------------------------------------------------------------------------------------------
@@ -1467,22 +1240,39 @@
 }
 
 #pragma --------------------------------------------------------------------------------------------
-#pragma mark =====  End To End Encryption =====
+#pragma mark ===== E2EE End To End Encryption =====
 #pragma --------------------------------------------------------------------------------------------
-// E2E
+// E2EE
 
-- (BOOL)newEndToEndFile:(NSString *)fileName fileNameIdentifier:(NSString *)fileNameIdentifier serverUrl:(NSString *)serverUrl
+- (void)encryptedE2EFile:(NSString *)fileName serverUrl:(NSString *)serverUrl directoryID:(NSString *)directoryID account:(NSString *)account user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url errorMessage:(NSString * __autoreleasing *)errorMessage fileNameIdentifier:(NSString **)fileNameIdentifier e2eMetadata:(NSString * __autoreleasing *)e2eMetadata
 {
+    __block NSError *error;
     NSString *key;
     NSString *initializationVector;
     NSString *authenticationTag;
     NSString *metadataKey;
     NSInteger metadataKeyIndex;
     
-    BOOL result = [[NCEndToEndEncryption sharedManager] encryptFileName:fileName fileNameIdentifier:fileNameIdentifier directoryUser: _directoryUser key:&key initializationVector:&initializationVector authenticationTag:&authenticationTag];
+    // Verify File Size
+    NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[NSString stringWithFormat:@"%@/%@", _directoryUser, fileName] error:&error];
+    NSNumber *fileSizeNumber = [fileAttributes objectForKey:NSFileSize];
+    long long fileSize = [fileSizeNumber longLongValue];
+        
+    if (fileSize > k_max_filesize_E2E) {
+        // Error for uploadFileFailure
+        *errorMessage = @"E2E Error file too big";
+        return;
+    }
+        
+    // if exists overwrite file else create a new encrypted filename
+    tableMetadata *overwriteMetadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND directoryID = %@ AND fileNameView = %@", _activeAccount, directoryID, fileName]];
+    if (overwriteMetadata)
+        *fileNameIdentifier = overwriteMetadata.fileName;
+    else
+        *fileNameIdentifier = [CCUtility generateRandomIdentifier];
     
     // Write to DB
-    if (result) {
+    if ([[NCEndToEndEncryption sharedManager] encryptFileName:fileName fileNameIdentifier:*fileNameIdentifier directoryUser: _directoryUser key:&key initializationVector:&initializationVector authenticationTag:&authenticationTag]) {
         
         tableE2eEncryption *object = [[NCManageDatabase sharedInstance] getE2eEncryptionWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", _activeAccount, serverUrl]];
         if (object) {
@@ -1498,7 +1288,7 @@
         addObject.account = _activeAccount;
         addObject.authenticationTag = authenticationTag;
         addObject.fileName = fileName;
-        addObject.fileNameIdentifier = fileNameIdentifier;
+        addObject.fileNameIdentifier = *fileNameIdentifier;
         addObject.fileNamePath = [CCUtility returnFileNamePathFromFileName:fileName serverUrl:serverUrl activeUrl:_activeUrl];
         addObject.key = key;
         addObject.initializationVector = initializationVector;
@@ -1516,78 +1306,26 @@
         addObject.serverUrl = serverUrl;
         addObject.version = [[NCManageDatabase sharedInstance] getEndToEndEncryptionVersion];
         
-        result = [[NCManageDatabase sharedInstance] addE2eEncryption:addObject];
-    }
-    
-    return result;
-}
-
-- (NSError *)SendEndToEndMetadataOnServerUrl:(NSString *)serverUrl
-{
-    tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", _activeAccount, serverUrl]];
-    
-    NSString *e2eTokenLock;
-    __block BOOL updateMetadata = false;
-    __block NSError *e2eError;
-    
-    // Enabled E2E
-    if ([CCUtility isEndToEndEnabled:_activeAccount] == NO)
-        return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:@"Serius internal error E2E Encryption not enabled" forKey:NSLocalizedDescriptionKey]];
-    
-    // exists a metadata on serverUrl ?
-    [[NCNetworkingSync sharedManager] getEndToEndMetadataWithUser:_activeUser userID:_activeUserID password:_activePassword url:_activeUrl fileID:directory.fileID success:^(NSString *encryptedMetadata) {
+        // Get the last metadata
+        NSString *metadata;
+        tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", account, serverUrl]];
 
-        if ([[NCEndToEndMetadata sharedInstance] decoderMetadata:encryptedMetadata privateKey:[CCUtility getEndToEndPrivateKey:_activeAccount] serverUrl:serverUrl account:_activeAccount url:_activeUrl] == false)
-            e2eError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:@"Serious internal error in decoding metadata" forKey:NSLocalizedDescriptionKey]];
-        updateMetadata = YES;
+        error = [[NCNetworkingSync sharedManager] getEndToEndMetadata:user userID:userID password:password url:url fileID:directory.fileID metadata:&metadata];
+        if (error == nil) {
+            if ([[NCEndToEndMetadata sharedInstance] decoderMetadata:metadata privateKey:[CCUtility getEndToEndPrivateKey:account] serverUrl:serverUrl account:account url:url] == false) {
+                *errorMessage = NSLocalizedString(@"_e2e_error_decode_metadata_", nil);
+                return;
+            }
+        }
+        *e2eMetadata = metadata;
         
-    } failure:^(NSError *error) {
+        // write new record e2ee
+        if([[NCManageDatabase sharedInstance] addE2eEncryption:addObject] == NO)
+            *errorMessage = NSLocalizedString(@"_e2e_error_create_encrypted_", nil);
         
-        e2eError = error;
-    }];
-    if (e2eError.code != 404 && e2eError != nil) {
-        return e2eError;
-    }
-
-    NSArray *tableE2eEncryption = [[NCManageDatabase sharedInstance] getE2eEncryptionsWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", _activeAccount, serverUrl]];
-    if (!tableE2eEncryption)
-         return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:@"Serius internal error tableE2eEncryption, records not found" forKey:NSLocalizedDescriptionKey]];
-    
-    NSString *e2eMetadataJSON = [[NCEndToEndMetadata sharedInstance] encoderMetadata:tableE2eEncryption privateKey:[CCUtility getEndToEndPrivateKey:_activeAccount] serverUrl:serverUrl];
-    if (!e2eMetadataJSON)
-        return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:@"Serious internal error in encoding metadata" forKey:NSLocalizedDescriptionKey]];
-    
-    // send Metadata
-    if (updateMetadata) {
-        e2eError = [[NCNetworkingSync sharedManager] updateEndToEndMetadata:_activeUser userID:_activeUserID password:_activePassword url:_activeUrl fileID:directory.fileID metadata:e2eMetadataJSON token:&e2eTokenLock];
     } else {
-        e2eError = [[NCNetworkingSync sharedManager] storeEndToEndMetadata:_activeUser userID:_activeUserID password:_activePassword url:_activeUrl fileID:directory.fileID metadata:e2eMetadataJSON token:&e2eTokenLock];
-    }
-    
-    return e2eError;
-}
-
-- (NSError *)rebuildAndSendEndToEndMetadataOnServerUrl:(NSString *)serverUrl
-{
-    NSString *e2eTokenLock;
-    NSError *error;
-    NSString *e2eMetadataJSON;
-
-    tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", _activeAccount, serverUrl]];
-    if (directory.e2eEncrypted == NO)
-        return nil;
-    
-    NSArray *tableE2eEncryption = [[NCManageDatabase sharedInstance] getE2eEncryptionsWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", _activeAccount, serverUrl]];
-    if (tableE2eEncryption) {
-
-        e2eMetadataJSON = [[NCEndToEndMetadata sharedInstance] encoderMetadata:tableE2eEncryption privateKey:[CCUtility getEndToEndPrivateKey:_activeAccount] serverUrl:serverUrl];
-        if (!e2eMetadataJSON)
-            return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:@"Serious internal error in encoding metadata" forKey:NSLocalizedDescriptionKey]];
+        *errorMessage = NSLocalizedString(@"_e2e_error_create_encrypted_", nil);
     }
-    
-    error = [[NCNetworkingSync sharedManager] rebuildEndToEndMetadata:_activeUser userID:_activeUserID password:_activePassword url:_activeUrl fileID:directory.fileID metadata:e2eMetadataJSON token:&e2eTokenLock];
-    
-    return error;
 }
 
 @end
@@ -1634,7 +1372,6 @@
     [metadataNet setDirectory: self.directory];
     [metadataNet setDirectoryID: self.directoryID];
     [metadataNet setDirectoryIDTo: self.directoryIDTo];
-    [metadataNet setE2eEncrypted: self.e2eEncrypted];
     [metadataNet setEncryptedMetadata: self.encryptedMetadata];
     [metadataNet setErrorCode: self.errorCode];
     [metadataNet setErrorRetry: self.errorRetry];
@@ -1661,7 +1398,6 @@
     [metadataNet setSharePermission: self.sharePermission];
     [metadataNet setSize: self.size];
     [metadataNet setTaskStatus: self.taskStatus];
-    [metadataNet setToken: self.token];
     
     return metadataNet;
 }

+ 8 - 2
iOSClient/Networking/NCNetworkingSync.h

@@ -23,10 +23,16 @@
 
 - (NSError *)markEndToEndFolderEncrypted:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID serverUrl:(NSString *)serverUrl token:(NSString  **)token;
 - (NSError *)deletemarkEndToEndFolderEncrypted:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID serverUrl:(NSString *)serverUrl token:(NSString  **)token;
-- (void)getEndToEndMetadataWithUser:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID success:(void (^)(NSString *encryptedMetadata))success failure:(void (^)(NSError *error))failure;
+
+- (NSError *)getEndToEndMetadata:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID metadata:(NSString **)metadata;
+- (NSError *)deleteEndToEndMetadata:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID;
 - (NSError *)storeEndToEndMetadata:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID metadata:(NSString *)metadata token:(NSString  **)token;
 - (NSError *)updateEndToEndMetadata:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID metadata:(NSString *)metadata token:(NSString  **)token;
-- (NSError *)rebuildEndToEndMetadata:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID metadata:(NSString *)metadata token:(NSString  **)token;
+
+- (NSError *)lockEndToEndFolderEncrypted:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID token:(NSString **)token;
 - (NSError *)unlockEndToEndFolderEncrypted:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID token:(NSString  *)token;
 
+- (NSError *)sendEndToEndMetadataOnServerUrl:(NSString *)serverUrl account:(NSString *)account user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileNameRename:(NSString *)fileName fileNameNewRename:(NSString *)fileNameNew token:(NSString **)token;
+- (NSError *)rebuildAndSendEndToEndMetadataOnServerUrl:(NSString *)serverUrl account:(NSString *)account user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url token:(NSString  **)token;
+
 @end

+ 140 - 84
iOSClient/Networking/NCNetworkingSync.m

@@ -47,7 +47,7 @@
     } failureRequest:^(NSURLResponse *response, NSString *redirectedServer, NSError *error) {
         
         NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
-        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:httpResponse.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Upload file error %d", (int)httpResponse.statusCode] forKey:NSLocalizedDescriptionKey]];
+        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:httpResponse.statusCode userInfo:[NSDictionary dictionaryWithObject:@"_error_upload_file_" forKey:NSLocalizedDescriptionKey]];
         dispatch_semaphore_signal(semaphore);
 
     } failureBeforeRequest:^(NSError *error) {
@@ -79,7 +79,7 @@
         
     } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
         
-        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Check server error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]];
+        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:@"_error_check_server_" forKey:NSLocalizedDescriptionKey]];
         dispatch_semaphore_signal(semaphore);
     }];
     
@@ -108,7 +108,7 @@
         
     } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
         
-        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Read file error %d", (int) response.statusCode] forKey:NSLocalizedDescriptionKey]];
+        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:response.description forKey:NSLocalizedDescriptionKey]];
         dispatch_semaphore_signal(semaphore);
     }];
     
@@ -138,7 +138,7 @@
 
     } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *token, NSString *redirectedServer) {
 
-        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Read folder error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]];
+        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:response.description forKey:NSLocalizedDescriptionKey]];
         dispatch_semaphore_signal(semaphore);
 
     }];
@@ -174,12 +174,12 @@
             
         } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
             
-            returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Read folder error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]];
+            returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:response.description forKey:NSLocalizedDescriptionKey]];
             dispatch_semaphore_signal(semaphore);
             
         } errorBeforeRequest:^(NSError *error) {
             
-            returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Read folder error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]];
+            returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:response.description forKey:NSLocalizedDescriptionKey]];
             dispatch_semaphore_signal(semaphore);
 
         }];
@@ -191,9 +191,9 @@
     return returnError;
 }
 #pragma --------------------------------------------------------------------------------------------
-#pragma mark ===== End-to-End Encryption =====
+#pragma mark ===== E2EE End-to-End Encryption =====
 #pragma --------------------------------------------------------------------------------------------
-// E2E
+// E2EE
 
 - (NSError *)markEndToEndFolderEncrypted:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID serverUrl:(NSString *)serverUrl token:(NSString  **)token
 {
@@ -212,7 +212,7 @@
     
         if (items.count > 1) {
             
-            returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:999 userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"The directory is not empty", nil) forKey:NSLocalizedDescriptionKey]];
+            returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:999 userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_directory_not_empty_", nil) forKey:NSLocalizedDescriptionKey]];
             dispatch_semaphore_signal(semaphore);
             return;
         }
@@ -225,9 +225,9 @@
 
             // REMOVE METADATA
             [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-                NSLog(@"Found metadata and delete");
+                NSLog(@"[LOG] Found metadata and delete");
             } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
-                NSLog(@"%@", [NSString stringWithFormat:@"Remove metadata error %d", (int)response.statusCode]);
+                NSLog(@"[LOG] %@", [NSString stringWithFormat:@"Remove metadata error %d", (int)response.statusCode]);
             }];
         
             // MARK
@@ -242,25 +242,25 @@
                 
                 } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
                 
-                    returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Unlock folder error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]];
+                    returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_unlock_", nil) forKey:NSLocalizedDescriptionKey]];
                     dispatch_semaphore_signal(semaphore);
                 }];
             
             } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
             
-                returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Mark folder as encrypted error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]];
+                returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_mark_folder_", nil) forKey:NSLocalizedDescriptionKey]];
                 dispatch_semaphore_signal(semaphore);
             }];
         
         } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
         
-            returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Lock folder error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]];
+            returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_lock_", nil) forKey:NSLocalizedDescriptionKey]];
             dispatch_semaphore_signal(semaphore);
         }];
         
     } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *token, NSString *redirectedServer) {
         
-        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Read folder error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]];
+        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:response.description forKey:NSLocalizedDescriptionKey]];
         dispatch_semaphore_signal(semaphore);
         
     }];
@@ -289,7 +289,7 @@
         
         if (items.count > 1) {
             
-            returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:999 userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"The directory is not empty", nil) forKey:NSLocalizedDescriptionKey]];
+            returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:999 userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_directory_not_empty_", nil) forKey:NSLocalizedDescriptionKey]];
             dispatch_semaphore_signal(semaphore);
             return;
         }
@@ -302,9 +302,9 @@
         
             // DELETE METADATA
             [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-                NSLog(@"Found metadata and delete");
+                NSLog(@"[LOG] Found metadata and delete");
             } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
-                NSLog(@"%@", [NSString stringWithFormat:@"Remove metadata error %d", (int)response.statusCode]);
+                NSLog(@"[LOG] %@", [NSString stringWithFormat:@"Remove metadata error %d", (int)response.statusCode]);
             }];
         
             // DELETE MARK
@@ -319,26 +319,26 @@
                 
                 } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
                 
-                    returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Unlock folder error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]];
+                    returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_unlock_", nil) forKey:NSLocalizedDescriptionKey]];
                     dispatch_semaphore_signal(semaphore);
                 }];
             
             } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
             
-                returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Delete mark folder as encrypted error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]];
+                returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_delete_mark_folder_", nil) forKey:NSLocalizedDescriptionKey]];
                 dispatch_semaphore_signal(semaphore);
             }];
         
         
         } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
         
-            returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Lock folder error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]];
+            returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_lock_", nil) forKey:NSLocalizedDescriptionKey]];
             dispatch_semaphore_signal(semaphore);
         }];
     
     } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *token, NSString *redirectedServer) {
     
-        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Read folder error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]];
+        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:@"Read folder error" forKey:NSLocalizedDescriptionKey]];
         dispatch_semaphore_signal(semaphore);
     
     }];
@@ -350,28 +350,61 @@
     return returnError;
 }
 
-- (void)getEndToEndMetadataWithUser:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID success:(void (^)(NSString *encryptedMetadata))success failure:(void (^)(NSError *error))failure
+- (NSError *)getEndToEndMetadata:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID metadata:(NSString **)metadata
 {
     OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
     
+    __block NSError *returnError = nil;
+    __block NSString *returnMetadata = nil;
+    
     dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
-
+    
     [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
     [communication setUserAgent:[CCUtility getUserAgent]];
     
     [communication getEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *encryptedMetadata, NSString *redirectedServer) {
         
-        success(encryptedMetadata);
+        returnMetadata = encryptedMetadata;
+        dispatch_semaphore_signal(semaphore);
+        
+    } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
+        
+        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_get_metadata_", nil) forKey:NSLocalizedDescriptionKey]];
+        dispatch_semaphore_signal(semaphore);
+    }];
+    
+    while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
+        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
+    
+    *metadata = returnMetadata;
+    return returnError;
+}
+
+- (NSError *)deleteEndToEndMetadata:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID
+{
+    OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
+    
+    __block NSError *returnError = nil;
+    
+    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
+    
+    [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
+    [communication setUserAgent:[CCUtility getUserAgent]];
+    
+    [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
+        
         dispatch_semaphore_signal(semaphore);
         
     } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
         
-        failure([NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Get metadata error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]]);
+        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_delete_metadata_", nil) forKey:NSLocalizedDescriptionKey]];
         dispatch_semaphore_signal(semaphore);
     }];
     
     while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
         [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
+    
+    return returnError;
 }
 
 - (NSError *)storeEndToEndMetadata:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID metadata:(NSString *)metadata token:(NSString  **)token
@@ -399,13 +432,13 @@
             
         } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
             
-            returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Store metadata error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]];
+            returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_store_metadata_", nil) forKey:NSLocalizedDescriptionKey]];
             dispatch_semaphore_signal(semaphore);
         }];
         
     } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
         
-        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Lock folder error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]];
+        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_lock_", nil) forKey:NSLocalizedDescriptionKey]];
         dispatch_semaphore_signal(semaphore);
     }];
     
@@ -438,16 +471,16 @@
         [communication updateEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID encryptedMetadata:metadata token:returnToken onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *encryptedMetadata, NSString *redirectedServer) {
             
             dispatch_semaphore_signal(semaphore);
-
+            
         } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
             
-            returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Update metadata error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]];
+            returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_update_metadata_", nil) forKey:NSLocalizedDescriptionKey]];
             dispatch_semaphore_signal(semaphore);
         }];
         
     } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
         
-        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Lock folder error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]];
+        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_lock_", nil) forKey:NSLocalizedDescriptionKey]];
         dispatch_semaphore_signal(semaphore);
     }];
     
@@ -458,13 +491,13 @@
     return returnError;
 }
 
-- (NSError *)rebuildEndToEndMetadata:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID metadata:(NSString *)metadata token:(NSString  **)token
+- (NSError *)lockEndToEndFolderEncrypted:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID token:(NSString **)token
 {
     OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
     
     __block NSError *returnError = nil;
     __block NSString *returnToken = nil;
-    
+
     dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
     
     [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
@@ -473,67 +506,21 @@
     // LOCK
     [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:*token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
         
+        // Write DB token
         returnToken = token;
         [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithFileID:fileID token:returnToken];
-        
-        // DELETE METADATA
-        [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-            
-            if (metadata) {
-            
-                // STORE METADATA
-                [communication storeEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID encryptedMetadata:metadata onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *encryptedMetadata, NSString *redirectedServer) {
-                
-                    // UNLOCK
-                    [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:returnToken onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-                    
-                        returnToken = nil;
-                        [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithFileID:fileID token:@""];
-                        dispatch_semaphore_signal(semaphore);
-                    
-                    } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
-                    
-                        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Unlock folder error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]];
-                        dispatch_semaphore_signal(semaphore);
-                    }];
-                
-                } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
-                
-                    returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Store metadata error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]];
-                    dispatch_semaphore_signal(semaphore);
-                }];
-                
-            } else {
-                
-                // UNLOCK
-                [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:returnToken onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-                    
-                    returnToken = nil;
-                    [[NCManageDatabase sharedInstance] setDirectoryE2ETokenLockWithFileID:fileID token:@""];
-                    dispatch_semaphore_signal(semaphore);
-                    
-                } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
-                    
-                    returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Unlock folder error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]];
-                    dispatch_semaphore_signal(semaphore);
-                }];
-            }
-            
-        } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
-            
-            returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Update metadata error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]];
-            dispatch_semaphore_signal(semaphore);
-        }];
+        dispatch_semaphore_signal(semaphore);
         
     } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
         
-        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Lock folder error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]];
+        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_lock_", nil) forKey:NSLocalizedDescriptionKey]];
         dispatch_semaphore_signal(semaphore);
     }];
     
     while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
         [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
     
+    *token = returnToken;
     return returnError;
 }
 
@@ -557,7 +544,7 @@
         
     } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
         
-        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"Unlock folder error %d", (int)response.statusCode] forKey:NSLocalizedDescriptionKey]];
+        returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_unlock_", nil) forKey:NSLocalizedDescriptionKey]];
         dispatch_semaphore_signal(semaphore);
     }];
     
@@ -567,4 +554,73 @@
     return returnError;
 }
 
+- (NSError *)sendEndToEndMetadataOnServerUrl:(NSString *)serverUrl account:(NSString *)account user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileNameRename:(NSString *)fileName fileNameNewRename:(NSString *)fileNameNew token:(NSString **)token
+{
+    tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", account, serverUrl]];
+    *token = directory.e2eTokenLock;
+    
+    NSString *e2eTokenLock = *token;
+    NSString *metadata;
+    NSError *error;
+    
+    // Enabled E2E
+    if ([CCUtility isEndToEndEnabled:account] == NO)
+        return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_not_enabled_", nil) forKey:NSLocalizedDescriptionKey]];
+    
+    // get Metadata for select updateEndToEndMetadata or storeEndToEndMetadata
+    error = [[NCNetworkingSync sharedManager] getEndToEndMetadata:user userID:userID password:password url:url fileID:directory.fileID metadata:&metadata];
+    if (error.code != 404 && error != nil) {
+        return error;
+    }
+    
+    // Rename
+    if (fileName && fileNameNew)
+        [[NCManageDatabase sharedInstance] renameFileE2eEncryptionWithServerUrl:serverUrl fileNameIdentifier:fileName newFileName:fileNameNew newFileNamePath:[CCUtility returnFileNamePathFromFileName:fileNameNew serverUrl:serverUrl activeUrl:url]];
+
+    NSArray *tableE2eEncryption = [[NCManageDatabase sharedInstance] getE2eEncryptionsWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", account, serverUrl]];
+    if (!tableE2eEncryption)
+        return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_record_not_found_", nil) forKey:NSLocalizedDescriptionKey]];
+    
+    NSString *e2eMetadataJSON = [[NCEndToEndMetadata sharedInstance] encoderMetadata:tableE2eEncryption privateKey:[CCUtility getEndToEndPrivateKey:account] serverUrl:serverUrl];
+    if (!e2eMetadataJSON)
+        return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_encode_metadata_", nil) forKey:NSLocalizedDescriptionKey]];
+    
+    // send Metadata
+    if (error == nil)
+        error = [[NCNetworkingSync sharedManager] updateEndToEndMetadata:user userID:userID password:password url:url fileID:directory.fileID metadata:e2eMetadataJSON token:&e2eTokenLock];
+    else if (error.code == 404)
+        error = [[NCNetworkingSync sharedManager] storeEndToEndMetadata:user userID:userID password:password url:url fileID:directory.fileID metadata:e2eMetadataJSON token:&e2eTokenLock];
+    
+    *token = e2eTokenLock;
+    return error;
+}
+
+- (NSError *)rebuildAndSendEndToEndMetadataOnServerUrl:(NSString *)serverUrl account:(NSString *)account user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url token:(NSString  **)token
+{
+    NSString *e2eTokenLock = *token;
+    NSError *error;
+    NSString *e2eMetadataJSON;
+    
+    tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", account, serverUrl]];
+    if (directory.e2eEncrypted == NO)
+        return nil;
+    
+    NSArray *tableE2eEncryption = [[NCManageDatabase sharedInstance] getE2eEncryptionsWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", account, serverUrl]];
+    if (tableE2eEncryption) {
+        
+        e2eMetadataJSON = [[NCEndToEndMetadata sharedInstance] encoderMetadata:tableE2eEncryption privateKey:[CCUtility getEndToEndPrivateKey:account] serverUrl:serverUrl];
+        if (!e2eMetadataJSON)
+            return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_encode_metadata_", nil) forKey:NSLocalizedDescriptionKey]];
+        
+        error = [[NCNetworkingSync sharedManager] updateEndToEndMetadata:user userID:userID password:password url:url fileID:directory.fileID metadata:e2eMetadataJSON token:&e2eTokenLock];
+    
+    } else {
+    
+        error = [[NCNetworkingSync sharedManager] deleteEndToEndMetadata:user userID:userID password:password url:url fileID:directory.fileID];
+    }
+    
+    *token = e2eTokenLock;
+    return error;
+}
+
 @end

+ 4 - 13
iOSClient/Networking/OCNetworking.h

@@ -78,19 +78,19 @@
 - (void)getSharePermissionsFileFailure:(CCMetadataNet *)metadataNet message:(NSString *)message errorCode:(NSInteger)errorCode;
 
 // Capabilities
-- (void)getCapabilitiesOfServerSuccess:(OCCapabilities *)capabilities;
+- (void)getCapabilitiesOfServerSuccess:(CCMetadataNet *)metadataNet capabilities:(OCCapabilities *)capabilities;
 - (void)getCapabilitiesOfServerFailure:(CCMetadataNet *)metadataNet message:(NSString *)message errorCode:(NSInteger)errorCode;
 
 // Activity
-- (void)getActivityServerSuccess:(NSArray *)listOfActivity;
+- (void)getActivityServerSuccess:(CCMetadataNet *)metadataNet listOfActivity:(NSArray *)listOfActivity;
 - (void)getActivityServerFailure:(CCMetadataNet *)metadataNet message:(NSString *)message errorCode:(NSInteger)errorCode;
 
 // External Sites
-- (void)getExternalSitesServerSuccess:(NSArray *)listOfExternalSites;
+- (void)getExternalSitesServerSuccess:(CCMetadataNet *)metadataNet listOfExternalSites:(NSArray *)listOfExternalSites;
 - (void)getExternalSitesServerFailure:(CCMetadataNet *)metadataNet message:(NSString *)message errorCode:(NSInteger)errorCode;
 
 // Notification
-- (void)getNotificationServerSuccess:(NSArray *)listOfNotifications;
+- (void)getNotificationServerSuccess:(CCMetadataNet *)metadataNet listOfNotifications:(NSArray *)listOfNotifications;
 - (void)getNotificationServerFailure:(CCMetadataNet *)metadataNet message:(NSString *)message errorCode:(NSInteger)errorCode;
 
 - (void)setNotificationServerSuccess:(CCMetadataNet *)metadataNet;
@@ -132,15 +132,6 @@
 - (void)getEndToEndServerPublicKeySuccess:(CCMetadataNet *)metadataNet;
 - (void)getEndToEndServerPublicKeyFailure:(CCMetadataNet *)metadataNet message:(NSString *)message errorCode:(NSInteger)errorCode;
 
-- (void)getEndToEndMetadataSuccess:(CCMetadataNet *)metadataNet;
-- (void)getEndToEndMetadataFailure:(CCMetadataNet *)metadataNet message:(NSString *)message errorCode:(NSInteger)errorCode;
-
-- (void)deleteEndToEndMetadataSuccess:(CCMetadataNet *)metadataNet;
-- (void)deleteEndToEndMetadataFailure:(CCMetadataNet *)metadataNet message:(NSString *)message errorCode:(NSInteger)errorCode;
-
-- (void)unlockEndToEndFolderEncryptedSuccess:(CCMetadataNet *)metadataNet;
-- (void)unlockEndToEndFolderEncryptedFailure:(CCMetadataNet *)metadataNet message:(NSString *)message errorCode:(NSInteger)errorCode;
-
 @end
 
 @interface OCURLSessionManager : AFURLSessionManager

+ 9 - 120
iOSClient/Networking/OCNetworking.m

@@ -718,15 +718,6 @@
     [communication setCredentialsWithUser:_activeUser andUserID:_activeUserID andPassword:_activePassword];
     [communication setUserAgent:[CCUtility getUserAgent]];
     
-    // E2E Delete only directory NOT encrypted
-    if (_metadataNet.directory && _metadataNet.e2eEncrypted) {
-        
-        [self.delegate deleteFileOrFolderFailure:_metadataNet message:NSLocalizedString(@"_e2e_delete_folder_not_permitted_", nil) errorCode:0];
-        [self complete];
-        
-        return;
-    }
-    
     [communication deleteFileOrFolder:serverFileUrl onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
         
         if ([_metadataNet.selector rangeOfString:selectorDelete].location != NSNotFound && [self.delegate respondsToSelector:@selector(deleteFileOrFolderSuccess:)])
@@ -1217,8 +1208,8 @@
     
     [communication getActivityServer:[_activeUrl stringByAppendingString:@"/"] onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSArray *listOfActivity, NSString *redirectedServer) {
         
-        if ([self.delegate respondsToSelector:@selector(getActivityServerSuccess:)])
-            [self.delegate getActivityServerSuccess:listOfActivity];
+        if ([self.delegate respondsToSelector:@selector(getActivityServerSuccess:listOfActivity:)])
+            [self.delegate getActivityServerSuccess:_metadataNet listOfActivity:listOfActivity];
         
         [self complete];
         
@@ -1258,8 +1249,8 @@
     
     [communication getExternalSitesServer:[_activeUrl stringByAppendingString:@"/"] onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSArray *listOfExternalSites, NSString *redirectedServer) {
         
-        if ([self.delegate respondsToSelector:@selector(getExternalSitesServerSuccess:)])
-            [self.delegate getExternalSitesServerSuccess:listOfExternalSites];
+        if ([self.delegate respondsToSelector:@selector(getExternalSitesServerSuccess:listOfExternalSites:)])
+            [self.delegate getExternalSitesServerSuccess:_metadataNet listOfExternalSites:listOfExternalSites];
         
         [self complete];
         
@@ -1340,8 +1331,8 @@
     
     [communication getNotificationServer:[_activeUrl stringByAppendingString:@"/"] onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSArray *listOfNotifications, NSString *redirectedServer) {
         
-        if ([self.delegate respondsToSelector:@selector(getNotificationServerSuccess:)])
-            [self.delegate getNotificationServerSuccess:listOfNotifications];
+        if ([self.delegate respondsToSelector:@selector(getNotificationServerSuccess:listOfNotifications:)])
+            [self.delegate getNotificationServerSuccess:_metadataNet listOfNotifications:listOfNotifications];
         
         [self complete];
         
@@ -1544,11 +1535,9 @@
     [communication setUserAgent:[CCUtility getUserAgent]];
     
     [communication getCapabilitiesOfServer:[_activeUrl stringByAppendingString:@"/"] onCommunication:communication successRequest:^(NSHTTPURLResponse *response, OCCapabilities *capabilities, NSString *redirectedServer) {
-        
-        tableAccount *recordAccount = [[NCManageDatabase sharedInstance] getAccountActive];
-        
-        if ([self.delegate respondsToSelector:@selector(getCapabilitiesOfServerSuccess:)] && [recordAccount.account isEqualToString:_metadataNet.account])
-            [self.delegate getCapabilitiesOfServerSuccess:capabilities];
+                
+        if ([self.delegate respondsToSelector:@selector(getCapabilitiesOfServerSuccess:capabilities:)])
+            [self.delegate getCapabilitiesOfServerSuccess:_metadataNet capabilities:capabilities];
         
         [self complete];
         
@@ -1820,106 +1809,6 @@
     }];
 }
 
-- (void)getEndToEndMetadata
-{
-    OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
-    
-    [communication setCredentialsWithUser:_activeUser andUserID:_activeUserID andPassword:_activePassword];
-    [communication setUserAgent:[CCUtility getUserAgent]];
-    
-    [communication getEndToEndMetadata:[_activeUrl stringByAppendingString:@"/"] fileID:_metadataNet.fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *encryptedMetadata, NSString *redirectedServer) {
-        
-        _metadataNet.encryptedMetadata = encryptedMetadata;
-        
-        if ([self.delegate respondsToSelector:@selector(getEndToEndMetadataSuccess:)])
-        [self.delegate getEndToEndMetadataSuccess:_metadataNet];
-        
-        [self complete];
-        
-    } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
-        
-        NSInteger errorCode = response.statusCode;
-        if (errorCode == 0)
-        errorCode = error.code;
-        
-        // Error
-        if ([self.delegate respondsToSelector:@selector(getEndToEndMetadataFailure:message:errorCode:)])
-        [self.delegate getEndToEndMetadataFailure:_metadataNet message:[error.userInfo valueForKey:@"NSLocalizedDescription"] errorCode:errorCode];
-        
-        // Request trusted certificated
-        if ([error code] == NSURLErrorServerCertificateUntrusted)
-        [[CCCertificate sharedManager] presentViewControllerCertificateWithTitle:[error localizedDescription] viewController:(UIViewController *)self.delegate delegate:self];
-        
-        [self complete];
-    }];
-}
-
-- (void)deleteEndToEndMetadata
-{
-    OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
-    
-    [communication setCredentialsWithUser:_activeUser andUserID:_activeUserID andPassword:_activePassword];
-    [communication setUserAgent:[CCUtility getUserAgent]];
-    
-    [communication deleteEndToEndMetadata:[_activeUrl stringByAppendingString:@"/"] fileID:_metadataNet.fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-                
-        if ([self.delegate respondsToSelector:@selector(deleteEndToEndMetadataSuccess:)])
-        [self.delegate deleteEndToEndMetadataSuccess:_metadataNet];
-        
-        [self complete];
-        
-    } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
-        
-        NSInteger errorCode = response.statusCode;
-        if (errorCode == 0)
-        errorCode = error.code;
-        
-        // Error
-        if ([self.delegate respondsToSelector:@selector(deleteEndToEndMetadataFailure:message:errorCode:)])
-        [self.delegate deleteEndToEndMetadataFailure:_metadataNet message:[error.userInfo valueForKey:@"NSLocalizedDescription"] errorCode:errorCode];
-        
-        // Request trusted certificated
-        if ([error code] == NSURLErrorServerCertificateUntrusted)
-        [[CCCertificate sharedManager] presentViewControllerCertificateWithTitle:[error localizedDescription] viewController:(UIViewController *)self.delegate delegate:self];
-        
-        [self complete];
-    }];
-}
-
-- (void)unlockEndToEndFolderEncrypted
-{
-    OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
-    
-    [communication setCredentialsWithUser:_activeUser andUserID:_activeUserID andPassword:_activePassword];
-    [communication setUserAgent:[CCUtility getUserAgent]];
-    
-    [communication unlockEndToEndFolderEncrypted:[_activeUrl stringByAppendingString:@"/"] fileID:_metadataNet.fileID token:_metadataNet.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
-        
-        // 200 ok: file unlocked successful
-        
-        if ([self.delegate respondsToSelector:@selector(unlockEndToEndFolderEncryptedSuccess:)])
-            [self.delegate unlockEndToEndFolderEncryptedSuccess:_metadataNet];
-        
-        [self complete];
-        
-    } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
-        
-        NSInteger errorCode = response.statusCode;
-        if (errorCode == 0)
-            errorCode = error.code;
-        
-        // Error
-        if ([self.delegate respondsToSelector:@selector(unlockEndToEndFolderEncryptedFailure:message:errorCode:)])
-            [self.delegate unlockEndToEndFolderEncryptedFailure:_metadataNet message:[error.userInfo valueForKey:@"NSLocalizedDescription"] errorCode:errorCode];
-        
-        // Request trusted certificated
-        if ([error code] == NSURLErrorServerCertificateUntrusted)
-            [[CCCertificate sharedManager] presentViewControllerCertificateWithTitle:[error localizedDescription] viewController:(UIViewController *)self.delegate delegate:self];
-        
-        [self complete];
-    }];
-}
-
 @end
 
 #pragma --------------------------------------------------------------------------------------------

+ 5 - 0
iOSClient/Notification/CCNotification.swift

@@ -195,6 +195,11 @@ class CCNotification: UITableViewController, OCNetworkingDelegate {
     
     func setNotificationServerSuccess(_ metadataNet: CCMetadataNet!) {
         
+        // Check Active Account
+        if (metadataNet.account != appDelegate.activeAccount) {
+            return
+        }
+        
         let listOfNotifications = appDelegate.listOfNotifications as NSArray as! [OCNotifications]
         
         if let index = listOfNotifications.index(where: {$0.idNotification == Int(metadataNet.assetLocalIdentifier)})  {

+ 9 - 1
iOSClient/PeekPop/CCPeekPop.m

@@ -92,6 +92,10 @@
 
 - (void)downloadThumbnailSuccess:(CCMetadataNet *)metadataNet
 {
+    // Check Active Account
+    if (![metadataNet.account isEqualToString:appDelegate.activeAccount])
+        return;
+    
     UIImage *image = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@.pvw",appDelegate.directoryUser, _metadata.fileID]];
     
     _imagePreview.image = image;
@@ -102,7 +106,11 @@
 }
 
 - (void)downloadThumbnailFailure:(CCMetadataNet *)metadataNet message:(NSString *)message errorCode:(NSInteger)errorCode
-{    
+{
+    // Check Active Account
+    if (![metadataNet.account isEqualToString:appDelegate.activeAccount])
+        return;
+    
     [appDelegate messageNotification:@"_error_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
     
     [self dismissViewControllerAnimated:YES completion:nil];

+ 5 - 3
iOSClient/Photos/CCPhotos.m

@@ -451,9 +451,7 @@
 {
     [_queueMetadatas addObject:selectorDelete];
     
-    [[CCActions sharedInstance] deleteFileOrFolder:metadata delegate:self];
-
-    [_hud visibleHudTitle:[NSString stringWithFormat:NSLocalizedString(@"_delete_file_n_", nil), ofFile - numFile + 1, ofFile] mode:MBProgressHUDModeIndeterminate color:nil];
+    [[CCActions sharedInstance] deleteFileOrFolder:metadata delegate:self hud:_hud hudTitled:[NSString stringWithFormat:NSLocalizedString(@"_delete_file_n_", nil), ofFile - numFile + 1, ofFile]];
 }
 
 - (void)deleteSelectedFiles
@@ -493,6 +491,10 @@
 
 - (void)downloadThumbnailSuccess:(CCMetadataNet *)metadataNet
 {
+    // Check Active Account
+    if (![metadataNet.account isEqualToString:appDelegate.activeAccount])
+        return;
+    
     NSIndexPath *indexPath = [_sectionDataSource.fileIDIndexPath objectForKey:metadataNet.fileID];
     
     if ([self indexPathIsValid:indexPath]) {

+ 1 - 1
iOSClient/QuickActions/CCQuickActions.m

@@ -167,7 +167,7 @@
     _move.barTintColor = [NCBrandColor sharedInstance].brand;
     _move.tintColorTitle = [NCBrandColor sharedInstance].brandText;
     _move.networkingOperationQueue = appDelegate.netQueue;
-    // E2E
+    // E2EE
     _move.includeDirectoryE2EEncryption = NO;
     
     [navigationController setModalPresentationStyle:UIModalPresentationFormSheet];

+ 5 - 3
iOSClient/Security/NCEndToEndMetadata.swift

@@ -188,8 +188,8 @@ class NCEndToEndMetadata : NSObject  {
                 do {
                     
                     let encryptedFileAttributes = try jsonDecoder.decode(e2eMetadata.encryptedFileAttributes.self, from: encryptedFileAttributesJson.data(using: .utf8)!)
-                    let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "account = %@ AND fileName = %@", account, fileNameIdentifier))
                     
+                    let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "account = %@ AND fileName = %@", account, fileNameIdentifier))
                     if  metadata != nil {
                     
                         let object = tableE2eEncryption()
@@ -209,6 +209,7 @@ class NCEndToEndMetadata : NSObject  {
                     
                         // If exists remove records
                         NCManageDatabase.sharedInstance.deleteE2eEncryption(predicate: NSPredicate(format: "account = %@ AND fileNamePath = %@", object.account, object.fileNamePath))
+                        NCManageDatabase.sharedInstance.deleteE2eEncryption(predicate: NSPredicate(format: "account = %@ AND fileNameIdentifier = %@", object.account, object.fileNameIdentifier))
                         
                         // Write file parameter for decrypted on DB
                         if NCManageDatabase.sharedInstance.addE2eEncryption(object) == false {
@@ -218,12 +219,13 @@ class NCEndToEndMetadata : NSObject  {
                         // Update metadata on tableMetadata
                         metadata?.fileNameView = encryptedFileAttributes.filename
                         CCUtility.insertTypeFileIconName(encryptedFileAttributes.filename, metadata: metadata)
-                        let _ = NCManageDatabase.sharedInstance.addMetadata(metadata!)
+                        DispatchQueue.main.async {
+                            _ = NCManageDatabase.sharedInstance.addMetadata(metadata!)
+                        }
                     }
                     
                 } catch let error {
                     print("Serious internal error in decoding metadata ("+error.localizedDescription+")")
-                    return false
                 }
             }
             

+ 2 - 3
iOSClient/Settings/CCAdvanced.m

@@ -340,10 +340,9 @@
     [[NCManageDatabase sharedInstance] clearTable:[tableQueueUpload class] account:appDelegate.activeAccount];
     
     [appDelegate.netQueue cancelAllOperations];
-    
     [[CCNetworking sharedNetworking] settingSessionsDownload:YES upload:YES taskStatus:k_taskStatusCancel activeAccount:appDelegate.activeAccount activeUser:appDelegate.activeUser activeUrl:appDelegate.activeUrl];
     
-    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC),dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC),dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
         
         [[NSURLCache sharedURLCache] setMemoryCapacity:0];
         [[NSURLCache sharedURLCache] setDiskCapacity:0];
@@ -464,7 +463,7 @@
         
         [self.hud visibleIndeterminateHud];
         
-        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.01 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void) {
+        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void) {
             
             [appDelegate.netQueue cancelAllOperations];
             [[CCNetworking sharedNetworking] settingSessionsDownload:YES upload:YES taskStatus:k_taskStatusCancel activeAccount:appDelegate.activeAccount activeUser:appDelegate.activeUser activeUrl:appDelegate.activeUrl];

+ 65 - 43
iOSClient/Settings/CCManageAccount.m

@@ -195,11 +195,16 @@
     }
 }
 
-- (void)loginDisappear
+- (void)loginClose
 {
     appDelegate.activeLogin = nil;
 }
 
+- (void)loginWebClose
+{
+    appDelegate.activeLoginWeb = nil;
+}
+
 #pragma --------------------------------------------------------------------------------------------
 #pragma mark === Add Account ===
 #pragma --------------------------------------------------------------------------------------------
@@ -208,10 +213,17 @@
 {
     [self deselectFormRow:sender];
     
+    // Verify session in progress
+    if ([[[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND sessionTaskIdentifier > 0", appDelegate.activeAccount] sorted:nil ascending:NO] count] > 0) {
+        [JDStatusBarNotification showWithStatus:NSLocalizedString(@"_transfers_in_queue_", nil) dismissAfter:k_dismissAfterSecond styleName:JDStatusBarStyleDefault];
+        return;
+    }
+    
     [appDelegate.netQueue cancelAllOperations];
-    [[CCNetworking sharedNetworking] settingSessionsDownload:YES upload:YES taskStatus:k_taskStatusCancel activeAccount:appDelegate.activeAccount activeUser:appDelegate.activeUser activeUrl:appDelegate.activeUrl];
     
-    [appDelegate openLoginView:self loginType:loginAdd];
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
+        [appDelegate openLoginView:self loginType:loginAdd];
+    });
 }
 
 - (void)addAccountForced
@@ -227,12 +239,17 @@
 {    
     [self deselectFormRow:sender];
     
-    [appDelegate.netQueue cancelAllOperations];
-    [[CCNetworking sharedNetworking] settingSessionsDownload:YES upload:YES taskStatus:k_taskStatusCancel activeAccount:appDelegate.activeAccount activeUser:appDelegate.activeUser activeUrl:appDelegate.activeUrl];
+    // Verify session in progress
+    if ([[[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND sessionTaskIdentifier > 0", appDelegate.activeAccount] sorted:nil ascending:NO] count] > 0) {
+        [JDStatusBarNotification showWithStatus:NSLocalizedString(@"_transfers_in_queue_", nil) dismissAfter:k_dismissAfterSecond styleName:JDStatusBarStyleDefault];
+        return;
+    }
     
-    [appDelegate openLoginView:self loginType:loginModifyPasswordUser];
+    [appDelegate.netQueue cancelAllOperations];
     
-    [self UpdateForm];
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
+        [appDelegate openLoginView:self loginType:loginModifyPasswordUser];
+    });
 }
 
 #pragma --------------------------------------------------------------------------------------------
@@ -261,24 +278,32 @@
 
 - (void)deleteAccount:(NSString *)account
 {
+    // Verify session in progress
+    if ([[[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND sessionTaskIdentifier > 0", appDelegate.activeAccount] sorted:nil ascending:NO] count] > 0) {
+        [JDStatusBarNotification showWithStatus:NSLocalizedString(@"_transfers_in_queue_", nil) dismissAfter:k_dismissAfterSecond styleName:JDStatusBarStyleDefault];
+        return;
+    }
+    
     [appDelegate.netQueue cancelAllOperations];
-    [[CCNetworking sharedNetworking] settingSessionsDownload:YES upload:YES taskStatus:k_taskStatusCancel activeAccount:appDelegate.activeAccount activeUser:appDelegate.activeUser activeUrl:appDelegate.activeUrl];
-    
-    [[NCManageDatabase sharedInstance] clearTable:[tableAccount class] account:account];
-    [[NCManageDatabase sharedInstance] clearTable:[tableActivity class] account:account];
-    [[NCManageDatabase sharedInstance] clearTable:[tableCapabilities class] account:account];
-    [[NCManageDatabase sharedInstance] clearTable:[tableDirectory class] account:account];
-    [[NCManageDatabase sharedInstance] clearTable:[tableE2eEncryption class] account:account];
-    [[NCManageDatabase sharedInstance] clearTable:[tableExternalSites class] account:account];
-    [[NCManageDatabase sharedInstance] clearTable:[tableLocalFile class] account:account];
-    [[NCManageDatabase sharedInstance] clearTable:[tableMetadata class] account:account];
-    [[NCManageDatabase sharedInstance] clearTable:[tablePhotoLibrary class] account:account];
-    [[NCManageDatabase sharedInstance] clearTable:[tableQueueDownload class] account:account];
-    [[NCManageDatabase sharedInstance] clearTable:[tableQueueUpload class] account:account];
-    [[NCManageDatabase sharedInstance] clearTable:[tableShare class] account:account];
-    
-    // Clear active user
-    [appDelegate settingActiveAccount:nil activeUrl:nil activeUser:nil activeUserID:nil activePassword:nil];
+    
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
+
+        [[NCManageDatabase sharedInstance] clearTable:[tableAccount class] account:account];
+        [[NCManageDatabase sharedInstance] clearTable:[tableActivity class] account:account];
+        [[NCManageDatabase sharedInstance] clearTable:[tableCapabilities class] account:account];
+        [[NCManageDatabase sharedInstance] clearTable:[tableDirectory class] account:account];
+        [[NCManageDatabase sharedInstance] clearTable:[tableE2eEncryption class] account:account];
+        [[NCManageDatabase sharedInstance] clearTable:[tableExternalSites class] account:account];
+        [[NCManageDatabase sharedInstance] clearTable:[tableLocalFile class] account:account];
+        [[NCManageDatabase sharedInstance] clearTable:[tableMetadata class] account:account];
+        [[NCManageDatabase sharedInstance] clearTable:[tablePhotoLibrary class] account:account];
+        [[NCManageDatabase sharedInstance] clearTable:[tableQueueDownload class] account:account];
+        [[NCManageDatabase sharedInstance] clearTable:[tableQueueUpload class] account:account];
+        [[NCManageDatabase sharedInstance] clearTable:[tableShare class] account:account];
+    
+        // Clear active user
+        [appDelegate settingActiveAccount:nil activeUrl:nil activeUser:nil activeUserID:nil activePassword:nil];        
+    });
 }
 
 - (void)answerDelAccount:(XLFormRowDescriptor *)sender
@@ -301,30 +326,27 @@
 
 - (void)ChangeDefaultAccount:(NSString *)account
 {
-    NSUInteger numInSession = [[[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND session != ''", appDelegate.activeAccount] sorted:nil ascending:NO] count];
-    NSUInteger numInQueue = [appDelegate.netQueue operationCount];
-    
-    if (numInSession+numInQueue > 0) {
-        
-        [JDStatusBarNotification showWithStatus:NSLocalizedString(@"_transfers_in_queue_", nil) dismissAfter:k_dismissAfterSecond styleName:JDStatusBarStyleDefault];        
-        [self UpdateForm];
+    // Verify session in progress
+    if ([[[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND sessionTaskIdentifier > 0", appDelegate.activeAccount] sorted:nil ascending:NO] count] > 0) {
+        [JDStatusBarNotification showWithStatus:NSLocalizedString(@"_transfers_in_queue_", nil) dismissAfter:k_dismissAfterSecond styleName:JDStatusBarStyleDefault];
         return;
     }
-
-    [appDelegate.netQueue cancelAllOperations];
-    [[CCNetworking sharedNetworking] settingSessionsDownload:YES upload:YES taskStatus:k_taskStatusCancel activeAccount:appDelegate.activeAccount activeUser:appDelegate.activeUser activeUrl:appDelegate.activeUrl];
     
-    // change account
-    tableAccount *tableAccount = [[NCManageDatabase sharedInstance] setAccountActive:account];
-    if (tableAccount) {
+    [appDelegate.netQueue cancelAllOperations];
+
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
+
+        tableAccount *tableAccount = [[NCManageDatabase sharedInstance] setAccountActive:account];
+        if (tableAccount) {
         
-        [appDelegate settingActiveAccount:tableAccount.account activeUrl:tableAccount.url activeUser:tableAccount.user activeUserID:tableAccount.userID activePassword:tableAccount.password];
+            [appDelegate settingActiveAccount:tableAccount.account activeUrl:tableAccount.url activeUser:tableAccount.user activeUserID:tableAccount.userID activePassword:tableAccount.password];
  
-        // Init home
-        [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"initializeMain" object:nil];
-    }
-    
-    [self UpdateForm];
+            // Init home
+            [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"initializeMain" object:nil];
+            
+            [self UpdateForm];
+        }
+    });
 }
 
 #pragma --------------------------------------------------------------------------------------------

+ 10 - 128
iOSClient/Security/NCEntoToEndInterface.swift → iOSClient/Settings/NCEndToEndInitialize.swift

@@ -1,5 +1,5 @@
 //
-//  NCEntoToEndInterface.swift
+//  NCEndToEndInitialize.swift
 //  Nextcloud
 //
 //  Created by Marino Faggiana on 03/04/17.
@@ -23,7 +23,14 @@
 
 import Foundation
 
-class NCEntoToEndInterface : NSObject, OCNetworkingDelegate  {
+@objc protocol NCEndToEndInitializeDelegate {
+    
+    func endToEndInitializeSuccess()
+}
+
+class NCEndToEndInitialize : NSObject, OCNetworkingDelegate  {
+
+    @objc weak var delegate: NCEndToEndInitializeDelegate?
 
     let appDelegate = UIApplication.shared.delegate as! AppDelegate
     
@@ -126,14 +133,6 @@ class NCEntoToEndInterface : NSObject, OCNetworkingDelegate  {
         }
     }
     
-    func deleteEnd(toEndPublicKeySuccess metadataNet: CCMetadataNet!) {
-        appDelegate.messageNotification("E2E delete publicKey", description: "Success", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.success, errorCode: 0)
-    }
-    
-    func deleteEnd(toEndPublicKeyFailure metadataNet: CCMetadataNet!, message: String!, errorCode: Int) {
-        appDelegate.messageNotification("E2E delete publicKey", description: message, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
-    }
-    
     // --------------------------------------------------------------------------------------------
     // MARK: Manage PrivateKey
     // --------------------------------------------------------------------------------------------
@@ -268,14 +267,6 @@ class NCEntoToEndInterface : NSObject, OCNetworkingDelegate  {
         }
     }
     
-    func deleteEnd(toEndPrivateKeySuccess metadataNet: CCMetadataNet!) {
-        appDelegate.messageNotification("E2E delete privateKey", description: "Success", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.success, errorCode: 0)
-    }
-    
-    func deleteEnd(toEndPrivateKeyFailure metadataNet: CCMetadataNet!, message: String!, errorCode: Int) {
-        appDelegate.messageNotification("E2E delete privateKey", description: message, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
-    }
-    
     // --------------------------------------------------------------------------------------------
     // MARK: Manage Server PublicKey
     // --------------------------------------------------------------------------------------------
@@ -288,11 +279,7 @@ class NCEntoToEndInterface : NSObject, OCNetworkingDelegate  {
         NCManageDatabase.sharedInstance.clearTable(tableDirectory.self, account: appDelegate.activeAccount)
         NCManageDatabase.sharedInstance.clearTable(tableE2eEncryption.self, account: appDelegate.activeAccount)
 
-        // Reload All Datasource
-        NotificationCenter.default.post(name: Notification.Name("clearDateReadDataSource"), object: nil)
-
-        // All OK Activated flsg on Manage EndToEnd Encryption
-        NotificationCenter.default.post(name: Notification.Name("reloadManageEndToEndEncryption"), object: nil)
+        self.delegate?.endToEndInitializeSuccess()
     }
     
     func getEndToEndServerPublicKeyFailure(_ metadataNet: CCMetadataNet!, message: String!, errorCode: Int) {
@@ -312,109 +299,4 @@ class NCEntoToEndInterface : NSObject, OCNetworkingDelegate  {
             appDelegate.messageNotification("E2E Server publicKey", description: message as String!, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
         }
     }
-    
-    // --------------------------------------------------------------------------------------------
-    // MARK: Manage Mark/Delete Encrypted Folder
-    // --------------------------------------------------------------------------------------------
-    
-    @objc func markEndToEndFolderEncrypted(_ url: String, fileID: String, serverUrl: String) -> Bool {
-        
-        var token: NSString?
-                
-        // Remove all records e2eMetadata
-        NCManageDatabase.sharedInstance.deleteE2eEncryption(predicate: NSPredicate(format: "account = %@ AND serverUrl = %@", appDelegate.activeAccount, serverUrl))
-        
-        if let error = NCNetworkingSync.sharedManager().markEnd(toEndFolderEncrypted: appDelegate.activeUser, userID: appDelegate.activeUserID, password: appDelegate.activePassword, url: url, fileID: fileID, serverUrl: serverUrl,token: &token) as NSError? {
-            
-            appDelegate.messageNotification("E2E Mark folder as encrypted", description: error.localizedDescription+" code \(error.code)", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: error.code)
-
-            return false
-        }
-        
-        return true
-    }
-    
-    @objc func deletemarkEndToEndFolderEncrypted(_ url: String, fileID: String, serverUrl: String) -> Bool {
-        
-        var token: NSString?
-
-        // Remove all records e2eMetadata
-        NCManageDatabase.sharedInstance.deleteE2eEncryption(predicate: NSPredicate(format: "account = %@ AND serverUrl = %@", appDelegate.activeAccount, serverUrl))
-        
-        if let error = NCNetworkingSync.sharedManager().deletemarkEnd(toEndFolderEncrypted: appDelegate.activeUser, userID: appDelegate.activeUserID, password: appDelegate.activePassword, url: url, fileID: fileID, serverUrl: serverUrl, token: &token) as NSError? {
-            
-            appDelegate.messageNotification("E2E Remove mark folder as encrypted", description: error.localizedDescription+" code \(error.code)", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: error.code)
-            
-            return false
-        }
-        
-        return true
-    }
-    
-    // --------------------------------------------------------------------------------------------
-    // MARK: Manage Metadata
-    // --------------------------------------------------------------------------------------------
-    
-    func getEndToEndMetadataSuccess(_ metadataNet: CCMetadataNet!) {
-        
-        guard let privateKey = CCUtility.getEndToEndPrivateKey(appDelegate.activeAccount) else {
-            
-            appDelegate.messageNotification("E2E Get Metadata", description: "Serious internal error: PrivareKey not found", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: 0)
-            return
-        }
-
-        guard let main = appDelegate.listMainVC[metadataNet.serverUrl] as? CCMain else {
-            
-            appDelegate.messageNotification("E2E Get Metadata", description: "Serious internal error: Main not found", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: 0)
-            return
-        }
-        
-        // Decode metadata JSON
-        if NCEndToEndMetadata.sharedInstance.decoderMetadata(metadataNet.encryptedMetadata, privateKey: privateKey, serverUrl: metadataNet.serverUrl, account: appDelegate.activeAccount, url: appDelegate.activeUrl) == false {
-        
-            appDelegate.messageNotification("E2E decode metadata", description: "Serious internal error in decoding metadata", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: 0)
-            return
-        }
-        
-        // Reload data source
-        main.reloadDatasource(metadataNet.serverUrl)
-    }
-    
-    func getEndToEndMetadataFailure(_ metadataNet: CCMetadataNet!, message: String!, errorCode: Int) {
-        
-        // Unauthorized
-        if (errorCode == kOCErrorServerUnauthorized) {
-            
-            appDelegate.openLoginView(appDelegate.activeMain, loginType: loginModifyPasswordUser)
-            
-        } else if (errorCode == 404) {
-            
-            print("No metadata found: "+metadataNet.serverUrl+"/"+metadataNet.fileName)
-            
-        } else if (errorCode != 404) {
-            
-            appDelegate.messageNotification("E2E Get metadata", description: message as String!, visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: errorCode)
-        }
-    }
-    
-    @objc func getEndToEndMetadata(_ fileName: String, fileID: String, serverUrl: String) {
-        
-        let metadataNet: CCMetadataNet = CCMetadataNet.init(account: appDelegate.activeAccount)
-        
-        metadataNet.action = actionGetEndToEndMetadata
-        metadataNet.fileID = fileID
-        metadataNet.fileName = fileName
-        metadataNet.serverUrl = serverUrl
-        
-        appDelegate.addNetworkingOperationQueue(appDelegate.netQueue, delegate: self, metadataNet: metadataNet)
-    }
-
 }
-
-
-
-
-
-
-
-

+ 6 - 1
iOSClient/Settings/NCManageEndToEndEncryption.h

@@ -24,7 +24,12 @@
 #import "XLFormViewController.h"
 #import "XLForm.h"
 #import "BKPasscodeViewController.h"
+#import "OCNetworking.h"
 
-@interface NCManageEndToEndEncryption : XLFormViewController <BKPasscodeViewControllerDelegate>
+@class NCEndToEndInitialize;
+
+@interface NCManageEndToEndEncryption : XLFormViewController <BKPasscodeViewControllerDelegate, OCNetworkingDelegate>
+
+@property (nonatomic, strong) NCEndToEndInitialize *endToEndInitialize;
 
 @end

+ 42 - 8
iOSClient/Settings/NCManageEndToEndEncryption.m

@@ -27,7 +27,7 @@
 
 #import "NCBridgeSwift.h"
 
-@interface NCManageEndToEndEncryption ()
+@interface NCManageEndToEndEncryption () <NCEndToEndInitializeDelegate>
 {
     AppDelegate *appDelegate;
 
@@ -45,7 +45,6 @@
         
         appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
         
-        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadForm) name:@"reloadManageEndToEndEncryption" object:nil];
         [self initializeForm];
     }
     return self;
@@ -58,7 +57,6 @@
         
         appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
         
-        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadForm) name:@"reloadManageEndToEndEncryption" object:nil];
         [self initializeForm];
     }
     return self;
@@ -178,9 +176,13 @@
     self.form = form;
 }
 
--(void)reloadForm
+- (void)viewDidLoad
 {
-    [self initializeForm];
+    [super viewDidLoad];
+    
+    // E2EE
+    self.endToEndInitialize = [NCEndToEndInitialize new];
+    self.endToEndInitialize.delegate = self;
 }
 
 #pragma --------------------------------------------------------------------------------------------
@@ -314,7 +316,7 @@
     CCMetadataNet *metadataNet = [[CCMetadataNet alloc] initWithAccount:appDelegate.activeAccount];
     
     metadataNet.action = actionDeleteEndToEndPublicKey;
-    [appDelegate addNetworkingOperationQueue:appDelegate.netQueue delegate:appDelegate.endToEndInterface metadataNet:metadataNet];
+    [appDelegate addNetworkingOperationQueue:appDelegate.netQueue delegate:self metadataNet:metadataNet];
 }
 
 - (void)deletePrivateKey:(XLFormRowDescriptor *)sender
@@ -324,7 +326,39 @@
     CCMetadataNet *metadataNet = [[CCMetadataNet alloc] initWithAccount:appDelegate.activeAccount];
     
     metadataNet.action = actionDeleteEndToEndPrivateKey;
-    [appDelegate addNetworkingOperationQueue:appDelegate.netQueue delegate:appDelegate.endToEndInterface metadataNet:metadataNet];
+    [appDelegate addNetworkingOperationQueue:appDelegate.netQueue delegate:self metadataNet:metadataNet];
+}
+
+#pragma --------------------------------------------------------------------------------------------
+#pragma mark === Delegate ===
+#pragma --------------------------------------------------------------------------------------------
+
+- (void)endToEndInitializeSuccess
+{
+    // Reload All Datasource
+    [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"clearDateReadDataSource" object:nil];
+
+    [self initializeForm];
+}
+
+- (void)deleteEndToEndPrivateKeySuccess:(CCMetadataNet *)metadataNet
+{
+    [appDelegate messageNotification:@"E2E delete privateKey" description:@"Success" visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeSuccess errorCode:0];
+}
+
+- (void)deleteEndToEndPrivateKeyFailure:(CCMetadataNet *)metadataNet message:(NSString *)message errorCode:(NSInteger)errorCode
+{
+    [appDelegate messageNotification:@"E2E delete privateKey" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:0];
+}
+
+- (void)deleteEndToEndPublicKeySuccess:(CCMetadataNet *)metadataNet
+{
+    [appDelegate messageNotification:@"E2E delete publicKey" description:@"Success" visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeSuccess errorCode:0];
+}
+
+- (void)deleteEndToEndPublicKeyFailure:(CCMetadataNet *)metadataNet message:(NSString *)message errorCode:(NSInteger)errorCode
+{
+    [appDelegate messageNotification:@"E2E delete publicKey" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:0];
 }
 
 #pragma --------------------------------------------------------------------------------------------
@@ -362,7 +396,7 @@
     
     if (aViewController.fromType == CCBKPasscodeFromStartEncryption) {
         
-        [appDelegate.endToEndInterface initEndToEndEncryption];
+        [self.endToEndInitialize initEndToEndEncryption];        
     }
     
     if (aViewController.fromType == CCBKPasscodeFromCheckPassphrase) {

+ 11 - 2
iOSClient/Share/CCShareUserOC.m

@@ -218,8 +218,17 @@
         
         NSString *title;
         
-        if (item.shareeType == 1) title = [item.name stringByAppendingString:NSLocalizedString(@"_user_is_group_", nil)];
-        else title = item.name;
+        if (item.shareeType == 1) {
+            if (item.displayName)
+                title = [item.displayName stringByAppendingString:NSLocalizedString(@"_user_is_group_", nil)];
+            else
+                title = [item.name stringByAppendingString:NSLocalizedString(@"_user_is_group_", nil)];
+        } else {
+            if (item.displayName)
+                title = item.displayName;
+            else
+                title = item.name;
+        }
         
         XLFormRowDescriptor *row = [XLFormRowDescriptor formRowDescriptorWithTag:[@(num) stringValue] rowType:XLFormRowDescriptorTypeBooleanCheck title:title];
         [row.cellConfig setObject:[UIFont systemFontOfSize:15.0]forKey:@"textLabel.font"];

二进制
iOSClient/Supporting Files/cs-CZ.lproj/Error.strings


二进制
iOSClient/Supporting Files/cs-CZ.lproj/Localizable.strings


二进制
iOSClient/Supporting Files/de.lproj/Error.strings


二进制
iOSClient/Supporting Files/de.lproj/Localizable.strings


二进制
iOSClient/Supporting Files/en-GB.lproj/Error.strings


二进制
iOSClient/Supporting Files/en-GB.lproj/Localizable.strings


+ 4 - 2
iOSClient/Supporting Files/en.lproj/Error.strings

@@ -38,7 +38,6 @@
 "_file_directory_locked_"               = "File or directory locked";
 "_ssl_certificate_untrusted_"           = "The certificate for this server is invalid";
 "_internal_server_"                     = "Internal Server Error";
-
 "_file_already_exists_"                 = "Unable to complete the operation, there is a file with the same name";
 "_file_folder_not_exists_"              = "The source file wasn't found at the specified path";
 "_folder_contents_nochanged_"           = "The folder contents have not changed";
@@ -49,5 +48,8 @@
 "_too_many_files_"                      = "Too many files would be involved in this operation to complete successfully";
 "_too_many_request_"                    = "Rate limit reached—too many requests sent";
 "_user_over_quota_"                     = "Storage quota is reached";
-
 "_ssl_connection_error_"                = "Connection SSL error, try again";
+"_bad_request_"                         = "Bad request";
+"_webdav_locked_"                       = "WebDAV Locked : The resource that is being accessed is locked";
+
+

+ 26 - 7
iOSClient/Supporting Files/en.lproj/Localizable.strings

@@ -44,6 +44,7 @@
 "_save_"                    = "Save";
 "_warning_"                 = "Warning";
 "_error_"                   = "Error";
+"_error_e2ee_"              = "Error E2EE";
 "_no_"                      = "No";
 "_yes_"                     = "Yes";
 "_select_"                  = "Select";
@@ -224,6 +225,8 @@
 "_login_bottom_label_"          = "Don't have a server yet?\nChoose one of the providers.";
 "_error_multidomain_"           = "Address not allowed, only the following domains are valid:";
 "_account_already_exists_"      = "The account %@ already exists";
+"_traditional_login_"           = "Revert to old login method";
+"_web_login_"                   = "Revert to web login method";
 
 // Favorite
 
@@ -501,17 +504,33 @@
 "_e2e_settings_start_"              = "Start end-to-end encryption";
 "_e2e_settings_not_available_"      = "End-to-end encryption not available";
 "_e2e_settings_activated_"          = "End-to-end encryption activated";
-"_e2e_settings_view_passphrase_"    = "This 12 word phrase is a very strong password providing full access to view and use your encrypted files. Please write it down and keep it somewhere safe.";
+"_e2e_settings_view_passphrase_"    = "All 12 words together make a very strong password, letting only you view and make use of your encrypted files. Please write it down and keep it somewhere safe.";
 "_e2e_settings_read_passphrase_"    = "Read passphrase";
 "_e2e_settings_lock_not_active_"    = "Lock not active, go back to \"Settings\" and activate it";
 "_e2e_settings_the_passphrase_is_"  = "The passphrase is:";
 "_e2e_passphrase_request_title_"    = "Request passphrase";
 "_e2e_passphrase_request_message_"  = "Insert the 12 words";
-"_e2e_settings_remove_"             = "Remove the encryption locally";
-"_e2e_settings_remove_message_"     = "Confirm removing encryption along with the passphrase.";
-"_e2e_set_folder_encrypted_"        = "Set as encrypted";
-"_e2e_remove_folder_encrypted_"     = "Remove as encrypted";
-"_e2e_goto_settings_for_enable_"    = "You are in a encrypted directory, go to on \"Settings\" and enable the end-to-end encryption";
+"_e2e_settings_remove_"             = "Decrypt locally";
+"_e2e_settings_remove_message_"     = "Confirm removal of encryption along with the passphrase.";
+"_e2e_set_folder_encrypted_"        = "Encrypt";
+"_e2e_remove_folder_encrypted_"     = "Decrypt";
+"_e2e_goto_settings_for_enable_"    = "You are in an encrypted directory, go to \"Settings\" and enable end-to-end encryption";
 "_e2e_delete_folder_not_permitted_" = "Deletion of the directory marked as 'encrypted' is not allowed";
-"_e2e_remove_folder_lock_"          = "Forced remove folder lock";
+"_e2e_remove_folder_lock_"          = "Force remove folder lock";
+"_e2e_error_encode_metadata_"       = "Serious internal error in encoding metadata";
+"_e2e_error_decode_metadata_"       = "Serious internal error in decoding metadata";
+"_e2e_error_create_encrypted_"      = "Could not create encrypted file";
+"_e2e_error_update_metadata_"       = "Update metadata error";
+"_e2e_error_store_metadata_"        = "Could not save metadata";
+"_e2e_error_send_metadata_"         = "Could not send metadata";
+"_e2e_error_delete_metadata_"       = "Could not delete metadata";
+"_e2e_error_get_metadata_"          = "Could not fetch metadata";
+"_e2e_error_not_enabled_"           = "Serious internal error. End-to-end encryption not enabled";
+"_e2e_error_record_not_found_"      = "Serious internal error. Records not found";
+"_e2e_error_unlock_"                = "Could not unlock folder";
+"_e2e_error_lock_"                  = "Could not lock folder";
+"_e2e_error_delete_mark_folder_"    = "Decrypt marked folder";
+"_e2e_error_mark_folder_"           = "Encrypt folder";
+"_e2e_error_directory_not_empty_"   = "The directory is not empty";
+
 

+ 0 - 0
iOSClient/Supporting Files/es_419.lproj/BKPasscodeView.strings → iOSClient/Supporting Files/es-419.lproj/BKPasscodeView.strings


+ 0 - 0
iOSClient/Supporting Files/es_419.lproj/CTAssetsPicker.strings → iOSClient/Supporting Files/es-419.lproj/CTAssetsPicker.strings


二进制
iOSClient/Supporting Files/es_419.lproj/Error.strings → iOSClient/Supporting Files/es-419.lproj/Error.strings


+ 0 - 0
iOSClient/Supporting Files/es_419.lproj/InfoPlist.strings → iOSClient/Supporting Files/es-419.lproj/InfoPlist.strings


+ 0 - 0
iOSClient/Supporting Files/es_419.lproj/Intro.strings → iOSClient/Supporting Files/es-419.lproj/Intro.strings


二进制
iOSClient/Supporting Files/es_419.lproj/Localizable.strings → iOSClient/Supporting Files/es-419.lproj/Localizable.strings


+ 0 - 0
iOSClient/Supporting Files/es_419.lproj/SwiftWebVC.strings → iOSClient/Supporting Files/es-419.lproj/SwiftWebVC.strings


二进制
iOSClient/Supporting Files/es-CL.lproj/Error.strings


二进制
iOSClient/Supporting Files/es-CL.lproj/Localizable.strings


二进制
iOSClient/Supporting Files/es-CO.lproj/Error.strings


二进制
iOSClient/Supporting Files/es-CO.lproj/Localizable.strings


二进制
iOSClient/Supporting Files/es-CR.lproj/Error.strings


二进制
iOSClient/Supporting Files/es-CR.lproj/Localizable.strings


二进制
iOSClient/Supporting Files/es-DO.lproj/Error.strings


二进制
iOSClient/Supporting Files/es-DO.lproj/Localizable.strings


二进制
iOSClient/Supporting Files/es-EC.lproj/Error.strings


二进制
iOSClient/Supporting Files/es-EC.lproj/Localizable.strings


二进制
iOSClient/Supporting Files/es-GT.lproj/Error.strings


二进制
iOSClient/Supporting Files/es-GT.lproj/Localizable.strings


二进制
iOSClient/Supporting Files/es-HN.lproj/Error.strings


部分文件因为文件数量过多而无法显示