feat(backend): add admin evaluation history, engine, simulation, bot API controllers and global exception middleware
This commit is contained in:
@@ -21,9 +21,6 @@ public interface IUserService
|
||||
/// <summary>Authenticates user credentials and returns JWT response.</summary>
|
||||
Task<AuthResponseDto?> AuthenticateAsync(LoginRequestDto request, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>Registers a new user account.</summary>
|
||||
Task<AuthResponseDto?> RegisterUserAsync(RegisterRequestDto request, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>Changes the initial password for a user.</summary>
|
||||
Task<bool> ChangeInitialPasswordAsync(Guid userId, string newPassword,
|
||||
CancellationToken cancellationToken = default);
|
||||
@@ -115,54 +112,6 @@ public class UserService : IUserService
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<AuthResponseDto?> RegisterUserAsync(RegisterRequestDto request,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
var dbContext = scope.ServiceProvider.GetRequiredService<BackendDbContext>();
|
||||
|
||||
string normalizedEmail = request.Email.Trim().ToLowerInvariant();
|
||||
bool exists = await dbContext.Users.AnyAsync(u => u.Email.ToLower() == normalizedEmail, cancellationToken);
|
||||
if (exists)
|
||||
{
|
||||
_logger.LogWarning("[{Channel}] Registration failed: Email '{Email}' is already taken.", "AuthChannel",
|
||||
request.Email);
|
||||
return null;
|
||||
}
|
||||
|
||||
string passwordHash = BCrypt.Net.BCrypt.HashPassword(request.Password);
|
||||
|
||||
var newUser = new UserEntity
|
||||
{
|
||||
Email = normalizedEmail,
|
||||
PasswordHash = passwordHash,
|
||||
FullName = string.IsNullOrWhiteSpace(request.FullName) ? normalizedEmail.Split('@')[0] : request.FullName,
|
||||
Role = "User",
|
||||
ThemePreference = "fluent_dark", // Default Theme for FluentAvalonia
|
||||
IsActive = true,
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
LastLoginAt = DateTime.UtcNow
|
||||
};
|
||||
|
||||
dbContext.Users.Add(newUser);
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
|
||||
var (token, expiresAt) = _jwtTokenService.GenerateToken(newUser);
|
||||
|
||||
return new AuthResponseDto
|
||||
{
|
||||
Token = token,
|
||||
UserId = newUser.Id,
|
||||
Email = newUser.Email,
|
||||
FullName = newUser.FullName,
|
||||
Role = newUser.Role,
|
||||
ThemePreference = newUser.ThemePreference,
|
||||
FcmTokens = new List<string>(),
|
||||
ExpiresAt = expiresAt
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<UserDto?> CreateUserByAdminAsync(CreateUserRequestDto request,
|
||||
CancellationToken cancellationToken = default)
|
||||
@@ -352,13 +301,21 @@ public class UserService : IUserService
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
string password = !string.IsNullOrWhiteSpace(defaultAdminPassword)
|
||||
? defaultAdminPassword
|
||||
: "AdminDefaultPassword2026!";
|
||||
// Fail-fast statt Fallback auf einen im Repo öffentlichen Literal (Rules.md §12): ein Gateway,
|
||||
// das den Default-Admin mit einem repo-öffentlichen Passwort anlegt, ist schlimmer als eines,
|
||||
// das nicht startet. Program.cs validiert dies bereits vor dem Aufruf; dieser Guard dient als
|
||||
// Verteidigung in der Tiefe, falls die Methode von anderer Stelle aufgerufen wird.
|
||||
if (string.IsNullOrWhiteSpace(defaultAdminPassword))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"ADMIN:DefaultPassword (bzw. ADMIN__DefaultPassword) ist nicht konfiguriert. " +
|
||||
"Das Seeding des Default-Admin-Accounts kann ohne explizit konfiguriertes Passwort nicht durchgeführt werden.");
|
||||
}
|
||||
|
||||
var adminUser = new UserEntity
|
||||
{
|
||||
Email = adminEmail,
|
||||
PasswordHash = BCrypt.Net.BCrypt.HashPassword(password),
|
||||
PasswordHash = BCrypt.Net.BCrypt.HashPassword(defaultAdminPassword),
|
||||
FullName = "System Administrator",
|
||||
Role = "Admin",
|
||||
ThemePreference = "fluent_dark",
|
||||
|
||||
Reference in New Issue
Block a user