diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c83ab600ab..cbb6f4ee20 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -186,7 +186,7 @@ test_detekt_test = { module = "io.gitlab.arturbosch.detekt:detekt-test", version # it as a plain `require`: without this, a library built against a newer SDK would silently drag this app # onto it. With it, this pin always wins, and a library that needs something newer fails at configuration # time naming both versions instead of at runtime with NoSuchMethodError. -matrix_sdk = { module = "org.matrix.rustcomponents:sdk-android", version = { strictly = "26.10.07-nightly" } } +matrix_sdk = { module = "org.matrix.rustcomponents:sdk-android", version = { strictly = "26.10.12-nightly" } } rustls_platform_verifier = "org.rustls:rustls-platform-verifier:0.2.0" # Others diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt index 71342d1b51..51579a88d4 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt @@ -410,7 +410,7 @@ interface MatrixClient : ClientUrlContentFetcher { /** * Deactivates the account on the homeserver, then destroys this client and deletes every local trace of the session. - * The password is only sent if the homeserver asks for re-authentication, and on failure the session is left untouched. + * On failure the session is left untouched. * * @param password the account password, required to confirm the deactivation. * @param eraseData whether the homeserver should also erase the messages the user sent. diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/encryption/EncryptionService.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/encryption/EncryptionService.kt index e036a198df..40f6ef20a2 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/encryption/EncryptionService.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/encryption/EncryptionService.kt @@ -123,6 +123,11 @@ interface EncryptionService { * A handle to reset the user's identity. */ sealed interface IdentityResetHandle { + /** + * The value of the session key given by the homeserver. + */ + val session: String + /** * Cancel the reset process and drops the existing handle in the SDK. */ diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index dcf75b78bc..94be2d3764 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -127,8 +127,6 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import kotlinx.coroutines.withTimeout -import org.matrix.rustcomponents.sdk.AuthData -import org.matrix.rustcomponents.sdk.AuthDataPasswordDetails import org.matrix.rustcomponents.sdk.BeaconInfoListener import org.matrix.rustcomponents.sdk.BeaconInfoUpdate import org.matrix.rustcomponents.sdk.Client @@ -794,33 +792,10 @@ class RustMatrixClient( clientDelegateTaskHandle?.cancelAndDestroy() clientDelegateTaskHandle = null runCatchingExceptions { - // First call without AuthData, should fail - val firstAttempt = runCatchingExceptions { - innerClient.deactivateAccount( - authData = null, - eraseData = eraseData, - ) - } - if (firstAttempt.isFailure) { - Timber.w(firstAttempt.exceptionOrNull(), "Expected failure, try again") - // This is expected, try again with the password - runCatchingExceptions { - innerClient.deactivateAccount( - authData = AuthData.Password( - passwordDetails = AuthDataPasswordDetails( - identifier = sessionId.value, - password = password, - ), - ), - eraseData = eraseData, - ) - }.onFailure { - Timber.e(it, "Failed to deactivate account") - // If the deactivation failed we need to restore the delegate - clientDelegateTaskHandle = innerClient.setDelegate(sessionDelegate) - throw it - } - } + innerClient.deactivateAccount( + password = password, + eraseData = eraseData, + ) destroy() deleteSessionDirectory() sessionStore.removeSession(sessionId.value) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustIdentityResetHandle.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustIdentityResetHandle.kt index 7ee9c7d0b3..6bbc8887d4 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustIdentityResetHandle.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustIdentityResetHandle.kt @@ -20,14 +20,14 @@ import org.matrix.rustcomponents.sdk.CrossSigningResetAuthType object RustIdentityResetHandleFactory { fun create( userId: UserId, - identityResetHandle: org.matrix.rustcomponents.sdk.IdentityResetHandle? + identityResetHandle: org.matrix.rustcomponents.sdk.IdentityResetHandle?, ): Result { return runCatchingExceptions { identityResetHandle?.let { when (val authType = identityResetHandle.authType()) { - is CrossSigningResetAuthType.OAuth -> RustIdentityOAuthResetHandle(identityResetHandle, authType.info.approvalUrl) + is CrossSigningResetAuthType.OAuth -> RustIdentityOAuthResetHandle(identityResetHandle, authType.info.approvalUrl, authType.info.session) // User interactive authentication (user + password) - CrossSigningResetAuthType.Uiaa -> RustPasswordIdentityResetHandle(userId, identityResetHandle) + is CrossSigningResetAuthType.Uiaa -> RustPasswordIdentityResetHandle(userId, identityResetHandle, authType.info.session) } } } @@ -37,9 +37,12 @@ object RustIdentityResetHandleFactory { class RustPasswordIdentityResetHandle( private val userId: UserId, private val identityResetHandle: org.matrix.rustcomponents.sdk.IdentityResetHandle, + override val session: String, ) : IdentityPasswordResetHandle { override suspend fun resetPassword(password: String): Result { - return runCatchingExceptions { identityResetHandle.reset(AuthData.Password(AuthDataPasswordDetails(userId.value, password))) } + return runCatchingExceptions { + identityResetHandle.reset(AuthData.Password(AuthDataPasswordDetails(userId.value, password, session))) + } } override suspend fun cancel() { @@ -50,9 +53,10 @@ class RustPasswordIdentityResetHandle( class RustIdentityOAuthResetHandle( private val identityResetHandle: org.matrix.rustcomponents.sdk.IdentityResetHandle, override val url: String, + override val session: String, ) : IdentityOAuthResetHandle { override suspend fun resetOAuth(): Result { - return runCatchingExceptions { identityResetHandle.reset(null) } + return runCatchingExceptions { identityResetHandle.reset(AuthData.OAuth(session)) } } override suspend fun cancel() { diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/encryption/FakeIdentityResetHandle.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/encryption/FakeIdentityResetHandle.kt index d65328d7fe..4248bc62d4 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/encryption/FakeIdentityResetHandle.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/encryption/FakeIdentityResetHandle.kt @@ -13,6 +13,7 @@ import io.element.android.libraries.matrix.api.encryption.IdentityPasswordResetH class FakeIdentityOAuthResetHandle( override val url: String = "", + override val session: String = "", var resetOAuthLambda: () -> Result = { error("Not implemented") }, var cancelLambda: () -> Unit = { error("Not implemented") }, ) : IdentityOAuthResetHandle { @@ -26,6 +27,7 @@ class FakeIdentityOAuthResetHandle( } class FakeIdentityPasswordResetHandle( + override val session: String = "", var resetPasswordLambda: (String) -> Result = { _ -> error("Not implemented") }, var cancelLambda: () -> Unit = { error("Not implemented") }, ) : IdentityPasswordResetHandle {