@@ -76,6 +76,7 @@ class AuthService {
76
76
String email,
77
77
String code, {
78
78
User ? currentAuthUser, // Parameter for potential future linking logic
79
+ String ? clientType, // e.g., 'dashboard', 'mobile_app'
79
80
}) async {
80
81
// 1. Validate the code for standard sign-in
81
82
final isValidCode = await _verificationCodeStorageService
@@ -100,7 +101,7 @@ class AuthService {
100
101
User user;
101
102
try {
102
103
if (currentAuthUser != null &&
103
- currentAuthUser.role == UserRole . guestUser) {
104
+ currentAuthUser.roles. contains ( UserRoles . guestUser) ) {
104
105
// This is an anonymous user linking their account.
105
106
// Migrate their existing data to the new permanent user.
106
107
print (
@@ -139,7 +140,7 @@ class AuthService {
139
140
// Update the existing anonymous user to be permanent
140
141
user = currentAuthUser.copyWith (
141
142
email: email,
142
- role : UserRole .standardUser,
143
+ roles : [ UserRoles .standardUser] ,
143
144
);
144
145
user = await _userRepository.update (id: user.id, item: user);
145
146
print (
@@ -197,10 +198,15 @@ class AuthService {
197
198
} else {
198
199
// User not found, create a new one
199
200
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];
200
206
user = User (
201
207
id: _uuid.v4 (), // Generate new ID
202
208
email: email,
203
- role : UserRole .standardUser, // Email verified user is standard user
209
+ roles : roles,
204
210
);
205
211
user = await _userRepository.create (item: user); // Save the new user
206
212
print ('Created new user: ${user .id }' );
@@ -258,7 +264,7 @@ class AuthService {
258
264
try {
259
265
user = User (
260
266
id: _uuid.v4 (), // Generate new ID
261
- role : UserRole .guestUser, // Anonymous users are guest users
267
+ roles : [ UserRoles .guestUser] , // Anonymous users are guest users
262
268
email: null , // Anonymous users don't have an email initially
263
269
);
264
270
user = await _userRepository.create (item: user);
@@ -368,25 +374,27 @@ class AuthService {
368
374
required User anonymousUser,
369
375
required String emailToLink,
370
376
}) async {
371
- if (anonymousUser.role != UserRole . guestUser) {
377
+ if (! anonymousUser.roles. contains ( UserRoles . guestUser) ) {
372
378
throw const BadRequestException (
373
379
'Account is already permanent. Cannot link email.' ,
374
380
);
375
381
}
376
382
377
383
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
+ );
390
398
}
391
399
392
400
// 2. Generate and store the link code.
@@ -430,7 +438,7 @@ class AuthService {
430
438
required String codeFromUser,
431
439
required String oldAnonymousToken, // Needed to invalidate it
432
440
}) async {
433
- if (anonymousUser.role != UserRole . guestUser) {
441
+ if (! anonymousUser.roles. contains ( UserRoles . guestUser) ) {
434
442
// Should ideally not happen if flow is correct, but good safeguard.
435
443
throw const BadRequestException (
436
444
'Account is already permanent. Cannot complete email linking.' ,
@@ -455,7 +463,7 @@ class AuthService {
455
463
final updatedUser = User (
456
464
id: anonymousUser.id, // Preserve original ID
457
465
email: linkedEmail,
458
- role : UserRole .standardUser, // Now a permanent standard user
466
+ roles : [ UserRoles .standardUser] , // Now a permanent standard user
459
467
);
460
468
final permanentUser = await _userRepository.update (
461
469
id: updatedUser.id,
0 commit comments