Skip to content

fix(contributions): downloadUrl reaches a member only through the grant (#908) - #926

Merged
obrien-k merged 2 commits into
mainfrom
fix/908-download-url-reads
Oct 3, 2026
Merged

obrien-k merged 2 commits into
mainfrom
fix/908-download-url-reads

Conversation

@obrien-k

@obrien-k obrien-k commented Oct 3, 2026

Copy link
Copy Markdown
Member

Closes #908. The grill outcome is on the issue.

The leak

GET /communities/{id}/releases/{releaseId}/contributions sent every release reader each contribution's downloadUrl. A direct API caller could skip POST /contributions/{id}/access, and with it the canDownload check and the debit. The ui never read the field there.

The change

  • The list drops downloadUrl from its select, for every reader. feat(reports): a report opens the release it concerns, for reports_manage (ADR-0055) #905's reportScoped ? '' : … blank goes too: there's nothing left to blank.
  • The contract:
    • ReleaseContributionDetail drops the field.
    • ReleaseContribution (the release detail's contributions[]) and Contribution drop it too. Both declared it as required, but their reads never sent it.
    • GET /contributions, the uploader's own uploads and the only list that sends the field, now declares the new OwnContribution (= Contribution + downloadUrl).
  • contributionDownloadUrl.spec.ts: a source scan that counts, per file, the three ways a query comes back holding the URL: a downloadUrl: true select, a contribution call with no select, and a whole-row include. The counts are checked against an allowlist where each entry has its reason.
  • Docs: a Download Grant term in CONTEXT.md, an ADR-0055 amendment, and a CHANGELOG entry under ### Changed. feat(reports): a report opens the release it concerns, for reports_manage (ADR-0055) #905's unreleased entry is corrected in place.

A fact that came up while building. The grill assumed POST /contributions returned the URL to the uploader. It doesn't: contributionSelect never selects it. So the split is the inverse of the one described: Contribution loses the field, and OwnContribution adds it for the one read that sends it. The agreed principle, that a schema declares only what its read sends, is unchanged.

Verification

  • New integration test: a consumer of the release's community gets no downloadUrl key. It fails on main, where it received https://example.com/kob.torrent.
  • Re-planting the leak (downloadUrl: true back in the list's select) is caught by the scan spec.
  • Integration files: releaseWorkbench, reportScopedRelease and ratioExemptReads pass (18 tests).
  • Full unit suite: 3,709 tests pass. Lint, tsc, typecheck:test, openapi:completeness, openapi:failure-coverage and changelog:check are clean.
  • ui types, generated from this branch's openapi.json before merging: OwnContribution comes out as Contribution & { downloadUrl: string }, and ui tsc reports exactly two errors. Both are listed on stellar-ui#478, the follow-up.

Filed from the grill

🤖 Generated with Claude Code

…nt (#908)

The release contributions list sent every reader each contribution's URL,
so a direct API caller could skip POST /contributions/:id/access and its
debit. The list drops the field for every reader, and #905's report-scoped
blank goes with it.

The contract stops declaring downloadUrl on ReleaseContributionDetail,
ReleaseContribution and Contribution; the last two never sent it. The
uploader's own GET /contributions keeps it, as the new OwnContribution.

contributionDownloadUrl.spec.ts counts, per file, every query that comes
back holding the URL against a reasoned allowlist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codacy-production

codacy-production Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 47 complexity

Metric Results
Complexity 47

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

…mplexity limit (#908)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@obrien-k
obrien-k merged commit 1a6963d into main Oct 3, 2026
6 checks passed
@obrien-k
obrien-k deleted the fix/908-download-url-reads branch October 3, 2026 21:34
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.

fix(contributions): the release contributions list hands members downloadUrl without the grant's debit

1 participant