Skip to content

Commit 0537af6

Browse files
committed
refactor(api): update AuthService to use multi-role system
1 parent 90049a0 commit 0537af6

File tree

1 file changed

+27
-19
lines changed

1 file changed

+27
-19
lines changed

lib/src/services/auth_service.dart

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ class AuthService {
7676
String email,
7777
String code, {
7878
User? currentAuthUser, // Parameter for potential future linking logic
79+
String? clientType, // e.g., 'dashboard', 'mobile_app'
7980
}) async {
8081
// 1. Validate the code for standard sign-in
8182
final isValidCode = await _verificationCodeStorageService
@@ -100,7 +101,7 @@ class AuthService {
100101
User user;
101102
try {
102103
if (currentAuthUser != null &&
103-
currentAuthUser.role == UserRole.guestUser) {
104+
currentAuthUser.roles.contains(UserRoles.guestUser)) {
104105
// This is an anonymous user linking their account.
105106
// Migrate their existing data to the new permanent user.
106107
print(
@@ -139,7 +140,7 @@ class AuthService {
139140
// Update the existing anonymous user to be permanent
140141
user = currentAuthUser.copyWith(
141142
email: email,
142-
role: UserRole.standardUser,
143+
roles: [UserRoles.standardUser],
143144
);
144145
user = await _userRepository.update(id: user.id, item: user);
145146
print(
@@ -197,10 +198,15 @@ class AuthService {
197198
} else {
198199
// User not found, create a new one
199200
print('User not found for $email, creating new user.');
201+
// Assign roles based on client type. New users from the dashboard
202+
// could be granted publisher rights, for example.
203+
final roles = (clientType == 'dashboard')
204+
? [UserRoles.standardUser, UserRoles.publisher]
205+
: [UserRoles.standardUser];
200206
user = User(
201207
id: _uuid.v4(), // Generate new ID
202208
email: email,
203-
role: UserRole.standardUser, // Email verified user is standard user
209+
roles: roles,
204210
);
205211
user = await _userRepository.create(item: user); // Save the new user
206212
print('Created new user: ${user.id}');
@@ -258,7 +264,7 @@ class AuthService {
258264
try {
259265
user = User(
260266
id: _uuid.v4(), // Generate new ID
261-
role: UserRole.guestUser, // Anonymous users are guest users
267+
roles: [UserRoles.guestUser], // Anonymous users are guest users
262268
email: null, // Anonymous users don't have an email initially
263269
);
264270
user = await _userRepository.create(item: user);
@@ -368,25 +374,27 @@ class AuthService {
368374
required User anonymousUser,
369375
required String emailToLink,
370376
}) async {
371-
if (anonymousUser.role != UserRole.guestUser) {
377+
if (!anonymousUser.roles.contains(UserRoles.guestUser)) {
372378
throw const BadRequestException(
373379
'Account is already permanent. Cannot link email.',
374380
);
375381
}
376382

377383
try {
378-
// 1. Check if emailToLink is already used by another *permanent* user.
379-
final query = {'email': emailToLink, 'isAnonymous': false};
380-
final existingUsers = await _userRepository.readAllByQuery(query);
381-
if (existingUsers.items.isNotEmpty) {
382-
// Ensure it's not the same user if somehow an anonymous user had an email
383-
// (though current logic prevents this for new anonymous users).
384-
// This check is more for emails used by *other* permanent accounts.
385-
if (existingUsers.items.any((u) => u.id != anonymousUser.id)) {
386-
throw ConflictException(
387-
'Email address "$emailToLink" is already in use by another account.',
388-
);
389-
}
384+
// 1. Check if emailToLink is already used by another permanent user.
385+
final query = {'email': emailToLink};
386+
final existingUsersResponse = await _userRepository.readAllByQuery(query);
387+
388+
// Filter for permanent users (not guests) that are not the current user.
389+
final conflictingPermanentUsers = existingUsersResponse.items.where(
390+
(u) =>
391+
!u.roles.contains(UserRoles.guestUser) && u.id != anonymousUser.id,
392+
);
393+
394+
if (conflictingPermanentUsers.isNotEmpty) {
395+
throw ConflictException(
396+
'Email address "$emailToLink" is already in use by another account.',
397+
);
390398
}
391399

392400
// 2. Generate and store the link code.
@@ -430,7 +438,7 @@ class AuthService {
430438
required String codeFromUser,
431439
required String oldAnonymousToken, // Needed to invalidate it
432440
}) async {
433-
if (anonymousUser.role != UserRole.guestUser) {
441+
if (!anonymousUser.roles.contains(UserRoles.guestUser)) {
434442
// Should ideally not happen if flow is correct, but good safeguard.
435443
throw const BadRequestException(
436444
'Account is already permanent. Cannot complete email linking.',
@@ -455,7 +463,7 @@ class AuthService {
455463
final updatedUser = User(
456464
id: anonymousUser.id, // Preserve original ID
457465
email: linkedEmail,
458-
role: UserRole.standardUser, // Now a permanent standard user
466+
roles: [UserRoles.standardUser], // Now a permanent standard user
459467
);
460468
final permanentUser = await _userRepository.update(
461469
id: updatedUser.id,

0 commit comments

Comments
 (0)