Skip to content

fix(web): verify pull request snapshots before hydration - #6470

Open
Adamulek123 wants to merge 3 commits into
pingdotgg:mainfrom
Adamulek123:t3code/pr-snapshot-safety
Open

fix(web): verify pull request snapshots before hydration#6470
Adamulek123 wants to merge 3 commits into
pingdotgg:mainfrom
Adamulek123:t3code/pr-snapshot-safety

Conversation

@Adamulek123

@Adamulek123 Adamulek123 commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

What Changed

Persisted pull request rows now carry a short expiration and are hydrated only after a lightweight server read freshly verifies the signed-in account for every host. The identity read is separate from the repository listing, so safe snapshots can still render while the slower live list is loading.

Why

Snapshots were scoped only by environment IDs. Switching a host CLI to another account could therefore briefly expose the previous account's pull requests, and an offline host could retain old rows indefinitely. Waiting for the full list would prevent the leak but also defeat early hydration, so account verification now has its own focused RPC.

UI Changes

No visual design changes. The loading behavior is unchanged for a valid, recent snapshot; expired or differently owned snapshots fall back to the existing loading state.

Validation

  • vp test run apps/server/src/pullRequest/PullRequestService.test.ts apps/web/src/components/pullRequest/pullRequestList.logic.test.ts packages/contracts/src/pullRequest.test.ts apps/server/src/auth/RpcAuthorization.test.ts (209 tests passed)
  • vp run --filter @t3tools/contracts typecheck
  • vp run --filter @t3tools/client-runtime typecheck
  • vp run --filter t3 typecheck
  • vp run --filter @t3tools/web typecheck

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • No visual UI change requires before/after screenshots
  • No animation or interaction change requires a video

Generated with GPT-5.6 in the Codex harness.


Note

Medium Risk
Touches account-scoped data hydration and a new RPC path, but changes are narrow, read-only for viewers, and covered by server and web snapshot tests.

Overview
Adds pullRequests.viewers, a read-scoped RPC that returns the current signed-in account per host without waiting on the full PR listing. The server resolves viewers with fresh: true so cached CLI identity cannot authorize hydration after an out-of-band gh auth switch.

Local list snapshots now store writtenAt and readPullRequestListSnapshot rejects them when they are older than five minutes, in the future, or their stored viewers map does not match the freshly fetched identities. The pull-requests route calls usePullRequestViewers and only hydrates from localStorage once that query settles.

Legacy project refinement also honors optional projectIds on viewer (and list) scoping so unrelated unknown-provider worktrees are not refined.

Reviewed by Cursor Bugbot for commit 1a73c27. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Verify pull request snapshots against viewer identity and age before hydration

  • Adds a new pullRequests.viewers RPC (contracts, server, client runtime) that returns fresh per-host viewer identities for a scoped set of projects.
  • readPullRequestListSnapshot now rejects snapshots that are older than 5 minutes or whose stored viewer identities don't match the current host accounts, preventing cross-account data leakage.
  • writePullRequestListSnapshot records a writtenAt timestamp so snapshots can be age-validated on read.
  • The pull requests route fetches viewer identities before hydrating any persisted snapshot, waiting until identity is known.
  • Behavioral Change: existing snapshots lacking writtenAt or viewer identity will be rejected and the list will cold-load on first visit after deploy.

Macroscope summarized 1a73c27.

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown

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: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c2ce59a5-2c30-4175-ba5f-1cd7d125d0b2

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

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.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 13, 2026
Comment thread apps/server/src/pullRequest/PullRequestService.ts
@macroscopeapp

macroscopeapp Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR adds security verification for pull request snapshots, touching authorization code and introducing a new RPC endpoint. Changes with authentication/security implications warrant human review.

You can customize Macroscope's approvability policy. Learn more.

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

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant