Skip to content

Frontend incorrectly redirecting all 403 and 401 errors to login #1

@CupOfGeo

Description

@CupOfGeo

Issue Content

The frontend global error handler in `main.tsx` was treating both 401 and 403 HTTP status codes as authentication failures, redirecting users to the login page and clearing their access token.

// Original code
const handleApiError = (error: Error) => {
  if (error instanceof ApiError && [401, 403].includes(error.status)) {
    localStorage.removeItem(\"access_token\")
    window.location.href = \"/login\"
  }
}

Problem

This is incorrect behavior:

  • 401 Unauthorized = User is not authenticated → redirect to login is correct
  • 403 Forbidden = User IS authenticated but lacks permission → should NOT redirect to login

Backend endpoints returning 403

File Reason
`deps.py:38` User account is inactive
`deps.py:55` User lacks superuser privileges
`users.py:135,220` Superuser attempting to delete themselves
`users.py:170` Permission check failure

All of these cases have a valid authenticated user who simply can't perform a specific action. Logging them out is wrong.

Suggested Fix

Change the global handler to only redirect on 401:

const handleApiError = (error: Error) => {
  // Only redirect on 401 (unauthorized), not 403 (forbidden)
  if (error instanceof ApiError && error.status === 401) {
    localStorage.removeItem(\"access_token\")
    window.location.href = \"/login\"
  }
}

Individual components should handle 403 errors appropriately (show error toast, display permission message, etc.).

Notes

This was discovered while implementing premium user item limits, where 403 is returned when a free user hits their item creation limit. The global handler was redirecting to login instead of showing the upgrade modal."

Next steps

lets find all the places that return 403 and decide if we need to handle them I know of one example where users can now access the /admin page but it will be blank. I see the 403 errors in the network tab. We can either instead block redirecting them to a more proper unauthorized.html or give them a UI error.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions