Skip to content

Commit c0aa245

Browse files
committed
Merge branch 'release/2.2.2'
2 parents f03b61d + c976b42 commit c0aa245

File tree

14 files changed

+87
-87
lines changed

14 files changed

+87
-87
lines changed

Cryptomator.xcodeproj/project.pbxproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -2852,7 +2852,7 @@
28522852
GCC_WARN_UNUSED_FUNCTION = YES;
28532853
GCC_WARN_UNUSED_VARIABLE = YES;
28542854
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
2855-
MARKETING_VERSION = 2.2.1;
2855+
MARKETING_VERSION = 2.2.2;
28562856
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
28572857
MTL_FAST_MATH = YES;
28582858
ONLY_ACTIVE_ARCH = YES;
@@ -2914,7 +2914,7 @@
29142914
GCC_WARN_UNUSED_FUNCTION = YES;
29152915
GCC_WARN_UNUSED_VARIABLE = YES;
29162916
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
2917-
MARKETING_VERSION = 2.2.1;
2917+
MARKETING_VERSION = 2.2.2;
29182918
MTL_ENABLE_DEBUG_INFO = NO;
29192919
MTL_FAST_MATH = YES;
29202920
OTHER_SWIFT_FLAGS = "-Xfrontend -warn-long-expression-type-checking=200 -Xfrontend -warn-long-function-bodies=200";

Cryptomator.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333
"repositoryURL": "https://github.com/cryptomator/cloud-access-swift.git",
3434
"state": {
3535
"branch": null,
36-
"revision": "fa5c2e9a9db0f91981e728679fca14005d230eac",
37-
"version": "1.2.1"
36+
"revision": "5e089b48d0dafe15f92c199dc82bbda0aa5cfc91",
37+
"version": "1.2.2"
3838
}
3939
},
4040
{

Cryptomator/AppDelegate.swift

+3-2
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
4242
DDLogError("Initializing CryptomatorDatabase failed with error: \(error)")
4343
return false
4444
}
45-
45+
VaultDBManager.shared.recoverMissingFileProviderDomains().catch { error in
46+
DDLogError("Recover missing FileProvider domains failed with error: \(error)")
47+
}
4648
// Clean up
47-
_ = VaultDBManager.shared.removeAllUnusedFileProviderDomains()
4849
do {
4950
let webDAVAccountUIDs = try CloudProviderAccountDBManager.shared.getAllAccountUIDs(for: .webDAV(type: .custom))
5051
try WebDAVAuthenticator.removeUnusedWebDAVCredentials(existingAccountUIDs: webDAVAccountUIDs)

Cryptomator/Common/CloudAuthenticator.swift

+19-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
// Copyright © 2021 Skymatic GmbH. All rights reserved.
77
//
88

9+
import CocoaLumberjackSwift
910
import CryptomatorCloudAccess
1011
import CryptomatorCloudAccessCore
1112
import CryptomatorCommonCore
@@ -16,10 +17,12 @@ import UIKit
1617
class CloudAuthenticator {
1718
private let accountManager: CloudProviderAccountManager
1819
private let vaultManager: VaultManager
20+
private let vaultAccountManager: VaultAccountManager
1921

20-
init(accountManager: CloudProviderAccountManager, vaultManager: VaultManager = VaultDBManager.shared) {
22+
init(accountManager: CloudProviderAccountManager, vaultManager: VaultManager = VaultDBManager.shared, vaultAccountManager: VaultAccountManager = VaultAccountDBManager.shared) {
2123
self.accountManager = accountManager
2224
self.vaultManager = vaultManager
25+
self.vaultAccountManager = vaultAccountManager
2326
}
2427

2528
func authenticateDropbox(from viewController: UIViewController) -> Promise<CloudProviderAccount> {
@@ -102,8 +105,21 @@ class CloudAuthenticator {
102105
case .localFileSystem:
103106
break
104107
}
105-
try accountManager.removeAccount(with: account.accountUID)
106-
_ = vaultManager.removeAllUnusedFileProviderDomains()
108+
let correspondingVaults = try vaultAccountManager.getAllAccounts().filter { $0.delegateAccountUID == account.accountUID }
109+
_ = Promise<Void>(on: .global()) { fulfill, _ in
110+
for correspondingVault in correspondingVaults {
111+
do {
112+
try awaitPromise(self.vaultManager.removeVault(withUID: correspondingVault.vaultUID))
113+
} catch {
114+
DDLogError("Remove corresponding vault: \(correspondingVault.vaultName) after deauthenticated account: \(account) - failed with error: \(error)")
115+
}
116+
}
117+
fulfill(())
118+
}.then {
119+
try self.accountManager.removeAccount(with: account.accountUID)
120+
}.catch { error in
121+
DDLogError("Deauthenticate account: \(account) failed with error: \(error)")
122+
}
107123
}
108124
}
109125

Cryptomator/Common/EditableTableViewHeader.swift

+24-15
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ class EditableTableViewHeader: UITableViewHeaderFooterView {
3434
return label
3535
}()
3636

37+
private lazy var stack = UIStackView(arrangedSubviews: [title, editButton])
38+
3739
convenience init(title: String) {
3840
self.init()
3941
self.title.text = title.uppercased()
@@ -42,23 +44,30 @@ class EditableTableViewHeader: UITableViewHeaderFooterView {
4244
convenience init() {
4345
self.init(reuseIdentifier: nil)
4446

45-
editButton.translatesAutoresizingMaskIntoConstraints = false
46-
title.translatesAutoresizingMaskIntoConstraints = false
47-
48-
contentView.addSubview(editButton)
49-
contentView.addSubview(title)
50-
47+
title.setContentHuggingPriority(.defaultLow, for: .vertical)
48+
editButton.setContentHuggingPriority(.defaultHigh, for: .horizontal)
49+
stack.translatesAutoresizingMaskIntoConstraints = false
50+
contentView.addSubview(stack)
51+
let topAnchor = stack.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor, constant: 20)
52+
topAnchor.priority = .almostRequired
53+
let bottomAnchor = stack.bottomAnchor.constraint(equalTo: contentView.layoutMarginsGuide.bottomAnchor)
54+
bottomAnchor.priority = .almostRequired
5155
NSLayoutConstraint.activate([
52-
title.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor),
53-
title.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor),
54-
title.trailingAnchor.constraint(lessThanOrEqualTo: editButton.leadingAnchor, constant: -10),
55-
title.bottomAnchor.constraint(equalTo: contentView.layoutMarginsGuide.bottomAnchor),
56-
title.centerYAnchor.constraint(equalTo: contentView.layoutMarginsGuide.centerYAnchor),
57-
58-
editButton.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor),
59-
editButton.trailingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor),
60-
editButton.centerYAnchor.constraint(equalTo: contentView.layoutMarginsGuide.centerYAnchor)
56+
topAnchor,
57+
bottomAnchor
6158
])
59+
NSLayoutConstraint.activate(stack.constraints(equalTo: contentView.layoutMarginsGuide, directions: [.horizontal]))
60+
}
61+
62+
func configure(with traitCollection: UITraitCollection) {
63+
let preferredContentSize = traitCollection.preferredContentSizeCategory
64+
if preferredContentSize.isAccessibilityCategory {
65+
stack.axis = .vertical
66+
stack.alignment = .leading
67+
} else {
68+
stack.axis = .horizontal
69+
stack.alignment = .firstBaseline
70+
}
6271
}
6372

6473
private func changeEditButton() {

Cryptomator/Common/ListViewController.swift

+1-4
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,10 @@ class ListViewController<T: TableViewCellViewModel>: BaseUITableViewController {
9898
// MARK: - UITableViewDelegate
9999

100100
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
101+
header.configure(with: tableView.traitCollection)
101102
return header
102103
}
103104

104-
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
105-
return 44
106-
}
107-
108105
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
109106
let deleteAction = UIContextualAction(style: .destructive, title: viewModel.removeAlert.confirmButtonText) { _, _, completion in
110107
let alertController = UIAlertController(title: self.viewModel.removeAlert.title, message: self.viewModel.removeAlert.message, preferredStyle: .alert)

CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/VaultDBManager.swift

+28-19
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ public protocol VaultManager {
2828
func manualUnlockVault(withUID vaultUID: String, kek: [UInt8]) throws -> CloudProvider
2929
func createVaultProvider(withUID vaultUID: String, masterkey: Masterkey) throws -> CloudProvider
3030
func removeVault(withUID vaultUID: String) throws -> Promise<Void>
31-
func removeAllUnusedFileProviderDomains() -> Promise<Void>
3231
func moveVault(account: VaultAccount, to targetVaultPath: CloudPath) -> Promise<Void>
3332
func changePassphrase(oldPassphrase: String, newPassphrase: String, forVaultUID vaultUID: String) -> Promise<Void>
3433
}
@@ -260,24 +259,6 @@ public class VaultDBManager: VaultManager {
260259
}
261260
}
262261

263-
public func removeAllUnusedFileProviderDomains() -> Promise<Void> {
264-
let vaultUIDs: [String]
265-
do {
266-
let vaults = try vaultAccountManager.getAllAccounts()
267-
vaultUIDs = vaults.map { $0.vaultUID }
268-
} catch {
269-
return Promise(error)
270-
}
271-
return NSFileProviderManager.getDomains().then { domains -> Promise<Void> in
272-
let unusedDomains = domains.filter { !vaultUIDs.contains($0.identifier.rawValue) }
273-
return self.removeDomainsFromFileProvider(unusedDomains)
274-
}.then { _ in
275-
DDLogInfo("Removed all unused FileProviderDomains")
276-
}.catch { error in
277-
DDLogError("Removing all unused FileProviderDomains failed with error: \(error)")
278-
}
279-
}
280-
281262
func removeDomainsFromFileProvider(_ domains: [NSFileProviderDomain]) -> Promise<Void> {
282263
return Promise(on: .global()) { fulfill, _ in
283264
for domain in domains {
@@ -369,6 +350,20 @@ public class VaultDBManager: VaultManager {
369350
}
370351
}
371352

353+
public func recoverMissingFileProviderDomains() -> Promise<Void> {
354+
let vaults: [VaultAccount]
355+
do {
356+
vaults = try vaultAccountManager.getAllAccounts()
357+
} catch {
358+
return Promise(error)
359+
}
360+
return NSFileProviderManager.getDomains().then { domains -> Promise<Void> in
361+
let domainIdentifiers = domains.map { $0.identifier.rawValue }
362+
let vaultsWithMissingDomains = vaults.filter { !domainIdentifiers.contains($0.vaultUID) }
363+
return self.recoverFileProviderDomains(for: vaultsWithMissingDomains)
364+
}
365+
}
366+
372367
// MARK: - Internal
373368

374369
func postProcessVaultCreation(cachedVault: CachedVault, password: String, storePasswordInKeychain: Bool) throws {
@@ -427,6 +422,20 @@ public class VaultDBManager: VaultManager {
427422
let domain = NSFileProviderDomain(vaultUID: vaultUID, displayName: displayName)
428423
return NSFileProviderManager.add(domain)
429424
}
425+
426+
private func recoverFileProviderDomains(for vaults: [VaultAccount]) -> Promise<Void> {
427+
return Promise(on: .global()) { fulfill, _ in
428+
for vault in vaults {
429+
do {
430+
try awaitPromise(self.addFileProviderDomain(forVaultUID: vault.vaultUID, displayName: vault.vaultName))
431+
DDLogInfo("Successfully recovered FileProvider domain for vault: \(vault.vaultName) - \(vault.vaultUID)")
432+
} catch {
433+
DDLogError("Recover FileProvider domain for vault: \(vault.vaultName) - \(vault.vaultUID) failed with error: \(error)")
434+
}
435+
}
436+
fulfill(())
437+
}
438+
}
430439
}
431440

432441
extension CloudProvider {

CryptomatorCommon/Sources/CryptomatorCommonCore/Mocks/VaultManagerMock.swift

-19
Original file line numberDiff line numberDiff line change
@@ -156,25 +156,6 @@ final class VaultManagerMock: VaultManager {
156156
return try removeVaultWithUIDClosure.map({ try $0(vaultUID) }) ?? removeVaultWithUIDReturnValue
157157
}
158158

159-
// MARK: - removeAllUnusedFileProviderDomains
160-
161-
var removeAllUnusedFileProviderDomainsThrowableError: Error?
162-
var removeAllUnusedFileProviderDomainsCallsCount = 0
163-
var removeAllUnusedFileProviderDomainsCalled: Bool {
164-
removeAllUnusedFileProviderDomainsCallsCount > 0
165-
}
166-
167-
var removeAllUnusedFileProviderDomainsReturnValue: Promise<Void>!
168-
var removeAllUnusedFileProviderDomainsClosure: (() -> Promise<Void>)?
169-
170-
func removeAllUnusedFileProviderDomains() -> Promise<Void> {
171-
if let error = removeAllUnusedFileProviderDomainsThrowableError {
172-
return Promise(error)
173-
}
174-
removeAllUnusedFileProviderDomainsCallsCount += 1
175-
return removeAllUnusedFileProviderDomainsClosure.map({ $0() }) ?? removeAllUnusedFileProviderDomainsReturnValue
176-
}
177-
178159
// MARK: - moveVault
179160

180161
var moveVaultAccountToThrowableError: Error?

CryptomatorCommon/Sources/CryptomatorCommonCore/WebDAV/WebDAVAuthenticatorError+Localization.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import Foundation
1212
extension WebDAVAuthenticatorError: LocalizedError {
1313
public var errorDescription: String? {
1414
switch self {
15-
case .unsupportedProcotol:
15+
case .unsupportedProtocol:
1616
return LocalizedString.getValue("webDAVAuthenticator.error.unsupportedProtocol")
1717
case .untrustedCertificate:
1818
return LocalizedString.getValue("webDAVAuthenticator.error.untrustedCertificate")

CryptomatorFileProviderTests/DB/CachedFileManagerTests.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ class CacheTestCase: XCTestCase {
244244
}
245245

246246
func getRandomData(sizeInBytes: Int) -> Data {
247-
let bytes = [UInt32](repeating: 0, count: sizeInBytes).map { _ in arc4random() }
247+
let bytes = [UInt32](repeating: 0, count: sizeInBytes).map { _ in UInt32.random(in: UInt32.min ... UInt32.max) }
248248
let data = Data(bytes: bytes, count: sizeInBytes)
249249
return data
250250
}

CryptomatorTests/CreateNewVaultPasswordViewModelTests.swift

-4
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,6 @@ private class PasswordVaultManagerMock: VaultManager {
171171
return Promise(MockError.notMocked)
172172
}
173173

174-
func removeAllUnusedFileProviderDomains() -> Promise<Void> {
175-
return Promise(MockError.notMocked)
176-
}
177-
178174
func moveVault(account: VaultAccount, to targetVaultPath: CloudPath) -> Promise<Void> {
179175
return Promise(MockError.notMocked)
180176
}

fastlane/changelog.txt

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,2 @@
1-
- Fixed copying of folders that sometimes doesn't finish completely and the vault gets "stuck" (#173, #197)
2-
- Fixed "not found" error in Google Drive due to unresolvable shortcuts (#194)
3-
- Fixed unexpected error when the path contained certain keywords like "Shared" in OneDrive (#189)
4-
- Fixed crash on iPad when tapping on disclosure button for signing out of a cloud storage service
5-
- Fixed missing pCloud in settings under cloud services
1+
- Fixed missing vaults in Files app (#176)
2+
- Fixed missing shortcuts in Google Drive (#201)
+2-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,2 @@
1-
- Kopieren von Ordnern behoben, was manchmal nicht vollständig abgeschlossen werden konnte und der Tresor „stecken“ bleibt (#173, #197)
2-
- Fehler „nicht gefunden“ aufgrund von nicht auflösbaren Shortcuts in Google Drive behoben (#194)
3-
- Unerwarteten Fehler behoben, wenn der Pfad bestimmte Schlüsselwörter wie „Shared“ in OneDrive enthielt (#189)
4-
- Absturz auf dem iPad behoben, wenn man auf den Disclosure-Button tippt, um sich von einem Cloudspeicher-Dienst abzumelden
5-
- Fehlendes pCloud in den Einstellungen unter Cloud-Dienste behoben
1+
- Fehlende Tresore in der App „Dateien“ behoben (#176)
2+
- Fehlende Shortcuts in Google Drive behoben (#201)
+2-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,2 @@
1-
- Fixed copying of folders that sometimes doesn't finish completely and the vault gets "stuck" (#173, #197)
2-
- Fixed "not found" error in Google Drive due to unresolvable shortcuts (#194)
3-
- Fixed unexpected error when the path contained certain keywords like "Shared" in OneDrive (#189)
4-
- Fixed crash on iPad when tapping on disclosure button for signing out of a cloud storage service
5-
- Fixed missing pCloud in settings under cloud services
1+
- Fixed missing vaults in Files app (#176)
2+
- Fixed missing shortcuts in Google Drive (#201)

0 commit comments

Comments
 (0)