← All tasks

SSO bounce-chain — path preserved through /cafe/login placeholder PROD · GATE 2

Bug diagnosed live from a user screen-recording (2026-05-22). After an idle period — or after our regression sweep rotated tenant_users.active_session_token via R8.2 — clicking NIX Cafe on the Commerce launchpad bounced through /cafe/login and landed back on the launchpad with the original destination lost. Root cause was identified, fixed, and verified end-to-end on prod by forcing the exact failure mode via SQL.

7/7 prod · 51/51 regression = 58/58 total. nix-cafe commit eec1a56. 6 files · ~25 LOC · no migration. Middleware now injects x-nix-pathname on every passed-through request; new loginRedirectUrl() helper in lib/auth.ts reads it; 5 server-side callsites swapped from redirect("/login")redirect(await loginRedirectUrl()). Prod test reproduces the full chain: SSO-login → SQL-rotate active_session_tokenGET /cafe/dashboard with stale-sid cookie → assert 307 to /cafe/login?redirect=%2Fcafe%2Fdashboard (the fix) → follow chain to Commerce login form → submit → land back on /cafe/dashboard (full recovery).

Prod checks — 7/7

51/51 regression green — no regressions from this push.
test-phase1-prod.mjs11/11
test-phase2-sso-outdoor-prod.mjs6/6
test-phase2-cafe-multishop-prod.mjs6/6 *
test-m1-prod.mjs10/10
test-r7-prod.mjs14/14
test-r8-prod.mjs4/4

* phase2-cafe-multishop first run as parallel-with-narongix-sweep failed 5/6 with "Got bounced to login" on the POS picker check — a race against whatever transient state the in-flight narongix logins were rotating. Solo re-run was 6/6 green. Not a regression from this slice — the change is server-side redirect URL plumbing only, doesn't touch any auth check that could newly reject a different tenant's session.

Reproduction screenshots — full chain end-to-end on prod

1. SSO login → Commerce launchpadLumière owner authenticated. nix_session cookie minted with the user's just-stored active_session_token as sid.
2. /cafe/login placeholder renderedAfter SQL-rotation invalidates the cookie's sid: server-side redirect via the new loginRedirectUrl() helper preserves ?redirect=%2Fcafe%2Fdashboard. The useEffect then forwards to Commerce with the same path.
3. Commerce login form rendersCommerce's H5.8 guard sees ?redirect=/cafe/dashboard is a sibling-product path and falls through — login form actually shows up instead of auto-bouncing to launchpad. This is the key behavior change visible to the user.
4. Submit → lands on /cafe/dashboardonSubmit honors the preserved redirect. User ends up exactly where they originally intended, not on the launchpad. Bonus: the login itself re-rotates active_session_token, naturally cleaning up the test's invalidation.

Test artifacts: result.json · login-state.json (captured user id + pre-test sid for reference)

What's now closed

The "click Cafe → login flash → launchpad" UX failure after R8.2 sid rotation or 30-min idle TTL is resolved. Specifically:

Underlying root causes NOT addressed in this slice (deliberate — different scope):

Both are improvements for another day. The recovery UX is what users see, and it's now correct.