Retire the v2 API cache, bound candidate offers, deflake link leak tests
CI / ci (push) Successful in 2m46s
CI / ci (pull_request) Successful in 2m51s

- Bump the service worker API cache to v3 so activation deletes the v2
  cache, whose recipe-candidate responses used the full page URL as
  candidate_id; test that activation deletes v1 and v2 and keeps v3.
- Give candidate offers a 30-minute lifetime, drop expired offers when
  new ones are stored, and clear a dinner's offers on every hand
  grounding (candidate, link or manual) and on archive. A candidate
  search still running when its dinner is cleared stores nothing, so a
  stale candidate_id gets the same 400 as an unknown one.
- Make the link leak assertions in TestDinnerResponsesHideTokenInLinkPath
  and TestCreateRegularNeverNamesFromLink check phrases a ULID cannot
  contain, so a dinner id holding "KEY" no longer fails them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-06 22:35:30 -04:00
co-authored by Claude Opus 5.5
parent db6f39cdb9
commit 515919088a
9 changed files with 301 additions and 36 deletions
+5 -4
View File
@@ -147,12 +147,13 @@ describe('cache names', () => {
for (const name of Object.values(cacheNames)) expect(name).toMatch(/^mealquest-/)
})
it('retire only the v1 API cache', () => {
// v1 API responses held dinners with the pasted recipe_url, which can
// carry a personal token; offline, the worker would still serve them.
it('retire only the v1 and v2 API caches', () => {
// v1 API responses held dinners with the pasted recipe_url and v2 ones
// recipe candidates whose candidate_id was the full URL; either can carry
// a personal token, and offline the worker would still serve them.
// The precache, photos and fonts keep their v1 caches.
expect(cacheNames).toEqual({
api: 'mealquest-api-v2',
api: 'mealquest-api-v3',
media: 'mealquest-media-v1',
fonts: 'mealquest-fonts-v1',
})