Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: UserSession is deleted when backend is unavailable (503) #724

Closed
3 tasks done
jacobian2020 opened this issue Sep 16, 2024 · 2 comments · Fixed by #725
Closed
3 tasks done

[Bug]: UserSession is deleted when backend is unavailable (503) #724

jacobian2020 opened this issue Sep 16, 2024 · 2 comments · Fixed by #725
Labels
bug Something isn't working

Comments

@jacobian2020
Copy link

General Info

  • I checked for similar bug report
  • I am using the latest version
  • I checked the troubleshooting page for similar problems

Version(s)

2.6.1

Kotlin Target(s) and their respective versions

JVM 17 Android 14

What happened? (include your code)

When backend is unavailable (503), UserSession is deleted.

Offending line is at

Our corporate reverse proxy returned 503 due to supabase backend being unavailable and it logged out all our users due to a background job that retried to upload images when users were not even using the app.

Suggestions: Please don't clear the session for all http error codes. Only clear it when refresh returns 401 due to the token being incorrect. If your backend does not support this, make it configurable for now to ignore at least 503s as this will be returned by most webservers if server is having issues/under load etc. At it's current state this is unusable in production for us.

Steps To Reproduce (optional)

class Test {


    @get:Rule
    val wireMockRule = WireMockRule(wireMockConfig().port(0))


    @Test
    fun does_not_delete_session_on_error() {

        stubFor(any(urlPathMatching(".*"))
            .willReturn(aResponse()
                .withStatus(503)
                .withBody("Service Unavailable")));

        val mockSessionManager: SessionManager = mockk()
        val userSession: UserSession = mockk()
        every { userSession.accessToken } returns "xxx"
        every { userSession.refreshToken } returns "xxx"
        every { userSession.expiresAt } returns Instant.DISTANT_PAST
        coEvery { mockSessionManager.loadSession() } returns userSession
        coEvery { mockSessionManager.deleteSession() } just runs

        val client = createSupabaseClient(
            supabaseUrl = wireMockRule.baseUrl(),
            supabaseKey = "xxxx",
        ) {
            useHTTPS = false
            install(Auth) {
                sessionManager = mockSessionManager
            }
        }

        runBlocking { client.auth.awaitInitialization() }

        coVerify(inverse = true) { mockSessionManager.deleteSession() }
    }

}

Relevant log output (optional)

Info: (Supabase-Auth) Successfully loaded session from storage!
Error: (Supabase-Auth) Couldn't refresh session. The refresh token may have been revoked.
io.github.jan.supabase.gotrue.exception.AuthRestException: 
	at io.github.jan.supabase.gotrue.AuthImpl.checkErrorCodes(AuthImpl.kt:523)
	at io.github.jan.supabase.gotrue.AuthImpl.parseErrorResponse(AuthImpl.kt:491)
	at io.github.jan.supabase.gotrue.AuthenticatedSupabaseApiKt$authenticatedSupabaseApi$3.invoke(AuthenticatedSupabaseApi.kt:60)
	at io.github.jan.supabase.gotrue.AuthenticatedSupabaseApiKt$authenticatedSupabaseApi$3.invoke(AuthenticatedSupabaseApi.kt:60)
	at io.github.jan.supabase.network.SupabaseApi.rawRequest$suspendImpl(SupabaseApi.kt:25)
	at io.github.jan.supabase.network.SupabaseApi$rawRequest$1.invokeSuspend(SupabaseApi.kt)
@jacobian2020 jacobian2020 added the bug Something isn't working label Sep 16, 2024
@jan-tennert
Copy link
Collaborator

Thanks for the issue, will publish a fix later!

@jan-tennert
Copy link
Collaborator

jan-tennert commented Sep 16, 2024

make it configurable for now to ignore at least 503s as this will be returned by most webservers if server is having issues/under load etc

Just to make sure, if the refresh fails with such a status code, what exactly should happen? Should the exception just be silently ignored (which causes auto refresh to stop essentially until restart), or should the client retry refreshing after AuthConfig#retryDelay?
I'd assume the latter, prepared a PR #725

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants