Fix C1/C2 + reliability cluster (L140/L141/L148, R6/R7)
Critical: - C1: single source of truth for IPC mock + Settings defaults. DEFAULT_SETTINGS in @shared/ipc; main DEFAULTS, renderer FALLBACK, and preview MOCK_SETTINGS all derive from it. Whole browser mock collapsed into one typed mockApi.ts; main.tsx shrinks to window.api = mockApi. PREVIEW check single-sourced in isPreview.ts. - C2: break the downloads<->sources circular import via a typed event bus (store/coordinator.ts). App eagerly imports sources for side-effects so startup load + scheduled --sync + downloadCompleted subscription still run. Reliability: - L140/L148: cancel/pause release the active slot synchronously; identity-guarded releaseActive; per-spawn cookie jar so a same-id retry/resume is never rejected by a stale entry nor run over the concurrency cap. - L141: renderer history capped at 500 + url de-dup to match main. - R6: writeJsonAtomic reports/logs write failures and keeps data dirty for retry instead of an empty catch. - R7: encryptSecret warns before the plaintext fallback. typecheck + 243 tests + eslint green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+11
-45
@@ -13,6 +13,7 @@ import {
|
||||
VIDEO_QUALITY_OPTIONS,
|
||||
AUDIO_QUALITY_OPTIONS,
|
||||
DEFAULT_DOWNLOAD_OPTIONS,
|
||||
DEFAULT_SETTINGS,
|
||||
isYtdlpUpdateChannel,
|
||||
type Settings,
|
||||
type DownloadOptions,
|
||||
@@ -22,51 +23,11 @@ import {
|
||||
type VideoCodecPref
|
||||
} from '@shared/ipc'
|
||||
|
||||
const DEFAULTS: Settings = {
|
||||
// Both blank by default → downloads land in Documents\Video / Documents\Audio
|
||||
// (see getDefaultMediaDir). A non-empty value is an explicit per-kind override.
|
||||
videoDir: '',
|
||||
audioDir: '',
|
||||
defaultKind: 'video',
|
||||
defaultVideoQuality: 'Best available',
|
||||
defaultAudioQuality: 'Best',
|
||||
maxConcurrent: 2,
|
||||
filenameTemplate: '%(title)s.%(ext)s',
|
||||
// Follow the OS theme on first launch (SR1) so a dark-mode Windows user isn't
|
||||
// greeted by a bright white window despite full system-theme support.
|
||||
theme: 'system',
|
||||
accentColor: 'teal',
|
||||
clipboardWatch: true,
|
||||
downloadOptions: DEFAULT_DOWNLOAD_OPTIONS,
|
||||
proxy: '',
|
||||
rateLimit: '',
|
||||
useAria2c: false,
|
||||
cookieSource: 'none',
|
||||
cookiesBrowser: 'chrome',
|
||||
youtubePlayerClient: '',
|
||||
youtubePoToken: '',
|
||||
restrictFilenames: false,
|
||||
downloadArchive: false,
|
||||
// yt-dlp is self-managed: a writable copy under userData, auto-updated on the
|
||||
// configured channel so a stale binary can't silently cause YouTube 403s.
|
||||
autoUpdateYtdlp: true,
|
||||
// Default to stable so a nightly regression doesn't break downloads for
|
||||
// everyone out of the box (SR2). Users who want the latest YouTube fixes
|
||||
// can switch to nightly in Settings → Software.
|
||||
ytdlpChannel: 'stable',
|
||||
ytdlpLastUpdateCheck: 0,
|
||||
customCommandEnabled: false,
|
||||
defaultTemplateId: null,
|
||||
notifyOnComplete: true,
|
||||
// Default off so adding a watched channel doesn't silently fill the user's
|
||||
// disk on first use (SR3). Enable explicitly once they know what it does.
|
||||
autoDownloadNew: false,
|
||||
hasCompletedOnboarding: false,
|
||||
minimizeToTray: false,
|
||||
launchAtStartup: false,
|
||||
sidebarCollapsed: false,
|
||||
updateToken: ''
|
||||
}
|
||||
// The electron-store defaults are the canonical DEFAULT_SETTINGS from the shared
|
||||
// contract — single-sourced so the renderer FALLBACK and the preview mock can't
|
||||
// drift from main (C1). The rationale for individual defaults (SR1/SR2/SR3) lives
|
||||
// alongside DEFAULT_SETTINGS in shared/ipc.ts.
|
||||
const DEFAULTS: Settings = DEFAULT_SETTINGS
|
||||
|
||||
/**
|
||||
* Sync the OS "run at sign-in" entry with the launchAtStartup setting. Called at
|
||||
@@ -197,6 +158,11 @@ function encryptSecret(plain: string): string {
|
||||
} catch {
|
||||
/* fall through — store plaintext, as it was before encryption existed */
|
||||
}
|
||||
// R7: OS encryption (DPAPI/keychain) is unavailable, so this credential is about
|
||||
// to be written in cleartext. Warn rather than fall back silently — a leaked
|
||||
// settings.json would then expose the proxy password / API token. (DPAPI is
|
||||
// effectively always present on Windows, so this should never fire in practice.)
|
||||
console.warn('[AeroFetch] OS secret encryption unavailable — storing credential as plaintext.')
|
||||
return plain
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user