using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Mvc; using MiniWiki.Data.Settings; namespace MiniWiki.Web.Auth; [Route("/auth")] public class AuthController(AuthAction authAction, ISettingsRepository settingsRepository) : ControllerBase { [HttpPost("register")] public async Task PostRegisterAsync([FromForm] string email, [FromForm] string password, [FromQuery] string? returnUrl) { var result = await authAction.RegisterAsync(email, password); if (result.IsError) { var registrationOpen = await settingsRepository.GetByKeyAsync("registration_open"); return new RazorComponentResult(new { IsRegistrationOpen = registrationOpen!.Value, result.ErrorMessage, Email = email, Password = password, ReturnUrl = returnUrl, IsRegistering = true, }) { StatusCode = StatusCodes.Status400BadRequest }; } var session = await authAction.CreateSessionAsync(result.Object!.Id, (long)TimeSpan.FromHours(720).TotalSeconds); SetSessionCookie(session.Id); return Results.Redirect("/"); } [HttpGet("login")] public async Task GetLogin([FromQuery] string? returnUrl) { var registrationOpen = await settingsRepository.GetByKeyAsync("registration_open"); return new RazorComponentResult(new { IsRegistrationOpen = registrationOpen!.Value, ReturnUrl = returnUrl }); } [HttpPost("login")] public async Task PostLoginPassword([FromForm] string email, [FromForm] string password, [FromForm] string? returnUrl) { var result = await authAction.LoginWithPasswordAsync(email, password); if (result.IsError) { var registrationOpen = await settingsRepository.GetByKeyAsync("registration_open"); return new RazorComponentResult(new { IsRegistrationOpen = registrationOpen!.Value, result.ErrorMessage, Email = email, Password = password, ReturnUrl = returnUrl, IsRegistering = false, }) { StatusCode = StatusCodes.Status400BadRequest }; } var session = await authAction.CreateSessionAsync(result.Object!.Id, (long)TimeSpan.FromHours(72).TotalSeconds); SetSessionCookie(session.Id); return Results.Redirect(!Url.IsLocalUrl(returnUrl) ? "/" : returnUrl); } [HttpPost("logout")] [HttpGet("logout")] public async Task Logout() { var sessionId = HttpContext.Request.Cookies["mw_session"]; if (!string.IsNullOrEmpty(sessionId)) await authAction.DeleteSessionAsync(sessionId); HttpContext.Response.Cookies.Delete("mw_session"); return Redirect("/"); } private void SetSessionCookie(string sessionId) => HttpContext.Response.Cookies.Append("mw_session", sessionId, new CookieOptions { HttpOnly = true, Secure = true, SameSite = SameSiteMode.Lax, MaxAge = TimeSpan.FromHours(720), Path = "/" }); }