mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-18 23:48:29 +02:00
Merge branch 'develop' into ismail/6177_wellknown_IS
This commit is contained in:
@@ -16,10 +16,14 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
protocol AuthenticationRestClient {
|
||||
protocol AuthenticationRestClient: AnyObject {
|
||||
// MARK: Configuration
|
||||
var credentials: MXCredentials! { get }
|
||||
var homeserver: String! { get }
|
||||
var identityServer: String! { get }
|
||||
var credentials: MXCredentials! { get }
|
||||
var acceptableContentTypes: Set<String>! { get set }
|
||||
|
||||
init(homeServer: URL, unrecognizedCertificateHandler handler: MXHTTPClientOnUnrecognizedCertificate?)
|
||||
|
||||
// MARK: Login
|
||||
var loginFallbackURL: URL { get }
|
||||
|
||||
@@ -36,15 +36,15 @@ class AuthenticationService: NSObject {
|
||||
|
||||
// MARK: Private
|
||||
|
||||
/// The rest client used to make authentication requests.
|
||||
private var client: AuthenticationRestClient
|
||||
/// The object used to create a new `MXSession` when authentication has completed.
|
||||
private var sessionCreator = SessionCreator()
|
||||
private var sessionCreator: SessionCreatorProtocol
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/// The current state of the authentication flow.
|
||||
private(set) var state: AuthenticationState
|
||||
/// The rest client used to make authentication requests.
|
||||
private(set) var client: AuthenticationRestClient
|
||||
/// The current login wizard or `nil` if `startFlow` hasn't been called.
|
||||
private(set) var loginWizard: LoginWizard?
|
||||
/// The current registration wizard or `nil` if `startFlow` hasn't been called for `.registration`.
|
||||
@@ -53,16 +53,21 @@ class AuthenticationService: NSObject {
|
||||
/// The authentication service's delegate.
|
||||
weak var delegate: AuthenticationServiceDelegate?
|
||||
|
||||
/// The type of client to use during the flow.
|
||||
var clientType: AuthenticationRestClient.Type = MXRestClient.self
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
override init() {
|
||||
init(sessionCreator: SessionCreatorProtocol = SessionCreator()) {
|
||||
guard let homeserverURL = URL(string: BuildSettings.serverConfigDefaultHomeserverUrlString) else {
|
||||
MXLog.failure("[AuthenticationService]: Failed to create URL from default homeserver URL string.")
|
||||
fatalError("Invalid default homeserver URL string.")
|
||||
}
|
||||
|
||||
state = AuthenticationState(flow: .login, homeserverAddress: BuildSettings.serverConfigDefaultHomeserverUrlString)
|
||||
client = MXRestClient(homeServer: homeserverURL, unrecognizedCertificateHandler: nil)
|
||||
client = clientType.init(homeServer: homeserverURL, unrecognizedCertificateHandler: nil)
|
||||
|
||||
self.sessionCreator = sessionCreator
|
||||
|
||||
super.init()
|
||||
}
|
||||
@@ -96,12 +101,12 @@ class AuthenticationService: NSObject {
|
||||
func startFlow(_ flow: AuthenticationFlow, for homeserverAddress: String) async throws {
|
||||
var (client, homeserver) = try await loginFlow(for: homeserverAddress)
|
||||
|
||||
let loginWizard = LoginWizard(client: client)
|
||||
let loginWizard = LoginWizard(client: client, sessionCreator: sessionCreator)
|
||||
self.loginWizard = loginWizard
|
||||
|
||||
if flow == .register {
|
||||
do {
|
||||
let registrationWizard = RegistrationWizard(client: client)
|
||||
let registrationWizard = RegistrationWizard(client: client, sessionCreator: sessionCreator)
|
||||
homeserver.registrationFlow = try await registrationWizard.registrationFlow()
|
||||
self.registrationWizard = registrationWizard
|
||||
} catch {
|
||||
@@ -200,7 +205,7 @@ class AuthenticationService: NSObject {
|
||||
}
|
||||
|
||||
#warning("Add an unrecognized certificate handler.")
|
||||
let client = MXRestClient(homeServer: homeserverURL, unrecognizedCertificateHandler: nil)
|
||||
let client = clientType.init(homeServer: homeserverURL, unrecognizedCertificateHandler: nil)
|
||||
if let identityServerURL = identityServerURL {
|
||||
client.identityServer = identityServerURL.absoluteString
|
||||
}
|
||||
@@ -229,7 +234,7 @@ class AuthenticationService: NSObject {
|
||||
return (client, homeserver)
|
||||
}
|
||||
|
||||
private func getLoginFlowResult(client: MXRestClient) async throws -> LoginFlowResult {
|
||||
private func getLoginFlowResult(client: AuthenticationRestClient) async throws -> LoginFlowResult {
|
||||
// Get the login flow
|
||||
let loginFlowResponse = try await client.getLoginSession()
|
||||
|
||||
@@ -241,7 +246,7 @@ class AuthenticationService: NSObject {
|
||||
|
||||
/// Perform a well-known request on the specified homeserver URL.
|
||||
private func wellKnown(for homeserverURL: URL) async throws -> MXWellKnown {
|
||||
let wellKnownClient = MXRestClient(homeServer: homeserverURL, unrecognizedCertificateHandler: nil)
|
||||
let wellKnownClient = clientType.init(homeServer: homeserverURL, unrecognizedCertificateHandler: nil)
|
||||
|
||||
// The .well-known/matrix/client API is often just a static file returned with no content type.
|
||||
// Make our HTTP client compatible with this behaviour
|
||||
|
||||
@@ -89,7 +89,6 @@ enum LoginMode {
|
||||
/// Data obtained when calling `LoginWizard.resetPassword` that will be used
|
||||
/// when calling `LoginWizard.checkResetPasswordMailConfirmed`.
|
||||
struct ResetPasswordData {
|
||||
let newPassword: String
|
||||
let addThreePIDSessionID: String
|
||||
}
|
||||
|
||||
|
||||
@@ -100,14 +100,18 @@ struct CheckResetPasswordParameters: DictionaryEncodable {
|
||||
let auth: AuthenticationParameters
|
||||
/// The new password
|
||||
let newPassword: String
|
||||
/// The sign out of all devices flag
|
||||
let signoutAllDevices: Bool
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case auth
|
||||
case newPassword = "new_password"
|
||||
case signoutAllDevices = "logout_devices"
|
||||
}
|
||||
|
||||
init(clientSecret: String, sessionID: String, newPassword: String) {
|
||||
init(clientSecret: String, sessionID: String, newPassword: String, signoutAllDevices: Bool) {
|
||||
self.auth = AuthenticationParameters.resetPasswordParameters(clientSecret: clientSecret, sessionID: sessionID)
|
||||
self.newPassword = newPassword
|
||||
self.signoutAllDevices = signoutAllDevices
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,11 +31,11 @@ class LoginWizard {
|
||||
}
|
||||
|
||||
let client: AuthenticationRestClient
|
||||
let sessionCreator: SessionCreator
|
||||
let sessionCreator: SessionCreatorProtocol
|
||||
|
||||
private(set) var state: State
|
||||
|
||||
init(client: AuthenticationRestClient, sessionCreator: SessionCreator = SessionCreator()) {
|
||||
init(client: AuthenticationRestClient, sessionCreator: SessionCreatorProtocol) {
|
||||
self.client = client
|
||||
self.sessionCreator = sessionCreator
|
||||
|
||||
@@ -87,24 +87,26 @@ class LoginWizard {
|
||||
// func loginCustom(data: Codable) async -> MXSession {
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
/// Ask the homeserver to reset the user password. The password will not be
|
||||
/// reset until `checkResetPasswordMailConfirmed` is successfully called.
|
||||
/// reset until `resetPasswordMailConfirmed` is successfully called.
|
||||
/// - Parameters:
|
||||
/// - email: An email previously associated to the account the user wants the password to be reset.
|
||||
/// - newPassword: The desired new password
|
||||
func resetPassword(email: String, newPassword: String) async throws {
|
||||
func resetPassword(email: String) async throws {
|
||||
let result = try await client.forgetPassword(for: email,
|
||||
clientSecret: state.clientSecret,
|
||||
sendAttempt: state.sendAttempt)
|
||||
|
||||
state.sendAttempt += 1
|
||||
state.resetPasswordData = ResetPasswordData(newPassword: newPassword, addThreePIDSessionID: result)
|
||||
state.resetPasswordData = ResetPasswordData(addThreePIDSessionID: result)
|
||||
}
|
||||
|
||||
|
||||
/// Confirm the new password, once the user has checked their email.
|
||||
/// When this method succeeds, the account password will be effectively modified.
|
||||
func checkResetPasswordMailConfirmed() async throws {
|
||||
/// - Parameters:
|
||||
/// - newPassword: The desired new password
|
||||
/// - signoutAllDevices: The flag to sign out of all devices
|
||||
func resetPasswordMailConfirmed(newPassword: String, signoutAllDevices: Bool) async throws {
|
||||
guard let resetPasswordData = state.resetPasswordData else {
|
||||
MXLog.error("[LoginWizard] resetPasswordMailConfirmed: Reset password data missing. Call resetPassword first.")
|
||||
throw LoginError.resetPasswordNotStarted
|
||||
@@ -112,7 +114,8 @@ class LoginWizard {
|
||||
|
||||
let parameters = CheckResetPasswordParameters(clientSecret: state.clientSecret,
|
||||
sessionID: resetPasswordData.addThreePIDSessionID,
|
||||
newPassword: resetPasswordData.newPassword)
|
||||
newPassword: newPassword,
|
||||
signoutAllDevices: signoutAllDevices)
|
||||
|
||||
try await client.resetPassword(parameters: parameters)
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import Foundation
|
||||
|
||||
/// The parameters used for registration requests.
|
||||
struct RegistrationParameters: DictionaryEncodable {
|
||||
struct RegistrationParameters: DictionaryEncodable, Equatable {
|
||||
/// Authentication parameters
|
||||
var auth: AuthenticationParameters?
|
||||
|
||||
@@ -44,7 +44,7 @@ struct RegistrationParameters: DictionaryEncodable {
|
||||
}
|
||||
|
||||
/// The data passed to the `auth` parameter in authentication requests.
|
||||
struct AuthenticationParameters: Encodable {
|
||||
struct AuthenticationParameters: Encodable, Equatable {
|
||||
/// The type of authentication taking place. The identifier from `MXLoginFlowType`.
|
||||
let type: String
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ class RegistrationWizard {
|
||||
}
|
||||
|
||||
let client: AuthenticationRestClient
|
||||
let sessionCreator: SessionCreator
|
||||
let sessionCreator: SessionCreatorProtocol
|
||||
|
||||
private(set) var state: State
|
||||
|
||||
@@ -59,7 +59,7 @@ class RegistrationWizard {
|
||||
state.isRegistrationStarted
|
||||
}
|
||||
|
||||
init(client: AuthenticationRestClient, sessionCreator: SessionCreator = SessionCreator()) {
|
||||
init(client: AuthenticationRestClient, sessionCreator: SessionCreatorProtocol) {
|
||||
self.client = client
|
||||
self.sessionCreator = sessionCreator
|
||||
|
||||
|
||||
@@ -16,9 +16,17 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
/// A WIP class that has common functionality to create a new session.
|
||||
class SessionCreator {
|
||||
protocol SessionCreatorProtocol {
|
||||
/// Creates an `MXSession` using the supplied credentials and REST client.
|
||||
/// - Parameters:
|
||||
/// - credentials: The `MXCredentials` for the account.
|
||||
/// - client: The client that completed the authentication.
|
||||
/// - Returns: A new `MXSession` for the account.
|
||||
func createSession(credentials: MXCredentials, client: AuthenticationRestClient) -> MXSession
|
||||
}
|
||||
|
||||
/// A struct that provides common functionality to create a new session.
|
||||
struct SessionCreator: SessionCreatorProtocol {
|
||||
func createSession(credentials: MXCredentials, client: AuthenticationRestClient) -> MXSession {
|
||||
// Report the new account in account manager
|
||||
if credentials.identityServer == nil {
|
||||
|
||||
@@ -21,7 +21,7 @@ enum RegisterThreePID {
|
||||
case msisdn(msisdn: String, countryCode: String)
|
||||
}
|
||||
|
||||
struct ThreePIDCredentials: Codable {
|
||||
struct ThreePIDCredentials: Codable, Equatable {
|
||||
var clientSecret: String?
|
||||
|
||||
var identityServer: String?
|
||||
|
||||
Reference in New Issue
Block a user