diff --git a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index f80659ec0..d97927b30 100644 --- a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -95,8 +95,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/matrix-org/matrix-rust-components-swift", "state" : { - "revision" : "852bb356fbd2b5053f17b3c6c27c8c098cf5f055", - "version" : "1.0.42-alpha" + "revision" : "32645162ea39badc586d610d2ada6bbc52f398ba", + "version" : "1.0.43-alpha" } }, { diff --git a/ElementX/Sources/Application/AppCoordinator.swift b/ElementX/Sources/Application/AppCoordinator.swift index ad3dd41ea..0d50222f7 100644 --- a/ElementX/Sources/Application/AppCoordinator.swift +++ b/ElementX/Sources/Application/AppCoordinator.swift @@ -154,7 +154,6 @@ class AppCoordinator: AppCoordinatorProtocol { userSessionStore.reset() } - // swiftlint:disable:next cyclomatic_complexity private func setupStateMachine() { stateMachine.addTransitionHandler { [weak self] context in guard let self else { return } @@ -162,25 +161,19 @@ class AppCoordinator: AppCoordinatorProtocol { switch (context.fromState, context.event, context.toState) { case (.initial, .startWithAuthentication, .signedOut): self.startAuthentication() - case (.signedOut, .succeededSigningIn, .signedIn): + case (.signedOut, .createdUserSession, .signedIn): self.setupUserSession() case (.initial, .startWithExistingSession, .restoringSession): self.restoreUserSession() case (.restoringSession, .failedRestoringSession, .signedOut): self.showLoginErrorToast() self.presentSplashScreen() - case (.restoringSession, .succeededRestoringSession, .signedIn): + case (.restoringSession, .createdUserSession, .signedIn): self.setupUserSession() - case (_, .signOut, .signingOut): - self.logout(isSoftLogout: false) - case (.signingOut, .completedSigningOut, .signedOut): - self.tearDownUserSession() - self.presentSplashScreen() - case (_, .remoteSignOut(let isSoftLogout), .remoteSigningOut): - self.logout(isSoftLogout: isSoftLogout) - case (.remoteSigningOut(let isSoftLogout), .completedSigningOut, .signedOut): - self.tearDownUserSession() - self.presentSplashScreen(isSoftLogout: isSoftLogout) + case (_, .signOut(let isSoft), .signingOut): + self.logout(isSoft: isSoft) + case (.signingOut, .completedSigningOut(let isSoft), .signedOut): + self.presentSplashScreen(isSoftLogout: isSoft) default: fatalError("Unknown transition: \(context)") } @@ -196,11 +189,7 @@ class AppCoordinator: AppCoordinatorProtocol { switch await userSessionStore.restoreUserSession() { case .success(let userSession): self.userSession = userSession - if userSession.isSoftLogout { - stateMachine.processEvent(.remoteSignOut(isSoft: true)) - } else { - stateMachine.processEvent(.succeededRestoringSession) - } + stateMachine.processEvent(.createdUserSession) case .failure: MXLog.error("Failed to restore an existing session.") stateMachine.processEvent(.failedRestoringSession) @@ -243,12 +232,9 @@ class AppCoordinator: AppCoordinatorProtocol { switch result { case .signedIn(let session): self.userSession = session - self.stateMachine.processEvent(.succeededSigningIn) + self.stateMachine.processEvent(.createdUserSession) case .clearAllData: - // clear user data - self.userSessionStore.logout(userSession: self.userSession) - self.userSession = nil - self.startAuthentication() + self.stateMachine.processEvent(.signOut(isSoft: false)) } } @@ -266,7 +252,7 @@ class AppCoordinator: AppCoordinatorProtocol { userSessionFlowCoordinator.callback = { [weak self] action in switch action { case .signOut: - self?.stateMachine.processEvent(.signOut) + self?.stateMachine.processEvent(.signOut(isSoft: false)) } } @@ -277,7 +263,7 @@ class AppCoordinator: AppCoordinatorProtocol { navigationRootCoordinator.setRootCoordinator(navigationSplitCoordinator) } - private func logout(isSoftLogout: Bool) { + private func logout(isSoft: Bool) { showLoadingIndicator() defer { @@ -287,8 +273,8 @@ class AppCoordinator: AppCoordinatorProtocol { userSession.clientProxy.stopSync() userSessionFlowCoordinator?.stop() - guard !isSoftLogout else { - stateMachine.processEvent(.completedSigningOut) + guard !isSoft else { + stateMachine.processEvent(.completedSigningOut(isSoft: isSoft)) return } @@ -298,8 +284,9 @@ class AppCoordinator: AppCoordinatorProtocol { // regardless of the result, clear user data userSessionStore.logout(userSession: userSession) + tearDownUserSession() - stateMachine.processEvent(.completedSigningOut) + stateMachine.processEvent(.completedSigningOut(isSoft: isSoft)) } } @@ -361,11 +348,7 @@ class AppCoordinator: AppCoordinatorProtocol { guard let self else { return } switch callback { case .didReceiveAuthError(let isSoftLogout): - self.stateMachine.processEvent(.remoteSignOut(isSoft: isSoftLogout)) - case .updateRestoreTokenNeeded: - if let userSession = self.userSession { - _ = self.userSessionStore.refreshRestorationToken(for: userSession) - } + self.stateMachine.processEvent(.signOut(isSoft: isSoftLogout)) default: break } @@ -463,7 +446,7 @@ class AppCoordinator: AppCoordinatorProtocol { extension AppCoordinator: AuthenticationCoordinatorDelegate { func authenticationCoordinator(_ authenticationCoordinator: AuthenticationCoordinator, didLoginWithSession userSession: UserSessionProtocol) { self.userSession = userSession - stateMachine.processEvent(.succeededSigningIn) + stateMachine.processEvent(.createdUserSession) } } diff --git a/ElementX/Sources/Application/AppCoordinatorStateMachine.swift b/ElementX/Sources/Application/AppCoordinatorStateMachine.swift index 1f17eba03..84a5fb08f 100644 --- a/ElementX/Sources/Application/AppCoordinatorStateMachine.swift +++ b/ElementX/Sources/Application/AppCoordinatorStateMachine.swift @@ -31,32 +31,27 @@ class AppCoordinatorStateMachine { case signedIn /// Processing a sign out request - case signingOut - - /// Processing a remote sign out - case remoteSigningOut(isSoft: Bool) + case signingOut(isSoft: Bool) } /// Events that can be triggered on the AppCoordinator state machine enum Event: EventType { /// Start the `AppCoordinator` by showing authentication. case startWithAuthentication - /// Signing in succeeded - case succeededSigningIn /// Start the `AppCoordinator` by restoring an existing account. case startWithExistingSession - /// Restoring session succeeded. - case succeededRestoringSession + /// Restoring session failed. case failedRestoringSession + /// A session has been created + case createdUserSession + /// Request sign out - case signOut - /// Remote sign out. - case remoteSignOut(isSoft: Bool) + case signOut(isSoft: Bool) /// Signing out completed - case completedSigningOut + case completedSigningOut(isSoft: Bool) } private let stateMachine: StateMachine @@ -72,21 +67,18 @@ class AppCoordinatorStateMachine { private func configure() { stateMachine.addRoutes(event: .startWithAuthentication, transitions: [.initial => .signedOut]) - stateMachine.addRoutes(event: .succeededSigningIn, transitions: [.signedOut => .signedIn]) + stateMachine.addRoutes(event: .createdUserSession, transitions: [.signedOut => .signedIn]) stateMachine.addRoutes(event: .startWithExistingSession, transitions: [.initial => .restoringSession]) - stateMachine.addRoutes(event: .succeededRestoringSession, transitions: [.restoringSession => .signedIn]) + stateMachine.addRoutes(event: .createdUserSession, transitions: [.restoringSession => .signedIn]) stateMachine.addRoutes(event: .failedRestoringSession, transitions: [.restoringSession => .signedOut]) - stateMachine.addRoutes(event: .signOut, transitions: [.any => .signingOut]) - stateMachine.addRoutes(event: .completedSigningOut, transitions: [.signingOut => .signedOut]) - // Transitions with associated values need to be handled through `addRouteMapping` stateMachine.addRouteMapping { event, fromState, _ in switch (event, fromState) { - case (.remoteSignOut(let isSoft), _): - return .remoteSigningOut(isSoft: isSoft) - case (.completedSigningOut, .remoteSigningOut): + case (.signOut(let isSoft), _): + return .signingOut(isSoft: isSoft) + case (.completedSigningOut, .signingOut): return .signedOut default: return nil diff --git a/ElementX/Sources/Services/Client/ClientProxy.swift b/ElementX/Sources/Services/Client/ClientProxy.swift index bc86f5893..944844b95 100644 --- a/ElementX/Sources/Services/Client/ClientProxy.swift +++ b/ElementX/Sources/Services/Client/ClientProxy.swift @@ -35,11 +35,6 @@ private class WeakClientProxyWrapper: ClientDelegate, SlidingSyncObserver { clientProxy?.didReceiveAuthError(isSoftLogout: isSoftLogout) } - func didUpdateRestoreToken() { - MXLog.info("Did update restoration token") - clientProxy?.didUpdateRestoreToken() - } - // MARK: - SlidingSyncDelegate func didReceiveSyncUpdate(summary: UpdateSummary) { @@ -98,10 +93,6 @@ class ClientProxy: ClientProxyProtocol { } } - var isSoftLogout: Bool { - client.isSoftLogout() - } - var deviceId: String? { do { return try client.deviceId() @@ -126,7 +117,7 @@ class ClientProxy: ClientProxyProtocol { func startSync() { MXLog.info("Starting sync") - guard !client.isSoftLogout(), slidingSyncObserverToken == nil else { + guard slidingSyncObserverToken == nil else { return } @@ -382,10 +373,6 @@ class ClientProxy: ClientProxyProtocol { fileprivate func didReceiveAuthError(isSoftLogout: Bool) { callbacks.send(.receivedAuthError(isSoftLogout: isSoftLogout)) } - - fileprivate func didUpdateRestoreToken() { - callbacks.send(.updatedRestoreToken) - } fileprivate func didReceiveSlidingSyncUpdate(summary: UpdateSummary) { callbacks.send(.receivedSyncUpdate) diff --git a/ElementX/Sources/Services/Client/ClientProxyProtocol.swift b/ElementX/Sources/Services/Client/ClientProxyProtocol.swift index be34934f4..96709289d 100644 --- a/ElementX/Sources/Services/Client/ClientProxyProtocol.swift +++ b/ElementX/Sources/Services/Client/ClientProxyProtocol.swift @@ -21,7 +21,6 @@ import MatrixRustSDK enum ClientProxyCallback { case receivedSyncUpdate case receivedAuthError(isSoftLogout: Bool) - case updatedRestoreToken } enum ClientProxyError: Error { @@ -69,8 +68,6 @@ protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol { var userID: String { get } - var isSoftLogout: Bool { get } - var deviceId: String? { get } var homeserver: String { get } diff --git a/ElementX/Sources/Services/Client/MockClientProxy.swift b/ElementX/Sources/Services/Client/MockClientProxy.swift index a0af26166..dfb911ff9 100644 --- a/ElementX/Sources/Services/Client/MockClientProxy.swift +++ b/ElementX/Sources/Services/Client/MockClientProxy.swift @@ -22,7 +22,6 @@ class MockClientProxy: ClientProxyProtocol { let callbacks = PassthroughSubject() let userID: String - let isSoftLogout = false let deviceId: String? = nil let homeserver = "" let restorationToken: RestorationToken? = nil diff --git a/ElementX/Sources/Services/Session/MockUserSession.swift b/ElementX/Sources/Services/Session/MockUserSession.swift index 334f90301..61bf0b2d1 100644 --- a/ElementX/Sources/Services/Session/MockUserSession.swift +++ b/ElementX/Sources/Services/Session/MockUserSession.swift @@ -20,7 +20,6 @@ struct MockUserSession: UserSessionProtocol { let callbacks = PassthroughSubject() let sessionVerificationController: SessionVerificationControllerProxyProtocol? = nil var userID: String { clientProxy.userID } - var isSoftLogout: Bool { clientProxy.isSoftLogout } var deviceID: String? { clientProxy.deviceId } var homeserver: String { clientProxy.homeserver } let clientProxy: ClientProxyProtocol diff --git a/ElementX/Sources/Services/Session/UserSession.swift b/ElementX/Sources/Services/Session/UserSession.swift index d1209e537..32a394b46 100644 --- a/ElementX/Sources/Services/Session/UserSession.swift +++ b/ElementX/Sources/Services/Session/UserSession.swift @@ -21,10 +21,8 @@ class UserSession: UserSessionProtocol { private var cancellables = Set() private var checkForSessionVerificationControllerCancellable: AnyCancellable? private var authErrorCancellable: AnyCancellable? - private var restoreTokenUpdateCancellable: AnyCancellable? var userID: String { clientProxy.userID } - var isSoftLogout: Bool { clientProxy.isSoftLogout } var deviceID: String? { clientProxy.deviceId } var homeserver: String { clientProxy.homeserver } @@ -39,7 +37,6 @@ class UserSession: UserSessionProtocol { setupSessionVerificationWatchdog() setupAuthErrorWatchdog() - setupRestoreTokenUpdateWatchdog() } // MARK: - Private @@ -102,21 +99,4 @@ class UserSession: UserSessionProtocol { private func tearDownAuthErrorWatchdog() { authErrorCancellable = nil } - - // MARK: Restore Token Update Watchdog - - private func setupRestoreTokenUpdateWatchdog() { - restoreTokenUpdateCancellable = clientProxy.callbacks - .receive(on: DispatchQueue.main) - .sink { [weak self] callback in - if case .updatedRestoreToken = callback { - self?.callbacks.send(.updateRestoreTokenNeeded) - self?.tearDownRestoreTokenUpdateWatchdog() - } - } - } - - private func tearDownRestoreTokenUpdateWatchdog() { - restoreTokenUpdateCancellable = nil - } } diff --git a/ElementX/Sources/Services/Session/UserSessionProtocol.swift b/ElementX/Sources/Services/Session/UserSessionProtocol.swift index 009ff3953..b8da4cd65 100644 --- a/ElementX/Sources/Services/Session/UserSessionProtocol.swift +++ b/ElementX/Sources/Services/Session/UserSessionProtocol.swift @@ -21,7 +21,6 @@ enum UserSessionCallback { case sessionVerificationNeeded case didVerifySession case didReceiveAuthError(isSoftLogout: Bool) - case updateRestoreTokenNeeded } protocol UserSessionProtocol { @@ -29,8 +28,6 @@ protocol UserSessionProtocol { var userID: String { get } var deviceID: String? { get } - var isSoftLogout: Bool { get } - var clientProxy: ClientProxyProtocol { get } var mediaProvider: MediaProviderProtocol { get } diff --git a/ElementX/Sources/Services/UserSession/RestorationToken.swift b/ElementX/Sources/Services/UserSession/RestorationToken.swift index e84f6ef40..9ef34a8b9 100644 --- a/ElementX/Sources/Services/UserSession/RestorationToken.swift +++ b/ElementX/Sources/Services/UserSession/RestorationToken.swift @@ -29,7 +29,6 @@ extension MatrixRustSDK.Session: Codable { userId: try container.decode(String.self, forKey: .userId), deviceId: try container.decode(String.self, forKey: .deviceId), homeserverUrl: try container.decode(String.self, forKey: .homeserverUrl), - isSoftLogout: try container.decode(Bool.self, forKey: .isSoftLogout), slidingSyncProxy: try container.decode(String.self, forKey: .slidingSyncProxy)) } @@ -40,11 +39,10 @@ extension MatrixRustSDK.Session: Codable { try container.encode(userId, forKey: .userId) try container.encode(deviceId, forKey: .deviceId) try container.encode(homeserverUrl, forKey: .homeserverUrl) - try container.encode(isSoftLogout, forKey: .isSoftLogout) try container.encode(slidingSyncProxy, forKey: .slidingSyncProxy) } enum CodingKeys: String, CodingKey { - case accessToken, refreshToken, userId, deviceId, homeserverUrl, isSoftLogout, slidingSyncProxy + case accessToken, refreshToken, userId, deviceId, homeserverUrl, slidingSyncProxy } } diff --git a/UnitTests/Sources/KeychainControllerTests.swift b/UnitTests/Sources/KeychainControllerTests.swift index f97e2a70a..d4fac3d84 100644 --- a/UnitTests/Sources/KeychainControllerTests.swift +++ b/UnitTests/Sources/KeychainControllerTests.swift @@ -37,7 +37,6 @@ class KeychainControllerTests: XCTestCase { userId: "userId", deviceId: "deviceId", homeserverUrl: "homeserverUrl", - isSoftLogout: false, slidingSyncProxy: "https://my.sync.proxy")) keychain.setRestorationToken(restorationToken, forUsername: username) @@ -53,7 +52,6 @@ class KeychainControllerTests: XCTestCase { userId: "userId", deviceId: "deviceId", homeserverUrl: "homeserverUrl", - isSoftLogout: false, slidingSyncProxy: "https://my.sync.proxy")) keychain.setRestorationToken(restorationToken, forUsername: username) XCTAssertEqual(keychain.restorationTokens().count, 1, "The keychain should have 1 restoration token.") @@ -75,7 +73,6 @@ class KeychainControllerTests: XCTestCase { userId: "userId", deviceId: "deviceId", homeserverUrl: "homeserverUrl", - isSoftLogout: false, slidingSyncProxy: "https://my.sync.proxy")) keychain.setRestorationToken(restorationToken, forUsername: "@test\(index):example.com") } @@ -96,7 +93,6 @@ class KeychainControllerTests: XCTestCase { userId: "userId", deviceId: "deviceId", homeserverUrl: "homeserverUrl", - isSoftLogout: false, slidingSyncProxy: "https://my.sync.proxy")) keychain.setRestorationToken(restorationToken, forUsername: "@test\(index):example.com") } diff --git a/UnitTests/Sources/UserSession/UserSessionTests.swift b/UnitTests/Sources/UserSession/UserSessionTests.swift index ab6552950..a1da5e368 100644 --- a/UnitTests/Sources/UserSession/UserSessionTests.swift +++ b/UnitTests/Sources/UserSession/UserSessionTests.swift @@ -69,20 +69,4 @@ final class UserSessionTests: XCTestCase { controller.callbacks.send(.finished) waitForExpectations(timeout: 1.0) } - - func test_whenUserSessionReceivesUpdatedRestoreToken_updateRestoreTokenNeededEventReceived() throws { - let expectation = expectation(description: "UpdatedRestoreToken expectation") - userSession.callbacks.sink { callback in - switch callback { - case .updateRestoreTokenNeeded: - expectation.fulfill() - default: - break - } - } - .store(in: &cancellables) - - clientProxy.callbacks.send(.updatedRestoreToken) - waitForExpectations(timeout: 1.0) - } } diff --git a/project.yml b/project.yml index 64458e6bb..b7a5fc815 100644 --- a/project.yml +++ b/project.yml @@ -40,7 +40,7 @@ include: packages: MatrixRustSDK: url: https://github.com/matrix-org/matrix-rust-components-swift - exactVersion: 1.0.42-alpha + exactVersion: 1.0.43-alpha # path: ../matrix-rust-sdk DesignKit: path: DesignKit