Skip to content

Commit 707b2f4

Browse files
Merge branch 'main' into X-NC-WebDAV-Auto-Mkcol
2 parents 2cba6ba + 21be08a commit 707b2f4

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed

Sources/NextcloudKit/NextcloudKit+Login.swift

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,92 @@ public extension NextcloudKit {
9595
}
9696
}
9797

98+
/// Retrieves an app password (token) for the given user, server URL and onetime token.
99+
///
100+
/// Parameters:
101+
/// - url: The base server URL (e.g., https://cloud.example.com).
102+
/// - user: The username for authentication.
103+
/// - onetimeToken: The onetime token (usually from QR code login).
104+
/// - userAgent: Optional user-agent string to include in the request.
105+
/// - options: Optional request configuration (headers, queue, etc.).
106+
/// - taskHandler: Callback for observing the underlying URLSessionTask.
107+
/// - completion: Returns the token string (if any), raw response data, and NKError result.
108+
func getAppPasswordOnetime(url: String,
109+
user: String,
110+
onetimeToken: String,
111+
userAgent: String? = nil,
112+
options: NKRequestOptions = NKRequestOptions(),
113+
taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in },
114+
completion: @escaping (_ token: String?, _ responseData: AFDataResponse<Data>?, _ error: NKError) -> Void) {
115+
let endpoint = "ocs/v2.php/core/getapppassword-onetime"
116+
guard let url = self.nkCommonInstance.createStandardUrl(serverUrl: url, endpoint: endpoint) else {
117+
return options.queue.async { completion(nil, nil, .urlError) }
118+
}
119+
var headers: HTTPHeaders = [.authorization(username: user, password: onetimeToken)]
120+
if let userAgent = userAgent {
121+
headers.update(.userAgent(userAgent))
122+
}
123+
headers.update(name: "OCS-APIRequest", value: "true")
124+
var urlRequest: URLRequest
125+
126+
do {
127+
try urlRequest = URLRequest(url: url, method: HTTPMethod(rawValue: "GET"), headers: headers)
128+
} catch {
129+
return options.queue.async { completion(nil, nil, NKError(error: error)) }
130+
}
131+
132+
unauthorizedSession.request(urlRequest).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in
133+
task.taskDescription = options.taskDescription
134+
taskHandler(task)
135+
}.responseData(queue: self.nkCommonInstance.backgroundQueue) { response in
136+
switch response.result {
137+
case .failure(let error):
138+
let error = NKError(error: error, afResponse: response, responseData: response.data)
139+
options.queue.async { completion(nil, response, error) }
140+
case .success(let data):
141+
let apppassword = NKDataFileXML(nkCommonInstance: self.nkCommonInstance).convertDataAppPassword(data: data)
142+
options.queue.async { completion(apppassword, response, .success) }
143+
}
144+
}
145+
}
146+
147+
/// Asynchronously fetches an app password for the provided user and onetime token.
148+
///
149+
/// - Parameters:
150+
/// - url: The base URL of the Nextcloud server.
151+
/// - user: The user login name.
152+
/// - onetimeToken: The onetime token (usually from QR code login).
153+
/// - userAgent: Optional custom user agent for the request.
154+
/// - options: Optional request configuration.
155+
/// - taskHandler: Callback to observe the task, if needed.
156+
/// - Returns: A tuple containing the token, response data, and error result.
157+
func getAppPasswordOnetimeAsync(url: String,
158+
user: String,
159+
onetimeToken: String,
160+
userAgent: String? = nil,
161+
options: NKRequestOptions = NKRequestOptions(),
162+
taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }
163+
) async -> (
164+
token: String?,
165+
responseData: AFDataResponse<Data>?,
166+
error: NKError
167+
) {
168+
await withCheckedContinuation { continuation in
169+
getAppPasswordOnetime(url: url,
170+
user: user,
171+
onetimeToken: onetimeToken,
172+
userAgent: userAgent,
173+
options: options,
174+
taskHandler: taskHandler) { token, responseData, error in
175+
continuation.resume(returning: (
176+
token: token,
177+
responseData: responseData,
178+
error: error
179+
))
180+
}
181+
}
182+
}
183+
98184
/// Deletes the app password (token) for a specific account using basic authentication.
99185
///
100186
/// Parameters:

0 commit comments

Comments
 (0)