mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 10:33:45 +00:00
#42: Proof of concept login via OIDC.
Uses AppAuth library in the app, ignoring token refresh
This commit is contained in:
@@ -110,8 +110,6 @@ class AuthenticationCoordinator: Coordinator, Presentable {
|
||||
switch action {
|
||||
case .signedIn(let userSession):
|
||||
self.delegate?.authenticationCoordinator(self, didLoginWithSession: userSession)
|
||||
case .continueWithOIDC:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import AppAuth
|
||||
import MatrixRustSDK
|
||||
import SwiftUI
|
||||
|
||||
@@ -27,8 +28,6 @@ struct LoginCoordinatorParameters {
|
||||
enum LoginCoordinatorAction {
|
||||
/// Login was successful.
|
||||
case signedIn(UserSessionProtocol)
|
||||
/// Continue using OIDC.
|
||||
case continueWithOIDC
|
||||
}
|
||||
|
||||
final class LoginCoordinator: Coordinator, Presentable {
|
||||
@@ -39,6 +38,8 @@ final class LoginCoordinator: Coordinator, Presentable {
|
||||
private let parameters: LoginCoordinatorParameters
|
||||
private let loginHostingController: UIViewController
|
||||
private var loginViewModel: LoginViewModelProtocol
|
||||
/// Passed to the OIDC service to provide a view controller from which to present the authentication session.
|
||||
private let oidcUserAgent: OIDExternalUserAgentIOS?
|
||||
|
||||
private var currentTask: Task<Void, Error>? {
|
||||
willSet {
|
||||
@@ -69,6 +70,7 @@ final class LoginCoordinator: Coordinator, Presentable {
|
||||
loginHostingController = UIHostingController(rootView: view)
|
||||
|
||||
indicatorPresenter = UserIndicatorTypePresenter(presentingViewController: loginHostingController)
|
||||
oidcUserAgent = OIDExternalUserAgentIOS(presenting: loginHostingController)
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
@@ -90,7 +92,7 @@ final class LoginCoordinator: Coordinator, Presentable {
|
||||
case .login(let username, let password):
|
||||
self.login(username: username, password: password)
|
||||
case .continueWithOIDC:
|
||||
self.callback?(.continueWithOIDC)
|
||||
self.loginWithOIDC()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,6 +140,26 @@ final class LoginCoordinator: Coordinator, Presentable {
|
||||
}
|
||||
}
|
||||
|
||||
private func loginWithOIDC() {
|
||||
guard let oidcUserAgent = oidcUserAgent else {
|
||||
handleError(AuthenticationServiceError.oidcError(.notSupported))
|
||||
return
|
||||
}
|
||||
|
||||
startLoading(isInteractionBlocking: true)
|
||||
|
||||
Task {
|
||||
switch await authenticationService.loginWithOIDC(userAgent: oidcUserAgent) {
|
||||
case .success(let userSession):
|
||||
callback?(.signedIn(userSession))
|
||||
stopLoading()
|
||||
case .failure(let error):
|
||||
stopLoading()
|
||||
handleError(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Requests the authentication coordinator to log in using the specified credentials.
|
||||
private func login(username: String, password: String) {
|
||||
startLoading(isInteractionBlocking: true)
|
||||
|
||||
@@ -53,7 +53,8 @@ final class HomeScreenCoordinator: Coordinator, Presentable {
|
||||
init(parameters: HomeScreenCoordinatorParameters) {
|
||||
self.parameters = parameters
|
||||
|
||||
viewModel = HomeScreenViewModel(attributedStringBuilder: parameters.attributedStringBuilder)
|
||||
viewModel = HomeScreenViewModel(initialDisplayName: parameters.userSession.userID,
|
||||
attributedStringBuilder: parameters.attributedStringBuilder)
|
||||
|
||||
let view = HomeScreen(context: viewModel.context)
|
||||
hostingController = UIHostingController(rootView: view)
|
||||
|
||||
@@ -31,7 +31,7 @@ enum HomeScreenViewAction {
|
||||
}
|
||||
|
||||
struct HomeScreenViewState: BindableState {
|
||||
var userDisplayName: String?
|
||||
var userDisplayName: String
|
||||
var userAvatar: UIImage?
|
||||
|
||||
var showSessionVerificationBanner = false
|
||||
|
||||
@@ -39,10 +39,11 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
init(attributedStringBuilder: AttributedStringBuilderProtocol) {
|
||||
init(initialDisplayName: String, attributedStringBuilder: AttributedStringBuilderProtocol) {
|
||||
self.attributedStringBuilder = attributedStringBuilder
|
||||
|
||||
super.init(initialViewState: HomeScreenViewState(isLoadingRooms: true))
|
||||
super.init(initialViewState: HomeScreenViewState(userDisplayName: initialDisplayName,
|
||||
isLoadingRooms: true))
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
@@ -84,7 +84,7 @@ struct HomeScreen: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ViewBuilder
|
||||
private var userAvatarImage: some View {
|
||||
if let avatar = context.viewState.userAvatar {
|
||||
@@ -94,21 +94,14 @@ struct HomeScreen: View {
|
||||
.frame(width: 32, height: 32, alignment: .center)
|
||||
.clipShape(Circle())
|
||||
.accessibilityIdentifier("userAvatarImage")
|
||||
} else {
|
||||
EmptyView()
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
|
||||
private var userDisplayNameView: some View {
|
||||
if let displayName = context.viewState.userDisplayName {
|
||||
Text(displayName)
|
||||
.font(.headline)
|
||||
.fontWeight(.bold)
|
||||
.foregroundColor(.primary)
|
||||
} else {
|
||||
EmptyView()
|
||||
}
|
||||
Text(context.viewState.userDisplayName)
|
||||
.font(.headline)
|
||||
.fontWeight(.bold)
|
||||
.foregroundColor(.primary)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,11 +166,14 @@ struct RoomCell: View {
|
||||
struct HomeScreen_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
body.preferredColorScheme(.light)
|
||||
.tint(.element.accent)
|
||||
body.preferredColorScheme(.dark)
|
||||
.tint(.element.accent)
|
||||
}
|
||||
|
||||
static var body: some View {
|
||||
let viewModel = HomeScreenViewModel(attributedStringBuilder: AttributedStringBuilder())
|
||||
let viewModel = HomeScreenViewModel(initialDisplayName: "@username:server.com",
|
||||
attributedStringBuilder: AttributedStringBuilder())
|
||||
|
||||
let eventBrief = EventBrief(eventId: "id",
|
||||
senderId: "senderId",
|
||||
|
||||
Reference in New Issue
Block a user