Implement role and user management enhancements
CI / Backend (build + test) (push) Successful in 1m14s
CI / Frontend (lint + typecheck + build) (push) Successful in 30s

- Added MaxIpLimit to roles, allowing for the configuration of simultaneous IP limits for users.
- Updated role creation and update commands to include MaxIpLimit, ensuring proper handling in the application logic.
- Enhanced user management by introducing a DELETE endpoint for user accounts, with appropriate checks to prevent self-deletion.
- Updated documentation to reflect changes in role and user management, clarifying the new IP limit functionality and user deletion process.
- Adjusted related tests to cover new functionality and ensure robust validation of role and user management features.
This commit is contained in:
Leonid Pershin
2026-07-13 07:18:13 +03:00
parent 48e8d06a41
commit 24d9ea1099
48 changed files with 1240 additions and 171 deletions
@@ -44,7 +44,7 @@ public sealed class CreateVpnConfigCommandHandler(
var addResult = await gateway.AddClientAsync(
node, inbound.RemoteInboundId, inbound.Protocol, config.ClientEmail,
config.Label ?? config.ClientEmail, cancellationToken);
config.Label ?? config.ClientEmail, profile.MaxIpLimit, cancellationToken);
if (!addResult.IsSuccess)
{
@@ -7,7 +7,8 @@ using PnvPanel.Domain.Configs;
namespace PnvPanel.Application.Configs.Rotate;
public sealed class RotateVpnConfigCommandHandler(IAppDbContext dbContext, IXuiPanelGateway gateway, ICurrentUser currentUser)
public sealed class RotateVpnConfigCommandHandler(
IAppDbContext dbContext, IXuiPanelGateway gateway, IIdentityService identityService, ICurrentUser currentUser)
: ICommandHandler<RotateVpnConfigCommand, Result<VpnConfigDto>>
{
public async Task<Result<VpnConfigDto>> Handle(RotateVpnConfigCommand command, CancellationToken cancellationToken)
@@ -32,10 +33,14 @@ public sealed class RotateVpnConfigCommandHandler(IAppDbContext dbContext, IXuiP
if (node is null)
return Result.Failure<VpnConfigDto>(ConfigErrors.NodeDisabled);
var profile = await identityService.GetProfileAsync(userId, cancellationToken);
if (profile is null)
return Result.Failure<VpnConfigDto>(AuthErrors.Unauthorized);
var newClientEmail = VpnConfig.GenerateClientEmail(userId);
var addResult = await gateway.AddClientAsync(
node, inbound.RemoteInboundId, config.Protocol, newClientEmail,
config.Label ?? newClientEmail, cancellationToken);
config.Label ?? newClientEmail, profile.MaxIpLimit, cancellationToken);
if (!addResult.IsSuccess)
return Result.Failure<VpnConfigDto>(addResult.Error);