Skip to content

fix: say private for every route keyed per caller under scope public - #262

Merged
derrickmehaffy merged 2 commits into
mainfrom
fix/cache-control-useauth-truthy
Oct 13, 2026
Merged

derrickmehaffy merged 2 commits into
mainfrom
fix/cache-control-useauth-truthy

Conversation

@derrickmehaffy

Copy link
Copy Markdown
Contributor

What changed and why

With cacheControl.scope: "public", the plugin downgrades routes whose entries are keyed per caller (keys.useAuth) to private. A shared cache told those responses are public could hand one caller's response to another (#113).

The downgrade checked keys.useAuth === true. The key generator (generateCacheKey.ts) puts the caller in the key for any truthy useAuth. A raw string, which is what useAuth: env("X") without env.bool gives, therefore:

  • keyed entries per caller;
  • still went out public, so a CDN or proxy could serve one caller's response to another.

Reproduced with category's useAuth set to the string "true" and scope public: both the MISS and the HIT carried public, max-age=3600 on a route keyed per caller.

Fix: the downgrade in buildCacheControl.ts, and its boot warning in resolveUserStrategy.ts, now test truthiness, matching the key generator.

Non-breaking:

  • Only configurations with a truthy non-boolean useAuth under scope public change, and only from public to private, which is safer.
  • Boolean true/false configs, keys, and what's cached are unchanged.

Found by the audit of #259, which aligns the "Shared across callers" badge and warning the same way.

Tests

  • New cacheControl: scope public, useAuth set to a truthy non-boolean block in shared/tests/flag-cache-control.test.js, using an opt-in CATEGORY_USE_AUTH_RAW fixture switch:
    • On main: Expected "private, max-age=3600", Received "public, max-age=3600".
    • With the fix: passes.
  • The existing public-scope tests are unchanged and still pass (11/11). The full memory suite passes (136/136), and test:lint is green.

Checklist

  • Tests added. A spec that fails before the change.
  • pnpm run test:e2e:memory passes.
  • pnpm run test:lint passes.
  • Conventional commit subjects, branched from main.

With `cacheControl.scope: "public"`, routes keyed per caller are downgraded
to private, because a shared cache told their responses are public could
hand one caller's response to another. The check compared
`keys.useAuth === true`, while the key generator puts the caller in the key
for any truthy useAuth. A raw string - `useAuth: env("X")` without
env.bool - therefore keyed entries per caller and still went out public.

The downgrade and its boot warning now use truthiness, as the key generator
does. Only configurations with a truthy non-boolean useAuth under scope
public change, and only from public to private.
@derrickmehaffy
derrickmehaffy merged commit 62a0799 into main Oct 13, 2026
13 checks passed
@derrickmehaffy
derrickmehaffy deleted the fix/cache-control-useauth-truthy branch October 13, 2026 05:42
@github-actions github-actions Bot mentioned this pull request Oct 13, 2026
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