diff --git a/Template/TemplateWeb/Views/Auth/Profile.cshtml b/Eshop/Eshop.Web/Views/Auth/Profile.cshtml
similarity index 98%
rename from Template/TemplateWeb/Views/Auth/Profile.cshtml
rename to Eshop/Eshop.Web/Views/Auth/Profile.cshtml
index d8ac084..d9110ed 100644
--- a/Template/TemplateWeb/Views/Auth/Profile.cshtml
+++ b/Eshop/Eshop.Web/Views/Auth/Profile.cshtml
@@ -1,4 +1,4 @@
-@model ProfileViewModel
+@model Eshop.Web.ViewModels.ProfileViewModel
@{
ViewData["Title"] = "My Profile";
}
diff --git a/Template/TemplateWeb/Views/Auth/Register.cshtml b/Eshop/Eshop.Web/Views/Auth/Register.cshtml
similarity index 97%
rename from Template/TemplateWeb/Views/Auth/Register.cshtml
rename to Eshop/Eshop.Web/Views/Auth/Register.cshtml
index f7b4776..2fcfcf9 100644
--- a/Template/TemplateWeb/Views/Auth/Register.cshtml
+++ b/Eshop/Eshop.Web/Views/Auth/Register.cshtml
@@ -1,4 +1,4 @@
-@model AuthRegisterViewModel
+@model Eshop.Web.ViewModels.AuthRegisterViewModel
diff --git a/Template/TemplateWeb/Views/Home/Index.cshtml b/Eshop/Eshop.Web/Views/Home/Index.cshtml
similarity index 100%
rename from Template/TemplateWeb/Views/Home/Index.cshtml
rename to Eshop/Eshop.Web/Views/Home/Index.cshtml
diff --git a/Template/TemplateWeb/Views/Home/Privacy.cshtml b/Eshop/Eshop.Web/Views/Home/Privacy.cshtml
similarity index 100%
rename from Template/TemplateWeb/Views/Home/Privacy.cshtml
rename to Eshop/Eshop.Web/Views/Home/Privacy.cshtml
diff --git a/Template/TemplateWeb/Views/Shared/Error.cshtml b/Eshop/Eshop.Web/Views/Shared/Error.cshtml
similarity index 94%
rename from Template/TemplateWeb/Views/Shared/Error.cshtml
rename to Eshop/Eshop.Web/Views/Shared/Error.cshtml
index 4d96f6a..3e6fba4 100644
--- a/Template/TemplateWeb/Views/Shared/Error.cshtml
+++ b/Eshop/Eshop.Web/Views/Shared/Error.cshtml
@@ -1,4 +1,4 @@
-@model ErrorViewModel
+@model Eshop.Web.ViewModels.ErrorViewModel
@{
ViewData["Title"] = "Error";
}
diff --git a/Template/TemplateWeb/Views/Shared/_Layout.cshtml b/Eshop/Eshop.Web/Views/Shared/_Layout.cshtml
similarity index 100%
rename from Template/TemplateWeb/Views/Shared/_Layout.cshtml
rename to Eshop/Eshop.Web/Views/Shared/_Layout.cshtml
diff --git a/Template/TemplateWeb/Views/Shared/_Layout.cshtml.css b/Eshop/Eshop.Web/Views/Shared/_Layout.cshtml.css
similarity index 100%
rename from Template/TemplateWeb/Views/Shared/_Layout.cshtml.css
rename to Eshop/Eshop.Web/Views/Shared/_Layout.cshtml.css
diff --git a/Template/TemplateWeb/Views/Shared/_ValidationScriptsPartial.cshtml b/Eshop/Eshop.Web/Views/Shared/_ValidationScriptsPartial.cshtml
similarity index 100%
rename from Template/TemplateWeb/Views/Shared/_ValidationScriptsPartial.cshtml
rename to Eshop/Eshop.Web/Views/Shared/_ValidationScriptsPartial.cshtml
diff --git a/Template/TemplateWeb/Views/_ViewImports.cshtml b/Eshop/Eshop.Web/Views/_ViewImports.cshtml
similarity index 52%
rename from Template/TemplateWeb/Views/_ViewImports.cshtml
rename to Eshop/Eshop.Web/Views/_ViewImports.cshtml
index f84e040..8130715 100644
--- a/Template/TemplateWeb/Views/_ViewImports.cshtml
+++ b/Eshop/Eshop.Web/Views/_ViewImports.cshtml
@@ -1,3 +1,3 @@
-@using TemplateWeb
-@using TemplateWeb.Models
+@using Eshop.Web
+@using Eshop.Web.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
\ No newline at end of file
diff --git a/Template/TemplateWeb/Views/_ViewStart.cshtml b/Eshop/Eshop.Web/Views/_ViewStart.cshtml
similarity index 100%
rename from Template/TemplateWeb/Views/_ViewStart.cshtml
rename to Eshop/Eshop.Web/Views/_ViewStart.cshtml
diff --git a/Template/TemplateWeb/appsettings.Development.json b/Eshop/Eshop.Web/appsettings.Development.json
similarity index 100%
rename from Template/TemplateWeb/appsettings.Development.json
rename to Eshop/Eshop.Web/appsettings.Development.json
diff --git a/Template/TemplateWeb/appsettings.json b/Eshop/Eshop.Web/appsettings.json
similarity index 100%
rename from Template/TemplateWeb/appsettings.json
rename to Eshop/Eshop.Web/appsettings.json
diff --git a/Template/TemplateWeb/wwwroot/css/site.css b/Eshop/Eshop.Web/wwwroot/css/site.css
similarity index 100%
rename from Template/TemplateWeb/wwwroot/css/site.css
rename to Eshop/Eshop.Web/wwwroot/css/site.css
diff --git a/Template/TemplateWeb/wwwroot/favicon.ico b/Eshop/Eshop.Web/wwwroot/favicon.ico
similarity index 100%
rename from Template/TemplateWeb/wwwroot/favicon.ico
rename to Eshop/Eshop.Web/wwwroot/favicon.ico
diff --git a/Template/TemplateWeb/wwwroot/js/site.js b/Eshop/Eshop.Web/wwwroot/js/site.js
similarity index 100%
rename from Template/TemplateWeb/wwwroot/js/site.js
rename to Eshop/Eshop.Web/wwwroot/js/site.js
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/LICENSE b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/LICENSE
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/LICENSE
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/LICENSE
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css.map b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css.map
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css.map
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css.map b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css.map
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css.map
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css.map b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css.map
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css.map
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css.map b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css.map
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css.map
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css.map b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css.map
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css.map
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css.map b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css.map
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css.map
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css.map b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css.map
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css.map
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css.map b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css.map
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css.map
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap.css b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.css
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap.css
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.css
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap.css.map b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.css.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap.css.map
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.css.map
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css.map b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css.map
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css.map
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css.map b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css.map
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css.map
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js.map b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js.map
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js.map
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js.map b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js.map
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js.map
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.js b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.js
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.js
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.js
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.js.map b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.js.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.js.map
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.js.map
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js
diff --git a/Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map b/Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map
rename to Eshop/Eshop.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map
diff --git a/Template/TemplateWeb/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt b/Eshop/Eshop.Web/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt
rename to Eshop/Eshop.Web/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt
diff --git a/Template/TemplateWeb/wwwroot/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.js b/Eshop/Eshop.Web/wwwroot/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.js
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.js
rename to Eshop/Eshop.Web/wwwroot/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.js
diff --git a/Template/TemplateWeb/wwwroot/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js b/Eshop/Eshop.Web/wwwroot/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js
rename to Eshop/Eshop.Web/wwwroot/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js
diff --git a/Template/TemplateWeb/wwwroot/lib/jquery-validation/LICENSE.md b/Eshop/Eshop.Web/wwwroot/lib/jquery-validation/LICENSE.md
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/jquery-validation/LICENSE.md
rename to Eshop/Eshop.Web/wwwroot/lib/jquery-validation/LICENSE.md
diff --git a/Template/TemplateWeb/wwwroot/lib/jquery-validation/dist/additional-methods.js b/Eshop/Eshop.Web/wwwroot/lib/jquery-validation/dist/additional-methods.js
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/jquery-validation/dist/additional-methods.js
rename to Eshop/Eshop.Web/wwwroot/lib/jquery-validation/dist/additional-methods.js
diff --git a/Template/TemplateWeb/wwwroot/lib/jquery-validation/dist/additional-methods.min.js b/Eshop/Eshop.Web/wwwroot/lib/jquery-validation/dist/additional-methods.min.js
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/jquery-validation/dist/additional-methods.min.js
rename to Eshop/Eshop.Web/wwwroot/lib/jquery-validation/dist/additional-methods.min.js
diff --git a/Template/TemplateWeb/wwwroot/lib/jquery-validation/dist/jquery.validate.js b/Eshop/Eshop.Web/wwwroot/lib/jquery-validation/dist/jquery.validate.js
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/jquery-validation/dist/jquery.validate.js
rename to Eshop/Eshop.Web/wwwroot/lib/jquery-validation/dist/jquery.validate.js
diff --git a/Template/TemplateWeb/wwwroot/lib/jquery-validation/dist/jquery.validate.min.js b/Eshop/Eshop.Web/wwwroot/lib/jquery-validation/dist/jquery.validate.min.js
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/jquery-validation/dist/jquery.validate.min.js
rename to Eshop/Eshop.Web/wwwroot/lib/jquery-validation/dist/jquery.validate.min.js
diff --git a/Template/TemplateWeb/wwwroot/lib/jquery/LICENSE.txt b/Eshop/Eshop.Web/wwwroot/lib/jquery/LICENSE.txt
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/jquery/LICENSE.txt
rename to Eshop/Eshop.Web/wwwroot/lib/jquery/LICENSE.txt
diff --git a/Template/TemplateWeb/wwwroot/lib/jquery/dist/jquery.js b/Eshop/Eshop.Web/wwwroot/lib/jquery/dist/jquery.js
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/jquery/dist/jquery.js
rename to Eshop/Eshop.Web/wwwroot/lib/jquery/dist/jquery.js
diff --git a/Template/TemplateWeb/wwwroot/lib/jquery/dist/jquery.min.js b/Eshop/Eshop.Web/wwwroot/lib/jquery/dist/jquery.min.js
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/jquery/dist/jquery.min.js
rename to Eshop/Eshop.Web/wwwroot/lib/jquery/dist/jquery.min.js
diff --git a/Template/TemplateWeb/wwwroot/lib/jquery/dist/jquery.min.map b/Eshop/Eshop.Web/wwwroot/lib/jquery/dist/jquery.min.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/jquery/dist/jquery.min.map
rename to Eshop/Eshop.Web/wwwroot/lib/jquery/dist/jquery.min.map
diff --git a/Template/TemplateWeb/wwwroot/lib/jquery/dist/jquery.slim.js b/Eshop/Eshop.Web/wwwroot/lib/jquery/dist/jquery.slim.js
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/jquery/dist/jquery.slim.js
rename to Eshop/Eshop.Web/wwwroot/lib/jquery/dist/jquery.slim.js
diff --git a/Template/TemplateWeb/wwwroot/lib/jquery/dist/jquery.slim.min.js b/Eshop/Eshop.Web/wwwroot/lib/jquery/dist/jquery.slim.min.js
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/jquery/dist/jquery.slim.min.js
rename to Eshop/Eshop.Web/wwwroot/lib/jquery/dist/jquery.slim.min.js
diff --git a/Template/TemplateWeb/wwwroot/lib/jquery/dist/jquery.slim.min.map b/Eshop/Eshop.Web/wwwroot/lib/jquery/dist/jquery.slim.min.map
similarity index 100%
rename from Template/TemplateWeb/wwwroot/lib/jquery/dist/jquery.slim.min.map
rename to Eshop/Eshop.Web/wwwroot/lib/jquery/dist/jquery.slim.min.map
diff --git a/Eshop/Eshop.slnx b/Eshop/Eshop.slnx
new file mode 100644
index 0000000..eb37532
--- /dev/null
+++ b/Eshop/Eshop.slnx
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Eshop/WebTests/AuthServiceTests.cs b/Eshop/WebTests/AuthServiceTests.cs
new file mode 100644
index 0000000..60e156f
--- /dev/null
+++ b/Eshop/WebTests/AuthServiceTests.cs
@@ -0,0 +1,111 @@
+using Eshop.Application.Auth;
+using Eshop.Infrastructure;
+using Eshop.Infrastructure.Persistence;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace WebTests;
+
+[TestClass]
+public class AuthServiceTests
+{
+ private ServiceProvider _serviceProvider = null!;
+ private IAuthenticationService _authenticationService = null!;
+ private IUserAccountService _userAccountService = null!;
+
+ [TestInitialize]
+ public void Initialize()
+ {
+ var services = new ServiceCollection();
+
+ services.AddLogging();
+ services.AddSingleton
();
+
+ services.AddDbContext(options =>
+ options.UseInMemoryDatabase(Guid.NewGuid().ToString()));
+
+ services.AddIdentity()
+ .AddEntityFrameworkStores()
+ .AddDefaultTokenProviders();
+
+ services.AddInfrastructure();
+
+ _serviceProvider = services.BuildServiceProvider();
+
+ var httpContext = new DefaultHttpContext { RequestServices = _serviceProvider };
+ _serviceProvider.GetRequiredService().HttpContext = httpContext;
+
+ var roleManager = _serviceProvider.GetRequiredService>();
+ foreach (var role in new[] { "Admin", "User" })
+ {
+ if (!roleManager.RoleExistsAsync(role).GetAwaiter().GetResult())
+ roleManager.CreateAsync(new IdentityRole(role)).GetAwaiter().GetResult();
+ }
+
+ _authenticationService = _serviceProvider.GetRequiredService();
+ _userAccountService = _serviceProvider.GetRequiredService();
+ }
+
+ [TestCleanup]
+ public void Cleanup()
+ {
+ _serviceProvider.Dispose();
+ }
+
+ [TestMethod]
+ public async Task RegisterAsync_ShouldReturnSuccess_WhenUserIsNew()
+ {
+ var result = await _userAccountService.RegisterAsync("testuser", "test@example.com", "Password123!");
+
+ Assert.IsTrue(result.Success);
+
+ var profile = await _userAccountService.GetProfileAsync(
+ (await _serviceProvider.GetRequiredService>()
+ .FindByNameAsync("testuser"))!.Id);
+
+ Assert.IsNotNull(profile);
+ Assert.AreEqual("testuser", profile.UserName);
+ Assert.AreEqual("test@example.com", profile.Email);
+ }
+
+ [TestMethod]
+ public async Task RegisterAsync_ShouldReturnFailure_WhenUsernameAlreadyExists()
+ {
+ await _userAccountService.RegisterAsync("existing", "existing@example.com", "Password123!");
+
+ var result = await _userAccountService.RegisterAsync("existing", "other@example.com", "Password123!");
+
+ Assert.IsFalse(result.Success);
+ Assert.IsTrue(result.Errors.Any(e => e.Contains("already taken", StringComparison.OrdinalIgnoreCase)));
+ }
+
+ [TestMethod]
+ public async Task SignInAsync_ShouldReturnSuccess_WithValidCredentials()
+ {
+ await _userAccountService.RegisterAsync("testuser", "test@example.com", "Password123!");
+
+ var result = await _authenticationService.SignInAsync("testuser", "Password123!", rememberMe: false);
+
+ Assert.IsTrue(result.Succeeded);
+ }
+
+ [TestMethod]
+ public async Task SignInAsync_ShouldReturnFailure_WithInvalidCredentials()
+ {
+ await _userAccountService.RegisterAsync("testuser", "test@example.com", "Password123!");
+
+ var result = await _authenticationService.SignInAsync("testuser", "WrongPassword!", rememberMe: false);
+
+ Assert.IsFalse(result.Succeeded);
+ }
+
+ [TestMethod]
+ public async Task SignInAsync_ShouldReturnFailure_WhenUserNotFound()
+ {
+ var result = await _authenticationService.SignInAsync("nonexistent", "Password123!", rememberMe: false);
+
+ Assert.IsFalse(result.Succeeded);
+ }
+}
diff --git a/Template/WebTests/MSTestSettings.cs b/Eshop/WebTests/MSTestSettings.cs
similarity index 100%
rename from Template/WebTests/MSTestSettings.cs
rename to Eshop/WebTests/MSTestSettings.cs
diff --git a/Template/WebTests/TestClassExample.cs b/Eshop/WebTests/TestClassExample.cs
similarity index 97%
rename from Template/WebTests/TestClassExample.cs
rename to Eshop/WebTests/TestClassExample.cs
index 7dbc94c..3411fad 100644
--- a/Template/WebTests/TestClassExample.cs
+++ b/Eshop/WebTests/TestClassExample.cs
@@ -1,5 +1,5 @@
using Microsoft.EntityFrameworkCore;
-using TemplateWeb.Data;
+using Eshop.Infrastructure;
namespace WebTests;
diff --git a/Template/WebTests/WebTests.csproj b/Eshop/WebTests/WebTests.csproj
similarity index 68%
rename from Template/WebTests/WebTests.csproj
rename to Eshop/WebTests/WebTests.csproj
index 121f38e..164a9ea 100644
--- a/Template/WebTests/WebTests.csproj
+++ b/Eshop/WebTests/WebTests.csproj
@@ -8,12 +8,11 @@
-
-
-
-
+
+
+
-
+
@@ -21,7 +20,8 @@
-
+
+
diff --git a/Template/compose.yaml b/Eshop/compose.yaml
similarity index 100%
rename from Template/compose.yaml
rename to Eshop/compose.yaml
diff --git a/Template/Template.slnx b/Template/Template.slnx
deleted file mode 100644
index c5a6adc..0000000
--- a/Template/Template.slnx
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/Template/TemplateWeb/Areas/Admin/Controllers/UsersController.cs b/Template/TemplateWeb/Areas/Admin/Controllers/UsersController.cs
deleted file mode 100644
index 57a65c9..0000000
--- a/Template/TemplateWeb/Areas/Admin/Controllers/UsersController.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using Microsoft.AspNetCore.Identity;
-using Microsoft.AspNetCore.Mvc;
-using TemplateWeb.Entities;
-using TemplateWeb.Models;
-
-namespace TemplateWeb.Areas.Admin.Controllers;
-
-public class UsersController : AdminBaseController
-{
- private readonly UserManager _userManager;
- private readonly RoleManager _roleManager;
-
- public UsersController(UserManager userManager, RoleManager roleManager)
- {
- _userManager = userManager;
- _roleManager = roleManager;
- }
-
- public async Task Index()
- {
- var allRoles = _roleManager.Roles.Select(r => r.Name!).ToList();
- var users = _userManager.Users.ToList();
- var viewModels = new List();
- foreach (var user in users)
- {
- var roles = await _userManager.GetRolesAsync(user);
- viewModels.Add(new UserWithRolesViewModel { UserEntity = user, Roles = roles, AllRoles = allRoles });
- }
- return View(viewModels);
- }
-
- public async Task Details(string id)
- {
- var user = await _userManager.FindByIdAsync(id);
- if (user == null) return NotFound();
-
- var roles = await _userManager.GetRolesAsync(user);
- var allRoles = _roleManager.Roles.Select(r => r.Name!).ToList();
- return View(new UserWithRolesViewModel { UserEntity = user, Roles = roles, AllRoles = allRoles });
- }
-
- [HttpPost]
- [ValidateAntiForgeryToken]
- public async Task UpdateRoles(string id, List selectedRoles)
- {
- var user = await _userManager.FindByIdAsync(id);
- if (user == null) return NotFound();
-
- var currentRoles = await _userManager.GetRolesAsync(user);
- await _userManager.RemoveFromRolesAsync(user, currentRoles);
- if (selectedRoles.Count > 0)
- await _userManager.AddToRolesAsync(user, selectedRoles);
-
- TempData["SuccessMessage"] = "Roles updated successfully.";
- return RedirectToAction(nameof(Details), new { id });
- }
-}
diff --git a/Template/TemplateWeb/Areas/Admin/Views/_ViewImports.cshtml b/Template/TemplateWeb/Areas/Admin/Views/_ViewImports.cshtml
deleted file mode 100644
index 1d6fbe7..0000000
--- a/Template/TemplateWeb/Areas/Admin/Views/_ViewImports.cshtml
+++ /dev/null
@@ -1,3 +0,0 @@
-@using TemplateWeb
-@using TemplateWeb.Models
-@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
diff --git a/Template/TemplateWeb/Controllers/AuthController.cs b/Template/TemplateWeb/Controllers/AuthController.cs
deleted file mode 100644
index 692a0f3..0000000
--- a/Template/TemplateWeb/Controllers/AuthController.cs
+++ /dev/null
@@ -1,240 +0,0 @@
-using System.Text;
-using System.Text.Json;
-using Microsoft.AspNetCore.Authorization;
-using Microsoft.AspNetCore.Identity;
-using Microsoft.AspNetCore.Mvc;
-using TemplateWeb.Entities;
-using TemplateWeb.Models;
-
-namespace TemplateWeb.Controllers;
-
-public class AuthController : Controller
-{
- private readonly ILogger _logger;
- private readonly UserManager _userManager;
- private readonly SignInManager _signInManager;
-
- public AuthController(
- ILogger logger,
- UserManager userManager,
- SignInManager signInManager)
- {
- _logger = logger;
- _userManager = userManager;
- _signInManager = signInManager;
- }
-
- #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 Profile()
- {
- var user = await _userManager.GetUserAsync(User);
- if (user == null) return RedirectToAction("Login");
-
- return View(new ProfileViewModel
- {
- UserName = user.UserName!,
- Email = user.Email!,
- });
- }
-
- #endregion
-
- #region HttpPost
-
- [HttpPost]
- [AllowAnonymous]
- [ValidateAntiForgeryToken]
- public async Task Login(AuthLoginViewModel model)
- {
- if (!ModelState.IsValid) return View(model);
-
- // Support login by email or username
- var user = model.EmailOrUsername.Contains('@')
- ? await _userManager.FindByEmailAsync(model.EmailOrUsername)
- : await _userManager.FindByNameAsync(model.EmailOrUsername);
-
- if (user == null)
- {
- ModelState.AddModelError(string.Empty, "Invalid credentials.");
- return View(model);
- }
-
- var result = await _signInManager.PasswordSignInAsync(
- user, model.Password, model.RememberMe, lockoutOnFailure: false);
-
- 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 Register(AuthRegisterViewModel model)
- {
- if (!ModelState.IsValid) return View(model);
-
- var user = new UserEntity
- {
- UserName = model.UserName.Trim(),
- Email = model.Email.Trim().ToLower(),
- };
-
- var result = await _userManager.CreateAsync(user, model.Password);
- if (!result.Succeeded)
- {
- foreach (var error in result.Errors)
- ModelState.AddModelError(string.Empty, error.Description);
- return View(model);
- }
-
- await _userManager.AddToRoleAsync(user, "User");
- _logger.LogInformation("User {UserName} registered.", user.UserName);
-
- if (!string.IsNullOrEmpty(model.ReturnUrl) && Url.IsLocalUrl(model.ReturnUrl))
- return Redirect(model.ReturnUrl);
-
- return RedirectToAction("Login");
- }
-
- [HttpPost]
- [Authorize]
- [ValidateAntiForgeryToken]
- public async Task Profile(ProfileViewModel model)
- {
- if (!ModelState.IsValid) return View(model);
-
- var user = await _userManager.GetUserAsync(User);
- if (user == null) return RedirectToAction("Login");
-
- // Update username
- if (user.UserName != model.UserName.Trim())
- {
- var setName = await _userManager.SetUserNameAsync(user, model.UserName.Trim());
- if (!setName.Succeeded)
- {
- foreach (var e in setName.Errors)
- ModelState.AddModelError(string.Empty, e.Description);
- return View(model);
- }
- }
-
- // Update email
- if (user.Email != model.Email.Trim().ToLower())
- {
- var setEmail = await _userManager.SetEmailAsync(user, model.Email.Trim().ToLower());
- if (!setEmail.Succeeded)
- {
- foreach (var e in setEmail.Errors)
- ModelState.AddModelError(string.Empty, e.Description);
- return View(model);
- }
- }
-
- // Change password (requires current password)
- if (!string.IsNullOrWhiteSpace(model.NewPassword))
- {
- if (string.IsNullOrWhiteSpace(model.CurrentPassword))
- {
- ModelState.AddModelError(nameof(model.CurrentPassword), "Current password is required to set a new password.");
- return View(model);
- }
-
- var changePassword = await _userManager.ChangePasswordAsync(user, model.CurrentPassword, model.NewPassword);
- if (!changePassword.Succeeded)
- {
- foreach (var e in changePassword.Errors)
- ModelState.AddModelError(string.Empty, e.Description);
- return View(model);
- }
- }
-
- // Refresh cookie so the user stays logged in after security-stamp changes
- await _signInManager.RefreshSignInAsync(user);
-
- TempData["SuccessMessage"] = "Profile updated successfully.";
- return RedirectToAction("Profile");
- }
-
- [HttpPost]
- [ValidateAntiForgeryToken]
- public async Task Logout()
- {
- await _signInManager.SignOutAsync();
- return RedirectToAction("Index", "Home");
- }
-
- [HttpPost]
- [Authorize]
- [ValidateAntiForgeryToken]
- public async Task DeleteAccount()
- {
- var user = await _userManager.GetUserAsync(User);
- if (user == null) return RedirectToAction("Login");
-
- await _signInManager.SignOutAsync();
- await _userManager.DeleteAsync(user);
- _logger.LogInformation("User {UserId} deleted their account.", user.Id);
-
- return RedirectToAction("Register");
- }
-
- [HttpGet]
- [Authorize]
- public async Task DownloadData()
- {
- var user = await _userManager.GetUserAsync(User);
- if (user == null) return RedirectToAction("Login");
-
- var roles = await _userManager.GetRolesAsync(user);
-
- var data = new
- {
- user.Id,
- user.UserName,
- user.Email,
- Roles = roles,
- ExportDate = DateTime.UtcNow,
- };
-
- var json = JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true });
- var bytes = Encoding.UTF8.GetBytes(json);
-
- return File(bytes, "application/json", $"user_data_{user.UserName}.json");
- }
-
- #endregion
-}
diff --git a/Template/TemplateWeb/Migrations/20260501160159_SwitchToIdentity.Designer.cs b/Template/TemplateWeb/Migrations/20260501160159_SwitchToIdentity.Designer.cs
deleted file mode 100644
index 848312d..0000000
--- a/Template/TemplateWeb/Migrations/20260501160159_SwitchToIdentity.Designer.cs
+++ /dev/null
@@ -1,277 +0,0 @@
-//
-using System;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Migrations;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
-using TemplateWeb.Data;
-
-#nullable disable
-
-namespace TemplateWeb.Migrations
-{
- [DbContext(typeof(AppDbContext))]
- [Migration("20260501160159_SwitchToIdentity")]
- partial class SwitchToIdentity
- {
- ///
- protected override void BuildTargetModel(ModelBuilder modelBuilder)
- {
-#pragma warning disable 612, 618
- modelBuilder
- .HasAnnotation("ProductVersion", "10.0.6")
- .HasAnnotation("Relational:MaxIdentifierLength", 63);
-
- NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
-
- modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
- {
- b.Property("Id")
- .HasColumnType("text");
-
- b.Property("ConcurrencyStamp")
- .IsConcurrencyToken()
- .HasColumnType("text");
-
- b.Property("Name")
- .HasMaxLength(256)
- .HasColumnType("character varying(256)");
-
- b.Property("NormalizedName")
- .HasMaxLength(256)
- .HasColumnType("character varying(256)");
-
- b.HasKey("Id");
-
- b.HasIndex("NormalizedName")
- .IsUnique()
- .HasDatabaseName("RoleNameIndex");
-
- b.ToTable("AspNetRoles", (string)null);
- });
-
- modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("integer");
-
- NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
-
- b.Property("ClaimType")
- .HasColumnType("text");
-
- b.Property("ClaimValue")
- .HasColumnType("text");
-
- b.Property("RoleId")
- .IsRequired()
- .HasColumnType("text");
-
- b.HasKey("Id");
-
- b.HasIndex("RoleId");
-
- b.ToTable("AspNetRoleClaims", (string)null);
- });
-
- modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("integer");
-
- NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
-
- b.Property("ClaimType")
- .HasColumnType("text");
-
- b.Property("ClaimValue")
- .HasColumnType("text");
-
- b.Property("UserId")
- .IsRequired()
- .HasColumnType("text");
-
- b.HasKey("Id");
-
- b.HasIndex("UserId");
-
- b.ToTable("AspNetUserClaims", (string)null);
- });
-
- modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
- {
- b.Property("LoginProvider")
- .HasColumnType("text");
-
- b.Property("ProviderKey")
- .HasColumnType("text");
-
- b.Property("ProviderDisplayName")
- .HasColumnType("text");
-
- b.Property("UserId")
- .IsRequired()
- .HasColumnType("text");
-
- b.HasKey("LoginProvider", "ProviderKey");
-
- b.HasIndex("UserId");
-
- b.ToTable("AspNetUserLogins", (string)null);
- });
-
- modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
- {
- b.Property("UserId")
- .HasColumnType("text");
-
- b.Property("RoleId")
- .HasColumnType("text");
-
- b.HasKey("UserId", "RoleId");
-
- b.HasIndex("RoleId");
-
- b.ToTable("AspNetUserRoles", (string)null);
- });
-
- modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
- {
- b.Property("UserId")
- .HasColumnType("text");
-
- b.Property("LoginProvider")
- .HasColumnType("text");
-
- b.Property("Name")
- .HasColumnType("text");
-
- b.Property("Value")
- .HasColumnType("text");
-
- b.HasKey("UserId", "LoginProvider", "Name");
-
- b.ToTable("AspNetUserTokens", (string)null);
- });
-
- modelBuilder.Entity("TemplateWeb.Entities.UserEntity", b =>
- {
- b.Property("Id")
- .HasColumnType("text");
-
- b.Property("AccessFailedCount")
- .HasColumnType("integer");
-
- b.Property("ConcurrencyStamp")
- .IsConcurrencyToken()
- .HasColumnType("text");
-
- b.Property("Email")
- .HasMaxLength(256)
- .HasColumnType("character varying(256)");
-
- b.Property("EmailConfirmed")
- .HasColumnType("boolean");
-
- b.Property("LockoutEnabled")
- .HasColumnType("boolean");
-
- b.Property("LockoutEnd")
- .HasColumnType("timestamp with time zone");
-
- b.Property("NormalizedEmail")
- .HasMaxLength(256)
- .HasColumnType("character varying(256)");
-
- b.Property("NormalizedUserName")
- .HasMaxLength(256)
- .HasColumnType("character varying(256)");
-
- b.Property("PasswordHash")
- .HasColumnType("text");
-
- b.Property("PhoneNumber")
- .HasColumnType("text");
-
- b.Property("PhoneNumberConfirmed")
- .HasColumnType("boolean");
-
- b.Property("SecurityStamp")
- .HasColumnType("text");
-
- b.Property("TwoFactorEnabled")
- .HasColumnType("boolean");
-
- b.Property("UserName")
- .HasMaxLength(256)
- .HasColumnType("character varying(256)");
-
- b.HasKey("Id");
-
- b.HasIndex("NormalizedEmail")
- .HasDatabaseName("EmailIndex");
-
- b.HasIndex("NormalizedUserName")
- .IsUnique()
- .HasDatabaseName("UserNameIndex");
-
- b.ToTable("AspNetUsers", (string)null);
- });
-
- modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
- {
- b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
- .WithMany()
- .HasForeignKey("RoleId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-
- modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
- {
- b.HasOne("TemplateWeb.Entities.UserEntity", null)
- .WithMany()
- .HasForeignKey("UserId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-
- modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
- {
- b.HasOne("TemplateWeb.Entities.UserEntity", null)
- .WithMany()
- .HasForeignKey("UserId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-
- modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
- {
- b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
- .WithMany()
- .HasForeignKey("RoleId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.HasOne("TemplateWeb.Entities.UserEntity", null)
- .WithMany()
- .HasForeignKey("UserId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-
- modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
- {
- b.HasOne("TemplateWeb.Entities.UserEntity", null)
- .WithMany()
- .HasForeignKey("UserId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-#pragma warning restore 612, 618
- }
- }
-}
diff --git a/Template/TemplateWeb/Migrations/20260501160159_SwitchToIdentity.cs b/Template/TemplateWeb/Migrations/20260501160159_SwitchToIdentity.cs
deleted file mode 100644
index a9ce1e3..0000000
--- a/Template/TemplateWeb/Migrations/20260501160159_SwitchToIdentity.cs
+++ /dev/null
@@ -1,223 +0,0 @@
-using System;
-using Microsoft.EntityFrameworkCore.Migrations;
-using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
-
-#nullable disable
-
-namespace TemplateWeb.Migrations
-{
- ///
- public partial class SwitchToIdentity : Migration
- {
- ///
- protected override void Up(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.CreateTable(
- name: "AspNetRoles",
- columns: table => new
- {
- Id = table.Column(type: "text", nullable: false),
- Name = table.Column(type: "character varying(256)", maxLength: 256, nullable: true),
- NormalizedName = table.Column(type: "character varying(256)", maxLength: 256, nullable: true),
- ConcurrencyStamp = table.Column(type: "text", nullable: true)
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_AspNetRoles", x => x.Id);
- });
-
- migrationBuilder.CreateTable(
- name: "AspNetUsers",
- columns: table => new
- {
- Id = table.Column(type: "text", nullable: false),
- UserName = table.Column(type: "character varying(256)", maxLength: 256, nullable: true),
- NormalizedUserName = table.Column(type: "character varying(256)", maxLength: 256, nullable: true),
- Email = table.Column(type: "character varying(256)", maxLength: 256, nullable: true),
- NormalizedEmail = table.Column(type: "character varying(256)", maxLength: 256, nullable: true),
- EmailConfirmed = table.Column(type: "boolean", nullable: false),
- PasswordHash = table.Column(type: "text", nullable: true),
- SecurityStamp = table.Column(type: "text", nullable: true),
- ConcurrencyStamp = table.Column(type: "text", nullable: true),
- PhoneNumber = table.Column(type: "text", nullable: true),
- PhoneNumberConfirmed = table.Column(type: "boolean", nullable: false),
- TwoFactorEnabled = table.Column(type: "boolean", nullable: false),
- LockoutEnd = table.Column(type: "timestamp with time zone", nullable: true),
- LockoutEnabled = table.Column(type: "boolean", nullable: false),
- AccessFailedCount = table.Column(type: "integer", nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_AspNetUsers", x => x.Id);
- });
-
- migrationBuilder.CreateTable(
- name: "AspNetRoleClaims",
- columns: table => new
- {
- Id = table.Column(type: "integer", nullable: false)
- .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
- RoleId = table.Column(type: "text", nullable: false),
- ClaimType = table.Column(type: "text", nullable: true),
- ClaimValue = table.Column(type: "text", nullable: true)
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
- table.ForeignKey(
- name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
- column: x => x.RoleId,
- principalTable: "AspNetRoles",
- principalColumn: "Id",
- onDelete: ReferentialAction.Cascade);
- });
-
- migrationBuilder.CreateTable(
- name: "AspNetUserClaims",
- columns: table => new
- {
- Id = table.Column(type: "integer", nullable: false)
- .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
- UserId = table.Column(type: "text", nullable: false),
- ClaimType = table.Column(type: "text", nullable: true),
- ClaimValue = table.Column(type: "text", nullable: true)
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
- table.ForeignKey(
- name: "FK_AspNetUserClaims_AspNetUsers_UserId",
- column: x => x.UserId,
- principalTable: "AspNetUsers",
- principalColumn: "Id",
- onDelete: ReferentialAction.Cascade);
- });
-
- migrationBuilder.CreateTable(
- name: "AspNetUserLogins",
- columns: table => new
- {
- LoginProvider = table.Column(type: "text", nullable: false),
- ProviderKey = table.Column(type: "text", nullable: false),
- ProviderDisplayName = table.Column(type: "text", nullable: true),
- UserId = table.Column(type: "text", nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
- table.ForeignKey(
- name: "FK_AspNetUserLogins_AspNetUsers_UserId",
- column: x => x.UserId,
- principalTable: "AspNetUsers",
- principalColumn: "Id",
- onDelete: ReferentialAction.Cascade);
- });
-
- migrationBuilder.CreateTable(
- name: "AspNetUserRoles",
- columns: table => new
- {
- UserId = table.Column(type: "text", nullable: false),
- RoleId = table.Column(type: "text", nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
- table.ForeignKey(
- name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
- column: x => x.RoleId,
- principalTable: "AspNetRoles",
- principalColumn: "Id",
- onDelete: ReferentialAction.Cascade);
- table.ForeignKey(
- name: "FK_AspNetUserRoles_AspNetUsers_UserId",
- column: x => x.UserId,
- principalTable: "AspNetUsers",
- principalColumn: "Id",
- onDelete: ReferentialAction.Cascade);
- });
-
- migrationBuilder.CreateTable(
- name: "AspNetUserTokens",
- columns: table => new
- {
- UserId = table.Column(type: "text", nullable: false),
- LoginProvider = table.Column(type: "text", nullable: false),
- Name = table.Column(type: "text", nullable: false),
- Value = table.Column(type: "text", nullable: true)
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
- table.ForeignKey(
- name: "FK_AspNetUserTokens_AspNetUsers_UserId",
- column: x => x.UserId,
- principalTable: "AspNetUsers",
- principalColumn: "Id",
- onDelete: ReferentialAction.Cascade);
- });
-
- migrationBuilder.CreateIndex(
- name: "IX_AspNetRoleClaims_RoleId",
- table: "AspNetRoleClaims",
- column: "RoleId");
-
- migrationBuilder.CreateIndex(
- name: "RoleNameIndex",
- table: "AspNetRoles",
- column: "NormalizedName",
- unique: true);
-
- migrationBuilder.CreateIndex(
- name: "IX_AspNetUserClaims_UserId",
- table: "AspNetUserClaims",
- column: "UserId");
-
- migrationBuilder.CreateIndex(
- name: "IX_AspNetUserLogins_UserId",
- table: "AspNetUserLogins",
- column: "UserId");
-
- migrationBuilder.CreateIndex(
- name: "IX_AspNetUserRoles_RoleId",
- table: "AspNetUserRoles",
- column: "RoleId");
-
- migrationBuilder.CreateIndex(
- name: "EmailIndex",
- table: "AspNetUsers",
- column: "NormalizedEmail");
-
- migrationBuilder.CreateIndex(
- name: "UserNameIndex",
- table: "AspNetUsers",
- column: "NormalizedUserName",
- unique: true);
- }
-
- ///
- protected override void Down(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.DropTable(
- name: "AspNetRoleClaims");
-
- migrationBuilder.DropTable(
- name: "AspNetUserClaims");
-
- migrationBuilder.DropTable(
- name: "AspNetUserLogins");
-
- migrationBuilder.DropTable(
- name: "AspNetUserRoles");
-
- migrationBuilder.DropTable(
- name: "AspNetUserTokens");
-
- migrationBuilder.DropTable(
- name: "AspNetRoles");
-
- migrationBuilder.DropTable(
- name: "AspNetUsers");
- }
- }
-}
diff --git a/Template/TemplateWeb/Migrations/AppDbContextModelSnapshot.cs b/Template/TemplateWeb/Migrations/AppDbContextModelSnapshot.cs
deleted file mode 100644
index 05b0b72..0000000
--- a/Template/TemplateWeb/Migrations/AppDbContextModelSnapshot.cs
+++ /dev/null
@@ -1,274 +0,0 @@
-//
-using System;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
-using TemplateWeb.Data;
-
-#nullable disable
-
-namespace TemplateWeb.Migrations
-{
- [DbContext(typeof(AppDbContext))]
- partial class AppDbContextModelSnapshot : ModelSnapshot
- {
- protected override void BuildModel(ModelBuilder modelBuilder)
- {
-#pragma warning disable 612, 618
- modelBuilder
- .HasAnnotation("ProductVersion", "10.0.6")
- .HasAnnotation("Relational:MaxIdentifierLength", 63);
-
- NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
-
- modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
- {
- b.Property("Id")
- .HasColumnType("text");
-
- b.Property("ConcurrencyStamp")
- .IsConcurrencyToken()
- .HasColumnType("text");
-
- b.Property("Name")
- .HasMaxLength(256)
- .HasColumnType("character varying(256)");
-
- b.Property("NormalizedName")
- .HasMaxLength(256)
- .HasColumnType("character varying(256)");
-
- b.HasKey("Id");
-
- b.HasIndex("NormalizedName")
- .IsUnique()
- .HasDatabaseName("RoleNameIndex");
-
- b.ToTable("AspNetRoles", (string)null);
- });
-
- modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("integer");
-
- NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
-
- b.Property("ClaimType")
- .HasColumnType("text");
-
- b.Property("ClaimValue")
- .HasColumnType("text");
-
- b.Property("RoleId")
- .IsRequired()
- .HasColumnType("text");
-
- b.HasKey("Id");
-
- b.HasIndex("RoleId");
-
- b.ToTable("AspNetRoleClaims", (string)null);
- });
-
- modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("integer");
-
- NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
-
- b.Property("ClaimType")
- .HasColumnType("text");
-
- b.Property("ClaimValue")
- .HasColumnType("text");
-
- b.Property("UserId")
- .IsRequired()
- .HasColumnType("text");
-
- b.HasKey("Id");
-
- b.HasIndex("UserId");
-
- b.ToTable("AspNetUserClaims", (string)null);
- });
-
- modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
- {
- b.Property("LoginProvider")
- .HasColumnType("text");
-
- b.Property("ProviderKey")
- .HasColumnType("text");
-
- b.Property("ProviderDisplayName")
- .HasColumnType("text");
-
- b.Property("UserId")
- .IsRequired()
- .HasColumnType("text");
-
- b.HasKey("LoginProvider", "ProviderKey");
-
- b.HasIndex("UserId");
-
- b.ToTable("AspNetUserLogins", (string)null);
- });
-
- modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
- {
- b.Property("UserId")
- .HasColumnType("text");
-
- b.Property("RoleId")
- .HasColumnType("text");
-
- b.HasKey("UserId", "RoleId");
-
- b.HasIndex("RoleId");
-
- b.ToTable("AspNetUserRoles", (string)null);
- });
-
- modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
- {
- b.Property("UserId")
- .HasColumnType("text");
-
- b.Property("LoginProvider")
- .HasColumnType("text");
-
- b.Property("Name")
- .HasColumnType("text");
-
- b.Property("Value")
- .HasColumnType("text");
-
- b.HasKey("UserId", "LoginProvider", "Name");
-
- b.ToTable("AspNetUserTokens", (string)null);
- });
-
- modelBuilder.Entity("TemplateWeb.Entities.UserEntity", b =>
- {
- b.Property("Id")
- .HasColumnType("text");
-
- b.Property("AccessFailedCount")
- .HasColumnType("integer");
-
- b.Property("ConcurrencyStamp")
- .IsConcurrencyToken()
- .HasColumnType("text");
-
- b.Property("Email")
- .HasMaxLength(256)
- .HasColumnType("character varying(256)");
-
- b.Property("EmailConfirmed")
- .HasColumnType("boolean");
-
- b.Property("LockoutEnabled")
- .HasColumnType("boolean");
-
- b.Property("LockoutEnd")
- .HasColumnType("timestamp with time zone");
-
- b.Property("NormalizedEmail")
- .HasMaxLength(256)
- .HasColumnType("character varying(256)");
-
- b.Property("NormalizedUserName")
- .HasMaxLength(256)
- .HasColumnType("character varying(256)");
-
- b.Property("PasswordHash")
- .HasColumnType("text");
-
- b.Property("PhoneNumber")
- .HasColumnType("text");
-
- b.Property("PhoneNumberConfirmed")
- .HasColumnType("boolean");
-
- b.Property("SecurityStamp")
- .HasColumnType("text");
-
- b.Property("TwoFactorEnabled")
- .HasColumnType("boolean");
-
- b.Property("UserName")
- .HasMaxLength(256)
- .HasColumnType("character varying(256)");
-
- b.HasKey("Id");
-
- b.HasIndex("NormalizedEmail")
- .HasDatabaseName("EmailIndex");
-
- b.HasIndex("NormalizedUserName")
- .IsUnique()
- .HasDatabaseName("UserNameIndex");
-
- b.ToTable("AspNetUsers", (string)null);
- });
-
- modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
- {
- b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
- .WithMany()
- .HasForeignKey("RoleId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-
- modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
- {
- b.HasOne("TemplateWeb.Entities.UserEntity", null)
- .WithMany()
- .HasForeignKey("UserId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-
- modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
- {
- b.HasOne("TemplateWeb.Entities.UserEntity", null)
- .WithMany()
- .HasForeignKey("UserId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-
- modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
- {
- b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
- .WithMany()
- .HasForeignKey("RoleId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.HasOne("TemplateWeb.Entities.UserEntity", null)
- .WithMany()
- .HasForeignKey("UserId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-
- modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
- {
- b.HasOne("TemplateWeb.Entities.UserEntity", null)
- .WithMany()
- .HasForeignKey("UserId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-#pragma warning restore 612, 618
- }
- }
-}
diff --git a/Template/TemplateWeb/Models/ServiceResult.cs b/Template/TemplateWeb/Models/ServiceResult.cs
deleted file mode 100644
index a7fb717..0000000
--- a/Template/TemplateWeb/Models/ServiceResult.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace TemplateWeb.Models;
-
-public class ServiceResult
-{
- public bool Success { get; protected set; }
- public string Message { get; protected set; } = string.Empty;
-
- public static ServiceResult Ok() => new() { Success = true };
- public static ServiceResult Failure(string message) => new() { Success = false, Message = message };
-}
-
-public class ServiceResult : ServiceResult
-{
- public T? Data { get; private set; }
-
- public static ServiceResult Ok(T data) => new() { Success = true, Data = data };
- public new static ServiceResult Failure(string message) => new() { Success = false, Message = message };
-}
diff --git a/Template/TemplateWeb/Models/UserWithRolesViewModel.cs b/Template/TemplateWeb/Models/UserWithRolesViewModel.cs
deleted file mode 100644
index c20f738..0000000
--- a/Template/TemplateWeb/Models/UserWithRolesViewModel.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using TemplateWeb.Entities;
-
-namespace TemplateWeb.Models;
-
-public class UserWithRolesViewModel
-{
- public UserEntity UserEntity { get; set; } = null!;
- public IList Roles { get; set; } = [];
- public IList AllRoles { get; set; } = [];
-}
diff --git a/Template/TemplateWeb/Program.cs b/Template/TemplateWeb/Program.cs
deleted file mode 100644
index d9f3a9d..0000000
--- a/Template/TemplateWeb/Program.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-using dotenv.net;
-using Microsoft.AspNetCore.Identity;
-using Microsoft.EntityFrameworkCore;
-using TemplateWeb.Data;
-using TemplateWeb.Entities;
-
-namespace TemplateWeb;
-
-public class Program
-{
- public static void Main(string[] args)
- {
- DotEnv.Load();
- var builder = WebApplication.CreateBuilder(args);
-
- // gets the connection string from configuration
- var connectionString = builder.Configuration.GetConnectionString("DefaultConnection")
- ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
-
- builder.Services.AddDbContext(options =>
- options.UseNpgsql(connectionString));
-
- builder.Services.AddControllersWithViews();
-
- // Configure Identity — password requirements are read from appsettings.json "Identity:Password"
- var pwSection = builder.Configuration.GetSection("Identity:Password");
- builder.Services.AddIdentity(options =>
- {
- options.Password.RequiredLength = pwSection.GetValue("RequiredLength", 6);
- options.Password.RequireDigit = pwSection.GetValue