From 0c4d32de0f787937aeac661933d8a36d2faa0e1d Mon Sep 17 00:00:00 2001 From: Meleki Date: Tue, 3 Mar 2026 10:01:30 +0100 Subject: [PATCH] fix: Backup-Download (0 Bytes + fehlender Dateiname) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - api.js: credentials: 'include' hinzugefügt (Auth-Cookie) - BackupEndpoint.cs: Task → Task mit direktem Response-Handling (ASP.NET hat IResult nicht korrekt verarbeitet → leerer Body) --- Endpoints/BackupEndpoint.cs | 33 +++++++++++++++++++++++++++------ wwwroot/js/api.js | 2 +- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/Endpoints/BackupEndpoint.cs b/Endpoints/BackupEndpoint.cs index b61f4ef..e36814a 100644 --- a/Endpoints/BackupEndpoint.cs +++ b/Endpoints/BackupEndpoint.cs @@ -2,6 +2,7 @@ using System; using System.Diagnostics; using System.IO; using System.Linq; +using System.Threading.Tasks; using Gott.Extensions; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; @@ -16,14 +17,23 @@ public static class BackupEndpoint app.MapPost("/api/backup", HandleBackup); } - private static async System.Threading.Tasks.Task HandleBackup(HttpContext ctx) + private static async Task HandleBackup(HttpContext ctx) { if (!ctx.IsAdmin()) - return Results.Forbid(); + { + ctx.Response.StatusCode = 403; + return; + } + var dataDir = Path.Combine(AppContext.BaseDirectory, "data"); if (!Directory.Exists(dataDir)) - return Results.NotFound(new { error = "Data-Ordner nicht gefunden" }); + { + ctx.Response.StatusCode = 404; + ctx.Response.ContentType = "application/json"; + await ctx.Response.WriteAsync("{\"error\":\"Data-Ordner nicht gefunden\"}"); + return; + } var backupDir = Path.Combine(dataDir, "backup"); Directory.CreateDirectory(backupDir); @@ -53,16 +63,27 @@ public static class BackupEndpoint using (var process = Process.Start(psi)) { if (process == null) - return Results.StatusCode(500); + { + ctx.Response.StatusCode = 500; + return; + } var stderr = await process.StandardError.ReadToEndAsync(); await process.WaitForExitAsync(); if (process.ExitCode != 0) - return Results.Problem($"tar fehlgeschlagen: {stderr}"); + { + ctx.Response.StatusCode = 500; + ctx.Response.ContentType = "application/json"; + await ctx.Response.WriteAsync($"{{\"error\":\"tar fehlgeschlagen: {stderr}\"}}"); + return; + } } var bytes = await File.ReadAllBytesAsync(archivePath); - return Results.File(bytes, "application/gzip", archiveName); + ctx.Response.StatusCode = 200; + ctx.Response.ContentType = "application/gzip"; + ctx.Response.Headers["Content-Disposition"] = $"attachment; filename=\"{archiveName}\""; + await ctx.Response.Body.WriteAsync(bytes); } } diff --git a/wwwroot/js/api.js b/wwwroot/js/api.js index 8993285..d1c6f6e 100644 --- a/wwwroot/js/api.js +++ b/wwwroot/js/api.js @@ -299,7 +299,7 @@ async function apiTelegramDeleteWebhook() { } async function apiBackupDb() { - const resp = await fetch('/api/backup', { method: 'POST' }); + const resp = await fetch('/api/backup', { method: 'POST', credentials: 'include' }); if (!resp.ok) throw new Error('Backup fehlgeschlagen'); const blob = await resp.blob(); const cd = resp.headers.get('content-disposition') || '';