Skip to content

refactor(auth): streamline user retrieval and add admin user reposito… #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 21 additions & 19 deletions lib/src/services/auth_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,7 @@ class AuthService {
try {
// For dashboard login, first validate the user exists and has permissions.
if (isDashboardLogin) {
print('Dashboard login initiated for $email. Verifying user...');
User? user;
try {
final query = {'email': email};
final response = await _userRepository.readAllByQuery(query);
if (response.items.isNotEmpty) {
user = response.items.first;
}
} on HtHttpException catch (e) {
print('Repository error while verifying dashboard user $email: $e');
rethrow;
}

final user = await _findUserByEmail(email);
if (user == null) {
print('Dashboard login failed: User $email not found.');
throw const UnauthorizedException(
Expand Down Expand Up @@ -162,12 +150,9 @@ class AuthService {
User user;
try {
// Attempt to find user by email
final query = {'email': email};
final paginatedResponse = await _userRepository.readAllByQuery(query);

if (paginatedResponse.items.isNotEmpty) {
user = paginatedResponse.items.first;
print('Found existing user: ${user.id} for email $email');
final existingUser = await _findUserByEmail(email);
if (existingUser != null) {
user = existingUser;
} else {
// User not found.
if (isDashboardLogin) {
Expand Down Expand Up @@ -556,4 +541,21 @@ class AuthService {
throw OperationFailedException('Failed to delete user account: $e');
}
}

/// Finds a user by their email address.
///
/// Returns the [User] if found, otherwise `null`.
/// Re-throws any [HtHttpException] from the repository.
Future<User?> _findUserByEmail(String email) async {
try {
final query = {'email': email};
final response = await _userRepository.readAllByQuery(query);
if (response.items.isNotEmpty) {
return response.items.first;
}
return null;
} on HtHttpException {
rethrow;
}
Comment on lines +549 to +559

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The try...on HtHttpException { rethrow; } block is unnecessary as exceptions from _userRepository.readAllByQuery will automatically propagate up the call stack where they are already handled.

Future<User?> _findUserByEmail(String email) async {
  try {
    final query = {'email': email};
    final response = await _userRepository.readAllByQuery(query);
    if (response.items.isNotEmpty) {
      return response.items.first;
    }
    return null;
  } on HtHttpException {
    rethrow;
  }
}

}
}
25 changes: 16 additions & 9 deletions routes/_middleware.dart
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,19 @@ HtDataRepository<Country> _createCountryRepository() {
return HtDataRepository<Country>(dataClient: client);
}

HtDataRepository<User> _createAdminUserRepository() {
print('Initializing User Repository with Admin...');
// This assumes `adminUserFixtureData` is available from `ht_shared`.
final initialData = usersFixturesData;
Comment on lines +116 to +117

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The comment on line 116 refers to adminUserFixtureData, but the code on the next line uses usersFixturesData. Update the comment to match the variable being used.

// This assumes `usersFixturesData` is available from `ht_shared`.

final client = HtDataInMemory<User>(
toJson: (u) => u.toJson(),
getId: (u) => u.id,
initialData: initialData,
);
print('User Repository Initialized with admin user.');
return HtDataRepository<User>(dataClient: client);
}

// New repositories for user settings and preferences
HtDataRepository<UserAppSettings> _createUserAppSettingsRepository() {
print('Initializing UserAppSettings Repository...');
Expand Down Expand Up @@ -187,15 +200,9 @@ Handler middleware(Handler handler) {
const uuid = Uuid();

// --- Auth Dependencies ---
// User Repo (using InMemory for now)
final userRepository = HtDataRepository<User>(
dataClient: HtDataInMemory<User>(
toJson: (u) => u.toJson(),
getId: (u) => u.id,
// No initial user data fixture needed for auth flow typically
),
);
print('[MiddlewareSetup] HtDataRepository<User> instantiated.');
// User Repo with pre-loaded admin user
final userRepository = _createAdminUserRepository();
print('[MiddlewareSetup] HtDataRepository<User> with admin user instantiated.');
// Email Repo (using InMemory)
const emailRepository = HtEmailRepository(
emailClient: HtEmailInMemoryClient(),
Expand Down
Loading