Refactor auth to ASWebAuthenticationSession

This commit is contained in:
Thomas Ricouard 2023-12-06 08:05:26 +01:00
parent a6f6aa3a02
commit 3d2171d716
3 changed files with 28 additions and 24 deletions

View File

@ -3,6 +3,7 @@ import Env
import Observation
import SafariServices
import SwiftUI
import Models
extension View {
@MainActor func withSafariRouter() -> some View {
@ -26,7 +27,7 @@ private struct SafariRouter: ViewModifier {
})
.onOpenURL { url in
// Open external URL (from icecubesapp://)
let urlString = url.absoluteString.replacingOccurrences(of: "icecubesapp://", with: "https://")
let urlString = url.absoluteString.replacingOccurrences(of: AppInfo.scheme, with: "https://")
guard let url = URL(string: urlString), url.host != nil else { return }
_ = routerPath.handle(url: url)
}

View File

@ -1,4 +1,5 @@
import AppAccount
import AuthenticationServices
import Combine
import DesignSystem
import Env
@ -27,7 +28,6 @@ struct AddAccountView: View {
@State private var signInClient: Client?
@State private var instances: [InstanceSocial] = []
@State private var instanceFetchError: LocalizedStringKey?
@State private var oauthURL: URL?
private let instanceNamePublisher = PassthroughSubject<String, Never>()
@ -136,21 +136,6 @@ struct AddAccountView: View {
break
}
}
.onOpenURL(perform: { url in
Task {
await continueSignIn(url: url)
}
})
.onChange(of: oauthURL) { _, newValue in
if newValue == nil {
isSigninIn = false
}
}
#if !targetEnvironment(macCatalyst)
.sheet(item: $oauthURL, content: { url in
SafariView(url: url)
})
#endif
}
}
@ -233,11 +218,19 @@ struct AddAccountView: View {
do {
signInClient = .init(server: sanitizedName)
if let oauthURL = try await signInClient?.oauthURL() {
#if targetEnvironment(macCatalyst)
openURL(oauthURL)
#else
self.oauthURL = oauthURL
#endif
let session = ASWebAuthenticationSession(url: oauthURL,
callbackURLScheme: AppInfo.scheme.replacingOccurrences(of: "://", with: ""))
{ callbackURL, error in
if let callbackURL {
Task {
await continueSignIn(url: callbackURL)
}
} else {
isSigninIn = false
}
}
session.presentationContextProvider = SceneDelegate.authViewController
session.start()
} else {
isSigninIn = false
}
@ -252,7 +245,6 @@ struct AddAccountView: View {
return
}
do {
oauthURL = nil
let oauthToken = try await client.continueOauthFlow(url: url)
let client = Client(server: client.server, oauthToken: oauthToken)
let account: Account = try await client.get(endpoint: Accounts.verifyCredentials)
@ -266,7 +258,6 @@ struct AddAccountView: View {
isSigninIn = false
dismiss()
} catch {
oauthURL = nil
isSigninIn = false
}
}

View File

@ -1,4 +1,5 @@
import Combine
import AuthenticationServices
import UIKit
@Observable
@ -7,6 +8,9 @@ public class SceneDelegate: NSObject, UIWindowSceneDelegate, Sendable {
public private(set) var windowWidth: CGFloat = UIScreen.main.bounds.size.width
public private(set) var windowHeight: CGFloat = UIScreen.main.bounds.size.height
public static var globalPresentationAnchor: ASPresentationAnchor? = nil
public static var authViewController = AuthViewController()
public func scene(_ scene: UIScene,
willConnectTo _: UISceneSession,
options _: UIScene.ConnectionOptions)
@ -14,6 +18,8 @@ public class SceneDelegate: NSObject, UIWindowSceneDelegate, Sendable {
guard let windowScene = scene as? UIWindowScene else { return }
window = windowScene.keyWindow
Self.globalPresentationAnchor = window
#if targetEnvironment(macCatalyst)
if let titlebar = windowScene.titlebar {
titlebar.titleVisibility = .hidden
@ -54,3 +60,9 @@ public class SceneDelegate: NSObject, UIWindowSceneDelegate, Sendable {
}
}
}
public class AuthViewController: UIViewController, ASWebAuthenticationPresentationContextProviding {
public func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
return SceneDelegate.globalPresentationAnchor ?? ASPresentationAnchor()
}
}