Public: anyone can read this; the crew can change it.
An app's pictures are shown only to those allowed to see what they show #728
Check · Review · Land · Live done — Landed and live in production.
Closes #727
shipped production is serving it deploy d5b2fe2
Closes #727 (trust umbrella #586; related #620, which covers live access to apps; this pull covers the stored pictures). Replaces #717 on the same branch, so the pull names its issue.
Who may fetch a picture (mayFetchLook in src/web/pages/looks.ts), by kind:
- Phone and desktop are still taken signed in as the owner, because a writer judges a change as the owner sees it. They go to writers only: the picture route answers 404 to anyone else, a pull's Look card is hidden from readers who cannot write, and the app's page shows a reader only the thumb. Existing owner-taken files need no retake, because the route already withholds them.
- Thumb is taken as nobody (#684). It goes to whoever may open the app: anyone, for a public-access app; a signed-in reader, for a private one. A thumb from before #684 (200 px wide, the owner's view) goes to writers only until the looks sweep retakes it.
- The front door applies the same rule, so a stranger never sees a tile for a picture they may not fetch.
Caching. A retake at the same commit used to keep the same URL, while the response said immutable for a year, so a browser could keep a replaced picture indefinitely. Every picture URL now carries ?v=<when this one was taken>. That versioned URL is the only one cached for good; the bare name answers private, no-cache.
The sweep no longer retakes a picture that failed at the current head; the next deploy tries again.
Tests (refusals written first). test/looks.test.ts joins the gate. On a public repository that hosts a private app:
- a stranger gets 404 for all three pictures, and the app's page shows none;
- a signed-in non-writer gets 404 for phone and desktop and 200 for the thumb;
- a writer gets 200 for all three.
With the app made public-access, a stranger gets the thumb but not an old 200 px owner-taken one, and a retake changes the URL. Local results: looks and board 32 pass, studio door tests 21 pass, tsc clean.
🤖 Generated with Claude Code
Closes #727
Replaces #717 (same branch), so the pull names its issue. Work in progress: the description follows when it is ready for review.
🤖 Generated with Claude Code