Phase 4: backups + import/export config
ConfigStore.SaveAsync now snapshots the previous config to %ProgramData%\WebhookServer\backups\config-<timestamp>.json before overwriting, retaining the last 30. Failures are silent so a backup-write hiccup never blocks an actual save. Three new admin pipe ops: - list-backups: returns newest 50 entries with timestamps and sizes - restore-backup: takes a fileName, refuses path-traversal chars, loads the named backup over the live config (which itself triggers a fresh backup of the current state via the SaveAsync hook) - import-config: replaces the current config with a GUI-supplied ServerConfig, merging encrypted secrets where the GUI didn't supply new plaintext GUI File menu items are wired: - Import config: file picker -> ImportConfigAsync - Export config: SaveFileDialog writes the current config as JSON - Backups: dynamic submenu auto-refreshed when opened, listing backups with timestamp + size; click to confirm-and-restore Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -86,4 +86,18 @@ public sealed class AdminPipeClient
|
||||
var lst = resp.Data.Value.GetProperty("lines").Deserialize<List<LogLine>>(AdminProtocol.JsonOptions);
|
||||
return lst ?? new List<LogLine>();
|
||||
}
|
||||
|
||||
public async Task<List<BackupEntry>> ListBackupsAsync(CancellationToken ct = default)
|
||||
{
|
||||
var resp = await InvokeAsync(AdminOps.ListBackups, null, ct).ConfigureAwait(false);
|
||||
if (!resp.Ok || resp.Data is null) return new List<BackupEntry>();
|
||||
var lst = resp.Data.Value.GetProperty("backups").Deserialize<List<BackupEntry>>(AdminProtocol.JsonOptions);
|
||||
return lst ?? new List<BackupEntry>();
|
||||
}
|
||||
|
||||
public Task<AdminResponse> RestoreBackupAsync(string fileName, CancellationToken ct = default) =>
|
||||
InvokeAsync(AdminOps.RestoreBackup, new RestoreBackupArgs { FileName = fileName }, ct);
|
||||
|
||||
public Task<AdminResponse> ImportConfigAsync(ServerConfig config, CancellationToken ct = default) =>
|
||||
InvokeAsync(AdminOps.ImportConfig, config, ct);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user