Files
veye-lalwa/scripts/verifier-conformite.sh
T
Cyber MawonajandClaude Opus 5 bdeaa9fa7f Déploiement : plus aucune valeur d'exemple à corriger à la main
L'unité web portait ORIGIN=https://veille.example.org : un fichier versionné
qu'il fallait éditer à chaque déploiement, et dont l'oubli casse silencieusement
les soumissions de formulaire. Remplacé par PROTOCOL_HEADER / HOST_HEADER :
l'application déduit son origine des en-têtes du reverse proxy et fonctionne
donc sur n'importe quel domaine, sans édition.

Vérifié en exécutant réellement le binaire construit : deux domaines
différents servis par le même processus, HTTP 200 dans les deux cas, et un
ORIGIN figé l'emporte bien sur les en-têtes.

Au passage, une affirmation fausse que j'avais écrite en commentaire : « le
.env l'emporte sur les variables systemd ». C'est l'inverse — le --env-file de
Node ne remplace pas une variable déjà présente dans l'environnement (constaté
sur Node 24). Le commentaire dit désormais pourquoi ORIGIN dans .env fonctionne
quand même : parce que l'unité ne le déclare pas. Et un contrôle mécanique
interdit désormais de le redéclarer.

ExecStart passe par /usr/bin/env : NodeSource installe node dans /usr/bin, une
compilation manuelle dans /usr/local/bin, un chemin figé échouait sur l'un des
deux.

Deux contrôles ajoutés à make verifier : aucune valeur d'exemple active dans
les unités systemd, et ORIGIN laissé au .env.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-25 22:51:05 -04:00

122 lines
5.0 KiB
Bash

#!/usr/bin/env bash
# ─────────────────────────────────────────────────────────────────────────────
# Contrôles de conformité au cahier des charges (§3bis et §8).
#
# Ces vérifications sont mécaniques : elles constatent, elles n'interprètent
# pas. Un seul contrôle en échec fait échouer la commande.
# ─────────────────────────────────────────────────────────────────────────────
set -uo pipefail
cd "$(dirname "$0")/.."
echecs=0
ok() { printf ' \033[32m✓\033[0m %s\n' "$1"; }
ko() {
printf ' \033[31m✗\033[0m %s\n' "$1"
echecs=$((echecs + 1))
}
titre() { printf '\n\033[1m%s\033[0m\n' "$1"; }
titre "§3bis — architecture de rendu"
# Seule une déclaration exportée est lue par SvelteKit : chercher la chaîne
# brute ferait échouer le contrôle sur les commentaires qui la mentionnent,
# y compris ceux qui expliquent pourquoi on ne la pose pas.
MOTIF_SSR='^[[:space:]]*export[[:space:]]+const[[:space:]]+ssr[[:space:]]*=[[:space:]]*false'
MOTIF_CSR='^[[:space:]]*export[[:space:]]+const[[:space:]]+csr[[:space:]]*=[[:space:]]*false'
if grep -rnE "$MOTIF_SSR" web/src --include='*.ts' --include='*.js' --include='*.svelte' -q; then
ko "un fichier déclare export const ssr = false (le mode SPA est écarté)"
grep -rnE "$MOTIF_SSR" web/src --include='*.ts' --include='*.js' --include='*.svelte'
else
ok "aucun export const ssr = false : le rendu serveur est le défaut partout"
fi
if grep -rnE "$MOTIF_CSR" web/src/routes/+layout.ts web/src/routes/+layout.server.ts 2>/dev/null -q; then
ko "csr = false déclaré au layout racine"
else
ok "aucun csr = false global"
fi
for page in a-propos methode; do
if grep -q "prerender = true" "web/src/routes/$page/+page.ts" 2>/dev/null; then
ok "prerender = true sur /$page"
else
ko "prerender = true absent de /$page"
fi
done
grep -q "adapter-node" web/svelte.config.js &&
ok "adapter-node en place" || ko "adapter-node absent de svelte.config.js"
grep -q "precompress: true" web/svelte.config.js &&
ok "precompress activé" || ko "precompress non activé"
titre "§3 — souveraineté des ressources"
tiers=$(grep -rnE "https?://(fonts\.googleapis|fonts\.gstatic|cdn\.|unpkg|jsdelivr|googletagmanager|google-analytics)" \
web/src web/static 2>/dev/null | grep -v Binary || true)
if [ -z "$tiers" ]; then
ok "aucune ressource tierce référencée (polices, CDN, traceurs)"
else
ko "ressources tierces trouvées :"
echo "$tiers"
fi
nb_polices=$(find web/static/polices -name '*.woff2' 2>/dev/null | wc -l)
[ "$nb_polices" -gt 0 ] &&
ok "polices auto-hébergées ($nb_polices fichiers woff2)" ||
ko "polices non auto-hébergées — lancer npm run polices"
titre "Déploiement — pas de valeur d'exemple à corriger à la main"
# Les unités systemd sont copiées telles quelles dans /etc/systemd/system :
# un domaine d'exemple qui y traîne casse le déploiement sans le dire.
gabarits=$(grep -nE '^[^#]*(example\.(org|com)|votre-domaine|CHANGEME|TODO)' systemd/*.service systemd/*.socket systemd/*.timer 2>/dev/null || true)
if [ -z "$gabarits" ]; then
ok "aucune valeur d'exemple active dans les unités systemd"
else
ko "valeur d'exemple à remplacer dans une unité systemd :"
echo "$gabarits"
fi
if grep -qE '^[^#]*Environment=ORIGIN=' systemd/veille-web.service; then
ko "ORIGIN déclaré dans l'unité : le .env ne pourrait plus le surcharger"
else
ok "ORIGIN laissé au .env, l'origine est déduite des en-têtes du proxy"
fi
titre "§8 — livrables"
for chemin in pipeline web data systemd tests README.md README-pipeline.md .env.example Makefile; do
[ -e "$chemin" ] && ok "présent : $chemin" || ko "manquant : $chemin"
done
[ -f web/build/index.js ] &&
ok "build de production présent" || ko "build absent — lancer make build"
titre "§8.2 — intégrité des données"
if [ -f data/veille.db ]; then
total=$(sqlite3 data/veille.db "SELECT COUNT(*) FROM textes")
orphelins=$(sqlite3 data/veille.db \
"SELECT COUNT(*) FROM textes t WHERE NOT EXISTS (SELECT 1 FROM sources s WHERE s.texte_id = t.id)")
cc=$(sqlite3 data/veille.db "SELECT COUNT(*) FROM v_textes WHERE devant_cc = 1")
sans_url=$(sqlite3 data/veille.db \
"SELECT COUNT(*) FROM sources WHERE url NOT LIKE 'http%'")
[ "$total" -ge 49 ] && ok "$total textes (≥ 49 exigés)" || ko "$total textes, 49 exigés"
[ "$orphelins" -eq 0 ] && ok "aucun texte sans source URL" || ko "$orphelins textes sans source"
[ "$sans_url" -eq 0 ] && ok "toutes les sources ont une URL absolue" || ko "$sans_url sources sans URL"
[ "$cc" -ge 7 ] && ok "$cc textes devant le Conseil constitutionnel (≥ 7)" || ko "$cc textes, 7 attendus"
else
ko "base absente — lancer make seed"
fi
titre "Résultat"
if [ "$echecs" -eq 0 ]; then
printf ' \033[32mTous les contrôles passent.\033[0m\n\n'
else
printf ' \033[31m%d contrôle(s) en échec.\033[0m\n\n' "$echecs"
exit 1
fi