@@ -3,6 +3,7 @@ import 'package:ht_api/src/services/verification_code_storage_service.dart';
33import 'package:ht_data_repository/ht_data_repository.dart' ;
44import 'package:ht_email_repository/ht_email_repository.dart' ;
55import 'package:ht_shared/ht_shared.dart' ;
6+ import 'package:logging/logging.dart' ;
67import 'package:uuid/uuid.dart' ;
78
89/// {@template auth_service}
@@ -22,13 +23,15 @@ class AuthService {
2223 required HtDataRepository <UserContentPreferences >
2324 userContentPreferencesRepository,
2425 required Uuid uuidGenerator,
26+ required Logger log,
2527 }) : _userRepository = userRepository,
2628 _authTokenService = authTokenService,
2729 _verificationCodeStorageService = verificationCodeStorageService,
2830 _emailRepository = emailRepository,
2931 _userAppSettingsRepository = userAppSettingsRepository,
3032 _userContentPreferencesRepository = userContentPreferencesRepository,
31- _uuid = uuidGenerator;
33+ _uuid = uuidGenerator,
34+ _log = log;
3235
3336 final HtDataRepository <User > _userRepository;
3437 final AuthTokenService _authTokenService;
@@ -37,6 +40,7 @@ class AuthService {
3740 final HtDataRepository <UserAppSettings > _userAppSettingsRepository;
3841 final HtDataRepository <UserContentPreferences >
3942 _userContentPreferencesRepository;
43+ final Logger _log;
4044 final Uuid _uuid;
4145
4246 /// Initiates the email sign-in process.
@@ -67,7 +71,7 @@ class AuthService {
6771 if (isDashboardLogin) {
6872 final user = await _findUserByEmail (email);
6973 if (user == null ) {
70- print ('Dashboard login failed: User $email not found.' );
74+ _log. warning ('Dashboard login failed: User $email not found.' );
7175 throw const UnauthorizedException (
7276 'This email address is not registered for dashboard access.' ,
7377 );
@@ -77,14 +81,14 @@ class AuthService {
7781 user.dashboardRole == DashboardUserRole .publisher;
7882
7983 if (! hasRequiredRole) {
80- print (
84+ _log. warning (
8185 'Dashboard login failed: User ${user .id } lacks required roles.' ,
8286 );
8387 throw const ForbiddenException (
8488 'Your account does not have the required permissions to sign in.' ,
8589 );
8690 }
87- print ('Dashboard user ${user .id } verified successfully.' );
91+ _log. info ('Dashboard user ${user .id } verified successfully.' );
8892 }
8993
9094 // Generate and store the code for standard sign-in
@@ -93,13 +97,13 @@ class AuthService {
9397
9498 // Send the code via email
9599 await _emailRepository.sendOtpEmail (recipientEmail: email, otpCode: code);
96- print ('Initiated email sign-in for $email , code sent.' );
100+ _log. info ('Initiated email sign-in for $email , code sent.' );
97101 } on HtHttpException {
98102 // Propagate known exceptions from dependencies
99103 rethrow ;
100104 } catch (e) {
101105 // Catch unexpected errors during orchestration
102- print ('Error during initiateEmailSignIn for $email : $e ' );
106+ _log. severe ('Error during initiateEmailSignIn for $email : $e ' );
103107 throw const OperationFailedException (
104108 'Failed to initiate email sign-in process.' ,
105109 );
@@ -140,7 +144,7 @@ class AuthService {
140144 await _verificationCodeStorageService.clearSignInCode (email);
141145 } catch (e) {
142146 // Log or handle if clearing fails, but don't let it block sign-in
143- print (
147+ _log. warning (
144148 'Warning: Failed to clear sign-in code for $email after validation: $e ' ,
145149 );
146150 }
@@ -157,14 +161,14 @@ class AuthService {
157161 if (isDashboardLogin) {
158162 // This should not happen if the request-code flow is correct.
159163 // It's a safeguard.
160- print (
164+ _log. severe (
161165 'Error: Dashboard login verification failed for non-existent user $email .' ,
162166 );
163167 throw const UnauthorizedException ('User account does not exist.' );
164168 }
165169
166170 // Create a new user for the standard app flow.
167- print ('User not found for $email , creating new user.' );
171+ _log. info ('User not found for $email , creating new user.' );
168172
169173 // All new users created via the public API get the standard role.
170174 // Admin users must be provisioned out-of-band (e.g., via fixtures).
@@ -184,7 +188,7 @@ class AuthService {
184188 ),
185189 );
186190 user = await _userRepository.create (item: user);
187- print (
191+ _log. info (
188192 'Created new user: ${user .id } with appRole: ${user .appRole }' ,
189193 );
190194
@@ -194,33 +198,33 @@ class AuthService {
194198 item: defaultAppSettings,
195199 userId: user.id,
196200 );
197- print ('Created default UserAppSettings for user: ${user .id }' );
201+ _log. info ('Created default UserAppSettings for user: ${user .id }' );
198202
199203 // Create default UserContentPreferences for the new user
200204 final defaultUserPreferences = UserContentPreferences (id: user.id);
201205 await _userContentPreferencesRepository.create (
202206 item: defaultUserPreferences,
203207 userId: user.id,
204208 );
205- print ('Created default UserContentPreferences for user: ${user .id }' );
209+ _log. info ('Created default UserContentPreferences for user: ${user .id }' );
206210 }
207211 } on HtHttpException catch (e) {
208- print ('Error finding/creating user for $email : $e ' );
212+ _log. severe ('Error finding/creating user for $email : $e ' );
209213 throw const OperationFailedException (
210214 'Failed to find or create user account.' ,
211215 );
212216 } catch (e) {
213- print ('Unexpected error during user lookup/creation for $email : $e ' );
217+ _log. severe ('Unexpected error during user lookup/creation for $email : $e ' );
214218 throw const OperationFailedException ('Failed to process user account.' );
215219 }
216220
217221 // 3. Generate authentication token
218222 try {
219223 final token = await _authTokenService.generateToken (user);
220- print ('Generated token for user ${user .id }' );
224+ _log. info ('Generated token for user ${user .id }' );
221225 return (user: user, token: token);
222226 } catch (e) {
223- print ('Error generating token for user ${user .id }: $e ' );
227+ _log. severe ('Error generating token for user ${user .id }: $e ' );
224228 throw const OperationFailedException (
225229 'Failed to generate authentication token.' ,
226230 );
@@ -254,12 +258,12 @@ class AuthService {
254258 ),
255259 );
256260 user = await _userRepository.create (item: user);
257- print ('Created anonymous user: ${user .id }' );
261+ _log. info ('Created anonymous user: ${user .id }' );
258262 } on HtHttpException catch (e) {
259- print ('Error creating anonymous user: $e ' );
263+ _log. severe ('Error creating anonymous user: $e ' );
260264 throw const OperationFailedException ('Failed to create anonymous user.' );
261265 } catch (e) {
262- print ('Unexpected error during anonymous user creation: $e ' );
266+ _log. severe ('Unexpected error during anonymous user creation: $e ' );
263267 throw const OperationFailedException (
264268 'Failed to process anonymous sign-in.' ,
265269 );
@@ -271,25 +275,25 @@ class AuthService {
271275 item: defaultAppSettings,
272276 userId: user.id, // Pass user ID for scoping
273277 );
274- print ('Created default UserAppSettings for anonymous user: ${user .id }' );
278+ _log. info ('Created default UserAppSettings for anonymous user: ${user .id }' );
275279
276280 // Create default UserContentPreferences for the new anonymous user
277281 final defaultUserPreferences = UserContentPreferences (id: user.id);
278282 await _userContentPreferencesRepository.create (
279283 item: defaultUserPreferences,
280284 userId: user.id, // Pass user ID for scoping
281285 );
282- print (
286+ _log. info (
283287 'Created default UserContentPreferences for anonymous user: ${user .id }' ,
284288 );
285289
286290 // 2. Generate token
287291 try {
288292 final token = await _authTokenService.generateToken (user);
289- print ('Generated token for anonymous user ${user .id }' );
293+ _log. info ('Generated token for anonymous user ${user .id }' );
290294 return (user: user, token: token);
291295 } catch (e) {
292- print ('Error generating token for anonymous user ${user .id }: $e ' );
296+ _log. severe ('Error generating token for anonymous user ${user .id }: $e ' );
293297 throw const OperationFailedException (
294298 'Failed to generate authentication token.' ,
295299 );
@@ -319,32 +323,32 @@ class AuthService {
319323 required String userId,
320324 required String token,
321325 }) async {
322- print (
323- '[AuthService] Received request for server-side sign-out actions '
326+ _log. info (
327+ 'Received request for server-side sign-out actions '
324328 'for user $userId .' ,
325329 );
326330
327331 try {
328332 // Invalidate the token using the AuthTokenService
329333 await _authTokenService.invalidateToken (token);
330- print (
331- '[AuthService] Token invalidation logic executed for user $userId .' ,
334+ _log. info (
335+ 'Token invalidation logic executed for user $userId .' ,
332336 );
333337 } on HtHttpException catch (_) {
334338 // Propagate known exceptions from the token service
335339 rethrow ;
336340 } catch (e) {
337341 // Catch unexpected errors during token invalidation
338- print (
339- '[AuthService] Error during token invalidation for user $userId : $e ' ,
342+ _log. severe (
343+ 'Error during token invalidation for user $userId : $e ' ,
340344 );
341345 throw const OperationFailedException (
342346 'Failed server-side sign-out: Token invalidation failed.' ,
343347 );
344348 }
345349
346- print (
347- '[AuthService] Server-side sign-out actions complete for user $userId .' ,
350+ _log. info (
351+ 'Server-side sign-out actions complete for user $userId .' ,
348352 );
349353 }
350354
@@ -396,13 +400,13 @@ class AuthService {
396400 recipientEmail: emailToLink,
397401 otpCode: code,
398402 );
399- print (
403+ _log. info (
400404 'Initiated email link for user ${anonymousUser .id } to email $emailToLink , code sent: $code .' ,
401405 );
402406 } on HtHttpException {
403407 rethrow ;
404408 } catch (e) {
405- print (
409+ _log. severe (
406410 'Error during initiateLinkEmailProcess for user ${anonymousUser .id }, email $emailToLink : $e ' ,
407411 );
408412 throw OperationFailedException (
@@ -453,24 +457,24 @@ class AuthService {
453457 id: updatedUser.id,
454458 item: updatedUser,
455459 );
456- print (
460+ _log. info (
457461 'User ${permanentUser .id } successfully linked with email $linkedEmail .' ,
458462 );
459463
460464 // 3. Generate a new authentication token for the now-permanent user.
461465 final newToken = await _authTokenService.generateToken (permanentUser);
462- print ('Generated new token for linked user ${permanentUser .id }' );
466+ _log. info ('Generated new token for linked user ${permanentUser .id }' );
463467
464468 // 4. Invalidate the old anonymous token.
465469 try {
466470 await _authTokenService.invalidateToken (oldAnonymousToken);
467- print (
471+ _log. info (
468472 'Successfully invalidated old anonymous token for user ${permanentUser .id }.' ,
469473 );
470474 } catch (e) {
471475 // Log error but don't fail the whole linking process if invalidation fails.
472476 // The new token is more important.
473- print (
477+ _log. warning (
474478 'Warning: Failed to invalidate old anonymous token for user ${permanentUser .id }: $e ' ,
475479 );
476480 }
@@ -479,7 +483,7 @@ class AuthService {
479483 try {
480484 await _verificationCodeStorageService.clearLinkCode (anonymousUser.id);
481485 } catch (e) {
482- print (
486+ _log. warning (
483487 'Warning: Failed to clear link code for user ${anonymousUser .id } after linking: $e ' ,
484488 );
485489 }
@@ -488,7 +492,7 @@ class AuthService {
488492 } on HtHttpException {
489493 rethrow ;
490494 } catch (e) {
491- print (
495+ _log. severe (
492496 'Error during completeLinkEmailProcess for user ${anonymousUser .id }: $e ' ,
493497 );
494498 throw OperationFailedException (
@@ -508,21 +512,21 @@ class AuthService {
508512 try {
509513 // Fetch the user first to get their email if needed for cleanup
510514 final userToDelete = await _userRepository.read (id: userId);
511- print ( '[AuthService] Found user ${userToDelete .id } for deletion.' );
515+ _log. info ( ' Found user ${userToDelete .id } for deletion.' );
512516
513517 // 1. Delete the user record from the repository.
514518 // This implicitly invalidates tokens that rely on user lookup.
515519 await _userRepository.delete (id: userId);
516- print ( '[AuthService] User ${userToDelete .id } deleted from repository.' );
520+ _log. info ( ' User ${userToDelete .id } deleted from repository.' );
517521
518522 // 2. Clear any pending verification codes for this user ID (linking).
519523 try {
520524 await _verificationCodeStorageService.clearLinkCode (userId);
521- print ( '[AuthService] Cleared link code for user ${userToDelete .id }.' );
525+ _log. info ( ' Cleared link code for user ${userToDelete .id }.' );
522526 } catch (e) {
523527 // Log but don't fail deletion if clearing codes fails
524- print (
525- '[AuthService] Warning: Failed to clear link code for user ${userToDelete .id }: $e ' ,
528+ _log. warning (
529+ 'Warning: Failed to clear link code for user ${userToDelete .id }: $e ' ,
526530 );
527531 }
528532
@@ -532,13 +536,13 @@ class AuthService {
532536 await _verificationCodeStorageService.clearSignInCode (
533537 userToDelete.email! ,
534538 );
535- print (
536- '[AuthService] Cleared sign-in code for email ${userToDelete .email }.' ,
539+ _log. info (
540+ 'Cleared sign-in code for email ${userToDelete .email }.' ,
537541 );
538542 } catch (e) {
539543 // Log but don't fail deletion if clearing codes fails
540- print (
541- '[AuthService] Warning: Failed to clear sign-in code for email ${userToDelete .email }: $e ' ,
544+ _log. warning (
545+ 'Warning: Failed to clear sign-in code for email ${userToDelete .email }: $e ' ,
542546 );
543547 }
544548 }
@@ -547,8 +551,8 @@ class AuthService {
547551 // user-related data (e.g., settings, content) from other repositories
548552 // once those features are implemented.
549553
550- print (
551- '[AuthService] Account deletion process completed for user $userId .' ,
554+ _log. info (
555+ 'Account deletion process completed for user $userId .' ,
552556 );
553557 } on NotFoundException {
554558 // Propagate NotFoundException if user doesn't exist
@@ -558,7 +562,7 @@ class AuthService {
558562 rethrow ;
559563 } catch (e) {
560564 // Catch unexpected errors during orchestration
561- print ('Error during deleteAccount for user $userId : $e ' );
565+ _log. severe ('Error during deleteAccount for user $userId : $e ' );
562566 throw OperationFailedException ('Failed to delete user account: $e ' );
563567 }
564568 }
0 commit comments