|
12 | 12 | import UIKit |
13 | 13 | import SafariServices |
14 | 14 |
|
| 15 | +extension Notification.Name { |
| 16 | + static let callbackURLNotification = Notification.Name("callbackURL") |
| 17 | +} |
| 18 | + |
15 | 19 | class LoginViewController: UIViewController, Navigating { |
16 | 20 | static var navigableItem: NavigableItem = .login |
17 | 21 |
|
18 | 22 | private let guardianAPI = DependencyManager.shared.guardianAPI |
19 | 23 | private var safariViewController: SFSafariViewController? |
20 | | - private var verificationURL: URL? |
21 | | - private var verifyTimer: Timer? |
22 | | - private var isVerifying = false |
| 24 | + private let accountManager = DependencyManager.shared.accountManager |
| 25 | + private let PKCECode: (String, String) = PKCECodeGenerator.generateCode |
23 | 26 |
|
24 | 27 | init() { |
25 | 28 | super.init(nibName: nil, bundle: nil) |
26 | | - guardianAPI.initiateUserLogin { [weak self] result in |
27 | | - switch result { |
28 | | - case .success(let checkpointModel): |
29 | | - guard let loginURL = checkpointModel.loginUrl else { return } |
30 | | - self?.verificationURL = checkpointModel.verificationUrl |
31 | | - let safariViewController = SFSafariViewController(url: loginURL) |
32 | | - DispatchQueue.main.async { |
33 | | - self?.addChild(safariViewController) |
34 | | - self?.view.addSubview(safariViewController.view) |
35 | | - safariViewController.view.frame = self?.view.bounds ?? CGRect.zero |
36 | | - safariViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] |
37 | | - safariViewController.didMove(toParent: self) |
38 | | - } |
39 | | - safariViewController.delegate = self |
40 | | - self?.safariViewController = safariViewController |
41 | | - case .failure(let error): |
42 | | - let loginError = error.getLoginError() |
43 | | - let context: NavigableContext = loginError == .maxDevicesReached ? .maxDevicesReached : .error(loginError) |
44 | | - self?.navigate(to: .landing, context: context) |
45 | | - } |
46 | | - } |
47 | | - } |
48 | | - |
49 | | - deinit { |
50 | | - verifyTimer?.invalidate() |
51 | 29 | } |
52 | 30 |
|
53 | 31 | required init?(coder: NSCoder) { |
54 | 32 | fatalError("init(coder:) has not been implemented") |
55 | 33 | } |
56 | 34 |
|
57 | | - @objc private func verify() { |
58 | | - guard let verificationURL = verificationURL else { return } |
59 | | - if isVerifying { return } |
60 | | - isVerifying = true |
| 35 | + override func viewDidLoad() { |
| 36 | + super.viewDidLoad() |
61 | 37 |
|
62 | | - guardianAPI.verify(urlString: verificationURL.absoluteString) { [weak self] result in |
63 | | - guard let self = self else { return } |
| 38 | + let safariViewController = SFSafariViewController(url: GuardianURLRequest.pkceLoginURL(codeChallenge: PKCECode.0)) |
| 39 | + addChild(safariViewController) |
| 40 | + view.addSubview(safariViewController.view) |
| 41 | + safariViewController.view.frame = self.view.bounds |
| 42 | + safariViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] |
| 43 | + safariViewController.didMove(toParent: self) |
| 44 | + safariViewController.delegate = self |
| 45 | + self.safariViewController = safariViewController |
| 46 | + |
| 47 | + NotificationCenter.default.addObserver(self, selector: #selector(handleCallback), name: .callbackURLNotification, object: nil) |
| 48 | + } |
64 | 49 |
|
| 50 | + @objc private func handleCallback(notification: Notification) { |
| 51 | + guard let url = notification.userInfo?["callbackURL"] as? URL, |
| 52 | + let queryItems = URLComponents(string: url.absoluteString)?.queryItems, |
| 53 | + let code = queryItems.first(where: { $0.name == "code" })?.value else { |
| 54 | + navigate(to: .landing) |
| 55 | + return |
| 56 | + } |
| 57 | + verify(code: code) |
| 58 | + } |
| 59 | + |
| 60 | + private func verify(code: String) { |
| 61 | + guardianAPI.verify(code: code, codeVerifier: PKCECode.1) { [weak self] result in |
| 62 | + guard let self = self else { return } |
65 | 63 | switch result { |
66 | 64 | case .success(let verification): |
67 | | - DependencyManager.shared.accountManager.login(with: verification) { loginResult in |
68 | | - self.isVerifying = false |
69 | | - self.verifyTimer?.invalidate() |
70 | | - switch loginResult { |
71 | | - case .success: |
72 | | - self.navigate(to: .home) |
73 | | - case .failure(let error): |
74 | | - Logger.global?.log(message: "Authentication Error: \(error)") |
75 | | - let context: NavigableContext = error == .maxDevicesReached ? .maxDevicesReached : .error(error) |
76 | | - self.navigate(to: .landing, context: context) |
77 | | - } |
78 | | - } |
79 | | - case .failure: |
80 | | - self.isVerifying = false |
81 | | - return |
| 65 | + self.login(verification: verification) |
| 66 | + case .failure(let error): |
| 67 | + self.navigate(to: .landing, context: .error(error)) |
82 | 68 | } |
83 | 69 | } |
84 | 70 | } |
85 | | -} |
86 | 71 |
|
87 | | -// MARK: - SFSafariViewControllerDelegate |
88 | | -extension LoginViewController: SFSafariViewControllerDelegate { |
89 | | - func safariViewController(_ controller: SFSafariViewController, didCompleteInitialLoad didLoadSuccessfully: Bool) { |
90 | | - if didLoadSuccessfully && verifyTimer == nil { |
91 | | - verifyTimer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(verify), userInfo: nil, repeats: true) |
| 72 | + private func login(verification: VerifyResponse) { |
| 73 | + accountManager.login(with: verification) { [weak self] loginResult in |
| 74 | + guard let self = self else { return } |
| 75 | + switch loginResult { |
| 76 | + case .success: |
| 77 | + self.navigate(to: .home) |
| 78 | + case .failure(let error): |
| 79 | + Logger.global?.log(message: "Authentication Error: \(error)") |
| 80 | + let context: NavigableContext = error == .maxDevicesReached ? .maxDevicesReached : .error(error) |
| 81 | + self.navigate(to: .landing, context: context) |
| 82 | + } |
92 | 83 | } |
93 | 84 | } |
| 85 | +} |
94 | 86 |
|
| 87 | +// MARK: - SFSafariViewControllerDelegate |
| 88 | +extension LoginViewController: SFSafariViewControllerDelegate { |
95 | 89 | func safariViewControllerDidFinish(_ controller: SFSafariViewController) { |
96 | | - self.verifyTimer?.invalidate() |
97 | 90 | navigate(to: .landing) |
98 | 91 | } |
99 | 92 | } |
0 commit comments