Skip to content

Redirect expired sessions to login - #456

Merged
JacquesDelfrate merged 1 commit into
mainfrom
fix/issue-455-session-expiry
Sep 24, 2026
Merged

JacquesDelfrate merged 1 commit into
mainfrom
fix/issue-455-session-expiry

Conversation

@JacquesDelfrate

@JacquesDelfrate JacquesDelfrate commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • handle authenticated API 401 UNAUTHORIZED_ACCESS responses as an expired global session
  • clear the stale token, deduplicate concurrent failures, and redirect to tenant login
  • show a translated session-expired message and safely restore the previous route after login
  • exclude public authentication endpoints from expiry handling

Tests

  • 4 focused Jest suites passed
  • 30 tests passed

Closes #455

Summary by Sourcery

Handle expired authenticated sessions by clearing stale credentials, redirecting users to tenant login, and safely restoring their prior route after sign-in.

New Features:

  • Redirect authenticated users with expired sessions to their tenant login page and restore their previous safe route after reauthentication.

Bug Fixes:

  • Prevent stale session tokens and duplicate concurrent authorization failures from leaving users in an invalid authenticated state.
  • Exclude public authentication requests from triggering session-expiration redirects.

Enhancements:

  • Display a translated session-expired notification and preserve pending redirect state across logout flows.

Tests:

  • Add coverage for session-expiration detection, redirect deduplication, safe return paths, public endpoint exclusions, and login restoration.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @JacquesDelfrate, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 4 days and 11 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@sourcery-ai

sourcery-ai Bot commented Sep 24, 2026

Copy link
Copy Markdown

Reviewer's Guide

The PR adds a centralized expired-session flow that detects authenticated API 401s, clears stale authentication state, deduplicates redirects, and sends users to tenant login with a validated return path. Login consumes the redirect state, shows a localized message, restores the prior route after re-authentication, and public auth requests remain excluded.

Sequence diagram for expired session detection and login recovery

sequenceDiagram
    participant API as PACS API
    participant Client as Axios interceptor
    participant Session as Session expiry handler
    participant Storage as Local storage
    participant Login as Login page
    participant User as User

    API-->>Client: 401 UNAUTHORIZED_ACCESS
    Client->>Session: handleSessionExpiredError(error)
    Session->>Session: isPublicAuthRequest(url)
    Session->>Storage: Read sessionToken and redirect state
    Session->>Storage: Clear sessionToken
    Session->>Storage: Save safe returnTo and pending flag
    Session->>Login: Redirect to /login with tenant, reason, returnTo
    Login->>Session: consumeSessionExpiredRedirect(search)
    Session->>Storage: Clear pending redirect state
    Login->>User: Show translated session-expired message
    User->>Login: Submit credentials
    Login->>Login: navigateAfterAuth(user, returnTo)
    Login-->>User: Restore previous safe route
Loading

Flow diagram for expired session redirect safeguards

flowchart TD
    A[API response] --> B{401 and UNAUTHORIZED_ACCESS?}
    B -- No --> Z[Keep normal error handling]
    B -- Yes --> C{Public authentication endpoint?}
    C -- Yes --> Z
    C -- No --> D{Authenticated session exists?}
    D -- No --> Z
    D -- Yes --> E{Redirect already pending?}
    E -- Yes --> Z
    E -- No --> F[Clear stale session token]
    F --> G[Validate current route as safe returnTo]
    G --> H[Store pending state and returnTo]
    H --> I[Redirect to tenant login]
    I --> J[Re-authenticate and restore safe route]
Loading

File-Level Changes

Change Details Files
Centralize expired-session detection in the PACS API response interceptor.
  • Handle only 401 responses with UNAUTHORIZED_ACCESS.
  • Ignore public authentication endpoints.
  • Invoke the expiry handler while preserving the original rejected promise.
platform/app/src/pacsAPIAxios.js
platform/app/src/pacsAPIAxios.test.ts
Implement safe, deduplicated expiry cleanup and tenant login redirection.
  • Clear the authenticated token and persist pending redirect state.
  • Prevent concurrent unauthorized responses from triggering duplicate redirects.
  • Preserve only validated internal paths, including query strings and hashes.
  • Provide helpers to consume redirect state and support downstream logout flows.
platform/app/src/service/sessionExpirySession.ts
platform/app/src/service/sessionExpirySession.test.ts
platform/app/src/service/userService.ts
Integrate the expired-session flow into login and post-authentication navigation.
  • Consume the expiry reason once and display a translated session-expired alert.
  • Remove the transient reason while retaining tenant and safe return-route parameters.
  • Restore the prior route after successful login, defaulting unsafe destinations to the root route.
platform/app/src/routes/Login/Login.tsx
platform/app/src/routes/Login/Login.test.ts
Add translated session-expiration copy across supported locales and enforce translation coverage.
  • Add the session-expired message to each onboarding namespace.
  • Extend locale tests to require the new login-access message.
platform/i18n/src/locales/ar/Onboarding.json
platform/i18n/src/locales/de/Onboarding.json
platform/i18n/src/locales/en-US/Onboarding.json
platform/i18n/src/locales/es/Onboarding.json
platform/i18n/src/locales/fr/Onboarding.json
platform/app/src/routes/Members/memberAccessTranslations.test.ts

Assessment against linked issues

Issue Objective Addressed Explanation
#455 Globally detect authenticated API responses with HTTP 401 and errorCode UNAUTHORIZED_ACCESS, while excluding public authentication endpoints. ✅
#455 Clear the expired authenticated session, deduplicate concurrent expiry handling, redirect to the tenant login page, and display a translated session-expired message. ✅
#455 Safely preserve and restore the user's prior application route after login, with automated coverage for cleanup, redirect deduplication, excluded routes, and login restoration. ✅

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@cursor
cursor Bot requested review from danvincent11 and kabaluyot September 24, 2026 02:03
@JacquesDelfrate
JacquesDelfrate merged commit d9e016a into main Sep 24, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Log out and redirect to login when API session expires (401)

1 participant