using System; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using API.Data; using API.DTOs; using API.Entities; using API.Interfaces; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; namespace API.Controllers { public class AccountController : BaseApiController { private readonly DataContext _context; private readonly ITokenService _tokenService; private readonly IUserRepository _userRepository; private readonly ILogger _logger; public AccountController(DataContext context, ITokenService tokenService, IUserRepository userRepository, ILogger logger) { _context = context; _tokenService = tokenService; _userRepository = userRepository; _logger = logger; } [HttpPost("register")] public async Task> Register(RegisterDto registerDto) { _logger.LogInformation("Username: " + registerDto.Password); if (await UserExists(registerDto.Username)) { return BadRequest("Username is taken."); } using var hmac = new HMACSHA512(); var user = new AppUser { UserName = registerDto.Username.ToLower(), PasswordHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(registerDto.Password)), PasswordSalt = hmac.Key, IsAdmin = registerDto.IsAdmin, LastActive = DateTime.Now }; _context.Users.Add(user); await _context.SaveChangesAsync(); return new UserDto() { Username = user.UserName, Token = _tokenService.CreateToken(user), IsAdmin = user.IsAdmin }; } [HttpPost("login")] public async Task> Login(LoginDto loginDto) { var user = await _userRepository.GetUserByUsernameAsync(loginDto.Username); if (user == null) return Unauthorized("Invalid username"); using var hmac = new HMACSHA512(user.PasswordSalt); var computedHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(loginDto.Password)); for (int i = 0; i < computedHash.Length; i++) { if (computedHash[i] != user.PasswordHash[i]) return Unauthorized("Invalid password"); } // Update LastActive on account user.LastActive = DateTime.Now; _userRepository.Update(user); await _userRepository.SaveAllAsync(); return new UserDto() { Username = user.UserName, Token = _tokenService.CreateToken(user), IsAdmin = user.IsAdmin }; } private async Task UserExists(string username) { return await _context.Users.AnyAsync(user => user.UserName == username.ToLower()); } } }