Skip to content

console: the first-run setup wizard's completion redirect bypasses the console basename #4181

Description

@yinlianghui

Found while working objectui#2794 (the /setup deep link). Not fixed there — that card is about who reaches /setup, this is about where the wizard sends you once it is done. Filed unassigned.

What

apps/console/src/pages/auth/SetupPage.tsx finishes the first-run owner bootstrap with a full-page navigation to the site root, twice:

  • line 88 — the already-signed-in bounce: window.location.assign('/')
  • line 148 — the success path, after signUp() and the bootstrap-org rename: window.location.assign('/')

window.location.assign bypasses React Router's basename. The console resolves its basename from an injected base href (App.tsx:resolveBasename), and the framework CLI injects one for every embedded deployment — so on a console served at /_console/, both calls land on the ORIGIN root rather than the console root.

Why this is a real class, not a nitpick

apps/console/src/pages/auth/LoginPage.tsx already carries the fix for exactly this, as a named helper with a comment that states the rule:

function withConsoleBase(path: string): string

window.location.assign bypasses React Router's basename, so a path produced by the router […] or a literal like /organizations would resolve to http://host/settings, missing the /_console mount and 404-ing.

SetupPage makes the same call and does not use that helper. Same defect the helper exists to prevent, one file over.

Severity / reachability

Low reach, and that is why it is filed rather than smuggled into #2794's PR:

  • it only fires on a deployment that has no owner yet, i.e. genuinely first-run;
  • under the default / mount the two spellings coincide, so a standalone os dev run cannot see it — this needs an embedded / base href-mounted console to reproduce, which is why nothing has hit it.

The outcome, when it does fire, is a completed bootstrap that lands the brand-new owner outside the SPA — the worst possible moment for a dead end, since it is the first screen after creating the account.

Suggested fix

Route both calls through withConsoleBase (or lift that helper somewhere both pages can import it — it is currently module-private to LoginPage). Worth a quick grep for other window.location.assign / window.location.href = producers in apps/console at the same time; this one was found by reading, not by a sweep, so the set may be larger.


Generated by Claude Code

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions