feat(audit): Batch 23 — settings key renames with migration (CC1) + config.ts (CC11)
CC1: customCommandEnabled→enableCustomCommands, downloadArchive→ useDownloadArchive, clipboardWatch→watchClipboard, sidebarCollapsed→ isSidebarCollapsed, hardwareAcceleration→useHardwareAcceleration, videoDir/audioDir→videoFolder/audioFolder (+ chooseDir/clearDir store actions → chooseFolder/clearFolder). Rename map in settingsMigration.ts (pure, unit-tested incl. pre-rename backup fixture), applied as an idempotent on-disk shim at store open and on backup import so old settings.json and old backups both keep working. CC11: update host/owner/repo + release API moved to src/main/config.ts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+9
-4
@@ -1,6 +1,7 @@
|
||||
import { dialog, type BrowserWindow } from 'electron'
|
||||
import { readFileSync, writeFileSync } from 'fs'
|
||||
import { getSettings, setSettings, SECRET_KEYS } from './settings'
|
||||
import { migrateSettingsKeys } from './settingsMigration'
|
||||
import { listTemplates, replaceTemplates } from './templates'
|
||||
import { isTemplateLike } from './validation'
|
||||
import type { BackupExportResult, BackupImportResult, Settings, CommandTemplate } from '@shared/ipc'
|
||||
@@ -54,9 +55,13 @@ export async function importBackup(win: BrowserWindow | undefined): Promise<Back
|
||||
// hand-edited or partial backup file degrades gracefully rather than
|
||||
// corrupting the store.
|
||||
const file = parsed as Partial<BackupFile>
|
||||
// Backups exported by an older AeroFetch carry pre-rename keys (CC1) — map
|
||||
// them forward so old backup files keep restoring cleanly.
|
||||
const incomingSettings =
|
||||
file.settings && typeof file.settings === 'object'
|
||||
? (file.settings as Partial<Settings>)
|
||||
? (migrateSettingsKeys(
|
||||
file.settings as unknown as Record<string, unknown>
|
||||
) as Partial<Settings>)
|
||||
: undefined
|
||||
// Drop non-object / id-less entries up front (audit T3) so both the consent
|
||||
// check below and replaceTemplates see only well-shaped rows. Without this a
|
||||
@@ -67,7 +72,7 @@ export async function importBackup(win: BrowserWindow | undefined): Promise<Back
|
||||
: []
|
||||
|
||||
// A custom-command template's `args` are extra yt-dlp flags that get spawned on
|
||||
// the next download. A backup that arrives with customCommandEnabled + a default
|
||||
// the next download. A backup that arrives with enableCustomCommands + a default
|
||||
// template carrying args would silently enable code execution the moment a
|
||||
// download starts — so require an explicit, informed confirmation before
|
||||
// honouring that, and import the templates in a *disabled* state if declined.
|
||||
@@ -75,7 +80,7 @@ export async function importBackup(win: BrowserWindow | undefined): Promise<Back
|
||||
(t) => t && typeof t === 'object' && typeof t.args === 'string' && t.args.trim() !== ''
|
||||
)
|
||||
const wouldEnableCustomCommands =
|
||||
incomingSettings?.customCommandEnabled === true && commandTemplates.length > 0
|
||||
incomingSettings?.enableCustomCommands === true && commandTemplates.length > 0
|
||||
|
||||
let applyCustomCommands = true
|
||||
if (wouldEnableCustomCommands) {
|
||||
@@ -120,7 +125,7 @@ export async function importBackup(win: BrowserWindow | undefined): Promise<Back
|
||||
// enable), force the toggle off so an imported defaultTemplateId can't auto-run.
|
||||
const safeSettings = applyCustomCommands
|
||||
? restored
|
||||
: { ...restored, customCommandEnabled: false }
|
||||
: { ...restored, enableCustomCommands: false }
|
||||
setSettings(safeSettings)
|
||||
}
|
||||
if (incomingTemplates.length > 0 || Array.isArray(file.templates)) {
|
||||
|
||||
Reference in New Issue
Block a user