@@ -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