X\choro hace 10 meses
padre
commit
9bb28e4b18
Se han modificado 97 ficheros con 2089 adiciones y 1172 borrados
  1. BIN
      backend/.vs/ProjectEvaluation/bitforum.metadata.v9.bin
  2. BIN
      backend/.vs/ProjectEvaluation/bitforum.projects.v9.bin
  3. BIN
      backend/.vs/ProjectEvaluation/bitforum.strings.v9.bin
  4. BIN
      backend/.vs/bitforum/CopilotIndices/17.12.38.29086/CodeChunks.db
  5. BIN
      backend/.vs/bitforum/CopilotIndices/17.12.38.29086/SemanticSymbols.db
  6. BIN
      backend/.vs/bitforum/CopilotIndices/17.12.38.29086/SemanticSymbols.db-shm
  7. BIN
      backend/.vs/bitforum/CopilotIndices/17.12.38.29086/SemanticSymbols.db-wal
  8. BIN
      backend/.vs/bitforum/DesignTimeBuild/.dtbcache.v2
  9. BIN
      backend/.vs/bitforum/v17/.futdcache.v2
  10. BIN
      backend/.vs/bitforum/v17/.suo
  11. 45 191
      backend/.vs/bitforum/v17/DocumentLayout.backup.json
  12. 43 184
      backend/.vs/bitforum/v17/DocumentLayout.json
  13. 3 2
      backend/Areas/Identity/Pages/Account/ConfirmEmail.cshtml.cs
  14. 4 3
      backend/Areas/Identity/Pages/Account/ConfirmEmailChange.cshtml.cs
  15. 14 13
      backend/Areas/Identity/Pages/Account/ExternalLogin.cshtml.cs
  16. 3 2
      backend/Areas/Identity/Pages/Account/ForgotPassword.cshtml.cs
  17. 3 2
      backend/Areas/Identity/Pages/Account/Login.cshtml.cs
  18. 5 4
      backend/Areas/Identity/Pages/Account/LoginWithRecoveryCode.cshtml.cs
  19. 3 2
      backend/Areas/Identity/Pages/Account/Logout.cshtml.cs
  20. 5 4
      backend/Areas/Identity/Pages/Account/Manage/ChangePassword.cshtml.cs
  21. 5 4
      backend/Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml.cs
  22. 3 2
      backend/Areas/Identity/Pages/Account/Manage/Disable2fa.cshtml.cs
  23. 4 3
      backend/Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml.cs
  24. 3 3
      backend/Areas/Identity/Pages/Account/Manage/Email.cshtml
  25. 6 5
      backend/Areas/Identity/Pages/Account/Manage/Email.cshtml.cs
  26. 4 3
      backend/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml.cs
  27. 8 7
      backend/Areas/Identity/Pages/Account/Manage/ExternalLogins.cshtml.cs
  28. 3 2
      backend/Areas/Identity/Pages/Account/Manage/GenerateRecoveryCodes.cshtml.cs
  29. 6 1
      backend/Areas/Identity/Pages/Account/Manage/Index.cshtml
  30. 22 6
      backend/Areas/Identity/Pages/Account/Manage/Index.cshtml.cs
  31. 3 2
      backend/Areas/Identity/Pages/Account/Manage/PersonalData.cshtml.cs
  32. 5 4
      backend/Areas/Identity/Pages/Account/Manage/ResetAuthenticator.cshtml.cs
  33. 5 4
      backend/Areas/Identity/Pages/Account/Manage/SetPassword.cshtml.cs
  34. 4 3
      backend/Areas/Identity/Pages/Account/Manage/TwoFactorAuthentication.cshtml.cs
  35. 1 1
      backend/Areas/Identity/Pages/Account/Manage/_ManageNav.cshtml
  36. 14 13
      backend/Areas/Identity/Pages/Account/Register.cshtml.cs
  37. 3 2
      backend/Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs
  38. 3 2
      backend/Areas/Identity/Pages/Account/ResendEmailConfirmation.cshtml.cs
  39. 3 2
      backend/Areas/Identity/Pages/Account/ResetPassword.cshtml.cs
  40. 1 0
      backend/Areas/Identity/Pages/_ViewImports.cshtml
  41. 1 1
      backend/Areas/Identity/Pages/_ViewStart.cshtml
  42. 17 5
      backend/Constants/MenuData.cs
  43. 5 5
      backend/Controllers/Director/AttachController.cs
  44. 5 5
      backend/Controllers/Director/RoleController.cs
  45. 2 2
      backend/Controllers/Director/UserController.cs
  46. 204 0
      backend/Controllers/Page/DocumentController.cs
  47. 64 0
      backend/Controllers/Page/Faq/CategoryController.cs
  48. 4 4
      backend/Controllers/Setting/BasicController.cs
  49. 1 1
      backend/Controllers/Setting/CompanyController.cs
  50. 2 2
      backend/Controllers/Setting/EnvsController.cs
  51. 1 1
      backend/Controllers/Setting/MetaController.cs
  52. 59 0
      backend/Controllers/Setting/RegisterController.cs
  53. 6 4
      backend/Controllers/Setting/TestController.cs
  54. 5 1
      backend/Database/DefaultDbContext.cs
  55. 1 1
      backend/Database/UserContext.cs
  56. 203 0
      backend/Migrations/DefaultDb/20250117130258_AddFaqs.Designer.cs
  57. 124 0
      backend/Migrations/DefaultDb/20250117130258_AddFaqs.cs
  58. 145 0
      backend/Migrations/DefaultDb/DefaultDbContextModelSnapshot.cs
  59. 52 0
      backend/Models/Config.cs
  60. 34 0
      backend/Models/Page/Document.cs
  61. 47 0
      backend/Models/Page/Faq/Category.cs
  62. 50 0
      backend/Models/Page/Faq/Item.cs
  63. 5 5
      backend/Program.cs
  64. 33 22
      backend/Views/Director/Role.cshtml
  65. 1 1
      backend/Views/Director/User/Edit.cshtml
  66. 48 34
      backend/Views/Director/User/Index.cshtml
  67. 77 0
      backend/Views/Page/Document/Edit.cshtml
  68. 79 0
      backend/Views/Page/Document/Index.cshtml
  69. 54 0
      backend/Views/Page/Document/Write.cshtml
  70. 79 0
      backend/Views/Page/Faq/Index.cshtml
  71. 1 1
      backend/Views/Setting/Basic.cshtml
  72. 122 0
      backend/Views/Setting/Register.cshtml
  73. 3 3
      backend/Views/Setting/Test.cshtml
  74. 3 2
      backend/Views/Shared/_LoginPartial.cshtml
  75. 0 7
      backend/appsettings.json
  76. 0 7
      backend/bin/Debug/net8.0/appsettings.json
  77. BIN
      backend/bin/Debug/net8.0/bitforum.dll
  78. BIN
      backend/bin/Debug/net8.0/bitforum.exe
  79. BIN
      backend/bin/Debug/net8.0/bitforum.pdb
  80. 24 24
      backend/bin/Debug/net8.0/bitforum.staticwebassets.endpoints.json
  81. BIN
      backend/obj/Debug/net8.0/apphost.exe
  82. 1 1
      backend/obj/Debug/net8.0/bitforum.AssemblyInfo.cs
  83. 1 1
      backend/obj/Debug/net8.0/bitforum.AssemblyInfoInputs.cache
  84. 20 0
      backend/obj/Debug/net8.0/bitforum.GeneratedMSBuildEditorConfig.editorconfig
  85. 4 3
      backend/obj/Debug/net8.0/bitforum.MvcApplicationPartsAssemblyInfo.cs
  86. 1 1
      backend/obj/Debug/net8.0/bitforum.csproj.CoreCompileInputs.cache
  87. 0 1
      backend/obj/Debug/net8.0/bitforum.csproj.FileListAbsolute.txt
  88. BIN
      backend/obj/Debug/net8.0/bitforum.dll
  89. BIN
      backend/obj/Debug/net8.0/bitforum.pdb
  90. BIN
      backend/obj/Debug/net8.0/ref/bitforum.dll
  91. BIN
      backend/obj/Debug/net8.0/refint/bitforum.dll
  92. 24 24
      backend/obj/Debug/net8.0/staticwebassets.build.endpoints.json
  93. 212 212
      backend/obj/Debug/net8.0/staticwebassets.build.json
  94. 0 293
      backend/obj/Debug/net8.0/staticwebassets.upToDateCheck.txt
  95. 19 19
      backend/obj/Debug/net8.0/staticwebassets/msbuild.bitforum.Microsoft.AspNetCore.StaticWebAssetEndpoints.props
  96. 2 2
      backend/obj/Debug/net8.0/staticwebassets/msbuild.bitforum.Microsoft.AspNetCore.StaticWebAssets.props
  97. 10 1
      backend/wwwroot/js/site.js

BIN
backend/.vs/ProjectEvaluation/bitforum.metadata.v9.bin


BIN
backend/.vs/ProjectEvaluation/bitforum.projects.v9.bin


BIN
backend/.vs/ProjectEvaluation/bitforum.strings.v9.bin


BIN
backend/.vs/bitforum/CopilotIndices/17.12.38.29086/CodeChunks.db


BIN
backend/.vs/bitforum/CopilotIndices/17.12.38.29086/SemanticSymbols.db


BIN
backend/.vs/bitforum/CopilotIndices/17.12.38.29086/SemanticSymbols.db-shm


BIN
backend/.vs/bitforum/CopilotIndices/17.12.38.29086/SemanticSymbols.db-wal


BIN
backend/.vs/bitforum/DesignTimeBuild/.dtbcache.v2


BIN
backend/.vs/bitforum/v17/.futdcache.v2


BIN
backend/.vs/bitforum/v17/.suo


+ 45 - 191
backend/.vs/bitforum/v17/DocumentLayout.backup.json

@@ -3,56 +3,20 @@
   "WorkspaceRootPath": "E:\\workspace\\bitforum\\backend\\",
   "Documents": [
     {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\controllers\\director\\usercontroller.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:controllers\\director\\usercontroller.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\controllers\\page\\faq\\categorycontroller.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:controllers\\page\\faq\\categorycontroller.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     },
     {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\models\\user\\applicationuser.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:models\\user\\applicationuser.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\models\\page\\faq\\category.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:models\\page\\faq\\category.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     },
     {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\controllers\\director\\rolecontroller.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:controllers\\director\\rolecontroller.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\models\\page\\faq\\item.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:models\\page\\faq\\item.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     },
     {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\views\\director\\user\\index.cshtml||{40D31677-CBC0-4297-A9EF-89D907823A98}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:views\\director\\user\\index.cshtml||{40D31677-CBC0-4297-A9EF-89D907823A98}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\views\\director\\user\\edit.cshtml||{40D31677-CBC0-4297-A9EF-89D907823A98}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:views\\director\\user\\edit.cshtml||{40D31677-CBC0-4297-A9EF-89D907823A98}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\database\\usercontext.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:database\\usercontext.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\views\\shared\\_loginpartial.cshtml||{40D31677-CBC0-4297-A9EF-89D907823A98}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:views\\shared\\_loginpartial.cshtml||{40D31677-CBC0-4297-A9EF-89D907823A98}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\migrations\\user\\usercontextmodelsnapshot.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:migrations\\user\\usercontextmodelsnapshot.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\areas\\identity\\pages\\account\\confirmemail.cshtml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:areas\\identity\\pages\\account\\confirmemail.cshtml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\migrations\\user\\20250115120521_addfullnametousers.designer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:migrations\\user\\20250115120521_addfullnametousers.designer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\database\\defaultdbcontext.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:database\\defaultdbcontext.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\models\\config.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:models\\config.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\constants\\menudata.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:constants\\menudata.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     }
   ],
   "DocumentGroupContainers": [
@@ -62,86 +26,8 @@
       "DocumentGroups": [
         {
           "DockedWidth": 200,
-          "SelectedChildIndex": 14,
+          "SelectedChildIndex": 7,
           "Children": [
-            {
-              "$type": "Document",
-              "DocumentIndex": 2,
-              "Title": "RoleController.cs",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Controllers\\Director\\RoleController.cs",
-              "RelativeDocumentMoniker": "Controllers\\Director\\RoleController.cs",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Controllers\\Director\\RoleController.cs",
-              "RelativeToolTip": "Controllers\\Director\\RoleController.cs",
-              "ViewState": "AgIAAAAAAAAAAAAAAAAAAA0AAAAsAAAAAAAAAA==",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2025-01-15T12:41:49.437Z",
-              "EditorCaption": ""
-            },
-            {
-              "$type": "Document",
-              "DocumentIndex": 3,
-              "Title": "Index.cshtml",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Views\\Director\\User\\Index.cshtml",
-              "RelativeDocumentMoniker": "Views\\Director\\User\\Index.cshtml",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Views\\Director\\User\\Index.cshtml",
-              "RelativeToolTip": "Views\\Director\\User\\Index.cshtml",
-              "ViewState": "AgIAAAAAAAAAAAAAAAAAAB4AAAAYAAAAAAAAAA==",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000759|",
-              "WhenOpened": "2025-01-15T12:39:24.229Z",
-              "EditorCaption": ""
-            },
-            {
-              "$type": "Document",
-              "DocumentIndex": 7,
-              "Title": "_LoginPartial.cshtml",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Views\\Shared\\_LoginPartial.cshtml",
-              "RelativeDocumentMoniker": "Views\\Shared\\_LoginPartial.cshtml",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Views\\Shared\\_LoginPartial.cshtml",
-              "RelativeToolTip": "Views\\Shared\\_LoginPartial.cshtml",
-              "ViewState": "AgIAAAAAAAAAAAAAAAAAAAMAAAAgAAAAAAAAAA==",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000759|",
-              "WhenOpened": "2025-01-15T12:38:07.337Z",
-              "EditorCaption": ""
-            },
-            {
-              "$type": "Document",
-              "DocumentIndex": 8,
-              "Title": "UserContextModelSnapshot.cs",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Migrations\\User\\UserContextModelSnapshot.cs",
-              "RelativeDocumentMoniker": "Migrations\\User\\UserContextModelSnapshot.cs",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Migrations\\User\\UserContextModelSnapshot.cs",
-              "RelativeToolTip": "Migrations\\User\\UserContextModelSnapshot.cs",
-              "ViewState": "AgIAAC0AAAAAAAAAAAAQwEsAAAA/AAAAAAAAAA==",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2025-01-15T12:38:00.852Z",
-              "EditorCaption": ""
-            },
-            {
-              "$type": "Document",
-              "DocumentIndex": 9,
-              "Title": "ConfirmEmail.cshtml.cs",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Areas\\Identity\\Pages\\Account\\ConfirmEmail.cshtml.cs",
-              "RelativeDocumentMoniker": "Areas\\Identity\\Pages\\Account\\ConfirmEmail.cshtml.cs",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Areas\\Identity\\Pages\\Account\\ConfirmEmail.cshtml.cs",
-              "RelativeToolTip": "Areas\\Identity\\Pages\\Account\\ConfirmEmail.cshtml.cs",
-              "ViewState": "AgIAAAAAAAAAAAAAAAAAAA8AAAABAAAAAAAAAA==",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2025-01-15T12:37:50.37Z",
-              "EditorCaption": ""
-            },
-            {
-              "$type": "Document",
-              "DocumentIndex": 10,
-              "Title": "20250115120521_AddFullNameToUsers.Designer.cs",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Migrations\\User\\20250115120521_AddFullNameToUsers.Designer.cs",
-              "RelativeDocumentMoniker": "Migrations\\User\\20250115120521_AddFullNameToUsers.Designer.cs",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Migrations\\User\\20250115120521_AddFullNameToUsers.Designer.cs",
-              "RelativeToolTip": "Migrations\\User\\20250115120521_AddFullNameToUsers.Designer.cs",
-              "ViewState": "AgIAADAAAAAAAAAAAAAQwE4AAAA/AAAAAAAAAA==",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2025-01-15T12:37:45.407Z",
-              "EditorCaption": ""
-            },
             {
               "$type": "Bookmark",
               "Name": "ST:0:0:{d78612c7-9962-4b83-95d9-268046dad23a}"
@@ -155,95 +41,63 @@
               "Name": "ST:0:0:{aa2115a1-9712-457b-9047-dbb71ca2cdd2}"
             },
             {
-              "$type": "Document",
-              "DocumentIndex": 1,
-              "Title": "ApplicationUser.cs",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Models\\User\\ApplicationUser.cs",
-              "RelativeDocumentMoniker": "Models\\User\\ApplicationUser.cs",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Models\\User\\ApplicationUser.cs",
-              "RelativeToolTip": "Models\\User\\ApplicationUser.cs",
-              "ViewState": "AgIAAAAAAAAAAAAAAAAAAAgAAAAXAAAAAAAAAA==",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2025-01-15T12:28:04.769Z",
-              "EditorCaption": ""
-            },
-            {
-              "$type": "Document",
-              "DocumentIndex": 5,
-              "Title": "Program.cs",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Program.cs",
-              "RelativeDocumentMoniker": "Program.cs",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Program.cs",
-              "RelativeToolTip": "Program.cs",
-              "ViewState": "AgIAAAAAAAAAAAAAAAAAAAYAAAAaAAAAAAAAAA==",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2025-01-15T12:27:40.087Z",
-              "EditorCaption": ""
+              "$type": "Bookmark",
+              "Name": "ST:129:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
             },
             {
-              "$type": "Document",
-              "DocumentIndex": 6,
-              "Title": "UserContext.cs",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Database\\UserContext.cs",
-              "RelativeDocumentMoniker": "Database\\UserContext.cs",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Database\\UserContext.cs",
-              "RelativeToolTip": "Database\\UserContext.cs",
-              "ViewState": "AgIAAAAAAAAAAAAAAAAAAAUAAAA5AAAAAAAAAA==",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2025-01-15T12:14:36.287Z",
-              "EditorCaption": ""
+              "$type": "Bookmark",
+              "Name": "ST:130:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
             },
             {
               "$type": "Document",
-              "DocumentIndex": 11,
-              "Title": "DefaultDbContext.cs",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Database\\DefaultDbContext.cs",
-              "RelativeDocumentMoniker": "Database\\DefaultDbContext.cs",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Database\\DefaultDbContext.cs",
-              "RelativeToolTip": "Database\\DefaultDbContext.cs",
-              "ViewState": "AgIAAAAAAAAAAAAAAAAAAAkAAAABAAAAAAAAAA==",
+              "DocumentIndex": 2,
+              "Title": "Item.cs",
+              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Models\\Page\\Faq\\Item.cs",
+              "RelativeDocumentMoniker": "Models\\Page\\Faq\\Item.cs",
+              "ToolTip": "E:\\workspace\\bitforum\\backend\\Models\\Page\\Faq\\Item.cs",
+              "RelativeToolTip": "Models\\Page\\Faq\\Item.cs",
+              "ViewState": "AgIAAAAAAAAAAAAAAAAAAB8AAAAAAAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2025-01-15T12:14:31.682Z",
+              "WhenOpened": "2025-01-17T10:55:37.051Z",
               "EditorCaption": ""
             },
             {
               "$type": "Document",
-              "DocumentIndex": 12,
-              "Title": "Config.cs",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Models\\Config.cs",
-              "RelativeDocumentMoniker": "Models\\Config.cs",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Models\\Config.cs",
-              "RelativeToolTip": "Models\\Config.cs",
-              "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
+              "DocumentIndex": 1,
+              "Title": "Category.cs",
+              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Models\\Page\\Faq\\Category.cs",
+              "RelativeDocumentMoniker": "Models\\Page\\Faq\\Category.cs",
+              "ToolTip": "E:\\workspace\\bitforum\\backend\\Models\\Page\\Faq\\Category.cs",
+              "RelativeToolTip": "Models\\Page\\Faq\\Category.cs",
+              "ViewState": "AgIAAAAAAAAAAAAAAAAAAAkAAAAFAAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2025-01-15T12:12:22.862Z",
+              "WhenOpened": "2025-01-17T10:39:00.389Z",
               "EditorCaption": ""
             },
             {
               "$type": "Document",
               "DocumentIndex": 0,
-              "Title": "UserController.cs",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Controllers\\Director\\UserController.cs",
-              "RelativeDocumentMoniker": "Controllers\\Director\\UserController.cs",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Controllers\\Director\\UserController.cs",
-              "RelativeToolTip": "Controllers\\Director\\UserController.cs",
-              "ViewState": "AgIAACoAAAAAAAAAAAAQwFMAAAAuAAAAAAAAAA==",
+              "Title": "CategoryController.cs",
+              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Controllers\\Page\\Faq\\CategoryController.cs",
+              "RelativeDocumentMoniker": "Controllers\\Page\\Faq\\CategoryController.cs",
+              "ToolTip": "E:\\workspace\\bitforum\\backend\\Controllers\\Page\\Faq\\CategoryController.cs",
+              "RelativeToolTip": "Controllers\\Page\\Faq\\CategoryController.cs",
+              "ViewState": "AgIAAAAAAAAAAAAAAAAAAB8AAAAAAAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2025-01-15T12:11:37.184Z",
+              "WhenOpened": "2025-01-17T10:32:26.406Z",
               "EditorCaption": ""
             },
             {
               "$type": "Document",
-              "DocumentIndex": 4,
-              "Title": "Edit.cshtml",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Views\\Director\\User\\Edit.cshtml",
-              "RelativeDocumentMoniker": "Views\\Director\\User\\Edit.cshtml",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Views\\Director\\User\\Edit.cshtml",
-              "RelativeToolTip": "Views\\Director\\User\\Edit.cshtml",
-              "ViewState": "AgIAAAAAAAAAAAAAAAAAABkAAAAqAAAAAAAAAA==",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000759|",
-              "WhenOpened": "2025-01-15T12:11:22.837Z",
-              "EditorCaption": ""
+              "DocumentIndex": 3,
+              "Title": "MenuData.cs",
+              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Constants\\MenuData.cs",
+              "RelativeDocumentMoniker": "Constants\\MenuData.cs",
+              "ToolTip": "E:\\workspace\\bitforum\\backend\\Constants\\MenuData.cs",
+              "RelativeToolTip": "Constants\\MenuData.cs",
+              "ViewState": "AgIAAEIAAAAAAAAAAAAAAGIAAAAaAAAAAAAAAA==",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+              "WhenOpened": "2025-01-17T10:30:45.706Z"
             }
           ]
         }

+ 43 - 184
backend/.vs/bitforum/v17/DocumentLayout.json

@@ -3,56 +3,20 @@
   "WorkspaceRootPath": "E:\\workspace\\bitforum\\backend\\",
   "Documents": [
     {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\controllers\\director\\usercontroller.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:controllers\\director\\usercontroller.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\models\\user\\applicationuser.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:models\\user\\applicationuser.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\controllers\\director\\rolecontroller.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:controllers\\director\\rolecontroller.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\views\\director\\user\\index.cshtml||{40D31677-CBC0-4297-A9EF-89D907823A98}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:views\\director\\user\\index.cshtml||{40D31677-CBC0-4297-A9EF-89D907823A98}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\views\\director\\user\\edit.cshtml||{40D31677-CBC0-4297-A9EF-89D907823A98}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:views\\director\\user\\edit.cshtml||{40D31677-CBC0-4297-A9EF-89D907823A98}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\database\\usercontext.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:database\\usercontext.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\views\\shared\\_loginpartial.cshtml||{40D31677-CBC0-4297-A9EF-89D907823A98}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:views\\shared\\_loginpartial.cshtml||{40D31677-CBC0-4297-A9EF-89D907823A98}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\migrations\\user\\usercontextmodelsnapshot.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:migrations\\user\\usercontextmodelsnapshot.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
-    },
-    {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\areas\\identity\\pages\\account\\confirmemail.cshtml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:areas\\identity\\pages\\account\\confirmemail.cshtml.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\models\\config.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:models\\config.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     },
     {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\migrations\\user\\20250115120521_addfullnametousers.designer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:migrations\\user\\20250115120521_addfullnametousers.designer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\views\\setting\\register.cshtml||{40D31677-CBC0-4297-A9EF-89D907823A98}",
+      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:views\\setting\\register.cshtml||{40D31677-CBC0-4297-A9EF-89D907823A98}"
     },
     {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\database\\defaultdbcontext.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:database\\defaultdbcontext.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\controllers\\setting\\registercontroller.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:controllers\\setting\\registercontroller.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     },
     {
-      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\models\\config.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
-      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:models\\config.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+      "AbsoluteMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|e:\\workspace\\bitforum\\backend\\models\\user\\applicationuser.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+      "RelativeMoniker": "D:0:0:{07B22B2C-9DC6-4B8E-AA16-8F826E758BDD}|bitforum.csproj|solutionrelative:models\\user\\applicationuser.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
     }
   ],
   "DocumentGroupContainers": [
@@ -62,86 +26,8 @@
       "DocumentGroups": [
         {
           "DockedWidth": 200,
-          "SelectedChildIndex": 14,
+          "SelectedChildIndex": 8,
           "Children": [
-            {
-              "$type": "Document",
-              "DocumentIndex": 2,
-              "Title": "RoleController.cs",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Controllers\\Director\\RoleController.cs",
-              "RelativeDocumentMoniker": "Controllers\\Director\\RoleController.cs",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Controllers\\Director\\RoleController.cs",
-              "RelativeToolTip": "Controllers\\Director\\RoleController.cs",
-              "ViewState": "AgIAAAAAAAAAAAAAAAAAAA0AAAAsAAAAAAAAAA==",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2025-01-15T12:41:49.437Z",
-              "EditorCaption": ""
-            },
-            {
-              "$type": "Document",
-              "DocumentIndex": 3,
-              "Title": "Index.cshtml",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Views\\Director\\User\\Index.cshtml",
-              "RelativeDocumentMoniker": "Views\\Director\\User\\Index.cshtml",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Views\\Director\\User\\Index.cshtml",
-              "RelativeToolTip": "Views\\Director\\User\\Index.cshtml",
-              "ViewState": "AgIAAAAAAAAAAAAAAAAAAB4AAAAYAAAAAAAAAA==",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000759|",
-              "WhenOpened": "2025-01-15T12:39:24.229Z",
-              "EditorCaption": ""
-            },
-            {
-              "$type": "Document",
-              "DocumentIndex": 7,
-              "Title": "_LoginPartial.cshtml",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Views\\Shared\\_LoginPartial.cshtml",
-              "RelativeDocumentMoniker": "Views\\Shared\\_LoginPartial.cshtml",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Views\\Shared\\_LoginPartial.cshtml",
-              "RelativeToolTip": "Views\\Shared\\_LoginPartial.cshtml",
-              "ViewState": "AgIAAAAAAAAAAAAAAAAAAAMAAAAgAAAAAAAAAA==",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000759|",
-              "WhenOpened": "2025-01-15T12:38:07.337Z",
-              "EditorCaption": ""
-            },
-            {
-              "$type": "Document",
-              "DocumentIndex": 8,
-              "Title": "UserContextModelSnapshot.cs",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Migrations\\User\\UserContextModelSnapshot.cs",
-              "RelativeDocumentMoniker": "Migrations\\User\\UserContextModelSnapshot.cs",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Migrations\\User\\UserContextModelSnapshot.cs",
-              "RelativeToolTip": "Migrations\\User\\UserContextModelSnapshot.cs",
-              "ViewState": "AgIAAC0AAAAAAAAAAAAQwEsAAAA/AAAAAAAAAA==",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2025-01-15T12:38:00.852Z",
-              "EditorCaption": ""
-            },
-            {
-              "$type": "Document",
-              "DocumentIndex": 9,
-              "Title": "ConfirmEmail.cshtml.cs",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Areas\\Identity\\Pages\\Account\\ConfirmEmail.cshtml.cs",
-              "RelativeDocumentMoniker": "Areas\\Identity\\Pages\\Account\\ConfirmEmail.cshtml.cs",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Areas\\Identity\\Pages\\Account\\ConfirmEmail.cshtml.cs",
-              "RelativeToolTip": "Areas\\Identity\\Pages\\Account\\ConfirmEmail.cshtml.cs",
-              "ViewState": "AgIAAAAAAAAAAAAAAAAAAA8AAAABAAAAAAAAAA==",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2025-01-15T12:37:50.37Z",
-              "EditorCaption": ""
-            },
-            {
-              "$type": "Document",
-              "DocumentIndex": 10,
-              "Title": "20250115120521_AddFullNameToUsers.Designer.cs",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Migrations\\User\\20250115120521_AddFullNameToUsers.Designer.cs",
-              "RelativeDocumentMoniker": "Migrations\\User\\20250115120521_AddFullNameToUsers.Designer.cs",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Migrations\\User\\20250115120521_AddFullNameToUsers.Designer.cs",
-              "RelativeToolTip": "Migrations\\User\\20250115120521_AddFullNameToUsers.Designer.cs",
-              "ViewState": "AgIAADAAAAAAAAAAAAAQwE4AAAA/AAAAAAAAAA==",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2025-01-15T12:37:45.407Z",
-              "EditorCaption": ""
-            },
             {
               "$type": "Bookmark",
               "Name": "ST:0:0:{d78612c7-9962-4b83-95d9-268046dad23a}"
@@ -154,95 +40,68 @@
               "$type": "Bookmark",
               "Name": "ST:0:0:{aa2115a1-9712-457b-9047-dbb71ca2cdd2}"
             },
+            {
+              "$type": "Bookmark",
+              "Name": "ST:128:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
+            },
             {
               "$type": "Document",
               "DocumentIndex": 1,
+              "Title": "Register.cshtml",
+              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Views\\Setting\\Register.cshtml",
+              "RelativeDocumentMoniker": "Views\\Setting\\Register.cshtml",
+              "ToolTip": "E:\\workspace\\bitforum\\backend\\Views\\Setting\\Register.cshtml",
+              "RelativeToolTip": "Views\\Setting\\Register.cshtml",
+              "ViewState": "AgIAAD0AAAAAAAAAAAAuwHMAAAAtAAAAAAAAAA==",
+              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000759|",
+              "WhenOpened": "2025-01-17T13:55:20.328Z",
+              "EditorCaption": ""
+            },
+            {
+              "$type": "Document",
+              "DocumentIndex": 3,
               "Title": "ApplicationUser.cs",
               "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Models\\User\\ApplicationUser.cs",
               "RelativeDocumentMoniker": "Models\\User\\ApplicationUser.cs",
               "ToolTip": "E:\\workspace\\bitforum\\backend\\Models\\User\\ApplicationUser.cs",
               "RelativeToolTip": "Models\\User\\ApplicationUser.cs",
-              "ViewState": "AgIAAAAAAAAAAAAAAAAAAAgAAAAXAAAAAAAAAA==",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2025-01-15T12:28:04.769Z",
-              "EditorCaption": ""
-            },
-            {
-              "$type": "Document",
-              "DocumentIndex": 5,
-              "Title": "Program.cs",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Program.cs",
-              "RelativeDocumentMoniker": "Program.cs",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Program.cs",
-              "RelativeToolTip": "Program.cs",
-              "ViewState": "AgIAAAAAAAAAAAAAAAAAAAYAAAAaAAAAAAAAAA==",
+              "ViewState": "AgIAAAAAAAAAAAAAAAAAAAsAAAAAAAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2025-01-15T12:27:40.087Z",
+              "WhenOpened": "2025-01-17T13:51:58.659Z",
               "EditorCaption": ""
             },
             {
-              "$type": "Document",
-              "DocumentIndex": 6,
-              "Title": "UserContext.cs",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Database\\UserContext.cs",
-              "RelativeDocumentMoniker": "Database\\UserContext.cs",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Database\\UserContext.cs",
-              "RelativeToolTip": "Database\\UserContext.cs",
-              "ViewState": "AgIAAAAAAAAAAAAAAAAAAAUAAAA5AAAAAAAAAA==",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2025-01-15T12:14:36.287Z",
-              "EditorCaption": ""
+              "$type": "Bookmark",
+              "Name": "ST:129:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
             },
             {
-              "$type": "Document",
-              "DocumentIndex": 11,
-              "Title": "DefaultDbContext.cs",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Database\\DefaultDbContext.cs",
-              "RelativeDocumentMoniker": "Database\\DefaultDbContext.cs",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Database\\DefaultDbContext.cs",
-              "RelativeToolTip": "Database\\DefaultDbContext.cs",
-              "ViewState": "AgIAAAAAAAAAAAAAAAAAAAkAAAABAAAAAAAAAA==",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2025-01-15T12:14:31.682Z",
-              "EditorCaption": ""
+              "$type": "Bookmark",
+              "Name": "ST:130:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}"
             },
             {
               "$type": "Document",
-              "DocumentIndex": 12,
+              "DocumentIndex": 0,
               "Title": "Config.cs",
               "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Models\\Config.cs",
               "RelativeDocumentMoniker": "Models\\Config.cs",
               "ToolTip": "E:\\workspace\\bitforum\\backend\\Models\\Config.cs",
               "RelativeToolTip": "Models\\Config.cs",
-              "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
+              "ViewState": "AgIAALYAAAAAAAAAAAAuwOIAAAA0AAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2025-01-15T12:12:22.862Z",
+              "WhenOpened": "2025-01-17T13:49:45.122Z",
               "EditorCaption": ""
             },
             {
               "$type": "Document",
-              "DocumentIndex": 0,
-              "Title": "UserController.cs",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Controllers\\Director\\UserController.cs",
-              "RelativeDocumentMoniker": "Controllers\\Director\\UserController.cs",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Controllers\\Director\\UserController.cs",
-              "RelativeToolTip": "Controllers\\Director\\UserController.cs",
-              "ViewState": "AgIAACoAAAAAAAAAAAAQwEsAAAANAAAAAAAAAA==",
+              "DocumentIndex": 2,
+              "Title": "RegisterController.cs",
+              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Controllers\\Setting\\RegisterController.cs",
+              "RelativeDocumentMoniker": "Controllers\\Setting\\RegisterController.cs",
+              "ToolTip": "E:\\workspace\\bitforum\\backend\\Controllers\\Setting\\RegisterController.cs",
+              "RelativeToolTip": "Controllers\\Setting\\RegisterController.cs",
+              "ViewState": "AgIAAAAAAAAAAAAAAAAAACQAAAAkAAAAAAAAAA==",
               "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
-              "WhenOpened": "2025-01-15T12:11:37.184Z",
-              "EditorCaption": ""
-            },
-            {
-              "$type": "Document",
-              "DocumentIndex": 4,
-              "Title": "Edit.cshtml",
-              "DocumentMoniker": "E:\\workspace\\bitforum\\backend\\Views\\Director\\User\\Edit.cshtml",
-              "RelativeDocumentMoniker": "Views\\Director\\User\\Edit.cshtml",
-              "ToolTip": "E:\\workspace\\bitforum\\backend\\Views\\Director\\User\\Edit.cshtml",
-              "RelativeToolTip": "Views\\Director\\User\\Edit.cshtml",
-              "ViewState": "AgIAAAAAAAAAAAAAAAAAABkAAAAqAAAAAAAAAA==",
-              "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000759|",
-              "WhenOpened": "2025-01-15T12:11:22.837Z",
+              "WhenOpened": "2025-01-17T13:49:40.547Z",
               "EditorCaption": ""
             }
           ]

+ 3 - 2
backend/Areas/Identity/Pages/Account/ConfirmEmail.cshtml.cs

@@ -6,6 +6,7 @@ using System;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using bitforum.Models.User;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.AspNetCore.Mvc;
@@ -16,9 +17,9 @@ namespace bitforum.Areas.Identity.Pages.Account
 {
     public class ConfirmEmailModel : PageModel
     {
-        private readonly UserManager<IdentityUser> _userManager;
+        private readonly UserManager<ApplicationUser> _userManager;
 
-        public ConfirmEmailModel(UserManager<IdentityUser> userManager)
+        public ConfirmEmailModel(UserManager<ApplicationUser> userManager)
         {
             _userManager = userManager;
         }

+ 4 - 3
backend/Areas/Identity/Pages/Account/ConfirmEmailChange.cshtml.cs

@@ -5,6 +5,7 @@
 using System;
 using System.Text;
 using System.Threading.Tasks;
+using bitforum.Models.User;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.AspNetCore.Mvc;
@@ -15,10 +16,10 @@ namespace bitforum.Areas.Identity.Pages.Account
 {
     public class ConfirmEmailChangeModel : PageModel
     {
-        private readonly UserManager<IdentityUser> _userManager;
-        private readonly SignInManager<IdentityUser> _signInManager;
+        private readonly UserManager<ApplicationUser> _userManager;
+        private readonly SignInManager<ApplicationUser> _signInManager;
 
-        public ConfirmEmailChangeModel(UserManager<IdentityUser> userManager, SignInManager<IdentityUser> signInManager)
+        public ConfirmEmailChangeModel(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager)
         {
             _userManager = userManager;
             _signInManager = signInManager;

+ 14 - 13
backend/Areas/Identity/Pages/Account/ExternalLogin.cshtml.cs

@@ -17,23 +17,24 @@ using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
 using Microsoft.AspNetCore.WebUtilities;
 using Microsoft.Extensions.Logging;
+using bitforum.Models.User;
 
 namespace bitforum.Areas.Identity.Pages.Account
 {
     [AllowAnonymous]
     public class ExternalLoginModel : PageModel
     {
-        private readonly SignInManager<IdentityUser> _signInManager;
-        private readonly UserManager<IdentityUser> _userManager;
-        private readonly IUserStore<IdentityUser> _userStore;
-        private readonly IUserEmailStore<IdentityUser> _emailStore;
+        private readonly SignInManager<ApplicationUser> _signInManager;
+        private readonly UserManager<ApplicationUser> _userManager;
+        private readonly IUserStore<ApplicationUser> _userStore;
+        private readonly IUserEmailStore<ApplicationUser> _emailStore;
         private readonly IEmailSender _emailSender;
         private readonly ILogger<ExternalLoginModel> _logger;
 
         public ExternalLoginModel(
-            SignInManager<IdentityUser> signInManager,
-            UserManager<IdentityUser> userManager,
-            IUserStore<IdentityUser> userStore,
+            SignInManager<ApplicationUser> signInManager,
+            UserManager<ApplicationUser> userManager,
+            IUserStore<ApplicationUser> userStore,
             ILogger<ExternalLoginModel> logger,
             IEmailSender emailSender)
         {
@@ -197,27 +198,27 @@ namespace bitforum.Areas.Identity.Pages.Account
             return Page();
         }
 
-        private IdentityUser CreateUser()
+        private ApplicationUser CreateUser()
         {
             try
             {
-                return Activator.CreateInstance<IdentityUser>();
+                return Activator.CreateInstance<ApplicationUser>();
             }
             catch
             {
-                throw new InvalidOperationException($"Can't create an instance of '{nameof(IdentityUser)}'. " +
-                    $"Ensure that '{nameof(IdentityUser)}' is not an abstract class and has a parameterless constructor, or alternatively " +
+                throw new InvalidOperationException($"Can't create an instance of '{nameof(ApplicationUser)}'. " +
+                    $"Ensure that '{nameof(ApplicationUser)}' is not an abstract class and has a parameterless constructor, or alternatively " +
                     $"override the external login page in /Areas/Identity/Pages/Account/ExternalLogin.cshtml");
             }
         }
 
-        private IUserEmailStore<IdentityUser> GetEmailStore()
+        private IUserEmailStore<ApplicationUser> GetEmailStore()
         {
             if (!_userManager.SupportsUserEmail)
             {
                 throw new NotSupportedException("The default UI requires a user store with email support.");
             }
-            return (IUserEmailStore<IdentityUser>)_userStore;
+            return (IUserEmailStore<ApplicationUser>)_userStore;
         }
     }
 }

+ 3 - 2
backend/Areas/Identity/Pages/Account/ForgotPassword.cshtml.cs

@@ -7,6 +7,7 @@ using System.ComponentModel.DataAnnotations;
 using System.Text;
 using System.Text.Encodings.Web;
 using System.Threading.Tasks;
+using bitforum.Models.User;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.AspNetCore.Identity.UI.Services;
@@ -18,10 +19,10 @@ namespace bitforum.Areas.Identity.Pages.Account
 {
     public class ForgotPasswordModel : PageModel
     {
-        private readonly UserManager<IdentityUser> _userManager;
+        private readonly UserManager<ApplicationUser> _userManager;
         private readonly IEmailSender _emailSender;
 
-        public ForgotPasswordModel(UserManager<IdentityUser> userManager, IEmailSender emailSender)
+        public ForgotPasswordModel(UserManager<ApplicationUser> userManager, IEmailSender emailSender)
         {
             _userManager = userManager;
             _emailSender = emailSender;

+ 3 - 2
backend/Areas/Identity/Pages/Account/Login.cshtml.cs

@@ -14,15 +14,16 @@ using Microsoft.AspNetCore.Identity.UI.Services;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
 using Microsoft.Extensions.Logging;
+using bitforum.Models.User;
 
 namespace bitforum.Areas.Identity.Pages.Account
 {
     public class LoginModel : PageModel
     {
-        private readonly SignInManager<IdentityUser> _signInManager;
+        private readonly SignInManager<ApplicationUser> _signInManager;
         private readonly ILogger<LoginModel> _logger;
 
-        public LoginModel(SignInManager<IdentityUser> signInManager, ILogger<LoginModel> logger)
+        public LoginModel(SignInManager<ApplicationUser> signInManager, ILogger<LoginModel> logger)
         {
             _signInManager = signInManager;
             _logger = logger;

+ 5 - 4
backend/Areas/Identity/Pages/Account/LoginWithRecoveryCode.cshtml.cs

@@ -5,6 +5,7 @@
 using System;
 using System.ComponentModel.DataAnnotations;
 using System.Threading.Tasks;
+using bitforum.Models.User;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.AspNetCore.Mvc;
@@ -14,13 +15,13 @@ namespace bitforum.Areas.Identity.Pages.Account
 {
     public class LoginWithRecoveryCodeModel : PageModel
     {
-        private readonly SignInManager<IdentityUser> _signInManager;
-        private readonly UserManager<IdentityUser> _userManager;
+        private readonly SignInManager<ApplicationUser> _signInManager;
+        private readonly UserManager<ApplicationUser> _userManager;
         private readonly ILogger<LoginWithRecoveryCodeModel> _logger;
 
         public LoginWithRecoveryCodeModel(
-            SignInManager<IdentityUser> signInManager,
-            UserManager<IdentityUser> userManager,
+            SignInManager<ApplicationUser> signInManager,
+            UserManager<ApplicationUser> userManager,
             ILogger<LoginWithRecoveryCodeModel> logger)
         {
             _signInManager = signInManager;

+ 3 - 2
backend/Areas/Identity/Pages/Account/Logout.cshtml.cs

@@ -4,6 +4,7 @@
 
 using System;
 using System.Threading.Tasks;
+using bitforum.Models.User;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.AspNetCore.Mvc;
@@ -14,10 +15,10 @@ namespace bitforum.Areas.Identity.Pages.Account
 {
     public class LogoutModel : PageModel
     {
-        private readonly SignInManager<IdentityUser> _signInManager;
+        private readonly SignInManager<ApplicationUser> _signInManager;
         private readonly ILogger<LogoutModel> _logger;
 
-        public LogoutModel(SignInManager<IdentityUser> signInManager, ILogger<LogoutModel> logger)
+        public LogoutModel(SignInManager<ApplicationUser> signInManager, ILogger<LogoutModel> logger)
         {
             _signInManager = signInManager;
             _logger = logger;

+ 5 - 4
backend/Areas/Identity/Pages/Account/Manage/ChangePassword.cshtml.cs

@@ -5,6 +5,7 @@
 using System;
 using System.ComponentModel.DataAnnotations;
 using System.Threading.Tasks;
+using bitforum.Models.User;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
@@ -14,13 +15,13 @@ namespace bitforum.Areas.Identity.Pages.Account.Manage
 {
     public class ChangePasswordModel : PageModel
     {
-        private readonly UserManager<IdentityUser> _userManager;
-        private readonly SignInManager<IdentityUser> _signInManager;
+        private readonly UserManager<ApplicationUser> _userManager;
+        private readonly SignInManager<ApplicationUser> _signInManager;
         private readonly ILogger<ChangePasswordModel> _logger;
 
         public ChangePasswordModel(
-            UserManager<IdentityUser> userManager,
-            SignInManager<IdentityUser> signInManager,
+            UserManager<ApplicationUser> userManager,
+            SignInManager<ApplicationUser> signInManager,
             ILogger<ChangePasswordModel> logger)
         {
             _userManager = userManager;

+ 5 - 4
backend/Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml.cs

@@ -5,6 +5,7 @@
 using System;
 using System.ComponentModel.DataAnnotations;
 using System.Threading.Tasks;
+using bitforum.Models.User;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
@@ -14,13 +15,13 @@ namespace bitforum.Areas.Identity.Pages.Account.Manage
 {
     public class DeletePersonalDataModel : PageModel
     {
-        private readonly UserManager<IdentityUser> _userManager;
-        private readonly SignInManager<IdentityUser> _signInManager;
+        private readonly UserManager<ApplicationUser> _userManager;
+        private readonly SignInManager<ApplicationUser> _signInManager;
         private readonly ILogger<DeletePersonalDataModel> _logger;
 
         public DeletePersonalDataModel(
-            UserManager<IdentityUser> userManager,
-            SignInManager<IdentityUser> signInManager,
+            UserManager<ApplicationUser> userManager,
+            SignInManager<ApplicationUser> signInManager,
             ILogger<DeletePersonalDataModel> logger)
         {
             _userManager = userManager;

+ 3 - 2
backend/Areas/Identity/Pages/Account/Manage/Disable2fa.cshtml.cs

@@ -4,6 +4,7 @@
 
 using System;
 using System.Threading.Tasks;
+using bitforum.Models.User;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
@@ -13,11 +14,11 @@ namespace bitforum.Areas.Identity.Pages.Account.Manage
 {
     public class Disable2faModel : PageModel
     {
-        private readonly UserManager<IdentityUser> _userManager;
+        private readonly UserManager<ApplicationUser> _userManager;
         private readonly ILogger<Disable2faModel> _logger;
 
         public Disable2faModel(
-            UserManager<IdentityUser> userManager,
+            UserManager<ApplicationUser> userManager,
             ILogger<Disable2faModel> logger)
         {
             _userManager = userManager;

+ 4 - 3
backend/Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml.cs

@@ -8,6 +8,7 @@ using System.Linq;
 using System.Text;
 using System.Text.Json;
 using System.Threading.Tasks;
+using bitforum.Models.User;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
@@ -17,11 +18,11 @@ namespace bitforum.Areas.Identity.Pages.Account.Manage
 {
     public class DownloadPersonalDataModel : PageModel
     {
-        private readonly UserManager<IdentityUser> _userManager;
+        private readonly UserManager<ApplicationUser> _userManager;
         private readonly ILogger<DownloadPersonalDataModel> _logger;
 
         public DownloadPersonalDataModel(
-            UserManager<IdentityUser> userManager,
+            UserManager<ApplicationUser> userManager,
             ILogger<DownloadPersonalDataModel> logger)
         {
             _userManager = userManager;
@@ -45,7 +46,7 @@ namespace bitforum.Areas.Identity.Pages.Account.Manage
 
             // Only include personal data for download
             var personalData = new Dictionary<string, string>();
-            var personalDataProps = typeof(IdentityUser).GetProperties().Where(
+            var personalDataProps = typeof(ApplicationUser).GetProperties().Where(
                             prop => Attribute.IsDefined(prop, typeof(PersonalDataAttribute)));
             foreach (var p in personalDataProps)
             {

+ 3 - 3
backend/Areas/Identity/Pages/Account/Manage/Email.cshtml

@@ -15,9 +15,9 @@
                 {
                     <div class="form-floating mb-3 input-group">
                         <input asp-for="Email" class="form-control" placeholder="Please enter your email." disabled />
-                            <div class="input-group-append">
-                                <span class="h-100 input-group-text text-success font-weight-bold">✓</span>
-                            </div>
+                        <div class="input-group-text">
+                            <span class="text-success font-weight-bold align-middle">✓</span>
+                        </div>
                         <label asp-for="Email" class="form-label"></label>
                     </div>
                 }

+ 6 - 5
backend/Areas/Identity/Pages/Account/Manage/Email.cshtml.cs

@@ -7,6 +7,7 @@ using System.ComponentModel.DataAnnotations;
 using System.Text;
 using System.Text.Encodings.Web;
 using System.Threading.Tasks;
+using bitforum.Models.User;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.AspNetCore.Identity.UI.Services;
 using Microsoft.AspNetCore.Mvc;
@@ -17,13 +18,13 @@ namespace bitforum.Areas.Identity.Pages.Account.Manage
 {
     public class EmailModel : PageModel
     {
-        private readonly UserManager<IdentityUser> _userManager;
-        private readonly SignInManager<IdentityUser> _signInManager;
+        private readonly UserManager<ApplicationUser> _userManager;
+        private readonly SignInManager<ApplicationUser> _signInManager;
         private readonly IEmailSender _emailSender;
 
         public EmailModel(
-            UserManager<IdentityUser> userManager,
-            SignInManager<IdentityUser> signInManager,
+            UserManager<ApplicationUser> userManager,
+            SignInManager<ApplicationUser> signInManager,
             IEmailSender emailSender)
         {
             _userManager = userManager;
@@ -73,7 +74,7 @@ namespace bitforum.Areas.Identity.Pages.Account.Manage
             public string NewEmail { get; set; }
         }
 
-        private async Task LoadAsync(IdentityUser user)
+        private async Task LoadAsync(ApplicationUser user)
         {
             var email = await _userManager.GetEmailAsync(user);
             Email = email;

+ 4 - 3
backend/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml.cs

@@ -9,6 +9,7 @@ using System.Linq;
 using System.Text;
 using System.Text.Encodings.Web;
 using System.Threading.Tasks;
+using bitforum.Models.User;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
@@ -18,14 +19,14 @@ namespace bitforum.Areas.Identity.Pages.Account.Manage
 {
     public class EnableAuthenticatorModel : PageModel
     {
-        private readonly UserManager<IdentityUser> _userManager;
+        private readonly UserManager<ApplicationUser> _userManager;
         private readonly ILogger<EnableAuthenticatorModel> _logger;
         private readonly UrlEncoder _urlEncoder;
 
         private const string AuthenticatorUriFormat = "otpauth://totp/{0}:{1}?secret={2}&issuer={0}&digits=6";
 
         public EnableAuthenticatorModel(
-            UserManager<IdentityUser> userManager,
+            UserManager<ApplicationUser> userManager,
             ILogger<EnableAuthenticatorModel> logger,
             UrlEncoder urlEncoder)
         {
@@ -142,7 +143,7 @@ namespace bitforum.Areas.Identity.Pages.Account.Manage
             }
         }
 
-        private async Task LoadSharedKeyAndQrCodeUriAsync(IdentityUser user)
+        private async Task LoadSharedKeyAndQrCodeUriAsync(ApplicationUser user)
         {
             // Load the authenticator key & QR code URI to display on the form
             var unformattedKey = await _userManager.GetAuthenticatorKeyAsync(user);

+ 8 - 7
backend/Areas/Identity/Pages/Account/Manage/ExternalLogins.cshtml.cs

@@ -7,6 +7,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
+using bitforum.Models.User;
 using Microsoft.AspNetCore.Authentication;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.AspNetCore.Mvc;
@@ -16,14 +17,14 @@ namespace bitforum.Areas.Identity.Pages.Account.Manage
 {
     public class ExternalLoginsModel : PageModel
     {
-        private readonly UserManager<IdentityUser> _userManager;
-        private readonly SignInManager<IdentityUser> _signInManager;
-        private readonly IUserStore<IdentityUser> _userStore;
+        private readonly UserManager<ApplicationUser> _userManager;
+        private readonly SignInManager<ApplicationUser> _signInManager;
+        private readonly IUserStore<ApplicationUser> _userStore;
 
         public ExternalLoginsModel(
-            UserManager<IdentityUser> userManager,
-            SignInManager<IdentityUser> signInManager,
-            IUserStore<IdentityUser> userStore)
+            UserManager<ApplicationUser> userManager,
+            SignInManager<ApplicationUser> signInManager,
+            IUserStore<ApplicationUser> userStore)
         {
             _userManager = userManager;
             _signInManager = signInManager;
@@ -69,7 +70,7 @@ namespace bitforum.Areas.Identity.Pages.Account.Manage
                 .ToList();
 
             string passwordHash = null;
-            if (_userStore is IUserPasswordStore<IdentityUser> userPasswordStore)
+            if (_userStore is IUserPasswordStore<ApplicationUser> userPasswordStore)
             {
                 passwordHash = await userPasswordStore.GetPasswordHashAsync(user, HttpContext.RequestAborted);
             }

+ 3 - 2
backend/Areas/Identity/Pages/Account/Manage/GenerateRecoveryCodes.cshtml.cs

@@ -5,6 +5,7 @@
 using System;
 using System.Linq;
 using System.Threading.Tasks;
+using bitforum.Models.User;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
@@ -14,11 +15,11 @@ namespace bitforum.Areas.Identity.Pages.Account.Manage
 {
     public class GenerateRecoveryCodesModel : PageModel
     {
-        private readonly UserManager<IdentityUser> _userManager;
+        private readonly UserManager<ApplicationUser> _userManager;
         private readonly ILogger<GenerateRecoveryCodesModel> _logger;
 
         public GenerateRecoveryCodesModel(
-            UserManager<IdentityUser> userManager,
+            UserManager<ApplicationUser> userManager,
             ILogger<GenerateRecoveryCodesModel> logger)
         {
             _userManager = userManager;

+ 6 - 1
backend/Areas/Identity/Pages/Account/Manage/Index.cshtml

@@ -7,7 +7,7 @@
 
 <partial name="_StatusMessage" for="StatusMessage" />
 
-<div class="contaasdasdner">
+<div class="container">
     <div class="row">
         <div class="col-md-6">
             <form id="profile-form" method="post">
@@ -16,6 +16,11 @@
                     <input asp-for="Username" class="form-control" placeholder="Please choose your username." disabled />
                     <label asp-for="Username" class="form-label"></label>
                 </div>
+                <div class="form-floating mb-3">
+                    <input asp-for="Input.FullName" class="form-control" placeholder="Please enter your fullname." />
+                    <label asp-for="Input.FullName" class="form-label"></label>
+                    <span asp-validation-for="Input.FullName" class="text-danger"></span>
+                </div>
                 <div class="form-floating mb-3">
                     <input asp-for="Input.PhoneNumber" class="form-control" placeholder="Please enter your phone number."/>
                     <label asp-for="Input.PhoneNumber" class="form-label"></label>

+ 22 - 6
backend/Areas/Identity/Pages/Account/Manage/Index.cshtml.cs

@@ -9,17 +9,18 @@ using System.Threading.Tasks;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
+using bitforum.Models.User;
 
 namespace bitforum.Areas.Identity.Pages.Account.Manage
 {
     public class IndexModel : PageModel
     {
-        private readonly UserManager<IdentityUser> _userManager;
-        private readonly SignInManager<IdentityUser> _signInManager;
+        private readonly UserManager<ApplicationUser> _userManager;
+        private readonly SignInManager<ApplicationUser> _signInManager;
 
         public IndexModel(
-            UserManager<IdentityUser> userManager,
-            SignInManager<IdentityUser> signInManager)
+            UserManager<ApplicationUser> userManager,
+            SignInManager<ApplicationUser> signInManager)
         {
             _userManager = userManager;
             _signInManager = signInManager;
@@ -58,9 +59,12 @@ namespace bitforum.Areas.Identity.Pages.Account.Manage
             [Phone]
             [Display(Name = "Phone number")]
             public string PhoneNumber { get; set; }
+
+            [Display(Name = "Full name")]
+            public string FullName { get; set; }
         }
 
-        private async Task LoadAsync(IdentityUser user)
+        private async Task LoadAsync(ApplicationUser user)
         {
             var userName = await _userManager.GetUserNameAsync(user);
             var phoneNumber = await _userManager.GetPhoneNumberAsync(user);
@@ -69,7 +73,8 @@ namespace bitforum.Areas.Identity.Pages.Account.Manage
 
             Input = new InputModel
             {
-                PhoneNumber = phoneNumber
+                PhoneNumber = phoneNumber,
+                FullName = user.FullName
             };
         }
 
@@ -110,6 +115,17 @@ namespace bitforum.Areas.Identity.Pages.Account.Manage
                 }
             }
 
+            if (Input.FullName != user.FullName)
+            {
+                user.FullName = Input.FullName;
+                var updateResult = await _userManager.UpdateAsync(user);
+                if (!updateResult.Succeeded)
+                {
+                    StatusMessage = "Unexpected error when trying to set full name.";
+                    return RedirectToPage();
+                }
+            }
+
             await _signInManager.RefreshSignInAsync(user);
             StatusMessage = "Your profile has been updated";
             return RedirectToPage();

+ 3 - 2
backend/Areas/Identity/Pages/Account/Manage/PersonalData.cshtml.cs

@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 using System;
 using System.Threading.Tasks;
+using bitforum.Models.User;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
@@ -11,11 +12,11 @@ namespace bitforum.Areas.Identity.Pages.Account.Manage
 {
     public class PersonalDataModel : PageModel
     {
-        private readonly UserManager<IdentityUser> _userManager;
+        private readonly UserManager<ApplicationUser> _userManager;
         private readonly ILogger<PersonalDataModel> _logger;
 
         public PersonalDataModel(
-            UserManager<IdentityUser> userManager,
+            UserManager<ApplicationUser> userManager,
             ILogger<PersonalDataModel> logger)
         {
             _userManager = userManager;

+ 5 - 4
backend/Areas/Identity/Pages/Account/Manage/ResetAuthenticator.cshtml.cs

@@ -4,6 +4,7 @@
 
 using System;
 using System.Threading.Tasks;
+using bitforum.Models.User;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
@@ -13,13 +14,13 @@ namespace bitforum.Areas.Identity.Pages.Account.Manage
 {
     public class ResetAuthenticatorModel : PageModel
     {
-        private readonly UserManager<IdentityUser> _userManager;
-        private readonly SignInManager<IdentityUser> _signInManager;
+        private readonly UserManager<ApplicationUser> _userManager;
+        private readonly SignInManager<ApplicationUser> _signInManager;
         private readonly ILogger<ResetAuthenticatorModel> _logger;
 
         public ResetAuthenticatorModel(
-            UserManager<IdentityUser> userManager,
-            SignInManager<IdentityUser> signInManager,
+            UserManager<ApplicationUser> userManager,
+            SignInManager<ApplicationUser> signInManager,
             ILogger<ResetAuthenticatorModel> logger)
         {
             _userManager = userManager;

+ 5 - 4
backend/Areas/Identity/Pages/Account/Manage/SetPassword.cshtml.cs

@@ -5,6 +5,7 @@
 using System;
 using System.ComponentModel.DataAnnotations;
 using System.Threading.Tasks;
+using bitforum.Models.User;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
@@ -13,12 +14,12 @@ namespace bitforum.Areas.Identity.Pages.Account.Manage
 {
     public class SetPasswordModel : PageModel
     {
-        private readonly UserManager<IdentityUser> _userManager;
-        private readonly SignInManager<IdentityUser> _signInManager;
+        private readonly UserManager<ApplicationUser> _userManager;
+        private readonly SignInManager<ApplicationUser> _signInManager;
 
         public SetPasswordModel(
-            UserManager<IdentityUser> userManager,
-            SignInManager<IdentityUser> signInManager)
+            UserManager<ApplicationUser> userManager,
+            SignInManager<ApplicationUser> signInManager)
         {
             _userManager = userManager;
             _signInManager = signInManager;

+ 4 - 3
backend/Areas/Identity/Pages/Account/Manage/TwoFactorAuthentication.cshtml.cs

@@ -4,6 +4,7 @@
 
 using System;
 using System.Threading.Tasks;
+using bitforum.Models.User;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
@@ -13,12 +14,12 @@ namespace bitforum.Areas.Identity.Pages.Account.Manage
 {
     public class TwoFactorAuthenticationModel : PageModel
     {
-        private readonly UserManager<IdentityUser> _userManager;
-        private readonly SignInManager<IdentityUser> _signInManager;
+        private readonly UserManager<ApplicationUser> _userManager;
+        private readonly SignInManager<ApplicationUser> _signInManager;
         private readonly ILogger<TwoFactorAuthenticationModel> _logger;
 
         public TwoFactorAuthenticationModel(
-            UserManager<IdentityUser> userManager, SignInManager<IdentityUser> signInManager, ILogger<TwoFactorAuthenticationModel> logger)
+            UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager, ILogger<TwoFactorAuthenticationModel> logger)
         {
             _userManager = userManager;
             _signInManager = signInManager;

+ 1 - 1
backend/Areas/Identity/Pages/Account/Manage/_ManageNav.cshtml

@@ -1,4 +1,4 @@
-@inject SignInManager<IdentityUser> SignInManager
+@inject SignInManager<ApplicationUser> SignInManager
 @{
     var hasExternalLogins = (await SignInManager.GetExternalAuthenticationSchemesAsync()).Any();
 }

+ 14 - 13
backend/Areas/Identity/Pages/Account/Register.cshtml.cs

@@ -10,6 +10,7 @@ using System.Text;
 using System.Text.Encodings.Web;
 using System.Threading;
 using System.Threading.Tasks;
+using bitforum.Models.User;
 using Microsoft.AspNetCore.Authentication;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Identity;
@@ -23,17 +24,17 @@ namespace bitforum.Areas.Identity.Pages.Account
 {
     public class RegisterModel : PageModel
     {
-        private readonly SignInManager<IdentityUser> _signInManager;
-        private readonly UserManager<IdentityUser> _userManager;
-        private readonly IUserStore<IdentityUser> _userStore;
-        private readonly IUserEmailStore<IdentityUser> _emailStore;
+        private readonly SignInManager<ApplicationUser> _signInManager;
+        private readonly UserManager<ApplicationUser> _userManager;
+        private readonly IUserStore<ApplicationUser> _userStore;
+        private readonly IUserEmailStore<ApplicationUser> _emailStore;
         private readonly ILogger<RegisterModel> _logger;
         private readonly IEmailSender _emailSender;
 
         public RegisterModel(
-            UserManager<IdentityUser> userManager,
-            IUserStore<IdentityUser> userStore,
-            SignInManager<IdentityUser> signInManager,
+            UserManager<ApplicationUser> userManager,
+            IUserStore<ApplicationUser> userStore,
+            SignInManager<ApplicationUser> signInManager,
             ILogger<RegisterModel> logger,
             IEmailSender emailSender)
         {
@@ -154,27 +155,27 @@ namespace bitforum.Areas.Identity.Pages.Account
             return Page();
         }
 
-        private IdentityUser CreateUser()
+        private ApplicationUser CreateUser()
         {
             try
             {
-                return Activator.CreateInstance<IdentityUser>();
+                return Activator.CreateInstance<ApplicationUser>();
             }
             catch
             {
-                throw new InvalidOperationException($"Can't create an instance of '{nameof(IdentityUser)}'. " +
-                    $"Ensure that '{nameof(IdentityUser)}' is not an abstract class and has a parameterless constructor, or alternatively " +
+                throw new InvalidOperationException($"Can't create an instance of '{nameof(ApplicationUser)}'. " +
+                    $"Ensure that '{nameof(ApplicationUser)}' is not an abstract class and has a parameterless constructor, or alternatively " +
                     $"override the register page in /Areas/Identity/Pages/Account/Register.cshtml");
             }
         }
 
-        private IUserEmailStore<IdentityUser> GetEmailStore()
+        private IUserEmailStore<ApplicationUser> GetEmailStore()
         {
             if (!_userManager.SupportsUserEmail)
             {
                 throw new NotSupportedException("The default UI requires a user store with email support.");
             }
-            return (IUserEmailStore<IdentityUser>)_userStore;
+            return (IUserEmailStore<ApplicationUser>)_userStore;
         }
     }
 }

+ 3 - 2
backend/Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs

@@ -5,6 +5,7 @@
 using System;
 using System.Text;
 using System.Threading.Tasks;
+using bitforum.Models.User;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.AspNetCore.Identity.UI.Services;
@@ -17,10 +18,10 @@ namespace bitforum.Areas.Identity.Pages.Account
     [AllowAnonymous]
     public class RegisterConfirmationModel : PageModel
     {
-        private readonly UserManager<IdentityUser> _userManager;
+        private readonly UserManager<ApplicationUser> _userManager;
         private readonly IEmailSender _sender;
 
-        public RegisterConfirmationModel(UserManager<IdentityUser> userManager, IEmailSender sender)
+        public RegisterConfirmationModel(UserManager<ApplicationUser> userManager, IEmailSender sender)
         {
             _userManager = userManager;
             _sender = sender;

+ 3 - 2
backend/Areas/Identity/Pages/Account/ResendEmailConfirmation.cshtml.cs

@@ -7,6 +7,7 @@ using System.ComponentModel.DataAnnotations;
 using System.Text;
 using System.Text.Encodings.Web;
 using System.Threading.Tasks;
+using bitforum.Models.User;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.AspNetCore.Identity.UI.Services;
@@ -19,10 +20,10 @@ namespace bitforum.Areas.Identity.Pages.Account
     [AllowAnonymous]
     public class ResendEmailConfirmationModel : PageModel
     {
-        private readonly UserManager<IdentityUser> _userManager;
+        private readonly UserManager<ApplicationUser> _userManager;
         private readonly IEmailSender _emailSender;
 
-        public ResendEmailConfirmationModel(UserManager<IdentityUser> userManager, IEmailSender emailSender)
+        public ResendEmailConfirmationModel(UserManager<ApplicationUser> userManager, IEmailSender emailSender)
         {
             _userManager = userManager;
             _emailSender = emailSender;

+ 3 - 2
backend/Areas/Identity/Pages/Account/ResetPassword.cshtml.cs

@@ -6,6 +6,7 @@ using System;
 using System.ComponentModel.DataAnnotations;
 using System.Text;
 using System.Threading.Tasks;
+using bitforum.Models.User;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Identity;
 using Microsoft.AspNetCore.Mvc;
@@ -16,9 +17,9 @@ namespace bitforum.Areas.Identity.Pages.Account
 {
     public class ResetPasswordModel : PageModel
     {
-        private readonly UserManager<IdentityUser> _userManager;
+        private readonly UserManager<ApplicationUser> _userManager;
 
-        public ResetPasswordModel(UserManager<IdentityUser> userManager)
+        public ResetPasswordModel(UserManager<ApplicationUser> userManager)
         {
             _userManager = userManager;
         }

+ 1 - 0
backend/Areas/Identity/Pages/_ViewImports.cshtml

@@ -1,4 +1,5 @@
 @using Microsoft.AspNetCore.Identity
 @using bitforum.Areas.Identity
 @using bitforum.Areas.Identity.Pages
+@using bitforum.Models.User
 @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

+ 1 - 1
backend/Areas/Identity/Pages/_ViewStart.cshtml

@@ -8,5 +8,5 @@
     else
     {
         Layout = "~/Views/Shared/_Sub.cshtml";
-    } 
+    }
 }

+ 17 - 5
backend/Constants/MenuData.cs

@@ -64,13 +64,19 @@ namespace bitforum.Constants
                         },
                         new Menu
                         {
-                            Id = 206,
+                            Id = 207,
+                            Name = "회원가입 설정",
+                            Path = "/Setting/Register"
+                        },
+                        new Menu
+                        {
+                            Id = 208,
                             Name = "알림 발송 확인",
                             Path = "/Setting/Test"
                         },
                         new Menu
                         {
-                            Id = 207,
+                            Id = 209,
                             Name = "권한 관리",
                             Path = "/Director/User"
                         },
@@ -93,9 +99,15 @@ namespace bitforum.Constants
                         },
                         new Menu
                         {
-                            Id = 302,
-                            Name = "배너 관리",
-                            Path = "/Page/Banner"
+                            Id = 303,
+                            Name = "FAQ 관리",
+                            Path = "/Page/Faq"
+                        },
+                        new Menu
+                        {
+                            Id = 304,
+                            Name = "팝업 관리",
+                            Path = "/Page/Popup"
                         }
                     }
                 },

+ 5 - 5
backend/Controllers/Director/AttachController.cs

@@ -58,14 +58,14 @@ namespace bitforum.Controllers.Director
         }
 
         [HttpPost]
-        public async Task<IActionResult> Save(AttachViewModel model)
+        public async Task<IActionResult> Save(AttachViewModel request)
         {
             if (!ModelState.IsValid)
             {
-                return View(_ViewPath, model);
+                return View(_ViewPath, request);
             }
 
-            var user = await _userManager.FindByIdAsync(model.UserID);
+            var user = await _userManager.FindByIdAsync(request.UserID);
 
             if (user == null)
             {
@@ -81,7 +81,7 @@ namespace bitforum.Controllers.Director
             await _userManager.AddToRolesAsync(user, model.Roles.Where(r => r.IsSelected).Select(r => r.DisplayValue));
             */
 
-            foreach (var role in model.Roles)
+            foreach (var role in request.Roles)
             {
                 // 현재 사용자의 역할에 포함되어 있으나 선택되지 않은 경우 해당 역할 제거
                 if (userRoles.Any(r => r == role.DisplayValue) && !role.IsSelected)
@@ -100,7 +100,7 @@ namespace bitforum.Controllers.Director
             TempData["SuccessMessage"] = message;
             _logger.LogInformation(message);
 
-            return RedirectToAction("index", "Attach", new { userId = model.UserID });
+            return RedirectToAction("index", "Attach", new { userId = request.UserID });
         }
     }
 }

+ 5 - 5
backend/Controllers/Director/RoleController.cs

@@ -80,7 +80,7 @@ namespace bitforum.Controllers.Director
             {
                 var roles = await _roleManager.Roles.ToListAsync();
                 _logger.LogError(e, e.Message);
-                TempData["ErrorMessage"] = "역할 추가가 정상적으로 완료되었습니다.";
+                TempData["ErrorMessages"] = "역할 추가가 정상적으로 완료되었습니다.";
 
                 return View(_RoleViewPath, roles);
             }
@@ -123,9 +123,9 @@ namespace bitforum.Controllers.Director
         }
 
         [HttpPost("ManagePermissions")]
-        public async Task<IActionResult> ManagePermissions(PermissionsFormViewModel model)
+        public async Task<IActionResult> ManagePermissions(PermissionsFormViewModel request)
         {
-            var role = await _roleManager.FindByIdAsync(model.RoleID);
+            var role = await _roleManager.FindByIdAsync(request.RoleID);
 
             if (role == null)
             {
@@ -139,7 +139,7 @@ namespace bitforum.Controllers.Director
                 await _roleManager.RemoveClaimAsync(role, claim);
             }
 
-            var selectedClaims = model.RoleClaims.Where(c => c.IsSelected).ToList();
+            var selectedClaims = request.RoleClaims.Where(c => c.IsSelected).ToList();
 
             foreach (var claim in selectedClaims)
             {
@@ -150,7 +150,7 @@ namespace bitforum.Controllers.Director
             TempData["SuccessMessage"] = message;
             _logger.LogInformation(message);
 
-            return RedirectToAction("ManagePermissions", "Role", new { model.RoleID });
+            return RedirectToAction("ManagePermissions", "Role", new { request.RoleID });
         }
     }
 }

+ 2 - 2
backend/Controllers/Director/UserController.cs

@@ -77,7 +77,7 @@ namespace bitforum.Controllers.Director
             catch (Exception e)
             {
                 _logger.LogError(e, e.Message);
-                TempData["ErrorMessage"] = e.Message;
+                TempData["ErrorMessages"] = e.Message;
                 return RedirectToAction(nameof(Index));
             }
 
@@ -140,7 +140,7 @@ namespace bitforum.Controllers.Director
             catch (Exception e)
             {
                 _logger.LogError(e, e.Message);
-                TempData["ErrorMessage"] = e.Message;
+                TempData["ErrorMessages"] = e.Message;
                 return RedirectToAction(nameof(Edit), new { userID = request.ID });
             }
         }

+ 204 - 0
backend/Controllers/Page/DocumentController.cs

@@ -0,0 +1,204 @@
+using System.Diagnostics;
+using bitforum.Models;
+using bitforum.Models.Page;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+
+namespace bitforum.Controllers.Page
+{
+    [Authorize]
+    [Route("Page")]
+    public class DocumentController : Controller
+    {
+        private readonly ILogger<DocumentController> _logger;
+        private readonly DefaultDbContext _db;
+        private readonly IConfiguration _config;
+
+        public DocumentController(ILogger<DocumentController> logger, DefaultDbContext db, IConfiguration config)
+        {
+            _logger = logger;
+            _db = db;
+            _config = config;
+        }
+
+        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
+        public IActionResult Error()
+        {
+            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
+        }
+
+        [HttpGet("Document")]
+        public IActionResult Index()
+        {
+            ViewBag.siteURL = _config["AppConfig:AppName"];
+            var viewModel = _db.Document.OrderByDescending(c => c.ID).ToList();
+
+            return View("~/Views/Page/Document/Index.cshtml", viewModel);
+        }
+
+        [HttpGet("Document/Write")]
+        public IActionResult Write()
+        {
+            ViewBag.siteURL = _config["AppConfig:AppName"];
+            return View("~/Views/Page/Document/Write.cshtml");
+        }
+
+        [HttpPost("Document/Create")]
+        public async Task<IActionResult> Create(Document request)
+        {
+            try
+            {
+                if (!ModelState.IsValid)
+                {
+                    throw new Exception("유효성 검사에 실패하였습니다.");
+                }
+
+                // 중복확인
+                if (await _db.Document.AnyAsync(c => c.Code == request.Code))
+                {
+                    throw new Exception("이미 존재하는 Code 주소입니다.");
+                }
+
+
+                request.UpdatedAt = null;
+                request.CreatedAt = DateTime.Now;
+
+                _db.Document.Add(request);
+                int affectedRows = await _db.SaveChangesAsync();
+
+                if (affectedRows <= 0)
+                {
+                    throw new Exception("문서 등록 중 오류가 발생했습니다.");
+                }
+
+                string message = "문서가 정상적으로 등록되었습니다.";
+                TempData["SuccessMessage"] = message;
+                _logger.LogInformation(message);
+                return RedirectToAction("Index");
+            }
+            catch (Exception e)
+            {
+                _logger.LogError(e, e.Message);
+                TempData["ErrorMessages"] = e.Message;
+                return View("~/Views/Page/Document/Write.cshtml", request);
+            }
+        }
+
+        [HttpGet("Document/Edit/{id}")]
+        public async Task<IActionResult> Edit(int id)
+        {
+            ViewBag.siteURL = _config["AppConfig:AppName"];
+
+            try
+            {
+                if (id <= 0)
+                {
+                    throw new Exception("유효하지 않은 문서 ID입니다.");
+                }
+
+                var document = await _db.Document.FirstAsync(c => c.ID == id);
+
+                if (document is null)
+                {
+                    throw new Exception("사용자 정보를 찾을 수 없습니다.");
+                }
+
+                return View("~/Views/Page/Document/Edit.cshtml", document);
+            }
+            catch (Exception e)
+            {
+                _logger.LogError(e, e.Message);
+                TempData["ErrorMessages"] = e.Message;
+                return RedirectToAction("Edit", new { id = id });
+            }
+        }
+
+        [HttpPost("Document/Update")]
+        public async Task<IActionResult> Update(Document request)
+        {
+            try
+            {
+                if (!ModelState.IsValid)
+                {
+                    throw new Exception("유효성 검사에 실패하였습니다.");
+                }
+
+                // 중복확인
+                if (await _db.Document.AnyAsync(c => c.Code == request.Code && c.ID != request.ID))
+                {
+                    throw new Exception("이미 존재하는 Code 주소입니다.");
+                }
+
+                // 기존 문서 조회
+                var document = await _db.Document.FindAsync(request.ID);
+
+                if (document is null)
+                {
+                    throw new Exception("사용자 정보를 찾을 수 없습니다.");
+                }
+
+                document.IsDisplay = request.IsDisplay;
+                document.Code = request.Code;
+                document.Subject = request.Subject;
+                document.Content = request.Content;
+                document.UpdatedAt = DateTime.Now;
+
+                _db.Document.Update(document);
+
+                int affectedRows = await _db.SaveChangesAsync();
+                if (affectedRows <= 0)
+                {
+                    throw new Exception("문서 수정 중 오류가 발생했습니다.");
+                }
+
+                string message = "문서가 정상적으로 수정되었습니다.";
+                TempData["SuccessMessage"] = message;
+                _logger.LogInformation(message);
+                return RedirectToAction("Edit", new { id = request.ID });
+            }
+            catch (Exception e)
+            {
+                _logger.LogError(e, e.Message);
+                TempData["ErrorMessages"] = e.Message;
+                return View("~/Views/Page/Document/Edit.cshtml", request);
+            }
+        }
+
+        [HttpGet("Document/Delete/{id}")]
+        public async Task<IActionResult> Delete(int id)
+        {
+            try
+            {
+                if (id <= 0)
+                {
+                    throw new Exception("유효하지 않은 문서 ID입니다.");
+                }
+
+                var document = await _db.Document.FindAsync(id);
+                if (document == null)
+                {
+                    throw new Exception("문서 정보를 찾을 수 없습니다.");
+                }
+
+                _db.Document.Remove(document);
+                int affectedRows = await _db.SaveChangesAsync();
+                if (affectedRows <= 0)
+                {
+                    throw new Exception("문서 삭제 중 오류가 발생했습니다.");
+                }
+
+                string message = "문서가 정상적으로 삭제되었습니다.";
+                TempData["SuccessMessage"] = message;
+                _logger.LogInformation(message);
+                return RedirectToAction("Index");
+            }
+            catch (Exception e)
+            {
+                _logger.LogError(e, e.Message);
+                TempData["ErrorMessages"] = e.Message;
+                return View("~/Views/Page/Document/Index.cshtml");
+            }
+        }
+    }
+}

+ 64 - 0
backend/Controllers/Page/Faq/CategoryController.cs

@@ -0,0 +1,64 @@
+using System.Diagnostics;
+using bitforum.Models;
+using bitforum.Models.Page.Faq;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+
+namespace bitforum.Controllers.Page
+{
+    [Authorize]
+    [Route("Page")]
+    public class CategoryController : Controller
+    {
+        private readonly ILogger<CategoryController> _logger;
+        private readonly DefaultDbContext _db;
+
+        public CategoryController(ILogger<CategoryController> logger, DefaultDbContext db)
+        {
+            _logger = logger;
+            _db = db;
+        }
+
+        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
+        public IActionResult Error()
+        {
+            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
+        }
+
+        [HttpGet("Faq")]
+        public IActionResult Index()
+        {
+
+            return View();
+        }
+
+        [HttpGet("Faq/Write")]
+        public IActionResult Write()
+        {
+            return View("~/Views/Page/Document/Write.cshtml");
+        }
+
+        /*
+        [HttpPost("Faq/Create")]
+        public async Task<IActionResult> Create(FaqCategory request)
+        {
+        }
+
+        [HttpGet("Faq/Edit/{id}")]
+        public async Task<IActionResult> Edit(int id)
+        {
+        }
+
+        [HttpPost("Faq/Update")]
+        public async Task<IActionResult> Update(FaqCategory request)
+        {
+        }
+
+        [HttpGet("Faq/Delete/{id}")]
+        public async Task<IActionResult> Delete(int id)
+        {
+        }
+        */
+    }
+}

+ 4 - 4
backend/Controllers/Setting/BasicController.cs

@@ -9,13 +9,13 @@ namespace bitforum.Controllers.Setting
 {
     [Authorize]
     [Route("Setting")]
-    public class DirectorController : Controller
+    public class BasicController : Controller
     {
-        private readonly ILogger<DirectorController> _logger;
+        private readonly ILogger<BasicController> _logger;
         private readonly ConfigRepository _configRepository;
         private readonly string _ViewPath = "~/Views/Setting/Basic.cshtml";
 
-        public DirectorController(ILogger<DirectorController> logger, ConfigRepository configRepository)
+        public BasicController(ILogger<BasicController> logger, ConfigRepository configRepository)
         {
             _logger = logger;
             _configRepository = configRepository;
@@ -38,7 +38,7 @@ namespace bitforum.Controllers.Setting
             {
                 message = "기본 설정 값 저장에 실패";
                 _logger.LogWarning(message);
-                TempData["ErrorMessage"] = message;
+                TempData["ErrorMessages"] = message;
                 return View(_ViewPath, request);
             }
 

+ 1 - 1
backend/Controllers/Setting/CompanyController.cs

@@ -47,7 +47,7 @@ namespace bitforum.Controllers.Setting
             {
                 message = "회사 정보 설정 값 저장에 실패";
                 _logger.LogWarning(message);
-                TempData["ErrorMessage"] = message;
+                TempData["ErrorMessages"] = message;
                 return View(_ViewPath, request);
             }
 

+ 2 - 2
backend/Controllers/Setting/EnvsController.cs

@@ -9,10 +9,10 @@ namespace bitforum.Controllers.Setting
     [Route("Setting")]
     public class EnvsController : Controller
     {
-        private readonly ILogger<HomeController> _logger;
+        private readonly ILogger<EnvsController> _logger;
         private readonly IHostEnvironment _env;
 
-        public EnvsController(ILogger<HomeController> logger, IHostEnvironment env)
+        public EnvsController(ILogger<EnvsController> logger, IHostEnvironment env)
         {
             _logger = logger;
             _env = env;

+ 1 - 1
backend/Controllers/Setting/MetaController.cs

@@ -38,7 +38,7 @@ namespace bitforum.Controllers.Setting
             {
                 message = "메타 태그 설정 값 저장에 실패";
                 _logger.LogWarning(message);
-                TempData["ErrorMessage"] = message;
+                TempData["ErrorMessages"] = message;
                 return View(_ViewPath, request);
             }
 

+ 59 - 0
backend/Controllers/Setting/RegisterController.cs

@@ -0,0 +1,59 @@
+using System.Diagnostics;
+using bitforum.Models;
+using bitforum.Repository;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using bitforum.Helpers;
+
+namespace bitforum.Controllers.Setting
+{
+    [Authorize]
+    [Route("Setting")]
+    public class RegisterController : Controller
+    {
+        private readonly ILogger<RegisterController> _logger;
+        private readonly ConfigRepository _configRepository;
+        private readonly string _ViewPath = "~/Views/Setting/Register.cshtml";
+
+        public RegisterController(ILogger<RegisterController> logger, ConfigRepository configRepository)
+        {
+            _logger = logger;
+            _configRepository = configRepository;
+        }
+
+        [HttpGet("Register")]
+        public IActionResult Index()
+        {
+            ViewBag.config = _configRepository.GetAll();
+
+            return View(_ViewPath);
+        }
+
+        [HttpPost("Register")]
+        public IActionResult Save(RegisterForm request)
+        {
+            string message;
+
+            if (!ModelState.IsValid)
+            {
+                message = "회원가입 설정 값 저장에 실패";
+                _logger.LogWarning(message);
+                TempData["ErrorMessages"] = message;
+                return View(_ViewPath, request);
+            }
+
+            Func.SaveConfig(request, _configRepository.Replace);
+
+            message = "회원가입 설정 값이 정상적으로 저장되었습니다.";
+            _logger.LogInformation(message);
+            TempData["SuccessMessage"] = message;
+            return RedirectToAction("Index");
+        }
+
+        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
+        public IActionResult Error()
+        {
+            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
+        }
+    }
+}

+ 6 - 4
backend/Controllers/Setting/TestController.cs

@@ -38,8 +38,8 @@ namespace bitforum.Controllers.Setting
             {
                 if (string.IsNullOrEmpty(email))
                 {
-                    TempData["ErrorMessage"] = "이메일 주소를 입력해주세요.";
-                    return RedirectToAction("Test", "Setting");
+                    TempData["ErrorMessages"] = "이메일 주소를 입력해주세요.";
+                    return RedirectToAction("Index", "Test");
                 }
 
                 var config = _configRepository.GetAll();
@@ -69,15 +69,17 @@ namespace bitforum.Controllers.Setting
             }
             catch (SmtpException smtpEx)
             {
+                TempData["ErrorMessages"] = smtpEx.Message;
                 Console.WriteLine($"SMTP error: {smtpEx.Message}");
                 _logger.LogError($"SMTP error: {smtpEx.StatusCode} - {smtpEx.Message}");
-                throw;
+                return RedirectToAction("Index", "Test");
             }
             catch (Exception ex)
             {
+                TempData["ErrorMessages"] = ex.Message;
                 Console.WriteLine($"Email sending failed: {ex.Message}");
                 _logger.LogError($"Failed to send email to {email}: {ex.Message}");
-                throw;
+                return RedirectToAction("Index", "Test");
             }
         }
 

+ 5 - 1
backend/Database/DefaultDbContext.cs

@@ -1,10 +1,14 @@
 using Microsoft.EntityFrameworkCore;
 using bitforum.Models;
+using bitforum.Models.Page;
+using bitforum.Models.Page.Faq;
 
 public class DefaultDbContext : DbContext
 {
     public DefaultDbContext(DbContextOptions<DefaultDbContext> options) : base(options) { }
 
-    // Config 테이블과 매핑
     public DbSet<Config> Config { get; set; }
+    public DbSet<Document> Document { get; set; }
+    public DbSet<FaqCategory> FaqCategory { get; set; }
+    public DbSet<FaqItem> FaqItem { get; set; }
 }

+ 1 - 1
backend/Database/UserContext.cs

@@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Identity;
 using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
 using Microsoft.EntityFrameworkCore;
 
-public class UserContext : IdentityDbContext<IdentityUser, IdentityRole, string>
+public class UserContext : IdentityDbContext<ApplicationUser, IdentityRole, string>
 {
     public UserContext(DbContextOptions<UserContext> options): base(options)
     {

+ 203 - 0
backend/Migrations/DefaultDb/20250117130258_AddFaqs.Designer.cs

@@ -0,0 +1,203 @@
+// <auto-generated />
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace bitforum.Migrations.DefaultDb
+{
+    [DbContext(typeof(DefaultDbContext))]
+    [Migration("20250117130258_AddFaqs")]
+    partial class AddFaqs
+    {
+        /// <inheritdoc />
+        protected override void BuildTargetModel(ModelBuilder modelBuilder)
+        {
+#pragma warning disable 612, 618
+            modelBuilder
+                .HasAnnotation("ProductVersion", "8.0.0")
+                .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+            SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+            modelBuilder.Entity("bitforum.Models.Config", b =>
+                {
+                    b.Property<int>("ID")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("int");
+
+                    SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
+
+                    b.Property<DateTime>("CreatedAt")
+                        .HasColumnType("datetime2");
+
+                    b.Property<string>("Description")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<string>("Key")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(450)");
+
+                    b.Property<string>("Value")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.HasKey("ID");
+
+                    b.HasIndex("Key")
+                        .IsUnique();
+
+                    b.ToTable("Config");
+                });
+
+            modelBuilder.Entity("bitforum.Models.Page.Document", b =>
+                {
+                    b.Property<int>("ID")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("int");
+
+                    SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
+
+                    b.Property<string>("Code")
+                        .IsRequired()
+                        .HasMaxLength(30)
+                        .HasColumnType("nvarchar(30)");
+
+                    b.Property<string>("Content")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<DateTime?>("CreatedAt")
+                        .HasColumnType("datetime2");
+
+                    b.Property<bool>("IsDisplay")
+                        .HasColumnType("bit");
+
+                    b.Property<string>("Subject")
+                        .IsRequired()
+                        .HasMaxLength(120)
+                        .HasColumnType("nvarchar(120)");
+
+                    b.Property<DateTime?>("UpdatedAt")
+                        .HasColumnType("datetime2");
+
+                    b.Property<int>("Views")
+                        .HasColumnType("int");
+
+                    b.HasKey("ID");
+
+                    b.HasIndex(new[] { "Code" }, "IX_Document_Code")
+                        .IsUnique();
+
+                    b.ToTable("Document");
+                });
+
+            modelBuilder.Entity("bitforum.Models.Page.Faq.FaqCategory", b =>
+                {
+                    b.Property<int>("ID")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("int");
+
+                    SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
+
+                    b.Property<string>("Code")
+                        .IsRequired()
+                        .HasMaxLength(30)
+                        .HasColumnType("nvarchar(30)");
+
+                    b.Property<string>("Content")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<DateTime?>("CreatedAt")
+                        .HasColumnType("datetime2");
+
+                    b.Property<bool>("IsActive")
+                        .HasColumnType("bit");
+
+                    b.Property<int>("Order")
+                        .HasColumnType("int");
+
+                    b.Property<string>("Subject")
+                        .IsRequired()
+                        .HasMaxLength(255)
+                        .HasColumnType("nvarchar(255)");
+
+                    b.Property<DateTime?>("UpdatedAt")
+                        .HasColumnType("datetime2");
+
+                    b.HasKey("ID");
+
+                    b.HasIndex(new[] { "Code" }, "IX_FaqCategory_Code")
+                        .IsUnique();
+
+                    b.HasIndex(new[] { "Order" }, "IX_FaqCategory_Order");
+
+                    b.ToTable("FaqCategory");
+                });
+
+            modelBuilder.Entity("bitforum.Models.Page.Faq.FaqItem", b =>
+                {
+                    b.Property<int>("ID")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("int");
+
+                    SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
+
+                    b.Property<string>("Answer")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<int>("CategoryID")
+                        .HasColumnType("int");
+
+                    b.Property<DateTime?>("CreatedAt")
+                        .HasColumnType("datetime2");
+
+                    b.Property<bool>("IsActive")
+                        .HasColumnType("bit");
+
+                    b.Property<int>("Order")
+                        .HasColumnType("int");
+
+                    b.Property<string>("Question")
+                        .IsRequired()
+                        .HasMaxLength(255)
+                        .HasColumnType("nvarchar(255)");
+
+                    b.Property<DateTime?>("UpdatedAt")
+                        .HasColumnType("datetime2");
+
+                    b.Property<int>("Views")
+                        .HasColumnType("int");
+
+                    b.HasKey("ID");
+
+                    b.HasIndex("CategoryID");
+
+                    b.HasIndex(new[] { "IsActive" }, "IX_FaqItem_IsActive");
+
+                    b.HasIndex(new[] { "Order" }, "IX_FaqItem_Order");
+
+                    b.ToTable("FaqItem");
+                });
+
+            modelBuilder.Entity("bitforum.Models.Page.Faq.FaqItem", b =>
+                {
+                    b.HasOne("bitforum.Models.Page.Faq.FaqCategory", "FaqCategory")
+                        .WithMany("FaqItem")
+                        .HasForeignKey("CategoryID")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.Navigation("FaqCategory");
+                });
+
+            modelBuilder.Entity("bitforum.Models.Page.Faq.FaqCategory", b =>
+                {
+                    b.Navigation("FaqItem");
+                });
+#pragma warning restore 612, 618
+        }
+    }
+}

+ 124 - 0
backend/Migrations/DefaultDb/20250117130258_AddFaqs.cs

@@ -0,0 +1,124 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace bitforum.Migrations.DefaultDb
+{
+    /// <inheritdoc />
+    public partial class AddFaqs : Migration
+    {
+        /// <inheritdoc />
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.CreateTable(
+                name: "Document",
+                columns: table => new
+                {
+                    ID = table.Column<int>(type: "int", nullable: false)
+                        .Annotation("SqlServer:Identity", "1, 1"),
+                    IsDisplay = table.Column<bool>(type: "bit", nullable: false),
+                    Code = table.Column<string>(type: "nvarchar(30)", maxLength: 30, nullable: false),
+                    Subject = table.Column<string>(type: "nvarchar(120)", maxLength: 120, nullable: false),
+                    Content = table.Column<string>(type: "nvarchar(max)", nullable: true),
+                    Views = table.Column<int>(type: "int", nullable: false),
+                    UpdatedAt = table.Column<DateTime>(type: "datetime2", nullable: true),
+                    CreatedAt = table.Column<DateTime>(type: "datetime2", nullable: true)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_Document", x => x.ID);
+                });
+
+            migrationBuilder.CreateTable(
+                name: "FaqCategory",
+                columns: table => new
+                {
+                    ID = table.Column<int>(type: "int", nullable: false)
+                        .Annotation("SqlServer:Identity", "1, 1"),
+                    Code = table.Column<string>(type: "nvarchar(30)", maxLength: 30, nullable: false),
+                    Subject = table.Column<string>(type: "nvarchar(255)", maxLength: 255, nullable: false),
+                    Content = table.Column<string>(type: "nvarchar(max)", nullable: true),
+                    Order = table.Column<int>(type: "int", nullable: false),
+                    IsActive = table.Column<bool>(type: "bit", nullable: false),
+                    UpdatedAt = table.Column<DateTime>(type: "datetime2", nullable: true),
+                    CreatedAt = table.Column<DateTime>(type: "datetime2", nullable: true)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_FaqCategory", x => x.ID);
+                });
+
+            migrationBuilder.CreateTable(
+                name: "FaqItem",
+                columns: table => new
+                {
+                    ID = table.Column<int>(type: "int", nullable: false)
+                        .Annotation("SqlServer:Identity", "1, 1"),
+                    CategoryID = table.Column<int>(type: "int", nullable: false),
+                    Question = table.Column<string>(type: "nvarchar(255)", maxLength: 255, nullable: false),
+                    Answer = table.Column<string>(type: "nvarchar(max)", nullable: true),
+                    Order = table.Column<int>(type: "int", nullable: false),
+                    IsActive = table.Column<bool>(type: "bit", nullable: false),
+                    Views = table.Column<int>(type: "int", nullable: false),
+                    UpdatedAt = table.Column<DateTime>(type: "datetime2", nullable: true),
+                    CreatedAt = table.Column<DateTime>(type: "datetime2", nullable: true)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_FaqItem", x => x.ID);
+                    table.ForeignKey(
+                        name: "FK_FaqItem_FaqCategory_CategoryID",
+                        column: x => x.CategoryID,
+                        principalTable: "FaqCategory",
+                        principalColumn: "ID",
+                        onDelete: ReferentialAction.Cascade);
+                });
+
+            migrationBuilder.CreateIndex(
+                name: "IX_Document_Code",
+                table: "Document",
+                column: "Code",
+                unique: true);
+
+            migrationBuilder.CreateIndex(
+                name: "IX_FaqCategory_Code",
+                table: "FaqCategory",
+                column: "Code",
+                unique: true);
+
+            migrationBuilder.CreateIndex(
+                name: "IX_FaqCategory_Order",
+                table: "FaqCategory",
+                column: "Order");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_FaqItem_CategoryID",
+                table: "FaqItem",
+                column: "CategoryID");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_FaqItem_IsActive",
+                table: "FaqItem",
+                column: "IsActive");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_FaqItem_Order",
+                table: "FaqItem",
+                column: "Order");
+        }
+
+        /// <inheritdoc />
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropTable(
+                name: "Document");
+
+            migrationBuilder.DropTable(
+                name: "FaqItem");
+
+            migrationBuilder.DropTable(
+                name: "FaqCategory");
+        }
+    }
+}

+ 145 - 0
backend/Migrations/DefaultDb/DefaultDbContextModelSnapshot.cs

@@ -49,6 +49,151 @@ namespace bitforum.Migrations.DefaultDb
 
                     b.ToTable("Config");
                 });
+
+            modelBuilder.Entity("bitforum.Models.Page.Document", b =>
+                {
+                    b.Property<int>("ID")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("int");
+
+                    SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
+
+                    b.Property<string>("Code")
+                        .IsRequired()
+                        .HasMaxLength(30)
+                        .HasColumnType("nvarchar(30)");
+
+                    b.Property<string>("Content")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<DateTime?>("CreatedAt")
+                        .HasColumnType("datetime2");
+
+                    b.Property<bool>("IsDisplay")
+                        .HasColumnType("bit");
+
+                    b.Property<string>("Subject")
+                        .IsRequired()
+                        .HasMaxLength(120)
+                        .HasColumnType("nvarchar(120)");
+
+                    b.Property<DateTime?>("UpdatedAt")
+                        .HasColumnType("datetime2");
+
+                    b.Property<int>("Views")
+                        .HasColumnType("int");
+
+                    b.HasKey("ID");
+
+                    b.HasIndex(new[] { "Code" }, "IX_Document_Code")
+                        .IsUnique();
+
+                    b.ToTable("Document");
+                });
+
+            modelBuilder.Entity("bitforum.Models.Page.Faq.FaqCategory", b =>
+                {
+                    b.Property<int>("ID")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("int");
+
+                    SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
+
+                    b.Property<string>("Code")
+                        .IsRequired()
+                        .HasMaxLength(30)
+                        .HasColumnType("nvarchar(30)");
+
+                    b.Property<string>("Content")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<DateTime?>("CreatedAt")
+                        .HasColumnType("datetime2");
+
+                    b.Property<bool>("IsActive")
+                        .HasColumnType("bit");
+
+                    b.Property<int>("Order")
+                        .HasColumnType("int");
+
+                    b.Property<string>("Subject")
+                        .IsRequired()
+                        .HasMaxLength(255)
+                        .HasColumnType("nvarchar(255)");
+
+                    b.Property<DateTime?>("UpdatedAt")
+                        .HasColumnType("datetime2");
+
+                    b.HasKey("ID");
+
+                    b.HasIndex(new[] { "Code" }, "IX_FaqCategory_Code")
+                        .IsUnique();
+
+                    b.HasIndex(new[] { "Order" }, "IX_FaqCategory_Order");
+
+                    b.ToTable("FaqCategory");
+                });
+
+            modelBuilder.Entity("bitforum.Models.Page.Faq.FaqItem", b =>
+                {
+                    b.Property<int>("ID")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("int");
+
+                    SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"));
+
+                    b.Property<string>("Answer")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<int>("CategoryID")
+                        .HasColumnType("int");
+
+                    b.Property<DateTime?>("CreatedAt")
+                        .HasColumnType("datetime2");
+
+                    b.Property<bool>("IsActive")
+                        .HasColumnType("bit");
+
+                    b.Property<int>("Order")
+                        .HasColumnType("int");
+
+                    b.Property<string>("Question")
+                        .IsRequired()
+                        .HasMaxLength(255)
+                        .HasColumnType("nvarchar(255)");
+
+                    b.Property<DateTime?>("UpdatedAt")
+                        .HasColumnType("datetime2");
+
+                    b.Property<int>("Views")
+                        .HasColumnType("int");
+
+                    b.HasKey("ID");
+
+                    b.HasIndex("CategoryID");
+
+                    b.HasIndex(new[] { "IsActive" }, "IX_FaqItem_IsActive");
+
+                    b.HasIndex(new[] { "Order" }, "IX_FaqItem_Order");
+
+                    b.ToTable("FaqItem");
+                });
+
+            modelBuilder.Entity("bitforum.Models.Page.Faq.FaqItem", b =>
+                {
+                    b.HasOne("bitforum.Models.Page.Faq.FaqCategory", "FaqCategory")
+                        .WithMany("FaqItem")
+                        .HasForeignKey("CategoryID")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.Navigation("FaqCategory");
+                });
+
+            modelBuilder.Entity("bitforum.Models.Page.Faq.FaqCategory", b =>
+                {
+                    b.Navigation("FaqItem");
+                });
 #pragma warning restore 612, 618
         }
     }

+ 52 - 0
backend/Models/Config.cs

@@ -179,4 +179,56 @@ namespace bitforum.Models
         [BindProperty(Name = "company_bank_number")]
         public string? CompanyBankNumber { get; set; } = null;
     }
+
+    // 회원가입 설정
+    public class RegisterForm
+    {
+        [Display(Name = "회원가입 차단")]
+        [BindProperty(Name = "is_register_block")]
+        public bool IsRegisterBlock { get; set; } = false;
+
+        [Display(Name = "회원가입 시 이메일 인증")]
+        [BindProperty(Name = "register_able")]
+        public bool IsRegisterEmailAuth { get; set; } = false;
+
+        [Display(Name = "비밀번호 최소 길이")]
+        [BindProperty(Name = "password_min_length")]
+        public int? PasswordMinLength { get; set; } = null;
+
+        [Display(Name = "비밀번호 최소 대문자 수")]
+        [BindProperty(Name = "password_uppercase_length")]
+        public int? PasswordUppercaseLength { get; set; } = null;
+
+        [Display(Name = "비밀번호 최소 숫자 수")]
+        [BindProperty(Name = "password_numbers_length")]
+        public int? PasswordNumbersLength { get; set; } = null;
+
+        [Display(Name = "비밀번호 최소 특수문자 수")]
+        [BindProperty(Name = "password_specialchars_length")]
+        public int? PasswordSpecialcharsLength { get; set; } = null;
+
+        [Display(Name = "금지 별명")]
+        [BindProperty(Name = "denied_nickname_list")]
+        public string? DeniedNicknameList { get; set; } = null; 
+
+        [Display(Name = "별명 갱신 주기")]
+        [BindProperty(Name = "change_nickname_day")]
+        public int? ChangeNicknameDay { get; set; } = null;
+
+        [Display(Name = "이메일 갱신 주기")]
+        [BindProperty(Name = "change_email_day")]
+        public int? ChangeEmailDay { get; set; } = null;
+
+        [Display(Name = "비밀번호 갱신 주기")]
+        [BindProperty(Name = "change_password_day")]
+        public int? ChangePasswordDay { get; set; } = null;
+
+        [Display(Name = "로그인 시도 제한 횟수")]
+        [BindProperty(Name = "max_login_try_count")]
+        public int? MaxLoginTryCount { get; set; } = null;
+
+        [Display(Name = "로그인 시도 제한 시간")]
+        [BindProperty(Name = "max_login_try_limit_second")]
+        public int? MaxLoginTryLimitSecond { get; set; } = null;
+    }
 }

+ 34 - 0
backend/Models/Page/Document.cs

@@ -0,0 +1,34 @@
+using Microsoft.EntityFrameworkCore;
+using System.ComponentModel.DataAnnotations;
+
+namespace bitforum.Models.Page
+{
+    [Index(nameof(Code), Name = "IX_Document_Code", IsUnique = true)]
+    public class Document
+    {
+        [Key]
+        public int ID { get; set; }
+
+        public bool IsDisplay { get; set; } = false;
+
+        [DataType(DataType.Text)]
+        [MaxLength(30)]
+        [RegularExpression(@"^[a-zA-Z0-9]+$", ErrorMessage = "Code는 영문 및 숫자로만 구성되어야 합니다.")]
+        public string Code { get; set; }
+
+        [DataType(DataType.Text)]
+        [MaxLength(120)]
+        public string Subject { get; set; }
+
+        [DataType(DataType.Html)]
+        public string? Content { get; set; } = null;
+
+        public int Views { get; set; } = 0;
+
+        [DataType(DataType.DateTime)]
+        public DateTime? UpdatedAt { get; set; } = null;
+
+        [DataType(DataType.DateTime)]
+        public DateTime? CreatedAt { get; set; } = null;
+    }
+}

+ 47 - 0
backend/Models/Page/Faq/Category.cs

@@ -0,0 +1,47 @@
+using Microsoft.EntityFrameworkCore;
+using System.ComponentModel;
+using System.ComponentModel.DataAnnotations;
+
+namespace bitforum.Models.Page.Faq
+{
+    [Index(nameof(Code), Name = "IX_FaqCategory_Code", IsUnique = true)]
+    [Index(nameof(Order), Name = "IX_FaqCategory_Order")]
+    public class FaqCategory
+    {
+        [Key]
+        public int ID { get; set; }
+
+        [DisplayName("주소")]
+        [DataType(DataType.Text)]
+        [MaxLength(30)]
+        [RegularExpression(@"^[a-zA-Z0-9]+$", ErrorMessage = "Code는 영문 및 숫자로만 구성되어야 합니다.")]
+        public string Code { get; set; }
+
+        [DisplayName("제목")]
+        [DataType(DataType.Text)]
+        [MaxLength(255)]
+        public string Subject { get; set; }
+
+        [DisplayName("내용")]
+        [DataType(DataType.Html)]
+        public string? Content { get; set; } = null;
+
+        [Required]
+        [DisplayName("순서")]
+        public int Order { get; set; } = 0;
+
+        [Required]
+        [DisplayName("사용 여부")]
+        public bool IsActive { get; set; } = false;
+
+        [Display(Name = "수정일시")]
+        [DataType(DataType.DateTime)]
+        public DateTime? UpdatedAt { get; set; } = null;
+
+        [Display(Name = "등록일시")]
+        [DataType(DataType.DateTime)]
+        public DateTime? CreatedAt { get; set; } = null;
+
+        public virtual List<FaqItem> FaqItem { get; set; }
+    }
+}

+ 50 - 0
backend/Models/Page/Faq/Item.cs

@@ -0,0 +1,50 @@
+using Microsoft.EntityFrameworkCore;
+using System.ComponentModel;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace bitforum.Models.Page.Faq
+{
+    [Index(nameof(Order), Name = "IX_FaqItem_Order")]
+    [Index(nameof(IsActive), Name = "IX_FaqItem_IsActive")]
+    public class FaqItem
+    {
+        [Key]
+        public int ID { get; set; }
+
+        [Required]
+        [ForeignKey("FaqCategory")]
+        [DisplayName("분류ID")]
+        public int CategoryID { get; set; }
+
+        [DisplayName("질문")]
+        [DataType(DataType.Text)]
+        [MaxLength(255)]
+        public string Question { get; set; }
+
+        [DisplayName("답변")]
+        [DataType(DataType.Html)]
+        public string? Answer { get; set; } = null;
+
+        [Required]
+        [DisplayName("순서")]
+        public int Order { get; set; } = 0;
+
+        [Required]
+        [DisplayName("사용 여부")]
+        public bool IsActive { get; set; } = false;
+
+        [DisplayName("조회 수")]
+        public int Views { get; set; } = 0;
+
+        [Display(Name = "수정일시")]
+        [DataType(DataType.DateTime)]
+        public DateTime? UpdatedAt { get; set; } = null;
+
+        [Display(Name = "등록일시")]
+        [DataType(DataType.DateTime)]
+        public DateTime? CreatedAt { get; set; } = null;
+
+        public virtual FaqCategory FaqCategory { get; set; }
+    }
+}

+ 5 - 5
backend/Program.cs

@@ -31,10 +31,10 @@ builder.Services.AddDbContext<UserContext>(options => options.UseSqlServer(conne
 builder.Services.AddIdentity<ApplicationUser, IdentityRole>(options =>
 {
     options.SignIn.RequireConfirmedAccount = true; // 이메일 확인 비활성화
-}).AddEntityFrameworkStores<UserContext>().AddDefaultTokenProviders();
-
-// Identity UI 추가
-builder.Services.AddRazorPages();
+})
+    .AddEntityFrameworkStores<UserContext>()
+    .AddDefaultUI()
+    .AddDefaultTokenProviders();
 
 builder.Services.Configure<IdentityOptions>(options =>
 {
@@ -78,7 +78,7 @@ builder.Services.AddScoped<ConfigRepository>();
 
 // Add services to the container.
 builder.Services.AddControllersWithViews();
-
+builder.Services.AddRazorPages();
 builder.Logging.ClearProviders();
 builder.Logging.AddConsole();
 builder.Logging.AddDebug();

+ 33 - 22
backend/Views/Director/Role.cshtml

@@ -26,27 +26,38 @@
         </div>
     </form>
 
-    <table class="table table-bordered table-striped table-hover mt-4">
-        <thead>
-            <tr class="text-center">
-                <th>ID</th>
-                <th>Role Name</th>
-                <th>Permission</th>
-                <th>Actions</th>
-            </tr>
-        </thead>
-        <tbody>
-            @foreach (var role in Model)
-            {
-                <tr class="text-center align-middle">
-                    <td>@role.Id</td>
-                    <td>@role.Name</td>
-                    <td>@ViewBag.RoleClaimsCount[role.Name]</td>
-                    <td>
-                        <a class="btn btn-sm btn-primary" asp-controller="Role" asp-action="ManagePermissions" asp-route-roleID="@role.Id">권한 관리</a>
-                    </td>
+    <div class="table-responsive">
+        <table class="table table-bordered table-striped table-hover mt-4">
+            <thead>
+                <tr class="text-center">
+                    <th>ID</th>
+                    <th>Role Name</th>
+                    <th>Permission</th>
+                    <th>Actions</th>
                 </tr>
-            }
-        </tbody>
-    </table>
+            </thead>
+            <tbody>
+                @if (Model == null || !Model.Any())
+                {
+                    <tr>
+                        <td colspan="4" class="text-center align-middle">No Data.</td>
+                    </tr>
+                }
+                else
+                {
+                    @foreach (var role in Model)
+                    {
+                        <tr class="text-center align-middle">
+                            <td>@role.Id</td>
+                            <td>@role.Name</td>
+                            <td>@ViewBag.RoleClaimsCount[role.Name]</td>
+                            <td>
+                                <a class="btn btn-sm btn-primary" asp-controller="Role" asp-action="ManagePermissions" asp-route-roleID="@role.Id">권한 관리</a>
+                            </td>
+                        </tr>
+                    }
+                }
+            </tbody>
+        </table>
+    </div>
 </div>

+ 1 - 1
backend/Views/Director/User/Edit.cshtml

@@ -36,7 +36,7 @@
             </div>
         </div>
         <hr/>
-        <div class="grid gap-2 text-center">
+        <div class="d-grid gap-2 text-center d-md-block">
             <button type="submit" class="btn btn-sm btn-success">저장</button>
             <a asp-action="Index" class="btn btn-sm btn-secondary">취소</a>
         </div>

+ 48 - 34
backend/Views/Director/User/Index.cshtml

@@ -11,44 +11,58 @@
     <small>관리자 가입 회원들입니다. 메뉴 접근 권한을 관리할 수 있습니다.</small>
 
     <div class="row g-2">
+        <div class="col align-self-end">
+            Total : @Model.Count.ToString("N0")
+        </div>
         <div class="col text-end">
             <a class="btn btn-sm btn-primary" asp-controller="Role" asp-action="Index">역할 관리</a>
         </div>
     </div>
 
-    <table class="table table-striped table-bordered mt-3">
-        <thead>
-            <tr class="text-center">
-                <th>User</th>
-                <th>Role</th>
-                <th>Actions</th>
-            </tr>
-        </thead>
-        <tbody>
-            @foreach (var user in Model)
-            {
-                <tr class="text-center align-middle">
-                    <td>
-                        @user.Name<br/>
-                        @user.Email<br/>
-                        <small>(@user.ID)</small>
-                    </td>
-                    <td>
-                        @if (user.Roles.Any())
-                        {
-                            @string.Join(", ", user.Roles)
-                        }
-                        else
-                        {
-                            <span>역할 없음</span>
-                        }
-                    </td>
-                    <td>
-                        <a class="btn btn-sm btn-info text-white" asp-controller="User" asp-action="Edit" asp-route-userId="@user.ID">수정</a>
-                        <a class="btn btn-sm btn-danger" asp-controller="Attach" asp-action="Index" asp-route-userId="@user.ID">권한</a>
-                    </td>
+    <div class="table-responsive">
+        <table class="table table-striped table-bordered table-hover mt-3">
+            <thead>
+                <tr class="text-center">
+                    <th>User</th>
+                    <th>Role</th>
+                    <th>Actions</th>
                 </tr>
-            }
-        </tbody>
-    </table>
+            </thead>
+            <tbody>
+                @if (Model == null || !Model.Any())
+                {
+                    <tr>
+                        <td colspan="3" class="text-center align-middle">No Data.</td>
+                    </tr>
+                }
+                else
+                {
+                    @foreach (var user in Model)
+                    {
+                        <tr class="text-center align-middle">
+                            <td>
+                                @user.Name<br />
+                                @user.Email<br />
+                                <small>(@user.ID)</small>
+                            </td>
+                            <td>
+                                @if (user.Roles.Any())
+                                {
+                                    @string.Join(", ", user.Roles)
+                                }
+                                else
+                                {
+                                    <span>역할 없음</span>
+                                }
+                            </td>
+                            <td>
+                                <a class="btn btn-sm btn-info text-white" asp-controller="User" asp-action="Edit" asp-route-userId="@user.ID">수정</a>
+                                <a class="btn btn-sm btn-danger" asp-controller="Attach" asp-action="Index" asp-route-userId="@user.ID">권한</a>
+                            </td>
+                        </tr>
+                    }
+                }
+            </tbody>
+        </table>
+    </div>
 </div>

+ 77 - 0
backend/Views/Page/Document/Edit.cshtml

@@ -0,0 +1,77 @@
+@model bitforum.Models.Page.Document
+@{
+    ViewData["Title"] = "문서 수정";
+}
+
+<div class="container">
+    <h3>@ViewData["Title"]</h3>
+    <hr />
+
+    <partial name="_StatusMessage" />
+    <partial name="_Editor" />
+
+    <form name="f_admin_write" id="fAdminWrite" method="post" accept-charset="utf-8" autocomplete="off" asp-controller="Document" asp-action="Update">
+        <input type="hidden" asp-for="ID" />
+
+        <div class="row mb-2">
+            <label for="IsDisplay" class="col-sm-2 col-form-label">사용 여부</label>
+            <div class="col-sm-10 align-content-center">
+                <div class="form-check-inline">
+                    <input type="checkbox" asp-for="IsDisplay" class="form-check-input" />
+                    <label class="form-check-label" for="IsDisplay">
+                        사용합니다.
+                    </label>
+                    <span asp-validation-for="IsDisplay" class="text-danger"></span>
+                </div>
+            </div>
+        </div>
+        <div class="row mb-2">
+            <label for="Code" class="col-sm-2 col-form-label">주소</label>
+            <div class="col-sm-10">
+                @ViewBag.siteURL /docs/ <input type="text" asp-for="Code" class="form-control d-inline w-auto"/>
+                <span asp-validation-for="Code" class="text-danger"></span>
+            </div>
+        </div>
+        <div class="row mb-2">
+            <label for="Subject" class="col-sm-2 col-form-label">제목</label>
+            <div class="col-sm-10">
+                <input asp-for="Subject" class="form-control"/>
+                <span asp-validation-for="Subject" class="text-danger"></span>
+            </div>
+        </div>
+        <div class="row mb-2">
+            <label for="Content" class="col-sm-2 col-form-label">내용</label>
+            <div class="col-sm-10">
+                <textarea asp-for="Content" class="form-control ck-editor"></textarea>
+                <span asp-validation-for="Content" class="text-danger"></span>
+            </div>
+        </div>
+
+        @if (Model.UpdatedAt is not null)
+        {
+            <div class="row mb-2">
+                <label class="col-sm-2 col-form-label">수정일시</label>
+            <div class="col-sm-10">
+                <input asp-for="UpdatedAt" class="form-control-plaintext" type="text" readonly />
+            </div>
+        </div>
+        }
+
+         @if (Model.CreatedAt is not null)
+        {
+            <div class="row mb-2">
+                <label class="col-sm-2 col-form-label">등록일시</label>
+            <div class="col-sm-10">
+                    <input asp-for="CreatedAt" class="form-control-plaintext" type="text" readonly />
+            </div>
+        </div>
+        }
+
+        <hr/>
+        <div class="d-grid gap-2 text-center d-md-block">
+            <button type="submit" class="btn btn-sm btn-success">저장</button>
+            <a asp-action="Index" class="btn btn-sm btn-secondary">취소</a>
+        </div>
+        <br/>
+    </form>
+</div>

+ 79 - 0
backend/Views/Page/Document/Index.cshtml

@@ -0,0 +1,79 @@
+@model List<bitforum.Models.Page.Document>
+@{
+    ViewData["Title"] = "문서 관리";
+}
+
+<div class="container">
+    <h3>@ViewData["Title"]</h3>
+    <hr />
+
+    <partial name="_StatusMessage" />
+
+    <div class="row g-2 align-items-end">
+        <div class="col">
+            Total : @((Model?.Count ?? 0).ToString("N0"))
+        </div>
+        <div class="col text-end">
+            <a class="btn btn-sm btn-success" asp-controller="Document" asp-action="Write">새로등록</a>
+        </div>
+    </div>
+
+    <div class="table-responsive">
+        <table class="table table-striped table-bordered table-hover mt-3">
+            <colgroup>
+                <col width="5%"/>
+                <col width="*"/>
+                <col width="25%"/>
+                <col width="10%"/>
+                <col width="9%"/>
+                <col width="9%"/>
+                <col width="8%"/>
+            </colgroup>
+            <thead>
+                <tr class="text-center">
+                    <th>ID</th>
+                    <th>제목</th>
+                    <th>주소</th>
+                    <th>조회 수</th>
+                    <th>등록일시</th>
+                    <th>수정일시</th>
+                    <th>비고</th>
+                </tr>
+            </thead>
+            <tbody>
+                @if (Model == null || !Model.Any())
+                {
+                    <tr>
+                        <td colspan="7" class="text-center align-middle">No Data.</td>
+                    </tr>
+                }
+                else
+                {
+                    @foreach (var row in Model)
+                    {
+                        string url = $"https://{ViewBag.siteURL}/{row.Code}";
+
+                        <tr class="text-center align-middle">
+                            <td>@row.ID</td>
+                            <td>@row.Subject</td>
+                            <td>
+                                <a href="@url" target="_blank" rel="external">
+                                    @url
+                                </a>
+                            </td>
+                            <td>@row.Views</td>
+                            <td>@row.CreatedAt</td>
+                            <td>@row.UpdatedAt</td>
+                            <td>
+                                <div class="d-grid gap-2">
+                                    <a class="btn btn-sm btn-info text-white" asp-controller="Document" asp-action="Edit" asp-route-id="@row.ID">수정</a>
+                                    <a class="btn btn-sm btn-danger text-white btn-delete-row" asp-controller="Document" asp-action="Delete" asp-route-id="@row.ID">삭제</a>
+                                </div>
+                            </td>
+                        </tr>
+                    }
+                }
+            </tbody>
+        </table>
+    </div>
+</div>

+ 54 - 0
backend/Views/Page/Document/Write.cshtml

@@ -0,0 +1,54 @@
+@model bitforum.Models.Page.Document
+@{
+    ViewData["Title"] = "문서 등록";
+}
+
+<div class="container">
+    <h3>@ViewData["Title"]</h3>
+    <hr />
+
+    <partial name="_StatusMessage" />
+    <partial name="_Editor" />
+
+    <form name="f_admin_write" id="fAdminWrite" method="post" accept-charset="utf-8" autocomplete="off" asp-controller="Document" asp-action="Create">
+        <div class="row mb-2">
+            <label for="IsDisplay" class="col-sm-2 col-form-label">사용 여부</label>
+            <div class="col-sm-10 align-content-center">
+                <div class="form-check-inline">
+                    <input type="checkbox" asp-for="IsDisplay" class="form-check-input" />
+                    <label class="form-check-label" for="IsDisplay">
+                        사용합니다.
+                    </label>
+                    <span asp-validation-for="IsDisplay" class="text-danger"></span>
+                </div>
+            </div>
+        </div>
+        <div class="row mb-2">
+            <label for="Code" class="col-sm-2 col-form-label">주소</label>
+            <div class="col-sm-10">
+                @ViewBag.siteURL /docs/ <input type="text" asp-for="Code" class="form-control d-inline w-auto"/>
+                <span asp-validation-for="Code" class="text-danger"></span>
+            </div>
+        </div>
+        <div class="row mb-2">
+            <label for="Subject" class="col-sm-2 col-form-label">제목</label>
+            <div class="col-sm-10">
+                <input asp-for="Subject" class="form-control"/>
+                <span asp-validation-for="Subject" class="text-danger"></span>
+            </div>
+        </div>
+        <div class="row mb-2">
+            <label for="Content" class="col-sm-2 col-form-label">내용</label>
+            <div class="col-sm-10">
+                <textarea asp-for="Content" class="form-control ck-editor"></textarea>
+                <span asp-validation-for="Content" class="text-danger"></span>
+            </div>
+        </div>
+        <hr/>
+        <div class="d-grid gap-2 text-center d-md-block">
+            <button type="submit" class="btn btn-sm btn-success">저장</button>
+            <a asp-action="Index" class="btn btn-sm btn-secondary">취소</a>
+        </div>
+        <br/>
+    </form>
+</div>

+ 79 - 0
backend/Views/Page/Faq/Index.cshtml

@@ -0,0 +1,79 @@
+@model List<bitforum.Models.Page.Document>
+@{
+    ViewData["Title"] = "문서 관리";
+}
+
+<div class="container">
+    <h3>@ViewData["Title"]</h3>
+    <hr />
+
+    <partial name="_StatusMessage" />
+
+    <div class="row g-2 align-items-end">
+        <div class="col">
+            Total : @((Model?.Count ?? 0).ToString("N0"))
+        </div>
+        <div class="col text-end">
+            <a class="btn btn-sm btn-success" asp-controller="Document" asp-action="Write">새로등록</a>
+        </div>
+    </div>
+
+    <div class="table-responsive">
+        <table class="table table-striped table-bordered table-hover mt-3">
+            <colgroup>
+                <col width="5%"/>
+                <col width="*"/>
+                <col width="25%"/>
+                <col width="10%"/>
+                <col width="9%"/>
+                <col width="9%"/>
+                <col width="8%"/>
+            </colgroup>
+            <thead>
+                <tr class="text-center">
+                    <th>ID</th>
+                    <th>제목</th>
+                    <th>주소</th>
+                    <th>조회 수</th>
+                    <th>등록일시</th>
+                    <th>수정일시</th>
+                    <th>비고</th>
+                </tr>
+            </thead>
+            <tbody>
+                @if (Model == null || !Model.Any())
+                {
+                    <tr>
+                        <td colspan="7" class="text-center align-middle">No Data.</td>
+                    </tr>
+                }
+                else
+                {
+                    @foreach (var row in Model)
+                    {
+                        string url = $"https://{ViewBag.siteURL}/{row.Code}";
+
+                        <tr class="text-center align-middle">
+                            <td>@row.ID</td>
+                            <td>@row.Subject</td>
+                            <td>
+                                <a href="@url" target="_blank" rel="external">
+                                    @url
+                                </a>
+                            </td>
+                            <td>@row.Views</td>
+                            <td>@row.CreatedAt</td>
+                            <td>@row.UpdatedAt</td>
+                            <td>
+                                <div class="d-grid gap-2">
+                                    <a class="btn btn-sm btn-info text-white" asp-controller="Document" asp-action="Edit" asp-route-id="@row.ID">수정</a>
+                                    <a class="btn btn-sm btn-danger text-white btn-delete-row" asp-controller="Document" asp-action="Delete" asp-route-id="@row.ID">삭제</a>
+                                </div>
+                            </td>
+                        </tr>
+                    }
+                }
+            </tbody>
+        </table>
+    </div>
+</div>

+ 1 - 1
backend/Views/Setting/Basic.cshtml

@@ -48,7 +48,7 @@
         <div class="row mb-3">
             <label for="smtpPort" class="col-sm-2 col-form-label">SMTP Port</label>
             <div class="col-sm-10">
-                <input type="number" name="smtp_port" id="smtpPort" class="form-control" value="@config.GetConfig("smtp_port")" />
+                <input type="number" name="smtp_port" id="smtpPort" class="form-control d-inline w-auto" value="@config.GetConfig("smtp_port")" />
             </div>
         </div>
         <div class="row mb-3">

+ 122 - 0
backend/Views/Setting/Register.cshtml

@@ -0,0 +1,122 @@
+@using bitforum.Helpers
+
+@{
+    ViewData["Title"] = "회원가입 설정";
+    var config = ViewBag.Config as Dictionary<string, string>;
+}
+
+<div id="settingBasic" class="container">
+    <h3>@ViewData["Title"]</h3>
+    <hr />
+
+    <partial name="_StatusMessage" />
+
+    <form name="f_admin_write" id="fAdminWrite" method="post" asp-controller="Register" asp-action="Save" autocomplete="off">
+        <div class="row mb-3">
+            <label for="isRegisterBlock" class="col-sm-2 col-form-label">회원가입 차단</label>
+            <div class="col-sm-10 align-content-center">
+                <input type="checkbox" name="is_register_block" id="isRegisterBlock" class="form-check-input" value="1" @(config.GetConfig("is_register_block") == "1" ? "checked" : "") />
+                <label class="form-check-label" for="isRegisterBlock">회원가입을 차단합니다.</label>
+            </div>
+        </div>
+        <div class="row mb-3">
+            <label for="isRegisterEmailAuth" class="col-sm-2 col-form-label">회원가입 시 이메일 인증</label>
+            <div class="col-sm-10 align-content-center">
+                <input type="checkbox" name="register_able" id="isRegisterEmailAuth" class="form-check-input" value="1" @(config.GetConfig("register_able") == "1" ? "checked" : "") />
+                <label class="form-check-label" for="isRegisterEmailAuth">가입 시 이메일 인증을 확인합니다.</label>
+            </div>
+        </div>
+        <hr/>
+        <div class="row mb-3">
+            <label for="passwordMinLength" class="col-sm-2 col-form-label">비밀번호 최소 길이</label>
+            <div class="col-sm-10">
+                <input type="number" name="password_min_length" id="passwordMinLength" class="form-control d-inline w-auto" value="@config.GetConfig("password_min_length")" />
+            </div>
+        </div>
+        <div class="row mb-3">
+            <label for="passwordUppercaseLength" class="col-sm-2 col-form-label">비밀번호 최소 대문자 수</label>
+            <div class="col-sm-10">
+                <input type="number" name="password_uppercase_length" id="passwordUppercaseLength" class="form-control d-inline w-auto" value="@config.GetConfig("password_uppercase_length")" />
+            </div>
+        </div>
+        <div class="row mb-3">
+            <label for="passwordNumbersLength" class="col-sm-2 col-form-label">비밀번호 최소 숫자 수</label>
+            <div class="col-sm-10">
+                <input type="number" name="password_numbers_length" id="passwordNumbersLength" class="form-control d-inline w-auto" value="@config.GetConfig("password_numbers_length")" />
+            </div>
+        </div>
+        <div class="row mb-3">
+            <label for="passwordSpecialcharsLength" class="col-sm-2 col-form-label">비밀번호 최소 특수문자 수</label>
+            <div class="col-sm-10">
+                <input type="number" name="password_specialchars_length" id="passwordSpecialcharsLength" class="form-control d-inline w-auto" value="@config.GetConfig("password_specialchars_length")" />
+                <small class="text-muted form-text d-block">
+                    비밀번호 길이는 최소 4자 이상이어야 하며, 대문자, 숫자, 특수문자를 포함하기를 원하지 않는 경우 0을 입력하면 됩니다. 이 규칙은 회원가입 시, 정보수정 시 적용되며 이미 가입한 회원이 로그인을 하는 경우에는 적용되지 않습니다. 즉 가입 당시 규칙에는 대문자 규칙이 없어서 대문자 없이 회원 가입하였는데, 지금 대문자를 꼭 입력하게끔 규칙을 변경하더라도 기존 회원은 대문자 없는 비밀번호로 로그인이 가능합니다.
+                </small>
+            </div>
+        </div>
+        <hr/>
+        <div class="row mb-3">
+            <label for="deniedNicknameList" class="col-sm-2 col-form-label">금지 별명</label>
+            <div class="col-sm-10">
+                <textarea name="denied_nickname_list" id="deniedNicknameList" class="form-control" rows="3">@config.GetConfig("denied_nickname_list")</textarea>
+                 <small class="text-muted form-text d-block">
+                     제한하고 싶은 닉네임을 쉼표로 구분하여 입력해주세요.
+                 </small>
+            </div>
+        </div>
+        <hr/>
+        <div class="row mb-3">
+            <label for="changeNicknameDay" class="col-sm-2 col-form-label">별명 갱신 주기</label>
+            <div class="col-sm-10">
+                <input type="number" name="change_nickname_day" id="changeNicknameDay" class="form-control d-inline w-auto" value="@config.GetConfig("change_nickname_day")" />
+                  <small class="text-muted form-text d-block">
+                      별명 변경 후 해당일 동안 바꿀 수 없습니다, 0 으로 설정하면 항상 변경 가능
+                 </small>
+            </div>
+        </div>
+        <div class="row mb-3">
+            <label for="changeEmailDay" class="col-sm-2 col-form-label">이메일 갱신 주기</label>
+            <div class="col-sm-10">
+                <input type="number" name="change_email_day" id="changeEmailDay" class="form-control d-inline w-auto" value="@config.GetConfig("change_email_day")" />
+                  <small class="text-muted form-text d-block">
+                      이메일 변경 후 해당일 동안 바꿀 수 없습니다, 0 으로 설정하면 항상 변경 가능
+                 </small>
+            </div>
+        </div>
+        <div class="row mb-3">
+            <label for="changePasswordDay" class="col-sm-2 col-form-label">비밀번호 갱신 주기</label>
+            <div class="col-sm-10">
+                <input type="number" name="change_password_day" id="changePasswordDay" class="form-control d-inline w-auto" value="@config.GetConfig("change_password_day")" />
+                  <small class="text-muted form-text d-block">
+                      일, 일정기간이 지나면 비밀번호 변경을 하도록 유도하는 기능입니다. (사용하지 않음 : 0 입력)
+                 </small>
+            </div>
+        </div>
+        <hr/>
+        <div class="row mb-3">
+            <label for="maxLoginTryCount" class="col-sm-2 col-form-label">로그인 시도 제한 횟수</label>
+            <div class="col-sm-10">
+                <input type="number" name="max_login_try_count" id="maxLoginTryCount" class="form-control d-inline w-auto" value="@config.GetConfig("max_login_try_count")" />
+                  <small class="text-muted form-text d-block">
+                      정해진 시간 안에 허용되는 로그인 시도 횟수를 입력하십시오. 짧은 시간 동안 하나의 IP에서 시도할 수 있는 로그인 횟수에 제한을 둡니다.
+                 </small>
+            </div>
+        </div>
+        <div class="row mb-3">
+            <label for="maxLoginTryLimitSecond" class="col-sm-2 col-form-label">로그인 시도 제한시간</label>
+            <div class="col-sm-10">
+                <input type="number" name="max_login_try_limit_second" id="maxLoginTryLimitSecond" class="form-control d-inline w-auto d-inline w-auto" value="@config.GetConfig("max_login_try_limit_second")" />
+                  <small class="text-muted form-text d-block">
+                      위에서 설정한 횟수 이상 로그인실실패하였을 경우, 해당 초 동안 로그인 시도를 할 수 없습니다.
+                 </small>
+            </div>
+        </div>
+        <hr/>
+        <div class="row">
+            <div class="col text-center p-3">
+                <button type="submit" class="btn btn-success">저장하기</button>
+            </div>
+        </div>
+        <br />
+    </form>
+</div>

+ 3 - 3
backend/Views/Setting/Test.cshtml

@@ -43,15 +43,15 @@
     <div class="mb-3 row">
         <label class="col-sm-2 col-form-label">Send E-mail</label>
         <div class="col-sm-10">
-            <input type="text" readonly class="form-control-plaintext" value="@config.GetConfig("from_email")" />
+            <input type="text" readonly class="form-control-plaintext" value="@config.GetConfig("smtp_from_email")" />
         </div>
     </div>
     <div class="row">
         <label for="email" class="col-sm-2 col-form-label">Receive E-mail</label>
         <div class="col-sm-10">
             <form name="f_admin_write" id="fAdminWrite" method="post" asp-controller="Test" asp-action="Send" autocomplete="off">
-                <input type="email" name="email" id="email" class="form-control" placeholder="수신받을 이메일을 입력하세요." />
-                <button type="submit" class="btn btn-success mt-2">보내기</button>
+                <input type="email" name="email" id="email" class="form-control w-auto d-inline" size="35" placeholder="수신받을 이메일을 입력하세요." />
+                <button type="submit" class="btn btn-success">보내기</button>
             </form>
         </div>
     </div>

+ 3 - 2
backend/Views/Shared/_LoginPartial.cshtml

@@ -1,7 +1,8 @@
 @using Microsoft.AspNetCore.Identity
+@using bitforum.Models.User
 
-@inject SignInManager<IdentityUser> SignInManager
-@inject UserManager<IdentityUser> UserManager
+@inject SignInManager<ApplicationUser> SignInManager
+@inject UserManager<ApplicationUser> UserManager
 
 <ul class="navbar-nav">
 @if (SignInManager.IsSignedIn(User))

+ 0 - 7
backend/appsettings.json

@@ -19,12 +19,5 @@
     "ConnectionStrings": {
         //"DefaultConnection": "Server=192.168.0.110;Database=bitforum;Trusted_Connection=True;MultipleActiveResultSets=true"
         "DefaultConnection": "Server=192.168.0.110;Database=bitforum;User ID=sa;Password=@@20120726KKh;Encrypt=False;"
-    },
-
-    "EmailSettings": {
-        "SmtpServer": "smtp.gmail.com",
-        "SmtpPort": 587,
-        "FromEmail": "chorongski@gmail.com",
-        "EmailPassword": "lfxciuwuopjlfdzc"
     }
 }

+ 0 - 7
backend/bin/Debug/net8.0/appsettings.json

@@ -19,12 +19,5 @@
     "ConnectionStrings": {
         //"DefaultConnection": "Server=192.168.0.110;Database=bitforum;Trusted_Connection=True;MultipleActiveResultSets=true"
         "DefaultConnection": "Server=192.168.0.110;Database=bitforum;User ID=sa;Password=@@20120726KKh;Encrypt=False;"
-    },
-
-    "EmailSettings": {
-        "SmtpServer": "smtp.gmail.com",
-        "SmtpPort": 587,
-        "FromEmail": "chorongski@gmail.com",
-        "EmailPassword": "lfxciuwuopjlfdzc"
     }
 }

BIN
backend/bin/Debug/net8.0/bitforum.dll


BIN
backend/bin/Debug/net8.0/bitforum.exe


BIN
backend/bin/Debug/net8.0/bitforum.pdb


+ 24 - 24
backend/bin/Debug/net8.0/bitforum.staticwebassets.endpoints.json

@@ -2249,7 +2249,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:04 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:11 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2294,7 +2294,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:04 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:11 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2331,7 +2331,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2368,7 +2368,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2413,7 +2413,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2450,7 +2450,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2495,7 +2495,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2532,7 +2532,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2577,7 +2577,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2614,7 +2614,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2659,7 +2659,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2704,7 +2704,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2741,7 +2741,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2786,7 +2786,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2961,7 +2961,7 @@
       ]
     },
     {
-      "Route": "js/site.es0zx3fd95.js",
+      "Route": "js/site.4a80i8ynpk.js",
       "AssetFile": "js/site.js",
       "Selectors": [],
       "ResponseHeaders": [
@@ -2975,7 +2975,7 @@
         },
         {
           "Name": "Content-Length",
-          "Value": "3176"
+          "Value": "3419"
         },
         {
           "Name": "Content-Type",
@@ -2983,21 +2983,21 @@
         },
         {
           "Name": "ETag",
-          "Value": "\"vsuucnLqyJZOfT1tAqZr34i5pW4wjC0G2/E5ZCv1Dvc=\""
+          "Value": "\"FITMTC/ZAZWo7IhHMLw8U/kpuVpkFx3EH2xwdIvHXqc=\""
         },
         {
           "Name": "Last-Modified",
-          "Value": "Mon, 13 Jan 2025 10:33:37 GMT"
+          "Value": "Thu, 16 Jan 2025 09:40:22 GMT"
         }
       ],
       "EndpointProperties": [
         {
           "Name": "fingerprint",
-          "Value": "es0zx3fd95"
+          "Value": "4a80i8ynpk"
         },
         {
           "Name": "integrity",
-          "Value": "sha256-vsuucnLqyJZOfT1tAqZr34i5pW4wjC0G2/E5ZCv1Dvc="
+          "Value": "sha256-FITMTC/ZAZWo7IhHMLw8U/kpuVpkFx3EH2xwdIvHXqc="
         },
         {
           "Name": "label",
@@ -3020,7 +3020,7 @@
         },
         {
           "Name": "Content-Length",
-          "Value": "3176"
+          "Value": "3419"
         },
         {
           "Name": "Content-Type",
@@ -3028,17 +3028,17 @@
         },
         {
           "Name": "ETag",
-          "Value": "\"vsuucnLqyJZOfT1tAqZr34i5pW4wjC0G2/E5ZCv1Dvc=\""
+          "Value": "\"FITMTC/ZAZWo7IhHMLw8U/kpuVpkFx3EH2xwdIvHXqc=\""
         },
         {
           "Name": "Last-Modified",
-          "Value": "Mon, 13 Jan 2025 10:33:37 GMT"
+          "Value": "Thu, 16 Jan 2025 09:40:22 GMT"
         }
       ],
       "EndpointProperties": [
         {
           "Name": "integrity",
-          "Value": "sha256-vsuucnLqyJZOfT1tAqZr34i5pW4wjC0G2/E5ZCv1Dvc="
+          "Value": "sha256-FITMTC/ZAZWo7IhHMLw8U/kpuVpkFx3EH2xwdIvHXqc="
         }
       ]
     },

BIN
backend/obj/Debug/net8.0/apphost.exe


+ 1 - 1
backend/obj/Debug/net8.0/bitforum.AssemblyInfo.cs

@@ -15,7 +15,7 @@ using System.Reflection;
 [assembly: System.Reflection.AssemblyCompanyAttribute("bitforum")]
 [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
 [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
-[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+ec699fe8e114d2670159876880c2e9a0f358239e")]
+[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+d0dac867f954604339372cf0cc37d6b3ae08dbb3")]
 [assembly: System.Reflection.AssemblyProductAttribute("bitforum")]
 [assembly: System.Reflection.AssemblyTitleAttribute("bitforum")]
 [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

+ 1 - 1
backend/obj/Debug/net8.0/bitforum.AssemblyInfoInputs.cache

@@ -1 +1 @@
-a1225150368b45df7dfbeeca0b60ad24fc72ffec8d3af0fd020604ad6d324eaa
+e6ec48d21fa2a2b16952a30d8812051d863652b2d76fe16cb95efb05fc2f0387

+ 20 - 0
backend/obj/Debug/net8.0/bitforum.GeneratedMSBuildEditorConfig.editorconfig

@@ -216,6 +216,22 @@ build_metadata.AdditionalFiles.CssScope =
 build_metadata.AdditionalFiles.TargetPath = Vmlld3NcSG9tZVxQcml2YWN5LmNzaHRtbA==
 build_metadata.AdditionalFiles.CssScope = 
 
+[E:/workspace/bitforum/backend/Views/Page/Document/Edit.cshtml]
+build_metadata.AdditionalFiles.TargetPath = Vmlld3NcUGFnZVxEb2N1bWVudFxFZGl0LmNzaHRtbA==
+build_metadata.AdditionalFiles.CssScope = 
+
+[E:/workspace/bitforum/backend/Views/Page/Document/Index.cshtml]
+build_metadata.AdditionalFiles.TargetPath = Vmlld3NcUGFnZVxEb2N1bWVudFxJbmRleC5jc2h0bWw=
+build_metadata.AdditionalFiles.CssScope = 
+
+[E:/workspace/bitforum/backend/Views/Page/Document/Write.cshtml]
+build_metadata.AdditionalFiles.TargetPath = Vmlld3NcUGFnZVxEb2N1bWVudFxXcml0ZS5jc2h0bWw=
+build_metadata.AdditionalFiles.CssScope = 
+
+[E:/workspace/bitforum/backend/Views/Page/Faq/Index.cshtml]
+build_metadata.AdditionalFiles.TargetPath = Vmlld3NcUGFnZVxGYXFcSW5kZXguY3NodG1s
+build_metadata.AdditionalFiles.CssScope = 
+
 [E:/workspace/bitforum/backend/Views/Setting/Basic.cshtml]
 build_metadata.AdditionalFiles.TargetPath = Vmlld3NcU2V0dGluZ1xCYXNpYy5jc2h0bWw=
 build_metadata.AdditionalFiles.CssScope = 
@@ -232,6 +248,10 @@ build_metadata.AdditionalFiles.CssScope =
 build_metadata.AdditionalFiles.TargetPath = Vmlld3NcU2V0dGluZ1xNZXRhLmNzaHRtbA==
 build_metadata.AdditionalFiles.CssScope = 
 
+[E:/workspace/bitforum/backend/Views/Setting/Register.cshtml]
+build_metadata.AdditionalFiles.TargetPath = Vmlld3NcU2V0dGluZ1xSZWdpc3Rlci5jc2h0bWw=
+build_metadata.AdditionalFiles.CssScope = 
+
 [E:/workspace/bitforum/backend/Views/Setting/Server.cshtml]
 build_metadata.AdditionalFiles.TargetPath = Vmlld3NcU2V0dGluZ1xTZXJ2ZXIuY3NodG1s
 build_metadata.AdditionalFiles.CssScope = 

+ 4 - 3
backend/obj/Debug/net8.0/bitforum.MvcApplicationPartsAssemblyInfo.cs

@@ -1,9 +1,10 @@
 //------------------------------------------------------------------------------
 // <auto-generated>
-//     This code was generated by a tool.
+//     이 코드는 도구를 사용하여 생성되었습니다.
+//     런타임 버전:4.0.30319.42000
 //
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
+//     파일 내용을 변경하면 잘못된 동작이 발생할 수 있으며, 코드를 다시 생성하면
+//     이러한 변경 내용이 손실됩니다.
 // </auto-generated>
 //------------------------------------------------------------------------------
 

+ 1 - 1
backend/obj/Debug/net8.0/bitforum.csproj.CoreCompileInputs.cache

@@ -1 +1 @@
-c53e3ff51434225b7f1402bcf898ea85eca50439dea4fdd69e5a768ceb365e0e
+c5b279fecc0a2a5e5fc321eb8eb9114a86197051585e88cafa83fddc8abff7d8

+ 0 - 1
backend/obj/Debug/net8.0/bitforum.csproj.FileListAbsolute.txt

@@ -262,4 +262,3 @@ E:\workspace\bitforum\backend\obj\Debug\net8.0\refint\bitforum.dll
 E:\workspace\bitforum\backend\obj\Debug\net8.0\bitforum.pdb
 E:\workspace\bitforum\backend\obj\Debug\net8.0\bitforum.genruntimeconfig.cache
 E:\workspace\bitforum\backend\obj\Debug\net8.0\ref\bitforum.dll
-E:\workspace\bitforum\backend\obj\Debug\net8.0\staticwebassets.upToDateCheck.txt

BIN
backend/obj/Debug/net8.0/bitforum.dll


BIN
backend/obj/Debug/net8.0/bitforum.pdb


BIN
backend/obj/Debug/net8.0/ref/bitforum.dll


BIN
backend/obj/Debug/net8.0/refint/bitforum.dll


+ 24 - 24
backend/obj/Debug/net8.0/staticwebassets.build.endpoints.json

@@ -2249,7 +2249,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:04 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:11 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2294,7 +2294,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:04 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:11 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2331,7 +2331,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2368,7 +2368,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2413,7 +2413,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2450,7 +2450,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2495,7 +2495,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2532,7 +2532,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2577,7 +2577,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2614,7 +2614,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2659,7 +2659,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2704,7 +2704,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2741,7 +2741,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2786,7 +2786,7 @@
         },
         {
           "Name": "Last-Modified",
-          "Value": "Wed, 15 Jan 2025 12:22:02 GMT"
+          "Value": "Wed, 15 Jan 2025 13:34:04 GMT"
         }
       ],
       "EndpointProperties": [
@@ -2961,7 +2961,7 @@
       ]
     },
     {
-      "Route": "js/site.es0zx3fd95.js",
+      "Route": "js/site.4a80i8ynpk.js",
       "AssetFile": "js/site.js",
       "Selectors": [],
       "ResponseHeaders": [
@@ -2975,7 +2975,7 @@
         },
         {
           "Name": "Content-Length",
-          "Value": "3176"
+          "Value": "3419"
         },
         {
           "Name": "Content-Type",
@@ -2983,21 +2983,21 @@
         },
         {
           "Name": "ETag",
-          "Value": "\"vsuucnLqyJZOfT1tAqZr34i5pW4wjC0G2/E5ZCv1Dvc=\""
+          "Value": "\"FITMTC/ZAZWo7IhHMLw8U/kpuVpkFx3EH2xwdIvHXqc=\""
         },
         {
           "Name": "Last-Modified",
-          "Value": "Mon, 13 Jan 2025 10:33:37 GMT"
+          "Value": "Thu, 16 Jan 2025 09:40:22 GMT"
         }
       ],
       "EndpointProperties": [
         {
           "Name": "fingerprint",
-          "Value": "es0zx3fd95"
+          "Value": "4a80i8ynpk"
         },
         {
           "Name": "integrity",
-          "Value": "sha256-vsuucnLqyJZOfT1tAqZr34i5pW4wjC0G2/E5ZCv1Dvc="
+          "Value": "sha256-FITMTC/ZAZWo7IhHMLw8U/kpuVpkFx3EH2xwdIvHXqc="
         },
         {
           "Name": "label",
@@ -3020,7 +3020,7 @@
         },
         {
           "Name": "Content-Length",
-          "Value": "3176"
+          "Value": "3419"
         },
         {
           "Name": "Content-Type",
@@ -3028,17 +3028,17 @@
         },
         {
           "Name": "ETag",
-          "Value": "\"vsuucnLqyJZOfT1tAqZr34i5pW4wjC0G2/E5ZCv1Dvc=\""
+          "Value": "\"FITMTC/ZAZWo7IhHMLw8U/kpuVpkFx3EH2xwdIvHXqc=\""
         },
         {
           "Name": "Last-Modified",
-          "Value": "Mon, 13 Jan 2025 10:33:37 GMT"
+          "Value": "Thu, 16 Jan 2025 09:40:22 GMT"
         }
       ],
       "EndpointProperties": [
         {
           "Name": "integrity",
-          "Value": "sha256-vsuucnLqyJZOfT1tAqZr34i5pW4wjC0G2/E5ZCv1Dvc="
+          "Value": "sha256-FITMTC/ZAZWo7IhHMLw8U/kpuVpkFx3EH2xwdIvHXqc="
         }
       ]
     },

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 212 - 212
backend/obj/Debug/net8.0/staticwebassets.build.json


+ 0 - 293
backend/obj/Debug/net8.0/staticwebassets.upToDateCheck.txt

@@ -1,293 +0,0 @@
-wwwroot\css\account.css
-wwwroot\css\account.min.css
-wwwroot\css\admin.css
-wwwroot\css\admin.min.css
-wwwroot\css\site.css
-wwwroot\css\site.min.css
-wwwroot\images\favicon.ico
-wwwroot\js\func.js
-wwwroot\js\site.js
-wwwroot\lib\bootstrap\dist\css\bootstrap.css
-wwwroot\lib\bootstrap\dist\css\bootstrap.css.map
-wwwroot\lib\bootstrap\dist\css\bootstrap.min.css
-wwwroot\lib\bootstrap\dist\css\bootstrap.min.css.map
-wwwroot\lib\bootstrap\dist\css\bootstrap.rtl.css
-wwwroot\lib\bootstrap\dist\css\bootstrap.rtl.css.map
-wwwroot\lib\bootstrap\dist\css\bootstrap.rtl.min.css
-wwwroot\lib\bootstrap\dist\css\bootstrap.rtl.min.css.map
-wwwroot\lib\bootstrap\dist\css\bootstrap-grid.css
-wwwroot\lib\bootstrap\dist\css\bootstrap-grid.css.map
-wwwroot\lib\bootstrap\dist\css\bootstrap-grid.min.css
-wwwroot\lib\bootstrap\dist\css\bootstrap-grid.min.css.map
-wwwroot\lib\bootstrap\dist\css\bootstrap-grid.rtl.css
-wwwroot\lib\bootstrap\dist\css\bootstrap-grid.rtl.css.map
-wwwroot\lib\bootstrap\dist\css\bootstrap-grid.rtl.min.css
-wwwroot\lib\bootstrap\dist\css\bootstrap-grid.rtl.min.css.map
-wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.css
-wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.css.map
-wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.min.css
-wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.min.css.map
-wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.rtl.css
-wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.rtl.css.map
-wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.rtl.min.css
-wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.rtl.min.css.map
-wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.css
-wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.css.map
-wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.min.css
-wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.min.css.map
-wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.rtl.css
-wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.rtl.css.map
-wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.rtl.min.css
-wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.rtl.min.css.map
-wwwroot\lib\bootstrap\dist\js\bootstrap.bundle.js
-wwwroot\lib\bootstrap\dist\js\bootstrap.bundle.js.map
-wwwroot\lib\bootstrap\dist\js\bootstrap.bundle.min.js
-wwwroot\lib\bootstrap\dist\js\bootstrap.bundle.min.js.map
-wwwroot\lib\bootstrap\dist\js\bootstrap.esm.js
-wwwroot\lib\bootstrap\dist\js\bootstrap.esm.js.map
-wwwroot\lib\bootstrap\dist\js\bootstrap.esm.min.js
-wwwroot\lib\bootstrap\dist\js\bootstrap.esm.min.js.map
-wwwroot\lib\bootstrap\dist\js\bootstrap.js
-wwwroot\lib\bootstrap\dist\js\bootstrap.js.map
-wwwroot\lib\bootstrap\dist\js\bootstrap.min.js
-wwwroot\lib\bootstrap\dist\js\bootstrap.min.js.map
-wwwroot\lib\bootstrap\LICENSE
-wwwroot\lib\ckeditor\ckeditor5\ckeditor5.css
-wwwroot\lib\ckeditor\ckeditor5\ckeditor5.css.map
-wwwroot\lib\ckeditor\ckeditor5\ckeditor5.js
-wwwroot\lib\ckeditor\ckeditor5\ckeditor5.js.map
-wwwroot\lib\ckeditor\ckeditor5\ckeditor5.umd.js
-wwwroot\lib\ckeditor\ckeditor5\ckeditor5.umd.js.map
-wwwroot\lib\ckeditor\ckeditor5\ckeditor5-content.css
-wwwroot\lib\ckeditor\ckeditor5\ckeditor5-editor.css
-wwwroot\lib\ckeditor\ckeditor5\translations\af.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\af.js
-wwwroot\lib\ckeditor\ckeditor5\translations\af.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ar.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\ar.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ar.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ast.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\ast.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ast.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\az.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\az.js
-wwwroot\lib\ckeditor\ckeditor5\translations\az.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\bg.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\bg.js
-wwwroot\lib\ckeditor\ckeditor5\translations\bg.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\bn.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\bn.js
-wwwroot\lib\ckeditor\ckeditor5\translations\bn.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\bs.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\bs.js
-wwwroot\lib\ckeditor\ckeditor5\translations\bs.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ca.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\ca.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ca.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\cs.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\cs.js
-wwwroot\lib\ckeditor\ckeditor5\translations\cs.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\da.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\da.js
-wwwroot\lib\ckeditor\ckeditor5\translations\da.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\de.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\de.js
-wwwroot\lib\ckeditor\ckeditor5\translations\de.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\de-ch.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\de-ch.js
-wwwroot\lib\ckeditor\ckeditor5\translations\de-ch.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\el.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\el.js
-wwwroot\lib\ckeditor\ckeditor5\translations\el.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\en.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\en.js
-wwwroot\lib\ckeditor\ckeditor5\translations\en.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\en-au.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\en-au.js
-wwwroot\lib\ckeditor\ckeditor5\translations\en-au.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\en-gb.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\en-gb.js
-wwwroot\lib\ckeditor\ckeditor5\translations\en-gb.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\eo.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\eo.js
-wwwroot\lib\ckeditor\ckeditor5\translations\eo.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\es.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\es.js
-wwwroot\lib\ckeditor\ckeditor5\translations\es.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\es-co.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\es-co.js
-wwwroot\lib\ckeditor\ckeditor5\translations\es-co.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\et.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\et.js
-wwwroot\lib\ckeditor\ckeditor5\translations\et.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\eu.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\eu.js
-wwwroot\lib\ckeditor\ckeditor5\translations\eu.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\fa.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\fa.js
-wwwroot\lib\ckeditor\ckeditor5\translations\fa.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\fi.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\fi.js
-wwwroot\lib\ckeditor\ckeditor5\translations\fi.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\fr.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\fr.js
-wwwroot\lib\ckeditor\ckeditor5\translations\fr.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\gl.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\gl.js
-wwwroot\lib\ckeditor\ckeditor5\translations\gl.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\gu.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\gu.js
-wwwroot\lib\ckeditor\ckeditor5\translations\gu.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\he.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\he.js
-wwwroot\lib\ckeditor\ckeditor5\translations\he.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\hi.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\hi.js
-wwwroot\lib\ckeditor\ckeditor5\translations\hi.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\hr.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\hr.js
-wwwroot\lib\ckeditor\ckeditor5\translations\hr.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\hu.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\hu.js
-wwwroot\lib\ckeditor\ckeditor5\translations\hu.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\hy.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\hy.js
-wwwroot\lib\ckeditor\ckeditor5\translations\hy.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\id.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\id.js
-wwwroot\lib\ckeditor\ckeditor5\translations\id.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\it.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\it.js
-wwwroot\lib\ckeditor\ckeditor5\translations\it.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ja.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\ja.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ja.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\jv.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\jv.js
-wwwroot\lib\ckeditor\ckeditor5\translations\jv.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\kk.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\kk.js
-wwwroot\lib\ckeditor\ckeditor5\translations\kk.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\km.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\km.js
-wwwroot\lib\ckeditor\ckeditor5\translations\km.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\kn.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\kn.js
-wwwroot\lib\ckeditor\ckeditor5\translations\kn.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ko.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\ko.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ko.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ku.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\ku.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ku.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\lt.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\lt.js
-wwwroot\lib\ckeditor\ckeditor5\translations\lt.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\lv.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\lv.js
-wwwroot\lib\ckeditor\ckeditor5\translations\lv.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ms.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\ms.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ms.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\nb.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\nb.js
-wwwroot\lib\ckeditor\ckeditor5\translations\nb.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ne.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\ne.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ne.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\nl.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\nl.js
-wwwroot\lib\ckeditor\ckeditor5\translations\nl.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\no.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\no.js
-wwwroot\lib\ckeditor\ckeditor5\translations\no.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\oc.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\oc.js
-wwwroot\lib\ckeditor\ckeditor5\translations\oc.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\pl.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\pl.js
-wwwroot\lib\ckeditor\ckeditor5\translations\pl.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\pt.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\pt.js
-wwwroot\lib\ckeditor\ckeditor5\translations\pt.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\pt-br.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\pt-br.js
-wwwroot\lib\ckeditor\ckeditor5\translations\pt-br.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ro.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\ro.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ro.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ru.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\ru.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ru.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\si.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\si.js
-wwwroot\lib\ckeditor\ckeditor5\translations\si.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\sk.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\sk.js
-wwwroot\lib\ckeditor\ckeditor5\translations\sk.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\sl.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\sl.js
-wwwroot\lib\ckeditor\ckeditor5\translations\sl.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\sq.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\sq.js
-wwwroot\lib\ckeditor\ckeditor5\translations\sq.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\sr.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\sr.js
-wwwroot\lib\ckeditor\ckeditor5\translations\sr.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\sr-latn.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\sr-latn.js
-wwwroot\lib\ckeditor\ckeditor5\translations\sr-latn.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\sv.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\sv.js
-wwwroot\lib\ckeditor\ckeditor5\translations\sv.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\th.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\th.js
-wwwroot\lib\ckeditor\ckeditor5\translations\th.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ti.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\ti.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ti.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\tk.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\tk.js
-wwwroot\lib\ckeditor\ckeditor5\translations\tk.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\tr.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\tr.js
-wwwroot\lib\ckeditor\ckeditor5\translations\tr.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\tt.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\tt.js
-wwwroot\lib\ckeditor\ckeditor5\translations\tt.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ug.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\ug.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ug.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\uk.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\uk.js
-wwwroot\lib\ckeditor\ckeditor5\translations\uk.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ur.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\ur.js
-wwwroot\lib\ckeditor\ckeditor5\translations\ur.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\uz.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\uz.js
-wwwroot\lib\ckeditor\ckeditor5\translations\uz.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\vi.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\vi.js
-wwwroot\lib\ckeditor\ckeditor5\translations\vi.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\zh.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\zh.js
-wwwroot\lib\ckeditor\ckeditor5\translations\zh.umd.js
-wwwroot\lib\ckeditor\ckeditor5\translations\zh-cn.d.ts
-wwwroot\lib\ckeditor\ckeditor5\translations\zh-cn.js
-wwwroot\lib\ckeditor\ckeditor5\translations\zh-cn.umd.js
-wwwroot\lib\ckeditor\index.html
-wwwroot\lib\ckeditor\LICENSE.md
-wwwroot\lib\ckeditor\README.md
-wwwroot\lib\jquery\dist\jquery.js
-wwwroot\lib\jquery\dist\jquery.min.js
-wwwroot\lib\jquery\dist\jquery.min.map
-wwwroot\lib\jquery\LICENSE.txt
-wwwroot\lib\jquery-validation\dist\additional-methods.js
-wwwroot\lib\jquery-validation\dist\additional-methods.min.js
-wwwroot\lib\jquery-validation\dist\jquery.validate.js
-wwwroot\lib\jquery-validation\dist\jquery.validate.min.js
-wwwroot\lib\jquery-validation\LICENSE.md
-wwwroot\lib\jquery-validation-unobtrusive\jquery.validate.unobtrusive.js
-wwwroot\lib\jquery-validation-unobtrusive\jquery.validate.unobtrusive.min.js
-wwwroot\lib\jquery-validation-unobtrusive\LICENSE.txt

+ 19 - 19
backend/obj/Debug/net8.0/staticwebassets/msbuild.bitforum.Microsoft.AspNetCore.StaticWebAssetEndpoints.props

@@ -4,85 +4,85 @@
       <AssetFile>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\staticwebassets\bitforum.erjk5fla2s.bundle.scp.css'))</AssetFile>
       <Selectors><![CDATA[[]]]></Selectors>
       <EndpointProperties><![CDATA[[{"Name":"integrity","Value":"sha256-9s20qVWcEaT6PkL04xzKZr5WANEDo\u002BjqXWaUSt2Y5wU="}]]]></EndpointProperties>
-      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"2249"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u00229s20qVWcEaT6PkL04xzKZr5WANEDo\u002BjqXWaUSt2Y5wU=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 12:22:04 GMT"}]]]></ResponseHeaders>
+      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"2249"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u00229s20qVWcEaT6PkL04xzKZr5WANEDo\u002BjqXWaUSt2Y5wU=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 13:34:11 GMT"}]]]></ResponseHeaders>
     </StaticWebAssetEndpoint>
     <StaticWebAssetEndpoint Include="_content/bitforum/bitforum.erjk5fla2s.bundle.scp.css">
       <AssetFile>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\staticwebassets\bitforum.erjk5fla2s.bundle.scp.css'))</AssetFile>
       <Selectors><![CDATA[[]]]></Selectors>
       <EndpointProperties><![CDATA[[{"Name":"fingerprint","Value":"erjk5fla2s"},{"Name":"integrity","Value":"sha256-9s20qVWcEaT6PkL04xzKZr5WANEDo\u002BjqXWaUSt2Y5wU="},{"Name":"label","Value":"_content/bitforum/bitforum.bundle.scp.css"}]]]></EndpointProperties>
-      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"2249"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u00229s20qVWcEaT6PkL04xzKZr5WANEDo\u002BjqXWaUSt2Y5wU=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 12:22:04 GMT"}]]]></ResponseHeaders>
+      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"2249"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u00229s20qVWcEaT6PkL04xzKZr5WANEDo\u002BjqXWaUSt2Y5wU=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 13:34:11 GMT"}]]]></ResponseHeaders>
     </StaticWebAssetEndpoint>
     <StaticWebAssetEndpoint Include="_content/bitforum/css/account.css">
       <AssetFile>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\staticwebassets\css\account.css'))</AssetFile>
       <Selectors><![CDATA[[]]]></Selectors>
       <EndpointProperties><![CDATA[[{"Name":"integrity","Value":"sha256-sZwptD6HodRymlH\u002B5c4WIT3NVxTkUrPPKDXtgv71NS8="}]]]></EndpointProperties>
-      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"997"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022sZwptD6HodRymlH\u002B5c4WIT3NVxTkUrPPKDXtgv71NS8=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 12:22:02 GMT"}]]]></ResponseHeaders>
+      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"997"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022sZwptD6HodRymlH\u002B5c4WIT3NVxTkUrPPKDXtgv71NS8=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 13:34:04 GMT"}]]]></ResponseHeaders>
     </StaticWebAssetEndpoint>
     <StaticWebAssetEndpoint Include="_content/bitforum/css/account.min.3dzx742fuu.css">
       <AssetFile>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\staticwebassets\css\account.min.css'))</AssetFile>
       <Selectors><![CDATA[[]]]></Selectors>
       <EndpointProperties><![CDATA[[{"Name":"fingerprint","Value":"3dzx742fuu"},{"Name":"integrity","Value":"sha256-RwiQYhnMLToQzve3hgmYNVM1qBKa05xtYo58oAwOX\u002BQ="},{"Name":"label","Value":"_content/bitforum/css/account.min.css"}]]]></EndpointProperties>
-      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"999"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022RwiQYhnMLToQzve3hgmYNVM1qBKa05xtYo58oAwOX\u002BQ=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 12:22:02 GMT"}]]]></ResponseHeaders>
+      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"999"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022RwiQYhnMLToQzve3hgmYNVM1qBKa05xtYo58oAwOX\u002BQ=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 13:34:04 GMT"}]]]></ResponseHeaders>
     </StaticWebAssetEndpoint>
     <StaticWebAssetEndpoint Include="_content/bitforum/css/account.min.css">
       <AssetFile>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\staticwebassets\css\account.min.css'))</AssetFile>
       <Selectors><![CDATA[[]]]></Selectors>
       <EndpointProperties><![CDATA[[{"Name":"integrity","Value":"sha256-RwiQYhnMLToQzve3hgmYNVM1qBKa05xtYo58oAwOX\u002BQ="}]]]></EndpointProperties>
-      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"999"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022RwiQYhnMLToQzve3hgmYNVM1qBKa05xtYo58oAwOX\u002BQ=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 12:22:02 GMT"}]]]></ResponseHeaders>
+      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"999"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022RwiQYhnMLToQzve3hgmYNVM1qBKa05xtYo58oAwOX\u002BQ=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 13:34:04 GMT"}]]]></ResponseHeaders>
     </StaticWebAssetEndpoint>
     <StaticWebAssetEndpoint Include="_content/bitforum/css/account.t5us5ky8m2.css">
       <AssetFile>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\staticwebassets\css\account.css'))</AssetFile>
       <Selectors><![CDATA[[]]]></Selectors>
       <EndpointProperties><![CDATA[[{"Name":"fingerprint","Value":"t5us5ky8m2"},{"Name":"integrity","Value":"sha256-sZwptD6HodRymlH\u002B5c4WIT3NVxTkUrPPKDXtgv71NS8="},{"Name":"label","Value":"_content/bitforum/css/account.css"}]]]></EndpointProperties>
-      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"997"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022sZwptD6HodRymlH\u002B5c4WIT3NVxTkUrPPKDXtgv71NS8=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 12:22:02 GMT"}]]]></ResponseHeaders>
+      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"997"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022sZwptD6HodRymlH\u002B5c4WIT3NVxTkUrPPKDXtgv71NS8=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 13:34:04 GMT"}]]]></ResponseHeaders>
     </StaticWebAssetEndpoint>
     <StaticWebAssetEndpoint Include="_content/bitforum/css/admin.css">
       <AssetFile>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\staticwebassets\css\admin.css'))</AssetFile>
       <Selectors><![CDATA[[]]]></Selectors>
       <EndpointProperties><![CDATA[[{"Name":"integrity","Value":"sha256-lkcDNEB5lcFJ4FNyO4UgORDBuqBc9LEytJ2PvSRDEP4="}]]]></EndpointProperties>
-      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"153"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022lkcDNEB5lcFJ4FNyO4UgORDBuqBc9LEytJ2PvSRDEP4=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 12:22:02 GMT"}]]]></ResponseHeaders>
+      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"153"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022lkcDNEB5lcFJ4FNyO4UgORDBuqBc9LEytJ2PvSRDEP4=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 13:34:04 GMT"}]]]></ResponseHeaders>
     </StaticWebAssetEndpoint>
     <StaticWebAssetEndpoint Include="_content/bitforum/css/admin.illdtnevdp.css">
       <AssetFile>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\staticwebassets\css\admin.css'))</AssetFile>
       <Selectors><![CDATA[[]]]></Selectors>
       <EndpointProperties><![CDATA[[{"Name":"fingerprint","Value":"illdtnevdp"},{"Name":"integrity","Value":"sha256-lkcDNEB5lcFJ4FNyO4UgORDBuqBc9LEytJ2PvSRDEP4="},{"Name":"label","Value":"_content/bitforum/css/admin.css"}]]]></EndpointProperties>
-      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"153"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022lkcDNEB5lcFJ4FNyO4UgORDBuqBc9LEytJ2PvSRDEP4=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 12:22:02 GMT"}]]]></ResponseHeaders>
+      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"153"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022lkcDNEB5lcFJ4FNyO4UgORDBuqBc9LEytJ2PvSRDEP4=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 13:34:04 GMT"}]]]></ResponseHeaders>
     </StaticWebAssetEndpoint>
     <StaticWebAssetEndpoint Include="_content/bitforum/css/admin.min.css">
       <AssetFile>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\staticwebassets\css\admin.min.css'))</AssetFile>
       <Selectors><![CDATA[[]]]></Selectors>
       <EndpointProperties><![CDATA[[{"Name":"integrity","Value":"sha256-zm/B82eA9Z4lUjeURB5A5aAzsnKX3qRgusT8bPLamBs="}]]]></EndpointProperties>
-      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"154"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022zm/B82eA9Z4lUjeURB5A5aAzsnKX3qRgusT8bPLamBs=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 12:22:02 GMT"}]]]></ResponseHeaders>
+      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"154"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022zm/B82eA9Z4lUjeURB5A5aAzsnKX3qRgusT8bPLamBs=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 13:34:04 GMT"}]]]></ResponseHeaders>
     </StaticWebAssetEndpoint>
     <StaticWebAssetEndpoint Include="_content/bitforum/css/admin.min.qxtxag1zp9.css">
       <AssetFile>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\staticwebassets\css\admin.min.css'))</AssetFile>
       <Selectors><![CDATA[[]]]></Selectors>
       <EndpointProperties><![CDATA[[{"Name":"fingerprint","Value":"qxtxag1zp9"},{"Name":"integrity","Value":"sha256-zm/B82eA9Z4lUjeURB5A5aAzsnKX3qRgusT8bPLamBs="},{"Name":"label","Value":"_content/bitforum/css/admin.min.css"}]]]></EndpointProperties>
-      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"154"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022zm/B82eA9Z4lUjeURB5A5aAzsnKX3qRgusT8bPLamBs=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 12:22:02 GMT"}]]]></ResponseHeaders>
+      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"154"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022zm/B82eA9Z4lUjeURB5A5aAzsnKX3qRgusT8bPLamBs=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 13:34:04 GMT"}]]]></ResponseHeaders>
     </StaticWebAssetEndpoint>
     <StaticWebAssetEndpoint Include="_content/bitforum/css/site.bh06sh7otq.css">
       <AssetFile>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\staticwebassets\css\site.css'))</AssetFile>
       <Selectors><![CDATA[[]]]></Selectors>
       <EndpointProperties><![CDATA[[{"Name":"fingerprint","Value":"bh06sh7otq"},{"Name":"integrity","Value":"sha256-EcgUTDCHpb/IHwu4B65lmHVa764F\u002BLnQRCR2qD2l4Y8="},{"Name":"label","Value":"_content/bitforum/css/site.css"}]]]></EndpointProperties>
-      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"1413"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022EcgUTDCHpb/IHwu4B65lmHVa764F\u002BLnQRCR2qD2l4Y8=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 12:22:02 GMT"}]]]></ResponseHeaders>
+      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"1413"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022EcgUTDCHpb/IHwu4B65lmHVa764F\u002BLnQRCR2qD2l4Y8=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 13:34:04 GMT"}]]]></ResponseHeaders>
     </StaticWebAssetEndpoint>
     <StaticWebAssetEndpoint Include="_content/bitforum/css/site.css">
       <AssetFile>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\staticwebassets\css\site.css'))</AssetFile>
       <Selectors><![CDATA[[]]]></Selectors>
       <EndpointProperties><![CDATA[[{"Name":"integrity","Value":"sha256-EcgUTDCHpb/IHwu4B65lmHVa764F\u002BLnQRCR2qD2l4Y8="}]]]></EndpointProperties>
-      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"1413"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022EcgUTDCHpb/IHwu4B65lmHVa764F\u002BLnQRCR2qD2l4Y8=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 12:22:02 GMT"}]]]></ResponseHeaders>
+      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"1413"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022EcgUTDCHpb/IHwu4B65lmHVa764F\u002BLnQRCR2qD2l4Y8=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 13:34:04 GMT"}]]]></ResponseHeaders>
     </StaticWebAssetEndpoint>
     <StaticWebAssetEndpoint Include="_content/bitforum/css/site.min.504tlq0gfj.css">
       <AssetFile>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\staticwebassets\css\site.min.css'))</AssetFile>
       <Selectors><![CDATA[[]]]></Selectors>
       <EndpointProperties><![CDATA[[{"Name":"fingerprint","Value":"504tlq0gfj"},{"Name":"integrity","Value":"sha256-hZbigZL0YKYOCNY30G1NM/Yl3De\u002BNXmBCR67Db\u002BlzwA="},{"Name":"label","Value":"_content/bitforum/css/site.min.css"}]]]></EndpointProperties>
-      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"1412"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022hZbigZL0YKYOCNY30G1NM/Yl3De\u002BNXmBCR67Db\u002BlzwA=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 12:22:02 GMT"}]]]></ResponseHeaders>
+      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"1412"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022hZbigZL0YKYOCNY30G1NM/Yl3De\u002BNXmBCR67Db\u002BlzwA=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 13:34:04 GMT"}]]]></ResponseHeaders>
     </StaticWebAssetEndpoint>
     <StaticWebAssetEndpoint Include="_content/bitforum/css/site.min.css">
       <AssetFile>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\staticwebassets\css\site.min.css'))</AssetFile>
       <Selectors><![CDATA[[]]]></Selectors>
       <EndpointProperties><![CDATA[[{"Name":"integrity","Value":"sha256-hZbigZL0YKYOCNY30G1NM/Yl3De\u002BNXmBCR67Db\u002BlzwA="}]]]></EndpointProperties>
-      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"1412"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022hZbigZL0YKYOCNY30G1NM/Yl3De\u002BNXmBCR67Db\u002BlzwA=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 12:22:02 GMT"}]]]></ResponseHeaders>
+      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"1412"},{"Name":"Content-Type","Value":"text/css"},{"Name":"ETag","Value":"\u0022hZbigZL0YKYOCNY30G1NM/Yl3De\u002BNXmBCR67Db\u002BlzwA=\u0022"},{"Name":"Last-Modified","Value":"Wed, 15 Jan 2025 13:34:04 GMT"}]]]></ResponseHeaders>
     </StaticWebAssetEndpoint>
     <StaticWebAssetEndpoint Include="_content/bitforum/images/favicon.0dvehdwh9a.ico">
       <AssetFile>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\staticwebassets\images\favicon.ico'))</AssetFile>
@@ -108,17 +108,17 @@
       <EndpointProperties><![CDATA[[{"Name":"integrity","Value":"sha256-gdzI5MbOC4NqTYkN/Mm2cfVgQ7DVcOQunPUNGgCwkI4="}]]]></EndpointProperties>
       <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"1028"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\u0022gdzI5MbOC4NqTYkN/Mm2cfVgQ7DVcOQunPUNGgCwkI4=\u0022"},{"Name":"Last-Modified","Value":"Wed, 08 Jan 2025 01:32:59 GMT"}]]]></ResponseHeaders>
     </StaticWebAssetEndpoint>
-    <StaticWebAssetEndpoint Include="_content/bitforum/js/site.es0zx3fd95.js">
+    <StaticWebAssetEndpoint Include="_content/bitforum/js/site.4a80i8ynpk.js">
       <AssetFile>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\staticwebassets\js\site.js'))</AssetFile>
       <Selectors><![CDATA[[]]]></Selectors>
-      <EndpointProperties><![CDATA[[{"Name":"fingerprint","Value":"es0zx3fd95"},{"Name":"integrity","Value":"sha256-vsuucnLqyJZOfT1tAqZr34i5pW4wjC0G2/E5ZCv1Dvc="},{"Name":"label","Value":"_content/bitforum/js/site.js"}]]]></EndpointProperties>
-      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"3176"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\u0022vsuucnLqyJZOfT1tAqZr34i5pW4wjC0G2/E5ZCv1Dvc=\u0022"},{"Name":"Last-Modified","Value":"Mon, 13 Jan 2025 10:33:37 GMT"}]]]></ResponseHeaders>
+      <EndpointProperties><![CDATA[[{"Name":"fingerprint","Value":"4a80i8ynpk"},{"Name":"integrity","Value":"sha256-FITMTC/ZAZWo7IhHMLw8U/kpuVpkFx3EH2xwdIvHXqc="},{"Name":"label","Value":"_content/bitforum/js/site.js"}]]]></EndpointProperties>
+      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"max-age=31536000, immutable"},{"Name":"Content-Length","Value":"3419"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\u0022FITMTC/ZAZWo7IhHMLw8U/kpuVpkFx3EH2xwdIvHXqc=\u0022"},{"Name":"Last-Modified","Value":"Thu, 16 Jan 2025 09:40:22 GMT"}]]]></ResponseHeaders>
     </StaticWebAssetEndpoint>
     <StaticWebAssetEndpoint Include="_content/bitforum/js/site.js">
       <AssetFile>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\staticwebassets\js\site.js'))</AssetFile>
       <Selectors><![CDATA[[]]]></Selectors>
-      <EndpointProperties><![CDATA[[{"Name":"integrity","Value":"sha256-vsuucnLqyJZOfT1tAqZr34i5pW4wjC0G2/E5ZCv1Dvc="}]]]></EndpointProperties>
-      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"3176"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\u0022vsuucnLqyJZOfT1tAqZr34i5pW4wjC0G2/E5ZCv1Dvc=\u0022"},{"Name":"Last-Modified","Value":"Mon, 13 Jan 2025 10:33:37 GMT"}]]]></ResponseHeaders>
+      <EndpointProperties><![CDATA[[{"Name":"integrity","Value":"sha256-FITMTC/ZAZWo7IhHMLw8U/kpuVpkFx3EH2xwdIvHXqc="}]]]></EndpointProperties>
+      <ResponseHeaders><![CDATA[[{"Name":"Accept-Ranges","Value":"bytes"},{"Name":"Cache-Control","Value":"no-cache"},{"Name":"Content-Length","Value":"3419"},{"Name":"Content-Type","Value":"text/javascript"},{"Name":"ETag","Value":"\u0022FITMTC/ZAZWo7IhHMLw8U/kpuVpkFx3EH2xwdIvHXqc=\u0022"},{"Name":"Last-Modified","Value":"Thu, 16 Jan 2025 09:40:22 GMT"}]]]></ResponseHeaders>
     </StaticWebAssetEndpoint>
     <StaticWebAssetEndpoint Include="_content/bitforum/lib/bootstrap/dist/css/bootstrap-grid.agp80tu62r.css">
       <AssetFile>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\staticwebassets\lib\bootstrap\dist\css\bootstrap-grid.css'))</AssetFile>

+ 2 - 2
backend/obj/Debug/net8.0/staticwebassets/msbuild.bitforum.Microsoft.AspNetCore.StaticWebAssets.props

@@ -174,8 +174,8 @@
       <RelatedAsset></RelatedAsset>
       <AssetTraitName></AssetTraitName>
       <AssetTraitValue></AssetTraitValue>
-      <Fingerprint>es0zx3fd95</Fingerprint>
-      <Integrity>vsuucnLqyJZOfT1tAqZr34i5pW4wjC0G2/E5ZCv1Dvc=</Integrity>
+      <Fingerprint>4a80i8ynpk</Fingerprint>
+      <Integrity>FITMTC/ZAZWo7IhHMLw8U/kpuVpkFx3EH2xwdIvHXqc=</Integrity>
       <CopyToOutputDirectory>Never</CopyToOutputDirectory>
       <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
       <OriginalItemSpec>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\staticwebassets\js\site.js'))</OriginalItemSpec>

+ 10 - 1
backend/wwwroot/js/site.js

@@ -102,5 +102,14 @@ collapseElementList.forEach(collapseEl => {
     });
 });
 
+// 드롭박스 적용
 const dropdownElementList = document.querySelectorAll('.dropdown-toggle');
-const dropdownList = [...dropdownElementList].map(dropdownToggleEl => new bootstrap.Dropdown(dropdownToggleEl))
+const dropdownList = [...dropdownElementList].map(dropdownToggleEl => new bootstrap.Dropdown(dropdownToggleEl));
+
+// 삭제 처리
+$(document).on("click", ".btn-delete-row", function (e) {
+    e.preventDefault();
+    if (confirm("삭제하시겠습니까?")) {
+        location.href = e.target.closest("a").href;
+    }
+});

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio