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

only fail awaiting token confirmation for valid auth response #24

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

erquhart
Copy link

@erquhart erquhart commented Jan 22, 2025

Bug

An authenticated user is suddenly kicked to the unauthenticated view. This happens often when a native app is brought from background after token has expired, but can happen outside of this context as well.

Root cause

  1. Once token authenticate succeeds, a refetch is scheduled for just before the new token expires.
  2. The scheduled refetch runs, and auth state is set to waitingForServerConfirmationOfFreshToken.
    • Two things can change this auth state, either a Transition message showing the server has validated the token, or an AuthError.
    • The server message for a query/mutation with an old token and the message for a failed authentication atttempt both return the same message type of AuthError (source links below).
  3. In a race condition, around this time, the user initiates a query or mutation with the near-expired token.
  4. The server finds the token to be expired and returns an auth error.
  5. The query/mutation auth error reaches the client before the Transition message that would otherwise validate the new token.
  6. The client clears authentication state and the user is shown the unauthenticated view.

Despite the user having a valid session and token, the client remains unauthenticated until refresh/reopen of app.

This solution

While authentication errors have the same type as expired token responses, the messages are currently distinct.

Error when ModifyQuerySet, Mutation, or Action message encounters an expired token:
https://github.com/get-convex/convex-backend/blob/4121cc0700cf47a16f0861655f1906d810085fba/crates/sync/src/state.rs#L271

Error when an Authenticate message encounters an expired token:
https://github.com/get-convex/convex-backend/blob/4121cc0700cf47a16f0861655f1906d810085fba/crates/authentication/src/lib.rs#L121

This solution is brittle, but fixes the problem until a more permanent fix can be applied. When the auth state is set to waitingForServerConfirmationOfFreshToken, only the auth error resulting from an Authenticate request can trigger clearing of auth state in the client. This is done by ignoring query/mutation/action auth errors via message text matching (again, brittle).

Other solutions considered

An ideal solution would work similarly, but involve more distinct backend handling of these two error states, maybe through an explicit AuthError type alternative for Authenticate failures.

@erquhart erquhart force-pushed the fix-mistaken-unauth branch 2 times, most recently from a951e5e to ed035cb Compare January 23, 2025 02:20
@erquhart erquhart marked this pull request as draft January 23, 2025 02:24
@erquhart erquhart force-pushed the fix-mistaken-unauth branch 2 times, most recently from 6c10ec8 to 49f2261 Compare January 23, 2025 21:51
@erquhart erquhart force-pushed the fix-mistaken-unauth branch from 49f2261 to 893f731 Compare January 23, 2025 21:51
@erquhart erquhart marked this pull request as ready for review January 23, 2025 22:00
@erquhart erquhart marked this pull request as draft January 25, 2025 03:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant