mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-23 06:58:19 +02:00
Improve user creation process with better error logging and testing
Add detailed logging and a test script to diagnose and fix user creation failures in production. Replit-Commit-Author: Agent Replit-Commit-Session-Id: a8a78c07-e900-425c-a577-5b4c5894379d Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/a8a78c07-e900-425c-a577-5b4c5894379d/AwxJU6M
This commit is contained in:
1 parent
7235be8b84
commit
b886f317ca
5 files changed
+198
-16
No files matched your search
@@ -51,12 +51,33 @@ Si l'interface affiche "Aucun utilisateur trouvé" :
|
|||||||
- `debug-usergroups-production.sql` : Problèmes d'association utilisateur-groupe
|
- `debug-usergroups-production.sql` : Problèmes d'association utilisateur-groupe
|
||||||
- `production-users-debug.sql` : Problème de récupération des utilisateurs
|
- `production-users-debug.sql` : Problème de récupération des utilisateurs
|
||||||
|
|
||||||
|
### Problème Création d'Utilisateur
|
||||||
|
Si la création d'utilisateur échoue :
|
||||||
|
|
||||||
|
1. **Test Manuel** : Utilisez `test-create-user-production.js`
|
||||||
|
```bash
|
||||||
|
PRODUCTION_HOST=votre-domaine.com SESSION_COOKIE="connect.sid=..." node test-create-user-production.js
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Vérification Logs** : Cherchez ces messages d'erreur :
|
||||||
|
- `❌ Password hashing failed`
|
||||||
|
- `❌ Storage createUser error`
|
||||||
|
- Database connection errors
|
||||||
|
|
||||||
### Logs de Débogage Disponibles
|
### Logs de Débogage Disponibles
|
||||||
|
**Récupération Utilisateurs :**
|
||||||
- `🔍 GET /api/users - Fetching users with simplified approach`
|
- `🔍 GET /api/users - Fetching users with simplified approach`
|
||||||
- `📊 Found X base users`
|
- `📊 Found X base users`
|
||||||
- `❌ Error getting groups for user [username]:`
|
- `❌ Error getting groups for user [username]:`
|
||||||
- `🔐 API /api/users - Returning: {length: X, totalGroups: Y}`
|
- `🔐 API /api/users - Returning: {length: X, totalGroups: Y}`
|
||||||
|
|
||||||
|
**Création Utilisateur :**
|
||||||
|
- `🔍 POST /api/users - Creating new user`
|
||||||
|
- `📥 Request body: [données]`
|
||||||
|
- `🔒 Hashing password...`
|
||||||
|
- `🔍 Storage createUser called with: [username]`
|
||||||
|
- `✅ Storage createUser successful: [username]`
|
||||||
|
|
||||||
## Déploiement
|
## Déploiement
|
||||||
|
|
||||||
1. Redéployez votre application avec les dernières modifications
|
1. Redéployez votre application avec les dernières modifications
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 278 KiB |
+44
-7
@@ -907,9 +907,13 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
|||||||
|
|
||||||
app.post('/api/users', isAuthenticated, async (req: any, res) => {
|
app.post('/api/users', isAuthenticated, async (req: any, res) => {
|
||||||
try {
|
try {
|
||||||
|
console.log('🔍 POST /api/users - Creating new user');
|
||||||
|
console.log('📥 Request body:', JSON.stringify(req.body, null, 2));
|
||||||
|
|
||||||
const userId = req.user.claims ? req.user.claims.sub : req.user.id;
|
const userId = req.user.claims ? req.user.claims.sub : req.user.id;
|
||||||
const currentUser = await storage.getUserWithGroups(userId);
|
const currentUser = await storage.getUserWithGroups(userId);
|
||||||
if (!currentUser || currentUser.role !== 'admin') {
|
if (!currentUser || currentUser.role !== 'admin') {
|
||||||
|
console.log('❌ Access denied - user not admin');
|
||||||
return res.status(403).json({ message: "Access denied" });
|
return res.status(403).json({ message: "Access denied" });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -924,23 +928,51 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
|||||||
role: z.enum(['admin', 'directeur', 'manager', 'employee']).optional(),
|
role: z.enum(['admin', 'directeur', 'manager', 'employee']).optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log('🔍 Parsing user data...');
|
||||||
const userData = createUserSchema.parse(req.body);
|
const userData = createUserSchema.parse(req.body);
|
||||||
|
console.log('✅ User data parsed successfully');
|
||||||
|
|
||||||
// Hash password if provided (for local auth)
|
// Hash password with improved error handling
|
||||||
|
let hashedPassword = userData.password;
|
||||||
if (userData.password) {
|
if (userData.password) {
|
||||||
userData.password = await hashPasswordSimple(userData.password);
|
try {
|
||||||
|
console.log('🔒 Hashing password...');
|
||||||
|
hashedPassword = await hashPasswordSimple(userData.password);
|
||||||
|
console.log('✅ Password hashed successfully');
|
||||||
|
} catch (hashError) {
|
||||||
|
console.error('❌ Password hashing failed:', hashError);
|
||||||
|
return res.status(500).json({ message: "Failed to secure password" });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const newUser = await storage.createUser({
|
// Generate unique ID
|
||||||
id: userData.id || `manual_${Date.now()}`, // Generate manual ID for created users
|
const newUserId = userData.id || `manual_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
||||||
...userData,
|
console.log('🔍 Generated user ID:', newUserId);
|
||||||
});
|
|
||||||
|
const userToCreate = {
|
||||||
|
id: newUserId,
|
||||||
|
username: userData.username,
|
||||||
|
email: userData.email || '',
|
||||||
|
firstName: userData.firstName || '',
|
||||||
|
lastName: userData.lastName || '',
|
||||||
|
password: hashedPassword,
|
||||||
|
role: userData.role || 'employee',
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('🔍 Creating user in database...');
|
||||||
|
const newUser = await storage.createUser(userToCreate);
|
||||||
|
console.log('✅ User created successfully:', newUser.username);
|
||||||
|
|
||||||
res.json(newUser);
|
res.json(newUser);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error creating user:", error);
|
console.error("❌ Error creating user:", error);
|
||||||
|
console.error("❌ Error type:", error.constructor.name);
|
||||||
|
console.error("❌ Error code:", error.code);
|
||||||
|
console.error("❌ Error constraint:", error.constraint);
|
||||||
|
console.error("❌ Error stack:", error.stack);
|
||||||
|
|
||||||
if (error instanceof z.ZodError) {
|
if (error instanceof z.ZodError) {
|
||||||
|
console.log('❌ Validation error:', error.errors);
|
||||||
return res.status(400).json({ message: "Invalid user data", errors: error.errors });
|
return res.status(400).json({ message: "Invalid user data", errors: error.errors });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -958,6 +990,11 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle connection errors
|
||||||
|
if (error.code === 'ECONNREFUSED' || error.code === 'ENOTFOUND') {
|
||||||
|
return res.status(503).json({ message: "Database connection error" });
|
||||||
|
}
|
||||||
|
|
||||||
res.status(500).json({ message: "Failed to create user" });
|
res.status(500).json({ message: "Failed to create user" });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
+18
-9
@@ -296,15 +296,24 @@ export class DatabaseStorage implements IStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async createUser(userData: UpsertUser): Promise<User> {
|
async createUser(userData: UpsertUser): Promise<User> {
|
||||||
const [user] = await db
|
console.log('🔍 Storage createUser called with:', userData.username);
|
||||||
.insert(users)
|
try {
|
||||||
.values({
|
const [user] = await db
|
||||||
...userData,
|
.insert(users)
|
||||||
createdAt: new Date(),
|
.values({
|
||||||
updatedAt: new Date(),
|
...userData,
|
||||||
})
|
createdAt: new Date(),
|
||||||
.returning();
|
updatedAt: new Date(),
|
||||||
return user;
|
})
|
||||||
|
.returning();
|
||||||
|
console.log('✅ Storage createUser successful:', user.username);
|
||||||
|
return user;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ Storage createUser error:', error);
|
||||||
|
console.error('❌ Storage error code:', error.code);
|
||||||
|
console.error('❌ Storage error constraint:', error.constraint);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateUser(id: string, userData: Partial<UpsertUser>): Promise<User> {
|
async updateUser(id: string, userData: Partial<UpsertUser>): Promise<User> {
|
||||||
|
|||||||
@@ -0,0 +1,115 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script de test pour la création d'utilisateur en production
|
||||||
|
* Usage: node test-create-user-production.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
const https = require('https');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
hostname: process.env.PRODUCTION_HOST || 'your-domain.com',
|
||||||
|
port: 443,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Cookie': process.env.SESSION_COOKIE || ''
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Test data
|
||||||
|
const testUser = {
|
||||||
|
username: `test_${Date.now()}`,
|
||||||
|
email: `test_${Date.now()}@example.com`,
|
||||||
|
firstName: 'Test',
|
||||||
|
lastName: 'User',
|
||||||
|
password: 'TestPassword123',
|
||||||
|
role: 'employee'
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('🔍 Testing user creation in production...');
|
||||||
|
console.log('📊 Test user data:', JSON.stringify(testUser, null, 2));
|
||||||
|
|
||||||
|
const postData = JSON.stringify(testUser);
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
...config,
|
||||||
|
path: '/api/users',
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
...config.headers,
|
||||||
|
'Content-Length': Buffer.byteLength(postData)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const req = https.request(options, (res) => {
|
||||||
|
console.log(`📡 Response status: ${res.statusCode}`);
|
||||||
|
console.log('📡 Response headers:', res.headers);
|
||||||
|
|
||||||
|
let data = '';
|
||||||
|
res.on('data', (chunk) => {
|
||||||
|
data += chunk;
|
||||||
|
});
|
||||||
|
|
||||||
|
res.on('end', () => {
|
||||||
|
try {
|
||||||
|
const response = JSON.parse(data);
|
||||||
|
if (res.statusCode === 200 || res.statusCode === 201) {
|
||||||
|
console.log('✅ User created successfully!');
|
||||||
|
console.log('👤 New user:', response);
|
||||||
|
} else {
|
||||||
|
console.log('❌ User creation failed');
|
||||||
|
console.log('📄 Error response:', response);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log('❌ Failed to parse response:', data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
req.on('error', (error) => {
|
||||||
|
console.error('❌ Request error:', error);
|
||||||
|
});
|
||||||
|
|
||||||
|
req.write(postData);
|
||||||
|
req.end();
|
||||||
|
|
||||||
|
// Also test the users endpoint
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log('\n🔍 Testing users list endpoint...');
|
||||||
|
|
||||||
|
const getUsersOptions = {
|
||||||
|
...config,
|
||||||
|
path: '/api/users',
|
||||||
|
method: 'GET'
|
||||||
|
};
|
||||||
|
|
||||||
|
const getUsersReq = https.request(getUsersOptions, (res) => {
|
||||||
|
console.log(`📡 Users list status: ${res.statusCode}`);
|
||||||
|
|
||||||
|
let data = '';
|
||||||
|
res.on('data', (chunk) => {
|
||||||
|
data += chunk;
|
||||||
|
});
|
||||||
|
|
||||||
|
res.on('end', () => {
|
||||||
|
try {
|
||||||
|
const users = JSON.parse(data);
|
||||||
|
if (Array.isArray(users)) {
|
||||||
|
console.log(`✅ Found ${users.length} users`);
|
||||||
|
console.log('👥 Users:', users.map(u => ({ username: u.username, role: u.role, groups: u.userGroups?.length || 0 })));
|
||||||
|
} else {
|
||||||
|
console.log('❌ Invalid users response:', users);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log('❌ Failed to parse users response:', data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
getUsersReq.on('error', (error) => {
|
||||||
|
console.error('❌ Users request error:', error);
|
||||||
|
});
|
||||||
|
|
||||||
|
getUsersReq.end();
|
||||||
|
}, 2000);
|
||||||
Reference in new issue
Block a user