mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 12:07:55 +00:00
Create sessions through the user session manager
Sign-in now creates and stores its session through the UserSessionManagerProtocol rather than the UserSessionStore, so the AppCoordinator no longer holds the store. - The manager forwards clientSessionDelegate and userSession(for:sessionDirectories:passphrase:) to its store. As with restoring, the new session isn't registered until the AppCoordinator adds it. - AuthenticationService takes the manager, for both sign-in and soft logout. - The store mock's configuration moves to the manager mock.
This commit is contained in:
@@ -784,7 +784,6 @@
|
||||
79741C1953269FF1A211D246 /* RoomPollsHistoryScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0E14FF533D25A0692F7CEB0 /* RoomPollsHistoryScreenViewModel.swift */; };
|
||||
798BF3072137833FBD3F4C96 /* TimelineDeliveryStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66F91544AC136BF6477BDAB8 /* TimelineDeliveryStatusView.swift */; };
|
||||
79959F8E45C3749997482A7F /* TimelineItemBubbledStylerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A459AE4B6566B2FA99E86B2 /* TimelineItemBubbledStylerView.swift */; };
|
||||
79D57E9AE03A2DC689D14EA2 /* UserSessionStoreMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB9BA2F30EB8C33226D8FF1 /* UserSessionStoreMock.swift */; };
|
||||
7A02EB29F3B993AB20E0A198 /* RoomPollsHistoryScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42C8C368A611B9CB79C7F5FA /* RoomPollsHistoryScreen.swift */; };
|
||||
7A0D335D38ECA095A575B4F7 /* TimelineStyler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DB0E533508094156D8024C3 /* TimelineStyler.swift */; };
|
||||
7A25D6926A2C01DB8D0D67A5 /* BadgeLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A028783CFFF861C5E44FFB1 /* BadgeLabel.swift */; };
|
||||
@@ -1538,6 +1537,7 @@
|
||||
EEC40663922856C65D1E0DF5 /* KeychainControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDB9C37196A4C79F24CE80C6 /* KeychainControllerTests.swift */; };
|
||||
EED33AFD9334EFD7398707A6 /* VisualListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD529C89924EE32CE307F36F /* VisualListItem.swift */; };
|
||||
EED3C107FEE82E324B3A2083 /* preview_image.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 44688A16934827A0D1668253 /* preview_image.jpg */; };
|
||||
EF03CD926B9444EF2E382E82 /* UserSessionManagerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = F483F39C950CB002F2DE6C69 /* UserSessionManagerMock.swift */; };
|
||||
EF0D0155DD104C7A41A2EB0E /* PlainMentionBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AE78FA0011E07920AE83135 /* PlainMentionBuilder.swift */; };
|
||||
EF1C1A5D212B14FFCE0E7C83 /* SpaceScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 094F6B21835890B470DF540C /* SpaceScreenCoordinator.swift */; };
|
||||
EF47D802A404A53F15D5D4B6 /* JoinRoomScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CD7C0A2750998C2D77AD00F /* JoinRoomScreenViewModel.swift */; };
|
||||
@@ -2736,7 +2736,6 @@
|
||||
9E3B41C36800DD4558D7BDA7 /* VoiceMessageRoomPlaybackView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceMessageRoomPlaybackView.swift; sourceTree = "<group>"; };
|
||||
9E6D88E8AFFBF2C1D589C0FA /* UIConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIConstants.swift; sourceTree = "<group>"; };
|
||||
9E8F4D7D61B80EBD5CB92F8A /* KnockedRoomProxyMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KnockedRoomProxyMock.swift; sourceTree = "<group>"; };
|
||||
9EB9BA2F30EB8C33226D8FF1 /* UserSessionStoreMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionStoreMock.swift; sourceTree = "<group>"; };
|
||||
9ECF11669EF253E98AA2977A /* CompletionSuggestionServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompletionSuggestionServiceProtocol.swift; sourceTree = "<group>"; };
|
||||
9F1DF3FFFE5ED2B8133F43A7 /* MessageComposer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageComposer.swift; sourceTree = "<group>"; };
|
||||
9F3E4640982CE98C6ADD7896 /* SearchServiceProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchServiceProxyProtocol.swift; sourceTree = "<group>"; };
|
||||
@@ -3279,6 +3278,7 @@
|
||||
F4469F6AE311BDC439B3A5EC /* UserSessionMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionMock.swift; sourceTree = "<group>"; };
|
||||
F4548A9BDE5CB3AB864BCA9F /* EffectsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EffectsView.swift; sourceTree = "<group>"; };
|
||||
F46E441BA50705E6CEC89FE0 /* RoomSummaryProviderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryProviderTests.swift; sourceTree = "<group>"; };
|
||||
F483F39C950CB002F2DE6C69 /* UserSessionManagerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionManagerMock.swift; sourceTree = "<group>"; };
|
||||
F48A2FA6814F824ABB4C07F3 /* RoomCallControlsToolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomCallControlsToolbar.swift; sourceTree = "<group>"; };
|
||||
F4CEB4590CCF70F0E3C0B171 /* GeneratedAccessibilityTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneratedAccessibilityTests.swift; sourceTree = "<group>"; };
|
||||
F505E3D79018B6EFF953F647 /* MediaEventsTimelineScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaEventsTimelineScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
@@ -4162,8 +4162,8 @@
|
||||
17A8AA0DFA06012A9DAB951E /* TimelineProxyMock.swift */,
|
||||
8536B40F578BA7FDB23D97B1 /* UserIdentityProxyMock.swift */,
|
||||
AAD01F7FC2BBAC7351948595 /* UserProfile+Mock.swift */,
|
||||
F483F39C950CB002F2DE6C69 /* UserSessionManagerMock.swift */,
|
||||
F4469F6AE311BDC439B3A5EC /* UserSessionMock.swift */,
|
||||
9EB9BA2F30EB8C33226D8FF1 /* UserSessionStoreMock.swift */,
|
||||
B23135B06B044CB811139D2F /* Generated */,
|
||||
E5E545F92D01588360A9BAC5 /* SDK */,
|
||||
);
|
||||
@@ -9820,11 +9820,11 @@
|
||||
4A618590DEB72C4F186BFED4 /* UserSessionFlowCoordinator.swift in Sources */,
|
||||
91C590378C591DCA3E40416A /* UserSessionHook.swift in Sources */,
|
||||
87DCBD9BC3A00D3E5849460B /* UserSessionManager.swift in Sources */,
|
||||
EF03CD926B9444EF2E382E82 /* UserSessionManagerMock.swift in Sources */,
|
||||
9FCE652911C1CDA6DC51924B /* UserSessionManagerProtocol.swift in Sources */,
|
||||
6586E1F1D5F0651D0638FFAF /* UserSessionMock.swift in Sources */,
|
||||
978BB24F2A5D31EE59EEC249 /* UserSessionProtocol.swift in Sources */,
|
||||
7E91BAC17963ED41208F489B /* UserSessionStore.swift in Sources */,
|
||||
79D57E9AE03A2DC689D14EA2 /* UserSessionStoreMock.swift in Sources */,
|
||||
AC69B6DF15FC451AB2945036 /* UserSessionStoreProtocol.swift in Sources */,
|
||||
AF640383EC85741D33F7558F /* UserSettings.swift in Sources */,
|
||||
9707AF8D41667FA9B35E8953 /* UserToInvite.swift in Sources */,
|
||||
|
||||
@@ -18,7 +18,6 @@ import Version
|
||||
class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDelegate, NotificationManagerDelegate, SecureWindowManagerDelegate {
|
||||
private let stateMachine: AppCoordinatorStateMachine
|
||||
private let navigationRootCoordinator: NavigationRootCoordinator
|
||||
private let userSessionStore: UserSessionStoreProtocol
|
||||
private let userSessionManager: UserSessionManagerProtocol
|
||||
// periphery:ignore - retaining purpose
|
||||
private let targetConfiguration: Target.ConfigurationResult
|
||||
@@ -117,11 +116,11 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
|
||||
|
||||
let keychainController = KeychainController(service: .sessions,
|
||||
accessGroup: InfoPlistReader.main.keychainAccessGroupIdentifier)
|
||||
userSessionStore = UserSessionStore(keychainController: keychainController,
|
||||
appSettings: appSettings,
|
||||
analyticsService: analyticsService,
|
||||
appHooks: appHooks,
|
||||
networkMonitor: networkMonitor)
|
||||
let userSessionStore = UserSessionStore(keychainController: keychainController,
|
||||
appSettings: appSettings,
|
||||
analyticsService: analyticsService,
|
||||
appHooks: appHooks,
|
||||
networkMonitor: networkMonitor)
|
||||
userSessionManager = UserSessionManager(userSessionStore: userSessionStore, appSettings: appSettings)
|
||||
|
||||
let appLockService = AppLockService(keychainController: keychainController, appSettings: appSettings)
|
||||
@@ -681,7 +680,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
|
||||
private func startAuthentication() {
|
||||
let encryptionKeyProvider = EncryptionKeyProvider()
|
||||
let classicAppManager = ClassicAppManager()
|
||||
let authenticationService = AuthenticationService(userSessionStore: userSessionStore,
|
||||
let authenticationService = AuthenticationService(userSessionManager: userSessionManager,
|
||||
encryptionKeyProvider: encryptionKeyProvider,
|
||||
classicAppManager: classicAppManager,
|
||||
appSettings: appSettings,
|
||||
@@ -736,7 +735,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
|
||||
userDisplayName: userSession.clientProxy.userProfilePublisher.value.displayName ?? "",
|
||||
deviceID: userSession.clientProxy.deviceID)
|
||||
|
||||
let authenticationService = AuthenticationService(userSessionStore: userSessionStore,
|
||||
let authenticationService = AuthenticationService(userSessionManager: userSessionManager,
|
||||
encryptionKeyProvider: EncryptionKeyProvider(),
|
||||
classicAppManager: ClassicAppManager(),
|
||||
appSettings: appSettings,
|
||||
|
||||
@@ -14818,6 +14818,11 @@ nonisolated class UserSessionManagerMock: UserSessionManagerProtocol, @unchecked
|
||||
}
|
||||
nonisolated(unsafe) var underlyingSessionsPublisher: CurrentValuePublisher<[UserSessionProtocol], Never>!
|
||||
nonisolated(unsafe) var activeSession: UserSessionProtocol?
|
||||
var clientSessionDelegate: ClientSessionDelegate {
|
||||
get { return underlyingClientSessionDelegate }
|
||||
set(value) { underlyingClientSessionDelegate = value }
|
||||
}
|
||||
nonisolated(unsafe) var underlyingClientSessionDelegate: ClientSessionDelegate!
|
||||
|
||||
//MARK: - session
|
||||
|
||||
@@ -14889,6 +14894,48 @@ nonisolated class UserSessionManagerMock: UserSessionManagerProtocol, @unchecked
|
||||
return restoreActiveSessionReturnValue
|
||||
}
|
||||
}
|
||||
//MARK: - userSession
|
||||
|
||||
private let userSessionForSessionDirectoriesPassphraseCallsCountLock = NSLock()
|
||||
private nonisolated(unsafe) var userSessionForSessionDirectoriesPassphraseUnderlyingCallsCount = 0
|
||||
var userSessionForSessionDirectoriesPassphraseCallsCount: Int {
|
||||
get { userSessionForSessionDirectoriesPassphraseCallsCountLock.withLock { userSessionForSessionDirectoriesPassphraseUnderlyingCallsCount } }
|
||||
set { userSessionForSessionDirectoriesPassphraseCallsCountLock.withLock { userSessionForSessionDirectoriesPassphraseUnderlyingCallsCount = newValue } }
|
||||
}
|
||||
var userSessionForSessionDirectoriesPassphraseCalled: Bool {
|
||||
return userSessionForSessionDirectoriesPassphraseCallsCount > 0
|
||||
}
|
||||
private let userSessionForSessionDirectoriesPassphraseReceivedArgumentsLock = NSLock()
|
||||
private nonisolated(unsafe) var userSessionForSessionDirectoriesPassphraseUnderlyingReceivedArguments: (client: ClientProtocol, sessionDirectories: SessionDirectories, passphrase: Data)?
|
||||
var userSessionForSessionDirectoriesPassphraseReceivedArguments: (client: ClientProtocol, sessionDirectories: SessionDirectories, passphrase: Data)? {
|
||||
get { userSessionForSessionDirectoriesPassphraseReceivedArgumentsLock.withLock { userSessionForSessionDirectoriesPassphraseUnderlyingReceivedArguments } }
|
||||
set { userSessionForSessionDirectoriesPassphraseReceivedArgumentsLock.withLock { userSessionForSessionDirectoriesPassphraseUnderlyingReceivedArguments = newValue } }
|
||||
}
|
||||
private let userSessionForSessionDirectoriesPassphraseReceivedInvocationsLock = NSLock()
|
||||
private nonisolated(unsafe) var userSessionForSessionDirectoriesPassphraseUnderlyingReceivedInvocations: [(client: ClientProtocol, sessionDirectories: SessionDirectories, passphrase: Data)] = []
|
||||
var userSessionForSessionDirectoriesPassphraseReceivedInvocations: [(client: ClientProtocol, sessionDirectories: SessionDirectories, passphrase: Data)] {
|
||||
get { userSessionForSessionDirectoriesPassphraseReceivedInvocationsLock.withLock { userSessionForSessionDirectoriesPassphraseUnderlyingReceivedInvocations } }
|
||||
set { userSessionForSessionDirectoriesPassphraseReceivedInvocationsLock.withLock { userSessionForSessionDirectoriesPassphraseUnderlyingReceivedInvocations = newValue } }
|
||||
}
|
||||
|
||||
private let userSessionForSessionDirectoriesPassphraseReturnValueLock = NSLock()
|
||||
private nonisolated(unsafe) var userSessionForSessionDirectoriesPassphraseUnderlyingReturnValue: Result<UserSessionProtocol, UserSessionStoreError>!
|
||||
var userSessionForSessionDirectoriesPassphraseReturnValue: Result<UserSessionProtocol, UserSessionStoreError>! {
|
||||
get { userSessionForSessionDirectoriesPassphraseReturnValueLock.withLock { userSessionForSessionDirectoriesPassphraseUnderlyingReturnValue } }
|
||||
set { userSessionForSessionDirectoriesPassphraseReturnValueLock.withLock { userSessionForSessionDirectoriesPassphraseUnderlyingReturnValue = newValue } }
|
||||
}
|
||||
nonisolated(unsafe) var userSessionForSessionDirectoriesPassphraseClosure: ((ClientProtocol, SessionDirectories, Data) async -> Result<UserSessionProtocol, UserSessionStoreError>)?
|
||||
|
||||
@concurrent func userSession(for client: ClientProtocol, sessionDirectories: SessionDirectories, passphrase: Data) async -> Result<UserSessionProtocol, UserSessionStoreError> {
|
||||
userSessionForSessionDirectoriesPassphraseCallsCountLock.withLock { userSessionForSessionDirectoriesPassphraseUnderlyingCallsCount += 1 }
|
||||
userSessionForSessionDirectoriesPassphraseReceivedArguments = (client: client, sessionDirectories: sessionDirectories, passphrase: passphrase)
|
||||
userSessionForSessionDirectoriesPassphraseReceivedInvocationsLock.withLock { userSessionForSessionDirectoriesPassphraseUnderlyingReceivedInvocations.append((client: client, sessionDirectories: sessionDirectories, passphrase: passphrase)) }
|
||||
if let userSessionForSessionDirectoriesPassphraseClosure = userSessionForSessionDirectoriesPassphraseClosure {
|
||||
return await userSessionForSessionDirectoriesPassphraseClosure(client, sessionDirectories, passphrase)
|
||||
} else {
|
||||
return userSessionForSessionDirectoriesPassphraseReturnValue
|
||||
}
|
||||
}
|
||||
//MARK: - add
|
||||
|
||||
private let addCallsCountLock = NSLock()
|
||||
|
||||
+2
-3
@@ -1,12 +1,11 @@
|
||||
//
|
||||
// Copyright 2025 Element Creations Ltd.
|
||||
// Copyright 2024-2025 New Vector Ltd.
|
||||
// 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.
|
||||
//
|
||||
|
||||
extension UserSessionStoreMock {
|
||||
extension UserSessionManagerMock {
|
||||
struct Configuration { }
|
||||
|
||||
convenience init(_ configuration: Configuration) {
|
||||
@@ -15,7 +15,7 @@ class AuthenticationService: AuthenticationServiceProtocol {
|
||||
private var sessionDirectories: SessionDirectories
|
||||
private let passphrase: Data
|
||||
|
||||
private let userSessionStore: UserSessionStoreProtocol
|
||||
private let userSessionManager: UserSessionManagerProtocol
|
||||
private let classicAppManager: ClassicAppManagerProtocol?
|
||||
private let clientFactory: ClientFactoryProtocol
|
||||
private let appSettings: AppSettings
|
||||
@@ -33,7 +33,7 @@ class AuthenticationService: AuthenticationServiceProtocol {
|
||||
|
||||
let classicAppAccount: ClassicAppAccount?
|
||||
|
||||
init(userSessionStore: UserSessionStoreProtocol,
|
||||
init(userSessionManager: UserSessionManagerProtocol,
|
||||
encryptionKeyProvider: EncryptionKeyProviderProtocol,
|
||||
classicAppManager: ClassicAppManagerProtocol?,
|
||||
clientFactory: ClientFactoryProtocol = ClientFactory(),
|
||||
@@ -42,7 +42,7 @@ class AuthenticationService: AuthenticationServiceProtocol {
|
||||
sessionDirectories = .init()
|
||||
passphrase = encryptionKeyProvider.generateKey()
|
||||
|
||||
self.userSessionStore = userSessionStore
|
||||
self.userSessionManager = userSessionManager
|
||||
self.classicAppManager = classicAppManager
|
||||
self.clientFactory = clientFactory
|
||||
self.appSettings = appSettings
|
||||
@@ -270,7 +270,7 @@ class AuthenticationService: AuthenticationServiceProtocol {
|
||||
let client = try await clientFactory.makeAuthenticationClient(serverNameOrBaseURL: serverNameOrBaseURL,
|
||||
sessionDirectories: sessionDirectories,
|
||||
passphrase: passphrase,
|
||||
clientSessionDelegate: userSessionStore.clientSessionDelegate,
|
||||
clientSessionDelegate: userSessionManager.clientSessionDelegate,
|
||||
appSettings: appSettings,
|
||||
appHooks: appHooks)
|
||||
try await appHooks.remoteSettingsHook.initializeCache(using: client, applyingTo: appSettings).get()
|
||||
@@ -284,7 +284,7 @@ class AuthenticationService: AuthenticationServiceProtocol {
|
||||
}
|
||||
|
||||
private func userSession(for client: ClientProtocol) async -> Result<UserSessionProtocol, AuthenticationServiceError> {
|
||||
switch await userSessionStore.userSession(for: client, sessionDirectories: sessionDirectories, passphrase: passphrase) {
|
||||
switch await userSessionManager.userSession(for: client, sessionDirectories: sessionDirectories, passphrase: passphrase) {
|
||||
case .success(let clientProxy):
|
||||
return .success(clientProxy)
|
||||
case .failure:
|
||||
@@ -302,7 +302,7 @@ class AuthenticationService: AuthenticationServiceProtocol {
|
||||
|
||||
do {
|
||||
let client = try await clientFactory.makeInMemoryClient(serverNameOrBaseURL: classicAppAccount.homeserverURL.absoluteString,
|
||||
clientSessionDelegate: userSessionStore.clientSessionDelegate,
|
||||
clientSessionDelegate: userSessionManager.clientSessionDelegate,
|
||||
appSettings: appSettings,
|
||||
appHooks: appHooks)
|
||||
let loginDetails = await client.homeserverLoginDetails()
|
||||
@@ -406,7 +406,7 @@ extension AuthenticationService {
|
||||
}
|
||||
|
||||
static func mock(classicAppManager: ClassicAppManagerProtocol?) -> AuthenticationService {
|
||||
AuthenticationService(userSessionStore: UserSessionStoreMock(.init()),
|
||||
AuthenticationService(userSessionManager: UserSessionManagerMock(.init()),
|
||||
encryptionKeyProvider: EncryptionKeyProvider(),
|
||||
classicAppManager: classicAppManager,
|
||||
clientFactory: ClientFactoryMock(.init()),
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
import Combine
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
import OrderedCollections
|
||||
|
||||
/// Owns the live session of every account signed in on this device, most recently active first.
|
||||
@@ -37,6 +38,10 @@ final class UserSessionManager: UserSessionManagerProtocol {
|
||||
accounts.values.first ?? nil
|
||||
}
|
||||
|
||||
var clientSessionDelegate: ClientSessionDelegate {
|
||||
userSessionStore.clientSessionDelegate
|
||||
}
|
||||
|
||||
init(userSessionStore: UserSessionStoreProtocol, appSettings: AppSettings) {
|
||||
self.userSessionStore = userSessionStore
|
||||
self.appSettings = appSettings
|
||||
@@ -79,6 +84,10 @@ final class UserSessionManager: UserSessionManagerProtocol {
|
||||
return .failure(.failedRestoringSessions)
|
||||
}
|
||||
|
||||
func userSession(for client: ClientProtocol, sessionDirectories: SessionDirectories, passphrase: Data) async -> Result<UserSessionProtocol, UserSessionStoreError> {
|
||||
await userSessionStore.userSession(for: client, sessionDirectories: sessionDirectories, passphrase: passphrase)
|
||||
}
|
||||
|
||||
func add(_ userSession: UserSessionProtocol) {
|
||||
let userID = userSession.clientProxy.userID
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
import Combine
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
|
||||
enum UserSessionManagerError: Error {
|
||||
/// There are no signed in accounts to restore.
|
||||
@@ -23,6 +24,8 @@ protocol UserSessionManagerProtocol: AnyObject {
|
||||
var sessionsPublisher: CurrentValuePublisher<[UserSessionProtocol], Never> { get }
|
||||
/// The session of the account whose UI is on screen.
|
||||
var activeSession: UserSessionProtocol? { get }
|
||||
/// The delegate that stores changes to a client's session, such as refreshed tokens.
|
||||
var clientSessionDelegate: ClientSessionDelegate { get }
|
||||
|
||||
func session(for userID: String) -> UserSessionProtocol?
|
||||
|
||||
@@ -32,6 +35,10 @@ protocol UserSessionManagerProtocol: AnyObject {
|
||||
///
|
||||
/// The session isn't registered: `add` it once it's ready to be used, e.g. after any migrations.
|
||||
func restoreActiveSession() async -> Result<UserSessionProtocol, UserSessionManagerError>
|
||||
/// Creates the session of an account that has just signed in, and stores its credentials.
|
||||
///
|
||||
/// The session isn't registered: `add` it once it's ready to be used.
|
||||
func userSession(for client: ClientProtocol, sessionDirectories: SessionDirectories, passphrase: Data) async -> Result<UserSessionProtocol, UserSessionStoreError>
|
||||
/// Registers a session that's ready to be used, replacing any previous session for its account.
|
||||
/// A new account becomes the active one, a known account keeps its place.
|
||||
func add(_ userSession: UserSessionProtocol)
|
||||
|
||||
@@ -15,7 +15,7 @@ import Testing
|
||||
struct AuthenticationServiceTests {
|
||||
var client: ClientSDKMock!
|
||||
var encryption: EncryptionSDKMock!
|
||||
var userSessionStore: UserSessionStoreMock!
|
||||
var userSessionManager: UserSessionManagerMock!
|
||||
var encryptionKeyProvider: MockEncryptionKeyProvider!
|
||||
var service: AuthenticationService!
|
||||
|
||||
@@ -36,8 +36,8 @@ struct AuthenticationServiceTests {
|
||||
switch await service.login(username: "alice", password: "12345678", initialDeviceName: nil, deviceID: nil) {
|
||||
case .success:
|
||||
#expect(client.loginUsernamePasswordInitialDeviceNameDeviceIdCallsCount == 1)
|
||||
#expect(userSessionStore.userSessionForSessionDirectoriesPassphraseCallsCount == 1)
|
||||
#expect(userSessionStore.userSessionForSessionDirectoriesPassphraseReceivedArguments?.passphrase == encryptionKeyProvider.generateKey())
|
||||
#expect(userSessionManager.userSessionForSessionDirectoriesPassphraseCallsCount == 1)
|
||||
#expect(userSessionManager.userSessionForSessionDirectoriesPassphraseReceivedArguments?.passphrase == encryptionKeyProvider.generateKey())
|
||||
case .failure(let error):
|
||||
Issue.record("Unexpected failure: \(error)")
|
||||
}
|
||||
@@ -138,14 +138,14 @@ struct AuthenticationServiceTests {
|
||||
encryption = EncryptionSDKMock()
|
||||
client.encryptionReturnValue = encryption
|
||||
|
||||
userSessionStore = UserSessionStoreMock(.init())
|
||||
userSessionManager = UserSessionManagerMock(.init())
|
||||
encryptionKeyProvider = MockEncryptionKeyProvider()
|
||||
|
||||
let classicAppManager = ClassicAppManagerMock(.init(accounts: classicAppAccounts,
|
||||
availableSecrets: availableSecrets,
|
||||
secretsBundle: SecretsBundleWithUserIdSDKMock()))
|
||||
|
||||
service = AuthenticationService(userSessionStore: userSessionStore,
|
||||
service = AuthenticationService(userSessionManager: userSessionManager,
|
||||
encryptionKeyProvider: encryptionKeyProvider,
|
||||
classicAppManager: classicAppManager,
|
||||
clientFactory: clientFactory,
|
||||
|
||||
@@ -296,7 +296,7 @@ final class AuthenticationStartScreenViewModelTests {
|
||||
notificationCenter = NotificationCenter()
|
||||
|
||||
clientFactory = ClientFactoryMock(configuration)
|
||||
authenticationService = AuthenticationService(userSessionStore: UserSessionStoreMock(.init()),
|
||||
authenticationService = AuthenticationService(userSessionManager: UserSessionManagerMock(.init()),
|
||||
encryptionKeyProvider: EncryptionKeyProvider(),
|
||||
classicAppManager: classicAppManager,
|
||||
clientFactory: clientFactory,
|
||||
|
||||
@@ -230,7 +230,7 @@ struct LoginScreenViewModelTests {
|
||||
let appSettings = AppSettings.volatile()
|
||||
|
||||
clientFactory = ClientFactoryMock(.init())
|
||||
service = AuthenticationService(userSessionStore: UserSessionStoreMock(.init()),
|
||||
service = AuthenticationService(userSessionManager: UserSessionManagerMock(.init()),
|
||||
encryptionKeyProvider: EncryptionKeyProvider(),
|
||||
classicAppManager: nil,
|
||||
clientFactory: clientFactory,
|
||||
|
||||
@@ -363,7 +363,7 @@ struct ServerSelectionScreenViewModelTests {
|
||||
client = factoryConfiguration.homeserverClients["matrix.org"]
|
||||
clientFactory = ClientFactoryMock(factoryConfiguration)
|
||||
|
||||
service = AuthenticationService(userSessionStore: UserSessionStoreMock(.init()),
|
||||
service = AuthenticationService(userSessionManager: UserSessionManagerMock(.init()),
|
||||
encryptionKeyProvider: EncryptionKeyProvider(),
|
||||
classicAppManager: nil,
|
||||
clientFactory: clientFactory,
|
||||
|
||||
Reference in New Issue
Block a user