molecule-core/canvas/src/lib
Hongming Wang 5a3dbb95e1 fix(api): probe /cp/auth/me before redirecting on 401
The actual cause-fix for the staging-tabs E2E saga (#2073/#2074/#2075).

Old behaviour: ANY 401 from any fetch on a SaaS tenant subdomain
called redirectToLogin → window.location.href = AuthKit. This is
wrong. Plenty of 401s don't mean "session is dead":

  - workspace-scoped endpoints (/workspaces/:id/peers, /plugins)
    require a workspace-scoped token, not the tenant admin bearer
  - resource-permission mismatches (user has tenant access but not
    this specific workspace)
  - misconfigured proxies returning 401 spuriously

A single transient one of those yanked authenticated users back to
AuthKit. Same bug yanked the staging-tabs E2E off the tenant origin
mid-test for 6+ hours tonight, leading to the cascade of test-side
mocks (#2073/#2074/#2075) that worked around the symptom without
fixing the cause.

This PR fixes it at the source. The new logic:

  - 401 on /cp/auth/* path → that IS the canonical session-dead
    signal → redirect (unchanged)
  - 401 on any other path with slug present → probe /cp/auth/me:
      probe 401 → session genuinely dead → redirect
      probe 200 → session fine, endpoint refused this token →
                  throw a real Error, caller renders error state
      probe network err → assume session-fine (conservative) →
                  throw real Error
  - slug empty (localhost / LAN / reserved subdomain) → throw
    without redirect (unchanged)

The probe adds one extra fetch on a 401, only when slug is set
and the path isn't already auth-scoped. That's rare and
worthwhile — a transient probe round-trip is cheap; an unwanted
auth redirect is a UX disaster.

Tests:
  - api-401.test.ts rewritten with the full matrix:
      * /cp/auth/me 401 → redirect (no probe, that IS the signal)
      * non-auth 401 + probe 401 → redirect
      * non-auth 401 + probe 200 → throw, no redirect  ← the fix
      * non-auth 401 + probe network err → throw, no redirect
      * empty slug paths (localhost/LAN/reserved) → throw, no probe
  - 43 tests in canvas/src/lib/__tests__/api*.test.ts all pass
  - tsc clean

The staging-tabs E2E spec's universal-401 route handler stays as
defense-in-depth (silences resource-load console noise + guards
against panels without try/catch), but the comment now describes
its role honestly: api.ts is the primary fix, the route is the
safety net.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 23:49:28 -07:00
..
__tests__ fix(api): probe /cp/auth/me before redirecting on 401 2026-04-25 23:49:28 -07:00
api feat(canvas): SaaS cross-origin — slug header + cookie credentials (Phase F) 2026-04-14 20:08:39 -07:00
validation initial commit — Molecule AI platform 2026-04-13 11:55:37 -07:00
api.ts fix(api): probe /cp/auth/me before redirecting on 401 2026-04-25 23:49:28 -07:00
auth.ts fix(auth): redirect to app.moleculesai.app for login, not tenant subdomain 2026-04-23 11:16:22 -07:00
billing.ts fix(canvas): apply flat-rate pricing copy for Phase 34 launch (Issue #1833) 2026-04-24 17:54:23 +00:00
canvas-actions.ts initial commit — Molecule AI platform 2026-04-13 11:55:37 -07:00
credits.ts feat(canvas): Phase 5 — credit balance pill + low-balance banner 2026-04-19 07:27:29 -07:00
deploy-preflight.ts refactor(canvas): data-drive provider picker from template config.yaml 2026-04-23 17:07:15 -07:00
design-tokens.ts fix(canvas): address all code review findings on PR #482 2026-04-16 07:48:47 -07:00
hydrate.ts initial commit — Molecule AI platform 2026-04-13 11:55:37 -07:00
runtime-names.ts initial commit — Molecule AI platform 2026-04-13 11:55:37 -07:00
runtimeProfiles.ts refactor(canvas): extract runtime profiles to @/lib/runtimeProfiles 2026-04-24 11:48:39 -07:00
services.ts refactor(secrets): strip Service dropdown from Add-Key form 2026-04-22 16:41:43 -07:00
tenant.ts feat(canvas): default tier T3 and hide T1/T2 on SaaS 2026-04-22 17:02:48 -07:00
utils.ts chore(canvas): initialize shadcn/ui — components.json + cn utility 2026-04-18 07:57:17 -07:00
ws-close.ts fix(canvas): Legend avoids TemplatePalette + silence WS handshake races 2026-04-23 16:03:01 -07:00
ws-url.ts fix: code review findings — token UI, auth hardening, WS dedup 2026-04-16 10:42:26 -07:00