diff --git a/src/main/app-controller.ts b/src/main/app-controller.ts index 41df20d..10e7450 100644 --- a/src/main/app-controller.ts +++ b/src/main/app-controller.ts @@ -372,17 +372,20 @@ export class AppController { return this.getRemoteDiagnostics(); } - private restoreMcpRemoteFromBackup(section: unknown): void { + private restoreMcpRemoteFromBackup(section: unknown, restartNow: boolean): void { const restore = resolveMcpRemoteRestore(section); if (!restore) { return; } writeDebugServerConfig({ host: restore.host, port: restore.port, allowlist: restore.allowlist }); - void restartDebugServer().catch(() => {}); + if (restartNow) { + void restartDebugServer().catch(() => {}); + } this.audit("INFO", "Ferndiagnose-Einstellungen aus Backup wiederhergestellt", { port: restore.port ?? null, allowlistCount: restore.allowlist?.length ?? 0, - host: restore.host ?? "unveraendert" + host: restore.host ?? "unveraendert", + restartNow }); } @@ -827,7 +830,7 @@ public async checkDebridAccounts(): Promise { this.settings = restoredSettings; saveSettings(this.storagePaths, this.settings); this.manager.setSettings(this.settings, { suppressRetroactiveCleanup: true }); - this.restoreMcpRemoteFromBackup(parsed.mcpRemote); + this.restoreMcpRemoteFromBackup(parsed.mcpRemote, true); this.audit("INFO", "Backup importiert (nur Einstellungen)", { accountSummary: buildAccountSummary(this.settings) }); @@ -864,6 +867,8 @@ public async checkDebridAccounts(): Promise { resetHistoryForRetention(this.storagePaths, this.settings.historyRetentionMode); + this.restoreMcpRemoteFromBackup(parsed.mcpRemote, false); + this.manager.skipShutdownPersist = true; this.manager.blockAllPersistence = true; logger.info("Backup wiederhergestellt — App startet automatisch neu"); diff --git a/tests/backup-mcp.test.ts b/tests/backup-mcp.test.ts index 79963a9..5e868c1 100644 --- a/tests/backup-mcp.test.ts +++ b/tests/backup-mcp.test.ts @@ -7,6 +7,7 @@ import { afterEach, describe, expect, it } from "vitest"; import { buildBackupPayload, resolveMcpRemoteRestore, BackupMcpRemote } from "../src/main/backup-payload"; import { defaultSettings } from "../src/main/constants"; +import { normalizeSettings } from "../src/main/storage"; import { startDebugServer, stopDebugServer, @@ -100,6 +101,14 @@ describe("backup mcpRemote export gating", () => { }); }); +describe("backupIncludeMcp settings persistence", () => { + it("normalizeSettings preserves backupIncludeMcp (the toggle survives save/load)", () => { + expect(normalizeSettings({ backupIncludeMcp: true } as unknown as AppSettings).backupIncludeMcp).toBe(true); + expect(normalizeSettings({ backupIncludeMcp: false } as unknown as AppSettings).backupIncludeMcp).toBe(false); + expect(normalizeSettings({} as unknown as AppSettings).backupIncludeMcp).toBe(false); + }); +}); + describe("resolveMcpRemoteRestore", () => { it("maps network + non-empty allowlist to 0.0.0.0", () => { expect(resolveMcpRemoteRestore({ allowlist: ["10.0.0.5"], port: 9868, hostMode: "network" })) @@ -167,4 +176,24 @@ describe("backup mcpRemote live restore round-trip", () => { await waitForReady(`http://127.0.0.1:${restorePort}/health?token=rt-secret`); }); + + it("full-backup path writes the debug_* files to disk without a restart (boot picks them up)", async () => { + const baseDir = fs.mkdtempSync(path.join(os.tmpdir(), "rd-bkmcp2-")); + tempDirs.push(baseDir); + const startPort = await getFreePort(); + fs.writeFileSync(path.join(baseDir, "debug_token.txt"), "rt2", "utf8"); + fs.writeFileSync(path.join(baseDir, "debug_port.txt"), String(startPort), "utf8"); + fs.writeFileSync(path.join(baseDir, "debug_host.txt"), "127.0.0.1", "utf8"); + fs.writeFileSync(path.join(baseDir, "debug_allowlist.txt"), "", "utf8"); + startDebugServer({} as unknown as DownloadManager, baseDir); + await waitForReady(`http://127.0.0.1:${startPort}/health?token=rt2`); + + const restore = resolveMcpRemoteRestore({ allowlist: ["198.51.100.9"], port: 9100, hostMode: "network" }); + writeDebugServerConfig({ host: restore!.host, port: restore!.port, allowlist: restore!.allowlist }); + + expect(fs.readFileSync(path.join(baseDir, "debug_host.txt"), "utf8").trim()).toBe("0.0.0.0"); + expect(fs.readFileSync(path.join(baseDir, "debug_port.txt"), "utf8").trim()).toBe("9100"); + expect(fs.readFileSync(path.join(baseDir, "debug_allowlist.txt"), "utf8")).toContain("198.51.100.9"); + expect(getDebugServerRuntimeStatus().port).toBe(startPort); + }); });