Add better logs to track token update failures (#6859)

1. Make some logs use `info` log level instead of `debug`, so they appear in most user's bug reports.
2. Make the anonymized tokens even harder to reverse.
3. Detect when the tokens we should be saving match the current ones, as that's an error.
This commit is contained in:
Jorge Martin Espinosa 2026-05-26 12:19:26 +02:00 committed by GitHub
parent 6cd0491292
commit d9403a0838
3 changed files with 17 additions and 4 deletions

View file

@ -65,10 +65,22 @@ class RustClientSessionDelegate(
// This always runs on a background thread, so we *can* do blocking calls here, although we should avoid doing heavy work
override fun saveSessionInKeychain(session: Session) {
Timber.tag(loggerTag.value).i("Saving new session info for user ${session.userId} after a token refresh")
runCatchingExceptions {
val existingData = runBlocking { sessionStore.getSession(session.userId) } ?: return
if (existingData.accessToken == session.accessToken) {
Timber.tag(loggerTag.value).e("Access token is the same as the one already stored, this should not happen after a token refresh!")
return
}
if (existingData.refreshToken == session.refreshToken) {
Timber.tag(loggerTag.value).e("Refresh token is the same as the one already stored, this should not happen after a token refresh!")
return
}
val (anonymizedAccessToken, anonymizedRefreshToken) = session.anonymizedTokens()
Timber.tag(loggerTag.value).d(
Timber.tag(loggerTag.value).i(
"Saving new session data with token: access token '$anonymizedAccessToken' and refresh token '$anonymizedRefreshToken'. " +
"Was token valid: ${existingData.isTokenValid}"
)
@ -79,7 +91,7 @@ class RustClientSessionDelegate(
sessionPaths = existingData.getSessionPaths(),
)
runBlocking { sessionStore.updateData(newData) }
Timber.tag(loggerTag.value).d("Saved new session data with access token: '$anonymizedAccessToken'.")
Timber.tag(loggerTag.value).i("Saved new session data.")
}.onFailure {
Timber.tag(loggerTag.value).e(it, "Failed to save new session data.")
}

View file

@ -131,7 +131,7 @@ class RustMatrixClientFactory(
analyticsService = analyticsService,
workManagerScheduler = workManagerScheduler,
).also {
Timber.tag(it.toString()).d("Creating Client with access token '$anonymizedAccessToken' and refresh token '$anonymizedRefreshToken'")
Timber.tag("RustMatrixClient").i("Creating Client with access token '$anonymizedAccessToken' and refresh token '$anonymizedRefreshToken'")
}
}

View file

@ -16,7 +16,8 @@ private val sha256 by lazy { MessageDigest.getInstance("SHA-256") }
@OptIn(ExperimentalStdlibApi::class)
private fun anonymizeToken(token: String): String {
return sha256.digest(token.toByteArray()).toHexString()
// Only keep the first 32 chars (16 bytes) of the hashed token to avoid displaying too much information.
return sha256.digest(token.toByteArray()).toHexString().take(32)
}
fun SessionData?.anonymizedTokens(): Pair<String?, String?> {