Add domestic vendor push infrastructure
This commit is contained in:
@@ -9,9 +9,10 @@ using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddOpenApi();
|
||||
builder.Services.AddRateLimiter(options =>
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddOpenApi();
|
||||
var authPermitLimit = Math.Max(1, builder.Configuration.GetValue("RateLimiting:AuthPermitLimit", 10));
|
||||
builder.Services.AddRateLimiter(options =>
|
||||
{
|
||||
options.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
|
||||
options.AddPolicy("auth", context =>
|
||||
@@ -19,7 +20,7 @@ builder.Services.AddRateLimiter(options =>
|
||||
context.Connection.RemoteIpAddress?.ToString() ?? "unknown",
|
||||
_ => new FixedWindowRateLimiterOptions
|
||||
{
|
||||
PermitLimit = 10,
|
||||
PermitLimit = authPermitLimit,
|
||||
Window = TimeSpan.FromMinutes(1),
|
||||
QueueLimit = 0,
|
||||
}));
|
||||
@@ -50,13 +51,32 @@ builder.Services.AddScoped<ReplyService>();
|
||||
builder.Services.AddScoped<LedgerResolver>();
|
||||
builder.Services.AddScoped<AiPermissionService>();
|
||||
builder.Services.AddScoped<AiChatQuotaService>();
|
||||
builder.Services.AddScoped<AiPermissionFilter>();
|
||||
builder.Services.AddHttpClient("LlmClient");
|
||||
builder.Services.AddScoped<BudgetPushService>();
|
||||
builder.Services.AddSingleton<PushTokenProtector>();
|
||||
builder.Services.AddScoped<AiPermissionFilter>();
|
||||
builder.Services.AddHttpClient("LlmClient");
|
||||
builder.Services.AddHttpClient("PushProviders", client =>
|
||||
{
|
||||
client.Timeout = TimeSpan.FromSeconds(20);
|
||||
});
|
||||
foreach (var provider in new[]
|
||||
{
|
||||
"huawei", "honor", "xiaomi", "oppo", "vivo", "meizu",
|
||||
})
|
||||
{
|
||||
builder.Services.AddSingleton<IPushProvider>(services => new OfficialPushProvider(
|
||||
provider,
|
||||
services.GetRequiredService<IConfiguration>(),
|
||||
services.GetRequiredService<IHttpClientFactory>(),
|
||||
services.GetRequiredService<ILogger<OfficialPushProvider>>()));
|
||||
}
|
||||
builder.Services.AddSingleton<PushProviderRegistry>();
|
||||
builder.Services.AddSingleton<OpenAiVisionClient>();
|
||||
builder.Services.AddSingleton<ILlmClient>(sp => sp.GetRequiredService<OpenAiVisionClient>());
|
||||
builder.Services.AddHostedService<RecycleBinCleanupService>();
|
||||
builder.Services.AddScoped<AccountDataEraser>();
|
||||
builder.Services.AddHostedService<AccountClosureCleanupService>();
|
||||
builder.Services.AddHostedService<AccountClosureCleanupService>();
|
||||
builder.Services.AddHostedService<PushDispatchService>();
|
||||
|
||||
var conn = builder.Configuration.GetConnectionString("Default");
|
||||
if (string.IsNullOrWhiteSpace(conn))
|
||||
@@ -64,9 +84,19 @@ if (string.IsNullOrWhiteSpace(conn))
|
||||
var jwtSecret = builder.Configuration["Jwt:Secret"];
|
||||
if (string.IsNullOrWhiteSpace(jwtSecret) || jwtSecret.Length < 32)
|
||||
throw new InvalidOperationException("必须通过 Jwt__Secret 配置至少 32 位的 JWT 密钥");
|
||||
var adminKey = builder.Configuration["Admin:Key"];
|
||||
var adminKey = builder.Configuration["Admin:Key"];
|
||||
if (string.IsNullOrWhiteSpace(adminKey) || adminKey.Length < 24)
|
||||
throw new InvalidOperationException("必须通过 Admin__Key 配置至少 24 位的管理密钥");
|
||||
throw new InvalidOperationException("必须通过 Admin__Key 配置至少 24 位的管理密钥");
|
||||
if (builder.Configuration.GetValue<bool>("Push:Enabled"))
|
||||
{
|
||||
var pushKey = builder.Configuration["Push:TokenEncryptionKey"];
|
||||
byte[]? key = null;
|
||||
try { key = string.IsNullOrWhiteSpace(pushKey) ? null : Convert.FromBase64String(pushKey); }
|
||||
catch (FormatException) { }
|
||||
if (key?.Length != 32)
|
||||
throw new InvalidOperationException(
|
||||
"启用推送时必须通过 Push__TokenEncryptionKey 配置 base64 编码的 32 字节密钥");
|
||||
}
|
||||
builder.Services.AddDbContext<AppDbContext>(o =>
|
||||
o.UseMySql(conn, ServerVersion.AutoDetect(conn)));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user