Enhance documentation with new features: added dark/light/system theme support, instructions page, and application catalog. Updated API and domain model for app management and automatic migrations on startup. Improved frontend structure with new routes and features for user instructions and app management.
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
using System.Text;
|
||||
using PnvPanel.Api.Common;
|
||||
using PnvPanel.Application.Common.Messaging;
|
||||
using PnvPanel.Application.Subscriptions;
|
||||
|
||||
namespace PnvPanel.Api.Endpoints;
|
||||
|
||||
public static class SubscriptionEndpoints
|
||||
{
|
||||
public static IEndpointRouteBuilder MapSubscriptionEndpoints(this IEndpointRouteBuilder app)
|
||||
{
|
||||
// Вне /api по дизайну (api-design.md) — публичный эндпоинт для VPN-клиентов.
|
||||
app.MapGet("/sub/{token}", GetSubscription)
|
||||
.WithTags("Subscription")
|
||||
.RequireRateLimiting(RateLimiting.AuthPolicy);
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
private static async Task<IResult> GetSubscription(string token, HttpResponse response, ISender sender, CancellationToken cancellationToken)
|
||||
{
|
||||
// Токен — либо AppUser.SubscriptionToken (агрегированная подписка), либо VpnConfig.SubscriptionToken
|
||||
// (один конфиг). Пробуем пользовательский токен первым.
|
||||
var userResult = await sender.Send(new GetUserSubscriptionQuery(token), cancellationToken);
|
||||
var result = userResult.IsSuccess ? userResult : await sender.Send(new GetConfigSubscriptionQuery(token), cancellationToken);
|
||||
|
||||
if (!result.IsSuccess)
|
||||
return Results.NotFound();
|
||||
|
||||
var body = string.Join('\n', result.Value.ConnectionStrings);
|
||||
var base64Body = Convert.ToBase64String(Encoding.UTF8.GetBytes(body));
|
||||
|
||||
var total = result.Value.UsedUpBytes + result.Value.UsedDownBytes;
|
||||
var expire = result.Value.ExpiresAt is { } exp ? exp.ToUnixTimeSeconds().ToString() : "0";
|
||||
response.Headers.Append(
|
||||
"Subscription-Userinfo",
|
||||
$"upload={result.Value.UsedUpBytes}; download={result.Value.UsedDownBytes}; total={total}; expire={expire}");
|
||||
response.Headers.Append("Profile-Update-Interval", "12");
|
||||
|
||||
return Results.Text(base64Body, "text/plain; charset=utf-8");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user