Skip to content

Keep signed image links of projects, accounts and avatars off disk - #48

Merged
TeoVader merged 1 commit into
mainfrom
fix/dont-persist-signed-images
Nov 11, 2026
Merged

TeoVader merged 1 commit into
mainfrom
fix/dont-persist-signed-images

Conversation

@TeoVader

Copy link
Copy Markdown
Owner

What changes

Before: after #47 the API cache (cache/api) still held signed links: the Home list (workspaces and projects) kept each project's and workspace's image, the accounts list each account's image, and project owners, asset creators, me and remembered guest comment authors their avatar_url. Frame.io says these links must not be stored.

After: no signed image link is written to disk. A Home opened offline shows the project covers, account badges and avatars the image cache already has (by a stable key), else the gradient/latest-file cover and the initials as before; the next refresh brings fresh links. Nothing changes on screen.

How

  • DiskScrub drops every image / avatar_url string and writes image_key / avatar_key in its place: linkImageKey(url), a SHA-256 of the link without its query string (so nothing link-shaped is stored, and it stays the same across signatures).
  • Account, Workspace, Project get imageKey + imageRef, User gets avatarKey + avatar (an ImageRef: link when in memory, key only from disk). Home cards, the project sheet, the account badge and Avatar use them.
  • stableImageKey (the Coil memory/disk cache key) is now linkImageKey, so the key on disk matches the image cache. Existing cached images get a new key once (one refetch).
  • The one-time legacy scrub marker is renamed (api.links-scrubbed.2) so files written by earlier versions are scrubbed again.
  • Guest comment authors read from disk have no avatar link, so they count as expired and are looked up once per session (as when a link expired before).

Other storage checked: DataStore/SharedPreferences (settings, upload destination), watch.json, transfer and folder-job files hold no image links. Coil's disk cache stores the image bytes under the hashed key, not the URL. Not in scope: the presigned upload part URLs kept to resume an upload (UploadItem.partUrls), which aren't media links.

Tests: DiskScrubTest covers the Home list, accounts and authors on disk (no Signature/Expires=), cache reads giving image = null with the right key, idempotence and the re-scrub of legacy files; GuestAuthorsTest is updated for the key-only disk copy.

Checks

  • ./gradlew :app:verifyRoborazziDebug :app:lintDebug passes (lint at 0) — unit tests and lint run on the workstation; Roborazzi left to CI (Linux baselines)
  • New or changed UI has a Roborazzi screenshot — no UI change
  • Tried on a phone (if it touches playback, uploads or permissions) — n/a

🤖 Generated with Claude Code

The API cache still wrote project, workspace and account images and user
avatars (signed links) to cache/api. DiskScrub now drops them and keeps a
hash of the unsigned path (image_key / avatar_key), which is also the image
cache key: a copy read from disk shows the cached picture or the initials,
and the next refresh brings a fresh link. The one-time legacy scrub runs
again for files written before. Guest authors read from disk are looked up
again, since their avatar link is no longer kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@TeoVader
TeoVader merged commit 78110c4 into main Nov 11, 2026
2 checks passed
@TeoVader
TeoVader deleted the fix/dont-persist-signed-images branch November 11, 2026 22:08
TeoVader added a commit that referenced this pull request Nov 11, 2026
Keep the stateless ProjectMenuContent and take the project's cover from
Project.imageRef (#48).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant