From 7f8104e7e44145e98ba956da8700513fd92cefdb Mon Sep 17 00:00:00 2001 From: Julien Martin Date: Tue, 17 Feb 2026 15:54:24 +0100 Subject: [PATCH] fix(auth): correctif login et parsing user (version stable) Co-authored-by: Cursor --- frontend/lib/models/user.dart | 44 +++++++++++++-------- frontend/lib/screens/auth/login_screen.dart | 8 ++-- frontend/lib/services/auth_service.dart | 18 +++++++-- 3 files changed, 46 insertions(+), 24 deletions(-) diff --git a/frontend/lib/models/user.dart b/frontend/lib/models/user.dart index 7ecbe79..5dbfa81 100644 --- a/frontend/lib/models/user.dart +++ b/frontend/lib/models/user.dart @@ -32,30 +32,42 @@ class AppUser { }); factory AppUser.fromJson(Map json) { + final id = json['id']?.toString(); + final email = json['email']?.toString(); + final role = json['role']?.toString(); + if (id == null || id.isEmpty) { + throw Exception('Profil invalide: id manquant'); + } + if (email == null || email.isEmpty) { + throw Exception('Profil invalide: email manquant'); + } + if (role == null || role.isEmpty) { + throw Exception('Profil invalide: rôle manquant'); + } return AppUser( - id: json['id'] as String, - email: json['email'] as String, - role: json['role'] as String, + id: id, + email: email, + role: role, createdAt: json['cree_le'] != null - ? DateTime.parse(json['cree_le'] as String) + ? DateTime.tryParse(json['cree_le'].toString()) ?? DateTime.now() : (json['createdAt'] != null - ? DateTime.parse(json['createdAt'] as String) + ? DateTime.tryParse(json['createdAt'].toString()) ?? DateTime.now() : DateTime.now()), updatedAt: json['modifie_le'] != null - ? DateTime.parse(json['modifie_le'] as String) + ? DateTime.tryParse(json['modifie_le'].toString()) ?? DateTime.now() : (json['updatedAt'] != null - ? DateTime.parse(json['updatedAt'] as String) + ? DateTime.tryParse(json['updatedAt'].toString()) ?? DateTime.now() : DateTime.now()), changementMdpObligatoire: - json['changement_mdp_obligatoire'] as bool? ?? false, - nom: json['nom'] as String?, - prenom: json['prenom'] as String?, - statut: json['statut'] as String?, - telephone: json['telephone'] as String?, - photoUrl: json['photo_url'] as String?, - adresse: json['adresse'] as String?, - ville: json['ville'] as String?, - codePostal: json['code_postal'] as String?, + json['changement_mdp_obligatoire'] == true, + nom: json['nom']?.toString(), + prenom: json['prenom']?.toString(), + statut: json['statut']?.toString(), + telephone: json['telephone']?.toString(), + photoUrl: json['photo_url']?.toString(), + adresse: json['adresse']?.toString(), + ville: json['ville']?.toString(), + codePostal: json['code_postal']?.toString(), ); } diff --git a/frontend/lib/screens/auth/login_screen.dart b/frontend/lib/screens/auth/login_screen.dart index b441062..eae2ee6 100644 --- a/frontend/lib/screens/auth/login_screen.dart +++ b/frontend/lib/screens/auth/login_screen.dart @@ -236,20 +236,20 @@ class _LoginPageState extends State with WidgetsBindingObserver { padding: const EdgeInsets.all(12), margin: const EdgeInsets.only(bottom: 15), decoration: BoxDecoration( - color: Colors.red[50], + color: Colors.red.shade50, borderRadius: BorderRadius.circular(10), - border: Border.all(color: Colors.red[300]!), + border: Border.all(color: Colors.red.shade300), ), child: Row( children: [ - Icon(Icons.error_outline, color: Colors.red[700], size: 20), + Icon(Icons.error_outline, color: Colors.red.shade700, size: 20), const SizedBox(width: 10), Expanded( child: Text( _errorMessage!, style: GoogleFonts.merienda( fontSize: 12, - color: Colors.red[700], + color: Colors.red.shade700, ), ), ), diff --git a/frontend/lib/services/auth_service.dart b/frontend/lib/services/auth_service.dart index 7a44678..536bea3 100644 --- a/frontend/lib/services/auth_service.dart +++ b/frontend/lib/services/auth_service.dart @@ -43,7 +43,8 @@ class AuthService { } } catch (e) { if (e is Exception) rethrow; - throw Exception('Erreur réseau: impossible de se connecter au serveur'); + if (e is Error) throw Exception('Erreur interne: ${e.toString()}'); + throw Exception('Erreur réseau: impossible de se connecter au serveur ($e)'); } } @@ -56,14 +57,22 @@ class AuthService { ); if (response.statusCode == 200) { - final data = jsonDecode(response.body); + final raw = jsonDecode(response.body); + if (raw is! Map) { + throw Exception('Profil invalide: réponse serveur inattendue'); + } + // Accepter réponse directe ou wrapper { data: {...} } + final data = raw.containsKey('data') && raw['data'] is Map + ? raw['data'] as Map + : raw; return AppUser.fromJson(data); } else { throw Exception('Erreur lors de la récupération du profil'); } } catch (e) { if (e is Exception) rethrow; - throw Exception('Erreur réseau: impossible de récupérer le profil'); + if (e is Error) throw Exception('Erreur interne: ${e.toString()}'); + throw Exception('Erreur réseau: impossible de récupérer le profil ($e)'); } } @@ -98,7 +107,8 @@ class AuthService { await _saveCurrentUser(user); } catch (e) { if (e is Exception) rethrow; - throw Exception('Erreur réseau: impossible de changer le mot de passe'); + if (e is Error) throw Exception('Erreur interne: ${e.toString()}'); + throw Exception('Erreur réseau: impossible de changer le mot de passe ($e)'); } }