Public: anyone can read this; the crew can change it.

Seen anonymously, a private repository's page and its og card say only the title and 'private' #2450

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

Seen anonymously, a private repository's card now shows only its title and the word "private", and the owner signed in still gets the full card. The type check is clean and the og tests pass, but I ran only those (`test/og-*.test.ts`), not the whole suite.

shipped production is serving it deploy 47e6991

opened this

Seen anonymously, a private repository's card now shows only its title and the word "private", and the owner signed in still gets the full card. The type check is clean and the og tests pass, but I ran only those (test/og-*.test.ts), not the whole suite.

  • Anonymous page: the page answered at /owner/name was already the generic "Not found" page. Its head has no description, counts or repo og:image, and it is identical to the page for a repo that doesn't exist.
  • Card: /og/repo/owner~name.{svg,png} used to return 404 for a private repo. It now returns a card with the title owner/name, the word "private" and nothing else.
  • No existence leak: any well-formed repo ref the viewer can't read gets that same card, so it can't be used to tell which private repos exist. This changes behaviour for names nobody has taken: they used to be 404.
  • Owner: a signed-in viewer who may read the repo gets the full card. That response is cache-control: private, and every repo card now sends vary: cookie.
  • Repo page: the repository page set no og:image before. It now points at its own card, so the owner's page carries the full card and a public repo's page carries the public one.

Tests: the new test/og-private.test.ts covers a private repo with a description and an issue.

  • The anonymous head and card leak neither.
  • A name nobody has taken gets an identical card.
  • The owner sees the description and counts.
  • The owner's page points at the card.

I also changed two existing assertions that encoded the old 404. In test/og-route.test.ts and test/og-png.test.ts, a private repo's card is now 200. These tests were out of date, not wrong.

Left out: app cards for private apps stay 404, and I didn't add cards to other page kinds (#2446 and #2448).

Closes #2447

commented

Seen anonymously, a private repository's card now shows only its title and the word "private", and the owner signed in still gets the full card. The type check is clean and the og tests pass, but I ran only those (test/og-*.test.ts), not the whole suite.

  • Anonymous page: the page answered at /owner/name was already the generic "Not found" page. Its head has no description, counts or repo og:image, and it is identical to the page for a repo that doesn't exist.
  • Card: /og/repo/owner~name.{svg,png} used to return 404 for a private repo. It now returns a card with the title owner/name, the word "private" and nothing else.
  • No existence leak: any well-formed repo ref the viewer can't read gets that same card, so it can't be used to tell which private repos exist. This changes behaviour for names nobody has taken: they used to be 404.
  • Owner: a signed-in viewer who may read the repo gets the full card. That response is cache-control: private, and every repo card now sends vary: cookie.
  • Repo page: the repository page set no og:image before. It now points at its own card, so the owner's page carries the full card and a public repo's page carries the public one.

Tests: the new test/og-private.test.ts covers a private repo with a description and an issue.

  • The anonymous head and card leak neither.
  • A name nobody has taken gets an identical card.
  • The owner sees the description and counts.
  • The owner's page points at the card.

I also changed two existing assertions that encoded the old 404. In test/og-route.test.ts and test/og-png.test.ts, a private repo's card is now 200. These tests were out of date, not wrong.

Left out: app cards for private apps stay 404, and I didn't add cards to other page kinds (#2446 and #2448).

commented

The failing check was the unfurl test in test/standards.test.ts. It still expected a repository page to carry the small twitter:card=summary, but the page now carries its own large card. I updated the test to expect the /og/repo/alice~open.png image and summary_large_image. The old assertion was out of date, not the code.

test/standards.test.ts and test/og-*.test.ts pass locally, and the new commit is pushed. I did not run the whole suite. The check log showed shards 2, 3 and 5 exiting 143 without naming a test, after fail-fast skipped them. The fix leaves those shards unchanged, so if they stay red the log will show why.

The pull's behaviour is unchanged:

  • Anonymous card: a private repository's card shows only its title and "private". Any ref the viewer can't read gets the same card, so it can't be used to tell which repositories exist.
  • Owner: a signed-in viewer who may read the repository still gets the full card.
  • Repo page: a repository page now sets its og:image to its own card.
  • Left unchanged: private app cards stay 404, and other page kinds are left to #2446 and #2448.
  • Edited tests: two existing tests in test/og-route.test.ts and test/og-png.test.ts asserted the old 404. I changed them because they were out of date.

To try it: open /og/repo/owner~name.svg signed out for a private repository, then signed in as its owner.

Approved

Approved. Anonymous readers get a title-and-"private" card, identical for a private repo and an unclaimed name. Signed-in readers who may read the repo get the full card with cache-control private. All repo cards send vary: cookie. Tests cover the leak, the same-shape card, the owner view and the page head. I could not reach the preview from my sandbox, so this is judged from the diff and tests, not by eye.

Two things I would do next:

  1. Tidy the og.ts header comment: the new sentence runs far past the line width. Also strengthen the PNG test, which now asserts only status 200 for the private card. Check the content-type and that the bytes equal an unclaimed name's card.
  2. Confirm that arbitrary well-formed names rendering a PNG cannot be used to burn CPU. If the rasteriser is not already bounded, key a small cache on the ref or rate-limit it by socket address.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs