Skip to content

Portal keeps a dead session alive: PortalProvider swallows a 401 from /portal/profile #183

Description

@pat-lewczuk

Found while fixing #111 (PR #171). PR #171 clears hackon:* localStorage at all three boundaries the
app controls — sign out, sign in, and accept-invite's own logout. This is the one path it cannot close
from application code.

What happens

PortalProvider (in @open-mercato/ui, node_modules — read-only framework code) swallows a 401
from /portal/profile without signing the user out or redirecting to login. When a portal session
cookie expires or is cleared out-of-band, no logout code ever runs, so:

  • The portal keeps rendering with whatever state it already had.
  • hackon:* localStorage keys survive, because clearing them is attached to the logout call sites.
  • The user sits in a half-authenticated shell where reads 401 silently.

This is the residual half of #111: the sweep-on-login that PR #171 added is defence in depth for
exactly this case, but it only helps once the user logs in again.

Why it is filed rather than fixed

PortalProvider lives in the framework. Per AGENTS.md the options are to eject (heavy, for one
behaviour) or to fix it upstream in @open-mercato/ui. Upstream is the right home: "a 401 from the
profile endpoint means the session is gone, so sign out and redirect" is correct for every consumer,
not just this app.

Related, same root

The portal only learns the competition stage when CompetitionProvider remounts, so a parked tab
never observes a stage advance. PR #168 makes the chrome react once the value changes, but nothing
pushes the new value. The app already has an SSE bridge (.ai/guides/events.md → DOM Event Bridge);
publishing stage changes over it would close this properly. Feature-sized, and worth considering
alongside the 401 handling since both are "the portal does not notice that the world changed".

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions