Skip to content

feat(dashboard): add connection token issuing ui#5411

Merged
abcxff merged 6 commits into
mainfrom
stack/feat-dashboard-add-connection-token-issuing-ui-oolwqlys
Jul 15, 2026
Merged

feat(dashboard): add connection token issuing ui#5411
abcxff merged 6 commits into
mainfrom
stack/feat-dashboard-add-connection-token-issuing-ui-oolwqlys

Conversation

@abcxff

@abcxff abcxff commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@claude

claude Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Review: feat(dashboard): add connection token issuing ui

Overview

Adds a "Connection Tokens" card to the namespace advanced settings, backed by a new createConnectionTokenMutationOptions() on the cloud data provider. Since the pinned cloud SDK doesn't expose the tokens/connection endpoint yet, the mutation calls cloud-api directly via fetch with the session cookie, and the UI reveals the returned token once via DiscreteInput, gated behind features.auth.

Correctness

Stale token can be shown for the wrong namespace after switching namespaces (tokens.tsx)
ConnectionTokensInner stores the issued token in useMutation's local data/error state. That state is not tied to mutationKey/mutationFn identity — React Query does not reset it when the namespace/project changes on a re-render; only useQuery-based state does that automatically. The file's own comment on ConnectionTokens (and the pre-existing DangerZone in namespace-settings.tsx) documents that this settings drawer can stay mounted while the user switches namespace/project from the nav. If a user issues a connection token, then switches to a different namespace while the drawer stays open, the previously issued token (and its "Expires ..." caption) remains displayed as if it belongs to the new namespace. Given the messaging ("This token is only shown once, copy it now"), a user could reasonably copy a token believing it's scoped to the namespace currently in view when it actually belongs to the old one.

  • Suggest resetting the mutation (reset()) when namespace/project changes (e.g. an effect keyed on those values), or remounting ConnectionTokensInner with a key derived from organization/project/namespace from the outer component so switching namespace clears data/error.

Code Quality / Style

  • The outer/inner split in ConnectionTokens/ConnectionTokensInner is a good pattern for keeping hook order stable while useCloudNamespaceDataProvider() can transiently resolve to undefined; it's cleaner than the pre-existing DangerZone component, which already calls useQuery after an early if (!dataProvider) return null (a latent hooks-order issue, out of scope here, but worth fixing at some point since this PR shows a good template for it).
  • The TODO comment on createConnectionTokenMutationOptions clearly explains why raw fetch is used instead of the generated RivetClient/fetcher, and what to do once the SDK adds support. Good practice per repo conventions — consider filing this in ~/.agents/todo/ so it isn't lost.
  • The unrelated formatting cleanup of the fetcher(...) call at the top of cloud-data-provider.tsx is a harmless drive-by change but unrelated to this PR's feature; could be split out, though not blocking.

Potential Issues

  • createConnectionTokenMutationOptions bypasses the shared fetcher/RivetClient wrapper (no maxRetries, no shared header stripping), so this call behaves slightly differently from every other cloud-data-provider request (e.g. no retry on transient failure). Presumably intentional/unavoidable given the SDK gap, but worth being aware of since a flaky network blip surfaces immediately as an error here while other calls get one retry.
  • The response is cast with as { token: string; expiresAt?: string } without runtime validation. This matches existing conventions elsewhere in the file (e.g. t.token as string), so it's consistent, but if the endpoint's shape drifts, data.token could silently be undefined and render an empty DiscreteInput.
  • Error display uses error.message directly (e.g. Failed to issue connection token. ${error.message}), which for the crafted !response.ok case is a clean Failed to issue connection token (<status>), but for network-level failures will surface a raw browser error string (e.g. "Failed to fetch"). Minor UX inconsistency, not a bug.

Security

  • Uses credentials: "include" with encodeURIComponent on all path segments (project/namespace/organization), consistent with how the rest of the cloud data provider talks to cloud-api. No injection or credential-handling concerns beyond what's already established in this file.

Test Coverage

  • No tests were added for the new mutation option or ConnectionTokens component. Given this is a dashboard UI change, manual verification across OSS/cloud flavors (per features.auth gating) is worth doing before merge, in particular exercising the namespace-switch scenario described above.

Overall this is a small, well-scoped addition that follows existing patterns in the file closely. The main thing worth addressing before merge is the stale-token-across-namespace-switch issue, since it directly affects the token displayed to the user.

@abcxff
abcxff changed the base branch from stack/feat-dashboard-allow-typing-cpu-value-in-compute-tab-wzzxwskk to main July 15, 2026 15:40
@abcxff
abcxff merged commit b2ba482 into main Jul 15, 2026
8 of 11 checks passed
@abcxff
abcxff deleted the stack/feat-dashboard-add-connection-token-issuing-ui-oolwqlys branch July 15, 2026 15:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant