mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-05 20:09:04 +00:00
Add an AccountProvider type and use it within the authentication flow. (#6103)
* Add an AccountProvider type and use it within AppSettings. * Use the AccountProvider type within the Authentication flow too. * Fix unit test compilation with Swift 6.4 * Make sure defaultAccountProvider takes allowOtherAccountProviders into account. * Document a caveat on using AuthenticationService.homeserver.value.accountProvider.
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// Copyright 2026 Element Creations Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
nonisolated enum AccountProvider: Equatable {
|
||||
/// An account provider that was input/chosen by the user.
|
||||
case generic(String)
|
||||
/// An account provider as provided by the app.
|
||||
case managed(serverName: String, baseURL: URL, canUseServerName: Bool = true)
|
||||
|
||||
/// The account provider's string value, shown in the UI and used to build a `Client` with.
|
||||
var serverNameOrBaseURL: String {
|
||||
let serverNameOrBaseURL = switch self {
|
||||
case .generic(let serverNameOrBaseURL):
|
||||
serverNameOrBaseURL
|
||||
case .managed(let serverName, let baseURL, let canUseServerName):
|
||||
canUseServerName ? serverName : baseURL.absoluteString
|
||||
}
|
||||
|
||||
return sanitize(serverNameOrBaseURL)
|
||||
}
|
||||
|
||||
var isGeneric: Bool {
|
||||
switch self {
|
||||
case .generic: true
|
||||
case .managed: false
|
||||
}
|
||||
}
|
||||
|
||||
/// Sanitizes an address with the following rules:
|
||||
/// - Trim any whitespace.
|
||||
/// - Lowercase the address.
|
||||
/// - Removes an https scheme (treating it as implicit).
|
||||
/// - Remove any trailing slashes.
|
||||
private func sanitize(_ serverNameOrBaseURL: String) -> String {
|
||||
serverNameOrBaseURL
|
||||
.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
.lowercased()
|
||||
.trimmingPrefix("https://") // Intentionally continue to show http:// as an indicator (and for history).
|
||||
.trimmingCharacters(in: CharacterSet(charactersIn: "/"))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Array
|
||||
|
||||
extension [AccountProvider] {
|
||||
/// Whether the collection includes a provider matching the given server name or base URL.
|
||||
func contains(serverName: String?, orBaseURL baseURL: URL?) -> Bool {
|
||||
contains { accountProvider in
|
||||
switch accountProvider {
|
||||
case .generic(let serverNameOrBaseURL):
|
||||
// Lower case potential user input to be safe. Full sanitisation is wrong given the scheme would be ignored.
|
||||
serverNameOrBaseURL.lowercased() == serverName || serverNameOrBaseURL.lowercased() == baseURL?.absoluteString
|
||||
case .managed(let providerServerName, let providerBaseURL, _):
|
||||
// We can ignore canUseServerName here, it's about constructing a client rather than matching.
|
||||
providerServerName == serverName || providerBaseURL == baseURL
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user