Allow an admin to override a user's email address.

This commit is contained in:
Joseph Milazzo 2024-12-08 10:22:31 -06:00
parent 0407d75d91
commit d522bccf86
6 changed files with 112 additions and 80 deletions

View file

@ -509,6 +509,21 @@ public class AccountController : BaseApiController
_unitOfWork.UserRepository.Update(user);
}
// Check if email is changing for a non-admin user
var isUpdatingAnotherAccount = user.Id != adminUser.Id;
if (isUpdatingAnotherAccount && !string.IsNullOrEmpty(dto.Email) && user.Email != dto.Email)
{
// Validate username change
var errors = await _accountService.ValidateEmail(dto.Email);
if (errors.Any()) return BadRequest(await _localizationService.Translate(User.GetUserId(), "email-taken"));
user.Email = dto.Email;
user.EmailConfirmed = true; // When an admin performs the flow, we assume the email address is able to receive data
await _userManager.UpdateNormalizedEmailAsync(user);
_unitOfWork.UserRepository.Update(user);
}
// Update roles
var existingRoles = await _userManager.GetRolesAsync(user);
var hasAdminRole = dto.Roles.Contains(PolicyConstants.AdminRole);
@ -612,8 +627,7 @@ public class AccountController : BaseApiController
if (adminUser == null) return Unauthorized(await _localizationService.Translate(userId, "permission-denied"));
dto.Email = dto.Email.Trim();
if (string.IsNullOrEmpty(dto.Email))
return BadRequest(await _localizationService.Translate(userId, "invalid-payload"));
if (string.IsNullOrEmpty(dto.Email)) return BadRequest(await _localizationService.Translate(userId, "invalid-payload"));
_logger.LogInformation("{User} is inviting {Email} to the server", adminUser.UserName, dto.Email);
@ -623,7 +637,7 @@ public class AccountController : BaseApiController
{
var invitedUser = await _unitOfWork.UserRepository.GetUserByEmailAsync(dto.Email);
if (await _userManager.IsEmailConfirmedAsync(invitedUser!))
return BadRequest(await _localizationService.Translate(User.GetUserId(), "user-already-registered", invitedUser.UserName));
return BadRequest(await _localizationService.Translate(User.GetUserId(), "user-already-registered", invitedUser!.UserName));
return BadRequest(await _localizationService.Translate(User.GetUserId(), "user-already-invited"));
}

View file

@ -18,4 +18,8 @@ public record UpdateUserDto
/// An Age Rating which will limit the account to seeing everything equal to or below said rating.
/// </summary>
public AgeRestrictionDto AgeRestriction { get; init; } = default!;
/// <summary>
/// Email of the user
/// </summary>
public string? Email { get; set; } = default!;
}

View file

@ -18,6 +18,7 @@
"age-restriction-update": "There was an error updating the age restriction",
"no-user": "User does not exist",
"username-taken": "Username already taken",
"email-taken": "Email already in use",
"user-already-confirmed": "User is already confirmed",
"generic-user-update": "There was an exception when updating the user",
"manual-setup-fail": "Manual setup is unable to be completed. Please cancel and recreate the invite",

View file

@ -95,12 +95,12 @@ public class AccountService : IAccountService
public async Task<IEnumerable<ApiException>> ValidateEmail(string email)
{
var user = await _unitOfWork.UserRepository.GetUserByEmailAsync(email);
if (user == null) return Array.Empty<ApiException>();
if (user == null) return [];
return new List<ApiException>()
{
return
[
new ApiException(400, "Email is already registered")
};
];
}
/// <summary>