• fix: A43 TERMINÉ + A38 phase 1 — CSRF rendu côté serveur, helper unique (v7.33.0)
    FlowDeck CI / lint (push) Successful in 1m57s
    FlowDeck CI / test (push) Successful in 15m20s
    FlowDeck CI / docker (push) Canceled after 0s

    bruno released this 2026-10-02 08:45:27 -04:00 | 87 commits to main since this release

    A43 (les 4 items sont clos) :

    • __CSRF_PLACEHOLDER__ supprimé : ContextVar CSRF_TOKEN posée par
      CSRFMiddleware avant call_next (même mécanique que le nonce CSP),
      global {{ csrf_token() }} dans templating, base.html rend
      {"X-CSRF-Token":{{ csrf_token()|tojson }}} — vide si cookie absent,
      htmx:configRequest re-lit le cookie à chaque appel → plus jamais de
      jeton factice servi.
    • Palette : fetch('/api/search…') SANS header (GET ∈ SAFE_METHODS →
      CSRF inapplicable) — le JSON.parse du body-attr par frappe disparaît.
    • utcnow déprécié = 0 dans app/**.py ; health loggé (A25) + booléens db/
      gitea = raison ; probe réseau = voulu (test de connectivité).

    A38 phase 1 (CSRF unifié) :

    • window.getCsrf() unique dans le <head> de base.html.
    • 76 lectures brutes du cookie → getCsrf() dans 13 fichiers (47 formes
      (…||[])[1]||'', 25 déclarations const X = match(…) avec conversion
      de leurs usages X?X[1]:'' → X (noms collectés PAR FICHIER, jamais
      de règle globale), 4 formes espacées).
    • Définitions dupliquées supprimées : card_detail.html (multi-lignes),
      database_table.js (1 ligne dans IIFE → chute sur le global).
    • Les 3 variantes de base.html (IIFE getCsrf + 2 getCsrfToken) →
      return getCsrf().
    • welcome.html garde sa lecture locale (page autonome sans base) ;
      reste exactement 1 raw dans base.html (la déf head) + 2 dans welcome.

    Test : test_csrf_server_rendered_no_placeholder (pas de placeholder +
    token du hx-headers == cookie csrf_token).

    suite 1092/1092 · ruff OK · node --check vert · docs à jour

    Downloads