Skip to content

fix(frontend): only redirect to /login when the session check returns 401/403#3231

Open
SubprimeHardware wants to merge 2 commits into
seerr-team:developfrom
SubprimeHardware:fix/login-redirect-on-aborted-session-check
Open

fix(frontend): only redirect to /login when the session check returns 401/403#3231
SubprimeHardware wants to merge 2 commits into
seerr-team:developfrom
SubprimeHardware:fix/login-redirect-on-aborted-session-check

Conversation

@SubprimeHardware

@SubprimeHardware SubprimeHardware commented Jul 7, 2026

Copy link
Copy Markdown

Description

If you're on any Seerr page and type a different site's URL into the address bar, Seerr sometimes cancels that navigation and drags you back to itself. I hit this regularly on iOS Safari and it took a while to work out what was actually happening.

The chain: useUser revalidates /api/v1/auth/me on window focus and every 30s. Tapping the address bar fires the focus revalidation; committing the navigation then aborts that fetch. The abort surfaces as an axios error with no response, and UserContext treats any error as a dead session and sets location.href = '/login'. The old page's JS keeps running until the new document commits, so that assignment races the user's navigation and wins (WebKit's slow commit makes it easy to hit). The session is actually still valid, so /login immediately 307s back to / — the visible result is "I typed another URL and ended up back on Seerr."

The fix: only treat the session as invalid when auth/me actually comes back 401/403. A rejection with no HTTP response (aborted fetch, offline blip, brief server restart mid-poll) no longer logs you out. The error field in UserHookResponse was declared string but is an AxiosError at runtime; fixed the type so the status check compiles. The other two consumers of error only check truthiness, so nothing else changes.

Disclosure: I used Claude to help trace this (it dug the failure sequence out of my reverse-proxy logs and drafted the patch); I've reviewed the change and the analysis myself.

How Has This Been Tested?

Diagnosed from reverse-proxy access logs on my instance — one occurrence captured end to end:

01:23:55.186  GET other-app/            -> 200   typed navigation, HTML delivered
01:23:55.453  GET seerr/api/v1/auth/me  -> 499   fetch aborted by the navigation
01:23:55.468  GET seerr/login           -> 307   UserContext redirect; session still valid
01:23:55.504  GET seerr/                -> 200   full reload, back on Seerr
01:24:00.288  GET other-app/            -> 200   second attempt sticks

I run a source build with this patch applied since 5 July and the yank has not recurred (monitored via the same access logs).

Checklist:

  • I have read and followed the contribution guidelines.
  • Disclosed any use of AI (see our policy)
  • I have updated the documentation accordingly. (n/a — behavior fix)
  • All new and existing tests passed.
  • Successful build pnpm build (not run locally; the same two-file patch builds and runs in my production docker image)
  • Translation keys pnpm i18n:extract (n/a — no strings changed)
  • Database migration (if required) (n/a)

Summary by CodeRabbit

  • Bug Fixes
    • Improved login redirection so users are sent to the login page only when their session is invalid or missing, not for unrelated errors.
    • Reduced unnecessary redirects caused by non-authentication-related failures.
    • Enhanced user-related error reporting to better reflect actual request failures during sign-in flows.

… 401/403

UserContext treats any auth/me error as a dead session and sets
location.href='/login'. A fetch aborted by the user navigating away (or
a brief proxy/network blip) rejects with no HTTP response and triggered
the same redirect — the old page's JS is still running until the new
document commits, so the redirect races the user's navigation and wins,
yanking the browser back to the app. The session is actually valid, so
/login 307s straight back to /.

Redirect only when auth/me actually returns 401/403. The error field in
UserHookResponse was declared string but is an AxiosError at runtime;
typed correctly so the status check compiles. The two other consumers of
error only check truthiness.
@SubprimeHardware SubprimeHardware requested a review from a team as a code owner July 7, 2026 03:05
@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e2b07c2c-743c-49e3-bf63-1a37f95f32b0

📥 Commits

Reviewing files that changed from the base of the PR and between 85c83cb and e9909eb.

📒 Files selected for processing (1)
  • src/context/UserContext.tsx

📝 Walkthrough

Walkthrough

UserContext now redirects to /login only when useUser returns a 401 or 403 error status. The useUser hook’s error field now exposes an optional AxiosError instead of a string.

Changes

Session Redirect Fix

Layer / File(s) Summary
Error type contract update
src/hooks/useUser.ts, src/context/UserContext.tsx
useUser now returns error?: AxiosError, and UserContext uses error?.response?.status to compute sessionInvalid before redirecting.

Estimated code review effort: 2 (Simple) | ~10 minutes

Poem

A bunny watched the status glow,
Two codes said “login,” others: “no.”
No more hops on every flaw,
Just 401 and 403 in paw. 🐰

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly states the main frontend behavior change: redirecting to /login only on 401/403 session checks.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/context/UserContext.tsx`:
- Around line 35-37: In UserContext’s redirect guard, the current `!user`
condition still forces a login redirect before `/api/v1/auth/me` has proven the
session is invalid. Update the redirect logic in the UserContext component so
the `/login` redirect is driven only by the authenticated failure state
(sessionInvalid from a 401/403) or otherwise explicitly gate the `!user` branch
behind that result, keeping transient empty user state from triggering
navigation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f12458d0-cf6a-4e53-96a3-d6db326b43fa

📥 Commits

Reviewing files that changed from the base of the PR and between 5ae70d0 and 85c83cb.

📒 Files selected for processing (2)
  • src/context/UserContext.tsx
  • src/hooks/useUser.ts

Comment thread src/context/UserContext.tsx Outdated
Review feedback: the !user branch could still navigate before auth/me
has proven anything (first fetch in flight with a cold cache). The
redirect is now driven solely by a 401/403 from the session check;
unauthenticated full page loads are already redirected server-side by
getInitialProps.
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.

1 participant