mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-20 09:09:35 +02:00
fix(web): serve the public JSON data files no-cache, not immutable
The static plugin gave every file under public/ a year of `immutable`, including the JSON the page fetches at runtime: whats-new.json (rewritten every release), the new security-notices.json (edited by hand) and manifest.json. None of them is content-hashed or `?v=`-busted, so a browser could keep last release's copy, and a security notice added in a later release might never reach it. A `.json` file now revalidates (`no-cache`); every other static asset keeps its immutable year, and a route that set its own Cache-Control still wins. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
0ab71d61d1
commit
ada2309721
2 files changed
+23
-2
No files matched your search
@@ -11,7 +11,8 @@
|
||||
*
|
||||
* That contract is load-bearing: assets are served `immutable` for a year, and
|
||||
* `index.html` must revalidate every time or a deploy leaves browsers on stale
|
||||
* markup (see `cacheBustAssets` in server.ts). No HTML is left behind the static
|
||||
* markup (see `cacheBustAssets` in server.ts). The JSON data files the page fetches at
|
||||
* runtime (whats-new.json, security-notices.json) revalidate too. No HTML is left behind the static
|
||||
* plugin (every page has its own route), so the HTML half is asserted on the route.
|
||||
*
|
||||
* These tests drive a REAL WebServer on purpose. Asserting against an inline
|
||||
@@ -73,6 +74,17 @@ describe('static asset Cache-Control headers', () => {
|
||||
expect(res.headers.get('cache-control')).toBe('no-cache, no-store');
|
||||
});
|
||||
|
||||
it('makes the runtime JSON data files revalidate instead of pinning them for a year', async () => {
|
||||
// whats-new.json is rewritten every release and security-notices.json by hand; neither is
|
||||
// content-hashed or `?v=`-busted, so an `immutable` copy could outlive the release that
|
||||
// replaced it, and a security notice added later would never reach that browser.
|
||||
for (const file of ['security-notices.json', 'whats-new.json', 'manifest.json']) {
|
||||
const res = await get(`${baseUrl}/${file}`);
|
||||
expect(res.status, file).toBe(200);
|
||||
expect(res.headers.get('cache-control'), file).toBe('no-cache');
|
||||
}
|
||||
});
|
||||
|
||||
it('serves the rendered index with no-cache too, via its own route', async () => {
|
||||
// Different code path from the above, same contract: index.html is generated per
|
||||
// request (cacheBustAssets stamps ?v= onto every asset ref), so caching it would
|
||||
|
||||
Reference in new issue
Block a user