Fixes the page-freeze exposure on LAN-only clients: the P0 templates loaded Alpine.js from cdn.jsdelivr.net and Tailwind from cdn.tailwindcss.com, so any device that cannot reach those CDNs got a login page whose JS never engaged.
Vendor Alpine 3.17.2 + Tailwind Play 3.4.17 under app/static/vendor/, served same-origin with immutable cache; template references moved to local paths.
CSP: both CDN hosts removed from script-src (self-only, connect-src 'self'); HTML responses now Cache-Control: no-cache; STS stays TLS-only (verified - it was already conditional).
New regression test tests/test_frontend_vendoring.py: /login HTML must carry no external script src and both vendor paths must return 200.
Validation: no-mistakes run complete (review / test / document / lint all passed). pytest tests/ -q -> 87 passed including the 5 new vendoring tests; live uvicorn check pasted in the lane log.
Reviewer finding on FastAPI /docs + /redoc (their swagger bundles load from a CDN) decided accept-as-is: those developer conveniences already cannot render for the LAN-only clients this fix exists for, /openapi.json is unaffected, and vendoring them would expand the accepted contract.
Head: 49b26926cfa74d558a9291cd90ed6fcd48b599b6 on fm/vendor-alpine-tailwind-locally-in-denya-00 (the pipeline's PR step reported provider-unsupported for Gitea, so firstmate opened this PR).
Fixes the page-freeze exposure on LAN-only clients: the P0 templates loaded Alpine.js from cdn.jsdelivr.net and Tailwind from cdn.tailwindcss.com, so any device that cannot reach those CDNs got a login page whose JS never engaged.
- Vendor Alpine 3.17.2 + Tailwind Play 3.4.17 under `app/static/vendor/`, served same-origin with immutable cache; template references moved to local paths.
- CSP: both CDN hosts removed from `script-src` (self-only, `connect-src 'self'`); HTML responses now `Cache-Control: no-cache`; STS stays TLS-only (verified - it was already conditional).
- New regression test `tests/test_frontend_vendoring.py`: /login HTML must carry no external script src and both vendor paths must return 200.
Validation: no-mistakes run complete (review / test / document / lint all passed). `pytest tests/ -q` -> 87 passed including the 5 new vendoring tests; live uvicorn check pasted in the lane log.
Reviewer finding on FastAPI /docs + /redoc (their swagger bundles load from a CDN) decided accept-as-is: those developer conveniences already cannot render for the LAN-only clients this fix exists for, `/openapi.json` is unaffected, and vendoring them would expand the accepted contract.
Head: `49b26926cfa74d558a9291cd90ed6fcd48b599b6` on `fm/vendor-alpine-tailwind-locally-in-denya-00` (the pipeline's PR step reported provider-unsupported for Gitea, so firstmate opened this PR).
The P0 templates loaded Alpine.js from cdn.jsdelivr.net and Tailwind from
cdn.tailwindcss.com, so LAN-only demo clients got a login page whose JS never
engaged (stuck form). Vendor both libraries under app/static/vendor/
(alpine-3.17.2.min.js, tailwind-3.4.17.js) served same-origin at /static,
point base.html at local paths, and drop both CDN hosts from the CSP
(script-src/style-src stay 'self' 'unsafe-inline'; connect-src 'self').
HTML pages now ship Cache-Control: no-cache; vendored assets are cached
public, max-age=31536000, immutable (versioned filenames). HSTS stays
TLS-gated. Adds tests/test_frontend_vendoring.py (no external script src on
/login, both vendor paths 200, no-cache + immutable header checks, CSP
without CDN hosts).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Fixes the page-freeze exposure on LAN-only clients: the P0 templates loaded Alpine.js from cdn.jsdelivr.net and Tailwind from cdn.tailwindcss.com, so any device that cannot reach those CDNs got a login page whose JS never engaged.
app/static/vendor/, served same-origin with immutable cache; template references moved to local paths.script-src(self-only,connect-src 'self'); HTML responses nowCache-Control: no-cache; STS stays TLS-only (verified - it was already conditional).tests/test_frontend_vendoring.py: /login HTML must carry no external script src and both vendor paths must return 200.Validation: no-mistakes run complete (review / test / document / lint all passed).
pytest tests/ -q-> 87 passed including the 5 new vendoring tests; live uvicorn check pasted in the lane log.Reviewer finding on FastAPI /docs + /redoc (their swagger bundles load from a CDN) decided accept-as-is: those developer conveniences already cannot render for the LAN-only clients this fix exists for,
/openapi.jsonis unaffected, and vendoring them would expand the accepted contract.Head:
49b26926cfa74d558a9291cd90ed6fcd48b599b6onfm/vendor-alpine-tailwind-locally-in-denya-00(the pipeline's PR step reported provider-unsupported for Gitea, so firstmate opened this PR).