diff --git a/src/backend/api/middleware/security_headers.py b/src/backend/api/middleware/security_headers.py index f67720d..9f2ba44 100644 --- a/src/backend/api/middleware/security_headers.py +++ b/src/backend/api/middleware/security_headers.py @@ -10,16 +10,18 @@ from starlette.middleware.base import BaseHTTPMiddleware from src.backend.config import settings -# Content Security Policy - allows CDN resources used by the client +# Content Security Policy - same-origin only: every third-party library now ships with +# the app (see frontend static/vendor/), so no CDN host needs allowing. The install runs +# on an isolated shop-floor network where an outbound fetch would simply fail. # Note: 'unsafe-eval' required for Plotly.js runtime evaluation in SPC charts CSP = ( "default-src 'self'; " - "script-src 'self' 'unsafe-inline' 'unsafe-eval' " - "https://cdn.tailwindcss.com https://cdn.jsdelivr.net https://cdn.plot.ly; " - "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; " - "font-src 'self' https://fonts.gstatic.com; " + "script-src 'self' 'unsafe-inline' 'unsafe-eval'; " + "style-src 'self' 'unsafe-inline'; " + "font-src 'self'; " "img-src 'self' data: blob:; " - "connect-src 'self'" + "connect-src 'self'; " + "worker-src 'self' blob:" ) diff --git a/src/frontend/flask_app/static/vendor/VERSIONS.md b/src/frontend/flask_app/static/vendor/VERSIONS.md new file mode 100644 index 0000000..3cea9dc --- /dev/null +++ b/src/frontend/flask_app/static/vendor/VERSIONS.md @@ -0,0 +1,77 @@ +# Librerie di terze parti — copie locali + +Queste copie servono al **punto 12** del documento delle modifiche: l'installazione a +Tràfilo è on-premise, su rete di produzione isolata. Finché queste librerie venivano +scaricate da CDN a ogni apertura di pagina, senza internet l'interfaccia non partiva +affatto (Alpine.js governa tutta la UI). + +Secondo effetto, non meno importante: le versioni sono **congelate**. Prima Alpine.js +era agganciato a `alpinejs@3.x.x`, cioè l'applicazione cambiava da sola a ogni rilascio +degli autori, senza validazione. Per un sistema che produce evidenze per audit +ISO 9001 / IATF 16949 questo è di per sé un difetto. + +Scaricate il **28 luglio 2026**. + +## JavaScript + +| File | Versione | Origine | +|---|---|---| +| `alpinejs-3.15.12.min.js` | 3.15.12 | `https://cdn.jsdelivr.net/npm/alpinejs@3.15.12/dist/cdn.min.js` | +| `plotly-2.32.0.min.js` | 2.32.0 | `https://cdn.plot.ly/plotly-2.32.0.min.js` | +| `pdf-3.11.174.min.js` | 3.11.174 | `https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js` | +| `pdf.worker-3.11.174.min.js` | 3.11.174 | `https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js` | +| `fabric-5.3.1.min.js` | 5.3.1 | `https://cdnjs.cloudflare.com/ajax/libs/fabric.js/5.3.1/fabric.min.js` | + +La versione di Alpine è quella a cui `3.x.x` risolveva il giorno del congelamento: +il pin non cambia il comportamento rispetto a quanto già in esercizio. + +`pdf.worker` è un file a sé che PDF.js carica **a runtime** via +`pdfjsLib.GlobalWorkerOptions.workerSrc`. Va ripuntato in tutti i template che usano +PDF.js, non basta lo script principale: altrimenti la libreria si carica in locale e il +worker continua a cercare internet — sembra funzionare finché non si apre un disegno. + +## Font + +`fonts.css` sostituisce il `` a `fonts.googleapis.com` in `base.html`. + +| File | Famiglia | Subset | +|---|---|---| +| `fonts/inter-latin.woff2` | Inter | latin | +| `fonts/inter-latin-ext.woff2` | Inter | latin-ext | +| `fonts/jetbrains-mono-latin.woff2` | JetBrains Mono | latin | +| `fonts/jetbrains-mono-latin-ext.woff2` | JetBrains Mono | latin-ext | + +Entrambe le famiglie sono **font variabili** (asse `wght`: Inter 100–900, JetBrains Mono +400–800): un solo file per subset copre tutti i pesi usati dall'interfaccia. Google +serviva lo stesso woff2 sotto otto URL diversi, uno per peso dichiarato. + +Tenuti i soli subset **latin** e **latin-ext**, che coprono per intero italiano e +inglese. Per gli altri alfabeti il browser ricade sul font di sistema — scelta +consapevole: cirillico, greco e vietnamita valevano 600 KB di peso morto. + +## Impronte SHA-256 + +``` +57b37d7cae9a27d965fdae4adcc844245dfdc407e655aee85dcfff3a08036a3f alpinejs-3.15.12.min.js +bb0442d69a4d4673320f689bc6e16c05a0e3f16ccfbf551f394d90a7e7cfc772 fabric-5.3.1.min.js +5b5799e6f8c680663207ac5b42ee14eed2a406fa7af48f50c154f0c0b1566946 pdf-3.11.174.min.js +feabdf309770ed24bba31a5467836cdc8cf639c705af27d52b585b041bb8527b pdf.worker-3.11.174.min.js +0a17719a72751704861215da0e5c5cdb3f9a8d50eff5cb84cb6f8b80786682b0 plotly-2.32.0.min.js +34b9c504cab7a73e37b746343a449132e56cf7b5481af2cb81dc74dcff25c956 fonts/inter-latin-ext.woff2 +3100e775e8616cd2611beecfa23a4263d7037586789b43f035236a2e6fbd4c62 fonts/inter-latin.woff2 +db5ff4db83e580426280e9337a58dc57d3a83784a1b03ad80914651594441d52 fonts/jetbrains-mono-latin-ext.woff2 +83c005d49d8a6a50474c73a5a36ac0468076e9c4a29da7bdb14995d80560a5be fonts/jetbrains-mono-latin.woff2 +``` + +Verifica: `sha256sum -c` da questa cartella, oppure +`sha256sum *.js fonts/*.woff2`. + +## Aggiornare una libreria + +1. Scaricare la nuova versione con il nome comprensivo di versione. +2. Ripuntare i ` + + diff --git a/src/frontend/flask_app/templates/maker/recipe_preview.html b/src/frontend/flask_app/templates/maker/recipe_preview.html index 17a86ee..5562e15 100644 --- a/src/frontend/flask_app/templates/maker/recipe_preview.html +++ b/src/frontend/flask_app/templates/maker/recipe_preview.html @@ -432,9 +432,9 @@ {% endblock %} {% block extra_js %} - + - + + - + + + diff --git a/src/frontend/flask_app/templates/statistics/dashboard.html b/src/frontend/flask_app/templates/statistics/dashboard.html index f591e7a..6b25177 100644 --- a/src/frontend/flask_app/templates/statistics/dashboard.html +++ b/src/frontend/flask_app/templates/statistics/dashboard.html @@ -4,7 +4,7 @@ {% block extra_head %} - + {% endblock %} {% block content %}