fix: show session expired modal instead of silent redirect to login#31
fix: show session expired modal instead of silent redirect to login#31wicky-zipstack wants to merge 1 commit intomainfrom
Conversation
- Trigger showSessionExpiredModal on 401 in axios interceptor - Show modal with "Session Expired" message before redirecting - Suppress error toasts when session expired modal is showing - User must click "Login" to proceed to login page
|
| Filename | Overview |
|---|---|
| frontend/src/auth/RequireAuth.js | Refactored to show a blocking "Session Expired" modal (closable={false}, maskClosable={false}) when !isLoggedIn && showSessionExpiredModal, instead of silently redirecting. handleLoginRedirect now resets the modal flag before navigating. The Outlet is no longer co-rendered with the modal, preventing protected content from appearing to an unauthenticated user. |
| frontend/src/service/axios-service.js | Added useSessionStore.getState().setShowSessionExpiredModal(true) in the 401 interceptor path, using the correct Zustand out-of-hook pattern for an effect callback context. |
| frontend/src/service/notification-service.js | Imports useSessionStore and uses getState() inside notify to suppress all error toasts while showSessionExpiredModal is true. This broadens the original 401-only suppression to cover all concurrent error notifications while the modal is visible. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[API Request] --> B{401 Response?}
B -- Yes --> C[axios-service: setShowSessionExpiredModal true]
C --> D[axios-service: clear sessionDetails]
D --> E{RequireAuth renders}
E -- isLoggedIn=false AND showSessionExpiredModal=true --> F[Show Session Expired Modal]
F --> G[User clicks Login]
G --> H[setShowSessionExpiredModal false]
H --> I[navigate to /login]
B -- No --> J[Normal response handling]
E -- isLoggedIn=false AND no modal flag --> I
E -- isLoggedIn=true --> K[Render Outlet]
F --> L[notification-service suppresses all error toasts]
Prompt To Fix All With AI
This is a comment left during a code review.
Path: frontend/src/service/notification-service.js
Line: 54-60
Comment:
**Overly broad notification suppression**
The added `useSessionStore.getState().showSessionExpiredModal` condition now suppresses **all** error notifications while the modal is visible — not just those originating from 401 responses. If any in-flight request (e.g., a concurrent 500 or network error) fails after the session-expired modal appears, its error toast will be silently swallowed.
The original intent (per the PR description) was to avoid *duplicate* toasts for the 401 that triggered the modal, but this check goes further and mutes all error feedback.
If the goal is only to avoid the duplicate 401 toast, the original condition (`error?.response?.status === 401`) already covered that. The extra clause only matters for non-401 errors that arrive while the modal is open. Consider scoping the suppression to 401 only, or adding a comment acknowledging the broader suppression is intentional:
```suggestion
if (
error?.response?.status === 401 ||
// Suppress all error toasts while the session-expired modal is shown,
// since any concurrent request failures are likely a consequence of
// the expired session and would only add noise.
useSessionStore.getState().showSessionExpiredModal
) {
return;
}
```
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "fix: show session expired modal instead ..." | Re-trigger Greptile
| // Skip all notifications when session expired modal is showing | ||
| if ( | ||
| error?.response?.status === 401 || | ||
| useSessionStore.getState().showSessionExpiredModal | ||
| ) { | ||
| return; | ||
| } |
There was a problem hiding this comment.
Overly broad notification suppression
The added useSessionStore.getState().showSessionExpiredModal condition now suppresses all error notifications while the modal is visible — not just those originating from 401 responses. If any in-flight request (e.g., a concurrent 500 or network error) fails after the session-expired modal appears, its error toast will be silently swallowed.
The original intent (per the PR description) was to avoid duplicate toasts for the 401 that triggered the modal, but this check goes further and mutes all error feedback.
If the goal is only to avoid the duplicate 401 toast, the original condition (error?.response?.status === 401) already covered that. The extra clause only matters for non-401 errors that arrive while the modal is open. Consider scoping the suppression to 401 only, or adding a comment acknowledging the broader suppression is intentional:
| // Skip all notifications when session expired modal is showing | |
| if ( | |
| error?.response?.status === 401 || | |
| useSessionStore.getState().showSessionExpiredModal | |
| ) { | |
| return; | |
| } | |
| if ( | |
| error?.response?.status === 401 || | |
| // Suppress all error toasts while the session-expired modal is shown, | |
| // since any concurrent request failures are likely a consequence of | |
| // the expired session and would only add noise. | |
| useSessionStore.getState().showSessionExpiredModal | |
| ) { | |
| return; | |
| } |
Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/src/service/notification-service.js
Line: 54-60
Comment:
**Overly broad notification suppression**
The added `useSessionStore.getState().showSessionExpiredModal` condition now suppresses **all** error notifications while the modal is visible — not just those originating from 401 responses. If any in-flight request (e.g., a concurrent 500 or network error) fails after the session-expired modal appears, its error toast will be silently swallowed.
The original intent (per the PR description) was to avoid *duplicate* toasts for the 401 that triggered the modal, but this check goes further and mutes all error feedback.
If the goal is only to avoid the duplicate 401 toast, the original condition (`error?.response?.status === 401`) already covered that. The extra clause only matters for non-401 errors that arrive while the modal is open. Consider scoping the suppression to 401 only, or adding a comment acknowledging the broader suppression is intentional:
```suggestion
if (
error?.response?.status === 401 ||
// Suppress all error toasts while the session-expired modal is shown,
// since any concurrent request failures are likely a consequence of
// the expired session and would only add noise.
useSessionStore.getState().showSessionExpiredModal
) {
return;
}
```
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Intentional — when the session expired modal is showing, the user is about to be redirected to login. Any concurrent errors (500s from other in-flight requests) are irrelevant at that point since the session is dead. Suppressing all toasts avoids a noisy screen full of stacked error notifications.
What
Why
How
setShowSessionExpiredModal(true)on 401 response in the interceptorshowSessionExpiredModalis true to avoid duplicate notificationsCan this PR break any existing features. If yes, please list possible items. If no, please explain why. (PS: Admins do not merge the PR without this section filled)
Database Migrations
Env Config
Relevant Docs
Related Issues or PRs
Dependencies Versions
Notes on Testing
Screenshots
N/A
Checklist