Add admin user creation & must-change flag
Add server and UI support for creating admin users and forcing password change. API: introduce CreateUserRequest contract and add CreateNewAppUser endpoint in AppUserController; extend ChangeUserRequest with MustChangePassword and handle role assignment and detailed error responses (409/422/400). Frontend: new CreateUserDialog component, integrate it into AdminUsers list, and add createAdminUser service with CreateAdminUserError and payload handling; include mustChangePassword in update payloads and EditUserDialog. UI polish: enhanced app banner enter/leave animations in Layout.vue and add auto-dismiss timers/cleanup to appBanners store to limit and auto-remove banners.
This commit is contained in:
@@ -4,5 +4,6 @@
|
||||
{
|
||||
public string? UserName { get; set; }
|
||||
public bool? IsActive { get; set; }
|
||||
public bool? MustChangePassword { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace API.Contracts.Auth
|
||||
{
|
||||
public class CreateUserRequest
|
||||
{
|
||||
public required string UserName { get; set; }
|
||||
public required string StartPassword { get; set; }
|
||||
public bool IsAdmin { get; set; } = false;
|
||||
public bool IsActive { get; set; } = true;
|
||||
}
|
||||
}
|
||||
@@ -92,7 +92,72 @@ namespace API.Controllers.Auth
|
||||
}
|
||||
}
|
||||
|
||||
if (changeDto.MustChangePassword != null)
|
||||
{
|
||||
user.MustChangePassword = changeDto.MustChangePassword.Value;
|
||||
|
||||
await userManager.UpdateAsync(user);
|
||||
}
|
||||
|
||||
return Ok(await user.ToCurrentUserResponseAsync(userManager));
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> CreateNewAppUser([FromBody] CreateUserRequest createDto)
|
||||
{
|
||||
var newUser = new AppUser
|
||||
{
|
||||
UserName = createDto.UserName.Trim(),
|
||||
MustChangePassword = true,
|
||||
IsActive = createDto.IsActive,
|
||||
};
|
||||
|
||||
var result = await userManager.CreateAsync(newUser, createDto.StartPassword);
|
||||
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
if (result.Errors.Any(e => e.Code == nameof(IdentityErrorDescriber.DuplicateUserName)))
|
||||
{
|
||||
return Conflict(new { message = "Benutzername ist bereits vergeben." });
|
||||
}
|
||||
|
||||
var passwordErrors = result.Errors
|
||||
.Where(e => e.Code.StartsWith("Password"))
|
||||
.Select(e => e.Description)
|
||||
.ToList();
|
||||
|
||||
if (passwordErrors.Any())
|
||||
{
|
||||
return UnprocessableEntity(new
|
||||
{
|
||||
message = "Passwort erfüllt nicht die Sicherheitsanforderungen.",
|
||||
errors = passwordErrors
|
||||
});
|
||||
}
|
||||
|
||||
return BadRequest(new
|
||||
{
|
||||
message = "Benutzer konnte nicht erstellt werden.",
|
||||
errors = result.Errors.Select(e => e.Description)
|
||||
});
|
||||
}
|
||||
|
||||
if (createDto.IsAdmin)
|
||||
{
|
||||
var roleResult = await userManager.AddToRoleAsync(newUser, RoleNames.Admin);
|
||||
|
||||
if (!roleResult.Succeeded)
|
||||
{
|
||||
return BadRequest(new
|
||||
{
|
||||
message = "Benutzer wurde erstellt, aber Rolle konnte nicht zugewiesen werden.",
|
||||
errors = roleResult.Errors.Select(e => e.Description)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return CreatedAtAction(nameof(GetAppUserById), new { id = newUser.Id },
|
||||
await newUser.ToCurrentUserResponseAsync(userManager));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user