release: v2.1.12 reliability and security hardening
CI / verify (push) Waiting to run

Verify update artifacts with exact metadata and SHA-512, require host-confirmed upload completion before cleanup, harden credentials and backups, improve queue recovery and skipped-state reporting, expand Windows path coverage, and add CI packaging checks.
This commit is contained in:
Sucukdeluxe
2026-08-11 22:36:21 +02:00
parent 2c124c848c
commit 2ba0106ef0
47 changed files with 2069 additions and 1192 deletions
+10 -3
View File
@@ -72,6 +72,8 @@ const DEFAULTS = {
// erase) the legacy sessionLog:true → "daily" migration. normalizeLogMode in
// load() sets logMode after the merge, looking at the saved-only data.
resumeQueueOnLaunch: true,
autoStartRestoredQueue: false,
allowPlaintextCredentialStorage: false,
parallelUploadCount: 0, // 0 = use per-hoster limits only
scaleParallelUploads: false,
lastBrowseDirectory: '',
@@ -91,6 +93,7 @@ const DEFAULTS = {
enabled: false,
folderPath: '',
recursive: false,
includeExisting: false,
filterMode: 'include', // 'include' | 'exclude'
extensions: '', // comma-separated: 'mp4,mkv,avi'
skipDuplicates: true,
@@ -179,7 +182,7 @@ function applyHistoryRetention(history, retention, nowMs) {
}
class ConfigStore {
constructor(app) {
constructor(app, options = {}) {
const useUserDataDir = app && (
app.isPackaged ||
(app.commandLine && typeof app.commandLine.hasSwitch === 'function' && app.commandLine.hasSwitch('user-data-dir'))
@@ -198,6 +201,7 @@ class ConfigStore {
this._cacheKey = '';
this._perfLog = null;
this._wqDepth = 0;
this._allowPlaintextCredentialStorage = options.allowPlaintextCredentialStorage === true;
// Migrate config from old location if current doesn't exist
if (!fs.existsSync(this.filePath) && app && app.isPackaged) {
@@ -468,7 +472,8 @@ class ConfigStore {
this._cacheKey = statKey;
}
return this._clone(result);
} catch {
} catch (error) {
if (error instanceof secretStore.SecretStoreError) throw error;
const fresh = JSON.parse(JSON.stringify(DEFAULTS));
fresh.globalSettings.logMode = normalizeLogMode(fresh.globalSettings);
return fresh;
@@ -482,7 +487,9 @@ class ConfigStore {
// on every write was a primary long-running main-thread stall.
_serializeForDisk(config) {
const hosters = this._clone(config.hosters || {});
secretStore.encryptCredentials({ hosters });
secretStore.encryptCredentials({ hosters }, {
allowPlaintext: this._allowPlaintextCredentialStorage || config.globalSettings?.allowPlaintextCredentialStorage === true
});
return JSON.stringify({ ...config, hosters }, null, 2);
}