Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ class FronteggAuthService(
// Reconnecting state
val isReconnecting = MutableLiveData<Boolean>()

// Maximum wait time for network recovery (3 minutes)
private val maxWaitTimeMs = 3 * 60 * 1000L
// No timeout for network recovery - wait indefinitely
private val maxWaitTimeMs = Long.MAX_VALUE


companion object {
Expand Down Expand Up @@ -278,14 +278,14 @@ class FronteggAuthService(
}

if (!networkOk) {
Log.w(TAG, "Network quality check timeout after ${maxWaitTimeMs}ms, clearing credentials")
Log.w(TAG, "Network quality check timeout, clearing credentials")
clearCredentials()
return false
}

isReconnecting.postValue(false)

val success = sendRefreshToken()
val success = sendRefreshToken(isManualCall = true)
if (success) {
val processedCount = requestQueue.processAll()
Log.d(TAG, "Processed $processedCount queued requests")
Expand Down Expand Up @@ -369,10 +369,8 @@ class FronteggAuthService(

override fun refreshTokenIfNeeded(): Boolean {
return synchronized(refreshMutex) {
// Check if auto refresh is disabled
if (disableAutoRefresh) {
return false
}
// Manual refresh token calls should always work, regardless of disableAutoRefresh
// disableAutoRefresh only blocks automatic refresh operations

// Check network quality before attempting refresh token
if (!isNetworkGoodSync()) {
Expand Down Expand Up @@ -874,8 +872,9 @@ class FronteggAuthService(
* @throws Exception if an error occurs during the process.
*/
@Throws(IllegalArgumentException::class, IOException::class)
fun sendRefreshToken(): Boolean {
if (disableAutoRefresh) {
fun sendRefreshToken(isManualCall: Boolean = false): Boolean {
// Only block automatic refresh operations, not manual calls
if (!isManualCall && disableAutoRefresh) {
return false
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,15 +211,18 @@ class FronteggAuthServiceTest {
}

@Test
fun `refreshTokenIfNeeded should return false if Exception`() {
every { apiMock.refreshToken(any()) }.throws(Exception())
// Mock network check to return true so it doesn't queue the request
fun `refreshTokenIfNeeded should work even when auto refresh is disabled`() {
every { apiMock.refreshToken(any()) }.returns(authResponse)
every { NetworkGate.isNetworkLikelyGood(any()) }.returns(true)
every { credentialManagerMock.save(any(), any()) }.returns(true)
every { apiMock.me() }.returns(mockk<User>())

// Test that refreshTokenIfNeeded works regardless of disableAutoRefresh setting
// because manual calls should always work
val result = auth.refreshTokenIfNeeded()

verify(exactly = 0) { credentialManagerMock.save(any(), any()) }
assert(result) // Should return true even if exception occurs, as it launches coroutine
// Should return true because manual calls should work even when auto refresh is disabled
assert(result)
}

@Test
Expand Down
Loading