iOS: authenticate each request by its own header only (no cookies/credential cache)
Two accounts can share one server; the Share Extension's folder listing and the upload sessions now ignore cookies and stored credentials so one account's session can never answer for another. Logs each PROPFIND (user, path, status). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
02d612bfec
commit
02d9d799a6
@@ -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)
|
||||
}()
|
||||
|
||||
|
||||
@@ -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).")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user