fix(frontend): vendor Alpine.js + Tailwind same-origin (LAN-safe demo) #12

Merged
abiba-bot merged 2 commits from fm/vendor-alpine-tailwind-locally-in-denya-00 into main 2026-09-09 12:41:22 +00:00
Owner

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).
abiba-bot added 2 commits 2026-09-09 02:10:08 +00:00
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).
abiba-bot merged commit 7b0365b135 into main 2026-09-09 12:41:22 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: SyslogSolution/denya-onecare#12