Skip to content

Commit f3de4e0

Browse files
committedApr 19, 2024··
Merge branch 'release/2.5.2'
2 parents a0d2b89 + 1289ab0 commit f3de4e0

File tree

20 files changed

+184
-71
lines changed

20 files changed

+184
-71
lines changed
 

‎.github/workflows/build.yml

+3-4
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@ on:
66
jobs:
77
build:
88
name: Build and test
9-
runs-on: macos-14
9+
runs-on: [self-hosted, macOS, ARM64]
1010
env:
1111
DERIVED_DATA_PATH: 'DerivedData'
1212
DEVICE: 'iPhone 15 Pro'
13-
if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')"
1413
strategy:
1514
matrix:
1615
config: ['freemium', 'premium']
@@ -32,8 +31,8 @@ jobs:
3231
run: |
3332
cd fastlane
3433
./scripts/create-cloud-access-secrets.sh
35-
- name: Select Xcode 15.2
36-
run: sudo xcode-select -s /Applications/Xcode_15.2.app
34+
- name: Select Xcode 15.3
35+
run: sudo xcode-select -s /Applications/Xcode_15.3.app
3736
- name: Configuration for freemium
3837
if: ${{ matrix.config == 'freemium' }}
3938
run: |

‎Cryptomator.xcodeproj/project.pbxproj

+12-2
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,10 @@
391391
740D3684266A1B180058744D /* SettingsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 740D3683266A1B180058744D /* SettingsCoordinator.swift */; };
392392
742679FC26A56CF9004C61BC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 742679F926A56B33004C61BC /* Localizable.strings */; };
393393
742679FD26A56CFA004C61BC /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 742679F926A56B33004C61BC /* Localizable.strings */; };
394+
74420BC32BD2449900E77F92 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 74420BC22BD2449900E77F92 /* PrivacyInfo.xcprivacy */; };
395+
74420BC42BD2449900E77F92 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 74420BC22BD2449900E77F92 /* PrivacyInfo.xcprivacy */; };
396+
74420BC52BD2449900E77F92 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 74420BC22BD2449900E77F92 /* PrivacyInfo.xcprivacy */; };
397+
74420BC62BD2449900E77F92 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 74420BC22BD2449900E77F92 /* PrivacyInfo.xcprivacy */; };
394398
7460FFEF26FCC6FC0018BCC4 /* OnboardingNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7460FFEE26FCC6FC0018BCC4 /* OnboardingNavigationController.swift */; };
395399
746815462475605E00038679 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4AE97DB324572E4A00452814 /* Assets.xcassets */; };
396400
746815472475605E00038679 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4AE97DB524572E4A00452814 /* LaunchScreen.storyboard */; };
@@ -996,6 +1000,7 @@
9961000
74275AE728478E160058AD25 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Intents.strings; sourceTree = "<group>"; };
9971001
74397A842832A05E00CB9410 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Localizable.strings"; sourceTree = "<group>"; };
9981002
74397A852832A09B00CB9410 /* sw-TZ */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "sw-TZ"; path = "sw-TZ.lproj/Localizable.strings"; sourceTree = "<group>"; };
1003+
74420BC22BD2449900E77F92 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
9991004
7460FFED26FB6C100018BCC4 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/Localizable.strings; sourceTree = "<group>"; };
10001005
7460FFEE26FCC6FC0018BCC4 /* OnboardingNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingNavigationController.swift; sourceTree = "<group>"; };
10011006
74626665283BD2D20070924B /* zh-HK */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-HK"; path = "zh-HK.lproj/Localizable.strings"; sourceTree = "<group>"; };
@@ -2024,6 +2029,7 @@
20242029
children = (
20252030
4AE97DB324572E4A00452814 /* Assets.xcassets */,
20262031
4AF91CC625A6437000ACF01E /* Colors.xcassets */,
2032+
74420BC22BD2449900E77F92 /* PrivacyInfo.xcprivacy */,
20272033
742679F926A56B33004C61BC /* Localizable.strings */,
20282034
);
20292035
path = SharedResources;
@@ -2380,6 +2386,7 @@
23802386
isa = PBXResourcesBuildPhase;
23812387
buildActionMask = 2147483647;
23822388
files = (
2389+
74420BC42BD2449900E77F92 /* PrivacyInfo.xcprivacy in Resources */,
23832390
4A80407B2769201400D7D999 /* Localizable.strings in Resources */,
23842391
);
23852392
runOnlyForDeploymentPostprocessing = 0;
@@ -2390,6 +2397,7 @@
23902397
files = (
23912398
4A6A5213268B66AC006F7368 /* Colors.xcassets in Resources */,
23922399
742679FD26A56CFA004C61BC /* Localizable.strings in Resources */,
2400+
74420BC52BD2449900E77F92 /* PrivacyInfo.xcprivacy in Resources */,
23932401
4A6A5212268B6697006F7368 /* Assets.xcassets in Resources */,
23942402
);
23952403
runOnlyForDeploymentPostprocessing = 0;
@@ -2398,6 +2406,7 @@
23982406
isa = PBXResourcesBuildPhase;
23992407
buildActionMask = 2147483647;
24002408
files = (
2409+
74420BC62BD2449900E77F92 /* PrivacyInfo.xcprivacy in Resources */,
24012410
4A1A7AC628327419008EEC84 /* Assets.xcassets in Resources */,
24022411
4A1A7AC528326554008EEC84 /* Localizable.strings in Resources */,
24032412
);
@@ -2413,6 +2422,7 @@
24132422
742679FC26A56CF9004C61BC /* Localizable.strings in Resources */,
24142423
7408E6C52677954000D7FAEA /* about.html in Resources */,
24152424
7408E6CA2677985800D7FAEA /* jquery-3.6.0.slim.min.js in Resources */,
2425+
74420BC32BD2449900E77F92 /* PrivacyInfo.xcprivacy in Resources */,
24162426
746815462475605E00038679 /* Assets.xcassets in Resources */,
24172427
);
24182428
runOnlyForDeploymentPostprocessing = 0;
@@ -3300,7 +3310,7 @@
33003310
GCC_WARN_UNUSED_FUNCTION = YES;
33013311
GCC_WARN_UNUSED_VARIABLE = YES;
33023312
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
3303-
MARKETING_VERSION = 2.5.1;
3313+
MARKETING_VERSION = 2.5.2;
33043314
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
33053315
MTL_FAST_MATH = YES;
33063316
ONLY_ACTIVE_ARCH = YES;
@@ -3362,7 +3372,7 @@
33623372
GCC_WARN_UNUSED_FUNCTION = YES;
33633373
GCC_WARN_UNUSED_VARIABLE = YES;
33643374
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
3365-
MARKETING_VERSION = 2.5.1;
3375+
MARKETING_VERSION = 2.5.2;
33663376
MTL_ENABLE_DEBUG_INFO = NO;
33673377
MTL_FAST_MATH = YES;
33683378
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
@@ -59,8 +59,8 @@
5959
"kind" : "remoteSourceControl",
6060
"location" : "https://github.com/cryptomator/cloud-access-swift.git",
6161
"state" : {
62-
"revision" : "bb9cc1c300be890f3a47efa0ac0808ee7c42146d",
63-
"version" : "1.9.2"
62+
"revision" : "cd7a18abcaf09349f066363c7524b738f4f4ad79",
63+
"version" : "1.10.1"
6464
}
6565
},
6666
{

‎Cryptomator/AppDelegate.swift

+5-4
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,17 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
3838
cleanup()
3939

4040
// Set up cloud storage services
41-
CloudProviderDBManager.shared.useBackgroundSession = false
4241
DropboxSetup.constants = DropboxSetup(appKey: CloudAccessSecrets.dropboxAppKey, sharedContainerIdentifier: nil, keychainService: CryptomatorConstants.mainAppBundleId, forceForegroundSession: true)
4342
GoogleDriveSetup.constants = GoogleDriveSetup(clientId: CloudAccessSecrets.googleDriveClientId, redirectURL: CloudAccessSecrets.googleDriveRedirectURL!, sharedContainerIdentifier: nil)
44-
let oneDriveConfiguration = MSALPublicClientApplicationConfig(clientId: CloudAccessSecrets.oneDriveClientId, redirectUri: CloudAccessSecrets.oneDriveRedirectURI, authority: nil)
45-
oneDriveConfiguration.cacheConfig.keychainSharingGroup = CryptomatorConstants.mainAppBundleId
4643
do {
47-
OneDriveSetup.clientApplication = try MSALPublicClientApplication(configuration: oneDriveConfiguration)
44+
let oneDriveConfiguration = MSALPublicClientApplicationConfig(clientId: CloudAccessSecrets.oneDriveClientId, redirectUri: CloudAccessSecrets.oneDriveRedirectURI, authority: nil)
45+
oneDriveConfiguration.cacheConfig.keychainSharingGroup = CryptomatorConstants.mainAppBundleId
46+
let oneDriveClientApplication = try MSALPublicClientApplication(configuration: oneDriveConfiguration)
47+
OneDriveSetup.constants = OneDriveSetup(clientApplication: oneDriveClientApplication, sharedContainerIdentifier: nil)
4848
} catch {
4949
DDLogError("Setting up OneDrive failed with error: \(error)")
5050
}
51+
PCloudSetup.constants = PCloudSetup(appKey: CloudAccessSecrets.pCloudAppKey, sharedContainerIdentifier: nil)
5152

5253
// Set up payment queue
5354
SKPaymentQueue.default().add(StoreObserver.shared)

‎Cryptomator/Common/CloudAuthenticator.swift

+1-2
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@ class CloudAuthenticator {
5252
}
5353

5454
func authenticatePCloud(from viewController: UIViewController) -> Promise<CloudProviderAccount> {
55-
let authenticator = PCloudAuthenticator(appKey: CloudAccessSecrets.pCloudAppKey)
56-
return authenticator.authenticate(from: viewController).then { credential -> CloudProviderAccount in
55+
return PCloudAuthenticator.authenticate(from: viewController).then { credential -> CloudProviderAccount in
5756
try credential.saveToKeychain()
5857
let account = CloudProviderAccount(accountUID: credential.userID, cloudProviderType: .pCloud)
5958
try self.accountManager.saveNewAccount(account)

‎CryptomatorCommon/Package.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ let package = Package(
2626
)
2727
],
2828
dependencies: [
29-
.package(url: "https://github.com/cryptomator/cloud-access-swift.git", .upToNextMinor(from: "1.9.0")),
29+
.package(url: "https://github.com/cryptomator/cloud-access-swift.git", .upToNextMinor(from: "1.10.0")),
3030
.package(url: "https://github.com/CocoaLumberjack/CocoaLumberjack.git", .upToNextMinor(from: "3.8.0")),
3131
.package(url: "https://github.com/PhilLibs/simple-swift-dependencies", .upToNextMajor(from: "0.1.0")),
3232
.package(url: "https://github.com/siteline/SwiftUI-Introspect.git", .upToNextMajor(from: "0.3.0")),

‎CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/CloudProviderDBManager.swift

+93-41
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,23 @@ import PCloudSDKSwift
1212

1313
public protocol CloudProviderManager {
1414
func getProvider(with accountUID: String) throws -> CloudProvider
15+
func getBackgroundSessionProvider(with accountUID: String, sessionIdentifier: String) throws -> CloudProvider
1516
}
1617

1718
public protocol CloudProviderUpdating {
1819
func providerShouldUpdate(with accountUID: String)
1920
}
2021

22+
struct CachedProvider {
23+
let accountUID: String
24+
let provider: CloudProvider
25+
let backgroundSessionIdentifier: String?
26+
var isBackgroundSession: Bool { backgroundSessionIdentifier != nil }
27+
}
28+
2129
public class CloudProviderDBManager: CloudProviderManager, CloudProviderUpdating {
22-
static var cachedProvider = [String: CloudProvider]()
30+
static var cachedProvider = [CachedProvider]()
2331
public static let shared = CloudProviderDBManager(accountManager: CloudProviderAccountDBManager.shared)
24-
public var useBackgroundSession = true
2532
let accountManager: CloudProviderAccountDBManager
2633

2734
private let maxPageSizeForFileProvider = 500
@@ -31,84 +38,129 @@ public class CloudProviderDBManager: CloudProviderManager, CloudProviderUpdating
3138
}
3239

3340
public func getProvider(with accountUID: String) throws -> CloudProvider {
34-
if let provider = CloudProviderDBManager.cachedProvider[accountUID] {
35-
return provider
41+
if let entry = CloudProviderDBManager.cachedProvider.first(where: {
42+
$0.accountUID == accountUID && !$0.isBackgroundSession
43+
}) {
44+
return entry.provider
3645
}
3746
return try createProvider(for: accountUID)
3847
}
3948

49+
public func getBackgroundSessionProvider(with accountUID: String, sessionIdentifier: String) throws -> any CloudProvider {
50+
if let entry = CloudProviderDBManager.cachedProvider.first(where: {
51+
$0.accountUID == accountUID && $0.backgroundSessionIdentifier == sessionIdentifier
52+
}) {
53+
return entry.provider
54+
}
55+
return try createBackgroundSessionProvider(for: accountUID, sessionIdentifier: sessionIdentifier)
56+
}
57+
4058
/**
4159
Creates and returns a cloud provider for the given `accountUID`.
42-
43-
If `useBackgroundURLSession` is set to `true`, the number of returned items from a `fetchItemList(forFolderAt:pageToken:)` call is limited to 500.
44-
This is necessary because otherwise memory limit problems can occur with folders with many items in the `FileProviderExtension` where a background `URLSession` is used.
4560
*/
4661
func createProvider(for accountUID: String) throws -> CloudProvider {
4762
let cloudProviderType = try accountManager.getCloudProviderType(for: accountUID)
4863
let provider: CloudProvider
4964
switch cloudProviderType {
5065
case .dropbox:
5166
let credential = DropboxCredential(tokenUID: accountUID)
52-
provider = DropboxCloudProvider(credential: credential, maxPageSize: useBackgroundSession ? maxPageSizeForFileProvider : .max)
67+
provider = DropboxCloudProvider(credential: credential, maxPageSize: .max)
5368
case .googleDrive:
5469
let credential = GoogleDriveCredential(userID: accountUID)
55-
provider = try GoogleDriveCloudProvider(credential: credential,
56-
useBackgroundSession: useBackgroundSession,
57-
maxPageSize: useBackgroundSession ? maxPageSizeForFileProvider : .max)
70+
provider = try GoogleDriveCloudProvider(credential: credential, maxPageSize: .max)
5871
case .oneDrive:
5972
let credential = try OneDriveCredential(with: accountUID)
60-
provider = try OneDriveCloudProvider(credential: credential,
61-
useBackgroundSession: useBackgroundSession,
62-
maxPageSize: useBackgroundSession ? maxPageSizeForFileProvider : .max)
73+
provider = try OneDriveCloudProvider(credential: credential, maxPageSize: .max)
6374
case .pCloud:
64-
provider = try createPCloudProvider(for: accountUID)
75+
let credential = try PCloudCredential(userID: accountUID)
76+
let client = PCloud.createClient(with: credential.user)
77+
provider = try PCloudCloudProvider(client: client)
6578
case .webDAV:
66-
guard let credential = WebDAVCredentialManager.shared.getCredentialFromKeychain(with: accountUID) else {
79+
let credential = try getWebDAVCredential(for: accountUID)
80+
let client = WebDAVClient(credential: credential)
81+
provider = try WebDAVProvider(with: client, maxPageSize: .max)
82+
case .localFileSystem:
83+
guard let rootURL = try LocalFileSystemBookmarkManager.getBookmarkedRootURL(for: accountUID) else {
6784
throw CloudProviderAccountError.accountNotFoundError
6885
}
69-
let client: WebDAVClient
70-
if useBackgroundSession {
71-
client = WebDAVClient.withBackgroundSession(credential: credential, sharedContainerIdentifier: CryptomatorConstants.appGroupName)
72-
} else {
73-
client = WebDAVClient(credential: credential)
74-
}
75-
provider = try WebDAVProvider(with: client, maxPageSize: useBackgroundSession ? maxPageSizeForFileProvider : .max)
86+
provider = try LocalFileSystemProvider(rootURL: rootURL, maxPageSize: .max)
87+
case .s3:
88+
let credential = try getS3Credential(for: accountUID)
89+
provider = try S3CloudProvider(credential: credential)
90+
}
91+
CloudProviderDBManager.cachedProvider.append(
92+
.init(
93+
accountUID: accountUID,
94+
provider: provider,
95+
backgroundSessionIdentifier: nil
96+
)
97+
)
98+
return provider
99+
}
100+
101+
/**
102+
Creates and returns a cloud provider for the given `accountUID` using a background URLSession with the given `sessionIdentifier`.
103+
104+
The number of returned items from a `fetchItemList(forFolderAt:pageToken:)` call is limited to 500.
105+
This is necessary because otherwise memory limit problems can occur with folders with many items in the `FileProviderExtension` where a background `URLSession` is used.
106+
*/
107+
func createBackgroundSessionProvider(for accountUID: String, sessionIdentifier: String) throws -> CloudProvider {
108+
let cloudProviderType = try accountManager.getCloudProviderType(for: accountUID)
109+
let provider: CloudProvider
110+
111+
switch cloudProviderType {
112+
case .dropbox:
113+
let credential = DropboxCredential(tokenUID: accountUID)
114+
provider = DropboxCloudProvider(credential: credential, maxPageSize: maxPageSizeForFileProvider)
115+
case .googleDrive:
116+
let credential = GoogleDriveCredential(userID: accountUID)
117+
provider = try GoogleDriveCloudProvider.withBackgroundSession(credential: credential, maxPageSize: maxPageSizeForFileProvider, sessionIdentifier: sessionIdentifier)
118+
case .oneDrive:
119+
let credential = try OneDriveCredential(with: accountUID)
120+
provider = try OneDriveCloudProvider.withBackgroundSession(credential: credential, maxPageSize: maxPageSizeForFileProvider, sessionIdentifier: sessionIdentifier)
121+
case .pCloud:
122+
let credential = try PCloudCredential(userID: accountUID)
123+
let client = PCloud.createBackgroundClient(with: credential.user, sessionIdentifier: sessionIdentifier)
124+
provider = try PCloudCloudProvider(client: client)
125+
case .webDAV:
126+
let credential = try getWebDAVCredential(for: accountUID)
127+
let client = WebDAVClient.withBackgroundSession(credential: credential, sessionIdentifier: sessionIdentifier, sharedContainerIdentifier: CryptomatorConstants.appGroupName)
128+
provider = try WebDAVProvider(with: client, maxPageSize: maxPageSizeForFileProvider)
76129
case .localFileSystem:
77130
guard let rootURL = try LocalFileSystemBookmarkManager.getBookmarkedRootURL(for: accountUID) else {
78131
throw CloudProviderAccountError.accountNotFoundError
79132
}
80-
provider = try LocalFileSystemProvider(rootURL: rootURL, maxPageSize: useBackgroundSession ? maxPageSizeForFileProvider : .max)
133+
provider = try LocalFileSystemProvider(rootURL: rootURL, maxPageSize: maxPageSizeForFileProvider)
81134
case .s3:
82-
provider = try createS3Provider(for: accountUID)
135+
let credential = try getS3Credential(for: accountUID)
136+
provider = try S3CloudProvider.withBackgroundSession(credential: credential, sharedContainerIdentifier: CryptomatorConstants.appGroupName)
83137
}
84-
CloudProviderDBManager.cachedProvider[accountUID] = provider
138+
CloudProviderDBManager.cachedProvider.append(
139+
.init(
140+
accountUID: accountUID,
141+
provider: provider,
142+
backgroundSessionIdentifier: sessionIdentifier
143+
)
144+
)
85145
return provider
86146
}
87147

88-
private func createS3Provider(for accountUID: String) throws -> CloudProvider {
148+
private func getS3Credential(for accountUID: String) throws -> S3Credential {
89149
guard let credential = S3CredentialManager.shared.getCredential(with: accountUID) else {
90150
throw CloudProviderAccountError.accountNotFoundError
91151
}
92-
if useBackgroundSession {
93-
return try S3CloudProvider.withBackgroundSession(credential: credential, sharedContainerIdentifier: CryptomatorConstants.appGroupName)
94-
} else {
95-
return try S3CloudProvider(credential: credential)
96-
}
152+
return credential
97153
}
98154

99-
private func createPCloudProvider(for accountUID: String) throws -> CloudProvider {
100-
let credential = try PCloudCredential(userID: accountUID)
101-
let client: PCloudClient
102-
if useBackgroundSession {
103-
client = PCloud.createBackgroundClient(with: credential.user, sharedContainerIdentifier: CryptomatorConstants.appGroupName)
104-
} else {
105-
client = PCloud.createClient(with: credential.user)
155+
private func getWebDAVCredential(for accountUID: String) throws -> WebDAVCredential {
156+
guard let credential = WebDAVCredentialManager.shared.getCredentialFromKeychain(with: accountUID) else {
157+
throw CloudProviderAccountError.accountNotFoundError
106158
}
107-
return try PCloudCloudProvider(client: client)
159+
return credential
108160
}
109161

110162
public func providerShouldUpdate(with accountUID: String) {
111-
CloudProviderDBManager.cachedProvider[accountUID] = nil
163+
CloudProviderDBManager.cachedProvider.removeAll(where: { $0.accountUID == accountUID })
112164
// call XPCService for FileProvider
113165
}
114166
}

‎CryptomatorCommon/Sources/CryptomatorCommonCore/Manager/VaultDBManager.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,8 @@ public class VaultDBManager: VaultManager {
483483
private func createVaultProvider(cachedVault: CachedVault, masterkey: Masterkey, masterkeyFile: MasterkeyFile) throws -> CloudProvider {
484484
let vaultUID = cachedVault.vaultUID
485485
let vaultAccount = try vaultAccountManager.getAccount(with: vaultUID)
486-
let provider = try providerManager.getProvider(with: vaultAccount.delegateAccountUID)
486+
// it's important to use the vaultUID as background URLSession identifier to avoid identifier collisions
487+
let provider = try providerManager.getBackgroundSessionProvider(with: vaultAccount.delegateAccountUID, sessionIdentifier: vaultUID)
487488
let decorator: CloudProvider
488489
if let vaultConfigToken = cachedVault.vaultConfigToken {
489490
let unverifiedVaultConfig = try UnverifiedVaultConfig(token: vaultConfigToken)

‎CryptomatorCommon/Tests/CryptomatorCommonCoreTests/Manager/CloudProviderManagerTests.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ class CloudProviderManagerTests: XCTestCase {
2525
DropboxSetup.constants = DropboxSetup(appKey: "", sharedContainerIdentifier: nil, keychainService: nil, forceForegroundSession: false)
2626
let account = CloudProviderAccount(accountUID: UUID().uuidString, cloudProviderType: .dropbox)
2727
try accountManager.saveNewAccount(account)
28-
XCTAssertNil(CloudProviderDBManager.cachedProvider[account.accountUID])
28+
XCTAssert(CloudProviderDBManager.cachedProvider.isEmpty)
2929
let provider = try manager.getProvider(with: account.accountUID)
3030
guard provider is DropboxCloudProvider else {
3131
XCTFail("Provider has wrong type")
3232
return
3333
}
34-
XCTAssertNotNil(CloudProviderDBManager.cachedProvider[account.accountUID])
34+
XCTAssertEqual(CloudProviderDBManager.cachedProvider.filter { $0.accountUID == account.accountUID }.count, 1)
3535
}
3636
}

‎FileProviderExtension/FileProviderExtension.swift

+3-2
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,11 @@ class FileProviderExtension: NSFileProviderExtension {
3030
FileProviderExtension.sharedDatabaseInitialized = true
3131
DropboxSetup.constants = DropboxSetup(appKey: CloudAccessSecrets.dropboxAppKey, sharedContainerIdentifier: CryptomatorConstants.appGroupName, keychainService: CryptomatorConstants.mainAppBundleId, forceForegroundSession: false)
3232
GoogleDriveSetup.constants = GoogleDriveSetup(clientId: CloudAccessSecrets.googleDriveClientId, redirectURL: CloudAccessSecrets.googleDriveRedirectURL!, sharedContainerIdentifier: CryptomatorConstants.appGroupName)
33-
OneDriveSetup.sharedContainerIdentifier = CryptomatorConstants.appGroupName
3433
let oneDriveConfiguration = MSALPublicClientApplicationConfig(clientId: CloudAccessSecrets.oneDriveClientId, redirectUri: CloudAccessSecrets.oneDriveRedirectURI, authority: nil)
3534
oneDriveConfiguration.cacheConfig.keychainSharingGroup = CryptomatorConstants.mainAppBundleId
36-
OneDriveSetup.clientApplication = try MSALPublicClientApplication(configuration: oneDriveConfiguration)
35+
let oneDriveClientApplication = try MSALPublicClientApplication(configuration: oneDriveConfiguration)
36+
OneDriveSetup.constants = OneDriveSetup(clientApplication: oneDriveClientApplication, sharedContainerIdentifier: CryptomatorConstants.appGroupName)
37+
PCloudSetup.constants = PCloudSetup(appKey: CloudAccessSecrets.pCloudAppKey, sharedContainerIdentifier: CryptomatorConstants.appGroupName)
3738
} catch {
3839
// MARK: Handle error
3940

‎FileProviderExtensionUI/RootViewController.swift

+5-4
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,17 @@ class RootViewController: FPUIActionExtensionViewController {
6161
LoggerSetup.oneTimeSetup()
6262

6363
// Set up cloud storage services
64-
CloudProviderDBManager.shared.useBackgroundSession = false
6564
DropboxSetup.constants = DropboxSetup(appKey: CloudAccessSecrets.dropboxAppKey, sharedContainerIdentifier: nil, keychainService: CryptomatorConstants.mainAppBundleId, forceForegroundSession: true)
6665
GoogleDriveSetup.constants = GoogleDriveSetup(clientId: CloudAccessSecrets.googleDriveClientId, redirectURL: CloudAccessSecrets.googleDriveRedirectURL!, sharedContainerIdentifier: nil)
67-
let oneDriveConfiguration = MSALPublicClientApplicationConfig(clientId: CloudAccessSecrets.oneDriveClientId, redirectUri: CloudAccessSecrets.oneDriveRedirectURI, authority: nil)
68-
oneDriveConfiguration.cacheConfig.keychainSharingGroup = CryptomatorConstants.mainAppBundleId
6966
do {
70-
OneDriveSetup.clientApplication = try MSALPublicClientApplication(configuration: oneDriveConfiguration)
67+
let oneDriveConfiguration = MSALPublicClientApplicationConfig(clientId: CloudAccessSecrets.oneDriveClientId, redirectUri: CloudAccessSecrets.oneDriveRedirectURI, authority: nil)
68+
oneDriveConfiguration.cacheConfig.keychainSharingGroup = CryptomatorConstants.mainAppBundleId
69+
let oneDriveClientApplication = try MSALPublicClientApplication(configuration: oneDriveConfiguration)
70+
OneDriveSetup.constants = OneDriveSetup(clientApplication: oneDriveClientApplication, sharedContainerIdentifier: nil)
7171
} catch {
7272
DDLogError("Setting up OneDrive failed with error: \(error)")
7373
}
74+
PCloudSetup.constants = PCloudSetup(appKey: CloudAccessSecrets.pCloudAppKey, sharedContainerIdentifier: nil)
7475
return {}
7576
}()
7677

‎SharedResources/PrivacyInfo.xcprivacy

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>NSPrivacyAccessedAPITypes</key>
6+
<array>
7+
<dict>
8+
<key>NSPrivacyAccessedAPIType</key>
9+
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
10+
<key>NSPrivacyAccessedAPITypeReasons</key>
11+
<array>
12+
<string>DDA9.1</string>
13+
<string>C617.1</string>
14+
<string>3B52.1</string>
15+
</array>
16+
</dict>
17+
<dict>
18+
<key>NSPrivacyAccessedAPIType</key>
19+
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
20+
<key>NSPrivacyAccessedAPITypeReasons</key>
21+
<array>
22+
<string>CA92.1</string>
23+
<string>1C8F.1</string>
24+
</array>
25+
</dict>
26+
</array>
27+
</dict>
28+
</plist>

‎SharedResources/ca.lproj/Localizable.strings

+10
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"common.button.next" = "Següent";
2323
"common.button.ok" = "D'acord";
2424
"common.button.refresh" = "Refresca";
25+
"common.button.register" = "Registre";
2526
"common.button.remove" = "Elimina";
2627
"common.button.retry" = "Reintenta";
2728
"common.button.signOut" = "Tanca la sessió";
@@ -59,6 +60,7 @@
5960
"addVault.openExistingVault.chooseCloud.header" = "On es troba la caixa forta?";
6061
"addVault.openExistingVault.detectedMasterkey.text" = "Cryptomator ha detectat la caixa forta \"%@\".\nVoleu afegir aquesta caixa forta?";
6162
"addVault.openExistingVault.detectedMasterkey.add" = "Afegeix aquesta caixa forta";
63+
"addVault.openExistingVault.downloadVault.progress" = "Descàrrega de la caixa forta…";
6264
"addVault.openExistingVault.password.footer" = "Introduïu la contrasenya per a \"%@\".";
6365
"addVault.openExistingVault.progress" = "Ara s'afegeix la caixa forta…";
6466
"addVault.success.info" = "S'ha afegit la caixa forta \"%@\".\nAccediu a la caixa forta via l'app de fitxers.";
@@ -111,10 +113,18 @@
111113

112114
"getFolderIntent.error.missingPath" = "No s'ha proporcionat cap ruta. Proporcioneu una ruta vàlida que retorni una carpeta.";
113115
"getFolderIntent.error.noVaultSelected" = "No s'ha seleccionat cap caixa forta.";
116+
117+
"hubAuthentication.title" = "Caixa forta de Hub";
114118
"hubAuthentication.accessNotGranted" = "El vostre dispositiu no ha estat encara autoritzat a accedir a aquesta caixa forta. Demaneu autorització al propietari.";
115119
"hubAuthentication.licenseExceeded" = "Aquest Cryptomator Hub no té una llicència vàlida. Informa si us plau a l'administrador perquè actualitzi o renovi la llicència.";
116120
"hubAuthentication.deviceRegistration.deviceName.cells.name" = "Nom del dispositiu";
121+
"hubAuthentication.deviceRegistration.deviceName.footer.title" = "Sembla que és el primer accés al Hub des d'aquest dispositiu. Per identificar-lo i poder autoritzar l'accés heu de posar nom a aquest dispositiu.";
122+
"hubAuthentication.deviceRegistration.accountKey.footer.title" = "Cal la vostra Account Key per a iniciar sessió des d'una aplicació o navegador nous. La trobareu al vostre perfil.";
123+
"hubAuthentication.deviceRegistration.needsAuthorization.alert.title" = "Registre de dispositiu correcte";
117124
"hubAuthentication.deviceRegistration.needsAuthorization.alert.message" = "Per a accedir a la caixa forta, el vostre dispositiu ha de ser autoritzat pel propietari de la caixa.";
125+
"hubAuthentication.requireAccountInit.alert.title" = "Acció necessària";
126+
"hubAuthentication.requireAccountInit.alert.message" = "Per a continuar, si us plau, seguiu els passos necessaris en el vostre perfil d'usuari de Hub.";
127+
"hubAuthentication.requireAccountInit.alert.actionButton" = "Vés al perfil";
118128

119129
"intents.saveFile.missingFile" = "El fitxer proporcionat no és vàlid.";
120130
"intents.saveFile.invalidFolder" = "La carpeta proporcionada no és vàlida.";

‎SharedResources/cs.lproj/Localizable.strings

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
"addVault.openExistingVault.chooseCloud.header" = "Kde je trezor umístěn?";
6161
"addVault.openExistingVault.detectedMasterkey.text" = "Cryptomator detekoval trezor \"%@\".\nChcete přidat tento trezor?";
6262
"addVault.openExistingVault.detectedMasterkey.add" = "Přidat tento trezor";
63+
"addVault.openExistingVault.downloadVault.progress" = "Stahování trezoru…";
6364
"addVault.openExistingVault.password.footer" = "Zadejte heslo pro \"%@\".";
6465
"addVault.openExistingVault.progress" = "Přidávání trezoru…";
6566
"addVault.success.info" = "Úspěšně přidán trezor \"%@\".\nPřistupujte k tomuto trezoru prostřednictvím aplikace Soubory.";

‎SharedResources/da.lproj/Localizable.strings

+11-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
"common.button.enable" = "Aktivér";
2222
"common.button.next" = "Næste";
2323
"common.button.ok" = "OK";
24-
"common.button.refresh" = "Opdatér";
24+
"common.button.refresh" = "Genopfrisk";
25+
"common.button.register" = "Registrer";
2526
"common.button.remove" = "Fjern";
2627
"common.button.retry" = "Forsøg igen";
2728
"common.button.signOut" = "Log ud";
@@ -59,6 +60,7 @@
5960
"addVault.openExistingVault.chooseCloud.header" = "Hvor er boksen placeret?";
6061
"addVault.openExistingVault.detectedMasterkey.text" = "Kryptomator fandt boksen \"%@\".\nVil du tilføje denne boks?";
6162
"addVault.openExistingVault.detectedMasterkey.add" = "Tilføj denne boks";
63+
"addVault.openExistingVault.downloadVault.progress" = "Downloader Boks…";
6264
"addVault.openExistingVault.password.footer" = "Indtast adgangskode for \"%@\".";
6365
"addVault.openExistingVault.progress" = "Tilføjer boks…";
6466
"addVault.success.info" = "Tilføjede boksen \"%@\".\nFå adgang til denne boks via Filer appen.";
@@ -111,10 +113,18 @@
111113

112114
"getFolderIntent.error.missingPath" = "Ingen sti blev angivet. Angiv venligst en gyldig sti til en mappe.";
113115
"getFolderIntent.error.noVaultSelected" = "Ingen boks er valgt.";
116+
117+
"hubAuthentication.title" = "Hub Boks";
114118
"hubAuthentication.accessNotGranted" = "Din enhed er endnu ikke blevet godkendt til at få adgang til denne boks. Spørg boks-ejeren om godkendelse.";
115119
"hubAuthentication.licenseExceeded" = "Din Cryptomator Hub har en ugyldig licens. Få venligst en Hub administrator til at opgradere eller forny licensen.";
116120
"hubAuthentication.deviceRegistration.deviceName.cells.name" = "Enheds-navn";
121+
"hubAuthentication.deviceRegistration.deviceName.footer.title" = "Det ser ud til at dette er første gang denne enhed tilgår Hub. For at kunne identificere den for adgangstilladelse, skal du navngive denne enhed.";
122+
"hubAuthentication.deviceRegistration.accountKey.footer.title" = "Din kontonøgle er påkrævet til at logge ind fra nye apps eller browsere. Den kan findes i din profil.";
123+
"hubAuthentication.deviceRegistration.needsAuthorization.alert.title" = "Registrering af Enhed Lykkedes";
117124
"hubAuthentication.deviceRegistration.needsAuthorization.alert.message" = "For at tilgå boksen, skal din enhed godkendes af boks-ejeren.";
125+
"hubAuthentication.requireAccountInit.alert.title" = "Handling Påkrævet";
126+
"hubAuthentication.requireAccountInit.alert.message" = "For at fortsætte, skal du fuldføre de nødvendige trin i din Hub brugerprofil.";
127+
"hubAuthentication.requireAccountInit.alert.actionButton" = "Gå til Profil";
118128

119129
"intents.saveFile.missingFile" = "Den angivne fil er ikke gyldig.";
120130
"intents.saveFile.invalidFolder" = "Den angivne mappe er ikke gyldig.";

‎fastlane/changelog.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
- Fixed "Content Unavailable" error when unlocking vault that was created on macOS in iCloud Drive (#316)
1+
- Fixed "Content Unavailable" error when unlocking multiple vaults in Google Drive, OneDrive, pCloud, and WebDAV (#342, #345, #351)
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
- Fehler "Inhalt nicht verfügbar" beim Entsperren eines Tresors, der auf macOS in iCloud Drive erstellt wurde, behoben (#316)
1+
- Fehler "Inhalt nicht verfügbar" beim Entsperren mehrerer Tresore in Google Drive, OneDrive, pCloud und WebDAV behoben (#342, #345, #351)
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
- Fixed "Content Unavailable" error when unlocking vault that was created on macOS in iCloud Drive (#316)
1+
- Fixed "Content Unavailable" error when unlocking multiple vaults in Google Drive, OneDrive, pCloud, and WebDAV (#342, #345, #351)
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
- Fehler "Inhalt nicht verfügbar" beim Entsperren eines Tresors, der auf macOS in iCloud Drive erstellt wurde, behoben (#316)
1+
- Fehler "Inhalt nicht verfügbar" beim Entsperren mehrerer Tresore in Google Drive, OneDrive, pCloud und WebDAV behoben (#342, #345, #351)
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
- Fixed "Content Unavailable" error when unlocking vault that was created on macOS in iCloud Drive (#316)
1+
- Fixed "Content Unavailable" error when unlocking multiple vaults in Google Drive, OneDrive, pCloud, and WebDAV (#342, #345, #351)

0 commit comments

Comments
 (0)
Please sign in to comment.