Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Nextcloud.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1322,6 +1322,7 @@
F321DA892B71205A00DDA0E6 /* NCTrashSelectTabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCTrashSelectTabBar.swift; sourceTree = "<group>"; };
F32FADA82D1176DE007035E2 /* UIButton+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIButton+Extension.swift"; sourceTree = "<group>"; };
F33918C32C7CD8F2002D9AA1 /* FileNameValidator+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileNameValidator+Extensions.swift"; sourceTree = "<group>"; };
F33D300E2D7EFE2800531D64 /* NextcloudKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = NextcloudKit; path = ../NextcloudKit; sourceTree = SOURCE_ROOT; };
F33EE6F12BF4C9B200CA1A51 /* PKCS12.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PKCS12.swift; sourceTree = "<group>"; };
F343A4B22A1E01FF00DDA874 /* PHAsset+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PHAsset+Extension.swift"; sourceTree = "<group>"; };
F343A4BA2A1E734600DDA874 /* Optional+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Optional+Extension.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3216,6 +3217,7 @@
F7F67B9F1A24D27800EE80DA = {
isa = PBXGroup;
children = (
F33D300E2D7EFE2800531D64 /* NextcloudKit */,
AA8E041E2D3114E200E7E89C /* README.md */,
F7B8B82F25681C3400967775 /* GoogleService-Info.plist */,
F7C1CDD91E6DFC6F005D92BE /* Brand */,
Expand Down Expand Up @@ -6155,8 +6157,8 @@
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/nextcloud/NextcloudKit";
requirement = {
branch = develop;
kind = branch;
kind = exactVersion;
version = 6.0.2;
};
};
F788ECC5263AAAF900ADC67F /* XCRemoteSwiftPackageReference "MarkdownKit" */ = {
Expand Down
81 changes: 8 additions & 73 deletions iOSClient/Login/NCLogin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate {
private var p12Data: Data?
private var p12Password: String?

var pollTimer: DispatchSourceTimer?

var loginFlowInProgress = false

// MARK: - View Life Cycle

override func viewDidLoad() {
Expand Down Expand Up @@ -189,15 +185,6 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate {
}
}

override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)

if navigationController?.isBeingDismissed == true {
pollTimer?.cancel()
pollTimer = nil
}
}

private func handleLoginWithAppConfig() {
let accountCount = NCManageDatabase.shared.getAccounts()?.count ?? 0

Expand Down Expand Up @@ -332,11 +319,13 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate {
NextcloudKit.shared.getLoginFlowV2(serverUrl: url, options: loginOptions) { [self] token, endpoint, login, _, error in
// Login Flow V2
if error == .success, let token, let endpoint, let login {
poll(loginFlowV2Token: token, loginFlowV2Endpoint: endpoint, loginFlowV2Login: login)

let safariVC = NCLoginProvider()
safariVC.urlBase = login
self.navigationController?.pushViewController(safariVC, animated: true)
safariVC.uiColor = textColor
safariVC.delegate = self
safariVC.poll(loginFlowV2Token: token, loginFlowV2Endpoint: endpoint, loginFlowV2Login: login)
navigationController?.pushViewController(safariVC, animated: true)
} else if serverInfo.versionMajor < NCGlobal.shared.nextcloudVersion12 { // No login flow available
let alertController = UIAlertController(title: NSLocalizedString("_error_", comment: ""), message: NSLocalizedString("_webflow_not_available_", comment: ""), preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { _ in }))
Expand Down Expand Up @@ -497,65 +486,11 @@ extension NCLogin: ClientCertificateDelegate, UIDocumentPickerDelegate {
self.present(alertWrongPassword, animated: true)
}
}

func poll(loginFlowV2Token: String, loginFlowV2Endpoint: String, loginFlowV2Login: String) {
let queue = DispatchQueue.global(qos: .background)
pollTimer = DispatchSource.makeTimerSource(queue: queue)

guard let timer = pollTimer else { return }

timer.schedule(deadline: .now(), repeating: .seconds(1), leeway: .seconds(1))
timer.setEventHandler(handler: {
DispatchQueue.main.async {
let controller = UIApplication.shared.firstWindow?.rootViewController as? NCMainTabBarController
let loginOptions = NKRequestOptions(customUserAgent: userAgent)
NextcloudKit.shared.getLoginFlowV2Poll(token: loginFlowV2Token, endpoint: loginFlowV2Endpoint, options: loginOptions) { [self] server, loginName, appPassword, _, error in
if error == .success, let urlBase = server, let user = loginName, let appPassword {
loginFlowInProgress = true

NCAccount().createAccount(urlBase: urlBase, user: user, password: appPassword, controller: controller) { account, error in

if error == .success {
let window = UIApplication.shared.firstWindow
if let controller = window?.rootViewController as? NCMainTabBarController {
controller.account = account
controller.dismiss(animated: true, completion: nil)
} else {
if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() as? NCMainTabBarController {
controller.account = account
controller.modalPresentationStyle = .fullScreen
controller.view.alpha = 0

window?.rootViewController = controller
window?.makeKeyAndVisible()

if let scene = window?.windowScene {
SceneManager.shared.register(scene: scene, withRootViewController: controller)
}

UIView.animate(withDuration: 0.5) {
controller.view.alpha = 1
}
}
}

timer.cancel()
}
}
}
}
}
})

timer.resume()
}
}

extension NCLogin: SFSafariViewControllerDelegate {
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
if !loginFlowInProgress {
loginButton.isEnabled = true
loginButton.hideSpinnerAndShowButton()
}
extension NCLogin: NCLoginProviderDelegate {
func onBack() {
loginButton.isEnabled = true
loginButton.hideSpinnerAndShowButton()
}
}
71 changes: 67 additions & 4 deletions iOSClient/Login/NCLoginProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ class NCLoginProvider: UIViewController {
let utility = NCUtility()
var titleView: String = ""
var urlBase = ""

var uiColor: UIColor = .white
var pollTimer: DispatchSourceTimer?
weak var delegate: NCLoginProviderDelegate?
// MARK: - View Life Cycle

override func viewDidLoad() {
super.viewDidLoad()
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .stop, target: self, action: #selector(self.closeView(sender:)))

webView = WKWebView(frame: CGRect.zero, configuration: WKWebViewConfiguration())
if let webView {
Expand All @@ -30,6 +31,10 @@ class NCLoginProvider: UIViewController {
webView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
webView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
}

let navigationItemBack = UIBarButtonItem(image: UIImage(systemName: "arrow.left"), style: .done, target: self, action: #selector(goBack))
navigationItemBack.tintColor = uiColor
navigationItem.leftBarButtonItem = navigationItemBack
}

override func viewDidAppear(_ animated: Bool) {
Expand Down Expand Up @@ -62,6 +67,9 @@ class NCLoginProvider: UIViewController {
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
NCActivityIndicator.shared.stop()

pollTimer?.cancel()
pollTimer = nil
}

func loadWebPage(webView: WKWebView, url: URL) {
Expand All @@ -81,8 +89,59 @@ class NCLoginProvider: UIViewController {
webView.load(request)
}

@objc func closeView(sender: UIBarButtonItem) {
self.dismiss(animated: true, completion: nil)
@objc func goBack() {
delegate?.onBack()
navigationController?.popViewController(animated: true)
}

func poll(loginFlowV2Token: String, loginFlowV2Endpoint: String, loginFlowV2Login: String) {
let queue = DispatchQueue.global(qos: .background)
pollTimer = DispatchSource.makeTimerSource(queue: queue)

guard let timer = pollTimer else { return }

timer.schedule(deadline: .now(), repeating: .seconds(1), leeway: .seconds(1))
timer.setEventHandler(handler: {
DispatchQueue.main.async {
let controller = UIApplication.shared.firstWindow?.rootViewController as? NCMainTabBarController
let loginOptions = NKRequestOptions(customUserAgent: userAgent)
NextcloudKit.shared.getLoginFlowV2Poll(token: loginFlowV2Token, endpoint: loginFlowV2Endpoint, options: loginOptions) { server, loginName, appPassword, _, error in
if error == .success, let urlBase = server, let user = loginName, let appPassword {
NCAccount().createAccount(urlBase: urlBase, user: user, password: appPassword, controller: controller) { account, error in

if error == .success {
let window = UIApplication.shared.firstWindow
if let controller = window?.rootViewController as? NCMainTabBarController {
controller.account = account
controller.dismiss(animated: true, completion: nil)
} else {
if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() as? NCMainTabBarController {
controller.account = account
controller.modalPresentationStyle = .fullScreen
controller.view.alpha = 0

window?.rootViewController = controller
window?.makeKeyAndVisible()

if let scene = window?.windowScene {
SceneManager.shared.register(scene: scene, withRootViewController: controller)
}

UIView.animate(withDuration: 0.5) {
controller.view.alpha = 1
}
}
}

timer.cancel()
}
}
}
}
}
})

timer.resume()
}
}

Expand Down Expand Up @@ -177,3 +236,7 @@ extension NCLoginProvider: WKNavigationDelegate {
NCActivityIndicator.shared.stop()
}
}

protocol NCLoginProviderDelegate: AnyObject {
func onBack()
}
Loading