diff --git a/LANCommander.Server/Endpoints/LogEndpoints.cs b/LANCommander.Server/Endpoints/LogEndpoints.cs new file mode 100644 index 00000000..959a2169 --- /dev/null +++ b/LANCommander.Server/Endpoints/LogEndpoints.cs @@ -0,0 +1,43 @@ +using LANCommander.Server.Settings.Enums; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using System.Net.Mime; + +namespace LANCommander.Server.Endpoints; + +public static class LogEndpoints +{ + public static void MapLogEndpoints(this IEndpointRouteBuilder routes) + { + var group = routes.MapGroup("/api/Logs") + .RequireAuthorization(); + + group.MapGet("/Download/{fileName}", DownloadAsync); + } + + private static IResult DownloadAsync( + string fileName, + [FromServices] IOptions settings) + { + var fileProvider = settings.Value.Server.Logs.Providers + .FirstOrDefault(p => p.Type == LoggingProviderType.File && p.Enabled); + + if (fileProvider == null) + return TypedResults.NotFound("No file logging provider is configured."); + + // Sanitize the file name to prevent directory traversal + fileName = Path.GetFileName(fileName); + + if (!fileName.StartsWith("log-") || !fileName.EndsWith(".txt")) + return TypedResults.BadRequest("Invalid log file name."); + + var logFilePath = Path.Combine(fileProvider.ConnectionString, fileName); + + if (!File.Exists(logFilePath)) + return TypedResults.NotFound("Log file not found."); + + var stream = new FileStream(logFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + + return TypedResults.File(stream, MediaTypeNames.Text.Plain, fileName); + } +} diff --git a/LANCommander.Server/Startup/Endpoints.cs b/LANCommander.Server/Startup/Endpoints.cs index 19415c03..40c18392 100644 --- a/LANCommander.Server/Startup/Endpoints.cs +++ b/LANCommander.Server/Startup/Endpoints.cs @@ -37,6 +37,7 @@ public static class Endpoints endpoints.MapSaveEndpoints(); endpoints.MapServerEndpoints(); endpoints.MapSettingsEndpoints(); + endpoints.MapLogEndpoints(); endpoints.MapHqEndpoints(); endpoints.MapTagEndpoints(); endpoints.MapControllers(); diff --git a/LANCommander.Server/UI/Pages/Settings/Logs/Index.razor b/LANCommander.Server/UI/Pages/Settings/Logs/Index.razor index 8921148f..4df6324d 100644 --- a/LANCommander.Server/UI/Pages/Settings/Logs/Index.razor +++ b/LANCommander.Server/UI/Pages/Settings/Logs/Index.razor @@ -7,10 +7,15 @@ @inject IOptions Settings @inject SettingsProvider SettingsProvider @inject IMessageService MessageService +@inject NavigationManager NavigationManager @inject ILogger Logger + @if (FileProvider != null) + { + + } @@ -52,6 +57,7 @@ @code { List Providers = new(); + LoggingProvider? FileProvider => Providers.FirstOrDefault(p => p.Type == LoggingProviderType.File && p.Enabled); protected override void OnInitialized() { @@ -92,4 +98,21 @@ { Providers.Remove(provider); } + + void DownloadLog() + { + if (FileProvider == null) + return; + + var logFileName = $"log-{DateTime.Now:yyyy-MM-dd}.txt"; + var logFilePath = Path.Combine(FileProvider.ConnectionString, logFileName); + + if (!File.Exists(logFilePath)) + { + MessageService.Warning("No log file exists for today."); + return; + } + + NavigationManager.NavigateTo($"/api/Logs/Download/{logFileName}", true); + } } \ No newline at end of file