Skip to content

Commit a05e276

Browse files
committed
feat: Implement one time login qr code
Signed-off-by: Marcel Müller <marcel-mueller@gmx.de>
1 parent 6e66371 commit a05e276

File tree

4 files changed

+61
-2
lines changed

4 files changed

+61
-2
lines changed

NextcloudTalk/Login/LoginViewController.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,4 +353,20 @@ class LoginViewController: UIViewController, UITextFieldDelegate, CCCertificateD
353353
NCSettingsController.sharedInstance().addNewAccount(forUser: user, withToken: password, inServer: serverURL)
354354
delegate?.loginViewControllerDidFinish()
355355
}
356+
357+
func qrScanner(_ scanner: QRScannerViewController, didScanNextcloudOnetimeLogin serverURL: String, user: String, onetimeToken: String) {
358+
// We received a onetime login token and need to convert it to a permanent one. The token only allows to retrieve a permanent one, no other routes allowed
359+
NCAPIController.sharedInstance().getAppPasswordOnetime(forServer: serverURL, withUsername: user, andOnetimeToken: onetimeToken) { [weak self] permanentAppToken in
360+
guard let permanentAppToken else {
361+
self?.showAlert(
362+
title: NSLocalizedString("Could not login with QR code", comment: ""),
363+
message: NSLocalizedString("The token might be used already or is expired. Please generate a new QR code and retry.", comment: ""))
364+
365+
return
366+
}
367+
368+
NCSettingsController.sharedInstance().addNewAccount(forUser: user, withToken: permanentAppToken, inServer: serverURL)
369+
self?.delegate?.loginViewControllerDidFinish()
370+
}
371+
}
356372
}

NextcloudTalk/Login/QRScannerViewController.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import VisionKit
88

99
@objc protocol QRScannerViewControllerDelegate: AnyObject {
1010
func qrScanner(_ scanner: QRScannerViewController, didScanNextcloudLogin serverURL: String, user: String, password: String)
11+
func qrScanner(_ scanner: QRScannerViewController, didScanNextcloudOnetimeLogin serverURL: String, user: String, onetimeToken: String)
1112
}
1213

1314
@objcMembers
@@ -137,7 +138,10 @@ class QRScannerViewController: UIViewController, DataScannerViewControllerDelega
137138
guard case let .barcode(barcode) = item,
138139
let value = barcode.payloadStringValue else { return }
139140

140-
if let urlComponents = NSURLComponents(string: value), var path = urlComponents.path, urlComponents.scheme == "nc", urlComponents.host == "login" {
141+
if let urlComponents = NSURLComponents(string: value), var path = urlComponents.path, urlComponents.scheme == "nc" {
142+
let isOnetimeLogin = (urlComponents.host == "onetime-login")
143+
guard urlComponents.host == "login" || isOnetimeLogin else { return }
144+
141145
if path.starts(with: "/") {
142146
path.removeFirst()
143147
}
@@ -152,7 +156,12 @@ class QRScannerViewController: UIViewController, DataScannerViewControllerDelega
152156

153157
scannerViewController?.stopScanning()
154158
self.dismiss(animated: true)
155-
self.delegate?.qrScanner(self, didScanNextcloudLogin: serverUrl, user: user, password: password)
159+
160+
if isOnetimeLogin {
161+
self.delegate?.qrScanner(self, didScanNextcloudOnetimeLogin: serverUrl, user: user, onetimeToken: password)
162+
} else {
163+
self.delegate?.qrScanner(self, didScanNextcloudLogin: serverUrl, user: user, password: password)
164+
}
156165

157166
return
158167
}

NextcloudTalk/Network/NCAPIControllerExtensions.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,4 +1277,32 @@ import NextcloudKit
12771277
completionBlock(thread)
12781278
}
12791279
}
1280+
1281+
// MARK: - Core
1282+
1283+
@nonobjc
1284+
func getAppPasswordOnetime(forServer server: String, withUsername username: String, andOnetimeToken onetimeToken: String, completionBlock: @escaping (_ permanentAppToken: String?) -> Void) {
1285+
let appPasswordRoute = "\(server)/ocs/v2.php/core/getapppassword-onetime"
1286+
1287+
let credentialsString = "\(username):\(onetimeToken)"
1288+
let authHeader = "Basic \(credentialsString.data(using: .utf8)!.base64EncodedString())"
1289+
1290+
let configuration = URLSessionConfiguration.default
1291+
let apiSessionManager = NCAPISessionManager(configuration: configuration)
1292+
apiSessionManager.requestSerializer.setValue(authHeader, forHTTPHeaderField: "Authorization")
1293+
1294+
_ = apiSessionManager.get(appPasswordRoute, parameters: nil, progress: nil) { _, result in
1295+
if let resultDict = result as? [String: AnyObject],
1296+
let ocs = resultDict["ocs"] as? [String: AnyObject],
1297+
let data = ocs["data"] as? [String: AnyObject],
1298+
let apppassword = data["apppassword"] as? String {
1299+
1300+
completionBlock(apppassword)
1301+
}
1302+
1303+
completionBlock(nil)
1304+
} failure: { _, _ in
1305+
completionBlock(nil)
1306+
}
1307+
}
12801308
}

NextcloudTalk/en.lproj/Localizable.strings

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,9 @@
712712
/* No comment provided by engineer. */
713713
"Could not leave conversation" = "Could not leave conversation";
714714

715+
/* No comment provided by engineer. */
716+
"Could not login with QR code" = "Could not login with QR code";
717+
715718
/* No comment provided by engineer. */
716719
"Could not remove participant" = "Could not remove participant";
717720

@@ -2093,6 +2096,9 @@
20932096
/* No comment provided by engineer. */
20942097
"The recording might include your voice, video from camera, and screen share. Your consent is required before joining the call." = "The recording might include your voice, video from camera, and screen share. Your consent is required before joining the call.";
20952098

2099+
/* No comment provided by engineer. */
2100+
"The token might be used already or is expired. Please generate a new QR code and retry." = "The token might be used already or is expired. Please generate a new QR code and retry.";
2101+
20962102
/* No comment provided by engineer. */
20972103
"There is no account for user %@ in server %@ configured in this app." = "There is no account for user %1$@ in server %2$@ configured in this app.";
20982104

0 commit comments

Comments
 (0)