Refactor client update handling to support nullable parameters for name and expiration
- Updated the `UpdateClientAsync` method in `IXuiPanelGateway` to accept nullable parameters for `name` and `expiresAt`, allowing for more flexible client management without unintended modifications. - Adjusted the `BlockUserCommandHandler`, `UnblockUserCommandHandler`, and other related command handlers to utilize the new nullable parameters, ensuring that client names remain unchanged during block/unblock operations and that expiration dates are managed correctly. - Enhanced the billing and configuration handling to reflect the new logic for managing client states based on expiration rather than enabling/disabling, improving reliability in client status management. - Updated tests to cover the new behavior and ensure proper functionality across the application.
This commit is contained in:
@@ -139,13 +139,18 @@ public sealed class BillingService(
|
||||
|
||||
if (inbound is not null && node is not null)
|
||||
{
|
||||
// Приостанавливаем через expiryTime в прошлом, а не enable:false — переключение enable
|
||||
// ненадёжно останавливает уже установленные соединения на стороне Xray/панели (см.
|
||||
// IXuiPanelGateway.UpdateClientAsync), просроченный expiryTime — надёжно и независимо
|
||||
// от enable. name: null — не переименовываем клиента.
|
||||
var updateResult = await gateway.UpdateClientAsync(
|
||||
node,
|
||||
inbound.RemoteInboundId,
|
||||
config.ClientExternalId,
|
||||
config.Protocol,
|
||||
config.Label ?? config.ClientEmail,
|
||||
enable: false,
|
||||
name: null,
|
||||
enable: null,
|
||||
expiresAt: DateTimeOffset.UtcNow.AddDays(-1),
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
|
||||
@@ -92,6 +92,7 @@ internal sealed class XuiPanelGateway(
|
||||
string clientEmail,
|
||||
string clientName,
|
||||
int limitIp,
|
||||
DateTimeOffset? expiresAt,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
@@ -105,7 +106,7 @@ internal sealed class XuiPanelGateway(
|
||||
clientEmail,
|
||||
ToRemoteProtocol(protocol),
|
||||
limitIp == RoleQuota.Unlimited ? 0 : limitIp,
|
||||
null
|
||||
expiresAt
|
||||
);
|
||||
var result = await client.AddClientAsync(inboundRemoteId, request, cancellationToken);
|
||||
return Result.Success(result.ExternalClientId);
|
||||
@@ -150,16 +151,17 @@ internal sealed class XuiPanelGateway(
|
||||
string inboundRemoteId,
|
||||
string clientExternalId,
|
||||
VpnProtocol protocol,
|
||||
string name,
|
||||
bool enable,
|
||||
string? name,
|
||||
bool? enable,
|
||||
DateTimeOffset? expiresAt,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
var client = GetClient(node);
|
||||
// deviceLimit: null — не трогаем то, что уже стоит на клиенте в панели (см. AddClientAsync).
|
||||
var request = new UpdateClientRequest(null, null, enable, name);
|
||||
// limitIp: null — не трогаем то, что уже стоит на клиенте в панели (см. AddClientAsync).
|
||||
var request = new UpdateClientRequest(null, expiresAt, enable, name);
|
||||
await client.UpdateClientAsync(
|
||||
inboundRemoteId,
|
||||
clientExternalId,
|
||||
|
||||
Reference in New Issue
Block a user