Merge branch 'Moonlight-Panel:main' into main

This commit is contained in:
Moritz 2023-09-06 19:51:07 +02:00 committed by GitHub
commit 450a954b9d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 380 additions and 331 deletions

View file

@ -1,333 +1,17 @@
using BlazorDownloadFile;
using BlazorTable;
using HealthChecks.UI.Client;
using Moonlight.App.ApiClients.CloudPanel;
using Moonlight.App.ApiClients.Daemon;
using Moonlight.App.ApiClients.Modrinth;
using Moonlight.App.ApiClients.Paper;
using Moonlight.App.ApiClients.Telemetry;
using Moonlight.App.ApiClients.Wings;
using Moonlight.App.Database;
using Moonlight.App.Diagnostics.HealthChecks;
using Moonlight.App.Events;
using Moonlight.App.Helpers;
using Moonlight.App.Helpers.Wings;
using Moonlight.App.LogMigrator;
using Moonlight.App.Repositories;
using Moonlight.App.Repositories.Domains;
using Moonlight.App.Repositories.Servers;
using Moonlight.App.Services;
using Moonlight.App.Services.Addon;
using Moonlight.App.Services.Background;
using Moonlight.App.Services.DiscordBot;
using Moonlight.App.Services.Files;
using Moonlight.App.Services.Interop;
using Moonlight.App.Services.Mail;
using Moonlight.App.Services.Minecraft;
using Moonlight.App.Services.Notifications;
using Moonlight.App.Services.Plugins;
using Moonlight.App.Services.Sessions;
using Moonlight.App.Services.Statistics;
using Moonlight.App.Services.SupportChat;
using Moonlight.App.Services.Tickets;
using Sentry;
using Serilog;
using Serilog.Events;
using Stripe;
using SubscriptionService = Moonlight.App.Services.SubscriptionService;
namespace Moonlight namespace Moonlight
{ {
public class Program public class Program
{ {
private static readonly Startup Startup = new();
public static async Task Main(string[] args) public static async Task Main(string[] args)
{ {
var storageService = new StorageService(); Console.WriteLine("Moonlight Panel");
await storageService.EnsureCreated(); Console.WriteLine($"Copyright {DateTime.UtcNow.Year} moonlightpanel.xyz");
Console.WriteLine();
var configService = new ConfigService(storageService);
var shouldUseSentry = configService
.Get()
.Moonlight.Sentry.Enable;
if (configService.DebugMode) await Startup.Init(args);
{ await Startup.Start();
if (shouldUseSentry)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Verbose()
.Enrich.FromLogContext()
.WriteTo.Console(
outputTemplate: "{Timestamp:HH:mm:ss} [{Level:u3}] {SourceContext} {Message:lj}{NewLine}{Exception}")
.WriteTo.File(PathBuilder.File("storage", "logs", $"{DateTime.UtcNow:yyyy-MM-dd}.log"))
.WriteTo.Sentry(options =>
{
options.MinimumBreadcrumbLevel = LogEventLevel.Debug;
options.MinimumEventLevel = LogEventLevel.Warning;
})
.CreateLogger();
}
else
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Verbose()
.Enrich.FromLogContext()
.WriteTo.Console(
outputTemplate: "{Timestamp:HH:mm:ss} [{Level:u3}] {SourceContext} {Message:lj}{NewLine}{Exception}")
.WriteTo.File(PathBuilder.File("storage", "logs", $"{DateTime.UtcNow:yyyy-MM-dd}.log"))
.CreateLogger();
}
}
else
{
if (shouldUseSentry)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.Enrich.FromLogContext()
.WriteTo.Console(
outputTemplate: "{Timestamp:HH:mm:ss} [{Level:u3}] {SourceContext} {Message:lj}{NewLine}{Exception}")
.WriteTo.Sentry(options =>
{
options.MinimumBreadcrumbLevel = LogEventLevel.Information;
options.MinimumEventLevel = LogEventLevel.Warning;
})
.WriteTo.File(PathBuilder.File("storage", "logs", $"{DateTime.UtcNow:yyyy-MM-dd}.log"))
.CreateLogger();
}
else
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.Enrich.FromLogContext()
.WriteTo.Console(
outputTemplate: "{Timestamp:HH:mm:ss} [{Level:u3}] {SourceContext} {Message:lj}{NewLine}{Exception}")
.WriteTo.File(PathBuilder.File("storage", "logs", $"{DateTime.UtcNow:yyyy-MM-dd}.log"))
.CreateLogger();
}
}
Logger.Info("Running pre-init tasks");
var databaseCheckupService = new DatabaseCheckupService(configService);
await databaseCheckupService.Perform();
var builder = WebApplication.CreateBuilder(args);
var eventSystem = new EventSystem();
var letsEncryptService = new LetsEncryptService(configService, eventSystem);
builder.WebHost.ConfigureKestrel(options =>
{
options.ConfigureHttpsDefaults(httpsOptions =>
{
httpsOptions.ServerCertificateSelector = letsEncryptService.SelectCertificate;
});
});
var pluginService = new PluginService();
await pluginService.BuildServices(builder.Services);
// Switch to logging.net injection
// TODO: Enable in production
builder.Logging.ClearProviders();
builder.Logging.AddProvider(new LogMigratorProvider());
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor()
.AddHubOptions(options =>
{
options.MaximumReceiveMessageSize = 10000000;
options.ClientTimeoutInterval = TimeSpan.FromSeconds(30);
options.HandshakeTimeout = TimeSpan.FromSeconds(10);
});
builder.Services.AddHttpContextAccessor();
builder.Services.AddHealthChecks()
.AddCheck<DatabaseHealthCheck>("Database")
.AddCheck<NodeHealthCheck>("Nodes")
.AddCheck<DaemonHealthCheck>("Daemons");
// Sentry
if (shouldUseSentry)
{
builder.WebHost.UseSentry(options =>
{
options.Dsn = configService
.Get()
.Moonlight.Sentry.Dsn;
options.Debug = configService.DebugMode;
options.DiagnosticLevel = SentryLevel.Warning;
options.TracesSampleRate = 1.0;
options.DiagnosticLogger = new SentryDiagnosticsLogger(SentryLevel.Warning);
});
}
// Databases
builder.Services.AddDbContext<DataContext>();
// Repositories
builder.Services.AddScoped<UserRepository>();
builder.Services.AddScoped<NodeRepository>();
builder.Services.AddScoped<ServerRepository>();
builder.Services.AddScoped<ServerBackupRepository>();
builder.Services.AddScoped<ImageRepository>();
builder.Services.AddScoped<DomainRepository>();
builder.Services.AddScoped<SharedDomainRepository>();
builder.Services.AddScoped<RevokeRepository>();
builder.Services.AddScoped<NotificationRepository>();
builder.Services.AddScoped<DdosAttackRepository>();
builder.Services.AddScoped<SubscriptionRepository>();
builder.Services.AddScoped<LoadingMessageRepository>();
builder.Services.AddScoped<NewsEntryRepository>();
builder.Services.AddScoped<NodeAllocationRepository>();
builder.Services.AddScoped<StatisticsRepository>();
builder.Services.AddScoped(typeof(Repository<>));
// Services
builder.Services.AddSingleton(configService);
builder.Services.AddSingleton<StorageService>();
builder.Services.AddScoped<CookieService>();
builder.Services.AddScoped<IdentityService>();
builder.Services.AddScoped<IpLocateService>();
builder.Services.AddScoped<AlertService>();
builder.Services.AddScoped<SmartTranslateService>();
builder.Services.AddScoped<UserService>();
builder.Services.AddScoped<TotpService>();
builder.Services.AddScoped<ToastService>();
builder.Services.AddScoped<NodeService>();
builder.Services.AddScoped<ServerService>();
builder.Services.AddSingleton<PaperService>();
builder.Services.AddScoped<ClipboardService>();
builder.Services.AddSingleton<ResourceService>();
builder.Services.AddScoped<DomainService>();
builder.Services.AddScoped<OneTimeJwtService>();
builder.Services.AddSingleton<NotificationServerService>();
builder.Services.AddScoped<NotificationAdminService>();
builder.Services.AddScoped<ModalService>();
builder.Services.AddScoped<SmartDeployService>();
builder.Services.AddScoped<WebSpaceService>();
builder.Services.AddScoped<StatisticsViewService>();
builder.Services.AddSingleton<DateTimeService>();
builder.Services.AddSingleton(eventSystem);
builder.Services.AddScoped<FileDownloadService>();
builder.Services.AddScoped<ForgeService>();
builder.Services.AddScoped<FabricService>();
builder.Services.AddSingleton<BucketService>();
builder.Services.AddScoped<RatingService>();
builder.Services.AddScoped<ReCaptchaService>();
builder.Services.AddScoped<IpBanService>();
builder.Services.AddSingleton<OAuth2Service>();
builder.Services.AddScoped<DynamicBackgroundService>();
builder.Services.AddScoped<ServerAddonPluginService>();
builder.Services.AddScoped<KeyListenerService>();
builder.Services.AddScoped<PopupService>();
builder.Services.AddScoped<SubscriptionService>();
builder.Services.AddScoped<BillingService>();
builder.Services.AddSingleton<PluginStoreService>();
builder.Services.AddSingleton<TicketServerService>();
builder.Services.AddScoped<TicketClientService>();
builder.Services.AddScoped<TicketAdminService>();
builder.Services.AddScoped<MalwareScanService>();
builder.Services.AddSingleton<IpVerificationService>();
builder.Services.AddScoped<SessionClientService>();
builder.Services.AddSingleton<SessionServerService>();
builder.Services.AddScoped<MailService>();
// Support chat
builder.Services.AddSingleton<SupportChatServerService>();
builder.Services.AddScoped<SupportChatClientService>();
builder.Services.AddScoped<SupportChatAdminService>();
// Helpers
builder.Services.AddSingleton<SmartTranslateHelper>();
builder.Services.AddScoped<WingsApiHelper>();
builder.Services.AddScoped<WingsServerConverter>();
builder.Services.AddSingleton<WingsJwtHelper>();
builder.Services.AddScoped<WingsConsoleHelper>();
builder.Services.AddSingleton<PaperApiHelper>();
builder.Services.AddSingleton<HostSystemHelper>();
builder.Services.AddScoped<DaemonApiHelper>();
builder.Services.AddScoped<CloudPanelApiHelper>();
builder.Services.AddScoped<ModrinthApiHelper>();
builder.Services.AddScoped<TelemetryApiHelper>();
// Background services
builder.Services.AddSingleton<DiscordBotService>();
builder.Services.AddSingleton<StatisticsCaptureService>();
builder.Services.AddSingleton<DiscordNotificationService>();
builder.Services.AddSingleton<CleanupService>();
builder.Services.AddSingleton<MalwareBackgroundScanService>();
builder.Services.AddSingleton<TelemetryService>();
builder.Services.AddSingleton<TempMailService>();
builder.Services.AddSingleton<DdosProtectionService>();
builder.Services.AddSingleton(pluginService);
builder.Services.AddSingleton(letsEncryptService);
// Other
builder.Services.AddSingleton<MoonlightService>();
// Third party services
builder.Services.AddBlazorTable();
builder.Services.AddBlazorContextMenu();
builder.Services.AddBlazorDownloadFile();
StripeConfiguration.ApiKey = configService
.Get()
.Moonlight.Stripe.ApiKey;
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
// Sentry
if (shouldUseSentry)
{
app.UseSentryTracing();
}
app.UseStaticFiles();
app.UseRouting();
app.UseWebSockets();
app.MapControllers();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.MapHealthChecks("/_health", new()
{
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
// AutoStart services
_ = app.Services.GetRequiredService<CleanupService>();
_ = app.Services.GetRequiredService<DiscordBotService>();
_ = app.Services.GetRequiredService<StatisticsCaptureService>();
_ = app.Services.GetRequiredService<DiscordNotificationService>();
_ = app.Services.GetRequiredService<MalwareBackgroundScanService>();
_ = app.Services.GetRequiredService<TelemetryService>();
_ = app.Services.GetRequiredService<TempMailService>();
_ = app.Services.GetRequiredService<DdosProtectionService>();
_ = app.Services.GetRequiredService<MoonlightService>();
// Discord bot service
//var discordBotService = app.Services.GetRequiredService<DiscordBotService>();
Task.Run(async () =>
{
await letsEncryptService.AutoProcess();
});
await app.RunAsync(configService.Get().Moonlight.AppUrl);
} }
} }
} }

View file

@ -1,8 +0,0 @@
# Some explanations
defaultstorage:
This directory is for the default assets of a Moonlight instance, e.g., Lang files, images, etc.
Storage:
This directory is empty in fresh Moonlight instances and will be populated with an example configuration upon first run. Before using Moonlight, this config file has to be modified. Also, resources are going to be copied from the default storage to this storage. To access files in this storage, we recommend using the Path Builder functions to ensure cross-platform compatibility. The storage directory should be mounted to a specific path when using a Docker container, so when the container is replaced or rebuilt,  your storage will not be modified.

373
Moonlight/Startup.cs Normal file
View file

@ -0,0 +1,373 @@
using BlazorDownloadFile;
using BlazorTable;
using HealthChecks.UI.Client;
using Moonlight.App.ApiClients.CloudPanel;
using Moonlight.App.ApiClients.Daemon;
using Moonlight.App.ApiClients.Modrinth;
using Moonlight.App.ApiClients.Paper;
using Moonlight.App.ApiClients.Telemetry;
using Moonlight.App.ApiClients.Wings;
using Moonlight.App.Database;
using Moonlight.App.Diagnostics.HealthChecks;
using Moonlight.App.Events;
using Moonlight.App.Helpers;
using Moonlight.App.Helpers.Wings;
using Moonlight.App.LogMigrator;
using Moonlight.App.Repositories;
using Moonlight.App.Repositories.Domains;
using Moonlight.App.Repositories.Servers;
using Moonlight.App.Services;
using Moonlight.App.Services.Background;
using Moonlight.App.Services.DiscordBot;
using Moonlight.App.Services.Files;
using Moonlight.App.Services.Interop;
using Moonlight.App.Services.Mail;
using Moonlight.App.Services.Notifications;
using Moonlight.App.Services.Plugins;
using Moonlight.App.Services.Sessions;
using Moonlight.App.Services.Statistics;
using Moonlight.App.Services.Tickets;
using Sentry;
using Serilog;
using Serilog.Events;
using Stripe;
using SubscriptionService = Moonlight.App.Services.SubscriptionService;
namespace Moonlight;
public class Startup
{
// Base services
private StorageService StorageService;
private ConfigService ConfigService;
private DatabaseCheckupService DatabaseCheckupService;
private EventSystem Event;
private LetsEncryptService LetsEncryptService;
private PluginService PluginService;
// Builders
private WebApplicationBuilder WebApplicationBuilder;
private WebApplication WebApplication;
public async Task Init(string[] args)
{
WebApplicationBuilder = WebApplication.CreateBuilder(args);
await PreInitServices();
await SetupLoggers();
Logger.Info("[1/5] Initialized base services and loggers");
await PreInit();
await Configure();
await BuildServices();
WebApplication = WebApplicationBuilder.Build();
await ConfigurePipeline();
Logger.Info("Initialisation complete!");
}
public async Task Start()
{
Logger.Info("Starting moonlight panel");
await StartBackgroundServices();
await PostInit();
Logger.Info("Done. Going live now!");
if(ConfigService.DebugMode)
await WebApplication.RunAsync();
else
await WebApplication.RunAsync(ConfigService.Get().Moonlight.AppUrl);
}
private Task PreInitServices()
{
StorageService = new();
ConfigService = new(StorageService);
DatabaseCheckupService = new(ConfigService);
Event = new();
LetsEncryptService = new(ConfigService, Event);
PluginService = new();
return Task.CompletedTask;
}
private Task StartBackgroundServices()
{
Logger.Info("[1/2] Starting background services");
_ = WebApplication.Services.GetRequiredService<CleanupService>();
_ = WebApplication.Services.GetRequiredService<DiscordBotService>();
_ = WebApplication.Services.GetRequiredService<StatisticsCaptureService>();
_ = WebApplication.Services.GetRequiredService<DiscordNotificationService>();
_ = WebApplication.Services.GetRequiredService<MalwareBackgroundScanService>();
_ = WebApplication.Services.GetRequiredService<TelemetryService>();
_ = WebApplication.Services.GetRequiredService<TempMailService>();
_ = WebApplication.Services.GetRequiredService<DdosProtectionService>();
_ = WebApplication.Services.GetRequiredService<MoonlightService>();
return Task.CompletedTask;
}
private Task PostInit()
{
Logger.Info("[2/2] Started post init tasks");
Task.Run(async () =>
{
await LetsEncryptService.AutoProcess();
});
return Task.CompletedTask;
}
private async Task PreInit()
{
Logger.Info("[2/5] Running pre init tasks");
await StorageService.EnsureCreated();
await DatabaseCheckupService.Perform();
}
private Task Configure()
{
Logger.Info("[3/5] Configuring kestrel");
WebApplicationBuilder.WebHost.ConfigureKestrel(options =>
{
options.ConfigureHttpsDefaults(httpsOptions =>
{
httpsOptions.ServerCertificateSelector = LetsEncryptService.SelectCertificate;
});
});
WebApplicationBuilder.Services.AddServerSideBlazor()
.AddHubOptions(options =>
{
options.MaximumReceiveMessageSize = 10000000;
options.ClientTimeoutInterval = TimeSpan.FromSeconds(30);
options.HandshakeTimeout = TimeSpan.FromSeconds(10);
});
WebApplicationBuilder.Services.AddHttpContextAccessor();
WebApplicationBuilder.Services.AddRazorPages();
WebApplicationBuilder.Services.AddHealthChecks()
.AddCheck<DatabaseHealthCheck>("Database")
.AddCheck<NodeHealthCheck>("Nodes")
.AddCheck<DaemonHealthCheck>("Daemons");
if (ConfigService.Get().Moonlight.Sentry.Enable)
{
WebApplicationBuilder.WebHost.UseSentry(options =>
{
options.Dsn = ConfigService
.Get()
.Moonlight.Sentry.Dsn;
options.Debug = ConfigService.DebugMode;
options.DiagnosticLevel = SentryLevel.Warning;
options.TracesSampleRate = 1.0;
options.DiagnosticLogger = new SentryDiagnosticsLogger(SentryLevel.Warning);
});
}
StripeConfiguration.ApiKey = ConfigService
.Get()
.Moonlight.Stripe.ApiKey;
return Task.CompletedTask;
}
private async Task BuildServices()
{
Logger.Info("[4/5] Building services");
await BuildSingletonServices();
await BuildScopedServices();
// Third party services
WebApplicationBuilder.Services.AddBlazorTable();
WebApplicationBuilder.Services.AddBlazorContextMenu();
WebApplicationBuilder.Services.AddBlazorDownloadFile();
await PluginService.BuildServices(WebApplicationBuilder.Services);
}
private Task BuildScopedServices()
{
// Databases
WebApplicationBuilder.Services.AddDbContext<DataContext>();
// Repositories
WebApplicationBuilder.Services.AddScoped<UserRepository>();
WebApplicationBuilder.Services.AddScoped<NodeRepository>();
WebApplicationBuilder.Services.AddScoped<ServerRepository>();
WebApplicationBuilder.Services.AddScoped<ServerBackupRepository>();
WebApplicationBuilder.Services.AddScoped<ImageRepository>();
WebApplicationBuilder.Services.AddScoped<DomainRepository>();
WebApplicationBuilder.Services.AddScoped<SharedDomainRepository>();
WebApplicationBuilder.Services.AddScoped<RevokeRepository>();
WebApplicationBuilder.Services.AddScoped<NotificationRepository>();
WebApplicationBuilder.Services.AddScoped<DdosAttackRepository>();
WebApplicationBuilder.Services.AddScoped<SubscriptionRepository>();
WebApplicationBuilder.Services.AddScoped<LoadingMessageRepository>();
WebApplicationBuilder.Services.AddScoped<NewsEntryRepository>();
WebApplicationBuilder.Services.AddScoped<NodeAllocationRepository>();
WebApplicationBuilder.Services.AddScoped<StatisticsRepository>();
WebApplicationBuilder.Services.AddScoped(typeof(Repository<>));
// Js interopt and session stuff
WebApplicationBuilder.Services.AddScoped<CookieService>();
WebApplicationBuilder.Services.AddScoped<IdentityService>();
WebApplicationBuilder.Services.AddScoped<IpLocateService>();
WebApplicationBuilder.Services.AddScoped<AlertService>();
WebApplicationBuilder.Services.AddScoped<ClipboardService>();
WebApplicationBuilder.Services.AddScoped<ModalService>();
WebApplicationBuilder.Services.AddScoped<FileDownloadService>();
WebApplicationBuilder.Services.AddScoped<KeyListenerService>();
WebApplicationBuilder.Services.AddScoped<PopupService>();
WebApplicationBuilder.Services.AddScoped<SessionClientService>();
WebApplicationBuilder.Services.AddScoped<ReCaptchaService>();
WebApplicationBuilder.Services.AddScoped<DynamicBackgroundService>();
// Main application stuff
WebApplicationBuilder.Services.AddScoped<SmartTranslateService>();
WebApplicationBuilder.Services.AddScoped<UserService>();
WebApplicationBuilder.Services.AddScoped<TotpService>();
WebApplicationBuilder.Services.AddScoped<ToastService>();
WebApplicationBuilder.Services.AddScoped<NodeService>();
WebApplicationBuilder.Services.AddScoped<ServerService>();
WebApplicationBuilder.Services.AddScoped<DomainService>();
WebApplicationBuilder.Services.AddScoped<OneTimeJwtService>();
WebApplicationBuilder.Services.AddScoped<NotificationAdminService>();
WebApplicationBuilder.Services.AddScoped<SmartDeployService>();
WebApplicationBuilder.Services.AddScoped<WebSpaceService>();
WebApplicationBuilder.Services.AddScoped<StatisticsViewService>();
WebApplicationBuilder.Services.AddScoped<RatingService>();
WebApplicationBuilder.Services.AddScoped<IpBanService>();
WebApplicationBuilder.Services.AddScoped<SubscriptionService>();
WebApplicationBuilder.Services.AddScoped<BillingService>();
WebApplicationBuilder.Services.AddScoped<TicketClientService>();
WebApplicationBuilder.Services.AddScoped<TicketAdminService>();
WebApplicationBuilder.Services.AddScoped<MalwareScanService>();
WebApplicationBuilder.Services.AddScoped<MailService>();
WebApplicationBuilder.Services.AddScoped<WingsServerConverter>();
WebApplicationBuilder.Services.AddScoped<WingsConsoleHelper>();
return Task.CompletedTask;
}
private Task BuildSingletonServices()
{
WebApplicationBuilder.Services.AddSingleton(ConfigService);
WebApplicationBuilder.Services.AddSingleton(Event);
WebApplicationBuilder.Services.AddSingleton(PluginService);
WebApplicationBuilder.Services.AddSingleton<StorageService>();
// Api helpers
WebApplicationBuilder.Services.AddSingleton<PaperApiHelper>();
WebApplicationBuilder.Services.AddSingleton<DaemonApiHelper>();
WebApplicationBuilder.Services.AddSingleton<CloudPanelApiHelper>();
WebApplicationBuilder.Services.AddSingleton<ModrinthApiHelper>();
WebApplicationBuilder.Services.AddSingleton<TelemetryApiHelper>();
WebApplicationBuilder.Services.AddSingleton<WingsApiHelper>();
// Main application stuff
WebApplicationBuilder.Services.AddSingleton<HostSystemHelper>();
WebApplicationBuilder.Services.AddSingleton<OAuth2Service>();
WebApplicationBuilder.Services.AddSingleton<PluginStoreService>();
WebApplicationBuilder.Services.AddSingleton<TicketServerService>();
WebApplicationBuilder.Services.AddSingleton<IpVerificationService>();
WebApplicationBuilder.Services.AddSingleton<NotificationServerService>();
WebApplicationBuilder.Services.AddSingleton<DateTimeService>();
WebApplicationBuilder.Services.AddSingleton<MoonlightService>();
WebApplicationBuilder.Services.AddSingleton<ResourceService>();
WebApplicationBuilder.Services.AddSingleton<BucketService>();
// Helpers
WebApplicationBuilder.Services.AddSingleton<SmartTranslateHelper>();
WebApplicationBuilder.Services.AddSingleton<WingsJwtHelper>();
// Background services
WebApplicationBuilder.Services.AddSingleton<DiscordBotService>();
WebApplicationBuilder.Services.AddSingleton<StatisticsCaptureService>();
WebApplicationBuilder.Services.AddSingleton<DiscordNotificationService>();
WebApplicationBuilder.Services.AddSingleton<CleanupService>();
WebApplicationBuilder.Services.AddSingleton<MalwareBackgroundScanService>();
WebApplicationBuilder.Services.AddSingleton<TelemetryService>();
WebApplicationBuilder.Services.AddSingleton<TempMailService>();
WebApplicationBuilder.Services.AddSingleton<DdosProtectionService>();
WebApplicationBuilder.Services.AddSingleton<SessionServerService>();
return Task.CompletedTask;
}
private Task SetupLoggers()
{
var logConfig = new LoggerConfiguration();
if (ConfigService.DebugMode)
logConfig = logConfig.MinimumLevel.Verbose();
else
logConfig = logConfig.MinimumLevel.Information();
if (ConfigService.Get().Moonlight.Sentry.Enable)
{
if (ConfigService.DebugMode)
{
logConfig = logConfig.WriteTo.Sentry(options =>
{
options.MinimumBreadcrumbLevel = LogEventLevel.Debug;
options.MinimumEventLevel = LogEventLevel.Warning;
});
}
else
{
logConfig = logConfig.WriteTo.Sentry(options =>
{
options.MinimumBreadcrumbLevel = LogEventLevel.Information;
options.MinimumEventLevel = LogEventLevel.Warning;
});
}
}
logConfig = logConfig.Enrich.FromLogContext()
.WriteTo.Console(
outputTemplate:
"{Timestamp:HH:mm:ss} [{Level:u3}] {SourceContext} {Message:lj}{NewLine}{Exception}")
.WriteTo.File(PathBuilder.File("storage", "logs", $"{DateTime.UtcNow:yyyy-MM-dd}.log"));
Log.Logger = logConfig.CreateLogger();
WebApplicationBuilder.Logging.ClearProviders();
WebApplicationBuilder.Logging.AddProvider(new LogMigratorProvider());
return Task.CompletedTask;
}
private Task ConfigurePipeline()
{
Logger.Info("[5/5] Configuring pipeline");
if (!WebApplication.Environment.IsDevelopment())
{
WebApplication.UseExceptionHandler("/Error");
}
// Sentry
if (ConfigService.Get().Moonlight.Sentry.Enable)
{
WebApplication.UseSentryTracing();
}
WebApplication.UseStaticFiles();
WebApplication.UseRouting();
WebApplication.UseWebSockets();
WebApplication.MapControllers();
WebApplication.MapBlazorHub();
WebApplication.MapFallbackToPage("/_Host");
WebApplication.MapHealthChecks("/_health", new()
{
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
return Task.CompletedTask;
}
}