Fix role change silently failing via @bind
The role <select> used a manual value=/@onchange pattern that parsed e.Value and returned silently when the parse failed, so changing a role did nothing and showed no message. Switch to @bind + @bind:after so the framework handles the enum conversion, and log/verify the persisted role in UpdateRoleAsync (now returns the previous role) for diagnosis. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -11,7 +11,9 @@ public interface IUserService
|
||||
|
||||
Task<AppUser?> GetByEmailAsync(string email);
|
||||
Task<IReadOnlyList<AppUser>> GetAllAsync();
|
||||
Task UpdateRoleAsync(string userId, UserRole role);
|
||||
/// <summary>Persist a new role for the user. Returns the previous role (read from the store).</summary>
|
||||
/// <exception cref="KeyNotFoundException">No user matches <paramref name="userId"/>.</exception>
|
||||
Task<UserRole> UpdateRoleAsync(string userId, UserRole role);
|
||||
Task DeleteAsync(string userId);
|
||||
|
||||
/// <summary>Create a local password-based account. First user ever becomes Admin.</summary>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using SharepointToolbox.Web.Core.Models;
|
||||
using SharepointToolbox.Web.Infrastructure.Persistence;
|
||||
|
||||
@@ -9,11 +10,13 @@ public class UserService : IUserService
|
||||
{
|
||||
private readonly UserRepository _repo;
|
||||
private readonly IPasswordHasher<AppUser> _hasher;
|
||||
private readonly ILogger<UserService> _logger;
|
||||
|
||||
public UserService(UserRepository repo, IPasswordHasher<AppUser> hasher)
|
||||
public UserService(UserRepository repo, IPasswordHasher<AppUser> hasher, ILogger<UserService> logger)
|
||||
{
|
||||
_repo = repo;
|
||||
_hasher = hasher;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<AppUser> ProvisionAsync(ClaimsPrincipal principal)
|
||||
@@ -56,13 +59,23 @@ public class UserService : IUserService
|
||||
|
||||
public Task<IReadOnlyList<AppUser>> GetAllAsync() => _repo.LoadAsync();
|
||||
|
||||
public async Task UpdateRoleAsync(string userId, UserRole role)
|
||||
public async Task<UserRole> UpdateRoleAsync(string userId, UserRole role)
|
||||
{
|
||||
var users = (await _repo.LoadAsync()).ToList();
|
||||
var user = users.FirstOrDefault(u => u.Id == userId)
|
||||
?? throw new KeyNotFoundException($"User {userId} not found.");
|
||||
?? throw new KeyNotFoundException($"User '{userId}' not found among {users.Count} stored users.");
|
||||
|
||||
var oldRole = user.Role;
|
||||
user.Role = role;
|
||||
await _repo.UpsertAsync(user);
|
||||
|
||||
// Verify the write landed by re-reading the row from disk.
|
||||
var persisted = (await _repo.LoadAsync()).FirstOrDefault(u => u.Id == user.Id)?.Role;
|
||||
_logger.LogInformation(
|
||||
"UpdateRoleAsync: {Email} (id {Id}) {OldRole} → {NewRole}; persisted value now {Persisted}.",
|
||||
user.Email, user.Id, oldRole, role, persisted);
|
||||
|
||||
return oldRole;
|
||||
}
|
||||
|
||||
public Task DeleteAsync(string userId) => _repo.DeleteAsync(userId);
|
||||
|
||||
Reference in New Issue
Block a user