Commit Graph

50 Commits

Author SHA1 Message Date
cedricAbonnel 53dbce5bb0 fix : gardes session OIDC + règle PHP-FPM www-data (v1.6.2)
- oidc/start.php : arrêt immédiat (500) si session_start() échoue, évite
  un flux OIDC condamné à l'échec silencieux (ex. session.save_path absent)
- oidc/callback.php : même garde + error_log sur échec du contrôle de state
  pour faciliter le diagnostic (STATE absent/présent + session_id)
- consignes.md : règle PHP-FPM — toujours user=www-data, pas le compte admin

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 14:34:39 +02:00
cedricAbonnel 7737edf402 chore : version 1.6.1 — fix ordre require login/logout, data/site/ hors git
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 12:57:21 +02:00
cedricAbonnel 6d159e7dda fix : ordre require config→bootstrap dans login et logout, data/site/ hors git
- public/login/index.php, login/magic.php, logout.php : config/config.php
  chargé avant bootstrap.php pour que SESSION_NAME soit défini avant session_start()
- data/site/ retiré du suivi git (.gitignore corrigé) : contenu site-spécifique
  déjà présent dans varlog-data/site/ et fr.abonnel.www-data/site/
- CLAUDE.md : chemins articles corrigés (varlog-data/, fr.abonnel.www-data/)
- consignes.md : ajouté (architecture, workflow, règles, procédures déploiement)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 12:52:06 +02:00
cedricAbonnel 331e9c9ecd chore : version 1.6.0 — bouton Mettre à jour, branche dev, guard git pull
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 11:16:35 +02:00
cedricAbonnel 0280ef3ca1 docs : architecture articles git (varlog.git + abonnel-www.git), sync bidirectionnelle
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 11:16:35 +02:00
cedricAbonnel eddde2165a fix : run_engine_update vérifie origin == folio_repo_url avant git pull
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 11:16:35 +02:00
cedricAbonnel 07d004b3f0 feat : bouton unique Mettre à jour (git pull + SQL + contenu), branche dev
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 11:16:35 +02:00
cedricAbonnel 5cb0e854fd Merge pull request 'release 1.5.0 : config admin FOLIO_REPO_URL, APP_TIMEZONE, push.sh protégé' (#68) from dev into main
release 1.5.0 : config admin FOLIO_REPO_URL, APP_TIMEZONE, push.sh protégé
2026-05-15 08:07:04 +00:00
cedricAbonnel 8f6c17f0f2 chore : version 1.5.0, push.sh bloque main, CHANGELOG
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 09:55:16 +02:00
cedricAbonnel 5452fb4927 Merge pull request 'feat : FOLIO_REPO_URL et APP_TIMEZONE configurables depuis admin' (#67) from feat/folio-repo-url-admin-config into main
Reviewed-on: #67
2026-05-15 07:52:17 +00:00
cedricAbonnel de8785d088 fix : déplacer config mises à jour Folio dans l'onglet Site
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 09:48:40 +02:00
cedricAbonnel 4b5943c0a4 feat : FOLIO_REPO_URL et branche configurables depuis l'admin (dashboard)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 09:48:40 +02:00
cedricAbonnel a552f105cd fix : masquer bouton Vérifier si FOLIO_REPO_URL non configuré, message explicatif
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 09:48:40 +02:00
cedricAbonnel 16afec3039 fix : APP_TIMEZONE configurable (défaut Europe/Paris), FOLIO_REPO_URL dans .env.example
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 09:48:40 +02:00
cedricAbonnel 2d2148079d Merge pull request 'docs: ajouter README avec guide d'installation' (#56) from docs/readme-installation into main
docs: ajouter README avec guide d'installation (v1.4.0)

Fixes #55.
2026-05-15 07:44:28 +00:00
cedricAbonnel 3965be6854 docs : mettre à jour README — DATA_PATH, permissions, setup.sh
- Ajouter DATA_PATH dans le tableau des variables .env avec note prod
- Étape 6 : permissions sur DATA_PATH (hors document root) au lieu de data/
- Étape 7 : référencer $DATA_PATH/site_settings.json
- Mentionner scripts/setup.sh
- Structure : retirer data/ (géré par DATA_PATH), ajouter scripts/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 09:36:37 +02:00
cedricAbonnel e803d2d0a7 fix : DATA_PATH défini dans config/config.php (manquant à l'exécution)
bootstrap.php ne suffisait pas — index.php, feed.php et sitemap.php passent
par config/config.php. DATA_PATH est maintenant défini là, juste après le
chargement du .env. file.php charge désormais config/config.php.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 09:24:01 +02:00
cedricAbonnel 9069a64a0c Merge pull request 'feat : statistiques admin, livres, setup.sh, permissions rsync (v1.3.0)' (#66) from feat/books into main
feat/books → main
2026-05-15 07:18:49 +00:00
cedricAbonnel 819d6d1b8f chore : ajouter fichiers non versionnés (migrations SQL, 404, PROJET.md)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 09:18:34 +02:00
cedricAbonnel 16965ee8cb feat : DATA_PATH configurable, DataGit auto-commit, UpdateChecker branche (v1.4.0)
- DATA_PATH : chemin /data hors document root, configurable via .env
  (fallback sur BASE_PATH/data si absent)
- DataGit : auto-commit git sur toutes les écritures articles/livres
  (create, update, delete, meta, tags, fichiers, liens…) sauf autosave
- UpdateChecker : getBranch() / getLastChecked() / clearCache(),
  branche configurable via FOLIO_UPDATE_BRANCH (plus de main hardcodé)
- Admin dashboard : affiche la branche suivie, date du dernier contrôle,
  bouton Vérifier pour forcer le check sans attendre le TTL
- CLAUDE.md : architecture DATA_PATH et flux de déploiement documentés

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 09:17:55 +02:00
cedricAbonnel 55a2120be1 chore : CHANGELOG + bump version 1.3.0 (statistiques, permissions, setup.sh)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 00:53:33 +02:00
cedricAbonnel 8be56bc27f Merge pull request 'feat #64 : onglet Statistiques — pages, livres, répartition AS' (#65) from feat/books into main
Reviewed-on: #65
2026-05-14 22:50:47 +00:00
cedricAbonnel ce70daaa34 Merge pull request 'fix : vérification écriture settings + script setup.sh' (#63) from feat/wizard-multi-step into main
Reviewed-on: #63
2026-05-14 22:50:36 +00:00
cedricAbonnel 8cab6362a3 feat : onglet Statistiques — pages, livres, répartition AS avec groupes configurables
- AccessLogParser : parse COMBINED, agrège hits /post/ et /book/, cache 10 min
- AsnLookup : batch lookup ip-api.com, cache 30j, agrégation et groupes AS
- Onglet Statistiques dans l'admin : top pages, top livres, répartition réseau
- Filtrage par groupe AS (badges) + formulaire de configuration des groupes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 00:48:34 +02:00
cedricAbonnel dbd76556fb feat : notion de livre — grouper des pages en série ordonnée
Ajoute un concept de "livre" (série de pages ordonnées) avec :
- BookManager : CRUD JSON dans data/books/<slug>.json
- Route /book/<slug> → page de sommaire (table des matières)
- Navigation chapitre ← → en bas de chaque article membre du livre
- Bandeau "Chapitre X/N — Nom du livre" en haut de l'article
- Admin → onglet Livres : créer, éditer, supprimer un livre, ajouter/ordonner les pages via textarea slug

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 00:47:41 +02:00
cedricAbonnel 3bb83b3ffd feat : SearchLogParser accepte un pattern glob pour les logs d'accès
Balaye tous les fichiers correspondant au pattern (ex: *-access.log)
et leurs rotations .gz/.tar.gz. Valeur par défaut : *-access.log.
Label renommé en "Pattern des logs d'accès".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 00:35:19 +02:00
cedricAbonnel 981c9f6cb3 feat : SearchLogParser supporte tar.gz + config log dans onglet Recherches
- logFiles() utilise glob() au lieu d'un range fixe 1-14
- Support .tar.gz via PharData
- Champ apache_access_log déplacé du tab Site vers un bloc dédié
  dans le tab Recherches (action admin_save_searches_config)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 00:26:16 +02:00
cedricAbonnel d18f9abd16 feat : log Apache configurable via Administration → Site (apache_access_log)
Ajoute apacheAccessLog() dans SiteSettings — priorité au réglage admin,
fallback sur APACHE_ACCESS_LOG dans .env. Champ ajouté dans le formulaire
Site de l'administration.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 00:16:49 +02:00
cedricAbonnel d488bcd00c fix : setup.sh — rappel redémarrage PHP-FPM en plus d'Apache pour groupe adm
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 00:12:31 +02:00
cedricAbonnel 157c30f20c feat : setup.sh — ajout de www-data au groupe adm pour les logs Apache
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 00:11:51 +02:00
cedricAbonnel fd2397ff90 feat : script setup.sh pour le déploiement initial de Folio
Crée les dossiers requis, applique setgid sur data/ et _cache/ pour
que les fichiers héritent du groupe web (www-data) quelle que soit
leur origine (PHP ou rsync), installe les dépendances et lance les
migrations SQL.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 00:10:30 +02:00
cedricAbonnel 9091a00a32 fix : saveSiteSettings et saveSmtpSettings retournent bool, erreur affichée
file_put_contents() échouait silencieusement (permissions), provoquant
un saved=1 trompeur. Les deux fonctions retournent maintenant bool ;
les callers redirigent vers ?error=write et le template affiche un
message d'erreur explicite.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 00:02:54 +02:00
cedricAbonnel 370e1a9062 Merge pull request 'fix #61 : afficher les résultats de recherche au lieu de rediriger vers le 1er' (#62) from feat/wizard-multi-step into main
Reviewed-on: #62
2026-05-14 21:47:29 +00:00
cedricAbonnel d6b75d44e3 chore : version 1.2.2 + CHANGELOG (#61)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 23:47:04 +02:00
cedricAbonnel dbb4684d7c chore : version 1.3.0 + CHANGELOG (#61)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 23:46:32 +02:00
cedricAbonnel edb5f03956 fix #61 : afficher les résultats de recherche au lieu de rediriger vers le 1er
Remplace la redirection 301 vers le premier résultat par une redirection
302 vers /search?q=... pour laisser l'utilisateur choisir parmi les
résultats.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 23:45:24 +02:00
cedricAbonnel 99a7f2e790 Merge pull request 'feat : wizard multi-étapes, migrations contenu, versionnage semver (v1.2.1)' (#60) from feat/wizard-multi-step into main
Reviewed-on: #60
2026-05-14 21:17:19 +00:00
cedricAbonnel 72cb7acae4 fix 1.2.1 : cache index.md, H1 rendu, scroll wizard, titre Modifier
- ArticleManager : invalider le cache si index.md est plus récent que meta.json
- migration_001 : touch(meta.json) après maj index.md pour forcer l'invalidation
- post_view.php : masquer le H1 initial du contenu (déjà affiché par le template)
- step1.php : en-tête "Modifier" sans le titre de l'article
- wizard.js : retirer scrollToCursor (erroné sur auto-resize) ; Ctrl+Home/End via scrollIntoView

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 23:07:15 +02:00
cedricAbonnel 1dbe6d8dd3 feat : versionnage semver, migrations contenu, bandeau mise à jour admin
- CHANGELOG.md : structure semver (1.0.0 / 1.1.0 / 1.2.0) remplace le journal non versionné
- public/version.txt : généré à chaque push depuis la première entrée CHANGELOG
- scripts/push.sh : extrait la version CHANGELOG avant git add
- src/UpdateChecker.php : compare version déployée vs version Gitea (raw file), cache 1 h
- templates/layout.php : bandeau alerte admin (nouvelle version / migrations en attente)
- templates/admin.php : dashboard moteur Folio (version déployée / disponible)
- scripts/migrate_content.php + migration_001 : ajout # titre dans les articles existants
- templates/maintenance.php : page HTTP 503 pendant une migration
- src/helpers.php : extractMarkdownTitle(), normalisation \r\n dans lineDiff()
- templates/wizard/step1.php : suppression champ titre, plan TOC dynamique
- public/assets/js/wizard.js : scope titleEl, scrollToCursor, buildToc, handlers externalisés

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 22:45:35 +02:00
cedricAbonnel 6200444e6d Merge pull request 'feat #58 : wizard multi-étapes création/édition article' (#59) from feat/wizard-multi-step into main
Reviewed-on: #59
2026-05-14 19:50:33 +00:00
cedricAbonnel c503f1dd66 style : formatage PHP-CS-Fixer sur le wizard
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 21:48:33 +02:00
cedricAbonnel 6895a3bf65 feat #58 : wizard multi-étapes création/édition d'article
Remplace le formulaire unique par un wizard 5 étapes (création) et
6 étapes (édition) avec auto-sauvegarde en brouillon, détection de
tags depuis le texte (TagSuggester), aperçu SEO, diff avant validation
et plan Markdown dynamique dans l'éditeur.

Détail des changements :
- ArticleManager : +6 méthodes (updatePartialMeta, saveDraftOverlay,
  getDraftOverlay, hasDraftOverlay, discardDraftOverlay, commitDraftOverlay)
- .htaccess : routes /new/{uuid}/{1-5} et /edit/{uuid}/{1-6}
- index.php : cases create et edit réécrits en switch($step),
  nouveau case autosave_draft et edit_discard_draft
- assets/js/wizard.js : autosave debounce, auto-resize textarea,
  scroll curseur, plan TOC dynamique, toggle pills tags
- templates/wizard/ : nav.php + step1..6.php

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 21:46:11 +02:00
cedricAbonnel 24bb244352 perf : session lazy + CSRF cookie + 410 DokuWiki
Contexte : sur abonnel.fr, session_start() était appelé sur chaque
requête PHP (y compris bots), créant ~17 000 fichiers de session/jour
dans un répertoire custom non nettoyé par le cron Debian. Les workers
PHP-FPM grossissaient en mémoire et le pool saturait (1 188 erreurs
503 en 30 minutes).

Changements :

public/index.php
- session_start() uniquement si le cookie de session existe déjà ou si
  la requête est POST. Les bots (GET sans cookie) ne créent plus de
  session.
- CSRF commentaires migré de $_SESSION['comment_csrf'] vers un double-
  submit cookie (_csrf_c, SameSite=Strict, HttpOnly). La session n'est
  plus requise pour les visiteurs anonymes qui postent un commentaire.

templates/comments_section.php
- Génère le token CSRF et le pose en cookie (_csrf_c) au lieu de
  l'écrire en session.

public/.htaccess
- Règle Apache 410 Gone pour toute URL contenant un paramètre ?do=
  (anciens paramètres DokuWiki : do=media, do=export_pdf…). Traité par
  Apache en 2ms sans toucher PHP-FPM.

public/oidc/{start,callback,me}.php
- Correction du bug introduit par 0b8077e : config.php (qui utilise
  BASE_PATH) était chargé avant bootstrap.php (qui définit BASE_PATH).
  Fix : define('BASE_PATH', …) ajouté avant le require config.php.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 13:06:54 +02:00
cedricAbonnel f92e9425ed docs : config PHP-FPM recommandée et protection bots DokuWiki
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 10:16:02 +02:00
cedricAbonnel 0b8077e43c fix : orphelins search_index + SESSION_NAME non appliqué
- ArticleManager::getSearchIndex() : rebuild automatique si un UUID
  référencé dans search_index.json n'existe plus sur le disque (article
  supprimé hors CMS via rsync ou suppression manuelle). Même logique que
  getBySlug() qui nettoie déjà le slug_index à la volée.

- bootstrap.php : lire SESSION_NAME depuis $_ENV avant session_start(),
  permettant de personnaliser le nom du cookie de session via le .env.

- oidc/{start,callback,me}.php : inverser l'ordre des require pour charger
  config.php (dotenv) avant bootstrap.php, condition nécessaire pour que
  SESSION_NAME soit disponible au démarrage de la session.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 10:06:11 +02:00
cedricAbonnel 5828aac4f5 docs: ajouter README avec guide d'installation
Couvre prérequis, installation pas-à-pas (clone, .env, BDD, migrations,
vhost Apache/Nginx, permissions), paramètres du site, mise à jour et
structure du projet. Fixes #55.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 09:58:05 +02:00
cedricAbonnel 03120457a7 clean : retirer les articles de production de folio, garder data/site/
data/ ne doit pas contenir de données de site (articles, config, cache).
Seuls data/.gitkeep et data/site/ (exemples pour installation fraîche)
sont conservés. Le .gitignore est mis à jour en conséquence.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 09:26:33 +02:00
cedricAbonnel 23acc1621f fix #54 : corriger autoloader PSR-4 — app/ → src/
L'autoloader mappait App\ vers app/ (inexistant).
Tous les namespaces App\ échouaient silencieusement sauf
quand les classes étaient chargées via require_once direct.
Première erreur visible : App\Http\Csrf introuvable → 500 sur /login/.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 09:20:29 +02:00
cedricAbonnel 2c8e31baff deploy: documenter le workflow d'installation fraîche
- Ajoute .env.example avec toutes les variables requises (DB_DSN, OIDC_*,
  SMTP_*, SESSION_NAME, ADMIN_EMAIL…) — DB_DSN était absent et cassait
  database/migrate.php au premier déploiement.
- Clarifie migrate-init.php : réservé aux serveurs existants antérieurs au
  système de migrations ; pour une installation fraîche, migrate.php suffit
  (applique tout depuis migration_000).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 08:47:29 +02:00
Cedric Abonnel 8a85c15372 fix #29 : envoyer le lien magique par email (envoyer_mail_smtp) 2026-05-13 23:41:58 +02:00