Commit Graph
6 Commits
Author SHA1 Message Date
Claude fab64bc38a Rôle modérateur + gestion des comptes admin/modérateur
- Nouveau rôle users.role='moderator' (contrainte CHECK migrée via
  DROP+ADD CONSTRAINT, idempotent) : accès à Membres, Rencontres,
  Inscriptions uniquement. Dashboard, Catégories (écriture), Contenu du
  site, Demandes d'adhésion et gestion des comptes restent admin-only,
  imposé côté serveur (requireAuth accepte désormais un tableau de rôles)
- Nouvel onglet « Administrateurs » (admin-only) : créer un compte admin
  ou modérateur (mot de passe temporaire généré, même mécanique que pour
  les membres — visible tant que non changé, changement forcé à la
  première connexion), réinitialiser l'accès, promouvoir/rétrograder,
  supprimer. Garde-fous : impossible de se supprimer ou de se rétrograder
  soi-même, impossible de supprimer le dernier administrateur
- users.full_name (colonne migrée) pour l'affichage des comptes staff
- AccessCell/CredentialsModal extraits dans AccessControls.jsx, partagés
  entre la gestion des membres et celle des comptes admin/modérateur
- AdminShell filtre ses onglets par rôle ; Espace.jsx route admin et
  modérateur vers le back-office

Corrigé en cours de route : GET /api/admin/categories doit rester lisible
par les modérateurs (nécessaire au formulaire membre) même si sa gestion
en écriture reste admin-only — sans quoi le Promise.all du frontend
échouait silencieusement et vidait la liste des membres.

Vérifié : 34 + 21 tests existants toujours au vert, 26 nouveaux tests de
permissions par rôle, parcours navigateur complet (création modérateur,
connexion, changement forcé, menu restreint, accès aux membres).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fkg15RCxNgUys4ru73He2o
2026-07-13 14:42:29 +00:00
Claude 56ca6d8559 Mot de passe temporaire à la création d'un membre, visible admin, changement forcé
- Nouveau membre créé avec email : un mot de passe temporaire aléatoire
  (~69 bits, sans caractères ambigus) est généré et haché ; il est retourné
  à l'admin et reste lisible en clair (users.temp_password) tant que le
  membre ne l'a pas changé
- Colonnes users.temp_password / must_change_password (migration
  ALTER TABLE IF NOT EXISTS, appliquée au démarrage par le bootstrap)
- POST /api/admin/members/:id/reset-access : régénère l'accès (création
  s'il n'existait pas, ou réinitialisation si le membre a perdu son mot
  de passe) ; login/me exposent mustChangePassword ; change-password
  efface systématiquement le mot de passe temporaire et lève le blocage
- Frontend : colonne « Accès » dans la liste des membres (mot de passe
  visible + copier + réinitialiser, ou « Défini », ou « Créer l'accès »),
  modal de confirmation après création/réinitialisation, écran de
  changement de mot de passe obligatoire avant tout accès au portail ou
  au back-office

Vérifié : cycle complet (création → mot de passe visible côté admin →
connexion → changement forcé → effacement automatique → réinitialisation
admin en cas de perte) via 21 tests e2e dédiés + parcours navigateur ;
34 tests existants toujours au vert.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fkg15RCxNgUys4ru73He2o
2026-07-13 09:23:38 +00:00
Claude 3ea069bfbb Fusionne l'espace admin dans l'espace membre : connexion unique
- Le menu public n'affiche plus « Espace admin » — un seul lien
  « Espace membre » pour tous les comptes
- /espace-membre devient le point de connexion unique : après connexion,
  le contenu affiché dépend du rôle du compte (portail membre avec header
  du site, ou back-office admin plein écran avec sa propre barre latérale)
- Admin.jsx exporte désormais AdminShell (coquille admin authentifiée,
  sans logique de connexion) réutilisée par Espace.jsx ; l'export par
  défaut devient une redirection de /admin vers /espace-membre pour ne
  pas casser d'anciens liens
- App.jsx masque le header/footer public uniquement quand un admin est
  affiché sur /espace-membre (ou sur l'ancienne route /admin)

Vérifié : navigation sans lien admin, /admin redirige, connexion membre
→ portail avec header, connexion admin → back-office sans header ; 34
tests e2e toujours au vert.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fkg15RCxNgUys4ru73He2o
2026-07-13 08:59:06 +00:00
Claude e3f5869bc8 Port interne de l'application : 3000 → 8321
Plus aucune référence au port 3000 : l'application écoute sur 8321 dans
le conteneur (PORT, EXPOSE, healthcheck, mapping 8321:8321, upstream
nginx sbc-app:8321, proxy de dev Vite, README).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fkg15RCxNgUys4ru73He2o
2026-07-10 20:15:36 +00:00
Claude 499b753c22 Supprime nginx : Express sert le frontend, ports peu utilisés
- Un seul conteneur applicatif : Express sert l'API, le frontend React
  compilé (fallback SPA, cache immutable sur /assets) et les images
  /uploads (nosniff + CSP default-src 'none')
- En-têtes de sécurité (CSP stricte, X-Frame-Options DENY, etc.) portés
  de nginx vers helmet, compression gzip ajoutée
- Application exposée sur le port 8321 (APP_PORT), PostgreSQL sur
  127.0.0.1:56432 (DB_PORT, loopback uniquement pour l'admin locale)
- TRUST_PROXY pilote la confiance aux en-têtes X-Forwarded-* (désactivé
  par défaut hors reverse-proxy)
- Dockerfile multi-étages unique à la racine (build React → deps → image
  finale non-root, fs en lecture seule)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fkg15RCxNgUys4ru73He2o
2026-07-10 19:52:52 +00:00
Claude 96dca2a802 Application complète SLUC Business Club (React + Express + PostgreSQL, Docker)
Implémente l'intégralité de la maquette « SLUC Business Club.dc.html » :
- Site public : accueil (héro administrable, carrousel membres, agenda avec
  inscription en ligne, rencontres passées, demande d'adhésion), annuaire
  avec recherche/filtres/fiche détaillée, page association
- Espace membre : connexion, édition de fiche avec aperçu direct, upload
  logo/photo, statut d'adhésion par saison, changement de mot de passe
- Espace admin : tableau de bord, membres (validation par saison),
  rencontres (CRUD + inscrits + impression + export Excel), inscriptions,
  catégories, contenu du site

Architecture : 3 conteneurs Docker Compose — PostgreSQL 16 (réseau interne,
rôle applicatif restreint), API Express (non-root, read-only fs), nginx
non privilégié (frontend React + reverse-proxy + CSP stricte).

Sécurité : requêtes 100 % paramétrées, bcrypt + JWT httpOnly SameSite=Strict,
vérification d'Origin (CSRF), validation zod, rate limiting, uploads vérifiés
par octets magiques avec noms aléatoires, aucun secret committé.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fkg15RCxNgUys4ru73He2o
2026-07-10 19:43:07 +00:00