127 lines
3.5 KiB
Dart
127 lines
3.5 KiB
Dart
import 'package:dartz/dartz.dart';
|
|
|
|
import '../../../../core/errors/failures.dart';
|
|
import '../../data/models/login_request_model.dart';
|
|
import '../entities/user_entity.dart';
|
|
import '../repositories/auth_repository.dart';
|
|
|
|
/// Use case for user login
|
|
///
|
|
/// Encapsulates the business logic for authentication
|
|
/// Validates input, calls repository, and handles the response
|
|
class LoginUseCase {
|
|
final AuthRepository repository;
|
|
|
|
LoginUseCase(this.repository);
|
|
|
|
/// Execute login operation
|
|
///
|
|
/// [request] - Login credentials (username and password)
|
|
///
|
|
/// Returns [Right(UserEntity)] on successful login
|
|
/// Returns [Left(Failure)] on error:
|
|
/// - [ValidationFailure] if credentials are invalid
|
|
/// - [AuthenticationFailure] if login fails
|
|
/// - [NetworkFailure] if network error occurs
|
|
Future<Either<Failure, UserEntity>> call(LoginRequestModel request) async {
|
|
// Validate input
|
|
final validationError = _validateInput(request);
|
|
if (validationError != null) {
|
|
return Left(validationError);
|
|
}
|
|
|
|
// Call repository to perform login
|
|
return await repository.login(request);
|
|
}
|
|
|
|
/// Validate login request input
|
|
///
|
|
/// Returns [ValidationFailure] if validation fails, null otherwise
|
|
ValidationFailure? _validateInput(LoginRequestModel request) {
|
|
// Validate username
|
|
if (request.username.trim().isEmpty) {
|
|
return const ValidationFailure('Username is required');
|
|
}
|
|
|
|
if (request.username.length < 3) {
|
|
return const ValidationFailure('Username must be at least 3 characters');
|
|
}
|
|
|
|
// Validate password
|
|
if (request.password.isEmpty) {
|
|
return const ValidationFailure('Password is required');
|
|
}
|
|
|
|
if (request.password.length < 6) {
|
|
return const ValidationFailure('Password must be at least 6 characters');
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// Use case for user logout
|
|
class LogoutUseCase {
|
|
final AuthRepository repository;
|
|
|
|
LogoutUseCase(this.repository);
|
|
|
|
/// Execute logout operation
|
|
///
|
|
/// Returns [Right(void)] on successful logout
|
|
/// Returns [Left(Failure)] on error
|
|
Future<Either<Failure, void>> call() async {
|
|
return await repository.logout();
|
|
}
|
|
}
|
|
|
|
/// Use case for checking authentication status
|
|
class CheckAuthStatusUseCase {
|
|
final AuthRepository repository;
|
|
|
|
CheckAuthStatusUseCase(this.repository);
|
|
|
|
/// Check if user is authenticated
|
|
///
|
|
/// Returns true if user has valid access token
|
|
Future<bool> call() async {
|
|
return await repository.isAuthenticated();
|
|
}
|
|
}
|
|
|
|
/// Use case for getting current user
|
|
class GetCurrentUserUseCase {
|
|
final AuthRepository repository;
|
|
|
|
GetCurrentUserUseCase(this.repository);
|
|
|
|
/// Get current authenticated user
|
|
///
|
|
/// Returns [Right(UserEntity)] if user is authenticated
|
|
/// Returns [Left(Failure)] if no user found or error occurs
|
|
Future<Either<Failure, UserEntity>> call() async {
|
|
return await repository.getCurrentUser();
|
|
}
|
|
}
|
|
|
|
/// Use case for refreshing access token
|
|
class RefreshTokenUseCase {
|
|
final AuthRepository repository;
|
|
|
|
RefreshTokenUseCase(this.repository);
|
|
|
|
/// Refresh access token using refresh token
|
|
///
|
|
/// [refreshToken] - The refresh token
|
|
///
|
|
/// Returns [Right(UserEntity)] with new tokens on success
|
|
/// Returns [Left(Failure)] on error
|
|
Future<Either<Failure, UserEntity>> call(String refreshToken) async {
|
|
if (refreshToken.isEmpty) {
|
|
return const Left(ValidationFailure('Refresh token is required'));
|
|
}
|
|
|
|
return await repository.refreshToken(refreshToken);
|
|
}
|
|
}
|