using AutoMapper; using IdentityService.Domain; using IdentityService.WebApi.Applications.Dtos; using IdentityService.WebApi.Applications.Dtos.Common; using IM.Commons; using IM.Jwt; using Microsoft.Extensions.Options; using System.Security.Claims; namespace IdentityService.WebApi.Applications.Auth { public class AuthService { private readonly ITokenService tokenService; private readonly IIdRepository idRepository; private readonly IOptions jwtOptions; private readonly IdDomainService idDomainService; private readonly IMapper mapper; public AuthService(ITokenService tokenService, IIdRepository idRepository, IOptions options, IdDomainService idDomainService, IMapper mapper ) { this.tokenService = tokenService; this.idRepository = idRepository; jwtOptions = options; this.idDomainService = idDomainService; this.mapper = mapper; } public async Task> LoginAsync(string username, string password) { var user = await idRepository.FindByUserNameAsync(username); if (user is null) { return Result.Fail(ResultCode.USER_NOT_FOUND); } var idResult = await idRepository.CheckForSignInAsync(user, password, true); if (!idResult.Succeeded) { return Result.Fail(ResultCode.PASSWORD_ERROR); } var token = await BuildTokenAsync(user); var refreshToken = await tokenService.CreateRefreshTokenAsync(user.Id); return Result.Success(new LoginResponse(user.Id, token, refreshToken, null, user.UserName, user.NickName,user.Avatar, user.CreationTime)); } public async Task> RegisterAsync(string userName, string password, string nickName) { var userResult = await idDomainService.CreateUserAsync(userName, password, nickName); if (!userResult.Succeeded) return Result.Fail(userResult); var idResult = await idRepository.CreateAsync(userResult.Data!, password); if (!idResult.Succeeded) { var msg = idResult.Errors.FirstOrDefault(); return Result.Fail( ResultCode.REGISTER_ERROR, msg?.Description ?? ResultCode.REGISTER_ERROR.GetDescription()); } return Result.Success(mapper.Map(userResult.Data)); } public async Task> RefreshAsync(string refreshToken) { var validateRes = await tokenService.ValidateRefreshTokenAsync(refreshToken); if (!validateRes.ok) { return Result.Fail(ResultCode.AUTH_FAILED); } var user = await idRepository.FindByIdAsync(validateRes.userId); if (user is null) { return Result.Fail(ResultCode.USER_NOT_FOUND); } var token = await BuildTokenAsync(user); return Result.Success(new LoginResponse(user.Id, token, refreshToken, null, user.UserName, user.NickName, user.Avatar, user.CreationTime)); } private async Task BuildTokenAsync(Domain.Entities.User user) { var roles = await idRepository.GetRolesAsync(user); List claims = new List(); claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())); foreach (string role in roles) { claims.Add(new Claim(ClaimTypes.Role, role)); } return tokenService.GetToken(claims, jwtOptions.Value); } } }