Adopt correct UIAA and session token passing usage as per spec.

This commit is contained in:
Stefan Ceriu
2026-10-12 22:27:32 +03:00
parent 8f54e6159d
commit 011087baf5
6 changed files with 16 additions and 34 deletions
@@ -16,7 +16,7 @@ nonisolated extension IdentityResetHandleSDKMock {
convenience init(_ configuration: Configuration) { convenience init(_ configuration: Configuration) {
self.init() self.init()
authTypeReturnValue = .uiaa authTypeReturnValue = .uiaa(info: .init(session: "session_token"))
resetAuthClosure = { _ in resetAuthClosure = { _ in
try await Task.sleep(for: .seconds(60)) try await Task.sleep(for: .seconds(60))
} }
@@ -75,12 +75,12 @@ class EncryptionResetScreenViewModel: EncryptionResetScreenViewModelType, Encryp
identityResetHandle = handle identityResetHandle = handle
switch handle.authType() { switch handle.authType() {
case .uiaa: case .uiaa(let info):
let passwordPublisher = PassthroughSubject<String, Never>() let passwordPublisher = PassthroughSubject<String, Never>()
passwordCancellable = passwordPublisher.sink { [weak self] password in passwordCancellable = passwordPublisher.sink { [weak self] password in
guard let self else { return } guard let self else { return }
passwordCancellable = nil passwordCancellable = nil
Task { await self.resetWith(password: password) } Task { await self.resetWith(password: password, session: info.session) }
} }
actionsSubject.send(.requestPassword(passwordPublisher: passwordPublisher)) actionsSubject.send(.requestPassword(passwordPublisher: passwordPublisher))
@@ -93,7 +93,7 @@ class EncryptionResetScreenViewModel: EncryptionResetScreenViewModelType, Encryp
actionsSubject.send(.requestOAuthAuthorisation(url: url)) actionsSubject.send(.requestOAuthAuthorisation(url: url))
await resetWithOAuthAuthorisation() await resetWithOAuthAuthorisation(session: oAuthInfo.session)
} }
case .failure(let error): case .failure(let error):
MXLog.error("Failed resetting encryption with error \(error)") MXLog.error("Failed resetting encryption with error \(error)")
@@ -101,7 +101,7 @@ class EncryptionResetScreenViewModel: EncryptionResetScreenViewModelType, Encryp
} }
} }
func resetWith(password: String) async { func resetWith(password: String, session: String) async {
guard let identityResetHandle else { guard let identityResetHandle else {
fatalError("Requested reset flow continuation without a stored handle") fatalError("Requested reset flow continuation without a stored handle")
} }
@@ -113,7 +113,7 @@ class EncryptionResetScreenViewModel: EncryptionResetScreenViewModelType, Encryp
} }
do { do {
try await identityResetHandle.reset(auth: .password(passwordDetails: .init(identifier: clientProxy.userID, password: password))) try await identityResetHandle.reset(auth: .password(passwordDetails: .init(identifier: clientProxy.userID, password: password, session: session)))
actionsSubject.send(.resetFinished) actionsSubject.send(.resetFinished)
} catch { } catch {
MXLog.error("Failed resetting encryption with error \(error)") MXLog.error("Failed resetting encryption with error \(error)")
@@ -121,13 +121,13 @@ class EncryptionResetScreenViewModel: EncryptionResetScreenViewModelType, Encryp
} }
} }
private func resetWithOAuthAuthorisation() async { private func resetWithOAuthAuthorisation(session: String) async {
guard let identityResetHandle else { guard let identityResetHandle else {
fatalError("Requested reset flow continuation without a stored handle") fatalError("Requested reset flow continuation without a stored handle")
} }
do { do {
try await identityResetHandle.reset(auth: nil) try await identityResetHandle.reset(auth: .oAuth(session: session))
actionsSubject.send(.resetFinished) actionsSubject.send(.resetFinished)
} catch { } catch {
MXLog.error("Failed resetting encryption with error \(error)") MXLog.error("Failed resetting encryption with error \(error)")
@@ -58,15 +58,6 @@ class DeactivateAccountScreenViewModel: DeactivateAccountScreenViewModelType, De
MXLog.warning("Deactivating account.") MXLog.warning("Deactivating account.")
switch await clientProxy.deactivateAccount(password: nil, eraseData: state.bindings.eraseData) {
case .success:
MXLog.info("Account deactivated (no password needed).")
actionsSubject.send(.accountDeactivated)
return
case .failure:
MXLog.info("Request failed, including password.")
}
switch await clientProxy.deactivateAccount(password: state.bindings.password, eraseData: state.bindings.eraseData) { switch await clientProxy.deactivateAccount(password: state.bindings.password, eraseData: state.bindings.eraseData) {
case .success: case .success:
MXLog.info("Account deactivated.") MXLog.info("Account deactivated.")
@@ -822,10 +822,9 @@ class ClientProxy: ClientProxyProtocol {
LinkNewDeviceService(handler: client.newGrantLoginWithQrCodeHandler()) LinkNewDeviceService(handler: client.newGrantLoginWithQrCodeHandler())
} }
func deactivateAccount(password: String?, eraseData: Bool) async -> Result<Void, ClientProxyError> { func deactivateAccount(password: String, eraseData: Bool) async -> Result<Void, ClientProxyError> {
do { do {
try await client.deactivateAccount(authData: password.map { .password(passwordDetails: .init(identifier: userID, password: $0)) }, try await client.deactivateAccount(password: password, eraseData: eraseData)
eraseData: eraseData)
return .success(()) return .success(())
} catch { } catch {
return .failure(.sdkError(error)) return .failure(.sdkError(error))
@@ -247,7 +247,7 @@ protocol ClientProxyProtocol: AnyObject {
func linkNewDeviceService() -> LinkNewDeviceServiceProtocol func linkNewDeviceService() -> LinkNewDeviceServiceProtocol
func deactivateAccount(password: String?, eraseData: Bool) async -> Result<Void, ClientProxyError> func deactivateAccount(password: String, eraseData: Bool) async -> Result<Void, ClientProxyError>
func logout() async func logout() async
@@ -37,18 +37,10 @@ struct DeactivateAccountScreenViewModelTests {
mutating func validateDeactivate(erasingData shouldErase: Bool) async throws { mutating func validateDeactivate(erasingData shouldErase: Bool) async throws {
let enteredPassword = UUID().uuidString let enteredPassword = UUID().uuidString
clientProxy.deactivateAccountPasswordEraseDataClosure = { [weak clientProxy] password, eraseData in clientProxy.deactivateAccountPasswordEraseDataClosure = { password, eraseData in
guard let clientProxy else { return .failure(.sdkError(ClientProxyMockError.generic)) } #expect(password == enteredPassword, "The password should match the user's input.")
#expect(eraseData == shouldErase, "The erase parameter is unexpected.")
if clientProxy.deactivateAccountPasswordEraseDataCallsCount == 1 { return .success(())
#expect(password == nil, "The password shouldn't be sent first time round.")
#expect(eraseData == shouldErase, "The erase parameter is unexpected.")
return .failure(.sdkError(ClientProxyMockError.generic))
} else {
#expect(password == enteredPassword, "The password should match the user's input on the second call.")
#expect(eraseData == shouldErase, "The erase parameter is unexpected.")
return .success(())
}
} }
context.eraseData = shouldErase context.eraseData = shouldErase
@@ -67,7 +59,7 @@ struct DeactivateAccountScreenViewModelTests {
confirmationAction() confirmationAction()
try await deferredAction.fulfill() try await deferredAction.fulfill()
#expect(clientProxy.deactivateAccountPasswordEraseDataCallsCount == 2) #expect(clientProxy.deactivateAccountPasswordEraseDataCallsCount == 1)
#expect(clientProxy.deactivateAccountPasswordEraseDataReceivedArguments?.password == enteredPassword) #expect(clientProxy.deactivateAccountPasswordEraseDataReceivedArguments?.password == enteredPassword)
#expect(clientProxy.deactivateAccountPasswordEraseDataReceivedArguments?.eraseData == shouldErase) #expect(clientProxy.deactivateAccountPasswordEraseDataReceivedArguments?.eraseData == shouldErase)
} }