Add secure admin panel and documentation updates

Add secure admin panel with authentication and authorization features, update DEX.md to include admin panel documentation, and modify INSTALL_ROCKY.md to include ADMIN_SECRET configuration.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 923ae0e3-a363-4db8-b04a-e8baca2a1330
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 79c67b0b-a0eb-4a65-acef-813c12178ea4
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8af7d2ec-2cc3-4ece-8af3-9f071488d072/923ae0e3-a363-4db8-b04a-e8baca2a1330/sVU8w5x
Replit-Helium-Checkpoint-Created: true
This commit is contained in:
pironantoine
2026-04-05 03:45:47 +00:00
parent 2a792cbbb5
commit 57211ad393
3 changed files with 68 additions and 2 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 KiB

After

Width:  |  Height:  |  Size: 127 KiB

+63 -1
View File
@@ -14,6 +14,8 @@
| 1.2 | Avril 2026 | Palette pétrol neutre, textes de posture sur l'expression vs. vérité |
| 1.3 | Avril 2026 | Dark mode pétrol, panneau d'accessibilité (dyslexie, contraste, zoom) |
| 1.4 | Avril 2026 | Synchronisation Gitea sécurisée — `GITEA_TOKEN` + `scripts/push-gitea.sh` |
| 1.5 | Avril 2026 | Droit pénal français intégré dans le filtre IA (16 sections) |
| 1.6 | Avril 2026 | Panel admin sécurisé (`/admin`), signalement public, export CSV |
---
@@ -367,7 +369,67 @@ Permissions requises : `repository` (lecture + écriture).
---
## 16. Contacts et ressources
## 16. Panel d'administration
### Accès
Le panel admin est accessible à l'URL `/admin` — il n'est **pas lié dans la navigation publique**. Seul l'administrateur connaît son existence.
```
https://votredomaine.fr/admin
```
### Authentification
À l'ouverture, un formulaire de connexion demande le mot de passe. Celui-ci est la valeur de la variable `ADMIN_SECRET` configurée dans les secrets de l'environnement. La session est stockée dans `sessionStorage` du navigateur — elle est perdue à la fermeture de l'onglet.
| Variable | Où la définir |
|----------|---------------|
| `ADMIN_SECRET` | Replit → Secrets · ou `.env` en auto-hébergement |
### Fonctionnalités
| Fonctionnalité | Description |
|----------------|-------------|
| **Tableau de bord** | Compteurs : total, acceptées, rejetées, signalées |
| **Liste filtrée** | Onglets : Toutes · Acceptées · Rejetées · Signalées |
| **Recherche** | Filtrage textuel en temps réel sur le contenu |
| **Suppression** | Suppression unitaire avec confirmation, puis régénération automatique de la synthèse |
| **Suppression en masse** | Sélection multiple → suppression groupée → synthèse régénérée |
| **Override IA** | Forcer l'acceptation ou le rejet d'une contribution, avec motif |
| **Note admin** | Annotation interne sur une contribution (invisible du public) |
| **Retrait de signalement** | Marquer un signalement comme traité |
| **Régénération manuelle** | Forcer la régénération complète de la synthèse |
| **Export CSV** | Télécharger toutes les contributions (UTF-8 BOM, compatible Excel) |
### Signalement public
Sur la page d'accueil, chaque contribution affiche un bouton **Signaler** au survol (icône drapeau). Ce bouton est limité à 3 signalements par minute et 10 par heure par IP. Les contributions signalées apparaissent en premier dans l'onglet **Signalées** du panel admin.
### Sécurité
- Toutes les routes `/api/admin/*` vérifient le header `Authorization: Bearer <ADMIN_SECRET>`
- La route de login est limitée à 10 tentatives par minute (protection brute-force)
- Aucune session persistante côté serveur — pas de cookie, pas de base de sessions
- L'URL `/admin` n'est pas mentionnée dans le code source public ni dans le `robots.txt`
### Routes API admin
| Méthode | Route | Action |
|---------|-------|--------|
| `POST` | `/api/admin/login` | Vérification du mot de passe |
| `GET` | `/api/admin/stats` | Statistiques détaillées |
| `GET` | `/api/admin/ideas` | Liste avec filtres (`status`, `page`, `q`) |
| `DELETE` | `/api/admin/ideas/<id>` | Suppression unitaire |
| `POST` | `/api/admin/ideas/bulk-delete` | Suppression en masse (`{ids: [...]}`) |
| `POST` | `/api/admin/ideas/<id>/override` | Override IA (`{accepted, reason, note}`) |
| `POST` | `/api/admin/ideas/<id>/unflag` | Retirer le signalement |
| `POST` | `/api/admin/synthesis/regenerate` | Forcer la régénération |
| `GET` | `/api/admin/export/csv` | Export CSV (toutes les contributions) |
---
## 17. Contacts et ressources
- Documentation Mistral : https://docs.mistral.ai
- PostgreSQL : https://www.postgresql.org/docs/
+5 -1
View File
@@ -190,6 +190,9 @@ MISTRAL_API_KEY=votre_cle_mistral_ici
# Sécurité Flask
SESSION_SECRET=generez-une-chaine-aleatoire-longue-ici
# Panel admin — mot de passe de connexion à /admin (OBLIGATOIRE)
ADMIN_SECRET=choisissez-un-mot-de-passe-long-et-complexe-ici
# Modèles IA (valeurs par défaut si omis)
# FILTER_MODEL=mistral-small-latest
# SYNTHESIS_MODEL=mistral-large-latest
@@ -198,10 +201,11 @@ SESSION_SECRET=generez-une-chaine-aleatoire-longue-ici
VITE_APP_URL=https://votredomaine.fr
```
Générer un SESSION_SECRET :
Générer `SESSION_SECRET` et `ADMIN_SECRET` :
```bash
python3 -c "import secrets; print(secrets.token_hex(32))"
# Exécuter deux fois pour obtenir deux valeurs distinctes
```
### 8.2 Changer le domaine (QR code)