refactoring and checkpoint

This commit is contained in:
DahoudG
2024-09-24 00:32:20 +00:00
parent dc73ba7dcc
commit 6b12cfeb41
159 changed files with 8119 additions and 1535 deletions

View File

@@ -33,7 +33,7 @@ class EventRemoteDataSource {
print('Création d\'un nouvel événement avec les données: ${event.toJson()}');
final response = await client.post(
Uri.parse(Urls.eventsUrl),
Uri.parse(Urls.createEvent),
headers: {'Content-Type': 'application/json'},
body: jsonEncode(event.toJson()),
);
@@ -53,7 +53,7 @@ class EventRemoteDataSource {
Future<EventModel> getEventById(String id) async {
print('Récupération de l\'événement avec l\'ID: $id');
final response = await client.get(Uri.parse('${Urls.eventsUrl}/$id'));
final response = await client.get(Uri.parse('${Urls.getEventById}/$id'));
print('Statut de la réponse: ${response.statusCode}');
@@ -71,7 +71,7 @@ class EventRemoteDataSource {
print('Mise à jour de l\'événement avec l\'ID: $id, données: ${event.toJson()}');
final response = await client.put(
Uri.parse('${Urls.eventsUrl}/$id'),
Uri.parse('${Urls.updateEvent}/$id'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode(event.toJson()),
);
@@ -91,7 +91,7 @@ class EventRemoteDataSource {
Future<void> deleteEvent(String id) async {
print('Suppression de l\'événement avec l\'ID: $id');
final response = await client.delete(Uri.parse('${Urls.eventsUrl}/$id'));
final response = await client.delete(Uri.parse('${Urls.deleteEvent}/$id'));
print('Statut de la réponse: ${response.statusCode}');
@@ -108,7 +108,7 @@ class EventRemoteDataSource {
print('Participation à l\'événement avec l\'ID: $eventId, utilisateur: $userId');
final response = await client.post(
Uri.parse('${Urls.eventsUrl}/$eventId/participate'),
Uri.parse('${Urls.addParticipant}/$eventId/participate'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({'userId': userId}),
);
@@ -129,7 +129,7 @@ class EventRemoteDataSource {
print('Réaction à l\'événement avec l\'ID: $eventId, utilisateur: $userId');
final response = await client.post(
Uri.parse('${Urls.eventsUrl}/$eventId/react'),
Uri.parse('${Urls.baseUrl}/$eventId/react'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({'userId': userId}),
);
@@ -149,7 +149,7 @@ class EventRemoteDataSource {
print('Fermeture de l\'événement avec l\'ID: $eventId');
final response = await client.post(
Uri.parse('${Urls.eventsUrl}/$eventId/close'),
Uri.parse('${Urls.closeEvent}/$eventId/close'),
headers: {'Content-Type': 'application/json'},
);
@@ -174,7 +174,7 @@ class EventRemoteDataSource {
print('Réouverture de l\'événement avec l\'ID: $eventId');
final response = await client.post(
Uri.parse('${Urls.eventsUrl}/$eventId/reopen'),
Uri.parse('${Urls.baseUrl}/$eventId/reopen'),
headers: {'Content-Type': 'application/json'},
);
@@ -193,4 +193,5 @@ class EventRemoteDataSource {
throw ServerExceptionWithMessage('Une erreur est survenue lors de la réouverture de l\'événement.');
}
}
}

View File

@@ -1,90 +1,141 @@
import 'dart:convert';
import 'package:afterwork/core/constants/urls.dart';
import 'package:afterwork/data/models/user_model.dart';
import 'package:http/http.dart' as http;
import '../../core/errors/exceptions.dart';
/// Classe pour gérer les opérations API pour les utilisateurs.
/// Chaque action est loguée pour faciliter la traçabilité et le débogage.
class UserRemoteDataSource {
final http.Client client;
/// Constructeur avec injection du client HTTP
UserRemoteDataSource(this.client);
// Authentifier l'utilisateur
Future<UserModel> authenticateUser(String email, String password, String userId) async {
if (email.isEmpty || password.isEmpty) {
throw Exception('Email ou mot de passe vide');
}
/// Authentifie un utilisateur avec l'email et le mot de passe en clair.
/// Si l'authentification réussit, retourne un objet `UserModel`.
Future<UserModel> authenticateUser(String email, String password) async {
print("Tentative d'authentification pour l'email : $email");
final response = await client.post(
Uri.parse('${Urls.baseUrl}/users/authenticate'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'email': email,
'motDePasse': password,
}),
);
try {
// Requête POST avec l'email et le mot de passe en clair
final response = await client.post(
Uri.parse('${Urls.baseUrl}/users/authenticate'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'email': email,
'motDePasse': password, // Le mot de passe est envoyé en clair pour le moment
}),
);
if (response.statusCode == 200) {
final jsonResponse = json.decode(response.body);
return UserModel.fromJson(jsonResponse);
} else if (response.statusCode == 401) {
throw AuthenticationException('Email ou mot de passe incorrect');
} else {
throw ServerException();
print("Réponse du serveur pour l'authentification : ${response.statusCode} - ${response.body}");
if (response.statusCode == 200) {
// Si l'authentification réussit, retourne l'utilisateur
return UserModel.fromJson(jsonDecode(response.body));
} else if (response.statusCode == 401) {
// Gestion des erreurs d'authentification
throw UnauthorizedException();
} else {
throw ServerException();
}
} catch (e) {
print("Erreur d'authentification : $e");
throw Exception("Erreur lors de l'authentification : $e");
}
}
// Récupérer un utilisateur par ID
/// Récupère un utilisateur par son identifiant et logue les étapes.
Future<UserModel> getUser(String id) async {
final response = await client.get(Uri.parse('${Urls.baseUrl}/users/$id'));
print("Tentative de récupération de l'utilisateur avec l'ID : $id");
if (response.statusCode == 200) {
return UserModel.fromJson(json.decode(response.body));
} else {
throw ServerException();
try {
final response = await client.get(Uri.parse('${Urls.baseUrl}/users/$id'));
print("Réponse du serveur pour getUser : ${response.statusCode} - ${response.body}");
if (response.statusCode == 200) {
return UserModel.fromJson(json.decode(response.body));
} else if (response.statusCode == 404) {
print("Utilisateur non trouvé.");
throw UserNotFoundException();
} else {
throw ServerException();
}
} catch (e) {
print("Erreur lors de la récupération de l'utilisateur : $e");
throw Exception("Erreur lors de la récupération de l'utilisateur : $e");
}
}
// Créer un nouvel utilisateur
/// Crée un nouvel utilisateur et logue les détails de la requête.
Future<UserModel> createUser(UserModel user) async {
final response = await client.post(
Uri.parse('${Urls.baseUrl}/users'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode(user.toJson()),
);
print("Création d'un nouvel utilisateur : ${user.toJson()}");
if (response.statusCode == 201) {
return UserModel.fromJson(json.decode(response.body));
} else {
throw ServerException();
try {
final response = await client.post(
Uri.parse('${Urls.baseUrl}/users'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode(user.toJson()),
);
print("Réponse du serveur pour createUser : ${response.statusCode} - ${response.body}");
if (response.statusCode == 201) {
return UserModel.fromJson(json.decode(response.body));
} else if (response.statusCode == 409) {
// Gestion des conflits (utilisateur déjà existant)
throw ConflictException();
} else {
throw ServerException();
}
} catch (e) {
print("Erreur lors de la création de l'utilisateur : $e");
throw Exception("Erreur lors de la création de l'utilisateur : $e");
}
}
// Mettre à jour un utilisateur
/// Met à jour un utilisateur existant et logue les étapes.
Future<UserModel> updateUser(UserModel user) async {
final response = await client.put(
Uri.parse('${Urls.baseUrl}/users/${user.userId}'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode(user.toJson()),
);
print("Mise à jour de l'utilisateur : ${user.toJson()}");
if (response.statusCode == 200) {
return UserModel.fromJson(json.decode(response.body));
} else {
throw ServerException();
try {
final response = await client.put(
Uri.parse('${Urls.baseUrl}/users/${user.userId}'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode(user.toJson()),
);
print("Réponse du serveur pour updateUser : ${response.statusCode} - ${response.body}");
if (response.statusCode == 200) {
return UserModel.fromJson(json.decode(response.body));
} else if (response.statusCode == 404) {
// Gestion des cas où l'utilisateur n'est pas trouvé
throw UserNotFoundException();
} else {
throw ServerException();
}
} catch (e) {
print("Erreur lors de la mise à jour de l'utilisateur : $e");
throw Exception("Erreur lors de la mise à jour de l'utilisateur : $e");
}
}
// Supprimer un utilisateur par ID
/// Supprime un utilisateur et logue chaque étape.
Future<void> deleteUser(String id) async {
final response = await client.delete(
Uri.parse('${Urls.baseUrl}/users/$id'),
);
print("Tentative de suppression de l'utilisateur avec l'ID : $id");
if (response.statusCode != 204) {
throw ServerException();
try {
final response = await client.delete(Uri.parse('${Urls.baseUrl}/users/$id'));
print("Réponse du serveur pour deleteUser : ${response.statusCode} - ${response.body}");
if (response.statusCode != 204) {
print("Erreur lors de la suppression de l'utilisateur.");
throw ServerException();
} else {
print("Utilisateur supprimé avec succès.");
}
} catch (e) {
print("Erreur lors de la suppression de l'utilisateur : $e");
throw Exception("Erreur lors de la suppression de l'utilisateur : $e");
}
}
}

View File

@@ -1,78 +1,71 @@
import 'package:afterwork/data/models/user_model.dart';
/// Modèle de données représentant un événement.
/// Cette classe encapsule toutes les propriétés d'un événement, y compris
/// le titre, la description, la date, la localisation, la catégorie, les liens,
/// l'image, le créateur, les participants et le statut de l'événement.
class EventModel {
final String id; // Identifiant unique de l'événement
final String title; // Titre de l'événement
final String description; // Description de l'événement
final String date; // Date de l'événement
final String location; // Localisation de l'événement
final String category; // Catégorie de l'événement
final String link; // Lien associé à l'événement
final String? imageUrl; // URL de l'image de l'événement (optionnel)
final UserModel creator; // Créateur de l'événement
final List<UserModel> participants; // Liste des participants à l'événement
final String status; // Statut de l'événement (e.g., "OPEN", "CLOSED")
final String id;
final String title;
final String description;
final String startDate; // Utiliser startDate au lieu de date, si c'est ce que l'API retourne
final String location;
final String category;
final String link;
final String? imageUrl; // Nullable
final String creatorEmail; // Remplacer UserModel si le créateur est un email
final List<dynamic> participants; // Si participants est une liste simple
final String status;
final int reactionsCount;
final int commentsCount;
final int sharesCount;
/// Constructeur pour initialiser toutes les propriétés de l'événement.
EventModel({
required this.id,
required this.title,
required this.description,
required this.date,
required this.startDate,
required this.location,
required this.category,
required this.link,
this.imageUrl,
required this.creator,
required this.creatorEmail,
required this.participants,
required this.status,
required this.reactionsCount,
required this.commentsCount,
required this.sharesCount,
});
/// Convertit un objet JSON en `EventModel`.
factory EventModel.fromJson(Map<String, dynamic> json) {
// Log de la conversion depuis JSON
print('Conversion de l\'objet JSON en EventModel: ${json['id']}');
return EventModel(
id: json['id'],
title: json['title'],
description: json['description'],
date: json['date'],
startDate: json['startDate'], // Vérifier si c'est bien startDate
location: json['location'],
category: json['category'],
link: json['link'] ?? '', // Assure qu'il ne soit pas null
imageUrl: json['imageUrl'] ?? '', // Assure qu'il ne soit pas null
status: json['status'],
creator: UserModel.fromJson(json['creator']),
participants: json['participants'] != null
? (json['participants'] as List)
.map((user) => UserModel.fromJson(user))
.toList()
: [], // Si participants est null, retourne une liste vide
link: json['link'] ?? '',
imageUrl: json['imageUrl'], // Peut être null
creatorEmail: json['creatorEmail'], // Email du créateur
participants: json['participants'] ?? [], // Gérer les participants
status: json['status'] ?? 'open', // Par défaut à "open" si non fourni
reactionsCount: json['reactionsCount'] ?? 0,
commentsCount: json['commentsCount'] ?? 0,
sharesCount: json['sharesCount'] ?? 0,
);
}
/// Convertit un `EventModel` en objet JSON.
Map<String, dynamic> toJson() {
// Log de la conversion en JSON
print('Conversion de l\'EventModel en objet JSON: $id');
return {
'id': id,
'title': title,
'description': description,
'date': date,
'startDate': startDate,
'location': location,
'category': category,
'link': link,
'imageUrl': imageUrl,
'creator': creator.toJson(),
'participants': participants.map((user) => user.toJson()).toList(),
'creatorEmail': creatorEmail,
'participants': participants,
'status': status,
'reactionsCount': reactionsCount,
'commentsCount': commentsCount,
'sharesCount': sharesCount,
};
}
}

View File

@@ -1,8 +1,10 @@
import 'package:afterwork/domain/entities/user.dart';
import '../../domain/entities/user.dart';
class UserModel extends User {
const UserModel({
required String userId, // Utilisez `id` pour correspondre à l'entité User
/// Modèle représentant l'utilisateur dans l'application AfterWork.
/// Ce modèle est utilisé pour la conversion JSON et l'interaction avec l'API.
class UserModel extends User {
UserModel({
required String userId,
required String nom,
required String prenoms,
required String email,
@@ -15,23 +17,25 @@ class UserModel extends User {
motDePasse: motDePasse,
);
/// Factory pour créer un `UserModel` à partir d'un JSON reçu depuis l'API.
factory UserModel.fromJson(Map<String, dynamic> json) {
return UserModel(
userId: json['id'] ?? '',
nom: json['nom'] ?? '',
prenoms: json['prenoms'] ?? '',
email: json['email'] ?? '',
nom: json['nom'] ?? 'Inconnu',
prenoms: json['prenoms'] ?? 'Inconnu',
email: json['email'] ?? 'inconnu@example.com',
motDePasse: json['motDePasse'] ?? '',
);
}
/// Convertit le `UserModel` en JSON pour l'envoi vers l'API.
Map<String, dynamic> toJson() {
return {
'id': userId, // Utilisez `id` pour correspondre à l'entité User
'id': userId,
'nom': nom,
'prenoms': prenoms,
'email': email,
'motDePasse': motDePasse,
'motDePasse': motDePasse, // Mot de passe en clair (comme demandé temporairement)
};
}
}

View File

@@ -1,21 +1,49 @@
import 'package:afterwork/domain/entities/user.dart';
import 'package:afterwork/domain/repositories/user_repository.dart';
import 'dart:convert';
import 'package:afterwork/data/datasources/user_remote_data_source.dart';
import 'package:afterwork/data/models/user_model.dart';
import 'package:afterwork/domain/entities/user.dart';
import 'package:afterwork/domain/repositories/user_repository.dart';
import 'package:http/http.dart' as http;
import '../../core/constants/urls.dart';
/// Implémentation du repository des utilisateurs.
/// Cette classe fait le lien entre les appels de l'application et les services distants pour les opérations sur les utilisateurs.
class UserRepositoryImpl implements UserRepository {
final UserRemoteDataSource remoteDataSource;
/// Constructeur avec injection de la source de données distante.
UserRepositoryImpl({required this.remoteDataSource});
/// Récupère un utilisateur par son ID depuis la source de données distante.
@override
Future<User> getUser(String id) async {
UserModel userModel = await remoteDataSource.getUser(id);
return userModel; // Retourne un UserModel qui est un sous-type de User
return userModel; // Retourne un UserModel qui est un sous-type de User.
}
Future<User> authenticateUser(String email, String password, String userId) async {
UserModel userModel = await remoteDataSource.authenticateUser(email, password, userId);
return userModel; // Retourne un UserModel qui est un sous-type de User
/// Authentifie un utilisateur par email et mot de passe (en clair, temporairement).
Future<UserModel> authenticateUser(String email, String password) async {
print("Tentative d'authentification pour l'email : $email");
try {
// Requête POST avec les identifiants utilisateur pour l'authentification
final response = await http.post(
Uri.parse('${Urls.baseUrl}/users/authenticate'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({'email': email, 'motDePasse': password}),
);
print("Réponse du serveur pour l'authentification : ${response.statusCode} - ${response.body}");
if (response.statusCode == 200) {
return UserModel.fromJson(jsonDecode(response.body));
} else {
throw Exception("Erreur lors de l'authentification : ${response.statusCode}");
}
} catch (e) {
print("Erreur d'authentification : $e");
throw Exception("Erreur lors de l'authentification : $e");
}
}
}

View File

@@ -1,8 +0,0 @@
import 'dart:convert';
import 'package:crypto/crypto.dart';
String hashPassword(String password) {
var bytes = utf8.encode(password); // Convertir en bytes
var digest = sha256.convert(bytes); // Hachage SHA-256
return digest.toString(); // Retourner le hash sous forme de chaîne
}

View File

@@ -0,0 +1,47 @@
import 'package:flutter_bcrypt/flutter_bcrypt.dart';
import 'package:http/http.dart' as http;
import 'package:afterwork/core/constants/urls.dart';
class HashPasswordService {
/// Hache le mot de passe en utilisant Bcrypt.
/// Renvoie une chaîne hachée sécurisée.
Future<String> hashPassword(String email, String password) async {
try {
print("Tentative de récupération du sel depuis le serveur pour l'email : $email");
// Récupérer le sel depuis le serveur avec l'email
final response = await http.get(Uri.parse('${Urls.baseUrl}/users/salt?email=$email'));
String salt;
if (response.statusCode == 200 && response.body.isNotEmpty) {
salt = response.body;
print("Sel récupéré depuis le serveur : $salt");
} else {
// Si le sel n'est pas trouvé, on en génère un
salt = await FlutterBcrypt.saltWithRounds(rounds: 12);
print("Sel généré : $salt");
}
// Hachage du mot de passe avec le sel
String hashedPassword = await FlutterBcrypt.hashPw(password: password, salt: salt);
print("Mot de passe haché avec succès : $hashedPassword");
return hashedPassword;
} catch (e) {
print("Erreur lors du hachage du mot de passe : $e");
throw Exception("Erreur lors du hachage du mot de passe.");
}
}
Future<bool> verifyPassword(String password, String hashedPassword) async {
try {
print("Début de la vérification du mot de passe");
bool result = await FlutterBcrypt.verify(password: password, hash: hashedPassword);
print("Résultat de la vérification : $result");
return result;
} catch (e) {
print("Erreur lors de la vérification du mot de passe : $e");
throw Exception("Erreur lors de la vérification du mot de passe.");
}
}
}

View File

@@ -1,50 +1,82 @@
import 'package:shared_preferences/shared_preferences.dart';
/// Classe pour gérer les préférences utilisateur à l'aide de SharedPreferences.
/// Permet de stocker et récupérer des informations de manière non sécurisée,
/// contrairement au stockage sécurisé qui est utilisé pour des données sensibles.
class PreferencesHelper {
// Initialisation de SharedPreferences en tant que Future
final Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
/// Sauvegarde une chaîne de caractères (String) dans les préférences.
Future<void> setString(String key, String value) async {
print("Sauvegarde dans les préférences : clé = $key, valeur = $value");
final prefs = await _prefs;
await prefs.setString(key, value);
print("Sauvegarde réussie pour la clé : $key");
}
/// Récupère une chaîne de caractères depuis les préférences.
Future<String?> getString(String key) async {
print("Récupération depuis les préférences pour la clé : $key");
final prefs = await _prefs;
return prefs.getString(key);
final value = prefs.getString(key);
print("Valeur récupérée pour la clé $key : $value");
return value;
}
/// Supprime une entrée dans les préférences.
Future<void> remove(String key) async {
print("Suppression dans les préférences pour la clé : $key");
final prefs = await _prefs;
await prefs.remove(key);
print("Suppression réussie pour la clé : $key");
}
/// Sauvegarde l'identifiant utilisateur dans les préférences.
Future<void> saveUserId(String userId) async {
print("Sauvegarde de l'userId dans les préférences : $userId");
await setString('user_id', userId);
print("Sauvegarde réussie de l'userId.");
}
/// Récupère l'identifiant utilisateur depuis les préférences.
Future<String?> getUserId() async {
print("Récupération de l'userId depuis les préférences.");
return await getString('user_id');
}
/// Sauvegarde le nom d'utilisateur dans les préférences.
Future<void> saveUserName(String userName) async {
print("Sauvegarde du userName dans les préférences : $userName");
await setString('user_name', userName);
print("Sauvegarde réussie du userName.");
}
/// Récupère le nom d'utilisateur depuis les préférences.
Future<String?> getUserName() async {
print("Récupération du userName depuis les préférences.");
return await getString('user_name');
}
/// Sauvegarde le prénom de l'utilisateur dans les préférences.
Future<void> saveUserLastName(String userLastName) async {
print("Sauvegarde du userLastName dans les préférences : $userLastName");
await setString('user_last_name', userLastName);
print("Sauvegarde réussie du userLastName.");
}
/// Récupère le prénom de l'utilisateur depuis les préférences.
Future<String?> getUserLastName() async {
print("Récupération du userLastName depuis les préférences.");
return await getString('user_last_name');
}
/// Supprime toutes les informations utilisateur dans les préférences.
Future<void> clearUserInfo() async {
print("Suppression des informations utilisateur (userId, userName, userLastName) des préférences.");
await remove('user_id');
await remove('user_name');
await remove('user_last_name');
print("Suppression réussie des informations utilisateur.");
}
}

View File

@@ -1,47 +1,78 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
/// Classe pour gérer le stockage sécurisé dans l'application.
/// Utilise FlutterSecureStorage pour stocker, lire et supprimer des données sensibles.
class SecureStorage {
// Instance de FlutterSecureStorage pour gérer le stockage sécurisé
final FlutterSecureStorage _storage = const FlutterSecureStorage();
/// Écrit une valeur dans le stockage sécurisé avec la clé spécifiée.
Future<void> write(String key, String value) async {
print("Écriture dans le stockage sécurisé : clé = $key, valeur = $value");
await _storage.write(key: key, value: value);
print("Écriture réussie pour la clé : $key");
}
/// Lit une valeur depuis le stockage sécurisé en fonction de la clé spécifiée.
Future<String?> read(String key) async {
return await _storage.read(key: key);
print("Lecture dans le stockage sécurisé pour la clé : $key");
final value = await _storage.read(key: key);
print("Valeur lue pour la clé $key : $value");
return value;
}
/// Supprime une entrée dans le stockage sécurisé pour la clé spécifiée.
Future<void> delete(String key) async {
print("Suppression dans le stockage sécurisé pour la clé : $key");
await _storage.delete(key: key);
print("Suppression réussie pour la clé : $key");
}
/// Sauvegarde l'identifiant utilisateur dans le stockage sécurisé.
Future<void> saveUserId(String userId) async {
print("Sauvegarde de l'userId dans le stockage sécurisé : $userId");
await write('user_id', userId);
print("Sauvegarde réussie de l'userId.");
}
/// Récupère l'identifiant utilisateur depuis le stockage sécurisé.
Future<String?> getUserId() async {
print("Récupération de l'userId depuis le stockage sécurisé.");
return await read('user_id');
}
/// Sauvegarde le nom d'utilisateur dans le stockage sécurisé.
Future<void> saveUserName(String userName) async {
print("Sauvegarde du userName dans le stockage sécurisé : $userName");
await write('user_name', userName);
print("Sauvegarde réussie du userName.");
}
/// Récupère le nom d'utilisateur depuis le stockage sécurisé.
Future<String?> getUserName() async {
print("Récupération du userName depuis le stockage sécurisé.");
return await read('user_name');
}
/// Sauvegarde le prénom de l'utilisateur dans le stockage sécurisé.
Future<void> saveUserLastName(String userLastName) async {
print("Sauvegarde du userLastName dans le stockage sécurisé : $userLastName");
await write('user_last_name', userLastName);
print("Sauvegarde réussie du userLastName.");
}
/// Récupère le prénom de l'utilisateur depuis le stockage sécurisé.
Future<String?> getUserLastName() async {
print("Récupération du userLastName depuis le stockage sécurisé.");
return await read('user_last_name');
}
/// Supprime toutes les informations utilisateur du stockage sécurisé.
Future<void> deleteUserInfo() async {
print("Suppression des informations utilisateur (userId, userName, userLastName).");
await delete('user_id');
await delete('user_name');
await delete('user_last_name');
print("Suppression réussie des informations utilisateur.");
}
}