diff --git a/Zotero/Controllers/Attachment Downloader/AttachmentDownloader.swift b/Zotero/Controllers/Attachment Downloader/AttachmentDownloader.swift index 955123c29..225ff47e7 100644 --- a/Zotero/Controllers/Attachment Downloader/AttachmentDownloader.swift +++ b/Zotero/Controllers/Attachment Downloader/AttachmentDownloader.swift @@ -948,3 +948,26 @@ extension AttachmentDownloader: URLSessionDelegate { } } } + +extension AttachmentDownloader: URLSessionTaskDelegate { + func urlSession( + _ session: URLSession, + task: URLSessionTask, + didReceive challenge: URLAuthenticationChallenge, + completionHandler: @escaping @Sendable (URLSession.AuthChallengeDisposition, URLCredential?) -> Void + ) { + let sessionStorage = webDavController.sessionStorage + let protectionSpace = challenge.protectionSpace + guard sessionStorage.isEnabled, + sessionStorage.isVerified, + protectionSpace.authenticationMethod == NSURLAuthenticationMethodHTTPBasic || protectionSpace.authenticationMethod == NSURLAuthenticationMethodHTTPDigest, + protectionSpace.host == sessionStorage.host, + protectionSpace.port == sessionStorage.port, + protectionSpace.protocol == sessionStorage.scheme.rawValue + else { + completionHandler(.performDefaultHandling, nil) + return + } + completionHandler(.useCredential, URLCredential(user: sessionStorage.username, password: sessionStorage.password, persistence: .permanent)) + } +} diff --git a/Zotero/Controllers/WebDAV/WebDavSessionStorage.swift b/Zotero/Controllers/WebDAV/WebDavSessionStorage.swift index d2628e0a0..1232cc746 100644 --- a/Zotero/Controllers/WebDAV/WebDavSessionStorage.swift +++ b/Zotero/Controllers/WebDAV/WebDavSessionStorage.swift @@ -14,10 +14,22 @@ protocol WebDavSessionStorage: AnyObject { var isVerified: Bool { get set } var username: String { get set } var url: String { get set } + var host: String { get } + var port: Int { get } var scheme: WebDavScheme { get set } var password: String { get set } } +extension WebDavSessionStorage { + var host: String { + return url.split(separator: ":", maxSplits: 2).first.flatMap { String($0) } ?? "" + } + + var port: Int { + url.split(separator: ":", maxSplits: 2).last.flatMap { Int($0) } ?? 80 + } +} + final class SecureWebDavSessionStorage: WebDavSessionStorage { private unowned let secureStorage: SecureStorage