Open sdomi opened 6 months ago
@sdomi We were unable to reproduce this internally. Is there any other information that you can help share (e.g. app/server logs or other info)?
@amyblais thanks for the quick response! for now I've only gathered some data from adb logcat
(as seen below), but I will attempt to dump you a (redacted) HAR of the requests later tonight.
04-26 15:23:40.849 29378 29378 W Glide : Load failed for https://mm.sakamoto.pl/api/v4/files/1kg38i1fi7n1df3qzj1m6osjje/preview with size [1213x1093]
04-26 15:23:40.849 29378 29378 W Glide : class com.bumptech.glide.load.engine.GlideException: Failed to load resource
04-26 15:23:40.849 29378 29378 W Glide : There was 1 root cause:
04-26 15:23:40.849 29378 29378 W Glide : com.bumptech.glide.load.HttpException(Unauthorized, status code: 401)
04-26 15:23:40.849 29378 29378 W Glide : call GlideException#logRootCauses(String) for more detail
04-26 15:23:40.849 29378 29378 W Glide : Cause (1 of 1): class com.bumptech.glide.load.engine.GlideException: Fetching data failed, class java.io.InputStream, REMOTE
04-26 15:23:40.849 29378 29378 W Glide : There was 1 root cause:
04-26 15:23:40.849 29378 29378 W Glide : com.bumptech.glide.load.HttpException(Unauthorized, status code: 401)
04-26 15:23:40.849 29378 29378 W Glide : call GlideException#logRootCauses(String) for more detail
04-26 15:23:40.849 29378 29378 W Glide : Cause (1 of 1): class com.bumptech.glide.load.HttpException: Unauthorized, status code: 401
04-26 15:23:40.849 29378 29378 I Glide : Root cause (1 of 1)
04-26 15:23:40.849 29378 29378 I Glide : com.bumptech.glide.load.HttpException: Unauthorized, status code: 401
04-26 15:23:40.849 29378 29378 I Glide : at com.bumptech.glide.integration.okhttp3.OkHttpStreamFetcher.onResponse(OkHttpStreamFetcher.java:71)
04-26 15:23:40.849 29378 29378 I Glide : at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)
04-26 15:23:40.849 29378 29378 I Glide : at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
04-26 15:23:40.849 29378 29378 I Glide : at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
04-26 15:23:40.849 29378 29378 I Glide : at java.lang.Thread.run(Thread.java:1012)
@larkox QA was unable to reproduce this, but I'm adding you here in case you're familiar with these errors.
@sdomi There might be some clues in the server logs. Can you enable the debug server logs and see what happens with those requests?
It may be also useful checking the app logs (Profile -> Settings -> Report a problem). There may be other errors, but let me know if you see any there about the loading of images.
@sdomi Also, what device are you on? We've tested this on Samsung S22 (Android 14) and Pixel 5a.
I'm on Pixel 7 Pro, latest GrapheneOS. this shouldn't affect the app tho.
I will provide more debug info later today - sorry for the belated response, lots of things happening the past few days.
okay, managed to look through it:
MMAUTHTOKEN
cookie to be set for the file/image/emoji endpoints/data/data/com.mattermost.rnbeta/app_webview/Default/Cookies
/signup/gitlab/complete?state=...
, from which I'm being redirected back into the app through deep-linking (mmauthbeta://callback?MMAUTHTOKEN=...&MMCSRF=...
)Cookie
header doesn't get sentThe codepath I found is roughtly:
My working theory is that a redirect to the browser wasn't intended, and instead it all should take place inside of the app? Either that, or something later was meant to save those cookies into the cookiejar and didn't.
I've got HARs dumped, but after comparing them request by request, they're exactly the same outside of the middle part of the auth flow. Redacting them would be kind of a pain to do, so I decided not to bother (sorry!).
"good" flow through the app: server returns Set-Cookie
headers which get appended to the cookie jar; (request first, then response):
broken flow with GitLab: this request is still in the browser; the next one from the app goes to /api/v4/users/me
, and it already has Authorization: BEARER ...
set. Thus, no cookies.
@sdomi Were you able to check also the server logs? Our server code should be able to handle the token coming from different places (not only from the cookie) so that may not be the problem. I want to make sure what is the error the server is really reporting.
Maybe the body of the unauthorized response has also the real reason, but the one in the server logs should be more clear.
@larkox the server response is as follows:
{
"detailed_error": "",
"id": "api.context.session_expired.app_error",
"message": "Invalid or expired session, please login again.",
"request_id": "1ani8qrkgpbfddbmqkjupqfx8e",
"status_code": 401
}
this is, again, caused by neither the BEARER token nor the cookie being attached to the request.
(slightly redacted) server logs attached below logs.txt
@sdomi looking a bit more into the code, I see that some logs get sanitized when the instance is not in developer mode, in particular the "detail_error" field you see there. Not sure if it is an option to enable developer mode in your instance to get the logs.
I could understand it is not possible, so let me know either way.
@larkox i can set up a separate developer instance for repro purposes later. Don't want to mess around with this one too much as it's mission-critical for me and my friends :)
will get back to you on that sometime soon
@sdomi Thank you so much for helping into troubleshooting this bug!
I'm on Pixel 7 Pro, latest GrapheneOS. this shouldn't affect the app tho.
I will provide more debug info later today - sorry for the belated response, lots of things happening the past few days.
I encountered the same issue. The problem is that if getDeviceToken fails, there is no request to /api/v4/users/sessions/device
, which triggers the Set-Cookie operation for the device. GrapheneOS and other devices without google service will fail to execute getDeviceToken.
This bro figured out the problem: https://github.com/mattermost/mattermost-mobile/issues/4486#issuecomment-1729067894
Summary
If the user logs in through SSO (GitLab), certain requests are not authenticated properly against the API. . This is only true for requests for files or images - sending and receiving messages works.
This only happens on Android + External Login. If user logs in on Android through the internal login, images load just fine.
Environment Information
Steps to reproduce
Expected behavior
The timeline shows up fully.
Observed behavior (that appears unintentional)
Messages can be seen, but no images load. If requests are intercepted, they lack the Authorization header.
Possible fixes
n/a