|
| 1 | +import 'package:ht_api/src/services/auth_token_service.dart'; |
| 2 | +import 'package:ht_data_repository/ht_data_repository.dart'; |
| 3 | +import 'package:ht_shared/ht_shared.dart'; |
| 4 | + |
| 5 | +/// {@template simple_auth_token_service} |
| 6 | +/// A minimal, dependency-free implementation of [AuthTokenService] for debugging. |
| 7 | +/// |
| 8 | +/// Generates simple, predictable tokens and validates them by checking a prefix |
| 9 | +/// and fetching the user from the repository. Does not involve JWT logic. |
| 10 | +/// {@endtemplate} |
| 11 | +class SimpleAuthTokenService implements AuthTokenService { |
| 12 | + /// {@macro simple_auth_token_service} |
| 13 | + const SimpleAuthTokenService({ |
| 14 | + required HtDataRepository<User> userRepository, |
| 15 | + }) : _userRepository = userRepository; |
| 16 | + |
| 17 | + final HtDataRepository<User> _userRepository; |
| 18 | + static const String _tokenPrefix = 'valid-token-for-user-id:'; |
| 19 | + |
| 20 | + @override |
| 21 | + Future<String> generateToken(User user) async { |
| 22 | + print('[SimpleAuthTokenService] Generating token for user ${user.id}'); |
| 23 | + final token = '$_tokenPrefix${user.id}'; |
| 24 | + print('[SimpleAuthTokenService] Generated token: $token'); |
| 25 | + // Simulate async operation if needed, though not strictly necessary here |
| 26 | + await Future<void>.delayed(Duration.zero); |
| 27 | + return token; |
| 28 | + } |
| 29 | + |
| 30 | + @override |
| 31 | + Future<User?> validateToken(String token) async { |
| 32 | + print('[SimpleAuthTokenService] Attempting to validate token: $token'); |
| 33 | + if (!token.startsWith(_tokenPrefix)) { |
| 34 | + print('[SimpleAuthTokenService] Validation failed: Invalid prefix.'); |
| 35 | + // Mimic JWT behavior by throwing Unauthorized for invalid format |
| 36 | + throw const UnauthorizedException('Invalid token format.'); |
| 37 | + } |
| 38 | + |
| 39 | + final userId = token.substring(_tokenPrefix.length); |
| 40 | + print('[SimpleAuthTokenService] Extracted user ID: $userId'); |
| 41 | + |
| 42 | + if (userId.isEmpty) { |
| 43 | + print('[SimpleAuthTokenService] Validation failed: Empty user ID.'); |
| 44 | + throw const UnauthorizedException('Invalid token: Empty user ID.'); |
| 45 | + } |
| 46 | + |
| 47 | + try { |
| 48 | + print('[SimpleAuthTokenService] Attempting to read user from repository...'); |
| 49 | + final user = await _userRepository.read(userId); |
| 50 | + print('[SimpleAuthTokenService] User read successful: ${user.id}'); |
| 51 | + return user; |
| 52 | + } on NotFoundException { |
| 53 | + print('[SimpleAuthTokenService] Validation failed: User ID $userId not found.'); |
| 54 | + // Return null if user not found, mimicking successful validation |
| 55 | + // of a token for a non-existent user. The middleware handles this. |
| 56 | + return null; |
| 57 | + } on HtHttpException catch (e, s) { |
| 58 | + // Handle other potential repository errors |
| 59 | + print( |
| 60 | + '[SimpleAuthTokenService] Validation failed: Repository error $e\n$s', |
| 61 | + ); |
| 62 | + // Re-throw other client/repo exceptions |
| 63 | + rethrow; |
| 64 | + } catch (e, s) { |
| 65 | + // Catch unexpected errors during validation |
| 66 | + print('[SimpleAuthTokenService] Unexpected validation error: $e\n$s'); |
| 67 | + throw OperationFailedException( |
| 68 | + 'Simple token validation failed unexpectedly: $e', |
| 69 | + ); |
| 70 | + } |
| 71 | + } |
| 72 | +} |
0 commit comments