Skip to content

feat(cloud-ui): org credentials tab + connect-link invite flow (#11332) - #11488

Merged
lalalune merged 4 commits into
developfrom
nubs/team-credential-pool-ui
Jul 2, 2026
Merged

feat(cloud-ui): org credentials tab + connect-link invite flow (#11332)#11488
lalalune merged 4 commits into
developfrom
nubs/team-credential-pool-ui

Conversation

@NubsCarson

Copy link
Copy Markdown
Member

Part of #11332Phase 1 of team credential pooling (frontend): the Credentials tab and the shareable connect-link invite flow. Backend routes land in the companion PR #11487; this branch is UI-only and merge-independent, but the tab needs those endpoints to serve live data.

what

  • Credentials tab beside Members in Settings → Organization: masked pooled-credential rows (label, provider badge, ••••last4, health dot with rate-limited-until, calls today, contributor with "(you)" marker, last-used). Owner/admin get the enable toggle and delete-any; a contributor can delete their own key; every member can view and contribute. Mirrors the route-level RBAC exactly.
  • Contribute modal: provider select (the 6 Phase-1 direct-API providers only — subscription providers are never rendered), password-masked key input, live-probe failures rendered inline, and a confirmation step showing the masked last4 only — the plaintext never comes back from the API and is never rendered after the masked input.
  • Connect link: the invite dialog now shows the copyable accept link (/invite/accept?token=…) after creation, with an optional connect=1 intent from the Credentials tab's "Invite & Connect". The accept page preserves the intent through the login round-trip and routes straight to dashboard/organization?tab=credentials&contribute=1 — the teammate lands with the contribute modal open. The link carries only the expiring hashed-token invite, no secrets; joining still requires an authenticated session.
  • DTO contract types (PooledCredentialDto etc.) mirror the backend summaries, including epoch-ms health/usage timestamps.

evidence

  • bunx vitest run src/cloud/organization/credentials-tab.test.tsx src/cloud/organization/connect-link.test.tsx11 pass / 0 fail (2 files): masked rows (health dot states, rate-limited-until copy, no key material beyond last4 anywhere in the DOM), RBAC gating per role (member sees no toggles, keeps own delete), PATCH on toggle + DELETE after confirm with exact request assertions, contribute happy path asserting the plaintext is not rendered on the confirmation step, inline probe-failure path, invite-link build/copy, and the ?tab=credentials&contribute=1 landing intent.
  • bun run typecheck clean in packages/ui; biome clean.

billing

Pooled-key usage is zero-rated (nubs decision) — no credit decrement, no fee; the org pays the provider directly. The "future monetization" options are documented (not implemented) in packages/cloud/shared/docs/team-credential-pooling.md in the backend PR.

credentials tab beside members: masked pooled-credential rows (label,
provider badge, last4, health dot w/ rate-limit until, calls today,
contributor), owner/admin enable toggle + delete (contributor can delete
own), member-readable list. contribute modal live-probes via POST and
confirms with the masked last4 only — the plaintext never comes back from
the api and is never rendered after the password-masked input. invite
dialog surfaces the copyable accept link (token echoed once at creation)
with connect=1 intent; accept page routes connect=1 straight to the
credentials tab with the contribute modal open. component tests cover
masked rows, rbac gating, probe-fail, no-plaintext confirmation, and the
connect-link intent.
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8be0d56b-e622-4ab8-a1f8-3e5696926387

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch nubs/team-credential-pool-ui

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

lalalune added a commit that referenced this pull request Jul 2, 2026
…es (#11565)

A fresh SIWE/wallet signup created its own organization but landed as a
plain 'member' (the users.role schema default) — unable to invite
teammates, manage members, or manage the org credential pool in an org
where they are the only human. The anonymous-migration path (session.ts)
already sets 'owner'; align the EVM and Solana wallet paths.

Surfaced live by the #11488 credentials-tab visual e2e (owner-gated
controls missing for a fresh SIWE user driving their own org).

Real-PGlite tests pin both paths + the returning-user path.

Co-authored-by: Shaw <shawgotbags@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Shaw and others added 2 commits July 2, 2026 16:27
…real pixels (#11332)

- run-credentials-e2e.mjs: boots the real mock cloud stack (Hono + PGlite +
  MOCK_REDIS) with a local provider stub as the live key-probe target, mints
  a real key via headless SIWE, compiles the real Tailwind stylesheet,
  bundles the real CredentialsTab fixture, and drives empty state →
  contribute (probe FAIL → probe PASS) → masked row → toggle → invite &
  connect link → connect-link landing → remove, desktop + mobile, with
  aesthetic gates on computed styles. 11/11 assertions green; screenshots +
  video under .github/issue-evidence/11332-credentials-tab-e2e/.
- copy fix: pooled-success dialog no longer claims 'nobody can read it back'
  (pooled keys reach member agent containers by design) — now says it's
  never shown again in the dashboard.

Notes for follow-up (flagged on tracking issues): BrandButton primary's
designed hover is bg-accent→bg-background (tension with the darker-orange
hover rule); RATE_LIMIT_MULTIPLIER is a dead knob on the hono-cloudflare
limiter path (harness uses RATE_LIMIT_DISABLED instead).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@lalalune

lalalune commented Jul 2, 2026

Copy link
Copy Markdown
Member

Rendered evidence + finishing commits (maintainer pass)

Landed on this branch:

  1. Copy fix — the pooled-success dialog no longer claims "Nobody — including you — can read it back" (pooled keys reach member agent containers by design, per the backend review); it now says the key is never shown again in the dashboard.
  2. Real-pixel visual e2e (packages/ui/src/cloud/organization/__e2e__/run-credentials-e2e.mjs) — boots the real mock cloud stack (Hono graph + PGlite + MOCK_REDIS) with a local provider stub as the live key-probe target, mints a real key via headless SIWE, compiles the real Tailwind stylesheet over the component sources, and drives the REAL CredentialsTab in headless Chromium. 11/11 assertions green, desktop + mobile, screenshots + video committed under .github/issue-evidence/11332-credentials-tab-e2e/.

It also surfaced and got fixed two real backend bugs along the way: fresh wallet-signup users weren't owners of their own org (#11565, merged), and RATE_LIMIT_MULTIPLIER is a dead knob on the hono-cloudflare limiter path (harness uses the RATE_LIMIT_DISABLED dev escape hatch; flagged for follow-up).

Walkthrough

Empty state empty
Contribute — live probe FAILURE renders inline probe-fail
Contribute — pooled (masked, fixed copy) pooled
Masked list row (••••last4, ANTHROPIC, you) row
Owner toggle → disabled disabled
Invite & connect — copyable connect=1 link, no secrets invite
Connect-link landing (?contribute=1 auto-opens modal) landing
Mobile row + contribute mobile
Remove confirm → server confirms empty pool remove

Video: walkthrough.webm

Aesthetic gates asserted on computed styles: no blue anywhere, primary button orange at rest; note — BrandButton primary's designed hover is bg-accent → bg-background (system-wide cloud-ui inversion, pre-existing), flagged on #11342 for the design pass vs the darker-orange-hover rule.

🤖 Generated with Claude Code

@lalalune
lalalune merged commit 82001b0 into develop Jul 2, 2026
36 of 62 checks passed
@lalalune
lalalune deleted the nubs/team-credential-pool-ui branch July 2, 2026 21:01
lalalune pushed a commit that referenced this pull request Jul 2, 2026
…s + frontend-hosting

The ui-e2e-runner-coverage ratchet was red on develop: run-credentials-e2e.mjs
(#11488 org credentials tab) and run-frontend-hosting-e2e.mjs (#10690/#11425
hosting work) landed with no packages/ui package.json script and no CI leg,
so they could only run by hand. Add test:credentials-e2e and
test:frontend-hosting-e2e scripts and matching ui-e2e-gate.yml legs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
lalalune added a commit that referenced this pull request Jul 2, 2026
…s + frontend-hosting (#11646)

The ui-e2e-runner-coverage ratchet was red on develop: run-credentials-e2e.mjs
(#11488 org credentials tab) and run-frontend-hosting-e2e.mjs (#10690/#11425
hosting work) landed with no packages/ui package.json script and no CI leg,
so they could only run by hand. Add test:credentials-e2e and
test:frontend-hosting-e2e scripts and matching ui-e2e-gate.yml legs.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error —— View job


I'll analyze this and get back to you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants