mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-03 16:10:00 +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 io.element.android.services.toolbox.api.systemclock.SystemClock
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.matrix.rustcomponents.sdk.Client
|
|
||||||
import org.matrix.rustcomponents.sdk.ClientBuilder
|
import org.matrix.rustcomponents.sdk.ClientBuilder
|
||||||
import org.matrix.rustcomponents.sdk.CrossProcessLockConfig
|
import org.matrix.rustcomponents.sdk.CrossProcessLockConfig
|
||||||
import org.matrix.rustcomponents.sdk.RequestConfig
|
import org.matrix.rustcomponents.sdk.RequestConfig
|
||||||
@@ -118,14 +117,6 @@ class RustMatrixClientFactory(
|
|||||||
|
|
||||||
client.restoreSession(sessionData.toSession())
|
client.restoreSession(sessionData.toSession())
|
||||||
|
|
||||||
create(client, sessionData, isMessageSearchAvailable)
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun create(
|
|
||||||
client: Client,
|
|
||||||
sessionData: SessionData,
|
|
||||||
isMessageSearchAvailable: Boolean,
|
|
||||||
): RustMatrixClient {
|
|
||||||
val (anonymizedAccessToken, anonymizedRefreshToken) = client.session().anonymizedTokens()
|
val (anonymizedAccessToken, anonymizedRefreshToken) = client.session().anonymizedTokens()
|
||||||
|
|
||||||
client.setUtdDelegate(UtdTracker(analyticsService))
|
client.setUtdDelegate(UtdTracker(analyticsService))
|
||||||
@@ -136,7 +127,7 @@ class RustMatrixClientFactory(
|
|||||||
.withProfilesExtension()
|
.withProfilesExtension()
|
||||||
.finish()
|
.finish()
|
||||||
|
|
||||||
return RustMatrixClient(
|
RustMatrixClient(
|
||||||
sessionPaths = sessionData.getSessionPaths(),
|
sessionPaths = sessionData.getSessionPaths(),
|
||||||
innerClient = client,
|
innerClient = client,
|
||||||
sessionStore = sessionStore,
|
sessionStore = sessionStore,
|
||||||
|
|||||||
+36
-53
@@ -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.mapper.toSessionData
|
||||||
import io.element.android.libraries.matrix.impl.paths.SessionPathsFactory
|
import io.element.android.libraries.matrix.impl.paths.SessionPathsFactory
|
||||||
import io.element.android.libraries.sessionstorage.api.LoginType
|
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 io.element.android.libraries.sessionstorage.api.SessionStore
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
@@ -101,17 +102,7 @@ class RustMatrixAuthenticationService(
|
|||||||
runCatchingExceptions {
|
runCatchingExceptions {
|
||||||
val sessionData = sessionStore.getSession(sessionId.value)
|
val sessionData = sessionStore.getSession(sessionId.value)
|
||||||
if (sessionData != null) {
|
if (sessionData != null) {
|
||||||
if (sessionData.isTokenValid) {
|
restoreSession(sessionData)
|
||||||
// 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()
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
throw SessionRestorationException.MissingSession(sessionId)
|
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 {
|
private fun getDatabaseKey(): ClientSecret {
|
||||||
Timber.d("New sessions will be encrypted with a raw key")
|
Timber.d("New sessions will be encrypted with a raw key")
|
||||||
return secretGenerator.generateKey()
|
return secretGenerator.generateKey()
|
||||||
@@ -137,7 +141,7 @@ class RustMatrixAuthenticationService(
|
|||||||
|
|
||||||
client.homeserverLoginDetails().map()
|
client.homeserverLoginDetails().map()
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
clear(destroyClient = true)
|
clear()
|
||||||
}.mapFailure { failure ->
|
}.mapFailure { failure ->
|
||||||
Timber.e(failure, "Failed to set homeserver to $homeserver")
|
Timber.e(failure, "Failed to set homeserver to $homeserver")
|
||||||
failure.mapAuthenticationException()
|
failure.mapAuthenticationException()
|
||||||
@@ -165,18 +169,7 @@ class RustMatrixAuthenticationService(
|
|||||||
passphrase = pendingKey.formattedAsString(),
|
passphrase = pendingKey.formattedAsString(),
|
||||||
sessionPaths = currentSessionPaths,
|
sessionPaths = currentSessionPaths,
|
||||||
)
|
)
|
||||||
val matrixClient = rustMatrixClientFactory.create(client, sessionData, isMessageSearchAvailable())
|
finalizeClientCreation(sessionData)
|
||||||
|
|
||||||
// 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)
|
|
||||||
}.mapFailure { failure ->
|
}.mapFailure { failure ->
|
||||||
Timber.e(failure, "Failed to login")
|
Timber.e(failure, "Failed to login")
|
||||||
failure.mapAuthenticationException()
|
failure.mapAuthenticationException()
|
||||||
@@ -305,20 +298,7 @@ class RustMatrixAuthenticationService(
|
|||||||
passphrase = pendingKey.formattedAsString(),
|
passphrase = pendingKey.formattedAsString(),
|
||||||
sessionPaths = currentSessionPaths,
|
sessionPaths = currentSessionPaths,
|
||||||
)
|
)
|
||||||
val matrixClient = rustMatrixClientFactory.create(client, sessionData, isMessageSearchAvailable())
|
finalizeClientCreation(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(destroyClient = false)
|
|
||||||
|
|
||||||
SessionId(sessionData.userId)
|
|
||||||
}.mapFailure { failure ->
|
}.mapFailure { failure ->
|
||||||
Timber.e(failure, "Failed to login with OAuth")
|
Timber.e(failure, "Failed to login with OAuth")
|
||||||
failure.mapAuthenticationException()
|
failure.mapAuthenticationException()
|
||||||
@@ -374,18 +354,7 @@ class RustMatrixAuthenticationService(
|
|||||||
passphrase = pendingKey.formattedAsString(),
|
passphrase = pendingKey.formattedAsString(),
|
||||||
sessionPaths = emptySessionPaths,
|
sessionPaths = emptySessionPaths,
|
||||||
)
|
)
|
||||||
val matrixClient = rustMatrixClientFactory.create(client, sessionData, isMessageSearchAvailable())
|
finalizeClientCreation(sessionData)
|
||||||
|
|
||||||
// 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)
|
|
||||||
}.mapFailure {
|
}.mapFailure {
|
||||||
when (it) {
|
when (it) {
|
||||||
is QrCodeDecodeException -> QrErrorMapper.map(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(
|
private suspend fun makeClient(
|
||||||
sessionPaths: SessionPaths,
|
sessionPaths: SessionPaths,
|
||||||
config: suspend ClientBuilder.() -> ClientBuilder,
|
config: suspend ClientBuilder.() -> ClientBuilder,
|
||||||
@@ -449,10 +434,8 @@ class RustMatrixAuthenticationService(
|
|||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun clear(destroyClient: Boolean) {
|
private fun clear() {
|
||||||
if (destroyClient) {
|
|
||||||
currentClient?.close()
|
currentClient?.close()
|
||||||
}
|
|
||||||
currentClient = null
|
currentClient = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user