mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-02 03:06:14 +00:00
Ensure we create a fresh Client when the sessionId is know after authentication.
This commit is contained in:
+1
-10
@@ -35,7 +35,6 @@ import io.element.android.services.analytics.api.AnalyticsService
|
||||
import io.element.android.services.toolbox.api.systemclock.SystemClock
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.rustcomponents.sdk.Client
|
||||
import org.matrix.rustcomponents.sdk.ClientBuilder
|
||||
import org.matrix.rustcomponents.sdk.CrossProcessLockConfig
|
||||
import org.matrix.rustcomponents.sdk.RequestConfig
|
||||
@@ -118,14 +117,6 @@ class RustMatrixClientFactory(
|
||||
|
||||
client.restoreSession(sessionData.toSession())
|
||||
|
||||
create(client, sessionData, isMessageSearchAvailable)
|
||||
}
|
||||
|
||||
suspend fun create(
|
||||
client: Client,
|
||||
sessionData: SessionData,
|
||||
isMessageSearchAvailable: Boolean,
|
||||
): RustMatrixClient {
|
||||
val (anonymizedAccessToken, anonymizedRefreshToken) = client.session().anonymizedTokens()
|
||||
|
||||
client.setUtdDelegate(UtdTracker(analyticsService))
|
||||
@@ -136,7 +127,7 @@ class RustMatrixClientFactory(
|
||||
.withProfilesExtension()
|
||||
.finish()
|
||||
|
||||
return RustMatrixClient(
|
||||
RustMatrixClient(
|
||||
sessionPaths = sessionData.getSessionPaths(),
|
||||
innerClient = client,
|
||||
sessionStore = sessionStore,
|
||||
|
||||
+37
-54
@@ -44,6 +44,7 @@ import io.element.android.libraries.matrix.impl.keys.SecretGenerator
|
||||
import io.element.android.libraries.matrix.impl.mapper.toSessionData
|
||||
import io.element.android.libraries.matrix.impl.paths.SessionPathsFactory
|
||||
import io.element.android.libraries.sessionstorage.api.LoginType
|
||||
import io.element.android.libraries.sessionstorage.api.SessionData
|
||||
import io.element.android.libraries.sessionstorage.api.SessionStore
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.flow.first
|
||||
@@ -101,17 +102,7 @@ class RustMatrixAuthenticationService(
|
||||
runCatchingExceptions {
|
||||
val sessionData = sessionStore.getSession(sessionId.value)
|
||||
if (sessionData != null) {
|
||||
if (sessionData.isTokenValid) {
|
||||
// Use the sessionData.passphrase, which can be null for a previously created session
|
||||
if (sessionData.passphrase == null) {
|
||||
Timber.w("Restoring a session without a passphrase")
|
||||
} else {
|
||||
Timber.w("Restoring a session with a passphrase")
|
||||
}
|
||||
rustMatrixClientFactory.create(sessionData)
|
||||
} else {
|
||||
throw SessionRestorationException.InvalidToken()
|
||||
}
|
||||
restoreSession(sessionData)
|
||||
} else {
|
||||
throw SessionRestorationException.MissingSession(sessionId)
|
||||
}
|
||||
@@ -120,6 +111,19 @@ class RustMatrixAuthenticationService(
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun restoreSession(sessionData: SessionData): MatrixClient {
|
||||
if (!sessionData.isTokenValid) {
|
||||
throw SessionRestorationException.InvalidToken()
|
||||
}
|
||||
// Use the sessionData.passphrase, which can be null for a previously created session
|
||||
if (sessionData.passphrase == null) {
|
||||
Timber.w("Restoring a session without a passphrase")
|
||||
} else {
|
||||
Timber.w("Restoring a session with a passphrase")
|
||||
}
|
||||
return rustMatrixClientFactory.create(sessionData)
|
||||
}
|
||||
|
||||
private fun getDatabaseKey(): ClientSecret {
|
||||
Timber.d("New sessions will be encrypted with a raw key")
|
||||
return secretGenerator.generateKey()
|
||||
@@ -137,7 +141,7 @@ class RustMatrixAuthenticationService(
|
||||
|
||||
client.homeserverLoginDetails().map()
|
||||
}.onFailure {
|
||||
clear(destroyClient = true)
|
||||
clear()
|
||||
}.mapFailure { failure ->
|
||||
Timber.e(failure, "Failed to set homeserver to $homeserver")
|
||||
failure.mapAuthenticationException()
|
||||
@@ -165,18 +169,7 @@ class RustMatrixAuthenticationService(
|
||||
passphrase = pendingKey.formattedAsString(),
|
||||
sessionPaths = currentSessionPaths,
|
||||
)
|
||||
val matrixClient = rustMatrixClientFactory.create(client, sessionData, isMessageSearchAvailable())
|
||||
|
||||
// Apply enterprise hooks to the newly created client as soon as possible
|
||||
clientEnterpriseHook(matrixClient)
|
||||
|
||||
newMatrixClientObservers.forEach { it.invoke(matrixClient) }
|
||||
sessionStore.addSession(sessionData)
|
||||
|
||||
// Clean up the strong reference held here since it's no longer necessary
|
||||
clear(destroyClient = false)
|
||||
|
||||
SessionId(sessionData.userId)
|
||||
finalizeClientCreation(sessionData)
|
||||
}.mapFailure { failure ->
|
||||
Timber.e(failure, "Failed to login")
|
||||
failure.mapAuthenticationException()
|
||||
@@ -305,20 +298,7 @@ class RustMatrixAuthenticationService(
|
||||
passphrase = pendingKey.formattedAsString(),
|
||||
sessionPaths = currentSessionPaths,
|
||||
)
|
||||
val matrixClient = rustMatrixClientFactory.create(client, sessionData, isMessageSearchAvailable())
|
||||
|
||||
// Apply enterprise hooks to the newly created client as soon as possible
|
||||
clientEnterpriseHook(matrixClient)
|
||||
|
||||
matrixClient.waitForKnownVerificationState()
|
||||
|
||||
newMatrixClientObservers.forEach { it.invoke(matrixClient) }
|
||||
sessionStore.addSession(sessionData)
|
||||
|
||||
// Clean up the strong reference held here since it's no longer necessary
|
||||
clear(destroyClient = false)
|
||||
|
||||
SessionId(sessionData.userId)
|
||||
finalizeClientCreation(sessionData)
|
||||
}.mapFailure { failure ->
|
||||
Timber.e(failure, "Failed to login with OAuth")
|
||||
failure.mapAuthenticationException()
|
||||
@@ -374,18 +354,7 @@ class RustMatrixAuthenticationService(
|
||||
passphrase = pendingKey.formattedAsString(),
|
||||
sessionPaths = emptySessionPaths,
|
||||
)
|
||||
val matrixClient = rustMatrixClientFactory.create(client, sessionData, isMessageSearchAvailable())
|
||||
|
||||
// Apply enterprise hooks to the newly created client as soon as possible
|
||||
clientEnterpriseHook(matrixClient)
|
||||
|
||||
newMatrixClientObservers.forEach { it.invoke(matrixClient) }
|
||||
sessionStore.addSession(sessionData)
|
||||
|
||||
// Clean up the strong reference held here since it's no longer necessary
|
||||
clear(destroyClient = false)
|
||||
|
||||
SessionId(sessionData.userId)
|
||||
finalizeClientCreation(sessionData)
|
||||
}.mapFailure {
|
||||
when (it) {
|
||||
is QrCodeDecodeException -> QrErrorMapper.map(it)
|
||||
@@ -400,6 +369,22 @@ class RustMatrixAuthenticationService(
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun finalizeClientCreation(sessionData: SessionData): SessionId {
|
||||
val matrixClient = restoreSession(sessionData)
|
||||
// Apply enterprise hooks to the newly created client as soon as possible
|
||||
clientEnterpriseHook(matrixClient)
|
||||
|
||||
matrixClient.waitForKnownVerificationState()
|
||||
|
||||
newMatrixClientObservers.forEach { it.invoke(matrixClient) }
|
||||
sessionStore.addSession(sessionData)
|
||||
|
||||
// Clean up the strong reference held here since it's no longer necessary
|
||||
clear()
|
||||
|
||||
return SessionId(sessionData.userId)
|
||||
}
|
||||
|
||||
private suspend fun makeClient(
|
||||
sessionPaths: SessionPaths,
|
||||
config: suspend ClientBuilder.() -> ClientBuilder,
|
||||
@@ -449,10 +434,8 @@ class RustMatrixAuthenticationService(
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun clear(destroyClient: Boolean) {
|
||||
if (destroyClient) {
|
||||
currentClient?.close()
|
||||
}
|
||||
private fun clear() {
|
||||
currentClient?.close()
|
||||
currentClient = null
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user