fix(bitbucket): render private images in pull request descriptions#28596

open3
main
GitHub fork: fix/bitbucket-pr-images-upstream
opened9d agobySShpetimA
View on GitHubTwo-way sync enabledPR last imported 13h ago

Problem

Private Bitbucket Cloud images in pull request descriptions and comments fail to load even when the saved account can read the repository. The renderer requests them without a Bitbucket browser session.

Reproduce by embedding a private repository's Downloads or raw/src image URL in a PR description, then opening Summary → Description in T3 Code. The image should render through the server's existing credentials.

Fixes #19828.

Change

  • Recognize Bitbucket Cloud Downloads and repository file URLs, and map web links to the API endpoints that accept tokens.
  • Connect Bitbucket to the existing signed media driver API, using saved credentials or the existing environment fallback.
  • Keep credentials on the configured API origin. Follow bounded HTTPS redirects to signed storage without forwarding the token, and preserve range requests and streamed bytes.
  • Bound response-header waits with the existing API timeout while allowing the media body to stream afterward.

The fix stays in the Bitbucket package. Contracts, UI components, and GitHub handling remain unchanged.

Scope and approval

This addresses the existing Bitbucket image-loading defect documented in #19828 and its maintainer source triage. Credential handling still needs maintainer review; this does not claim prior implementation approval.

Related: #19853 covers private Downloads. This independent implementation covers repository images through raw/src links as well as Downloads and uses the current source-control driver API.

Verification

  • Added regression cases failed on unmodified main before the implementation.
  • 91 focused tests passed: URL recognition, filename handling, current saved credentials, byte streaming, range forwarding, credential-free storage redirects, unsafe targets, redirect limits, response-header timeout, and existing registry/asset behavior.
  • Bitbucket package type checking, targeted lint, formatting, and commit-hook checks passed.
  • Manually confirmed private images rendering in a local macOS fork build. The screenshot below comes from that check; identifying content is blurred. The current-main driver port uses the production Bitbucket service with a fake HTTP transport in tests. Live-account rendering of this port and native mobile clients were not rechecked.

Focused test command:

sh
1vp test run \
2 packages/source-control-bitbucket/src/shared/definition.test.ts \
3 packages/source-control-bitbucket/src/server/BitbucketApi.test.ts \
4 apps/server/src/sourceControl/sourceControlDefinitions.test.ts \
5 apps/server/src/assets/AssetAccess.test.ts

Screenshot

StateBeforeAfter
Private Bitbucket image in a PR descriptionNot captured; reproduction and failure are documented in #19828.Private Bitbucket image rendered; identifying content blurred

Implemented with GPT-6.1-Sol using the Codex harness in T3 Code.

Fixes pingdotgg/t3code#19828

Checks

21 successful · 8 skipped
All checks passed
a545684

Added 1 commit

  • fix(bitbucket): render private images in pull request descriptionsbb5d2f6
Synced from GitHub

Approvability

Verdict: Approved at bb5d2f6

Macroscope's review found this PR approvable — Private Bitbucket images now load through the existing authenticated media pipeline. Restricted source URLs, origin-scoped credentials and existing media-response protections keep the change bounded.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Review in Change Stack →

No actionable comments were generated in the recent review.

Walkthrough

The Bitbucket source-control definition now recognizes supported media URLs and maps them to API URLs. The server exposes a media-fetch operation that applies origin-scoped authentication, validates redirects, and enforces a timeout.

Changes: Bitbucket media fetching

Layer / File(s)Summary
Media URL mapping and registration
packages/source-control-bitbucket/src/shared/*
The shared handler validates Bitbucket source and download URLs, maps accepted URLs to API endpoints, and sanitizes filenames. The Bitbucket definition registers the handler. Tests cover accepted and rejected URLs and filename handling.
Server fetch and driver integration
packages/source-control-bitbucket/src/server/*
BitbucketApi.fetchMedia forwards only range headers, applies configured authentication only to the API origin, and validates redirects with a maximum of three hops. The driver exposes the operation. Tests cover credentials, redirects, unrelated URLs, and response-header timeout behavior.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Medium

Sequence Diagram(s)

mermaid
1sequenceDiagram
2 participant Driver as Source-control driver
3 participant Fetch as BitbucketApi.fetchMedia
4 participant API as Configured Bitbucket API origin
5 participant Storage as Redirected storage URL
6 Driver->>Fetch: Send media request
7 Fetch->>API: Fetch with configured authentication and range headers
8 API-->>Fetch: Return redirect location
9 Fetch->>Storage: Fetch without API credentials
10 Storage-->>Fetch: Return media response
11 Fetch-->>Driver: Return response or null

Possibly related issues

Suggested reviewers: juliusmarminge, only21mil

Merge Risk: External image Minimal · up to bb5d2

The reviewed changes are ready to merge after normal checks; no concrete issue remains that requires a fix before merge.

Pre-merge checks: Passed 4

Check nameStatusExplanation
Title checkPassedThe title clearly describes the primary change: fixing private Bitbucket images in pull request descriptions.
Linked Issues checkPassedIssue #19828 requires the server to fetch private Bitbucket Cloud media with Bitbucket credentials, follow the signed-storage redirect, stream the bytes, and limit handling to Bitbucket hosts. The rev…
Out of Scope Changes checkPassedThe changed files are in packages/source-control-bitbucket:
- src/shared/bitbucketMedia.ts (new): URL recognition, API endpoint mapping, and filename derivation.
- src/shared/definition.ts: wire…
Description checkPassedThe description includes the required Problem, Change, Scope and approval, and Verification sections. It links the issue and maintainer source triage, describes the changes, and reports focused tests …
Full details: Linked Issues check

Explanation

Issue #19828 requires the server to fetch private Bitbucket Cloud media with Bitbucket credentials, follow the signed-storage redirect, stream the bytes, and limit handling to Bitbucket hosts. The reviewed head covers each point:

  • URL mapping: bitbucketMediaUrl in packages/source-control-bitbucket/src/shared/bitbucketMedia.ts accepts bitbucket.org, www.bitbucket.org, and api.bitbucket.org only, over HTTPS without credentials or port. It maps web Downloads and raw/src links, and API Downloads and src links, to https://api.bitbucket.org/2.0/repositories/{ws}/{repo}/downloads|src/....
  • Registration: definition.ts sets mediaUrl to this function. The core contract in packages/source-control-core/src/shared/definition.ts says a client asks the server for media that a host keeps behind a credential, and the host's driver fetches it. This is the generic path that the issue's github-media diagnosis describes.
  • Credentials and redirects: per the summary and the test list in BitbucketApi.test.ts, BitbucketApi.fetchMedia sends saved or environment credentials only to the configured API origin. It does not forward them to redirected storage URLs. It follows at most three bounded HTTPS redirects, rejects credential-bearing or non-HTTPS targets, and forwards only range and if-range.
  • Streaming: the response-header wait uses the existing API timeout, and the body streams afterward. Tests cover byte streaming and range forwarding.

Residual uncertainty: this review did not read the renderer dispatch code (ChatMarkdown) at head. The PR-level claim that the renderer routes Bitbucket images through mediaUrl rests on the core contract comment and the PR summary. Live-account rendering was not rechecked, and the issue's line references describe an earlier main. The author reports these checks, so they do not block this verdict.

Full details: Out of Scope Changes check

Explanation

The changed files are in packages/source-control-bitbucket:

  • src/shared/bitbucketMedia.ts (new): URL recognition, API endpoint mapping, and filename derivation.
  • src/shared/definition.ts: wires bitbucketMediaUrl into the definition's mediaUrl handler.
  • src/server/BitbucketApi.ts: adds the scoped fetchMedia operation.
  • src/server/driver.ts: exposes fetchMedia from makeInstance.
  • src/shared/definition.test.ts and src/server/BitbucketApi.test.ts: regression tests for these behaviors.

Each change maps to the #19828 objectives: URL mapping, credentialed fetch, redirect handling, and streaming. The PR description states that contracts, UI components, and GitHub handling are unchanged. The reviewed evidence does not show unrelated edits. The test command also names apps/server test files; the summary lists no change to them, so they only verify existing behavior. No out-of-scope change is demonstrated.

Full details: Description check

Explanation

The description includes the required Problem, Change, Scope and approval, and Verification sections. It links the issue and maintainer source triage, describes the changes, and reports focused tests and their limits. It also states that credential handling still needs maintainer review.

Finishing Touches

Generate unit tests (beta)

  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
External image Recent review info

External image Run configuration

External image Commits

Reviewing files that changed from the base of the PR and between b50d8a1b15eed3a75e1e0969765e14c6436d80d7 and bb5d2f6ea5d612411718ceadf293c922722b4f46.

External image Files selected for processing: 6

  • packages/source-control-bitbucket/src/server/BitbucketApi.test.ts
  • packages/source-control-bitbucket/src/server/BitbucketApi.ts
  • packages/source-control-bitbucket/src/server/driver.ts
  • packages/source-control-bitbucket/src/shared/bitbucketMedia.ts
  • packages/source-control-bitbucket/src/shared/definition.test.ts
  • packages/source-control-bitbucket/src/shared/definition.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Added 2 commits

  • Merge branch 'main' into fix/bitbucket-pr-images-upstream2662cf1
  • Merge remote-tracking branch 'github/main' into fix/bitbucket-pr-images-upstreama545684