diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/classic/ElementClassicConnection.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/classic/ElementClassicConnection.kt index 5e838094d3..e360aff376 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/classic/ElementClassicConnection.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/classic/ElementClassicConnection.kt @@ -319,8 +319,16 @@ class DefaultElementClassicConnection( if (userId == null) { ElementClassicConnectionState.ElementClassicReadyNoSession } else { - val secrets = getString(KEY_SECRETS_STR)?.takeIf { it.isNotEmpty() } - val roomKeysVersion = getString(KEY_ROOM_KEYS_VERSION_STR)?.takeIf { it.isNotEmpty() } + var secrets = getString(KEY_SECRETS_STR)?.takeIf { it.isNotEmpty() } + val roomKeysVersion = getString(KEY_ROOM_KEYS_VERSION_STR) + .also { + if (secrets != null && it == null) { + Timber.tag(loggerTag.value).w("Room keys version is null, outdated version of Element Classic, ignore secrets") + // In this case, just ignore the secrets, the SDK will not accept them anyway + secrets = null + } + } + ?.takeIf { it.isNotEmpty() } val homeserverUrl = getString(KEY_HOMESERVER_URL_STR)?.takeIf { it.isNotEmpty() } val displayName = getString(KEY_USER_DISPLAY_NAME_STR)?.takeIf { it.isNotEmpty() } val doesContainBackupKey = secrets != null && diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/classic/DefaultElementClassicConnectionTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/classic/DefaultElementClassicConnectionTest.kt index 1c76a93650..8ea1b2e3d3 100644 --- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/classic/DefaultElementClassicConnectionTest.kt +++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/classic/DefaultElementClassicConnectionTest.kt @@ -270,6 +270,82 @@ class DefaultElementClassicConnectionTest { } } + @Test + fun `when session is received with secret but without room keys version Element Classic is outdated and the secret is ignored`() = runTest { + val connection = createDefaultElementClassicConnection( + homeServerLoginCompatibilityChecker = FakeHomeServerLoginCompatibilityChecker( + checkResult = { Result.success(true) } + ), + matrixAuthenticationService = FakeMatrixAuthenticationService( + setElementClassicSessionResult = {}, + ), + ) + connection.stateFlow.test { + assertThat(awaitItem()).isEqualTo(ElementClassicConnectionState.Idle) + // Simulate receiving a session from Element Classic + connection.onSessionReceived( + Bundle().apply { + putString(DefaultElementClassicConnection.KEY_USER_ID_STR, A_USER_ID.value) + putString(DefaultElementClassicConnection.KEY_HOMESERVER_URL_STR, A_HOMESERVER_URL) + putString(DefaultElementClassicConnection.KEY_SECRETS_STR, A_SECRET) + putString(DefaultElementClassicConnection.KEY_ROOM_KEYS_VERSION_STR, null) + putString(DefaultElementClassicConnection.KEY_USER_DISPLAY_NAME_STR, A_USER_NAME) + } + ) + assertThat(awaitItem()).isEqualTo( + ElementClassicConnectionState.ElementClassicReady( + elementClassicSession = ElementClassicSession( + userId = A_USER_ID, + homeserverUrl = A_HOMESERVER_URL, + secrets = null, + roomKeysVersion = null, + doesContainBackupKey = false, + ), + displayName = A_USER_NAME, + avatar = null, + ) + ) + } + } + + @Test + fun `when session is received with secret but with empty room keys version, doesContainBackupKey is false`() = runTest { + val connection = createDefaultElementClassicConnection( + homeServerLoginCompatibilityChecker = FakeHomeServerLoginCompatibilityChecker( + checkResult = { Result.success(true) } + ), + matrixAuthenticationService = FakeMatrixAuthenticationService( + setElementClassicSessionResult = {}, + ), + ) + connection.stateFlow.test { + assertThat(awaitItem()).isEqualTo(ElementClassicConnectionState.Idle) + // Simulate receiving a session from Element Classic + connection.onSessionReceived( + Bundle().apply { + putString(DefaultElementClassicConnection.KEY_USER_ID_STR, A_USER_ID.value) + putString(DefaultElementClassicConnection.KEY_HOMESERVER_URL_STR, A_HOMESERVER_URL) + putString(DefaultElementClassicConnection.KEY_SECRETS_STR, A_SECRET) + putString(DefaultElementClassicConnection.KEY_ROOM_KEYS_VERSION_STR, "") + putString(DefaultElementClassicConnection.KEY_USER_DISPLAY_NAME_STR, A_USER_NAME) + } + ) + assertThat(awaitItem()).isEqualTo( + ElementClassicConnectionState.ElementClassicReady( + elementClassicSession = ElementClassicSession( + userId = A_USER_ID, + homeserverUrl = A_HOMESERVER_URL, + secrets = A_SECRET, + roomKeysVersion = null, + doesContainBackupKey = false, + ), + displayName = A_USER_NAME, + avatar = null, + ) + ) + } + } + @Test fun `when session is received with empty data, and homeserver is supported, ElementClassicReady is emitted`() = runTest { val connection = createDefaultElementClassicConnection(