login changes

This commit is contained in:
roman
2026-06-10 20:39:52 +02:00
parent 841037013a
commit 43011f0a77
13 changed files with 528 additions and 52 deletions
@@ -13,30 +13,30 @@ public class AuthController : ControllerBase
{
private readonly AppDbContext _db;
private readonly TokenService _tokenService;
private readonly EmailService _emailService;
public AuthController(AppDbContext db, TokenService tokenService)
public AuthController(AppDbContext db, TokenService tokenService, EmailService emailService)
{
_db = db;
_tokenService = tokenService;
_emailService = emailService;
}
// POST api/auth/register
// POST api/auth/register (interný endpoint — nie je vystavený vo frontende)
[HttpPost("register")]
public async Task<IActionResult> Register(RegisterRequest req)
{
if (await _db.Users.AnyAsync(u => u.Email == req.Email))
return BadRequest("Email je už registrovaný.");
if (await _db.Users.AnyAsync(u => u.Username == req.Username))
return BadRequest("Používateľské meno je obsadené.");
var user = new User
{
Username = req.Username,
Email = req.Email,
Email = req.Email,
PasswordHash = BCrypt.Net.BCrypt.HashPassword(req.Password)
};
_db.Users.Add(user);
await _db.SaveChangesAsync();
@@ -48,11 +48,90 @@ public class AuthController : ControllerBase
[HttpPost("login")]
public async Task<IActionResult> Login(LoginRequest req)
{
var user = await _db.Users.FirstOrDefaultAsync(u => u.Email == req.Email);
// Podpor prihlásenie cez email aj username
var user = await _db.Users.FirstOrDefaultAsync(u =>
u.Email == req.Email || u.Username == req.Email);
if (user is null || !BCrypt.Net.BCrypt.Verify(req.Password, user.PasswordHash))
return Unauthorized("Nesprávny email alebo heslo.");
return Unauthorized("Nesprávny email/meno alebo heslo.");
var token = _tokenService.GenerateToken(user);
return Ok(new AuthResponse(token, user.Username, user.Email));
}
// POST api/auth/send-reset-code
// Vygeneruje 8-znakový kód a odošle ho emailom (pre budúce použitie)
[HttpPost("send-reset-code")]
public async Task<IActionResult> SendResetCode([FromBody] SendResetCodeRequest req)
{
var user = await _db.Users.FirstOrDefaultAsync(u => u.Email == req.Email);
if (user is null)
return BadRequest("Email neexistuje.");
// Zneplatni staré tokeny
var old = _db.PasswordResetTokens.Where(t => t.Email == req.Email && !t.Used);
_db.PasswordResetTokens.RemoveRange(old);
// Vygeneruj nový 8-znakový kód
const string chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
var rng = new Random();
var code = new string(Enumerable.Range(0, 8).Select(_ => chars[rng.Next(chars.Length)]).ToArray());
_db.PasswordResetTokens.Add(new PasswordResetToken
{
Email = req.Email,
Code = code,
ExpiresAt = DateTime.UtcNow.AddMinutes(30),
Used = false
});
await _db.SaveChangesAsync();
await _emailService.SendAsync(req.Email, user.Username,
"🔑 Obnova hesla — Calendar Reminder",
$"""
<div style="font-family:Segoe UI,sans-serif;max-width:480px;margin:auto;background:#161b22;color:#e1e4e8;border-radius:10px;overflow:hidden">
<div style="background:#1f6feb;padding:1.2rem 1.5rem">
<h2 style="margin:0;color:#fff;font-size:1.1rem">🔑 Obnova hesla</h2>
</div>
<div style="padding:1.5rem">
<p style="margin:0 0 1rem">Tvoj kód na obnovu hesla:</p>
<div style="background:#0d1117;border:1px solid #30363d;border-radius:8px;padding:1rem;text-align:center;font-size:2rem;font-weight:700;letter-spacing:0.4rem;color:#58a6ff">{code}</div>
<p style="margin:1rem 0 0;color:#8b949e;font-size:0.85rem">Kód je platný 30 minút. Ak si o reset nepožiadal, ignoruj tento email.</p>
</div>
</div>
""");
return Ok("Kód bol odoslaný na email.");
}
// POST api/auth/reset-password
[HttpPost("reset-password")]
public async Task<IActionResult> ResetPassword([FromBody] ResetPasswordRequest req)
{
var user = await _db.Users.FirstOrDefaultAsync(u => u.Email == req.Email);
if (user is null)
return BadRequest("Email neexistuje.");
// Ak je kód zadaný — over ho
if (!string.IsNullOrEmpty(req.Code))
{
var resetToken = await _db.PasswordResetTokens
.Where(t => t.Email == req.Email && !t.Used && t.ExpiresAt > DateTime.UtcNow)
.OrderByDescending(t => t.ExpiresAt)
.FirstOrDefaultAsync();
if (resetToken is null || resetToken.Code != req.Code.ToUpper())
return BadRequest("Nesprávny alebo expirovaný kód.");
resetToken.Used = true;
}
user.PasswordHash = BCrypt.Net.BCrypt.HashPassword(req.NewPassword);
await _db.SaveChangesAsync();
return Ok("Heslo bolo úspešne zmenené.");
}
}
public record SendResetCodeRequest(string Email);
public record ResetPasswordRequest(string Email, string NewPassword, string? Code);