andrewmusselman opened a new issue, #28:
URL: https://github.com/apache/tooling-gofannon/issues/28

   ### Summary
   When a user's login session expires (24h default TTL), the next action fails 
with a generic UI error and no indication the *reason* is "you're no longer 
logged in." User has to figure out from context that they need to log in again, 
navigate to the login page manually, re-authenticate, and re-do the action.
    
   ### Details
   **Symptom:**
   - User clicks Save / Deploy / Update on something.
   - UI shows "Failed to save the agent" or similar.
   - No "session expired" indication, no re-login prompt.
   - After ISSUE-001 is fixed (it currently returns 500 instead of 401), the 
api log will show a 401, but the frontend won't surface it differently from any 
other failure.
   **Root cause:**
   - The frontend has no global 401 handler. `authService.js:75` checks for 401 
only in `_fetchMe()` during boot — not during ongoing operations.
   - Every other service (`agentService.js`, `dataStoreService.js`, deployment 
service) treats failed fetches generically: `throw new Error(errorData.detail 
|| 'Failed to save the agent.')`.
   - A 401 mid-session surfaces as a generic error with no hint about auth.
   **Impact:**
   - Confusing UX for any user who keeps a tab open longer than the session TTL.
   - Users repeat the same failed action multiple times before realizing what's 
wrong.
   - Lost work if the form state is cleared on error.
   ### Proposed solution
   **Backend:** distinguish session-expired from authz-denied with a structured 
header or detail string:
    
   ```python
   if sid and not user:
       raise HTTPException(
           status_code=401,
           detail="session_expired",
           headers={"X-Auth-Reason": "session_expired"},
       )
   raise HTTPException(
       status_code=401,
       detail="not_authenticated",
       headers={"X-Auth-Reason": "not_authenticated"},
   )
   ```
    
   **Frontend:** introduce `fetchWithAuth` helper that every service routes 
through:
    
   ```javascript
   async function fetchWithAuth(url, opts = {}) {
     const resp = await fetch(url, { ...opts, credentials: 'include' });
     if (resp.status === 401 && resp.headers.get('X-Auth-Reason') === 
'session_expired') {
       window.dispatchEvent(new CustomEvent('auth:session-expired', {
         detail: { returnTo: window.location.pathname + window.location.search 
},
       }));
     }
     return resp;
   }
   ```
    
   A top-level component (`App.jsx` or `AuthExpiryModal`) listens for the event 
and renders a clear modal: *"Your session has expired. Please sign in again to 
continue."* with a [Sign in] button. Successful re-login navigates to 
`returnTo`.
    
   ### Acceptance Criteria
   - [ ] Fixed: Backend distinguishes `session_expired` from 
`not_authenticated` via `X-Auth-Reason` header
   - [ ] Fixed: `fetchWithAuth` helper added to shared module
   - [ ] Fixed: All services (`agentService`, `dataStoreService`, 
`deploymentService`, etc.) routed through `fetchWithAuth`
   - [ ] Fixed: `AuthExpiryModal` component renders on `auth:session-expired` 
event
   - [ ] Fixed: After re-login, user returns to the URL they were on (via 
`returnTo`)
   - [ ] Test added: Expired session triggers modal, not generic error
   - [ ] Test added: 401 without `X-Auth-Reason: session_expired` (genuine 
authz) does NOT trigger the modal
   - [ ] Test added: All 30 fetch sites use `fetchWithAuth`
   - [ ] Documentation: re-login flow diagram
   ### References
   - File: `webapp/packages/api/user-service/routes.py:get_current_user` (after 
ISSUE-001)
   - File: `webapp/packages/webui/src/services/authService.js`
   - Tracker: FIXES.md item #14
   ### Priority
   **Medium** - Blocked on ISSUE-001 (no 401s for frontend to listen for while 
it returns 500). Once unblocked, ~20 LOC backend + ~150 LOC frontend including 
modal and refactoring services.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to