using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.RateLimiting; using SameBeat.Application.Interfejsy; using SameBeat.Application.Komendy; namespace SameBeat.Api.Controllers; [ApiController] [Route("api/auth")] public class AuthController : ControllerBase { private const string NazwaCiasteczkaAuth = "sb_auth"; private readonly ISerwisLogowania _serwisLogowania; private readonly ILogger _logger; public AuthController(ISerwisLogowania serwisLogowania, ILogger logger) { _serwisLogowania = serwisLogowania; _logger = logger; } /// /// Loguje hosta/moderatora. W przypadku sukcesu token JWT trafia do ciasteczka httpOnly. /// /// ETAP 7: [EnableRateLimiting("logowanie")] naklada surowsza polityke (5 prob / 5 minut per IP, /// patrz Program.cs) NA MIEJSCE ogolnego limitu /api/* (polityki nie sumuja sie -- ta CALKOWICIE /// zastepuje globalny limiter dla tego endpointu). To warstwa per-IP; per-konto chroni niezaleznie /// SerwisLogowania (blokada nicku po N nieudanych probach, patrz komentarz tam). /// [HttpPost("login")] [AllowAnonymous] [EnableRateLimiting("logowanie")] public async Task ZalogujAsync([FromBody] ZalogujKomenda zadanie, CancellationToken token) { var wynik = await _serwisLogowania.ZalogujAsync(zadanie, token); if (!wynik.Sukces || wynik.Dane is null) { return Unauthorized(new { blad = wynik.Blad }); } var dane = wynik.Dane; Response.Cookies.Append(NazwaCiasteczkaAuth, dane.Token, new CookieOptions { HttpOnly = true, Secure = true, SameSite = SameSiteMode.Strict, Expires = dane.WygasaUtc }); _logger.LogInformation("Zalogowano uzytkownika {UzytkownikId} przez /api/auth/login.", dane.UzytkownikId); return Ok(new { id = dane.UzytkownikId, nick = dane.Nick, rola = dane.Rola.ToString() }); } /// Wylogowanie -- czyszczenie ciasteczka po stronie serwera, bez zaleznosci od stanu tokenu. [HttpPost("logout")] [AllowAnonymous] public IActionResult Wyloguj() { Response.Cookies.Delete(NazwaCiasteczkaAuth, new CookieOptions { HttpOnly = true, Secure = true, SameSite = SameSiteMode.Strict }); return Ok(new { sukces = true }); } }