using Microsoft.AspNetCore.Mvc; using backend.Application; using backend.Models; using System.Text.Json.Nodes; using Microsoft.AspNetCore.Identity; using System.Web; using backend.Middleware; using backend.Migrations; namespace backend.Controllers; [ApiController] public class UserController : ControllerBase { [HttpPost("Register")] public IActionResult Register([FromBody] JsonObject input) { // Validate if (String.IsNullOrEmpty(input["username"]?.ToString()) || String.IsNullOrEmpty(input["password"]?.ToString())) { return BadRequest("Username and password required"); } if (ApplicationState.DbContext!.Users.FirstOrDefault(user => user.Username == input["username"]!.ToString()) != null) { return BadRequest("User already exists"); } // Hash password var passwordHasher = new PasswordHasher(); string hashedPassword = passwordHasher.HashPassword(null, input["password"]!.ToString()); // Generate touch code string touchCode = ""; for (int i = 0; i < 4; i++) { touchCode += (1 + new Random().Next() % 5).ToString(); } // Create user var user = new User { Username = input["username"]!.ToString(), Password = hashedPassword, TouchCode = touchCode, IsParent = false, }; // Save user ApplicationState.DbContext!.Add(user); ApplicationState.DbContext!.SaveChanges(); Console.WriteLine("Created user: " + user.Username); return Ok(); } [HttpPost("Login")] public IActionResult Login([FromBody] JsonObject input) { // Validate if (String.IsNullOrEmpty(input["username"]?.ToString()) || String.IsNullOrEmpty(input["password"]?.ToString())) { return BadRequest("Username and password required"); } if (Request.Cookies["session"] != null) { return BadRequest("You are already logged in"); } // Get user var user = ApplicationState.DbContext!.Users.FirstOrDefault(user => user.Username == input["username"]!.ToString()); if (user == null) { return BadRequest("Invalid username"); } // Verify password var passwordHasher = new PasswordHasher(); if (passwordHasher.VerifyHashedPassword(null, user.Password, input["password"]!.ToString()) == PasswordVerificationResult.Failed) { return BadRequest("Invalid password"); } // Create session token if necessary if (string.IsNullOrEmpty(user.SessionToken)) { user.SessionToken = Guid.NewGuid().ToString(); ApplicationState.DbContext!.SaveChanges(); } // Set session cookie Response.Cookies.Append("session", user.SessionToken); Console.WriteLine(user.Username + " has logged in"); return Ok(); } [HttpPost("Logout")] [MiddlewareFilter(typeof(AuthenticationMiddlewareBuilder))] public IActionResult LogOut() { // Get user var user = ApplicationState.DbContext!.Users.FirstOrDefault(user => user.SessionToken == Request.Cookies["session"]!.ToString()); if (user == null) { return BadRequest("Invalid session token"); } // Log out user.SessionToken = null; ApplicationState.DbContext!.SaveChanges(); Response.Cookies.Delete("session"); return Ok(); } [HttpGet("UserInfo")] [MiddlewareFilter(typeof(AuthenticationMiddlewareBuilder))] public IActionResult UserInfo() { // Get user var user = ApplicationState.DbContext!.Users.FirstOrDefault(user => user.SessionToken == Request.Cookies["session"]!.ToString()); if (user == null) { return BadRequest("Invalid session token"); } var data = new { username = user.Username, touchCode = user.TouchCode, isParent = user.IsParent, dispenses = user.Dispenses, }; return new JsonResult(data); } [HttpGet("Children")] [MiddlewareFilter(typeof(ParentMiddlewareBuilder))] public IActionResult ListChildren() { var users = ApplicationState.DbContext!.Users .Where(user => !user.IsParent) .Select(user => new { id = user.Id, username = user.Username, dispenses = user.Dispenses, }); return new JsonResult(users); } [HttpPut] [Route("Children/{id}/Dispenses")] [MiddlewareFilter(typeof(ParentMiddlewareBuilder))] public IActionResult UpdateChildDispenses(int id, [FromBody] JsonObject input) { int dispenses; if (!int.TryParse(input["dispenses"]?.ToString(), out dispenses)) { return BadRequest("Dispenses must be number"); } if (dispenses < 0) { return BadRequest("Dispenses cannot be less than 0"); } var user = ApplicationState.DbContext!.Users.Find(id); if (user == null) { return BadRequest("Invalid user ID"); } user.Dispenses = dispenses; ApplicationState.DbContext!.SaveChanges(); return Ok(); } }