fill
This commit is contained in:
134
lib/features/auth/data/repositories/auth_repository_impl.dart
Normal file
134
lib/features/auth/data/repositories/auth_repository_impl.dart
Normal file
@@ -0,0 +1,134 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
|
||||
import '../../../../core/errors/exceptions.dart';
|
||||
import '../../../../core/errors/failures.dart';
|
||||
import '../../../../core/storage/secure_storage.dart';
|
||||
import '../../domain/entities/user_entity.dart';
|
||||
import '../../domain/repositories/auth_repository.dart';
|
||||
import '../datasources/auth_remote_datasource.dart';
|
||||
import '../models/login_request_model.dart';
|
||||
|
||||
/// Implementation of AuthRepository
|
||||
///
|
||||
/// Coordinates between remote data source and local storage
|
||||
/// Handles error conversion from exceptions to failures
|
||||
class AuthRepositoryImpl implements AuthRepository {
|
||||
final AuthRemoteDataSource remoteDataSource;
|
||||
final SecureStorage secureStorage;
|
||||
|
||||
AuthRepositoryImpl({
|
||||
required this.remoteDataSource,
|
||||
required this.secureStorage,
|
||||
});
|
||||
|
||||
@override
|
||||
Future<Either<Failure, UserEntity>> login(LoginRequestModel request) async {
|
||||
try {
|
||||
// Call remote data source to login
|
||||
final userModel = await remoteDataSource.login(request);
|
||||
|
||||
// Save tokens to secure storage
|
||||
await secureStorage.saveAccessToken(userModel.accessToken);
|
||||
await secureStorage.saveUserId(userModel.userId);
|
||||
await secureStorage.saveUsername(userModel.username);
|
||||
|
||||
if (userModel.refreshToken != null) {
|
||||
await secureStorage.saveRefreshToken(userModel.refreshToken!);
|
||||
}
|
||||
|
||||
// Return user entity
|
||||
return Right(userModel.toEntity());
|
||||
} on ServerException catch (e) {
|
||||
return Left(AuthenticationFailure(e.message));
|
||||
} on NetworkException catch (e) {
|
||||
return Left(NetworkFailure(e.message));
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure('Login failed: ${e.toString()}'));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, void>> logout() async {
|
||||
try {
|
||||
// Call remote data source to logout (optional - can fail silently)
|
||||
try {
|
||||
await remoteDataSource.logout();
|
||||
} catch (e) {
|
||||
// Ignore remote logout errors, still clear local data
|
||||
}
|
||||
|
||||
// Clear all local authentication data
|
||||
await secureStorage.clearAll();
|
||||
|
||||
return const Right(null);
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure('Logout failed: ${e.toString()}'));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, UserEntity>> refreshToken(String refreshToken) async {
|
||||
try {
|
||||
// Call remote data source to refresh token
|
||||
final userModel = await remoteDataSource.refreshToken(refreshToken);
|
||||
|
||||
// Update tokens in secure storage
|
||||
await secureStorage.saveAccessToken(userModel.accessToken);
|
||||
if (userModel.refreshToken != null) {
|
||||
await secureStorage.saveRefreshToken(userModel.refreshToken!);
|
||||
}
|
||||
|
||||
return Right(userModel.toEntity());
|
||||
} on ServerException catch (e) {
|
||||
return Left(AuthenticationFailure(e.message));
|
||||
} on NetworkException catch (e) {
|
||||
return Left(NetworkFailure(e.message));
|
||||
} catch (e) {
|
||||
return Left(UnknownFailure('Token refresh failed: ${e.toString()}'));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> isAuthenticated() async {
|
||||
try {
|
||||
return await secureStorage.isAuthenticated();
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, UserEntity>> getCurrentUser() async {
|
||||
try {
|
||||
final userId = await secureStorage.getUserId();
|
||||
final username = await secureStorage.getUsername();
|
||||
final accessToken = await secureStorage.getAccessToken();
|
||||
final refreshToken = await secureStorage.getRefreshToken();
|
||||
|
||||
if (userId == null || username == null || accessToken == null) {
|
||||
return const Left(AuthenticationFailure('No user data found'));
|
||||
}
|
||||
|
||||
final user = UserEntity(
|
||||
userId: userId,
|
||||
username: username,
|
||||
accessToken: accessToken,
|
||||
refreshToken: refreshToken,
|
||||
);
|
||||
|
||||
return Right(user);
|
||||
} catch (e) {
|
||||
return Left(CacheFailure('Failed to get user data: ${e.toString()}'));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, void>> clearAuthData() async {
|
||||
try {
|
||||
await secureStorage.clearAll();
|
||||
return const Right(null);
|
||||
} catch (e) {
|
||||
return Left(CacheFailure('Failed to clear auth data: ${e.toString()}'));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user