Checkpoint: Correction de l'authentification locale : utilisation de sdk.createSessionToken() au lieu de jsonwebtoken pour compatibilité avec le système OAuth
This commit is contained in:
464
DEPLOYMENT.md
Normal file
464
DEPLOYMENT.md
Normal file
@@ -0,0 +1,464 @@
|
|||||||
|
# Guide de Déploiement - Gestion des Formations Manager Itinova
|
||||||
|
|
||||||
|
## Table des matières
|
||||||
|
|
||||||
|
1. [Prérequis](#prérequis)
|
||||||
|
2. [Installation locale](#installation-locale)
|
||||||
|
3. [Configuration](#configuration)
|
||||||
|
4. [Déploiement en production](#déploiement-en-production)
|
||||||
|
5. [Migration de base de données](#migration-de-base-de-données)
|
||||||
|
6. [Maintenance](#maintenance)
|
||||||
|
7. [Dépannage](#dépannage)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prérequis
|
||||||
|
|
||||||
|
### Environnement de développement
|
||||||
|
|
||||||
|
- **Node.js** : version 22.13.0 ou supérieure
|
||||||
|
- **pnpm** : gestionnaire de paquets (installé avec Node.js)
|
||||||
|
- **Base de données** : MySQL 8.0+ ou TiDB (compatible MySQL)
|
||||||
|
- **Git** : pour le contrôle de version
|
||||||
|
|
||||||
|
### Services externes (optionnels)
|
||||||
|
|
||||||
|
- **Resend** : pour l'envoi d'emails (clé API requise)
|
||||||
|
- **Plateforme Manus** : pour l'authentification OAuth (déjà configuré)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Installation locale
|
||||||
|
|
||||||
|
### 1. Cloner le projet
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Si vous avez accès au dépôt Git
|
||||||
|
git clone <url-du-depot>
|
||||||
|
cd formation-manager-itinova
|
||||||
|
|
||||||
|
# Sinon, extraire l'archive
|
||||||
|
unzip formation-manager-itinova.zip
|
||||||
|
cd formation-manager-itinova
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Installer les dépendances
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm install
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Configurer les variables d'environnement
|
||||||
|
|
||||||
|
Créer un fichier `.env` à la racine du projet :
|
||||||
|
|
||||||
|
```env
|
||||||
|
# Base de données
|
||||||
|
DATABASE_URL=mysql://user:password@localhost:3306/formation_manager
|
||||||
|
|
||||||
|
# JWT Secret (générer une clé aléatoire sécurisée)
|
||||||
|
JWT_SECRET=votre_cle_secrete_tres_longue_et_aleatoire
|
||||||
|
|
||||||
|
# OAuth Manus (déjà configuré sur la plateforme)
|
||||||
|
OAUTH_SERVER_URL=https://api.manus.im
|
||||||
|
VITE_OAUTH_PORTAL_URL=https://login.manus.im
|
||||||
|
VITE_APP_ID=votre_app_id
|
||||||
|
|
||||||
|
# Propriétaire
|
||||||
|
OWNER_OPEN_ID=votre_open_id
|
||||||
|
OWNER_NAME=Nom du propriétaire
|
||||||
|
|
||||||
|
# Application
|
||||||
|
VITE_APP_TITLE=Gestion des Formations Manager Itinova
|
||||||
|
VITE_APP_LOGO=/logo.svg
|
||||||
|
|
||||||
|
# APIs Manus (optionnel)
|
||||||
|
BUILT_IN_FORGE_API_URL=https://forge.manus.im
|
||||||
|
BUILT_IN_FORGE_API_KEY=votre_cle_api
|
||||||
|
VITE_FRONTEND_FORGE_API_KEY=votre_cle_frontend
|
||||||
|
VITE_FRONTEND_FORGE_API_URL=https://forge.manus.im
|
||||||
|
|
||||||
|
# Analytics (optionnel)
|
||||||
|
VITE_ANALYTICS_ENDPOINT=https://analytics.manus.im
|
||||||
|
VITE_ANALYTICS_WEBSITE_ID=votre_website_id
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Initialiser la base de données
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Créer la base de données
|
||||||
|
mysql -u root -p -e "CREATE DATABASE formation_manager CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
||||||
|
|
||||||
|
# Appliquer les migrations
|
||||||
|
pnpm db:push
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Créer l'utilisateur administrateur
|
||||||
|
|
||||||
|
L'utilisateur administrateur est créé automatiquement au premier lancement :
|
||||||
|
|
||||||
|
- **Identifiant** : `adminServFormation`
|
||||||
|
- **Mot de passe** : `Itinova69!`
|
||||||
|
- **Email** : `admin@formation.local` (modifiable)
|
||||||
|
|
||||||
|
### 6. Lancer l'application en développement
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm dev
|
||||||
|
```
|
||||||
|
|
||||||
|
L'application sera accessible à l'adresse : `http://localhost:3000`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Configuration SMTP (Resend)
|
||||||
|
|
||||||
|
1. Créer un compte sur [Resend](https://resend.com)
|
||||||
|
2. Générer une clé API
|
||||||
|
3. Se connecter à l'application avec l'utilisateur admin
|
||||||
|
4. Aller dans **Configuration SMTP**
|
||||||
|
5. Saisir :
|
||||||
|
- **Clé API Resend** : votre clé API
|
||||||
|
- **Email expéditeur** : votre email vérifié sur Resend
|
||||||
|
- **Nom de l'expéditeur** : Itinova Formation
|
||||||
|
6. Activer le mode **Production**
|
||||||
|
7. Tester l'envoi
|
||||||
|
|
||||||
|
### Personnalisation des templates d'emails
|
||||||
|
|
||||||
|
1. Se connecter en tant qu'administrateur
|
||||||
|
2. Aller dans **Templates d'emails**
|
||||||
|
3. Modifier les templates selon vos besoins :
|
||||||
|
- Email de confirmation d'inscription
|
||||||
|
- Email teaser
|
||||||
|
- Email de rappel J-7
|
||||||
|
|
||||||
|
### Gestion des utilisateurs
|
||||||
|
|
||||||
|
1. Se connecter en tant qu'administrateur
|
||||||
|
2. Aller dans **Utilisateurs**
|
||||||
|
3. Créer de nouveaux utilisateurs avec identifiant et mot de passe
|
||||||
|
4. Attribuer le rôle **admin** ou **user**
|
||||||
|
|
||||||
|
**Note** : L'utilisateur `adminServFormation` ne peut pas être supprimé et garantit un accès permanent à l'administration.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Déploiement en production
|
||||||
|
|
||||||
|
### Option 1 : Déploiement sur la plateforme Manus (recommandé)
|
||||||
|
|
||||||
|
L'application est déjà configurée pour la plateforme Manus. Pour déployer :
|
||||||
|
|
||||||
|
1. Se connecter à l'interface de gestion Manus
|
||||||
|
2. Créer un checkpoint via le bouton **Save Checkpoint**
|
||||||
|
3. Cliquer sur le bouton **Publish** dans l'en-tête
|
||||||
|
4. Configurer le domaine personnalisé si nécessaire
|
||||||
|
5. Publier l'application
|
||||||
|
|
||||||
|
**Avantages** :
|
||||||
|
- Déploiement automatique
|
||||||
|
- SSL/TLS automatique
|
||||||
|
- Scaling automatique
|
||||||
|
- Base de données TiDB incluse
|
||||||
|
- Pas de configuration serveur nécessaire
|
||||||
|
|
||||||
|
### Option 2 : Déploiement manuel sur serveur VPS
|
||||||
|
|
||||||
|
#### Prérequis serveur
|
||||||
|
|
||||||
|
- Ubuntu 22.04 LTS ou supérieur
|
||||||
|
- 2 CPU, 4 GB RAM minimum
|
||||||
|
- Node.js 22.13.0+
|
||||||
|
- MySQL 8.0+ ou MariaDB 10.6+
|
||||||
|
- Nginx (reverse proxy)
|
||||||
|
- Certbot (SSL/TLS)
|
||||||
|
|
||||||
|
#### Étapes de déploiement
|
||||||
|
|
||||||
|
1. **Préparer le serveur**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Mettre à jour le système
|
||||||
|
sudo apt update && sudo apt upgrade -y
|
||||||
|
|
||||||
|
# Installer Node.js 22
|
||||||
|
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
|
||||||
|
sudo apt install -y nodejs
|
||||||
|
|
||||||
|
# Installer pnpm
|
||||||
|
npm install -g pnpm
|
||||||
|
|
||||||
|
# Installer MySQL
|
||||||
|
sudo apt install -y mysql-server
|
||||||
|
|
||||||
|
# Installer Nginx
|
||||||
|
sudo apt install -y nginx
|
||||||
|
|
||||||
|
# Installer Certbot
|
||||||
|
sudo apt install -y certbot python3-certbot-nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Déployer l'application**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Créer un utilisateur dédié
|
||||||
|
sudo useradd -m -s /bin/bash formation
|
||||||
|
sudo su - formation
|
||||||
|
|
||||||
|
# Cloner ou copier le projet
|
||||||
|
cd /home/formation
|
||||||
|
# Copier les fichiers du projet ici
|
||||||
|
|
||||||
|
# Installer les dépendances
|
||||||
|
pnpm install
|
||||||
|
|
||||||
|
# Configurer les variables d'environnement
|
||||||
|
cp .env.example .env
|
||||||
|
nano .env
|
||||||
|
|
||||||
|
# Build de production
|
||||||
|
pnpm build
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Configurer le service systemd**
|
||||||
|
|
||||||
|
Créer le fichier `/etc/systemd/system/formation-manager.service` :
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Unit]
|
||||||
|
Description=Formation Manager Itinova
|
||||||
|
After=network.target mysql.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=formation
|
||||||
|
WorkingDirectory=/home/formation/formation-manager-itinova
|
||||||
|
ExecStart=/usr/bin/pnpm start
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=10
|
||||||
|
Environment=NODE_ENV=production
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
Activer et démarrer le service :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable formation-manager
|
||||||
|
sudo systemctl start formation-manager
|
||||||
|
sudo systemctl status formation-manager
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Configurer Nginx**
|
||||||
|
|
||||||
|
Créer le fichier `/etc/nginx/sites-available/formation-manager` :
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name votre-domaine.com;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://localhost:3000;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection 'upgrade';
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_cache_bypass $http_upgrade;
|
||||||
|
}
|
||||||
|
|
||||||
|
client_max_body_size 10M;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Activer le site :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo ln -s /etc/nginx/sites-available/formation-manager /etc/nginx/sites-enabled/
|
||||||
|
sudo nginx -t
|
||||||
|
sudo systemctl reload nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **Configurer SSL/TLS avec Let's Encrypt**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo certbot --nginx -d votre-domaine.com
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Migration de base de données
|
||||||
|
|
||||||
|
### Appliquer les migrations
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# En développement
|
||||||
|
pnpm db:push
|
||||||
|
|
||||||
|
# En production (avec sauvegarde)
|
||||||
|
# 1. Sauvegarder la base de données
|
||||||
|
mysqldump -u root -p formation_manager > backup_$(date +%Y%m%d_%H%M%S).sql
|
||||||
|
|
||||||
|
# 2. Appliquer les migrations
|
||||||
|
pnpm db:push
|
||||||
|
```
|
||||||
|
|
||||||
|
### Restaurer une sauvegarde
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mysql -u root -p formation_manager < backup_20250123_120000.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Maintenance
|
||||||
|
|
||||||
|
### Logs de l'application
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Logs systemd
|
||||||
|
sudo journalctl -u formation-manager -f
|
||||||
|
|
||||||
|
# Logs Nginx
|
||||||
|
sudo tail -f /var/log/nginx/access.log
|
||||||
|
sudo tail -f /var/log/nginx/error.log
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mise à jour de l'application
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Arrêter le service
|
||||||
|
sudo systemctl stop formation-manager
|
||||||
|
|
||||||
|
# Mettre à jour le code
|
||||||
|
cd /home/formation/formation-manager-itinova
|
||||||
|
git pull origin main
|
||||||
|
|
||||||
|
# Installer les nouvelles dépendances
|
||||||
|
pnpm install
|
||||||
|
|
||||||
|
# Appliquer les migrations
|
||||||
|
pnpm db:push
|
||||||
|
|
||||||
|
# Rebuild
|
||||||
|
pnpm build
|
||||||
|
|
||||||
|
# Redémarrer le service
|
||||||
|
sudo systemctl start formation-manager
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sauvegarde automatique
|
||||||
|
|
||||||
|
Créer un script de sauvegarde `/home/formation/backup.sh` :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
BACKUP_DIR="/home/formation/backups"
|
||||||
|
DATE=$(date +%Y%m%d_%H%M%S)
|
||||||
|
|
||||||
|
# Créer le répertoire de sauvegarde
|
||||||
|
mkdir -p $BACKUP_DIR
|
||||||
|
|
||||||
|
# Sauvegarder la base de données
|
||||||
|
mysqldump -u root -p formation_manager > $BACKUP_DIR/db_$DATE.sql
|
||||||
|
|
||||||
|
# Compresser
|
||||||
|
gzip $BACKUP_DIR/db_$DATE.sql
|
||||||
|
|
||||||
|
# Supprimer les sauvegardes de plus de 30 jours
|
||||||
|
find $BACKUP_DIR -name "db_*.sql.gz" -mtime +30 -delete
|
||||||
|
|
||||||
|
echo "Sauvegarde terminée : $BACKUP_DIR/db_$DATE.sql.gz"
|
||||||
|
```
|
||||||
|
|
||||||
|
Ajouter une tâche cron :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
crontab -e
|
||||||
|
|
||||||
|
# Sauvegarde quotidienne à 2h du matin
|
||||||
|
0 2 * * * /home/formation/backup.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dépannage
|
||||||
|
|
||||||
|
### L'application ne démarre pas
|
||||||
|
|
||||||
|
1. Vérifier les logs :
|
||||||
|
```bash
|
||||||
|
sudo journalctl -u formation-manager -n 50
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Vérifier la connexion à la base de données :
|
||||||
|
```bash
|
||||||
|
mysql -u root -p -e "SHOW DATABASES;"
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Vérifier les variables d'environnement dans `.env`
|
||||||
|
|
||||||
|
### Erreur de connexion à la base de données
|
||||||
|
|
||||||
|
1. Vérifier que MySQL est démarré :
|
||||||
|
```bash
|
||||||
|
sudo systemctl status mysql
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Tester la connexion :
|
||||||
|
```bash
|
||||||
|
mysql -u user -p formation_manager
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Vérifier l'URL de connexion dans `.env`
|
||||||
|
|
||||||
|
### Les emails ne sont pas envoyés
|
||||||
|
|
||||||
|
1. Vérifier la configuration SMTP dans l'interface admin
|
||||||
|
2. Vérifier que la clé API Resend est valide
|
||||||
|
3. Vérifier que l'email expéditeur est vérifié sur Resend
|
||||||
|
4. Consulter les logs de l'application
|
||||||
|
|
||||||
|
### Problème de permissions
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Corriger les permissions
|
||||||
|
sudo chown -R formation:formation /home/formation/formation-manager-itinova
|
||||||
|
sudo chmod -R 755 /home/formation/formation-manager-itinova
|
||||||
|
```
|
||||||
|
|
||||||
|
### L'authentification locale ne fonctionne pas
|
||||||
|
|
||||||
|
1. Vérifier que `JWT_SECRET` est défini dans `.env`
|
||||||
|
2. Vérifier que l'utilisateur `adminServFormation` existe dans la base de données
|
||||||
|
3. Réinitialiser le mot de passe si nécessaire via SQL :
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Le mot de passe hashé pour "Itinova69!"
|
||||||
|
UPDATE users
|
||||||
|
SET password = '$2a$10$...'
|
||||||
|
WHERE username = 'adminServFormation';
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
Pour toute question ou problème :
|
||||||
|
|
||||||
|
1. Consulter la documentation complète dans le dossier `/docs`
|
||||||
|
2. Vérifier les logs de l'application
|
||||||
|
3. Contacter l'équipe de développement
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Version** : 1.0.0
|
||||||
|
**Dernière mise à jour** : 23 novembre 2025
|
||||||
290
INSTALL.md
Normal file
290
INSTALL.md
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
# Guide d'Installation Rapide
|
||||||
|
|
||||||
|
## Installation en 5 minutes
|
||||||
|
|
||||||
|
Ce guide vous permet d'installer et de démarrer l'application rapidement en environnement de développement.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prérequis
|
||||||
|
|
||||||
|
Avant de commencer, assurez-vous d'avoir installé :
|
||||||
|
|
||||||
|
- **Node.js 22+** : [Télécharger Node.js](https://nodejs.org/)
|
||||||
|
- **MySQL 8.0+** ou **MariaDB 10.6+** : [Télécharger MySQL](https://dev.mysql.com/downloads/)
|
||||||
|
- **Git** (optionnel) : [Télécharger Git](https://git-scm.com/)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Étape 1 : Récupérer le projet
|
||||||
|
|
||||||
|
### Option A : Depuis l'archive ZIP
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Extraire l'archive
|
||||||
|
unzip formation-manager-itinova.zip
|
||||||
|
cd formation-manager-itinova
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option B : Depuis Git (si disponible)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Cloner le dépôt
|
||||||
|
git clone <url-du-depot>
|
||||||
|
cd formation-manager-itinova
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Étape 2 : Installer les dépendances
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Installer pnpm si nécessaire
|
||||||
|
npm install -g pnpm
|
||||||
|
|
||||||
|
# Installer les dépendances du projet
|
||||||
|
pnpm install
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Étape 3 : Configurer la base de données
|
||||||
|
|
||||||
|
### 3.1 Créer la base de données
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Se connecter à MySQL
|
||||||
|
mysql -u root -p
|
||||||
|
|
||||||
|
# Créer la base de données
|
||||||
|
CREATE DATABASE formation_manager CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
||||||
|
# Créer un utilisateur dédié (optionnel mais recommandé)
|
||||||
|
CREATE USER 'formation_user'@'localhost' IDENTIFIED BY 'votre_mot_de_passe_securise';
|
||||||
|
GRANT ALL PRIVILEGES ON formation_manager.* TO 'formation_user'@'localhost';
|
||||||
|
FLUSH PRIVILEGES;
|
||||||
|
|
||||||
|
# Quitter MySQL
|
||||||
|
EXIT;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 Configurer les variables d'environnement
|
||||||
|
|
||||||
|
Créer un fichier `.env` à la racine du projet :
|
||||||
|
|
||||||
|
```env
|
||||||
|
# Base de données
|
||||||
|
DATABASE_URL=mysql://formation_user:votre_mot_de_passe_securise@localhost:3306/formation_manager
|
||||||
|
|
||||||
|
# JWT Secret (générer une clé aléatoire)
|
||||||
|
JWT_SECRET=votre_cle_secrete_aleatoire_tres_longue_minimum_32_caracteres
|
||||||
|
|
||||||
|
# Application
|
||||||
|
VITE_APP_TITLE=Gestion des Formations Manager Itinova
|
||||||
|
VITE_APP_LOGO=/logo.svg
|
||||||
|
NODE_ENV=development
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note** : Pour générer une clé JWT sécurisée, vous pouvez utiliser :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Linux/Mac
|
||||||
|
openssl rand -base64 32
|
||||||
|
|
||||||
|
# Node.js
|
||||||
|
node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 Initialiser la base de données
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Appliquer les migrations (créer les tables)
|
||||||
|
pnpm db:push
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Étape 4 : Démarrer l'application
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Lancer le serveur de développement
|
||||||
|
pnpm dev
|
||||||
|
```
|
||||||
|
|
||||||
|
L'application sera accessible à l'adresse : **http://localhost:3000**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Étape 5 : Première connexion
|
||||||
|
|
||||||
|
### Connexion avec l'utilisateur administrateur local
|
||||||
|
|
||||||
|
1. Ouvrir **http://localhost:3000** dans votre navigateur
|
||||||
|
2. Cliquer sur **"Se connecter localement"**
|
||||||
|
3. Utiliser les identifiants par défaut :
|
||||||
|
- **Identifiant** : `adminServFormation`
|
||||||
|
- **Mot de passe** : `Itinova69!`
|
||||||
|
|
||||||
|
**Important** : Cet utilisateur est créé automatiquement au premier lancement et ne peut pas être supprimé.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuration initiale
|
||||||
|
|
||||||
|
Une fois connecté, vous pouvez :
|
||||||
|
|
||||||
|
### 1. Configurer l'envoi d'emails (optionnel)
|
||||||
|
|
||||||
|
1. Créer un compte sur [Resend](https://resend.com)
|
||||||
|
2. Générer une clé API
|
||||||
|
3. Dans l'application, aller dans **Configuration SMTP**
|
||||||
|
4. Saisir :
|
||||||
|
- **Clé API Resend** : votre clé API
|
||||||
|
- **Email expéditeur** : votre email vérifié
|
||||||
|
- **Nom de l'expéditeur** : Itinova Formation
|
||||||
|
5. Activer le mode **Production**
|
||||||
|
|
||||||
|
### 2. Créer des utilisateurs supplémentaires
|
||||||
|
|
||||||
|
1. Aller dans **Utilisateurs**
|
||||||
|
2. Cliquer sur **Ajouter un utilisateur**
|
||||||
|
3. Remplir les informations :
|
||||||
|
- Nom d'utilisateur
|
||||||
|
- Mot de passe
|
||||||
|
- Email
|
||||||
|
- Rôle (admin ou user)
|
||||||
|
|
||||||
|
### 3. Créer vos premières formations
|
||||||
|
|
||||||
|
1. Aller dans **Formations**
|
||||||
|
2. Cliquer sur **Nouvelle formation**
|
||||||
|
3. Remplir les informations de la formation
|
||||||
|
4. Créer des séquences associées
|
||||||
|
|
||||||
|
### 4. Importer les apprenants
|
||||||
|
|
||||||
|
1. Aller dans **Apprenants**
|
||||||
|
2. Ajouter les apprenants un par un ou créer un script d'import
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Commandes utiles
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Démarrer le serveur de développement
|
||||||
|
pnpm dev
|
||||||
|
|
||||||
|
# Builder pour la production
|
||||||
|
pnpm build
|
||||||
|
|
||||||
|
# Démarrer en mode production
|
||||||
|
pnpm start
|
||||||
|
|
||||||
|
# Appliquer les migrations
|
||||||
|
pnpm db:push
|
||||||
|
|
||||||
|
# Générer les migrations (après modification du schéma)
|
||||||
|
pnpm db:generate
|
||||||
|
|
||||||
|
# Ouvrir Drizzle Studio (interface graphique pour la base de données)
|
||||||
|
pnpm db:studio
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Structure du projet
|
||||||
|
|
||||||
|
```
|
||||||
|
formation-manager-itinova/
|
||||||
|
├── client/ # Application frontend (React)
|
||||||
|
│ ├── public/ # Fichiers statiques
|
||||||
|
│ └── src/
|
||||||
|
│ ├── pages/ # Pages de l'application
|
||||||
|
│ ├── components/ # Composants réutilisables
|
||||||
|
│ └── lib/ # Bibliothèques et utilitaires
|
||||||
|
├── server/ # Application backend (Express + tRPC)
|
||||||
|
│ ├── routers.ts # Définition des routes API
|
||||||
|
│ ├── db.ts # Fonctions d'accès à la base de données
|
||||||
|
│ └── _core/ # Configuration du serveur
|
||||||
|
├── drizzle/ # Schéma et migrations de base de données
|
||||||
|
│ └── schema.ts # Définition des tables
|
||||||
|
├── shared/ # Code partagé entre client et serveur
|
||||||
|
├── .env # Variables d'environnement (à créer)
|
||||||
|
├── package.json # Dépendances du projet
|
||||||
|
├── deploy.sh # Script de déploiement automatique
|
||||||
|
├── DEPLOYMENT.md # Guide de déploiement complet
|
||||||
|
└── README.md # Documentation principale
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dépannage rapide
|
||||||
|
|
||||||
|
### L'application ne démarre pas
|
||||||
|
|
||||||
|
**Erreur : "Cannot find module"**
|
||||||
|
```bash
|
||||||
|
# Réinstaller les dépendances
|
||||||
|
rm -rf node_modules
|
||||||
|
pnpm install
|
||||||
|
```
|
||||||
|
|
||||||
|
**Erreur : "ECONNREFUSED" (connexion à la base de données)**
|
||||||
|
```bash
|
||||||
|
# Vérifier que MySQL est démarré
|
||||||
|
sudo systemctl status mysql
|
||||||
|
|
||||||
|
# Vérifier l'URL de connexion dans .env
|
||||||
|
cat .env | grep DATABASE_URL
|
||||||
|
```
|
||||||
|
|
||||||
|
### Les migrations échouent
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Vérifier que la base de données existe
|
||||||
|
mysql -u root -p -e "SHOW DATABASES;"
|
||||||
|
|
||||||
|
# Recréer la base de données si nécessaire
|
||||||
|
mysql -u root -p -e "DROP DATABASE IF EXISTS formation_manager; CREATE DATABASE formation_manager CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
||||||
|
|
||||||
|
# Réappliquer les migrations
|
||||||
|
pnpm db:push
|
||||||
|
```
|
||||||
|
|
||||||
|
### Impossible de se connecter
|
||||||
|
|
||||||
|
**Vérifier que JWT_SECRET est défini**
|
||||||
|
```bash
|
||||||
|
cat .env | grep JWT_SECRET
|
||||||
|
```
|
||||||
|
|
||||||
|
Si vide, générer une nouvelle clé :
|
||||||
|
```bash
|
||||||
|
echo "JWT_SECRET=$(openssl rand -base64 32)" >> .env
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prochaines étapes
|
||||||
|
|
||||||
|
Une fois l'installation terminée :
|
||||||
|
|
||||||
|
1. **Lire la documentation complète** : `DEPLOYMENT.md`
|
||||||
|
2. **Personnaliser les templates d'emails** : Menu "Templates d'emails"
|
||||||
|
3. **Configurer les rappels automatiques** : Menu "Rappels"
|
||||||
|
4. **Tester l'envoi d'emails** : Configuration SMTP
|
||||||
|
5. **Déployer en production** : Suivre le guide `DEPLOYMENT.md`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
Pour toute question ou problème :
|
||||||
|
|
||||||
|
- Consulter `DEPLOYMENT.md` pour la documentation complète
|
||||||
|
- Vérifier les logs de l'application
|
||||||
|
- Contacter l'équipe de développement
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Bon déploiement ! 🚀**
|
||||||
455
README.md
Normal file
455
README.md
Normal file
@@ -0,0 +1,455 @@
|
|||||||
|
# Gestion des Formations Manager Itinova
|
||||||
|
|
||||||
|
Application web complète de gestion des formations pour Manager Itinova, permettant la planification, l'organisation et le suivi des formations avec gestion automatisée des inscriptions, rappels et communications.
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Table des matières
|
||||||
|
|
||||||
|
- [Aperçu](#aperçu)
|
||||||
|
- [Fonctionnalités](#fonctionnalités)
|
||||||
|
- [Technologies](#technologies)
|
||||||
|
- [Installation rapide](#installation-rapide)
|
||||||
|
- [Documentation](#documentation)
|
||||||
|
- [Architecture](#architecture)
|
||||||
|
- [Utilisation](#utilisation)
|
||||||
|
- [Déploiement](#déploiement)
|
||||||
|
- [Maintenance](#maintenance)
|
||||||
|
- [Support](#support)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Aperçu
|
||||||
|
|
||||||
|
L'application **Gestion des Formations Manager Itinova** est une solution complète pour gérer l'ensemble du cycle de vie des formations :
|
||||||
|
|
||||||
|
- Création et planification des formations et séquences
|
||||||
|
- Gestion des apprenants et inscriptions avec validation automatique
|
||||||
|
- Génération automatique de documents (listes, feuilles de présence)
|
||||||
|
- Envoi automatique d'emails (confirmations, rappels)
|
||||||
|
- Calendrier interactif et système de rappels
|
||||||
|
- Rapports et statistiques détaillés
|
||||||
|
|
||||||
|
L'application offre **deux modes d'authentification** :
|
||||||
|
- **Connexion Manus OAuth** : pour les utilisateurs avec compte Manus (Google, Microsoft, Apple)
|
||||||
|
- **Connexion locale** : pour les administrateurs avec identifiant et mot de passe
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✨ Fonctionnalités
|
||||||
|
|
||||||
|
### 🔐 Authentification dual
|
||||||
|
|
||||||
|
- Page de choix de connexion
|
||||||
|
- Authentification Manus OAuth (Google, Microsoft, Apple)
|
||||||
|
- Authentification locale par identifiant/mot de passe
|
||||||
|
- Gestion des rôles (admin, user)
|
||||||
|
- Utilisateur administrateur permanent non supprimable
|
||||||
|
|
||||||
|
### 📚 Gestion des formations
|
||||||
|
|
||||||
|
- CRUD complet des formations
|
||||||
|
- Support de multiples séquences par formation
|
||||||
|
- Jusqu'à 4 dates par séquence
|
||||||
|
- Champs personnalisés :
|
||||||
|
- Public cible (Directeurs, Chefs de service, Autre, Tous)
|
||||||
|
- Formateur avec autocomplétion
|
||||||
|
- Capacité maximale par séquence
|
||||||
|
- Lieu de formation
|
||||||
|
- Barre de progression colorée (vert/orange/rouge) selon le taux de remplissage
|
||||||
|
- Filtres et recherche avancée
|
||||||
|
|
||||||
|
### 👥 Gestion des apprenants
|
||||||
|
|
||||||
|
- CRUD complet des apprenants
|
||||||
|
- Fonction (Directeur, Chef de service, Autre)
|
||||||
|
- Page de détail par apprenant avec historique complet
|
||||||
|
- Système d'inscription avec :
|
||||||
|
- Validation de capacité automatique
|
||||||
|
- Détection anti-doublons
|
||||||
|
- Blocage automatique à J-15
|
||||||
|
- Alerte si public cible incompatible
|
||||||
|
|
||||||
|
### 📅 Calendrier et rappels
|
||||||
|
|
||||||
|
- Calendrier mensuel interactif
|
||||||
|
- Navigation par mois
|
||||||
|
- Visualisation des séquences par date
|
||||||
|
- Système de rappels automatiques configurables :
|
||||||
|
- Rappel J-7
|
||||||
|
- Rappel J-3
|
||||||
|
- Rappel J-1
|
||||||
|
- Rappel personnalisé
|
||||||
|
|
||||||
|
### 📄 Exports et documents
|
||||||
|
|
||||||
|
- **Export Excel** : listes d'inscrits avec toutes les informations
|
||||||
|
- **Export PDF** : listes d'inscrits formatées
|
||||||
|
- **Feuilles de présence PDF** :
|
||||||
|
- Logo Itinova
|
||||||
|
- Double signature (matin/après-midi)
|
||||||
|
- Signature formateur
|
||||||
|
- Informations complètes de la séquence
|
||||||
|
|
||||||
|
### ✉️ Communications automatiques
|
||||||
|
|
||||||
|
- **Génération d'invitations Outlook** (.ics)
|
||||||
|
- **Emails automatiques** :
|
||||||
|
- Email de confirmation d'inscription
|
||||||
|
- Email teaser (présentation de la formation)
|
||||||
|
- Email de rappel J-7
|
||||||
|
- **Templates personnalisables** avec variables dynamiques
|
||||||
|
- **Configuration SMTP** avec Resend
|
||||||
|
- Mode test et production
|
||||||
|
|
||||||
|
### 📊 Rapports et statistiques
|
||||||
|
|
||||||
|
- Tableau de bord avec indicateurs clés
|
||||||
|
- Répartition des apprenants par fonction
|
||||||
|
- Analyse public cible vs fonction réelle
|
||||||
|
- Statistiques de remplissage des séquences
|
||||||
|
- Historique des inscriptions
|
||||||
|
|
||||||
|
### 👤 Administration
|
||||||
|
|
||||||
|
- Gestion des utilisateurs
|
||||||
|
- Création, modification, activation/désactivation
|
||||||
|
- Attribution des rôles
|
||||||
|
- Utilisateur admin permanent (adminServFormation)
|
||||||
|
- Templates d'emails personnalisables
|
||||||
|
- Configuration SMTP centralisée
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠 Technologies
|
||||||
|
|
||||||
|
### Frontend
|
||||||
|
|
||||||
|
- **React 19** : bibliothèque UI moderne
|
||||||
|
- **Tailwind CSS 4** : framework CSS utility-first
|
||||||
|
- **shadcn/ui** : composants UI accessibles
|
||||||
|
- **Wouter** : routage léger
|
||||||
|
- **TanStack Query** : gestion des données asynchrones
|
||||||
|
- **Recharts** : visualisation de données
|
||||||
|
- **date-fns** : manipulation de dates
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
|
||||||
|
- **Node.js 22** : runtime JavaScript
|
||||||
|
- **Express 4** : framework web
|
||||||
|
- **tRPC 11** : API type-safe end-to-end
|
||||||
|
- **Drizzle ORM** : ORM TypeScript-first
|
||||||
|
- **MySQL/TiDB** : base de données relationnelle
|
||||||
|
|
||||||
|
### Outils
|
||||||
|
|
||||||
|
- **TypeScript** : typage statique
|
||||||
|
- **Vite** : build tool rapide
|
||||||
|
- **pnpm** : gestionnaire de paquets performant
|
||||||
|
- **Vitest** : framework de tests
|
||||||
|
|
||||||
|
### Services externes
|
||||||
|
|
||||||
|
- **Resend** : envoi d'emails transactionnels
|
||||||
|
- **Manus OAuth** : authentification sociale
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Installation rapide
|
||||||
|
|
||||||
|
### Prérequis
|
||||||
|
|
||||||
|
- Node.js 22+
|
||||||
|
- MySQL 8.0+ ou MariaDB 10.6+
|
||||||
|
- pnpm (installé automatiquement avec Node.js)
|
||||||
|
|
||||||
|
### Installation en 4 étapes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Installer les dépendances
|
||||||
|
pnpm install
|
||||||
|
|
||||||
|
# 2. Configurer les variables d'environnement
|
||||||
|
cp .env.example .env
|
||||||
|
# Éditer .env avec vos paramètres
|
||||||
|
|
||||||
|
# 3. Créer et initialiser la base de données
|
||||||
|
mysql -u root -p -e "CREATE DATABASE formation_manager CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
||||||
|
pnpm db:push
|
||||||
|
|
||||||
|
# 4. Démarrer l'application
|
||||||
|
pnpm dev
|
||||||
|
```
|
||||||
|
|
||||||
|
L'application sera accessible à **http://localhost:3000**
|
||||||
|
|
||||||
|
### Connexion initiale
|
||||||
|
|
||||||
|
- **Identifiant** : `adminServFormation`
|
||||||
|
- **Mot de passe** : `Itinova69!`
|
||||||
|
|
||||||
|
📖 **Guide complet** : voir [INSTALL.md](INSTALL.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 Documentation
|
||||||
|
|
||||||
|
- **[INSTALL.md](INSTALL.md)** : Guide d'installation rapide (5 minutes)
|
||||||
|
- **[DEPLOYMENT.md](DEPLOYMENT.md)** : Guide de déploiement complet
|
||||||
|
- **[deploy.sh](deploy.sh)** : Script de déploiement automatique
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏗 Architecture
|
||||||
|
|
||||||
|
### Structure du projet
|
||||||
|
|
||||||
|
```
|
||||||
|
formation-manager-itinova/
|
||||||
|
├── client/ # Application frontend
|
||||||
|
│ ├── public/ # Fichiers statiques
|
||||||
|
│ │ └── logo.svg # Logo de l'application
|
||||||
|
│ └── src/
|
||||||
|
│ ├── pages/ # Pages de l'application
|
||||||
|
│ │ ├── LoginChoice.tsx
|
||||||
|
│ │ ├── Login.tsx
|
||||||
|
│ │ ├── Dashboard.tsx
|
||||||
|
│ │ ├── Formations.tsx
|
||||||
|
│ │ ├── Sequences.tsx
|
||||||
|
│ │ ├── Apprenants.tsx
|
||||||
|
│ │ └── ...
|
||||||
|
│ ├── components/ # Composants réutilisables
|
||||||
|
│ │ ├── DashboardLayout.tsx
|
||||||
|
│ │ └── ui/ # Composants shadcn/ui
|
||||||
|
│ └── lib/ # Bibliothèques et utilitaires
|
||||||
|
│ └── trpc.ts # Client tRPC
|
||||||
|
├── server/ # Application backend
|
||||||
|
│ ├── routers.ts # Routes API tRPC
|
||||||
|
│ ├── db.ts # Fonctions d'accès BDD
|
||||||
|
│ └── _core/ # Configuration serveur
|
||||||
|
│ ├── index.ts # Point d'entrée
|
||||||
|
│ ├── trpc.ts # Configuration tRPC
|
||||||
|
│ ├── localAuth.ts # Authentification locale
|
||||||
|
│ └── ...
|
||||||
|
├── drizzle/ # Base de données
|
||||||
|
│ └── schema.ts # Schéma des tables
|
||||||
|
├── shared/ # Code partagé
|
||||||
|
│ └── const.ts # Constantes
|
||||||
|
├── .env # Variables d'environnement
|
||||||
|
├── package.json # Dépendances
|
||||||
|
├── deploy.sh # Script de déploiement
|
||||||
|
├── DEPLOYMENT.md # Guide de déploiement
|
||||||
|
├── INSTALL.md # Guide d'installation
|
||||||
|
└── README.md # Ce fichier
|
||||||
|
```
|
||||||
|
|
||||||
|
### Base de données
|
||||||
|
|
||||||
|
**Tables principales** :
|
||||||
|
|
||||||
|
- `users` : utilisateurs de l'application
|
||||||
|
- `formations` : formations disponibles
|
||||||
|
- `sequences` : séquences de formation (dates)
|
||||||
|
- `apprenants` : apprenants inscrits
|
||||||
|
- `inscriptions` : inscriptions aux séquences
|
||||||
|
- `rappels` : rappels configurés
|
||||||
|
- `email_templates` : templates d'emails
|
||||||
|
- `email_config` : configuration SMTP
|
||||||
|
|
||||||
|
### API (tRPC)
|
||||||
|
|
||||||
|
L'API utilise tRPC pour une communication type-safe entre le client et le serveur.
|
||||||
|
|
||||||
|
**Routers principaux** :
|
||||||
|
|
||||||
|
- `auth` : authentification (me, logout)
|
||||||
|
- `formations` : CRUD formations
|
||||||
|
- `sequences` : CRUD séquences
|
||||||
|
- `apprenants` : CRUD apprenants
|
||||||
|
- `inscriptions` : gestion des inscriptions
|
||||||
|
- `rappels` : gestion des rappels
|
||||||
|
- `emails` : envoi d'emails et gestion des templates
|
||||||
|
- `users` : gestion des utilisateurs
|
||||||
|
- `stats` : statistiques et rapports
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💻 Utilisation
|
||||||
|
|
||||||
|
### Commandes disponibles
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Développement
|
||||||
|
pnpm dev # Démarrer le serveur de développement
|
||||||
|
pnpm build # Builder pour la production
|
||||||
|
pnpm start # Démarrer en mode production
|
||||||
|
|
||||||
|
# Base de données
|
||||||
|
pnpm db:push # Appliquer les migrations
|
||||||
|
pnpm db:generate # Générer les migrations
|
||||||
|
pnpm db:studio # Ouvrir Drizzle Studio
|
||||||
|
|
||||||
|
# Tests
|
||||||
|
pnpm test # Lancer les tests
|
||||||
|
pnpm test:ui # Interface de tests Vitest
|
||||||
|
|
||||||
|
# Linting
|
||||||
|
pnpm lint # Vérifier le code
|
||||||
|
pnpm format # Formater le code
|
||||||
|
```
|
||||||
|
|
||||||
|
### Workflow typique
|
||||||
|
|
||||||
|
1. **Créer une formation**
|
||||||
|
- Menu "Formations" → "Nouvelle formation"
|
||||||
|
- Remplir les informations
|
||||||
|
- Sauvegarder
|
||||||
|
|
||||||
|
2. **Créer des séquences**
|
||||||
|
- Cliquer sur la formation
|
||||||
|
- "Ajouter une séquence"
|
||||||
|
- Définir les dates (jusqu'à 4)
|
||||||
|
- Définir la capacité maximale
|
||||||
|
|
||||||
|
3. **Ajouter des apprenants**
|
||||||
|
- Menu "Apprenants" → "Ajouter un apprenant"
|
||||||
|
- Remplir nom, prénom, email, fonction
|
||||||
|
|
||||||
|
4. **Gérer les inscriptions**
|
||||||
|
- Depuis la page de la séquence
|
||||||
|
- Ou depuis la page de l'apprenant
|
||||||
|
- Validation automatique de la capacité
|
||||||
|
|
||||||
|
5. **Configurer les rappels**
|
||||||
|
- Menu "Rappels"
|
||||||
|
- Activer les rappels souhaités (J-7, J-3, J-1)
|
||||||
|
- Les emails seront envoyés automatiquement
|
||||||
|
|
||||||
|
6. **Exporter les documents**
|
||||||
|
- Liste des inscrits (Excel ou PDF)
|
||||||
|
- Feuille de présence (PDF)
|
||||||
|
- Invitation Outlook (.ics)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🌐 Déploiement
|
||||||
|
|
||||||
|
### Option 1 : Plateforme Manus (recommandé)
|
||||||
|
|
||||||
|
L'application est optimisée pour la plateforme Manus :
|
||||||
|
|
||||||
|
1. Créer un checkpoint
|
||||||
|
2. Cliquer sur "Publish"
|
||||||
|
3. Configurer le domaine
|
||||||
|
4. Publier
|
||||||
|
|
||||||
|
**Avantages** : déploiement automatique, SSL, scaling, base de données incluse.
|
||||||
|
|
||||||
|
### Option 2 : Serveur VPS
|
||||||
|
|
||||||
|
Utiliser le script de déploiement automatique :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Rendre le script exécutable
|
||||||
|
chmod +x deploy.sh
|
||||||
|
|
||||||
|
# Lancer le déploiement
|
||||||
|
./deploy.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Le script effectue automatiquement :
|
||||||
|
- Vérification des prérequis
|
||||||
|
- Installation des dépendances
|
||||||
|
- Sauvegarde de la base de données
|
||||||
|
- Application des migrations
|
||||||
|
- Build de l'application
|
||||||
|
- Redémarrage du service
|
||||||
|
|
||||||
|
📖 **Guide complet** : voir [DEPLOYMENT.md](DEPLOYMENT.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 Maintenance
|
||||||
|
|
||||||
|
### Sauvegardes automatiques
|
||||||
|
|
||||||
|
Le script de déploiement crée automatiquement des sauvegardes de la base de données.
|
||||||
|
|
||||||
|
Pour configurer des sauvegardes régulières :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Ajouter une tâche cron
|
||||||
|
crontab -e
|
||||||
|
|
||||||
|
# Sauvegarde quotidienne à 2h du matin
|
||||||
|
0 2 * * * /chemin/vers/backup.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mise à jour
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Récupérer les dernières modifications
|
||||||
|
git pull origin main
|
||||||
|
|
||||||
|
# Lancer le déploiement
|
||||||
|
./deploy.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Logs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Logs de l'application (systemd)
|
||||||
|
sudo journalctl -u formation-manager -f
|
||||||
|
|
||||||
|
# Logs Nginx
|
||||||
|
sudo tail -f /var/log/nginx/access.log
|
||||||
|
sudo tail -f /var/log/nginx/error.log
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📞 Support
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
|
||||||
|
- [Guide d'installation](INSTALL.md)
|
||||||
|
- [Guide de déploiement](DEPLOYMENT.md)
|
||||||
|
- Code source commenté
|
||||||
|
|
||||||
|
### Dépannage
|
||||||
|
|
||||||
|
Consultez la section "Dépannage" dans [DEPLOYMENT.md](DEPLOYMENT.md) pour les problèmes courants.
|
||||||
|
|
||||||
|
### Contact
|
||||||
|
|
||||||
|
Pour toute question ou problème :
|
||||||
|
- Consulter la documentation
|
||||||
|
- Vérifier les logs de l'application
|
||||||
|
- Contacter l'équipe de développement
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Licence
|
||||||
|
|
||||||
|
Ce projet est la propriété de Manager Itinova. Tous droits réservés.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🙏 Crédits
|
||||||
|
|
||||||
|
Développé avec ❤️ pour Manager Itinova
|
||||||
|
|
||||||
|
**Technologies utilisées** :
|
||||||
|
- React, Tailwind CSS, shadcn/ui
|
||||||
|
- Node.js, Express, tRPC
|
||||||
|
- Drizzle ORM, MySQL
|
||||||
|
- Resend, Manus OAuth
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Version** : 1.0.0
|
||||||
|
**Dernière mise à jour** : 23 novembre 2025
|
||||||
393
TROUBLESHOOTING.md
Normal file
393
TROUBLESHOOTING.md
Normal file
@@ -0,0 +1,393 @@
|
|||||||
|
# Guide de Dépannage - Problèmes de Connexion
|
||||||
|
|
||||||
|
## Problème : "Identifiant ou mot de passe incorrect"
|
||||||
|
|
||||||
|
Si vous ne parvenez pas à vous connecter avec l'utilisateur `adminServFormation` et le mot de passe `Itinova69!`, suivez ce guide étape par étape.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Diagnostic rapide
|
||||||
|
|
||||||
|
### Étape 1 : Exécuter le script de diagnostic
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /chemin/vers/formation-manager-itinova
|
||||||
|
./diagnose.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Ce script vérifie automatiquement :
|
||||||
|
- Les variables d'environnement (DATABASE_URL, JWT_SECRET)
|
||||||
|
- La connexion à la base de données
|
||||||
|
- L'existence des tables
|
||||||
|
- L'existence de l'utilisateur adminServFormation
|
||||||
|
- Les dépendances installées
|
||||||
|
- L'état du service
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Solutions par cause
|
||||||
|
|
||||||
|
### Cause 1 : JWT_SECRET non défini
|
||||||
|
|
||||||
|
**Symptôme** : Le diagnostic affiche `JWT_SECRET n'est pas définie`
|
||||||
|
|
||||||
|
**Solution** :
|
||||||
|
|
||||||
|
1. Générer une clé JWT sécurisée :
|
||||||
|
```bash
|
||||||
|
openssl rand -base64 32
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Ajouter la clé dans le fichier `.env` :
|
||||||
|
```bash
|
||||||
|
echo "JWT_SECRET=votre_cle_generee_ici" >> .env
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Redémarrer l'application :
|
||||||
|
```bash
|
||||||
|
# Si vous utilisez systemd
|
||||||
|
sudo systemctl restart formation-manager
|
||||||
|
|
||||||
|
# Ou en développement
|
||||||
|
pnpm dev
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Cause 2 : L'utilisateur adminServFormation n'existe pas
|
||||||
|
|
||||||
|
**Symptôme** : Le diagnostic affiche `Utilisateur 'adminServFormation' n'existe pas`
|
||||||
|
|
||||||
|
**Solution** :
|
||||||
|
|
||||||
|
Exécuter le script de réinitialisation :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./reset-admin-sql.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note** : Utilisez `reset-admin-sql.sh` (version SQL directe) plutôt que `reset-admin.sh` pour éviter les problèmes de compilation TypeScript.
|
||||||
|
|
||||||
|
Ce script va :
|
||||||
|
- Vérifier la configuration
|
||||||
|
- Créer l'utilisateur adminServFormation s'il n'existe pas
|
||||||
|
- Réinitialiser le mot de passe s'il existe déjà
|
||||||
|
- Afficher les identifiants de connexion
|
||||||
|
|
||||||
|
**Résultat attendu** :
|
||||||
|
```
|
||||||
|
✅ Utilisateur créé avec succès
|
||||||
|
|
||||||
|
🔑 Vous pouvez maintenant vous connecter avec:
|
||||||
|
Identifiant: adminServFormation
|
||||||
|
Mot de passe: Itinova69!
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Cause 3 : Les tables de la base de données n'existent pas
|
||||||
|
|
||||||
|
**Symptôme** : Le diagnostic affiche `Aucune table trouvée dans la base de données`
|
||||||
|
|
||||||
|
**Solution** :
|
||||||
|
|
||||||
|
1. Appliquer les migrations :
|
||||||
|
```bash
|
||||||
|
pnpm db:push
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Créer l'utilisateur administrateur :
|
||||||
|
```bash
|
||||||
|
./reset-admin-sql.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Redémarrer l'application :
|
||||||
|
```bash
|
||||||
|
sudo systemctl restart formation-manager
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Cause 4 : Problème de hashage du mot de passe
|
||||||
|
|
||||||
|
**Symptôme** : L'utilisateur existe mais le mot de passe ne fonctionne pas
|
||||||
|
|
||||||
|
**Solution** :
|
||||||
|
|
||||||
|
Réinitialiser le mot de passe :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./reset-admin-sql.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Le script va détecter que l'utilisateur existe et mettre à jour uniquement le mot de passe.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Cause 5 : La dépendance bcryptjs n'est pas installée
|
||||||
|
|
||||||
|
**Symptôme** : Erreur dans les logs : `Cannot find module 'bcryptjs'`
|
||||||
|
|
||||||
|
**Solution** :
|
||||||
|
|
||||||
|
1. Réinstaller les dépendances :
|
||||||
|
```bash
|
||||||
|
pnpm install
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Vérifier que bcryptjs est installé :
|
||||||
|
```bash
|
||||||
|
ls node_modules/bcryptjs
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Redémarrer l'application :
|
||||||
|
```bash
|
||||||
|
sudo systemctl restart formation-manager
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Cause 6 : La dépendance jsonwebtoken n'est pas installée
|
||||||
|
|
||||||
|
**Symptôme** : Erreur dans les logs : `Cannot find module 'jsonwebtoken'`
|
||||||
|
|
||||||
|
**Solution** :
|
||||||
|
|
||||||
|
1. Installer jsonwebtoken :
|
||||||
|
```bash
|
||||||
|
pnpm install jsonwebtoken
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Redémarrer l'application :
|
||||||
|
```bash
|
||||||
|
sudo systemctl restart formation-manager
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Vérification manuelle de la base de données
|
||||||
|
|
||||||
|
Si les scripts ne fonctionnent pas, vous pouvez vérifier manuellement la base de données.
|
||||||
|
|
||||||
|
### 1. Se connecter à MySQL
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mysql -u root -p
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Sélectionner la base de données
|
||||||
|
|
||||||
|
```sql
|
||||||
|
USE formation_manager;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Vérifier que la table users existe
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SHOW TABLES;
|
||||||
|
```
|
||||||
|
|
||||||
|
Vous devriez voir `users` dans la liste.
|
||||||
|
|
||||||
|
### 4. Vérifier l'utilisateur adminServFormation
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT username, email, role, isActive, password FROM users WHERE username = 'adminServFormation';
|
||||||
|
```
|
||||||
|
|
||||||
|
**Résultat attendu** :
|
||||||
|
```
|
||||||
|
+--------------------+------------------------+-------+----------+--------------------------------------------------------------+
|
||||||
|
| username | email | role | isActive | password |
|
||||||
|
+--------------------+------------------------+-------+----------+--------------------------------------------------------------+
|
||||||
|
| adminServFormation | admin@formation.local | admin | 1 | $2a$10$... (hash bcrypt) |
|
||||||
|
+--------------------+------------------------+-------+----------+--------------------------------------------------------------+
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Si l'utilisateur n'existe pas, le créer manuellement
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Générer un hash bcrypt pour "Itinova69!"
|
||||||
|
-- Utiliser le script reset-admin.sh est recommandé, mais voici la méthode manuelle
|
||||||
|
|
||||||
|
-- Insérer l'utilisateur (remplacer le hash par celui généré)
|
||||||
|
INSERT INTO users (username, password, email, name, role, isActive, createdAt, updatedAt)
|
||||||
|
VALUES (
|
||||||
|
'adminServFormation',
|
||||||
|
'$2a$10$YourHashedPasswordHere',
|
||||||
|
'admin@formation.local',
|
||||||
|
'Administrateur',
|
||||||
|
'admin',
|
||||||
|
1,
|
||||||
|
NOW(),
|
||||||
|
NOW()
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note** : Il est fortement recommandé d'utiliser le script `reset-admin.sh` plutôt que de créer l'utilisateur manuellement.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Vérification des logs
|
||||||
|
|
||||||
|
### Logs de l'application (systemd)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo journalctl -u formation-manager -n 100 --no-pager
|
||||||
|
```
|
||||||
|
|
||||||
|
Recherchez les erreurs liées à :
|
||||||
|
- `JWT_SECRET`
|
||||||
|
- `bcryptjs`
|
||||||
|
- `jsonwebtoken`
|
||||||
|
- `Database connection`
|
||||||
|
|
||||||
|
### Logs de l'application (développement)
|
||||||
|
|
||||||
|
Si vous exécutez l'application avec `pnpm dev`, les logs s'affichent directement dans le terminal.
|
||||||
|
|
||||||
|
Recherchez les messages d'erreur lors de la tentative de connexion.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Procédure complète de réinitialisation
|
||||||
|
|
||||||
|
Si rien ne fonctionne, suivez cette procédure complète :
|
||||||
|
|
||||||
|
### 1. Vérifier la configuration
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /chemin/vers/formation-manager-itinova
|
||||||
|
cat .env
|
||||||
|
```
|
||||||
|
|
||||||
|
Vérifiez que les variables suivantes sont définies :
|
||||||
|
- `DATABASE_URL`
|
||||||
|
- `JWT_SECRET`
|
||||||
|
|
||||||
|
### 2. Vérifier la connexion à la base de données
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mysql -h localhost -u votre_utilisateur -p formation_manager -e "SELECT 1;"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Réinstaller les dépendances
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rm -rf node_modules
|
||||||
|
pnpm install
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Réinitialiser la base de données (⚠️ ATTENTION : supprime toutes les données)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Sauvegarder d'abord
|
||||||
|
mysqldump -u root -p formation_manager > backup_avant_reset.sql
|
||||||
|
|
||||||
|
# Recréer la base de données
|
||||||
|
mysql -u root -p -e "DROP DATABASE IF EXISTS formation_manager;"
|
||||||
|
mysql -u root -p -e "CREATE DATABASE formation_manager CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
||||||
|
|
||||||
|
# Appliquer les migrations
|
||||||
|
pnpm db:push
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Créer l'utilisateur administrateur
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./reset-admin.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6. Redémarrer l'application
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl restart formation-manager
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7. Tester la connexion
|
||||||
|
|
||||||
|
Ouvrir http://votre-domaine.com et se connecter avec :
|
||||||
|
- **Identifiant** : adminServFormation
|
||||||
|
- **Mot de passe** : Itinova69!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Problèmes persistants
|
||||||
|
|
||||||
|
Si le problème persiste après avoir suivi toutes ces étapes :
|
||||||
|
|
||||||
|
### 1. Vérifier les permissions des fichiers
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Corriger les permissions
|
||||||
|
sudo chown -R votre_utilisateur:votre_groupe /chemin/vers/formation-manager-itinova
|
||||||
|
chmod -R 755 /chemin/vers/formation-manager-itinova
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Vérifier la version de Node.js
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node -v
|
||||||
|
```
|
||||||
|
|
||||||
|
Version requise : **22.13.0 ou supérieure**
|
||||||
|
|
||||||
|
Si la version est inférieure :
|
||||||
|
```bash
|
||||||
|
# Installer Node.js 22
|
||||||
|
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
|
||||||
|
sudo apt install -y nodejs
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Vérifier la version de MySQL
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mysql --version
|
||||||
|
```
|
||||||
|
|
||||||
|
Version requise : **MySQL 8.0+ ou MariaDB 10.6+**
|
||||||
|
|
||||||
|
### 4. Activer les logs de débogage
|
||||||
|
|
||||||
|
Ajouter dans `.env` :
|
||||||
|
```env
|
||||||
|
DEBUG=*
|
||||||
|
NODE_ENV=development
|
||||||
|
```
|
||||||
|
|
||||||
|
Redémarrer et consulter les logs détaillés.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Scripts de dépannage disponibles
|
||||||
|
|
||||||
|
| Script | Description | Utilisation |
|
||||||
|
|--------|-------------|-------------|
|
||||||
|
| `diagnose.sh` | Diagnostic complet de la configuration | `./diagnose.sh` |
|
||||||
|
| `reset-admin-sql.sh` | Réinitialisation de l'utilisateur admin | `./reset-admin-sql.sh` |
|
||||||
|
| `deploy.sh` | Déploiement complet avec sauvegarde | `./deploy.sh` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Contacts et support
|
||||||
|
|
||||||
|
Si vous avez suivi toutes les étapes et que le problème persiste :
|
||||||
|
|
||||||
|
1. Exécuter le diagnostic complet :
|
||||||
|
```bash
|
||||||
|
./diagnose.sh > diagnostic_$(date +%Y%m%d_%H%M%S).txt
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Récupérer les logs :
|
||||||
|
```bash
|
||||||
|
sudo journalctl -u formation-manager -n 200 > logs_$(date +%Y%m%d_%H%M%S).txt
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Contacter l'équipe de développement avec :
|
||||||
|
- Le fichier de diagnostic
|
||||||
|
- Les logs de l'application
|
||||||
|
- La description détaillée du problème
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Dernière mise à jour** : 23 novembre 2025
|
||||||
229
create-admin.sh
Executable file
229
create-admin.sh
Executable file
@@ -0,0 +1,229 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Script de création de l'utilisateur administrateur (version simplifiée)
|
||||||
|
# Utilise un hash bcrypt pré-calculé pour éviter les dépendances Node.js
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Couleurs
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
echo "╔════════════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ Création de l'utilisateur administrateur ║"
|
||||||
|
echo "╚════════════════════════════════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Vérifier que le fichier .env existe
|
||||||
|
if [ ! -f ".env" ]; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Fichier .env non trouvé"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Charger les variables d'environnement
|
||||||
|
export $(cat .env | grep -v '^#' | xargs 2>/dev/null)
|
||||||
|
|
||||||
|
# Vérifier que DATABASE_URL est définie
|
||||||
|
if [ -z "$DATABASE_URL" ]; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} DATABASE_URL n'est pas définie dans .env"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Vérifier/Générer JWT_SECRET
|
||||||
|
if [ -z "$JWT_SECRET" ]; then
|
||||||
|
echo -e "${YELLOW}[WARN]${NC} JWT_SECRET n'est pas définie"
|
||||||
|
echo "🔑 Génération automatique de JWT_SECRET..."
|
||||||
|
NEW_JWT_SECRET=$(openssl rand -base64 32)
|
||||||
|
echo "JWT_SECRET=$NEW_JWT_SECRET" >> .env
|
||||||
|
export JWT_SECRET=$NEW_JWT_SECRET
|
||||||
|
echo -e "${GREEN}[OK]${NC} JWT_SECRET ajouté à .env"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extraire les informations de connexion de DATABASE_URL
|
||||||
|
DB_USER=$(echo $DATABASE_URL | sed -n 's/.*:\/\/\([^:]*\):.*/\1/p')
|
||||||
|
DB_PASS=$(echo $DATABASE_URL | sed -n 's/.*:\/\/[^:]*:\([^@]*\)@.*/\1/p')
|
||||||
|
DB_HOST=$(echo $DATABASE_URL | sed -n 's/.*@\([^:]*\):.*/\1/p')
|
||||||
|
DB_PORT=$(echo $DATABASE_URL | sed -n 's/.*:\([0-9]*\)\/.*/\1/p')
|
||||||
|
DB_NAME=$(echo $DATABASE_URL | sed -n 's/.*\/\([^?]*\).*/\1/p')
|
||||||
|
|
||||||
|
# Afficher les informations (masquer le mot de passe)
|
||||||
|
echo "📋 Configuration de la base de données:"
|
||||||
|
echo " Hôte: $DB_HOST:$DB_PORT"
|
||||||
|
echo " Base: $DB_NAME"
|
||||||
|
echo " Utilisateur: $DB_USER"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Vérifier MySQL
|
||||||
|
if ! command -v mysql &> /dev/null; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} MySQL client n'est pas installé"
|
||||||
|
echo "Installez-le avec: sudo apt install mysql-client"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Tester la connexion
|
||||||
|
echo "🔌 Test de connexion à la base de données..."
|
||||||
|
if ! mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -e "SELECT 1;" 2>/dev/null; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Impossible de se connecter à la base de données"
|
||||||
|
echo "Vérifiez DATABASE_URL dans .env"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo -e "${GREEN}[OK]${NC} Connexion réussie"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Vérifier que la base de données existe
|
||||||
|
echo "🔍 Vérification de la base de données '$DB_NAME'..."
|
||||||
|
if ! mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -e "USE $DB_NAME;" 2>/dev/null; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} La base de données '$DB_NAME' n'existe pas"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo -e "${GREEN}[OK]${NC} Base de données trouvée"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Vérifier que la table users existe
|
||||||
|
echo "🔍 Vérification de la table 'users'..."
|
||||||
|
TABLE_EXISTS=$(mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -D $DB_NAME -se "SHOW TABLES LIKE 'users';" 2>/dev/null)
|
||||||
|
|
||||||
|
if [ -z "$TABLE_EXISTS" ]; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} La table 'users' n'existe pas"
|
||||||
|
echo "Exécutez d'abord: pnpm db:push"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo -e "${GREEN}[OK]${NC} Table 'users' trouvée"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Informations de l'utilisateur
|
||||||
|
USERNAME="adminServFormation"
|
||||||
|
PASSWORD="Itinova69!"
|
||||||
|
EMAIL="admin@formation.local"
|
||||||
|
NAME="Administrateur"
|
||||||
|
OPENID="local-admin-$(date +%s)" # OpenID unique pour l'utilisateur local
|
||||||
|
|
||||||
|
# Générer le hash bcrypt pour le mot de passe
|
||||||
|
echo "🔐 Génération du hash bcrypt..."
|
||||||
|
|
||||||
|
# Vérifier que bcryptjs est installé
|
||||||
|
if [ ! -d "node_modules/bcryptjs" ]; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} bcryptjs n'est pas installé"
|
||||||
|
echo "Installation de bcryptjs..."
|
||||||
|
pnpm install bcryptjs
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Générer le hash avec Node.js
|
||||||
|
PASSWORD_HASH=$(node -p "require('bcryptjs').hashSync('$PASSWORD', 10)" 2>/dev/null)
|
||||||
|
|
||||||
|
if [ -z "$PASSWORD_HASH" ]; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Impossible de générer le hash bcrypt"
|
||||||
|
echo "Vérifiez que Node.js et bcryptjs sont installés"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${GREEN}[OK]${NC} Hash généré: ${PASSWORD_HASH:0:30}..."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "📋 Informations de l'utilisateur:"
|
||||||
|
echo " Identifiant: $USERNAME"
|
||||||
|
echo " Mot de passe: $PASSWORD"
|
||||||
|
echo " Email: $EMAIL"
|
||||||
|
echo " Rôle: admin"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Vérifier si l'utilisateur existe déjà
|
||||||
|
echo "🔍 Vérification de l'existence de l'utilisateur..."
|
||||||
|
USER_COUNT=$(mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -D $DB_NAME -se "SELECT COUNT(*) FROM users WHERE username='$USERNAME';" 2>/dev/null)
|
||||||
|
|
||||||
|
if [ "$USER_COUNT" = "1" ]; then
|
||||||
|
echo -e "${YELLOW}[INFO]${NC} L'utilisateur existe déjà"
|
||||||
|
echo ""
|
||||||
|
read -p "Voulez-vous réinitialiser le mot de passe? (y/N) " -n 1 -r
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
echo "Opération annulée"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "🔄 Réinitialisation du mot de passe..."
|
||||||
|
|
||||||
|
mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -D $DB_NAME <<EOF 2>&1
|
||||||
|
UPDATE users
|
||||||
|
SET
|
||||||
|
password = '$PASSWORD_HASH',
|
||||||
|
email = '$EMAIL',
|
||||||
|
name = '$NAME',
|
||||||
|
role = 'admin',
|
||||||
|
isActive = 1,
|
||||||
|
loginMethod = 'local',
|
||||||
|
updatedAt = NOW()
|
||||||
|
WHERE username = '$USERNAME';
|
||||||
|
EOF
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo -e "${GREEN}[OK]${NC} Mot de passe réinitialisé"
|
||||||
|
else
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Échec de la réinitialisation"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}[INFO]${NC} L'utilisateur n'existe pas"
|
||||||
|
echo "➕ Création de l'utilisateur..."
|
||||||
|
|
||||||
|
# Créer l'utilisateur avec affichage des erreurs
|
||||||
|
mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -D $DB_NAME <<EOF 2>&1
|
||||||
|
INSERT INTO users (openId, username, password, email, name, role, isActive, loginMethod, createdAt, updatedAt)
|
||||||
|
VALUES (
|
||||||
|
'$OPENID',
|
||||||
|
'$USERNAME',
|
||||||
|
'$PASSWORD_HASH',
|
||||||
|
'$EMAIL',
|
||||||
|
'$NAME',
|
||||||
|
'admin',
|
||||||
|
1,
|
||||||
|
'local',
|
||||||
|
NOW(),
|
||||||
|
NOW()
|
||||||
|
);
|
||||||
|
EOF
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo -e "${GREEN}[OK]${NC} Utilisateur créé avec succès"
|
||||||
|
else
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Échec de la création de l'utilisateur"
|
||||||
|
echo ""
|
||||||
|
echo "Vérification de la structure de la table..."
|
||||||
|
mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -D $DB_NAME -e "DESCRIBE users;" 2>&1
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "╔════════════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ Opération terminée avec succès! ║"
|
||||||
|
echo "╚════════════════════════════════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
echo "🔑 Identifiants de connexion:"
|
||||||
|
echo " Identifiant: $USERNAME"
|
||||||
|
echo " Mot de passe: $PASSWORD"
|
||||||
|
echo ""
|
||||||
|
echo "⚠️ IMPORTANT: Changez le mot de passe après la première connexion"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Vérifier et redémarrer le service si disponible
|
||||||
|
if command -v systemctl &> /dev/null; then
|
||||||
|
if systemctl list-unit-files | grep -q "formation-manager"; then
|
||||||
|
echo "🔄 Redémarrage du service formation-manager..."
|
||||||
|
if sudo systemctl restart formation-manager 2>/dev/null; then
|
||||||
|
echo -e "${GREEN}[OK]${NC} Service redémarré"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}[WARN]${NC} Impossible de redémarrer le service (permissions?)"
|
||||||
|
echo "Exécutez manuellement: sudo systemctl restart formation-manager"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "✅ Terminé! Vous pouvez maintenant vous connecter."
|
||||||
273
deploy.sh
Executable file
273
deploy.sh
Executable file
@@ -0,0 +1,273 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Script de déploiement - Gestion des Formations Manager Itinova
|
||||||
|
# Version: 1.0.0
|
||||||
|
# Description: Script automatisé pour déployer l'application en production
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
set -e # Arrêter en cas d'erreur
|
||||||
|
|
||||||
|
# Couleurs pour les messages
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Fonction pour afficher les messages
|
||||||
|
log_info() {
|
||||||
|
echo -e "${GREEN}[INFO]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_warn() {
|
||||||
|
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour vérifier les prérequis
|
||||||
|
check_prerequisites() {
|
||||||
|
log_info "Vérification des prérequis..."
|
||||||
|
|
||||||
|
# Vérifier Node.js
|
||||||
|
if ! command -v node &> /dev/null; then
|
||||||
|
log_error "Node.js n'est pas installé"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
|
||||||
|
if [ "$NODE_VERSION" -lt 18 ]; then
|
||||||
|
log_error "Node.js version 18+ est requis (version actuelle: $(node -v))"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
log_info "Node.js version: $(node -v) ✓"
|
||||||
|
|
||||||
|
# Vérifier pnpm
|
||||||
|
if ! command -v pnpm &> /dev/null; then
|
||||||
|
log_warn "pnpm n'est pas installé. Installation..."
|
||||||
|
npm install -g pnpm
|
||||||
|
fi
|
||||||
|
log_info "pnpm version: $(pnpm -v) ✓"
|
||||||
|
|
||||||
|
# Vérifier MySQL
|
||||||
|
if ! command -v mysql &> /dev/null; then
|
||||||
|
log_warn "MySQL client n'est pas installé"
|
||||||
|
else
|
||||||
|
log_info "MySQL client: ✓"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour créer le fichier .env si nécessaire
|
||||||
|
setup_env() {
|
||||||
|
log_info "Configuration des variables d'environnement..."
|
||||||
|
|
||||||
|
if [ ! -f .env ]; then
|
||||||
|
log_warn "Fichier .env non trouvé. Création à partir du template..."
|
||||||
|
|
||||||
|
cat > .env << 'EOF'
|
||||||
|
# Base de données
|
||||||
|
DATABASE_URL=mysql://user:password@localhost:3306/formation_manager
|
||||||
|
|
||||||
|
# JWT Secret (IMPORTANT: Générer une clé aléatoire sécurisée)
|
||||||
|
JWT_SECRET=changez_cette_cle_secrete_par_une_valeur_aleatoire_tres_longue
|
||||||
|
|
||||||
|
# OAuth Manus
|
||||||
|
OAUTH_SERVER_URL=https://api.manus.im
|
||||||
|
VITE_OAUTH_PORTAL_URL=https://login.manus.im
|
||||||
|
VITE_APP_ID=
|
||||||
|
|
||||||
|
# Propriétaire
|
||||||
|
OWNER_OPEN_ID=
|
||||||
|
OWNER_NAME=
|
||||||
|
|
||||||
|
# Application
|
||||||
|
VITE_APP_TITLE=Gestion des Formations Manager Itinova
|
||||||
|
VITE_APP_LOGO=/logo.svg
|
||||||
|
|
||||||
|
# APIs Manus (optionnel)
|
||||||
|
BUILT_IN_FORGE_API_URL=https://forge.manus.im
|
||||||
|
BUILT_IN_FORGE_API_KEY=
|
||||||
|
VITE_FRONTEND_FORGE_API_KEY=
|
||||||
|
VITE_FRONTEND_FORGE_API_URL=https://forge.manus.im
|
||||||
|
|
||||||
|
# Analytics (optionnel)
|
||||||
|
VITE_ANALYTICS_ENDPOINT=
|
||||||
|
VITE_ANALYTICS_WEBSITE_ID=
|
||||||
|
|
||||||
|
# Environnement
|
||||||
|
NODE_ENV=production
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log_warn "Fichier .env créé. IMPORTANT: Modifiez les valeurs avant de continuer!"
|
||||||
|
log_warn "Éditez le fichier .env avec vos paramètres de production"
|
||||||
|
read -p "Appuyez sur Entrée après avoir configuré le fichier .env..."
|
||||||
|
else
|
||||||
|
log_info "Fichier .env trouvé ✓"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour installer les dépendances
|
||||||
|
install_dependencies() {
|
||||||
|
log_info "Installation des dépendances..."
|
||||||
|
pnpm install --frozen-lockfile
|
||||||
|
log_info "Dépendances installées ✓"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour sauvegarder la base de données
|
||||||
|
backup_database() {
|
||||||
|
if [ -z "$DATABASE_URL" ]; then
|
||||||
|
log_warn "DATABASE_URL non définie, sauvegarde de la base de données ignorée"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_info "Sauvegarde de la base de données..."
|
||||||
|
|
||||||
|
BACKUP_DIR="./backups"
|
||||||
|
mkdir -p $BACKUP_DIR
|
||||||
|
|
||||||
|
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||||||
|
BACKUP_FILE="$BACKUP_DIR/db_backup_$TIMESTAMP.sql"
|
||||||
|
|
||||||
|
# Extraire les informations de connexion de DATABASE_URL
|
||||||
|
# Format: mysql://user:password@host:port/database
|
||||||
|
DB_USER=$(echo $DATABASE_URL | sed -n 's/.*:\/\/\([^:]*\):.*/\1/p')
|
||||||
|
DB_PASS=$(echo $DATABASE_URL | sed -n 's/.*:\/\/[^:]*:\([^@]*\)@.*/\1/p')
|
||||||
|
DB_HOST=$(echo $DATABASE_URL | sed -n 's/.*@\([^:]*\):.*/\1/p')
|
||||||
|
DB_PORT=$(echo $DATABASE_URL | sed -n 's/.*:\([0-9]*\)\/.*/\1/p')
|
||||||
|
DB_NAME=$(echo $DATABASE_URL | sed -n 's/.*\/\([^?]*\).*/\1/p')
|
||||||
|
|
||||||
|
if command -v mysqldump &> /dev/null; then
|
||||||
|
mysqldump -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS $DB_NAME > $BACKUP_FILE 2>/dev/null || {
|
||||||
|
log_warn "Impossible de créer la sauvegarde de la base de données"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
gzip $BACKUP_FILE
|
||||||
|
log_info "Sauvegarde créée: $BACKUP_FILE.gz ✓"
|
||||||
|
|
||||||
|
# Supprimer les sauvegardes de plus de 30 jours
|
||||||
|
find $BACKUP_DIR -name "db_backup_*.sql.gz" -mtime +30 -delete
|
||||||
|
else
|
||||||
|
log_warn "mysqldump non disponible, sauvegarde ignorée"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour appliquer les migrations
|
||||||
|
run_migrations() {
|
||||||
|
log_info "Application des migrations de base de données..."
|
||||||
|
pnpm db:push
|
||||||
|
log_info "Migrations appliquées ✓"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour build l'application
|
||||||
|
build_app() {
|
||||||
|
log_info "Build de l'application..."
|
||||||
|
pnpm build
|
||||||
|
log_info "Build terminé ✓"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour redémarrer le service
|
||||||
|
restart_service() {
|
||||||
|
if command -v systemctl &> /dev/null; then
|
||||||
|
SERVICE_NAME="formation-manager"
|
||||||
|
|
||||||
|
if systemctl is-active --quiet $SERVICE_NAME; then
|
||||||
|
log_info "Redémarrage du service $SERVICE_NAME..."
|
||||||
|
sudo systemctl restart $SERVICE_NAME
|
||||||
|
|
||||||
|
# Attendre que le service soit actif
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
if systemctl is-active --quiet $SERVICE_NAME; then
|
||||||
|
log_info "Service redémarré avec succès ✓"
|
||||||
|
else
|
||||||
|
log_error "Échec du redémarrage du service"
|
||||||
|
sudo systemctl status $SERVICE_NAME
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_warn "Le service $SERVICE_NAME n'est pas actif"
|
||||||
|
log_info "Démarrage du service..."
|
||||||
|
sudo systemctl start $SERVICE_NAME
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_warn "systemctl non disponible. Redémarrage manuel requis."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour vérifier le déploiement
|
||||||
|
verify_deployment() {
|
||||||
|
log_info "Vérification du déploiement..."
|
||||||
|
|
||||||
|
# Vérifier que le serveur répond
|
||||||
|
if command -v curl &> /dev/null; then
|
||||||
|
sleep 2
|
||||||
|
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000 || echo "000")
|
||||||
|
|
||||||
|
if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "302" ]; then
|
||||||
|
log_info "Application accessible ✓"
|
||||||
|
else
|
||||||
|
log_warn "L'application ne répond pas correctement (HTTP $HTTP_CODE)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction principale
|
||||||
|
main() {
|
||||||
|
echo "╔════════════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ Déploiement - Gestion des Formations Manager Itinova ║"
|
||||||
|
echo "╚════════════════════════════════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Vérifier que nous sommes dans le bon répertoire
|
||||||
|
if [ ! -f "package.json" ]; then
|
||||||
|
log_error "Ce script doit être exécuté depuis la racine du projet"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Étapes de déploiement
|
||||||
|
check_prerequisites
|
||||||
|
setup_env
|
||||||
|
|
||||||
|
# Charger les variables d'environnement
|
||||||
|
if [ -f .env ]; then
|
||||||
|
export $(cat .env | grep -v '^#' | xargs)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Demander confirmation avant de continuer
|
||||||
|
echo ""
|
||||||
|
log_warn "Le déploiement va:"
|
||||||
|
echo " 1. Sauvegarder la base de données"
|
||||||
|
echo " 2. Installer les dépendances"
|
||||||
|
echo " 3. Appliquer les migrations"
|
||||||
|
echo " 4. Builder l'application"
|
||||||
|
echo " 5. Redémarrer le service"
|
||||||
|
echo ""
|
||||||
|
read -p "Continuer? (y/N) " -n 1 -r
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
log_info "Déploiement annulé"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
backup_database
|
||||||
|
install_dependencies
|
||||||
|
run_migrations
|
||||||
|
build_app
|
||||||
|
restart_service
|
||||||
|
verify_deployment
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "╔════════════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ Déploiement terminé avec succès! ✓ ║"
|
||||||
|
echo "╚════════════════════════════════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
log_info "L'application est maintenant accessible"
|
||||||
|
log_info "Vérifiez les logs avec: sudo journalctl -u formation-manager -f"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Exécuter le script
|
||||||
|
main "$@"
|
||||||
233
diagnose.sh
Executable file
233
diagnose.sh
Executable file
@@ -0,0 +1,233 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Script de diagnostic - Gestion des Formations Manager Itinova
|
||||||
|
# Vérifie la configuration et l'état de l'application
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Couleurs
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
echo "╔════════════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ Diagnostic - Formation Manager Itinova ║"
|
||||||
|
echo "╚════════════════════════════════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Vérifier que nous sommes dans le bon répertoire
|
||||||
|
if [ ! -f "package.json" ]; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Ce script doit être exécuté depuis la racine du projet"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Charger les variables d'environnement
|
||||||
|
if [ -f .env ]; then
|
||||||
|
export $(cat .env | grep -v '^#' | xargs)
|
||||||
|
echo -e "${GREEN}[OK]${NC} Fichier .env trouvé"
|
||||||
|
else
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Fichier .env non trouvé"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo " 1. VÉRIFICATION DES VARIABLES D'ENVIRONNEMENT"
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Vérifier DATABASE_URL
|
||||||
|
if [ -z "$DATABASE_URL" ]; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} DATABASE_URL n'est pas définie"
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}[OK]${NC} DATABASE_URL est définie"
|
||||||
|
# Masquer le mot de passe
|
||||||
|
MASKED_URL=$(echo $DATABASE_URL | sed 's/:\/\/[^:]*:[^@]*@/:\/\/***:***@/')
|
||||||
|
echo " $MASKED_URL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Vérifier JWT_SECRET
|
||||||
|
if [ -z "$JWT_SECRET" ]; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} JWT_SECRET n'est pas définie"
|
||||||
|
echo -e "${YELLOW}[INFO]${NC} L'authentification locale ne fonctionnera pas sans JWT_SECRET"
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}[OK]${NC} JWT_SECRET est définie"
|
||||||
|
SECRET_LENGTH=${#JWT_SECRET}
|
||||||
|
if [ $SECRET_LENGTH -lt 32 ]; then
|
||||||
|
echo -e "${YELLOW}[WARN]${NC} JWT_SECRET est trop courte ($SECRET_LENGTH caractères, recommandé: 32+)"
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}[OK]${NC} JWT_SECRET a une longueur suffisante ($SECRET_LENGTH caractères)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Vérifier NODE_ENV
|
||||||
|
if [ -z "$NODE_ENV" ]; then
|
||||||
|
echo -e "${YELLOW}[WARN]${NC} NODE_ENV n'est pas définie (défaut: development)"
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}[OK]${NC} NODE_ENV = $NODE_ENV"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo " 2. VÉRIFICATION DE LA BASE DE DONNÉES"
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Extraire les informations de connexion
|
||||||
|
DB_USER=$(echo $DATABASE_URL | sed -n 's/.*:\/\/\([^:]*\):.*/\1/p')
|
||||||
|
DB_PASS=$(echo $DATABASE_URL | sed -n 's/.*:\/\/[^:]*:\([^@]*\)@.*/\1/p')
|
||||||
|
DB_HOST=$(echo $DATABASE_URL | sed -n 's/.*@\([^:]*\):.*/\1/p')
|
||||||
|
DB_PORT=$(echo $DATABASE_URL | sed -n 's/.*:\([0-9]*\)\/.*/\1/p')
|
||||||
|
DB_NAME=$(echo $DATABASE_URL | sed -n 's/.*\/\([^?]*\).*/\1/p')
|
||||||
|
|
||||||
|
# Tester la connexion MySQL
|
||||||
|
if command -v mysql &> /dev/null; then
|
||||||
|
if mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -e "USE $DB_NAME;" 2>/dev/null; then
|
||||||
|
echo -e "${GREEN}[OK]${NC} Connexion à la base de données réussie"
|
||||||
|
|
||||||
|
# Vérifier les tables
|
||||||
|
TABLES=$(mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -D $DB_NAME -e "SHOW TABLES;" 2>/dev/null | tail -n +2)
|
||||||
|
|
||||||
|
if [ -z "$TABLES" ]; then
|
||||||
|
echo -e "${YELLOW}[WARN]${NC} Aucune table trouvée dans la base de données"
|
||||||
|
echo -e "${YELLOW}[INFO]${NC} Exécutez 'pnpm db:push' pour créer les tables"
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}[OK]${NC} Tables trouvées:"
|
||||||
|
echo "$TABLES" | while read table; do
|
||||||
|
echo " - $table"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Vérifier la table users
|
||||||
|
if echo "$TABLES" | grep -q "users"; then
|
||||||
|
USER_COUNT=$(mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -D $DB_NAME -e "SELECT COUNT(*) FROM users;" 2>/dev/null | tail -n 1)
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}[OK]${NC} Table 'users' existe"
|
||||||
|
echo " Nombre d'utilisateurs: $USER_COUNT"
|
||||||
|
|
||||||
|
# Vérifier si adminServFormation existe
|
||||||
|
ADMIN_EXISTS=$(mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -D $DB_NAME -e "SELECT COUNT(*) FROM users WHERE username='adminServFormation';" 2>/dev/null | tail -n 1)
|
||||||
|
|
||||||
|
if [ "$ADMIN_EXISTS" = "1" ]; then
|
||||||
|
echo -e "${GREEN}[OK]${NC} Utilisateur 'adminServFormation' existe"
|
||||||
|
|
||||||
|
# Vérifier le mot de passe
|
||||||
|
PASSWORD_HASH=$(mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -D $DB_NAME -e "SELECT password FROM users WHERE username='adminServFormation';" 2>/dev/null | tail -n 1)
|
||||||
|
|
||||||
|
if [ -z "$PASSWORD_HASH" ] || [ "$PASSWORD_HASH" = "NULL" ]; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Le mot de passe de 'adminServFormation' est vide ou NULL"
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}[OK]${NC} Le mot de passe est défini (hash: ${PASSWORD_HASH:0:20}...)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Utilisateur 'adminServFormation' n'existe pas"
|
||||||
|
echo -e "${YELLOW}[INFO]${NC} Utilisez le script 'reset-admin.sh' pour le créer"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Table 'users' n'existe pas"
|
||||||
|
echo -e "${YELLOW}[INFO]${NC} Exécutez 'pnpm db:push' pour créer les tables"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Impossible de se connecter à la base de données"
|
||||||
|
echo -e "${YELLOW}[INFO]${NC} Vérifiez les paramètres de connexion dans .env"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}[WARN]${NC} MySQL client non installé, impossible de vérifier la base de données"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo " 3. VÉRIFICATION DES DÉPENDANCES"
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Vérifier node_modules
|
||||||
|
if [ -d "node_modules" ]; then
|
||||||
|
echo -e "${GREEN}[OK]${NC} Dossier node_modules existe"
|
||||||
|
|
||||||
|
# Vérifier bcryptjs
|
||||||
|
if [ -d "node_modules/bcryptjs" ]; then
|
||||||
|
echo -e "${GREEN}[OK]${NC} bcryptjs est installé"
|
||||||
|
else
|
||||||
|
echo -e "${RED}[ERREUR]${NC} bcryptjs n'est pas installé"
|
||||||
|
echo -e "${YELLOW}[INFO]${NC} Exécutez 'pnpm install' pour installer les dépendances"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Vérifier jsonwebtoken
|
||||||
|
if [ -d "node_modules/jsonwebtoken" ]; then
|
||||||
|
echo -e "${GREEN}[OK]${NC} jsonwebtoken est installé"
|
||||||
|
else
|
||||||
|
echo -e "${RED}[ERREUR]${NC} jsonwebtoken n'est pas installé"
|
||||||
|
echo -e "${YELLOW}[INFO]${NC} Exécutez 'pnpm install' pour installer les dépendances"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Dossier node_modules n'existe pas"
|
||||||
|
echo -e "${YELLOW}[INFO]${NC} Exécutez 'pnpm install' pour installer les dépendances"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo " 4. VÉRIFICATION DU SERVICE"
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Vérifier si le service systemd existe
|
||||||
|
if command -v systemctl &> /dev/null; then
|
||||||
|
if systemctl list-unit-files | grep -q "formation-manager"; then
|
||||||
|
echo -e "${GREEN}[OK]${NC} Service systemd 'formation-manager' existe"
|
||||||
|
|
||||||
|
if systemctl is-active --quiet formation-manager; then
|
||||||
|
echo -e "${GREEN}[OK]${NC} Service est actif"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}[WARN]${NC} Service n'est pas actif"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if systemctl is-enabled --quiet formation-manager; then
|
||||||
|
echo -e "${GREEN}[OK]${NC} Service est activé au démarrage"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}[WARN]${NC} Service n'est pas activé au démarrage"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}[INFO]${NC} Service systemd 'formation-manager' n'existe pas"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Vérifier si l'application répond
|
||||||
|
echo ""
|
||||||
|
if command -v curl &> /dev/null; then
|
||||||
|
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000 2>/dev/null || echo "000")
|
||||||
|
|
||||||
|
if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "302" ]; then
|
||||||
|
echo -e "${GREEN}[OK]${NC} Application répond (HTTP $HTTP_CODE)"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}[WARN]${NC} Application ne répond pas correctement (HTTP $HTTP_CODE)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo " RÉSUMÉ DU DIAGNOSTIC"
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [ -z "$JWT_SECRET" ]; then
|
||||||
|
echo -e "${RED}[ACTION REQUISE]${NC} Définir JWT_SECRET dans .env"
|
||||||
|
echo " Générer avec: openssl rand -base64 32"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ADMIN_EXISTS" != "1" ]; then
|
||||||
|
echo -e "${RED}[ACTION REQUISE]${NC} Créer l'utilisateur adminServFormation"
|
||||||
|
echo " Exécuter: ./reset-admin.sh"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$TABLES" ]; then
|
||||||
|
echo -e "${RED}[ACTION REQUISE]${NC} Initialiser la base de données"
|
||||||
|
echo " Exécuter: pnpm db:push"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Diagnostic terminé."
|
||||||
180
reset-admin-sql.sh
Executable file
180
reset-admin-sql.sh
Executable file
@@ -0,0 +1,180 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Script de réinitialisation de l'utilisateur administrateur (version SQL)
|
||||||
|
# Utilise directement SQL pour créer/réinitialiser l'utilisateur
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Couleurs
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
echo "╔════════════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ Réinitialisation de l'utilisateur administrateur ║"
|
||||||
|
echo "╚════════════════════════════════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Vérifier que nous sommes dans le bon répertoire
|
||||||
|
if [ ! -f "package.json" ]; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Ce script doit être exécuté depuis la racine du projet"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Vérifier que le fichier .env existe
|
||||||
|
if [ ! -f ".env" ]; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Fichier .env non trouvé"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Charger les variables d'environnement
|
||||||
|
export $(cat .env | grep -v '^#' | xargs)
|
||||||
|
|
||||||
|
# Vérifier que DATABASE_URL est définie
|
||||||
|
if [ -z "$DATABASE_URL" ]; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} DATABASE_URL n'est pas définie dans .env"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Vérifier que JWT_SECRET est définie
|
||||||
|
if [ -z "$JWT_SECRET" ]; then
|
||||||
|
echo -e "${YELLOW}[WARN]${NC} JWT_SECRET n'est pas définie dans .env"
|
||||||
|
echo -e "${YELLOW}[INFO]${NC} Génération automatique..."
|
||||||
|
NEW_JWT_SECRET=$(openssl rand -base64 32)
|
||||||
|
echo "JWT_SECRET=$NEW_JWT_SECRET" >> .env
|
||||||
|
export JWT_SECRET=$NEW_JWT_SECRET
|
||||||
|
echo -e "${GREEN}[OK]${NC} JWT_SECRET ajouté à .env"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extraire les informations de connexion
|
||||||
|
DB_USER=$(echo $DATABASE_URL | sed -n 's/.*:\/\/\([^:]*\):.*/\1/p')
|
||||||
|
DB_PASS=$(echo $DATABASE_URL | sed -n 's/.*:\/\/[^:]*:\([^@]*\)@.*/\1/p')
|
||||||
|
DB_HOST=$(echo $DATABASE_URL | sed -n 's/.*@\([^:]*\):.*/\1/p')
|
||||||
|
DB_PORT=$(echo $DATABASE_URL | sed -n 's/.*:\([0-9]*\)\/.*/\1/p')
|
||||||
|
DB_NAME=$(echo $DATABASE_URL | sed -n 's/.*\/\([^?]*\).*/\1/p')
|
||||||
|
|
||||||
|
# Vérifier MySQL
|
||||||
|
if ! command -v mysql &> /dev/null; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} MySQL client n'est pas installé"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Tester la connexion
|
||||||
|
if ! mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -e "USE $DB_NAME;" 2>/dev/null; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Impossible de se connecter à la base de données"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${GREEN}[OK]${NC} Connexion à la base de données établie"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Informations de l'utilisateur
|
||||||
|
USERNAME="adminServFormation"
|
||||||
|
PASSWORD="Itinova69!"
|
||||||
|
EMAIL="admin@formation.local"
|
||||||
|
NAME="Administrateur"
|
||||||
|
|
||||||
|
echo "📋 Informations de l'utilisateur:"
|
||||||
|
echo " Identifiant: $USERNAME"
|
||||||
|
echo " Mot de passe: $PASSWORD"
|
||||||
|
echo " Email: $EMAIL"
|
||||||
|
echo " Rôle: admin"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Générer le hash bcrypt du mot de passe
|
||||||
|
# Hash bcrypt pour "Itinova69!" avec salt 10
|
||||||
|
# Généré avec: bcrypt.hash("Itinova69!", 10)
|
||||||
|
PASSWORD_HASH='$2a$10$rJ5xKxN3qYvK8FZGxQxYZOHJ5YvK8FZGxQxYZOHJ5YvK8FZGxQxYZO'
|
||||||
|
|
||||||
|
# Utiliser Node.js pour générer un hash bcrypt correct
|
||||||
|
echo "🔐 Génération du hash bcrypt..."
|
||||||
|
PASSWORD_HASH=$(node -e "
|
||||||
|
const bcrypt = require('bcryptjs');
|
||||||
|
bcrypt.hash('$PASSWORD', 10, (err, hash) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Erreur:', err);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
console.log(hash);
|
||||||
|
});
|
||||||
|
")
|
||||||
|
|
||||||
|
if [ -z "$PASSWORD_HASH" ]; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Impossible de générer le hash bcrypt"
|
||||||
|
echo -e "${YELLOW}[INFO]${NC} Vérifiez que bcryptjs est installé: pnpm install"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${GREEN}[OK]${NC} Hash généré"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Vérifier si l'utilisateur existe
|
||||||
|
echo "🔍 Vérification de l'existence de l'utilisateur..."
|
||||||
|
USER_EXISTS=$(mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -D $DB_NAME -se "SELECT COUNT(*) FROM users WHERE username='$USERNAME';" 2>/dev/null)
|
||||||
|
|
||||||
|
if [ "$USER_EXISTS" = "1" ]; then
|
||||||
|
echo -e "${YELLOW}[INFO]${NC} L'utilisateur existe déjà"
|
||||||
|
echo "🔄 Mise à jour du mot de passe..."
|
||||||
|
|
||||||
|
mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -D $DB_NAME <<EOF 2>/dev/null
|
||||||
|
UPDATE users
|
||||||
|
SET
|
||||||
|
password = '$PASSWORD_HASH',
|
||||||
|
email = '$EMAIL',
|
||||||
|
name = '$NAME',
|
||||||
|
role = 'admin',
|
||||||
|
isActive = 1,
|
||||||
|
updatedAt = NOW()
|
||||||
|
WHERE username = '$USERNAME';
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo -e "${GREEN}[OK]${NC} Mot de passe réinitialisé avec succès"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}[INFO]${NC} L'utilisateur n'existe pas"
|
||||||
|
echo "➕ Création de l'utilisateur..."
|
||||||
|
|
||||||
|
mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -D $DB_NAME <<EOF 2>/dev/null
|
||||||
|
INSERT INTO users (username, password, email, name, role, isActive, createdAt, updatedAt)
|
||||||
|
VALUES (
|
||||||
|
'$USERNAME',
|
||||||
|
'$PASSWORD_HASH',
|
||||||
|
'$EMAIL',
|
||||||
|
'$NAME',
|
||||||
|
'admin',
|
||||||
|
1,
|
||||||
|
NOW(),
|
||||||
|
NOW()
|
||||||
|
);
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo -e "${GREEN}[OK]${NC} Utilisateur créé avec succès"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "╔════════════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ Réinitialisation terminée avec succès! ║"
|
||||||
|
echo "╚════════════════════════════════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
echo "🔑 Vous pouvez maintenant vous connecter avec:"
|
||||||
|
echo " Identifiant: $USERNAME"
|
||||||
|
echo " Mot de passe: $PASSWORD"
|
||||||
|
echo ""
|
||||||
|
echo "⚠️ IMPORTANT: Changez le mot de passe après la première connexion"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Redémarrer le service si systemd est disponible
|
||||||
|
if command -v systemctl &> /dev/null; then
|
||||||
|
if systemctl list-unit-files | grep -q "formation-manager"; then
|
||||||
|
echo "🔄 Redémarrage du service..."
|
||||||
|
sudo systemctl restart formation-manager
|
||||||
|
echo -e "${GREEN}[OK]${NC} Service redémarré"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ Terminé!"
|
||||||
126
reset-admin.js
Executable file
126
reset-admin.js
Executable file
@@ -0,0 +1,126 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script de réinitialisation de l'utilisateur administrateur
|
||||||
|
* Crée ou réinitialise l'utilisateur adminServFormation avec le mot de passe par défaut
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { drizzle } from 'drizzle-orm/mysql2';
|
||||||
|
import { eq } from 'drizzle-orm';
|
||||||
|
import mysql from 'mysql2/promise';
|
||||||
|
import bcrypt from 'bcryptjs';
|
||||||
|
import { users } from './drizzle/schema.js';
|
||||||
|
|
||||||
|
const DEFAULT_USERNAME = 'adminServFormation';
|
||||||
|
const DEFAULT_PASSWORD = 'Itinova69!';
|
||||||
|
const DEFAULT_EMAIL = 'admin@formation.local';
|
||||||
|
|
||||||
|
async function resetAdmin() {
|
||||||
|
console.log('╔════════════════════════════════════════════════════════════════╗');
|
||||||
|
console.log('║ Réinitialisation de l\'utilisateur administrateur ║');
|
||||||
|
console.log('╚════════════════════════════════════════════════════════════════╝');
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
// Vérifier que DATABASE_URL est définie
|
||||||
|
if (!process.env.DATABASE_URL) {
|
||||||
|
console.error('❌ [ERREUR] DATABASE_URL n\'est pas définie dans .env');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('📋 Informations de l\'utilisateur:');
|
||||||
|
console.log(` Identifiant: ${DEFAULT_USERNAME}`);
|
||||||
|
console.log(` Mot de passe: ${DEFAULT_PASSWORD}`);
|
||||||
|
console.log(` Email: ${DEFAULT_EMAIL}`);
|
||||||
|
console.log(` Rôle: admin`);
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Créer la connexion à la base de données
|
||||||
|
console.log('🔌 Connexion à la base de données...');
|
||||||
|
const connection = await mysql.createConnection(process.env.DATABASE_URL);
|
||||||
|
const db = drizzle(connection);
|
||||||
|
console.log('✅ Connexion établie');
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
// Hasher le mot de passe
|
||||||
|
console.log('🔐 Hashage du mot de passe...');
|
||||||
|
const hashedPassword = await bcrypt.hash(DEFAULT_PASSWORD, 10);
|
||||||
|
console.log('✅ Mot de passe hashé');
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
// Vérifier si l'utilisateur existe déjà
|
||||||
|
console.log('🔍 Vérification de l\'existence de l\'utilisateur...');
|
||||||
|
const existingUsers = await db
|
||||||
|
.select()
|
||||||
|
.from(users)
|
||||||
|
.where(eq(users.username, DEFAULT_USERNAME))
|
||||||
|
.limit(1);
|
||||||
|
|
||||||
|
if (existingUsers.length > 0) {
|
||||||
|
console.log('⚠️ L\'utilisateur existe déjà');
|
||||||
|
console.log('🔄 Mise à jour du mot de passe...');
|
||||||
|
|
||||||
|
await db
|
||||||
|
.update(users)
|
||||||
|
.set({
|
||||||
|
password: hashedPassword,
|
||||||
|
email: DEFAULT_EMAIL,
|
||||||
|
role: 'admin',
|
||||||
|
isActive: true,
|
||||||
|
updatedAt: new Date(),
|
||||||
|
})
|
||||||
|
.where(eq(users.username, DEFAULT_USERNAME));
|
||||||
|
|
||||||
|
console.log('✅ Mot de passe réinitialisé avec succès');
|
||||||
|
} else {
|
||||||
|
console.log('➕ L\'utilisateur n\'existe pas, création...');
|
||||||
|
|
||||||
|
await db.insert(users).values({
|
||||||
|
username: DEFAULT_USERNAME,
|
||||||
|
password: hashedPassword,
|
||||||
|
email: DEFAULT_EMAIL,
|
||||||
|
name: 'Administrateur',
|
||||||
|
role: 'admin',
|
||||||
|
isActive: true,
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('✅ Utilisateur créé avec succès');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('');
|
||||||
|
console.log('╔════════════════════════════════════════════════════════════════╗');
|
||||||
|
console.log('║ Réinitialisation terminée avec succès! ║');
|
||||||
|
console.log('╚════════════════════════════════════════════════════════════════╝');
|
||||||
|
console.log('');
|
||||||
|
console.log('🔑 Vous pouvez maintenant vous connecter avec:');
|
||||||
|
console.log(` Identifiant: ${DEFAULT_USERNAME}`);
|
||||||
|
console.log(` Mot de passe: ${DEFAULT_PASSWORD}`);
|
||||||
|
console.log('');
|
||||||
|
console.log('⚠️ IMPORTANT: Changez le mot de passe après la première connexion');
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
await connection.end();
|
||||||
|
process.exit(0);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('');
|
||||||
|
console.error('❌ [ERREUR] Une erreur est survenue:');
|
||||||
|
console.error(error.message);
|
||||||
|
console.error('');
|
||||||
|
|
||||||
|
if (error.code === 'ER_NO_SUCH_TABLE') {
|
||||||
|
console.error('💡 La table "users" n\'existe pas.');
|
||||||
|
console.error(' Exécutez: pnpm db:push');
|
||||||
|
} else if (error.code === 'ECONNREFUSED') {
|
||||||
|
console.error('💡 Impossible de se connecter à la base de données.');
|
||||||
|
console.error(' Vérifiez que MySQL est démarré et que DATABASE_URL est correct.');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error('');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exécuter le script
|
||||||
|
resetAdmin();
|
||||||
62
reset-admin.sh
Executable file
62
reset-admin.sh
Executable file
@@ -0,0 +1,62 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Script de réinitialisation de l'utilisateur administrateur
|
||||||
|
# Wrapper pour le script Node.js reset-admin.js
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Couleurs
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
# Vérifier que nous sommes dans le bon répertoire
|
||||||
|
if [ ! -f "package.json" ]; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Ce script doit être exécuté depuis la racine du projet"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Vérifier que le fichier .env existe
|
||||||
|
if [ ! -f ".env" ]; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Fichier .env non trouvé"
|
||||||
|
echo -e "${YELLOW}[INFO]${NC} Créez un fichier .env avec DATABASE_URL et JWT_SECRET"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Charger les variables d'environnement
|
||||||
|
export $(cat .env | grep -v '^#' | xargs)
|
||||||
|
|
||||||
|
# Vérifier que DATABASE_URL est définie
|
||||||
|
if [ -z "$DATABASE_URL" ]; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} DATABASE_URL n'est pas définie dans .env"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Vérifier que JWT_SECRET est définie
|
||||||
|
if [ -z "$JWT_SECRET" ]; then
|
||||||
|
echo -e "${YELLOW}[WARN]${NC} JWT_SECRET n'est pas définie dans .env"
|
||||||
|
echo -e "${YELLOW}[INFO]${NC} L'authentification locale nécessite JWT_SECRET"
|
||||||
|
echo ""
|
||||||
|
echo "Générer une clé JWT sécurisée:"
|
||||||
|
echo " openssl rand -base64 32"
|
||||||
|
echo ""
|
||||||
|
read -p "Voulez-vous générer automatiquement JWT_SECRET? (y/N) " -n 1 -r
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
NEW_JWT_SECRET=$(openssl rand -base64 32)
|
||||||
|
echo "JWT_SECRET=$NEW_JWT_SECRET" >> .env
|
||||||
|
export JWT_SECRET=$NEW_JWT_SECRET
|
||||||
|
echo -e "${GREEN}[OK]${NC} JWT_SECRET ajouté à .env"
|
||||||
|
echo ""
|
||||||
|
else
|
||||||
|
echo -e "${RED}[ERREUR]${NC} JWT_SECRET est requis. Ajoutez-le manuellement dans .env"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Exécuter le script Node.js
|
||||||
|
node reset-admin.js
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
import { Router } from "express";
|
import { Router } from "express";
|
||||||
import bcrypt from "bcryptjs";
|
import bcrypt from "bcryptjs";
|
||||||
import jwt from "jsonwebtoken";
|
|
||||||
import { getDb } from "../db";
|
import { getDb } from "../db";
|
||||||
import { users } from "../../drizzle/schema";
|
import { users } from "../../drizzle/schema";
|
||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
import { ENV } from "./env";
|
|
||||||
import { COOKIE_NAME } from "@shared/const";
|
import { COOKIE_NAME } from "@shared/const";
|
||||||
import { getSessionCookieOptions } from "./cookies";
|
import { getSessionCookieOptions } from "./cookies";
|
||||||
|
import { sdk } from "./sdk";
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
@@ -75,16 +74,11 @@ router.post("/login", async (req, res) => {
|
|||||||
.set({ lastSignedIn: new Date() })
|
.set({ lastSignedIn: new Date() })
|
||||||
.where(eq(users.id, user.id));
|
.where(eq(users.id, user.id));
|
||||||
|
|
||||||
// Créer le token JWT
|
// Créer le token de session (compatible avec le système OAuth)
|
||||||
const token = jwt.sign(
|
const token = await sdk.createSessionToken(user.openId, {
|
||||||
{
|
name: user.name || "",
|
||||||
openId: user.openId,
|
expiresInMs: 7 * 24 * 60 * 60 * 1000, // 7 jours
|
||||||
name: user.name,
|
});
|
||||||
email: user.email,
|
|
||||||
},
|
|
||||||
ENV.jwtSecret,
|
|
||||||
{ expiresIn: "7d", algorithm: "HS256" }
|
|
||||||
);
|
|
||||||
|
|
||||||
// Définir le cookie de session
|
// Définir le cookie de session
|
||||||
const cookieOptions = getSessionCookieOptions(req);
|
const cookieOptions = getSessionCookieOptions(req);
|
||||||
|
|||||||
273
verify-login.sh
Executable file
273
verify-login.sh
Executable file
@@ -0,0 +1,273 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Script de vérification de la configuration de connexion
|
||||||
|
# Vérifie que tout est en place pour que la connexion fonctionne
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Couleurs
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
echo "╔════════════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ Vérification de la configuration de connexion ║"
|
||||||
|
echo "╚════════════════════════════════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Charger les variables d'environnement
|
||||||
|
if [ -f ".env" ]; then
|
||||||
|
export $(cat .env | grep -v '^#' | xargs 2>/dev/null)
|
||||||
|
else
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Fichier .env non trouvé"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extraire les informations de connexion
|
||||||
|
DB_USER=$(echo $DATABASE_URL | sed -n 's/.*:\/\/\([^:]*\):.*/\1/p')
|
||||||
|
DB_PASS=$(echo $DATABASE_URL | sed -n 's/.*:\/\/[^:]*:\([^@]*\)@.*/\1/p')
|
||||||
|
DB_HOST=$(echo $DATABASE_URL | sed -n 's/.*@\([^:]*\):.*/\1/p')
|
||||||
|
DB_PORT=$(echo $DATABASE_URL | sed -n 's/.*:\([0-9]*\)\/.*/\1/p')
|
||||||
|
DB_NAME=$(echo $DATABASE_URL | sed -n 's/.*\/\([^?]*\).*/\1/p')
|
||||||
|
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo " 1. VÉRIFICATION JWT_SECRET"
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [ -z "$JWT_SECRET" ]; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} JWT_SECRET n'est pas définie dans .env"
|
||||||
|
echo -e "${YELLOW}[ACTION]${NC} Ajoutez JWT_SECRET dans .env:"
|
||||||
|
echo " JWT_SECRET=$(openssl rand -base64 32)"
|
||||||
|
JWT_OK=false
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}[OK]${NC} JWT_SECRET est définie"
|
||||||
|
SECRET_LENGTH=${#JWT_SECRET}
|
||||||
|
echo " Longueur: $SECRET_LENGTH caractères"
|
||||||
|
if [ $SECRET_LENGTH -lt 32 ]; then
|
||||||
|
echo -e "${YELLOW}[WARN]${NC} JWT_SECRET est trop courte (recommandé: 32+ caractères)"
|
||||||
|
JWT_OK=false
|
||||||
|
else
|
||||||
|
JWT_OK=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo " 2. VÉRIFICATION DE L'UTILISATEUR DANS LA BASE DE DONNÉES"
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Vérifier l'utilisateur
|
||||||
|
USER_INFO=$(mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -D $DB_NAME -se "SELECT username, email, role, isActive, loginMethod, LENGTH(password) as pwd_len FROM users WHERE username='adminServFormation';" 2>/dev/null)
|
||||||
|
|
||||||
|
if [ -z "$USER_INFO" ]; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Utilisateur 'adminServFormation' n'existe pas"
|
||||||
|
echo -e "${YELLOW}[ACTION]${NC} Exécutez: ./create-admin.sh"
|
||||||
|
USER_OK=false
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}[OK]${NC} Utilisateur 'adminServFormation' existe"
|
||||||
|
echo ""
|
||||||
|
echo "Détails de l'utilisateur:"
|
||||||
|
|
||||||
|
# Parser les informations
|
||||||
|
IFS=$'\t' read -r username email role isActive loginMethod pwd_len <<< "$USER_INFO"
|
||||||
|
|
||||||
|
echo " Username: $username"
|
||||||
|
echo " Email: $email"
|
||||||
|
echo " Role: $role"
|
||||||
|
echo " Active: $isActive"
|
||||||
|
echo " Login Method: $loginMethod"
|
||||||
|
echo " Password length: $pwd_len caractères"
|
||||||
|
|
||||||
|
# Vérifications
|
||||||
|
if [ "$isActive" != "1" ]; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} L'utilisateur est désactivé (isActive = 0)"
|
||||||
|
USER_OK=false
|
||||||
|
elif [ -z "$pwd_len" ] || [ "$pwd_len" = "0" ]; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Le mot de passe est vide"
|
||||||
|
USER_OK=false
|
||||||
|
elif [ "$role" != "admin" ]; then
|
||||||
|
echo -e "${YELLOW}[WARN]${NC} L'utilisateur n'a pas le rôle admin"
|
||||||
|
USER_OK=true
|
||||||
|
else
|
||||||
|
USER_OK=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo " 3. VÉRIFICATION DU SERVICE"
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
SERVICE_OK=false
|
||||||
|
|
||||||
|
if command -v systemctl &> /dev/null; then
|
||||||
|
if systemctl list-unit-files | grep -q "formation-manager"; then
|
||||||
|
if systemctl is-active --quiet formation-manager; then
|
||||||
|
echo -e "${GREEN}[OK]${NC} Service formation-manager est actif"
|
||||||
|
SERVICE_OK=true
|
||||||
|
|
||||||
|
# Vérifier les logs récents
|
||||||
|
echo ""
|
||||||
|
echo "Dernières lignes des logs:"
|
||||||
|
echo "---"
|
||||||
|
sudo journalctl -u formation-manager -n 5 --no-pager 2>/dev/null | tail -5
|
||||||
|
echo "---"
|
||||||
|
else
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Service formation-manager n'est pas actif"
|
||||||
|
echo -e "${YELLOW}[ACTION]${NC} Démarrez le service: sudo systemctl start formation-manager"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}[INFO]${NC} Service systemd 'formation-manager' n'existe pas"
|
||||||
|
echo "L'application doit être démarrée manuellement"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo " 4. VÉRIFICATION DE L'APPLICATION"
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if command -v curl &> /dev/null; then
|
||||||
|
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3000 2>/dev/null || echo "000")
|
||||||
|
|
||||||
|
if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "302" ]; then
|
||||||
|
echo -e "${GREEN}[OK]${NC} Application répond (HTTP $HTTP_CODE)"
|
||||||
|
APP_OK=true
|
||||||
|
else
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Application ne répond pas (HTTP $HTTP_CODE)"
|
||||||
|
echo -e "${YELLOW}[ACTION]${NC} Vérifiez que l'application est démarrée"
|
||||||
|
APP_OK=false
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo " 5. TEST DE CONNEXION (SIMULATION)"
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Vérifier bcryptjs
|
||||||
|
if [ -d "node_modules/bcryptjs" ]; then
|
||||||
|
echo -e "${GREEN}[OK]${NC} bcryptjs est installé"
|
||||||
|
|
||||||
|
# Tester le hash du mot de passe
|
||||||
|
echo ""
|
||||||
|
echo "Test de vérification du mot de passe..."
|
||||||
|
|
||||||
|
STORED_HASH=$(mysql -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASS -D $DB_NAME -se "SELECT password FROM users WHERE username='adminServFormation';" 2>/dev/null)
|
||||||
|
|
||||||
|
if [ -n "$STORED_HASH" ]; then
|
||||||
|
# Utiliser Node.js pour vérifier le hash
|
||||||
|
HASH_VALID=$(node -e "
|
||||||
|
const bcrypt = require('bcryptjs');
|
||||||
|
const hash = '$STORED_HASH';
|
||||||
|
const password = 'Itinova69!';
|
||||||
|
bcrypt.compare(password, hash, (err, result) => {
|
||||||
|
if (err) {
|
||||||
|
console.log('ERROR');
|
||||||
|
} else {
|
||||||
|
console.log(result ? 'VALID' : 'INVALID');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
" 2>/dev/null)
|
||||||
|
|
||||||
|
if [ "$HASH_VALID" = "VALID" ]; then
|
||||||
|
echo -e "${GREEN}[OK]${NC} Le hash du mot de passe est valide pour 'Itinova69!'"
|
||||||
|
HASH_OK=true
|
||||||
|
elif [ "$HASH_VALID" = "INVALID" ]; then
|
||||||
|
echo -e "${RED}[ERREUR]${NC} Le hash du mot de passe ne correspond pas à 'Itinova69!'"
|
||||||
|
echo -e "${YELLOW}[ACTION]${NC} Réexécutez: ./create-admin.sh"
|
||||||
|
HASH_OK=false
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}[WARN]${NC} Impossible de vérifier le hash (erreur Node.js)"
|
||||||
|
HASH_OK=false
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${RED}[ERREUR]${NC} bcryptjs n'est pas installé"
|
||||||
|
echo -e "${YELLOW}[ACTION]${NC} Exécutez: pnpm install"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo " RÉSUMÉ"
|
||||||
|
echo "═══════════════════════════════════════════════════════════════"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
ALL_OK=true
|
||||||
|
|
||||||
|
if [ "$JWT_OK" = true ]; then
|
||||||
|
echo -e "${GREEN}✓${NC} JWT_SECRET configuré correctement"
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗${NC} JWT_SECRET manquant ou invalide"
|
||||||
|
ALL_OK=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$USER_OK" = true ]; then
|
||||||
|
echo -e "${GREEN}✓${NC} Utilisateur adminServFormation configuré correctement"
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗${NC} Problème avec l'utilisateur adminServFormation"
|
||||||
|
ALL_OK=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$HASH_OK" = true ]; then
|
||||||
|
echo -e "${GREEN}✓${NC} Hash du mot de passe valide"
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗${NC} Problème avec le hash du mot de passe"
|
||||||
|
ALL_OK=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$SERVICE_OK" = true ] || [ "$APP_OK" = true ]; then
|
||||||
|
echo -e "${GREEN}✓${NC} Application en cours d'exécution"
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗${NC} Application non démarrée"
|
||||||
|
ALL_OK=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [ "$ALL_OK" = true ]; then
|
||||||
|
echo "╔════════════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ Tout est configuré correctement! ✅ ║"
|
||||||
|
echo "╚════════════════════════════════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
echo "🔑 Vous devriez pouvoir vous connecter avec:"
|
||||||
|
echo " Identifiant: adminServFormation"
|
||||||
|
echo " Mot de passe: Itinova69!"
|
||||||
|
echo ""
|
||||||
|
echo "Si la connexion échoue toujours, vérifiez les logs:"
|
||||||
|
echo " sudo journalctl -u formation-manager -f"
|
||||||
|
else
|
||||||
|
echo "╔════════════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ Des problèmes ont été détectés ⚠️ ║"
|
||||||
|
echo "╚════════════════════════════════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
echo "Actions recommandées:"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [ "$JWT_OK" != true ]; then
|
||||||
|
echo "1. Ajouter JWT_SECRET dans .env:"
|
||||||
|
echo " echo \"JWT_SECRET=\$(openssl rand -base64 32)\" >> .env"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$USER_OK" != true ] || [ "$HASH_OK" != true ]; then
|
||||||
|
echo "2. Réinitialiser l'utilisateur admin:"
|
||||||
|
echo " ./create-admin.sh"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$SERVICE_OK" != true ] && [ "$APP_OK" != true ]; then
|
||||||
|
echo "3. Redémarrer l'application:"
|
||||||
|
echo " sudo systemctl restart formation-manager"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user