mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-06 12:28:29 +00:00
Add support for Account Provisioning links. (#4108)
* Add support for account provisioning links and route them to the authentication flow. * Use the provisioning parameters to configure the authentication flow. * Add UI tests for the provisioned authentication flow. * Record new preview snapshots. * Add unit tests. * Make the domain configurable in the app settings. * Use the loginHint in the login screen too.
This commit is contained in:
@@ -11,6 +11,8 @@ import SwiftUI
|
||||
struct LoginScreenCoordinatorParameters {
|
||||
/// The service used to authenticate the user.
|
||||
let authenticationService: AuthenticationServiceProtocol
|
||||
/// An optional hint that can be used to pre-fill the form.
|
||||
let loginHint: String?
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
let analytics: AnalyticsService
|
||||
}
|
||||
@@ -42,6 +44,7 @@ final class LoginScreenCoordinator: CoordinatorProtocol {
|
||||
self.parameters = parameters
|
||||
|
||||
viewModel = LoginScreenViewModel(authenticationService: parameters.authenticationService,
|
||||
loginHint: parameters.loginHint,
|
||||
userIndicatorController: parameters.userIndicatorController,
|
||||
analytics: parameters.analytics)
|
||||
}
|
||||
|
||||
@@ -21,13 +21,21 @@ class LoginScreenViewModel: LoginScreenViewModelType, LoginScreenViewModelProtoc
|
||||
}
|
||||
|
||||
init(authenticationService: AuthenticationServiceProtocol,
|
||||
loginHint: String?,
|
||||
userIndicatorController: UserIndicatorControllerProtocol,
|
||||
analytics: AnalyticsService) {
|
||||
self.authenticationService = authenticationService
|
||||
self.userIndicatorController = userIndicatorController
|
||||
self.analytics = analytics
|
||||
|
||||
let viewState = LoginScreenViewState(homeserver: authenticationService.homeserver.value)
|
||||
let username = switch loginHint {
|
||||
case .some(let hint) where hint.hasPrefix("mxid:"): String(hint.dropFirst(5)) // MSC4198
|
||||
case .some(let hint): hint
|
||||
case .none: ""
|
||||
}
|
||||
|
||||
let viewState = LoginScreenViewState(homeserver: authenticationService.homeserver.value,
|
||||
bindings: LoginScreenBindings(username: username))
|
||||
|
||||
super.init(initialViewState: viewState)
|
||||
|
||||
|
||||
@@ -161,6 +161,7 @@ struct LoginScreen_Previews: PreviewProvider, TestablePreview {
|
||||
Task { await authenticationService.configure(for: homeserverAddress, flow: .login) }
|
||||
|
||||
let viewModel = LoginScreenViewModel(authenticationService: authenticationService,
|
||||
loginHint: nil,
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
analytics: ServiceLocator.shared.analytics)
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@ class OIDCAuthenticationPresenter: NSObject {
|
||||
private let presentationAnchor: UIWindow
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
|
||||
private var activeSession: ASWebAuthenticationSession?
|
||||
|
||||
init(authenticationService: AuthenticationServiceProtocol,
|
||||
oidcRedirectURL: URL,
|
||||
presentationAnchor: UIWindow,
|
||||
@@ -36,9 +38,12 @@ class OIDCAuthenticationPresenter: NSObject {
|
||||
session.prefersEphemeralWebBrowserSession = false
|
||||
session.presentationContextProvider = self
|
||||
|
||||
activeSession = session
|
||||
session.start()
|
||||
}
|
||||
|
||||
activeSession = nil
|
||||
|
||||
guard let url else {
|
||||
// Check for user cancellation to avoid showing an alert in that instance.
|
||||
if let nsError = error as? NSError,
|
||||
@@ -76,6 +81,10 @@ class OIDCAuthenticationPresenter: NSObject {
|
||||
}
|
||||
}
|
||||
|
||||
func cancel() {
|
||||
activeSession?.cancel()
|
||||
}
|
||||
|
||||
private static let loadingIndicatorID = "\(OIDCAuthenticationPresenter.self)-Loading"
|
||||
|
||||
private func startLoading(delay: Duration? = nil) {
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ class ServerConfirmationScreenViewModel: ServerConfirmationScreenViewModelType,
|
||||
startLoading() // Uses the same ID, so no need to worry if the indicator already exists
|
||||
defer { stopLoading() }
|
||||
|
||||
switch await authenticationService.urlForOIDCLogin() {
|
||||
switch await authenticationService.urlForOIDCLogin(loginHint: nil) {
|
||||
case .success(let oidcData):
|
||||
actionsSubject.send(.continueWithOIDC(data: oidcData, window: window))
|
||||
case .failure:
|
||||
|
||||
+1
-1
@@ -134,7 +134,7 @@ final class SoftLogoutScreenCoordinator: CoordinatorProtocol {
|
||||
startLoading()
|
||||
|
||||
Task {
|
||||
switch await authenticationService.urlForOIDCLogin() {
|
||||
switch await authenticationService.urlForOIDCLogin(loginHint: nil) {
|
||||
case .failure(let error):
|
||||
stopLoading()
|
||||
handleError(error)
|
||||
|
||||
Reference in New Issue
Block a user