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 bcrypt from "bcryptjs";
|
||||
import jwt from "jsonwebtoken";
|
||||
import { getDb } from "../db";
|
||||
import { users } from "../../drizzle/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { ENV } from "./env";
|
||||
import { COOKIE_NAME } from "@shared/const";
|
||||
import { getSessionCookieOptions } from "./cookies";
|
||||
import { sdk } from "./sdk";
|
||||
|
||||
const router = Router();
|
||||
|
||||
@@ -75,16 +74,11 @@ router.post("/login", async (req, res) => {
|
||||
.set({ lastSignedIn: new Date() })
|
||||
.where(eq(users.id, user.id));
|
||||
|
||||
// Créer le token JWT
|
||||
const token = jwt.sign(
|
||||
{
|
||||
openId: user.openId,
|
||||
name: user.name,
|
||||
email: user.email,
|
||||
},
|
||||
ENV.jwtSecret,
|
||||
{ expiresIn: "7d", algorithm: "HS256" }
|
||||
);
|
||||
// Créer le token de session (compatible avec le système OAuth)
|
||||
const token = await sdk.createSessionToken(user.openId, {
|
||||
name: user.name || "",
|
||||
expiresInMs: 7 * 24 * 60 * 60 * 1000, // 7 jours
|
||||
});
|
||||
|
||||
// Définir le cookie de session
|
||||
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