fix(webapp): remove env from non-env-specific page URLs#6098
Conversation
There was a problem hiding this comment.
1 issue found across 12 files
Confidence score: 3/5
- There is a concrete regression risk in
packages/webapp/src/components/PrivateRoute.tsx: stalenotFoundEnv/unauthorizedEnvflags can persist and incorrectly block navigation to env-free pages. - Because this is a user-facing routing/access behavior issue (severity 6/10, confidence 8/10), the merge risk is moderate rather than minimal.
- This looks straightforward to mitigate by resetting the env error flags before early returns on non-env paths, which should reduce the chance of false blocking.
- Pay close attention to
packages/webapp/src/components/PrivateRoute.tsx- env error state needs to be cleared on non-env route handling to avoid stale access denials.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/webapp/src/components/PrivateRoute.tsx">
<violation number="1" location="packages/webapp/src/components/PrivateRoute.tsx:52">
P2: Reset env error flags before returning for non-env paths; otherwise stale `notFoundEnv`/`unauthorizedEnv` state can incorrectly block the new env-free pages.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
a4af425 to
6fe2d9b
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6fe2d9b564
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 58f239c667
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/webapp/src/components/PrivateRoute.tsx">
<violation number="1" location="packages/webapp/src/components/PrivateRoute.tsx:75">
P2: `notFoundEnv` can remain stuck `true` after navigation because it is no longer reset on valid/non-env paths.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Fix all with cubic
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c5a7e3fea2
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9d560a73f1
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3edfaf232f
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
3edfaf2 to
d90a1d7
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d90a1d78e7
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: df19a65847
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
kaposke
left a comment
There was a problem hiding this comment.
We already had a fix in place to make it linkable in docs. /team-settings, /user-settings, /team/billing should all work as links in the docs. It will find an environment and redirect you to it (eg: /dev/team/billing).
This PR achieves it with clean paths without the environment, relying on what is on localstorage to load an environment. It seems to work well, so I'm fine with shipping. I found a bug: if you rename the environment you're currently in from another tab, navigating back to one of the environment dependent route will break and sign you off. Very edge case though.
I believe Bastien forgot there was a fix in place. Worth double-checking if this is needed, and the tradeoff.
|
@kaposke Thanks for the review 🙏 On the existing fix — you're right that Good catch on the rename-env bug. I believe this is pre-existing, not a regression from this PR. I've created NAN-5663 as a follow-up fix. |
Team settings, user settings, and team billing pages were nested under /:env/ giving them URLs like /dev/team-settings. These pages are team/user-level and not environment-scoped, making them hard to link from documentation. Move them to /team-settings, /user-settings, and /team/billing with backward-compat redirects from the old env-prefixed paths.
Move the non-env path list to a shared utils/routes.ts so PrivateRoute and EnvironmentDropdown stay in sync. Also switch EnvironmentDropdown to a startsWith check (same as PrivateRoute) for precise path matching, and revert an unrelated package-lock.json pubsub dependency move.
Instead of an early return with duplicated env-resolution logic for non-env paths, thread an isNonEnvPath flag through the existing validation block. This removes the duplicate fallback and ensures non-env pages benefit from the same prod-env access guard logic.
Remove the !isNonEnvPath guard from the production-access check so that a stale prod env in the store is replaced even when navigating to /team-settings, /user-settings, or /team/billing. The PageEnvironmentUnauthorized splash is still suppressed for non-env paths via setUnauthorizedEnv(!isNonEnvPath). Also reset notFoundEnv to false in the valid-env branch to prevent it staying stuck true after navigating away from an invalid-env path.
Use a RedirectPreservingLocation component instead of plain Navigate so that backward-compat redirects (e.g. /dev/team/billing?tab=usage) forward search params and hash fragments to the new URLs.
startsWith('/team-settings') would incorrectly match a hypothetical
/team-settings-prod env path. Replace the raw startsWith check with
an isNonEnvPath helper that requires either an exact match or a
trailing slash, ensuring /team-settings-* env paths remain
env-specific.
/:env/team-settings etc. were still evaluated as env-scoped, so a stale or unauthorized env segment could show PageNotFound before the redirect route ran. Strip the leading env segment and check the remainder against NON_ENV_PATH_PREFIXES to handle both old and new URL forms.
cc29063 to
fadcc24
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fadcc24419
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
## Problem Team settings, user settings, and team billing pages were nested under `/:env/` giving them URLs like `/dev/team-settings`. These pages are team/user-level and not environment-specific, making them hard to link from documentation. ## Solution Moves them to env-free paths: `/team-settings`, `/user-settings`, `/team/billing`. Old env-prefixed URLs redirect to the new paths for backward compat. These pages still read `env` from the Zustand store (not from the URL) to make env-scoped API calls (e.g. `useTeam(env)`). The store is seeded from `localStorage` on load and kept in sync by `PrivateRoute` whenever the user is on an env-specific page. For direct navigation to these pages, `PrivateRoute` now validates the stored env against `meta.environments` and falls back to a valid one if stale — so API calls always get a real env regardless of what's in the URL. Note: the new top-level routes (`/team-settings`, `/user-settings`, `/team`) are now reserved and would shadow any environment with the same name. Validated against the prod DB — no existing account uses any of these as an env name. Follow-up: [NAN-5521](https://linear.app/nango/issue/NAN-5521) to block these names at env creation time. Fixes [NAN-5447](https://linear.app/nangohq/issue/NAN-5447) ## Testing - Navigate to `/team-settings`, `/user-settings`, `/team/billing` — pages load without env in URL - Navigate to `/dev/team-settings` — redirects to `/team-settings` - Switch environment while on `/team-settings` — URL stays at `/team-settings` - Env-specific pages (`/dev/integrations`, `/dev/connections`) still work normally --------- Co-authored-by: Matej Vobornik <matej.vobornik@users.noreply.github.com>
Problem
Team settings, user settings, and team billing pages were nested under
/:env/giving them URLs like/dev/team-settings. These pages are team/user-level and not environment-specific, making them hard to link from documentation.Solution
Moves them to env-free paths:
/team-settings,/user-settings,/team/billing. Old env-prefixed URLs redirect to the new paths for backward compat.These pages still read
envfrom the Zustand store (not from the URL) to make env-scoped API calls (e.g.useTeam(env)). The store is seeded fromlocalStorageon load and kept in sync byPrivateRoutewhenever the user is on an env-specific page. For direct navigation to these pages,PrivateRoutenow validates the stored env againstmeta.environmentsand falls back to a valid one if stale — so API calls always get a real env regardless of what's in the URL.Note: the new top-level routes (
/team-settings,/user-settings,/team) are now reserved and would shadow any environment with the same name. Validated against the prod DB — no existing account uses any of these as an env name. Follow-up: NAN-5521 to block these names at env creation time.Fixes NAN-5447
Testing
/team-settings,/user-settings,/team/billing— pages load without env in URL/dev/team-settings— redirects to/team-settings/team-settings— URL stays at/team-settings/dev/integrations,/dev/connections) still work normally