InitEshop+ddd+ca

This commit is contained in:
Matěj Kubíček
2026-07-16 18:33:05 +02:00
parent ffd8a087c8
commit 7e080eaef9
144 changed files with 972 additions and 1339 deletions
@@ -0,0 +1,206 @@
using System.Security.Claims;
using System.Text;
using System.Text.Json;
using Eshop.Application.Auth;
using Eshop.Web.ViewModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Eshop.Web.Controllers;
public class AuthController : Controller
{
private readonly ILogger<AuthController> _logger;
private readonly IAuthenticationService _authenticationService;
private readonly IUserAccountService _userAccountService;
public AuthController(
ILogger<AuthController> logger,
IAuthenticationService authenticationService,
IUserAccountService userAccountService)
{
_logger = logger;
_authenticationService = authenticationService;
_userAccountService = userAccountService;
}
#region HttpGet
[HttpGet]
[AllowAnonymous]
public IActionResult Login(string? returnUrl)
{
if (User.Identity?.IsAuthenticated == true)
return RedirectToAction("Index", "Home");
return View(new AuthLoginViewModel { ReturnUrl = returnUrl });
}
[HttpGet]
[AllowAnonymous]
public IActionResult Register(string? returnUrl)
{
if (User.Identity?.IsAuthenticated == true)
return RedirectToAction("Index", "Home");
return View(new AuthRegisterViewModel { ReturnUrl = returnUrl });
}
[HttpGet]
public IActionResult AccessDenied() => View();
[HttpGet]
[Authorize]
public async Task<IActionResult> Profile()
{
var userId = GetCurrentUserId();
if (userId is null) return RedirectToAction("Login");
var profile = await _userAccountService.GetProfileAsync(userId);
if (profile is null) return RedirectToAction("Login");
return View(new ProfileViewModel
{
UserName = profile.UserName,
Email = profile.Email,
});
}
#endregion
#region HttpPost
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(AuthLoginViewModel model)
{
if (!ModelState.IsValid) return View(model);
var result = await _authenticationService.SignInAsync(
model.EmailOrUsername, model.Password, model.RememberMe);
if (!result.Succeeded)
{
ModelState.AddModelError(string.Empty, "Invalid credentials.");
return View(model);
}
if (!string.IsNullOrEmpty(model.ReturnUrl) && Url.IsLocalUrl(model.ReturnUrl))
return Redirect(model.ReturnUrl);
return RedirectToAction("Index", "Home");
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Register(AuthRegisterViewModel model)
{
if (!ModelState.IsValid) return View(model);
var result = await _userAccountService.RegisterAsync(
model.UserName, model.Email, model.Password);
if (!result.Success)
{
foreach (var error in result.Errors)
ModelState.AddModelError(string.Empty, error);
return View(model);
}
_logger.LogInformation("User {UserName} registered.", model.UserName);
if (!string.IsNullOrEmpty(model.ReturnUrl) && Url.IsLocalUrl(model.ReturnUrl))
return Redirect(model.ReturnUrl);
return RedirectToAction("Login");
}
[HttpPost]
[Authorize]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Profile(ProfileViewModel model)
{
if (!ModelState.IsValid) return View(model);
var userId = GetCurrentUserId();
if (userId is null) return RedirectToAction("Login");
var result = await _userAccountService.UpdateProfileAsync(
userId,
new UpdateProfileRequest(
model.UserName,
model.Email,
model.CurrentPassword,
model.NewPassword));
if (!result.Success)
{
foreach (var error in result.Errors)
ModelState.AddModelError(string.Empty, error);
return View(model);
}
TempData["SuccessMessage"] = "Profile updated successfully.";
return RedirectToAction("Profile");
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Logout()
{
await _authenticationService.SignOutAsync();
return RedirectToAction("Index", "Home");
}
[HttpPost]
[Authorize]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteAccount()
{
var userId = GetCurrentUserId();
if (userId is null) return RedirectToAction("Login");
var result = await _userAccountService.DeleteAccountAsync(userId);
if (!result.Success)
{
foreach (var error in result.Errors)
ModelState.AddModelError(string.Empty, error);
return RedirectToAction("Profile");
}
_logger.LogInformation("User {UserId} deleted their account.", userId);
return RedirectToAction("Register");
}
[HttpGet]
[Authorize]
public async Task<IActionResult> DownloadData()
{
var userId = GetCurrentUserId();
if (userId is null) return RedirectToAction("Login");
var data = await _userAccountService.ExportUserDataAsync(userId);
if (data is null) return RedirectToAction("Login");
var export = new
{
data.Id,
data.UserName,
data.Email,
Roles = data.Roles,
data.ExportDate,
};
var json = JsonSerializer.Serialize(export, new JsonSerializerOptions { WriteIndented = true });
var bytes = Encoding.UTF8.GetBytes(json);
return File(bytes, "application/json", $"user_data_{data.UserName}.json");
}
#endregion
private string? GetCurrentUserId() =>
User.FindFirstValue(ClaimTypes.NameIdentifier);
}
@@ -0,0 +1,24 @@
using System.Diagnostics;
using Eshop.Web.ViewModels;
using Microsoft.AspNetCore.Mvc;
namespace Eshop.Web.Controllers;
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}