molecule-core/canvas/src/app
Hongming Wang 4cac4e7710 fix(canvas): wire SaaS Sign-out button — POST /cp/auth/signout was unreachable from the UI
Reported externally on 2026-05-05: "SaaS app logout does not work."

Root cause: the control plane has had POST /cp/auth/signout (clears the
WorkOS session cookie + revokes at the provider) since auth shipped,
but no canvas code ever called it. grep across canvas/ for
`logout|signOut|signout|sign-out` returned zero results — no helper,
no button, no menu entry. Users had no path to log out short of
clearing cookies in DevTools.

This is a UI gap, not a backend bug. Adding the missing pieces:

1. `signOut()` helper in `canvas/src/lib/auth.ts`:
   - POST /cp/auth/signout with credentials:include (cross-origin
     cookie required for tenant subdomain → app subdomain)
   - Best-effort: a 5xx, 401-stale-cookie, or network failure still
     redirects the browser to /cp/auth/login. Leaving the user on an
     authed-looking page after they clicked Sign out is the worst
     possible UX — that's the precise "logout doesn't work" symptom
     the report described.
   - Lands on /cp/auth/login (not the current URL) so the user
     doesn't loop back into the org they just left via AuthGate's
     return_to.

2. `AccountBar` component on /orgs page Shell — renders the signed-in
   email + Sign-out button at the top. Click → signOut() →
   `Signing out…` → bounces to login. Disabled-while-pending so a
   double-click can't fire two requests.

3. Tests in `auth.test.ts` (4 new, total 12 pass):
   - POSTs to the right endpoint with credentials:include
   - Redirects to /cp/auth/login after success
   - Redirects EVEN ON network failure (the critical UX invariant)
   - Redirects on 401 (stale cookie path)

The auth-origin resolution (`getAuthOrigin`) is reused so a tenant
subdomain (acme.moleculesai.app) correctly POSTs to
app.moleculesai.app/cp/auth/signout — same chain that fetchSession
+ redirectToLogin already use.

Test plan:
- [x] `npx vitest run src/lib/__tests__/auth.test.ts` — 12/12 green
- [x] `tsc --noEmit` — clean
- [ ] Manual: navigate to /orgs, click Sign out, observe redirect +
      that the next /orgs visit bounces to login (cookie cleared)
- [ ] CI green

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 12:20:18 -07:00
..
__tests__ fix(canvas/test): patch test regressions from PR #1243 + proximity hitbox fix (#1313) 2026-04-21 07:06:57 +00:00
api/buildinfo feat(canvas): add /api/buildinfo for version-display parity with tenant 2026-04-30 12:00:35 -07:00
blog/2026-04-20-chrome-devtools-mcp docs(marketing): add Phase 34 video assets + manual posting package + chrome-devtools blog 2026-04-23 19:12:17 +00:00
orgs fix(canvas): wire SaaS Sign-out button — POST /cp/auth/signout was unreachable from the UI 2026-05-05 12:20:18 -07:00
pricing feat(canvas): warm-paper theme + Tailwind v4 migration 2026-05-03 01:43:55 -07:00
globals.css fix(canvas): dark-mode chat bubble contrast 2026-05-03 12:00:51 -07:00
icon.png
layout.tsx feat(canvas): warm-paper theme + Tailwind v4 migration 2026-05-03 01:43:55 -07:00
page.tsx fix(canvas): add role=status + aria-live to remaining loading states 2026-05-03 07:11:48 -07:00