diff --git a/dashboard/src/components/app/Backups.vue b/dashboard/src/components/app/Backups.vue index 3b092bdfb..03738de63 100644 --- a/dashboard/src/components/app/Backups.vue +++ b/dashboard/src/components/app/Backups.vue @@ -219,20 +219,11 @@ function getDownloadLink(backup) { } async function onDownloadConfig(backup) { - const [error, backupSite] = await backupSitesModel.get(backup.siteId); - if (error) return console.error(error); - - const tmp = { - remotePath: backup.remotePath - }; - for (const k of ['provider', 'config', 'limits', 'format', 'encrypted', 'encryptedFilenames', 'encryptionPasswordHint']) { - tmp[k] = backupSite[k]; - } - - tmp.siteId = backupSite.id; + const [backupConfigError, backupConfig] = await backupSitesModel.generateBackupConfig(backup); + if (backupConfigError) return console.error(backupConfigError); const filename = `${props.app.fqdn}-backup-config-${(new Date(backup.creationTime)).toISOString().split('T')[0]}.json`; - download(filename, JSON.stringify(tmp, null, 4)); + download(filename, JSON.stringify(backupConfig, null, 4)); } const restoreBusy = ref(false); diff --git a/dashboard/src/models/BackupSitesModel.js b/dashboard/src/models/BackupSitesModel.js index 674a0e89a..e5e532059 100644 --- a/dashboard/src/models/BackupSitesModel.js +++ b/dashboard/src/models/BackupSitesModel.js @@ -190,6 +190,21 @@ function create() { if (error || result.status !== 202) return [error || result]; return [null, result.body]; }, + async generateBackupConfig(backupOrArchive) { + const [backupSiteError, backupSite] = await this.get(backupOrArchive.siteId); + if (backupSiteError) return [backupSiteError]; + + const config = { + remotePath: backupOrArchive.remotePath + }; + + for (const k of ['provider', 'config', 'limits', 'format', 'encrypted', 'encryptedFilenames', 'encryptionPasswordHint']) { + config[k] = backupSite[k]; + } + + config.siteId = backupSite.id; + return [null, config]; + } }; } diff --git a/dashboard/src/views/AppArchiveView.vue b/dashboard/src/views/AppArchiveView.vue index 599ca5050..4760ffa6d 100644 --- a/dashboard/src/views/AppArchiveView.vue +++ b/dashboard/src/views/AppArchiveView.vue @@ -12,8 +12,10 @@ import AppRestoreDialog from '../components/AppRestoreDialog.vue'; import Section from '../components/Section.vue'; import ArchivesModel from '../models/ArchivesModel.js'; import { download } from '../utils.js'; +import BackupSitesModel from '../models/BackupSitesModel.js'; const archivesModel = ArchivesModel.create(); +const backupSitesModel = BackupSitesModel.create(); const columns = { icon: {}, // archived @@ -98,19 +100,11 @@ async function onRestore(archive) { } async function onDownloadConfig(archive) { - // secrets and tokens already come with placeholder characters we remove them - // TODO fill tmp from target config - const tmp = { - remotePath: archive.remotePath, - // encrypted: !!props.config.password // we add this just to help the import UI - }; - - // Object.keys(props.config).forEach((k) => { - // if (props.config[k] !== SECRET_PLACEHOLDER) tmp[k] = props.config[k]; - // }); + const [backupConfigError, backupConfig] = await backupSitesModel.generateBackupConfig(archive); + if (backupConfigError) return console.error(backupConfigError); const filename = `${archive.appConfig.fqdn}-archive-config-${(new Date(archive.creationTime)).toISOString().split('T')[0]}.json`; - download(filename, JSON.stringify(tmp, null, 4)); + download(filename, JSON.stringify(backupConfig, null, 4)); } onMounted(async () => { diff --git a/dashboard/src/views/BackupListView.vue b/dashboard/src/views/BackupListView.vue index 7f2c43e7d..f4511e4f1 100644 --- a/dashboard/src/views/BackupListView.vue +++ b/dashboard/src/views/BackupListView.vue @@ -197,20 +197,11 @@ async function onDownloadConfig(backup) { const [error, dashboardConfig] = await dashboardModel.config(); if (error) return console.error(error); - const [backupSiteError, backupSite] = await backupSitesModel.get(backup.siteId); - if (backupSiteError) return console.error(backupSiteError); - - const tmp = { - remotePath: backup.remotePath - }; - for (const k of ['provider', 'config', 'limits', 'format', 'encrypted', 'encryptedFilenames', 'encryptionPasswordHint']) { - tmp[k] = backupSite[k]; - } - - tmp.siteId = backupSite.id; + const [backupConfigError, backupConfig] = await backupSitesModel.generateBackupConfig(backup); + if (backupConfigError) return console.error(backupConfigError); const filename = `${dashboardConfig.adminFqdn}-backup-config-${(new Date(backup.creationTime)).toISOString().split('T')[0]}.json`; - download(filename, JSON.stringify(tmp, null, 4)); + download(filename, JSON.stringify(backupConfig, null, 4)); } // backups info dialog diff --git a/src/archives.js b/src/archives.js index 68e2109dc..a346542dd 100644 --- a/src/archives.js +++ b/src/archives.js @@ -17,7 +17,7 @@ const assert = require('node:assert'), eventlog = require('./eventlog.js'), safe = require('safetydance'); -const ARCHIVE_FIELDS = [ 'archives.id', 'backupId', 'archives.creationTime', 'backups.remotePath', 'backups.manifestJson', 'backups.appConfigJson', '(archives.icon IS NOT NULL) AS hasIcon', '(archives.appStoreIcon IS NOT NULL) AS hasAppStoreIcon' ]; +const ARCHIVE_FIELDS = [ 'archives.id', 'backupId', 'archives.creationTime', 'backups.remotePath', 'backups.siteId', 'backups.manifestJson', 'backups.appConfigJson', '(archives.icon IS NOT NULL) AS hasIcon', '(archives.appStoreIcon IS NOT NULL) AS hasAppStoreIcon' ]; function postProcess(result) { assert.strictEqual(typeof result, 'object');