Use AuthenticationServices for Tailnet sign-in
This commit is contained in:
parent
7670a75840
commit
35f3b3ce4e
1 changed files with 29 additions and 8 deletions
|
|
@ -1,3 +1,4 @@
|
||||||
|
import AuthenticationServices
|
||||||
import BurrowConfiguration
|
import BurrowConfiguration
|
||||||
import Foundation
|
import Foundation
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
@ -184,7 +185,7 @@ private struct AccountDraft {
|
||||||
|
|
||||||
private struct ConfigurationSheetView: View {
|
private struct ConfigurationSheetView: View {
|
||||||
@Environment(\.dismiss) private var dismiss
|
@Environment(\.dismiss) private var dismiss
|
||||||
@Environment(\.openURL) private var openURL
|
@Environment(\.webAuthenticationSession) private var webAuthenticationSession
|
||||||
|
|
||||||
let sheet: ConfigurationSheet
|
let sheet: ConfigurationSheet
|
||||||
let networkViewModel: NetworkViewModel
|
let networkViewModel: NetworkViewModel
|
||||||
|
|
@ -197,6 +198,7 @@ private struct ConfigurationSheetView: View {
|
||||||
@State private var loginStatus: TailnetLoginStatus?
|
@State private var loginStatus: TailnetLoginStatus?
|
||||||
@State private var pollingTask: Task<Void, Never>?
|
@State private var pollingTask: Task<Void, Never>?
|
||||||
@State private var didRunAutomation = false
|
@State private var didRunAutomation = false
|
||||||
|
@State private var webAuthenticationTask: Task<Void, Never>?
|
||||||
|
|
||||||
init(
|
init(
|
||||||
sheet: ConfigurationSheet,
|
sheet: ConfigurationSheet,
|
||||||
|
|
@ -280,6 +282,8 @@ private struct ConfigurationSheetView: View {
|
||||||
}
|
}
|
||||||
.onDisappear {
|
.onDisappear {
|
||||||
pollingTask?.cancel()
|
pollingTask?.cancel()
|
||||||
|
webAuthenticationTask?.cancel()
|
||||||
|
webAuthenticationTask = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -307,7 +311,7 @@ private struct ConfigurationSheetView: View {
|
||||||
.autocorrectionDisabled()
|
.autocorrectionDisabled()
|
||||||
|
|
||||||
if draft.tailnetProvider.usesWebLogin {
|
if draft.tailnetProvider.usesWebLogin {
|
||||||
Text("Sign-in is brokered by `burrow auth-server` on the host and opens the real Tailscale login page in a browser.")
|
Text("Sign-in is brokered by `burrow auth-server` on the host and opens the real Tailscale login page in an in-app authentication session.")
|
||||||
.font(.footnote)
|
.font(.footnote)
|
||||||
.foregroundStyle(.secondary)
|
.foregroundStyle(.secondary)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -343,9 +347,9 @@ private struct ConfigurationSheetView: View {
|
||||||
}
|
}
|
||||||
if let authURL = loginStatus.authURL {
|
if let authURL = loginStatus.authURL {
|
||||||
labeledValue("Login URL", authURL)
|
labeledValue("Login URL", authURL)
|
||||||
Button("Open Login Page") {
|
Button("Resume Sign-In") {
|
||||||
if let url = URL(string: authURL) {
|
if let url = URL(string: authURL) {
|
||||||
openURL(url)
|
openLoginURL(url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -479,6 +483,8 @@ private struct ConfigurationSheetView: View {
|
||||||
private func submitTailnet() async throws {
|
private func submitTailnet() async throws {
|
||||||
if draft.tailnetProvider.usesWebLogin {
|
if draft.tailnetProvider.usesWebLogin {
|
||||||
if loginStatus?.running == true {
|
if loginStatus?.running == true {
|
||||||
|
webAuthenticationTask?.cancel()
|
||||||
|
webAuthenticationTask = nil
|
||||||
try await saveTailnetAccount(secret: nil, username: nil)
|
try await saveTailnetAccount(secret: nil, username: nil)
|
||||||
dismiss()
|
dismiss()
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -551,6 +557,8 @@ private struct ConfigurationSheetView: View {
|
||||||
openLoginURL(url)
|
openLoginURL(url)
|
||||||
}
|
}
|
||||||
if status.running {
|
if status.running {
|
||||||
|
webAuthenticationTask?.cancel()
|
||||||
|
webAuthenticationTask = nil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
|
@ -563,12 +571,25 @@ private struct ConfigurationSheetView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func openLoginURL(_ url: URL) {
|
private func openLoginURL(_ url: URL) {
|
||||||
Task { @MainActor in
|
webAuthenticationTask?.cancel()
|
||||||
|
webAuthenticationTask = Task { @MainActor in
|
||||||
try? await Task.sleep(for: .milliseconds(300))
|
try? await Task.sleep(for: .milliseconds(300))
|
||||||
openURL(url) { accepted in
|
do {
|
||||||
guard !accepted else { return }
|
_ = try await webAuthenticationSession.authenticate(
|
||||||
errorMessage = "Burrow got a Tailscale login URL, but iOS did not open it automatically."
|
using: url,
|
||||||
|
callbackURLScheme: "burrow",
|
||||||
|
preferredBrowserSession: .shared
|
||||||
|
)
|
||||||
|
} catch is CancellationError {
|
||||||
|
return
|
||||||
|
} catch let error as ASWebAuthenticationSessionError
|
||||||
|
where error.code == .canceledLogin
|
||||||
|
{
|
||||||
|
return
|
||||||
|
} catch {
|
||||||
|
errorMessage = error.localizedDescription
|
||||||
}
|
}
|
||||||
|
webAuthenticationTask = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue