149 lines
4.8 KiB
Dart
149 lines
4.8 KiB
Dart
import 'dart:convert';
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
import '../models/user.dart';
|
|
import 'api/api_config.dart';
|
|
import 'api/tokenService.dart';
|
|
|
|
class AuthService {
|
|
static const String _currentUserKey = 'current_user';
|
|
|
|
/// Connexion de l'utilisateur
|
|
/// Retourne l'utilisateur connecté avec le flag changement_mdp_obligatoire
|
|
static Future<AppUser> login(String email, String password) async {
|
|
try {
|
|
final response = await http.post(
|
|
Uri.parse('${ApiConfig.baseUrl}${ApiConfig.login}'),
|
|
headers: ApiConfig.headers,
|
|
body: jsonEncode({
|
|
'email': email,
|
|
'password': password,
|
|
}),
|
|
);
|
|
|
|
if (response.statusCode == 200 || response.statusCode == 201) {
|
|
final data = jsonDecode(response.body);
|
|
// API renvoie access_token / refresh_token (snake_case)
|
|
final accessToken = data['access_token'] as String? ?? data['accessToken'] as String?;
|
|
final refreshToken = data['refresh_token'] as String? ?? data['refreshToken'] as String?;
|
|
if (accessToken == null) throw Exception('Token absent dans la réponse serveur');
|
|
|
|
await TokenService.saveToken(accessToken);
|
|
await TokenService.saveRefreshToken(refreshToken ?? '');
|
|
|
|
final user = await _fetchUserProfile(accessToken);
|
|
|
|
// Stocker l'utilisateur en cache
|
|
await _saveCurrentUser(user);
|
|
|
|
return user;
|
|
} else {
|
|
final error = jsonDecode(response.body);
|
|
throw Exception(error['message'] ?? 'Erreur de connexion');
|
|
}
|
|
} catch (e) {
|
|
if (e is Exception) rethrow;
|
|
throw Exception('Erreur réseau: impossible de se connecter au serveur');
|
|
}
|
|
}
|
|
|
|
/// Récupère le profil utilisateur via /auth/me
|
|
static Future<AppUser> _fetchUserProfile(String token) async {
|
|
try {
|
|
final response = await http.get(
|
|
Uri.parse('${ApiConfig.baseUrl}${ApiConfig.authMe}'),
|
|
headers: ApiConfig.authHeaders(token),
|
|
);
|
|
|
|
if (response.statusCode == 200) {
|
|
final data = jsonDecode(response.body);
|
|
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');
|
|
}
|
|
}
|
|
|
|
/// Changement de mot de passe obligatoire
|
|
static Future<void> changePasswordRequired({
|
|
required String currentPassword,
|
|
required String newPassword,
|
|
}) async {
|
|
final token = await TokenService.getToken();
|
|
if (token == null) {
|
|
throw Exception('Non authentifié');
|
|
}
|
|
|
|
try {
|
|
final response = await http.post(
|
|
Uri.parse('${ApiConfig.baseUrl}${ApiConfig.changePasswordRequired}'),
|
|
headers: ApiConfig.authHeaders(token),
|
|
body: jsonEncode({
|
|
'mot_de_passe_actuel': currentPassword,
|
|
'nouveau_mot_de_passe': newPassword,
|
|
'confirmation_mot_de_passe': newPassword,
|
|
}),
|
|
);
|
|
|
|
if (response.statusCode != 200 && response.statusCode != 201) {
|
|
final error = jsonDecode(response.body);
|
|
throw Exception(error['message'] ?? 'Erreur lors du changement de mot de passe');
|
|
}
|
|
|
|
// Après le changement de MDP, rafraîchir le profil utilisateur
|
|
final user = await _fetchUserProfile(token);
|
|
await _saveCurrentUser(user);
|
|
} catch (e) {
|
|
if (e is Exception) rethrow;
|
|
throw Exception('Erreur réseau: impossible de changer le mot de passe');
|
|
}
|
|
}
|
|
|
|
/// Déconnexion de l'utilisateur
|
|
static Future<void> logout() async {
|
|
await TokenService.clearAll();
|
|
final prefs = await SharedPreferences.getInstance();
|
|
await prefs.remove(_currentUserKey);
|
|
}
|
|
|
|
/// Vérifie si l'utilisateur est connecté
|
|
static Future<bool> isLoggedIn() async {
|
|
final token = await TokenService.getToken();
|
|
return token != null;
|
|
}
|
|
|
|
/// Récupère l'utilisateur connecté depuis le cache
|
|
static Future<AppUser?> getCurrentUser() async {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final userJson = prefs.getString(_currentUserKey);
|
|
|
|
if (userJson != null) {
|
|
return AppUser.fromJson(jsonDecode(userJson));
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/// Sauvegarde l'utilisateur actuel en cache
|
|
static Future<void> _saveCurrentUser(AppUser user) async {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
await prefs.setString(_currentUserKey, jsonEncode(user.toJson()));
|
|
}
|
|
|
|
/// Rafraîchit le profil utilisateur depuis l'API
|
|
static Future<AppUser?> refreshCurrentUser() async {
|
|
final token = await TokenService.getToken();
|
|
if (token == null) return null;
|
|
|
|
try {
|
|
final user = await _fetchUserProfile(token);
|
|
await _saveCurrentUser(user);
|
|
return user;
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
} |