element-hq / element-x-android

Android Matrix messenger application using the Matrix Rust Sdk and Jetpack Compose
GNU Affero General Public License v3.0
966 stars 129 forks source link

Spontaneous logout #3176

Open kongo09 opened 1 month ago

kongo09 commented 1 month ago

Steps to reproduce

  1. Reading a room timeline

Outcome

What did you expect?

Nothing

What happened instead?

Spontaneously got logged out

Your phone model

Pixel 5

Operating system version

Android 14

Application version and app store

0.4.16-nightly

Homeserver

element.io

Will you send logs?

Yes

Are you willing to provide a PR?

No

bmarty commented 1 month ago

Without any logs, it will be hard to investigate this one. Have you sent a rageshake?

kongo09 commented 1 month ago

yes, I did

jmartinesp commented 1 month ago

The latest nightly contains https://github.com/element-hq/element-x-android/pull/3208, which should either fix the issue or at least gives us as much info as possible so we can debug what's happening.

It looks like a race condition when 2 refreshes happen almost simultaneously in the SDK due to 2 or more requests failing with errors indicating you need to refresh your token and the 'save token callback' is called in the app several times as well.

If the current code fails again, the only reason I can think about unless new data is discovered, is that:

  1. Two requests fail at the same time, two refreshes of the token happen too.
  2. Between the first refresh and the 2nd one, a new request is sent and it's received by the server when the 2nd refresh has finished.
  3. When this happens, the refresh token would be considered invalid by the server, as it's from the previous refresh result, not the one just returned to the app.
  4. The server logs out the client.
jmartinesp commented 1 month ago

Something like this maybe:

sequenceDiagram
Note left of Client: 2 simultaneous requests using the initial tokens.
Client ->> Server: Request_A (with Initial_Tokens)
Server ->> Server: Process Request_A: unknown access token error A
Client ->> Server: Request_B (with Initial_Tokens)
Note right of Server: The Server received both and processes them in parallel.
Server ->> Server: Process Request_B: unknown access token error B
Server ->> Server: Generate new Refreshed_Tokens_A
Note right of Server: Refreshed_Tokens_A are now valid, Initial_Tokens are invalid.
Server -->> Client: Refreshed_Tokens_A
Server ->> Server: Generate new Refreshed_Tokens_B
Note right of Server: Refreshed_Tokens_B are now valid, Refreshed_Tokens_A are invalid.
Client ->> Server: Request C (with Refreshed_Tokens_A)
Server -->> Client: Refreshed_Tokens_B
Server ->> Server: Process Request_C: unknown refresh token error.
Note right of Server: It should be Refreshed_Tokens_B but it's Refreshed_Tokens_A, which is no longer valid.
Server -->> Client: invalid grant error, logout.