using System.Security.Claims; using Microsoft.EntityFrameworkCore; using ProposalSystem.Application.Interfaces; using ProposalSystem.Domain.Entities; using ProposalSystem.Infrastructure.Data; namespace ProposalSystem.Api.Services; public class CurrentUserService : ICurrentUserService { private readonly IHttpContextAccessor _httpContext; private readonly ProposalDbContext _db; private User? _cachedUser; public CurrentUserService(IHttpContextAccessor httpContext, ProposalDbContext db) { _httpContext = httpContext; _db = db; } public Guid UserId => GetUser().Id; public string Email => GetUser().Email; public UserRole Role => GetUser().Role; public string? IpAddress => _httpContext.HttpContext?.Connection.RemoteIpAddress?.ToString(); private User GetUser() { if (_cachedUser != null) return _cachedUser; var cognitoSub = _httpContext.HttpContext?.User.FindFirstValue(ClaimTypes.NameIdentifier) ?? _httpContext.HttpContext?.User.FindFirstValue("sub") ?? throw new UnauthorizedAccessException("No authenticated user"); _cachedUser = _db.Users .FirstOrDefault(u => u.CognitoSub == cognitoSub); if (_cachedUser == null) { var email = _httpContext.HttpContext?.User.FindFirstValue(ClaimTypes.Email) ?? _httpContext.HttpContext?.User.FindFirstValue("email") ?? "unknown@seahaven.com"; var name = _httpContext.HttpContext?.User.FindFirstValue("name") ?? email.Split('@')[0]; var groups = _httpContext.HttpContext?.User.FindAll("cognito:groups") .Select(c => c.Value).ToList() ?? new List(); var role = groups.Contains("sysadmins") ? UserRole.SysAdmin : groups.Contains("admins") ? UserRole.Admin : UserRole.Dispatcher; _cachedUser = new User { Id = Guid.NewGuid(), CognitoSub = cognitoSub, Email = email, DisplayName = name, Role = role, IsActive = true, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow, }; _db.Users.Add(_cachedUser); _db.SaveChanges(); } return _cachedUser; } }