Spaces:
Running
Running
File size: 5,410 Bytes
b9c7f0e 7039b6a 35321eb b9c7f0e 7039b6a 67d4c53 b9c7f0e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | using System.Security.Cryptography;
using System.Text;
using FlowAPI.Application.DTOs.User;
using FlowAPI.Application.Interfaces;
using FlowAPI.Domain.Entities;
using Microsoft.Extensions.Configuration;
namespace FlowAPI.Application.Services
{
public class UserService : IUserService
{
private readonly IUserRepository _repo;
private readonly ITokenService _tokenService;
private readonly IConfiguration _config;
private readonly IAchievementService _achievementService;
public UserService(IUserRepository repo, ITokenService tokenService, IConfiguration config, IAchievementService achievementService)
{
_repo = repo;
_tokenService = tokenService;
_config = config;
_achievementService = achievementService;
}
public async Task<IEnumerable<UserResponseDto>> GetAllAsync()
{
var users = await _repo.GetAllAsync();
return users.Select(MapToDto);
}
public async Task<UserResponseDto?> GetByIdAsync(Guid id)
{
var user = await _repo.GetByIdAsync(id);
return user is null ? null : MapToDto(user);
}
public async Task<AuthResponseDto> RegisterAsync(CreateUserDto dto)
{
var existing = await _repo.GetByEmailAsync(dto.Email);
if (existing is not null)
throw new InvalidOperationException("User with this email already exists.");
var user = new User
{
Id = Guid.NewGuid(),
Email = dto.Email,
PasswordHash = HashPassword(dto.Password),
DisplayName = dto.DisplayName,
CreatedAt = DateTime.UtcNow
};
var created = await _repo.CreateAsync(user);
return new AuthResponseDto
{
User = MapToDto(created),
Token = _tokenService.CreateToken(created)
};
}
public async Task<AuthResponseDto?> LoginAsync(LoginDto dto)
{
var user = await _repo.GetByEmailAsync(dto.Email);
if (user is null || string.IsNullOrEmpty(user.PasswordHash) || user.PasswordHash != HashPassword(dto.Password))
return null;
return new AuthResponseDto
{
User = MapToDto(user),
Token = _tokenService.CreateToken(user)
};
}
public async Task<AuthResponseDto> GoogleLoginAsync(GoogleLoginDto dto)
{
var settings = new Google.Apis.Auth.GoogleJsonWebSignature.ValidationSettings
{
Audience = new List<string> { _config["Google:ClientId"]! }
};
var payload = await Google.Apis.Auth.GoogleJsonWebSignature.ValidateAsync(dto.IdToken, settings);
var user = await _repo.GetByEmailAsync(payload.Email);
if (user == null)
{
user = new User
{
Id = Guid.NewGuid(),
Email = payload.Email,
DisplayName = payload.Name,
CreatedAt = DateTime.UtcNow,
PasswordHash = "" // No password for Google users
};
user = await _repo.CreateAsync(user);
}
return new AuthResponseDto
{
User = MapToDto(user),
Token = _tokenService.CreateToken(user)
};
}
public async Task<UserResponseDto?> UpdateAsync(Guid id, UpdateUserDto dto)
{
var user = await _repo.GetByIdAsync(id);
if (user is null) return null;
bool isAvatarUpdated = dto.AvatarUrl is not null && user.AvatarUrl != dto.AvatarUrl;
if (dto.DisplayName is not null) user.DisplayName = dto.DisplayName;
if (dto.IsPremium.HasValue) user.IsPremium = dto.IsPremium.Value;
if (dto.AvatarUrl is not null) user.AvatarUrl = dto.AvatarUrl;
if (dto.SubscriptionTier is not null)
{
user.SubscriptionTier = dto.SubscriptionTier;
user.IsPremium = dto.SubscriptionTier != "Free";
}
if (!string.IsNullOrEmpty(dto.Password)) user.PasswordHash = HashPassword(dto.Password);
var updated = await _repo.UpdateAsync(user);
if (isAvatarUpdated)
{
await _achievementService.ProcessEventAsync(id, "AvatarUploaded");
}
return MapToDto(updated);
}
public async Task<bool> DeleteAsync(Guid id)
{
return await _repo.DeleteAsync(id);
}
private static string HashPassword(string password)
{
var bytes = SHA256.HashData(Encoding.UTF8.GetBytes(password));
return Convert.ToBase64String(bytes);
}
private static UserResponseDto MapToDto(User user) => new()
{
Id = user.Id,
Email = user.Email,
DisplayName = user.DisplayName,
IsPremium = user.IsPremium,
AvatarUrl = user.AvatarUrl,
CreatedAt = user.CreatedAt,
SubscriptionTier = user.SubscriptionTier,
DailyAiGenerationsCount = user.DailyAiGenerationsCount
};
}
}
|