fix(auth): surface 401 session expiry to frontend with user notification#489
fix(auth): surface 401 session expiry to frontend with user notification#489ayushshukla1807 wants to merge 4 commits intohatnote:masterfrom
Conversation
…re failures to surface Axios network catches (hatnote#116)
7accc5b to
6c28b7a
Compare
There was a problem hiding this comment.
Have you tested the application flow manually?
Previously, when cookies were invalid or unknown, the middleware returned an empty dictionary, which Clastic/MessageMiddleware interpreted as a silent 200 OK response. With your changes, those same scenarios now return {'_status_code': 401}, causing Axios to treat the response as a failure and the frontend to surface a 401 error.
more changes will be required, please check this whole flow manually.
| else: | ||
| if ep_is_public: | ||
| return next(user=None, user_dao=None) | ||
| # @ayushshukla1807: we must explicitly return 401 here so MessageMiddleware |
There was a problem hiding this comment.
Sorry, but this comment doesn’t seem relevant to the actual fix.
There was a problem hiding this comment.
Thanks for pointing that out, Aditya.
I've cleaned up the code by removing the redundant comments.
I also followed up on your suggestion to check the whole flow: I've updated all authentication failure paths in the middleware to return 401 (including missing cookies and unknown IDs) and added a global interceptor in the frontend to handle these cases gracefully.
This ensures that if a session drops mid-view, the app will now redirect back to home for a re-auth check instead of hanging or showing empty templates.
I've verified this behavior by simulating cookie drops locally.
- Replaced empty dict returns with explicit 401 status codes in UserMiddleware. - Removed redundant self-referential comments. - Added global Axios interceptor to catch 401s and redirect to Home, handling session drops gracefully. - Addresses feedback on hatnote#489 and hardening requirements for hatnote#116.
|
Thanks for working on this. There's a related closed PR — #472 by @userAdityaa — that covered the same ground. It's worth reading both for how it surfaces the error message to the user and for
|
- Added AlertService notification to Axios interceptor to prevent silent 401 redirects. - Refactored superuser impersonation failure to 400 (Bad Request) instead of 401 to avoid session expiry conflation. - Addresses maintainer feedback on hatnote#489 and hatnote#116.
Per @lgelauff's review: 1. Split interceptors: the 401 session-expiry handler is now in a separate addAuthInterceptor() applied ONLY to apiBackend. Previously, addInterceptors() added 401 handling to both apiBackend and apiCommons — but Commons API 401s are not Montage session failures and should not trigger a session redirect. This is now separated cleanly. 2. Show backend error text before redirect: rather than a generic 'Session expired' message, the interceptor now reads error.response.data.errors[0] — the text the backend already appends — so users see the actual reason (e.g. 'invalid cookie userid, try logging in again') before any redirect. This preserves context and prevents silent work loss. 3. su_to branch already returns 400 (not 401) — correctly distinguishes superuser impersonation misconfiguration from session expiry. No change needed here.
|
Thanks for the detailed review, @lgelauff — and for pointing to #472. I have addressed all three points: 1. Interceptor scope — Split into 2. Silent redirect — The interceptor now reads 3. Updated in the latest commit on this branch. |
Fixes the session dropping issue mentioned in #116.
If a user's session expired during a vote loop, the
UserMiddlewaredropped the cookie and returned an empty dict. The backend just forwarded a HTTP 200 with an error string attached, which meant the frontend.catch()block never triggered. The UI would move on like normal while the vote was lost.I've updated the middleware to throw an explicit 401 when the cookie is invalid, so the frontend correctly halts and prompts a re-login.