using AutoMapper; using RecNet.Application.Common.Interfaces; using RecNet.Domain.Repositories; using ProfileEntity = RecNet.Domain.Entities.Profiles.Profile; namespace RecNet.Application.Profiles; public class ProfileService( NameGenerator nameGenerator, IProfileRepository profileRepository, ITokenService tokenService, IConfigService configService, IEnumerable validators, IMapper mapper) : IProfileService { public async Task GetProfileAsync(Guid profileId, CancellationToken ct = default) { var profile = await profileRepository.GetByIdAsync(profileId, ct); return profile is null ? null : mapper.Map(profile); } public async Task> GetProfilesAsync( List profileIds, CancellationToken ct = default) { var profiles = await profileRepository.GetByIdsAsync(profileIds, ct); return mapper.Map>(profiles); } public async Task LoginAsync( LoginProfileCommand command, CancellationToken ct = default) { var validator = validators.FirstOrDefault(x => x.PlatformType == command.PlatformType); if (validator is null) return LoginProfileResult.Fail("Invalid platform type"); var ignoreAuthValidation = await configService.GetAsync("Profiles:IgnoreAuthValidation", true, ct); var auth = await validator.ValidateAsync( command.PlatformAuthentication, command.PlatformId, ct); if (!auth.Succeeded && !ignoreAuthValidation) return LoginProfileResult.Fail($"Platform Auth Failed: {auth.Message}"); var profile = await profileRepository.GetByPlatform( command.PlatformType, command.PlatformId, ct); if (profile is null) { var name = await nameGenerator.GenerateAsync(ct); profile = ProfileEntity.Create( name, command.PlatformType, command.PlatformId); await profileRepository.AddAsync(profile, ct); } if (profile.IsBanned) return LoginProfileResult.Fail("Profile is banned"); if (auth.Name is not null && profile.Name != auth.Name) profile.SetName(auth.Name); profile.AddDeviceId(command.DeviceId); await profileRepository.SaveChangesAsync(ct); var token = tokenService.GenerateProfileToken(profile); return LoginProfileResult.Success( profile: mapper.Map(profile), accessToken: token.AccessToken, expiresIn: token.ExpiresIn ); } }