From afafff825c361606675a06460435e86e6b7b7546 Mon Sep 17 00:00:00 2001 From: David Perez Date: Wed, 24 Jun 2026 16:08:14 -0500 Subject: [PATCH] Handle token refreshes when token is not present --- .../network/interceptor/AuthTokenManager.kt | 11 +++++----- .../interceptor/AuthTokenManagerTest.kt | 20 +++++++++++++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/network/src/main/kotlin/com/bitwarden/network/interceptor/AuthTokenManager.kt b/network/src/main/kotlin/com/bitwarden/network/interceptor/AuthTokenManager.kt index 64014b0f6d7..f014f949c0e 100644 --- a/network/src/main/kotlin/com/bitwarden/network/interceptor/AuthTokenManager.kt +++ b/network/src/main/kotlin/com/bitwarden/network/interceptor/AuthTokenManager.kt @@ -47,12 +47,11 @@ internal class AuthTokenManager( // If the same request keeps failing, let's just let the 401 pass through. return null } - val accessToken = requireNotNull( - response - .request - .header(name = HEADER_KEY_AUTHORIZATION) - ?.substringAfter(delimiter = HEADER_VALUE_BEARER_PREFIX), - ) + val accessToken = response + .request + .header(name = HEADER_KEY_AUTHORIZATION) + ?.substringAfter(delimiter = HEADER_VALUE_BEARER_PREFIX) + ?: return null return when (val userId = parseJwtTokenDataOrNull(accessToken)?.userId) { null -> { // We are unable to get the user ID, let's just let the 401 pass through. diff --git a/network/src/test/kotlin/com/bitwarden/network/interceptor/AuthTokenManagerTest.kt b/network/src/test/kotlin/com/bitwarden/network/interceptor/AuthTokenManagerTest.kt index 80f706f2fe3..c946236bcbe 100644 --- a/network/src/test/kotlin/com/bitwarden/network/interceptor/AuthTokenManagerTest.kt +++ b/network/src/test/kotlin/com/bitwarden/network/interceptor/AuthTokenManagerTest.kt @@ -109,6 +109,15 @@ class AuthTokenManagerTest { } } + @Test + fun `returns null when no token is available`() { + assertNull(authTokenManager.authenticate(null, RESPONSE_401_NO_TOKEN)) + + verify(exactly = 0) { + refreshTokenProvider.refreshAccessTokenSynchronously(any()) + } + } + @Test fun `returns null when refresh is failure`() { every { parseJwtTokenDataOrNull(JWT_ACCESS_TOKEN) } returns JTW_TOKEN @@ -307,6 +316,17 @@ private val JTW_TOKEN = JwtTokenDataJson( private const val JWT_ACCESS_TOKEN = "jwt" +private val RESPONSE_401_NO_TOKEN = Response.Builder() + .code(401) + .request( + request = Request.Builder() + .url("https://www.bitwarden.com") + .build(), + ) + .protocol(Protocol.HTTP_2) + .message("Unauthenticated") + .build() + private val RESPONSE_401 = Response.Builder() .code(401) .request(