Refactor admin project folder structure (#113)

This commit is contained in:
Leendert de Borst
2024-07-22 11:47:39 +02:00
parent 022370f799
commit aa5d229687
10 changed files with 34 additions and 96 deletions

View File

@@ -1,4 +1,4 @@
@page "/account/manage/ChangePassword"
@page "/account/manage/change-password"
@using System.ComponentModel.DataAnnotations
@using Microsoft.AspNetCore.Identity
@@ -50,7 +50,7 @@
hasPassword = await UserManager.HasPasswordAsync(UserService.User());
if (!hasPassword)
{
NavigationService.RedirectTo("account/manage/SetPassword");
NavigationService.RedirectTo("account/manage/set-password");
}
}

View File

@@ -1,4 +1,4 @@
@page "/account/manage/Disable2fa"
@page "/account/manage/disable-2fa"
@using Microsoft.AspNetCore.Identity
@@ -15,7 +15,7 @@
</p>
<p>
Disabling 2FA does not change the keys used in authenticator apps. If you wish to change the key
used in an authenticator app you should <a href="account/manage/ResetAuthenticator" class="text-primary-600 hover:text-primary-800 underline">reset your authenticator keys.</a>
used in an authenticator app you should <a href="account/manage/reset-authenticator" class="text-primary-600 hover:text-primary-800 underline">reset your authenticator keys.</a>
</p>
</div>

View File

@@ -1,4 +1,4 @@
@page "/account/manage/EnableAuthenticator"
@page "/account/manage/enable-authenticator"
@using System.ComponentModel.DataAnnotations
@using System.Globalization
@@ -114,7 +114,7 @@ else
else
{
// Navigate back to the two factor authentication page.
NavigationService.RedirectTo("account/manage/TwoFactorAuthentication", forceLoad: true);
NavigationService.RedirectTo("account/manage/2fa", forceLoad: true);
}
}

View File

@@ -1,4 +1,4 @@
@page "/account/manage/GenerateRecoveryCodes"
@page "/account/manage/generate-recovery-codes"
@using Microsoft.AspNetCore.Identity
@@ -26,7 +26,7 @@ else
</p>
<p>
Generating new recovery codes does not change the keys used in authenticator apps. If you wish to change the key
used in an authenticator app you should <a href="account/manage/ResetAuthenticator" class="text-primary-600 hover:text-primary-800 underline">reset your authenticator keys.</a>
used in an authenticator app you should <a href="account/manage/reset-authenticator" class="text-primary-600 hover:text-primary-800 underline">reset your authenticator keys.</a>
</p>
</div>
<div>

View File

@@ -1,4 +1,4 @@
@page "/account/manage/ResetAuthenticator"
@page "/account/manage/reset-authenticator"
@using Microsoft.AspNetCore.Identity
@@ -41,7 +41,7 @@
GlobalNotificationService.AddSuccessMessage("Your authenticator app key has been reset, you will need to configure your authenticator app using the new key.");
NavigationService.RedirectTo(
"account/manage/EnableAuthenticator");
"account/manage/enable-authenticator");
}
}

View File

@@ -1,4 +1,4 @@
@page "/account/manage/SetPassword"
@page "/account/manage/set-password"
@using System.ComponentModel.DataAnnotations
@using Microsoft.AspNetCore.Identity
@@ -47,7 +47,7 @@
var hasPassword = await UserManager.HasPasswordAsync(UserService.User());
if (hasPassword)
{
NavigationService.RedirectTo("account/manage/ChangePassword");
NavigationService.RedirectTo("account/manage/change-password");
}
}

View File

@@ -1,4 +1,4 @@
@page "/account/manage/TwoFactorAuthentication"
@page "/account/manage/2fa"
@using Microsoft.AspNetCore.Identity
@@ -16,27 +16,27 @@
{
<div class="mb-4 p-4 bg-red-100 border-l-4 border-red-500 text-red-700 dark:bg-red-900 dark:text-red-100">
<p class="font-bold">You have no recovery codes left.</p>
<p>You must <a href="account/manage/GenerateRecoveryCodes" class="text-red-800 dark:text-red-200 underline">generate a new set of recovery codes</a> before you can log in with a recovery code.</p>
<p>You must <a href="account/manage/generate-recovery-codes" class="text-red-800 dark:text-red-200 underline">generate a new set of recovery codes</a> before you can log in with a recovery code.</p>
</div>
}
else if (recoveryCodesLeft == 1)
{
<div class="mb-4 p-4 bg-red-100 border-l-4 border-red-500 text-red-700 dark:bg-red-900 dark:text-red-100">
<p class="font-bold">You have 1 recovery code left.</p>
<p>You can <a href="account/manage/GenerateRecoveryCodes" class="text-red-800 dark:text-red-200 underline">generate a new set of recovery codes</a>.</p>
<p>You can <a href="account/manage/generate-recovery-codes" class="text-red-800 dark:text-red-200 underline">generate a new set of recovery codes</a>.</p>
</div>
}
else if (recoveryCodesLeft <= 3)
{
<div class="mb-4 p-4 bg-yellow-100 border-l-4 border-yellow-500 text-yellow-700 dark:bg-yellow-900 dark:text-yellow-100">
<p class="font-bold">You have @recoveryCodesLeft recovery codes left.</p>
<p>You should <a href="account/manage/GenerateRecoveryCodes" class="text-yellow-800 dark:text-yellow-200 underline">generate a new set of recovery codes</a>.</p>
<p>You should <a href="account/manage/generate-recovery-codes" class="text-yellow-800 dark:text-yellow-200 underline">generate a new set of recovery codes</a>.</p>
</div>
}
<div class="flex space-x-4">
<a href="account/manage/Disable2fa" class="px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white font-medium rounded-lg text-sm focus:ring-4 focus:outline-none focus:ring-primary-300 dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">Disable 2FA</a>
<a href="account/manage/GenerateRecoveryCodes" class="px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white font-medium rounded-lg text-sm focus:ring-4 focus:outline-none focus:ring-primary-300 dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">Reset recovery codes</a>
<a href="account/manage/disable-2fa" class="px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white font-medium rounded-lg text-sm focus:ring-4 focus:outline-none focus:ring-primary-300 dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">Disable 2FA</a>
<a href="account/manage/generate-recovery-codes" class="px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white font-medium rounded-lg text-sm focus:ring-4 focus:outline-none focus:ring-primary-300 dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">Reset recovery codes</a>
</div>
</div>
}
@@ -46,16 +46,16 @@
<div class="flex flex-col sm:flex-row space-y-2 sm:space-y-0 sm:space-x-2">
@if (!hasAuthenticator)
{
<a href="account/manage/EnableAuthenticator" class="inline-block px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white font-medium rounded-lg text-sm text-center focus:ring-4 focus:outline-none focus:ring-primary-300 dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">
<a href="account/manage/enable-authenticator" class="inline-block px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white font-medium rounded-lg text-sm text-center focus:ring-4 focus:outline-none focus:ring-primary-300 dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">
Add authenticator app
</a>
}
else
{
<a href="account/manage/EnableAuthenticator" class="inline-block px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white font-medium rounded-lg text-sm text-center focus:ring-4 focus:outline-none focus:ring-primary-300 dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">
<a href="account/manage/enable-authenticator" class="inline-block px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white font-medium rounded-lg text-sm text-center focus:ring-4 focus:outline-none focus:ring-primary-300 dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">
Set up authenticator app
</a>
<a href="account/manage/ResetAuthenticator" class="inline-block px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white font-medium rounded-lg text-sm text-center focus:ring-4 focus:outline-none focus:ring-primary-300 dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">
<a href="account/manage/reset-authenticator" class="inline-block px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white font-medium rounded-lg text-sm text-center focus:ring-4 focus:outline-none focus:ring-primary-300 dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">
Reset authenticator app
</a>
}

View File

@@ -7,19 +7,9 @@
<NavLink href="account/manage" Match="NavLinkMatch.All" class="block px-4 py-2 text-sm font-medium text-gray-700 rounded-md hover:bg-gray-100 hover:text-gray-900 transition-colors duration-150">Profile</NavLink>
</li>
<li>
<NavLink href="account/manage/ChangePassword" class="block px-4 py-2 text-sm font-medium text-gray-700 rounded-md hover:bg-gray-100 hover:text-gray-900 transition-colors duration-150">Password</NavLink>
<NavLink href="account/manage/change-password" class="block px-4 py-2 text-sm font-medium text-gray-700 rounded-md hover:bg-gray-100 hover:text-gray-900 transition-colors duration-150">Password</NavLink>
</li>
<li>
<NavLink href="account/manage/TwoFactorAuthentication" class="block px-4 py-2 text-sm font-medium text-gray-700 rounded-md hover:bg-gray-100 hover:text-gray-900 transition-colors duration-150">Two-factor authentication</NavLink>
<NavLink href="account/manage/2fa" class="block px-4 py-2 text-sm font-medium text-gray-700 rounded-md hover:bg-gray-100 hover:text-gray-900 transition-colors duration-150">Two-factor authentication</NavLink>
</li>
</ul>
@code {
private bool hasExternalLogins;
protected override async Task OnInitializedAsync()
{
hasExternalLogins = (await SignInManager.GetExternalAuthenticationSchemesAsync()).Any();
}
}

View File

@@ -1,7 +1,5 @@
namespace AliasVault.Admin2.Services;
using Microsoft.AspNetCore.Components;
/// <summary>
/// Access check service to verify if the user is logged in and has a confirmed email.
/// </summary>

View File

@@ -23,11 +23,6 @@ public class UserService
/// </summary>
public event Action OnChange = () => { };
/// <summary>
/// The Event Ids that the current user is allowed to manage.
/// </summary>
private List<Guid> _managedEventIds = new();
/// <summary>
/// The roles of the current user
/// </summary>
@@ -39,7 +34,7 @@ public class UserService
private bool _isAdmin;
/// <summary>
/// Gets a value indicating whether an event is loaded and available, false if not. Use this before accessing Event() method.
/// Gets a value indicating whether the User is loaded and available, false if not. Use this before accessing User() method.
/// </summary>
public bool UserLoaded => _user != null;
@@ -88,7 +83,7 @@ public class UserService
}
/// <summary>
/// Returns inner event EF object.
/// Returns inner User EF object.
/// </summary>
/// <returns></returns>
public AdminUser User()
@@ -101,15 +96,6 @@ public class UserService
return _user;
}
/// <summary>
/// Returns managed Event ids list.
/// </summary>
/// <returns></returns>
public List<Guid> UserAllowedEventIds()
{
return _managedEventIds;
}
/// <summary>
/// Returns whether current user is admin or not.
/// </summary>
@@ -133,45 +119,18 @@ public class UserService
{
_user = user;
// Load all roles for current user.
_userRoles = await _userManager.GetRolesAsync(this.User());
// Define if current user is admin.
_isAdmin = _userRoles.Contains(AdminRole);
}
// UserManager implementation: throughout Blazor server session user is not updated when user is updated in database
// because of UserManager EF cache. That's why we load it ourselves straight from the database via new DbContext
// to ensure we get the latest data everytime.
/*var currentUser = await _userManager.GetUserAsync(_httpContextAccessor.HttpContext.User);
if (currentUser != null)
{
_user = currentUser;
// Load managed event ids for current user.
_managedEventIds = await GetUserAllowedEventIdsAsync(_user);
// Load all roles for current user.
_userRoles = await _userManager.GetRolesAsync(User());
// Define if current user is admin.
_isAdmin = _userRoles.Contains(AdminRole);
}*/
}
}
// Notify listeners that the user has been loaded.
NotifyStateChanged();
}
/// <summary>
/// Generate email confirmation token for current user.
/// </summary>
/// <returns>Email confirmation token.</returns>
public async Task<string> GenerateEmailConfirmTokenAsync()
{
return await _userManager.GenerateEmailConfirmationTokenAsync(User());
}
/// <summary>
/// Returns current logged on user roles based on HttpContext.
/// </summary>
@@ -193,15 +152,6 @@ public class UserService
return await _userManager.Users.Where(x => x.UserName.Contains(searchTerm)).Take(5).ToListAsync();
}
/// <summary>
/// Sign out the current user.
/// </summary>
/// <returns>Async task.</returns>
public async Task SignOutAsync()
{
await _signInManager.SignOutAsync();
}
/// <summary>
/// Create a new user.
/// </summary>
@@ -250,7 +200,7 @@ public class UserService
// Update password if necessary
if (!string.IsNullOrEmpty(newPassword))
{
var passwordRemoveResult = await this._userManager.RemovePasswordAsync(user);
var passwordRemoveResult = await _userManager.RemovePasswordAsync(user);
if (!passwordRemoveResult.Succeeded)
{
foreach (var error in passwordRemoveResult.Errors)
@@ -260,7 +210,7 @@ public class UserService
return errors;
}
var passwordAddResult = await this._userManager.AddPasswordAsync(user, newPassword);
var passwordAddResult = await _userManager.AddPasswordAsync(user, newPassword);
if (!passwordAddResult.Succeeded)
{
foreach (var error in passwordAddResult.Errors)
@@ -271,7 +221,7 @@ public class UserService
}
}
var result = await this._userManager.UpdateAsync(user);
var result = await _userManager.UpdateAsync(user);
if (!result.Succeeded)
{
foreach (var error in result.Errors)
@@ -305,8 +255,8 @@ public class UserService
var rolesToAdd = roles.Except(currentRoles).ToList();
var rolesToRemove = currentRoles.Except(roles).ToList();
await this._userManager.AddToRolesAsync(user, rolesToAdd);
await this._userManager.RemoveFromRolesAsync(user, rolesToRemove);
await _userManager.AddToRolesAsync(user, rolesToAdd);
await _userManager.RemoveFromRolesAsync(user, rolesToRemove);
return errors;
}
@@ -339,7 +289,7 @@ public class UserService
if (isUpdate)
{
var originalUser = await this._userManager.FindByIdAsync(user.Id);
var originalUser = await _userManager.FindByIdAsync(user.Id);
if (user.UserName != originalUser.UserName)
{
errors.Add("Username cannot be changed for existing users.");
@@ -347,13 +297,13 @@ public class UserService
}
else
{
var existingUser = await this._userManager.FindByNameAsync(user.UserName);
var existingUser = await _userManager.FindByNameAsync(user.UserName);
if (existingUser != null)
{
errors.Add("Username is already in use.");
}
var existingEmail = await this._userManager.FindByEmailAsync(user.Email);
var existingEmail = await _userManager.FindByEmailAsync(user.Email);
if (existingEmail != null)
{
errors.Add("Email is already in use.");