Commit Graph

24 Commits

Author SHA1 Message Date
Administrator
f42c55c521 feat(diagnostics): log levels, support bundle export, verbose toggle, log paths panel 2026-06-07 16:34:51 +02:00
Administrator
d720ba295a feat(log): add per-session log mode (one file per app launch)
Adds a third choice next to the existing single-file and per-day modes: a new
log file is created at every app start (process boot) and used until the app is
closed. A close → reopen of the app starts a new session, hence a new file.
File pattern: fileuploader-session-YYYY-MM-DD_HH-MM-SS-<pid>.log.

The boolean sessionLog field — misnamed: it actually toggled daily mode — is
replaced by a logMode enum: "single" | "daily" | "session". The misnomer made
the migration the trap to watch: existing users with sessionLog:true must land
on "daily", NOT "session". normalizeLogMode handles this and is unit-tested.

- lib/log-mode.js (new, pure, dual CJS/window export): normalizeLogMode +
  resolveLogFileName + format helpers. No fs, no Date.now() at call time.
- config-store.js: normalize at the single load() boundary so downstream
  readers consume logMode only. logMode is deliberately NOT seeded in DEFAULTS
  (would beat the legacy migration after merge).
- main.js: stamp SESSION_ID once at process start (with pid hedge against
  same-second restart collisions); getLogFilePath and buildFallbackLogName
  switch on mode via the lib. _resolveUploadLogTarget cache key is now just
  the primary path, which already encodes mode/date/session — self-invalidates.
- renderer: <select> with three German labels replaces the old checkbox;
  saveSettings writes logMode; index.html loads the lib so window.LogMode is
  available in renderSettings.
- Tests: 14 log-mode tests (incl. legacy-migration regression), 3 config-store
  tests (defaults, legacy migration, round-trip all three values). 200/200.

End-to-end simulated locally: two launches → two distinct session files; PID
hedge produces distinct names even within the same second.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 14:41:06 +02:00
Administrator
57f8f0876e feat(log): per-hoster toggle for writing links to fileuploader.log
New per-hoster setting "Links in Log schreiben" (logToFile, default
on). When unchecked for a hoster, that hoster's successful upload
links are no longer written to fileuploader.log — other hosters keep
logging independently.

- lib/config-store.js: logToFile: true added to HOSTER_SETTINGS_DEFAULTS;
  merge-on-load gives every hoster the key (old configs included).
- renderer/app.js: checkbox per hoster panel + collection loop now
  handles type=checkbox (boolean) alongside the numeric fields. The
  autosave bind already special-cased checkboxes (change event).
- lib/log-policy.js (new): hosterLogToFileEnabled() — pure, opt-out
  semantics. Only an explicit logToFile===false disables; missing/
  malformed/non-true values all default ON so links are never
  silently dropped.
- main.js: shouldLogHosterToFile() reads the LIVE uploadManager
  .hosterSettings (so a mid-batch toggle takes effect at once), falls
  back to persisted config, then to enabled. Guards appendUploadLog
  in the done handler; skipped writes get a debugLog line.

Tests: 8 log-policy (defaults, opt-out, per-hoster independence,
malformed input) + 2 config-store (default true, persisted false
survives reload). 147/147 green, eslint clean.
2026-05-23 15:29:25 +02:00
Administrator
a6958f1418 fix(persist): stop swallowing save errors + decouple .bak refresh from save
Two related fixes from the deep-audit pass:

HIGH-2: save-global-settings-sync used `try {} catch {}` and always
returned `event.returnValue = true`, so a disk-full / AV-lock /
permissions failure looked like success to the renderer's beforeunload
chain. The user closes the app, comes back, settings are gone —
without any indication. Now the catch sets returnValue=false and
debugLogs the error message, and the bak refresh is in its own
nested try so a transient lock there doesn't fail the whole save.

MED-4: lib/config-store.js _atomicWrite had the same TOCTOU on the
.bak refresh — fs.existsSync(...) then fs.readFileSync(...) without
guarding the read. Wrapped the read+write of the backup in its own
try/catch: a stale .bak is preferable to dropping the new write
entirely just because Windows Defender briefly locked the file mid-
operation. The rename of tmp → live still throws on real failure,
which is what the outer reject is for.

119/119 tests still green; both fixes are defensive guards on
already-tested write paths.
2026-04-28 09:40:08 +02:00
Administrator
60ceea41d7 fix: encrypt hoster credentials at rest; history CSV Link column urls-only
Two issues:
1. Verlauf-Export CSV put the opaque file_code in the Link column when
   the upload had no real URL, so the column looked like just a bunch
   of IDs. Now only real http(s) URLs land in that column.
2. Hoster passwords and API keys were stored as plaintext in
   electron-config.json. Now wrapped with Electron's safeStorage (DPAPI
   on Windows, Keychain on macOS, libsecret on Linux) and stored as
   'enc:v1:<base64>'.

Credentials are decrypted on load so in-memory flows stay unchanged,
and backups still export plaintext inside the existing .mhu envelope
so they remain portable between machines/users. Legacy plaintext
configs auto-migrate on next write.
2026-04-19 11:53:59 +02:00
Administrator
1164da37ea feat: add Clouddrop.cc as upload hoster (API key auth, chunked uploads)
- New lib/clouddrop-upload.js with chunked upload support (16 MB chunks)
- Auth via Bearer token (cd_XXX format)
- Files < 16 MB: simple multipart POST /api/cloud/upload
- Files > 16 MB: chunked protocol (init → PUT chunks → complete)
- After upload: auto-creates permanent share link via /api/cloud/share-link
- Health check verifies API key by listing root files

Registered in:
- lib/config-store.js (HOSTER_NAMES, templates, DEFAULTS)
- main.js (hosterAccountHasCreds, checkClouddropHealth, runHosterHealthCheck)
- lib/upload-manager.js (_executeUpload dispatch)
- renderer/app.js (HOSTERS, HOSTER_ADD_OPTIONS, getHosterLabel)

Tests: 74/74 pass. ESLint: 0/0.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 06:55:21 +02:00
Administrator
c197a004c8 Add full upload history export and keep complete history 2026-03-28 19:48:28 +01:00
Administrator
7ba2c63d51 🐛 fix: config race conditions, quit safety, update data loss
- Config write serialization via _writeQueue prevents concurrent
  read-modify-write races between settings/queue/history saves
- Cancel active uploads on app quit (prevents zombie processes)
- Persist queue before update install (prevents queue loss)
- Sync IPC save in beforeunload (guarantees save before close)
- Fix double configStore.load() call
- Guard against status regression in handleProgress (done→uploading)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 10:20:07 +01:00
Administrator
c2932a1577 feat(remote): add remote control defaults to config store
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 06:54:46 +01:00
Administrator
d53eea443e feat: multi-account support with primary/fallback and separate API/login types
- Multiple accounts per hoster with drag-sortable priority (primary + fallbacks)
- Separate account types: Web Login and API selectable per hoster
- Account fallback: after all retries fail, automatically switches to next fallback account
- Fix: Byse health check returning [Fehler] OK when API responds with msg "OK"
- Fix: retry during active upload sets status to "Wartet" instead of "Bereit"
- Config migration from single-object to multi-account array format

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 05:00:33 +01:00
Administrator
0851bb09fc feat: floating drop target window and English column labels
- Small always-on-top drop target window (toggle in Settings > Allgemein)
- Files dropped on it get added to the queue with hoster modal
- Auto-shows on app start if previously enabled
- Column headers now in English (Filename, Uploaded/Size, Progress)
- Statusbar labels in English (Connections, Total)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 04:11:01 +01:00
Administrator
22a378d36c feat: hoster preset in folder monitor + badge color fix
- Hoster pre-selection in Ordnerüberwachung settings (only configured accounts shown)
- With preset hosters: files go directly to queue without modal
- Without preset: hoster modal opens as before
- Fix: Aktiv badge now green on initial render

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 01:57:22 +01:00
Administrator
b5841c69f5 feat: add folder monitoring (Ordnerüberwachung) and fix statusbar display
- New FolderMonitor class with chokidar for watching folders
- Settings UI panel with all options (extensions filter, recursive, auto-start, skip duplicates)
- Auto-queue and auto-upload when files appear in monitored folder
- Fix statusbar to show uploaded/remaining instead of cumulative session bytes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 01:21:42 +01:00
Administrator
35334e365f feat: per-session log files
New "Neues Log pro Session" checkbox in settings. When enabled,
each app session creates a separate log file with timestamp
(e.g. fileuploader-2026-03-11_20-30-15.log). File is only created
when an upload actually completes. When disabled, behaves as before
(single appending log file).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 21:45:08 +01:00
Administrator
153ea2b193 fix: atomic config writes to prevent data loss on update/crash
- All config writes now go through _atomicWrite() (write to .tmp, backup
  to .bak, rename .tmp to main config)
- load() falls back to .bak if main config is empty or corrupt
- Prevents 0KB config files caused by process termination during write

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 04:06:41 +01:00
Administrator
f00dc36a41 fix: migrate config from old paths on first launch
Checks alternate AppData folder names and portable exe directory
to find existing config when current path has no config file.
Prevents losing accounts, settings, and queue after updates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 04:00:25 +01:00
Administrator
3d858b1ffd feat: global speed limit, settings cleanup, abort reset, resize panel
- Global speed throttle (shared across all uploads)
- Settings grouped into sections (Uploads, Verhalten, Log)
- Abort all resets jobs to queued (restartable without reupload)
- fileuploader.log writes immediately per upload
- Staggered interval per hoster (not parallel sleep)
- Recent files panel resizable via drag handle
- History hides aborted entries
- Done jobs removed from queue immediately when setting active

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 03:08:56 +01:00
Administrator
f59539e85b feat: improve account-driven uploads 2026-03-11 02:41:32 +01:00
Administrator
d94156943b feat: doodstream login support, auto-remove from queue, byse URL fix
- Add doodstream.com web login (email+password) as alternative to API key
- Fix doodstream login: use X-Requested-With header for JSON response
- Add "Aus der Queue entfernen bei Abschluss" setting
- Fix byse.sx download URLs to use /d/ prefix
- Make config writes async to prevent race conditions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 01:23:27 +01:00
Administrator
7d992206e8 feat: byse.sx health check + performance optimizations for large queues
- Add byse.sx health check via API upload/server endpoint
- Virtual scrolling for queue table (>200 rows renders only visible rows)
- O(1) job lookups via index Maps instead of O(n) array.find()
- Event delegation on queue tbody instead of per-row listeners
- Async config writes to avoid blocking main process
- Increase persist debounce to 3s during uploads (was 250ms)
- Reduce debug logging to state changes only
- Move save button to bottom-right in settings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 00:45:09 +01:00
Administrator
b4f4370041 feat: improve uploader UI and persist queue 2026-03-10 22:19:42 +01:00
Administrator
49655dc154 Fix critical upload stuck-at-queued bug and settings display
Root cause: startBatch() ran synchronously inside ipcMain.handle()
callback, causing webContents.send() events to conflict with the
handle response and never reach the renderer.

Fix: defer startBatch() via process.nextTick so IPC response is
sent first, then upload events flow correctly.

Also:
- Add .catch() on startBatch to surface hidden errors
- Fix settings panel not updating after save (renderSettings)
- Add select-folder IPC handler (was in preload but missing)
- Add debug-log and debug-test-upload IPC for diagnostics
- Add upload-debug.log file for tracing upload flow
- Add unhandledRejection handler for main process
- Add scramble defaults to config-store globalSettings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 21:19:54 +01:00
Administrator
25b2afbf11 feat: add queue system, per-hoster settings, retry logic, and full UI overhaul
- Add FIFO semaphore for per-hoster concurrency control
- Add token-bucket speed limiter with abort signal support
- Rewrite upload-manager with retry loop, speed monitoring, and rich progress events
- Add per-hoster settings: retries, max speed, parallel count, restart below speed, time interval, max size
- Add context menu with shutdown-after-finish (sleep/shutdown/restart), always-on-top
- Add z-o-o-m-style queue table with 8 columns, status-colored rows, progress bars
- Add debounced queue rendering with scroll position preservation
- Add statusbar with global speed, total bytes, elapsed time
- Fix speedMonitor interval leak on error and scoping bug
- Fix throttle not respecting abort signal during cancellation
- Fix combined signal listener cleanup
- Bump version to 1.1.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 05:57:00 +01:00
Administrator
9729ec6f3e chore: initial commit - Electron multi-hoster uploader 2026-03-10 02:32:06 +01:00