diff --git a/ios/Runner/Native/TransferManager.swift b/ios/Runner/Native/TransferManager.swift index dae9465..a303c07 100644 --- a/ios/Runner/Native/TransferManager.swift +++ b/ios/Runner/Native/TransferManager.swift @@ -34,6 +34,11 @@ final class TransferManager: NSObject { config.sessionSendsLaunchEvents = true config.isDiscretionary = false config.waitsForConnectivity = true + // Two accounts can share a server: authenticate by the request's own + // header only, never a cookie another account's request left behind. + config.httpShouldSetCookies = false + config.httpCookieAcceptPolicy = .never + config.urlCredentialStorage = nil return URLSession(configuration: config, delegate: self, delegateQueue: nil) }() diff --git a/ios/Shared/DavFolders.swift b/ios/Shared/DavFolders.swift index bb502c6..98f538a 100644 --- a/ios/Shared/DavFolders.swift +++ b/ios/Shared/DavFolders.swift @@ -149,6 +149,20 @@ enum DavClient { /// Every child folder, hidden and external ones included - the sheet's /// toggles filter that list in memory, so changing one doesn't refetch. + /// Two accounts can live on the same server, so a request must be + /// authenticated by its own `Authorization` header alone - never by a + /// session cookie or credential a previous account's request left behind + /// in the shared stores, or the second account could be answered as the + /// first. + private static let session: URLSession = { + let config = URLSessionConfiguration.ephemeral + config.httpShouldSetCookies = false + config.httpCookieAcceptPolicy = .never + config.urlCredentialStorage = nil + config.requestCachePolicy = .reloadIgnoringLocalCacheData + return URLSession(configuration: config) + }() + static func listFolders(account: SharedAccount, path: String) async throws -> [DavFolder] { guard let url = WebDAV.fileURL(serverUrl: account.serverUrl, username: account.username, remotePath: path) else { throw TransferError(message: "Invalid server address.") } @@ -160,8 +174,9 @@ enum DavClient { request.httpBody = body.data(using: .utf8) request.timeoutInterval = 20 - let (data, response) = try await URLSession.shared.data(for: request) + let (data, response) = try await session.data(for: request) let status = (response as? HTTPURLResponse)?.statusCode ?? 0 + NSLog("[DavClient] PROPFIND %@ as %@ -> %d", url.path, account.username, status) guard status == 207 else { throw TransferError(message: status == 401 ? "Signed out - open Noo to sign in again." : "Server returned \(status).") } diff --git a/ios/Shared/ShareUpload.swift b/ios/Shared/ShareUpload.swift index cb1a9a2..eb68ff1 100644 --- a/ios/Shared/ShareUpload.swift +++ b/ios/Shared/ShareUpload.swift @@ -16,6 +16,10 @@ enum ShareUpload { config.sessionSendsLaunchEvents = true config.isDiscretionary = false config.waitsForConnectivity = true + // Authenticate by the request's own header only (see DavClient.session). + config.httpShouldSetCookies = false + config.httpCookieAcceptPolicy = .never + config.urlCredentialStorage = nil return config }