fix(webui): defuse scaffold config traps, tighten inline guards

Micro-fix from re-review:

1. webui/components.json: deleted the font/iconLibrary keys instead of
   picking a value. Re-review checked shadcn-vue's actual parse schema
   (node_modules/shadcn-vue/dist/schema/index.js's rawConfigSchema):
   both fields are z.string().optional(), not an enum - the five-choice
   enum lives only on the init CLI's --font/--icon-library flags, not on
   the components.json schema. The previous commit's "schema forbids a
   fix" rationale was wrong; corrected here. Verified empirically, not
   just by reading the schema: ran a real `npx shadcn-vue add badge -o
   -y` against components.json with both keys removed - src/assets/
   main.css came back byte-for-byte unchanged (previously this exact
   class of call re-added a Google Fonts import and the .dark-class
   toggle). That same run did still re-add @lucide/vue to package.json's
   dependencies (some components' registry entries list an icon package
   regardless of iconLibrary) - reverted before committing, and
   webui/README.md's warning section rewritten to explain the omission
   (so nobody "helpfully" restores the keys), fix the schema claim, and
   note the narrower remaining package.json trap.

2. admin.go:27-28: adminCSP's doc comment now names all three set-sites
   (GET /admin, every GET /admin/assets/*, the three JSON routes) -
   previously only mentioned the page and JSON routes, dropped after the
   asset route gained the same header in the prior fix round.

3. Both inline-script guards (webui/generate.mjs's assertNoInlineAssets,
   admin_test.go's hasInlineScript) tightened from a bare \bsrc\s*=
   pattern to (^|\s)src\s*= - \b alone matches inside "data-src=" too
   (the "-" before "src" is a non-word character, so \b sits right
   before "src"), which would wrongly treat a data-src/nosrc attribute
   as the real src= that makes a <script> external. New Go test
   TestHasInlineScript_DataSrcIsNotExternal: <script data-src="x">
   is still flagged as inline.

No webui/src/ change this round - components.json isn't bundled, and
generate.mjs's edit only touches its own build-time guard, not the
Go-source-generation path. admin_assets_gen.go NOT regenerated
(confirmed via a throwaway `node generate.mjs` + gofmt -w run: output
is byte-identical to what's already committed).
This commit is contained in:
2026-08-21 09:54:48 +01:00
parent b98416d1e9
commit 1aa2b43932
5 changed files with 96 additions and 38 deletions
+7 -3
View File
@@ -24,9 +24,13 @@ const (
adminUsageHistoryPath = "/admin/api/usage/history"
)
// adminCSP is the Content-Security-Policy header served with GET /admin
// and the three /admin/api/* JSON routes (spec §4, v0.2; extended to the
// JSON routes by a folded review item, 2026-08-20 review). It was
// adminCSP is the Content-Security-Policy header served with GET /admin,
// every GET /admin/assets/{hashedname} response (serveAdminAsset), and
// the three /admin/api/* JSON routes — every /admin* response this
// gateway ever sends (spec §4, v0.2; extended to the JSON routes by a
// folded review item, 2026-08-20 review; extended to the asset route by
// a later review sweep — see serveAdminAsset's own doc comment for why).
// It was
// widened with `script-src 'unsafe-inline'`/`style-src 'unsafe-inline'`
// for the original vanilla-JS single-file page; the baked Vue build (Vue
// admin-panel task) needs neither: `vite build` emits index.html with