From c2c10103b8c57fcdf963731d26e99281a1f1e3fd Mon Sep 17 00:00:00 2001 From: librelad Date: Tue, 26 May 2026 00:31:23 +0100 Subject: [PATCH] feat(webui): surface system-config backup/restore on the backup dashboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a "System config" card to the backup dashboard with two actions wired through the task processor (same path as "Backup all apps"): - "Back up now" -> libreportal backup system - "Restore…" -> libreportal restore system (confirm dialog explains it lands in a staging folder and never overwrites live config) Card copy explains why it matters (the backup-location creds otherwise live only on the box). Click handlers + runBackupSystem/confirmRestoreSystem added; JS parses, data-actions match handlers, commands match the CLI subcommands. Co-Authored-By: Claude Opus 4.7 Signed-off-by: librelad --- .../frontend/html/backup-content.html | 15 +++++++++++++++ .../js/components/backup/backup-page.js | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/containers/libreportal/frontend/html/backup-content.html b/containers/libreportal/frontend/html/backup-content.html index a940f78..624d52f 100644 --- a/containers/libreportal/frontend/html/backup-content.html +++ b/containers/libreportal/frontend/html/backup-content.html @@ -88,6 +88,21 @@
+
+
+

System config

+ Global settings, WebUI login & backup-location credentials +
+

+ Snapshot the LibrePortal system config to every enabled location so a bare-metal + restore is self-sufficient — without it, the credentials needed to reach your own + backups live only on this box. Runs automatically with “Backup all apps” too. +

+
+ + +
+
diff --git a/containers/libreportal/frontend/js/components/backup/backup-page.js b/containers/libreportal/frontend/js/components/backup/backup-page.js index 6cb8fec..bc90606 100644 --- a/containers/libreportal/frontend/js/components/backup/backup-page.js +++ b/containers/libreportal/frontend/js/components/backup/backup-page.js @@ -176,6 +176,16 @@ class BackupPage { return; } + if (e.target.closest('[data-action="backup-system"]')) { + this.runBackupSystem(); + return; + } + + if (e.target.closest('[data-action="restore-system"]')) { + this.confirmRestoreSystem(); + return; + } + const restoreBtn = e.target.closest('[data-action="restore-snapshot"]'); if (restoreBtn) { this.openRestoreModal(restoreBtn.dataset.app, restoreBtn.dataset.loc, restoreBtn.dataset.snapshot); @@ -1724,6 +1734,15 @@ class BackupPage { await this.runTask(`libreportal backup all`, 'backup', null); } + async runBackupSystem() { + await this.runTask(`libreportal backup system`, 'backup', null); + } + + async confirmRestoreSystem() { + if (!confirm('Restore the latest system-config snapshot?\n\nIt is restored into a staging folder (not applied) — review it, then copy what you need (e.g. backup-location credentials, login, settings) into the live config. Your running config is NOT overwritten.')) return; + await this.runTask(`libreportal restore system`, 'restore', null); + } + async runTask(command, type, app) { if (!this.taskManager) { this.notify('Task system unavailable', 'error');