github tis24dev/proxsave v0.17.0

11 hours ago

ProxSave v0.17.0

🧭 Unified installer semantics, context-aware TUI flows, and safer atomic restore/write paths

This release is a broad quality and safety upgrade across ProxSave’s interactive workflows (CLI + TUI). It aligns installer and new-install behavior across entrypoints, makes TUI execution fully context-aware (cancellation and timeouts work end-to-end), hardens several file operations with atomic writes/extraction, and improves correctness in storage usage reporting and notification defaults. It also substantially expands test coverage (including true end-to-end decrypt TUI coverage) and reduces flakiness across CI.

  • Installer parity (CLI + TUI): one set of rules, everywhere

    • Existing backup.env handling aligned with four explicit actions: Overwrite, Edit existing, Keep existing & continue, and Cancel (same semantics in CLI and TUI).
    • “Keep existing” now consistently means continue, not abort, and runner errors are propagated instead of swallowed.
    • Post-config steps are skipped consistently when the config wizard is skipped (AGE setup, post-install audit, Telegram pairing), while finalization steps still run.
    • --new-install confirmation flow aligned via a shared reset plan and a single source of truth for preserved entries (build/env/identity). CLI confirmation is CLI-only; TUI confirmation is a pure adapter.
    • Secondary storage disable semantics aligned: disabling secondary now always writes the canonical cleared state:
      • SECONDARY_ENABLED=false, SECONDARY_PATH=, SECONDARY_LOG_PATH=
      • Prevents stale secondary paths surviving TUI edits.
    • Secondary path validation centralized across config load, CLI install, and TUI:
      • Enforces absolute local-path rules, rejects remote/UNC-style paths,
      • Keeps SECONDARY_LOG_PATH optional,
      • CLI installer retries invalid input instead of aborting.
    • Cron scheduling aligned across CLI and TUI: shared parsing/normalization and consistent precedence rules so wizard-selected/default cron values are honored reliably in both modes.
    • AGE setup consistency fixes: shared private-key validation to prevent silent retry loops; clearer “saved vs reused” messaging and explicit outcome reporting.
    • Telegram setup aligned across CLI and TUI: shared bootstrap eligibility rules, consistent skip behavior and centralized skip-reason logging (no more TUI-only fallback logic).
  • Decrypt workflow consistency + true end-to-end TUI coverage

    • Secret prompt semantics aligned: "0" is now an explicit abort in both CLI and TUI, with clear messaging and ErrDecryptAborted mapping.
    • Destination prompts hardened: reject unchanged destination paths (including normalized-equivalent paths) and require a real change before continuing.
    • Passphrases are preserved exactly: decrypt prompts no longer trim user input; leading/trailing spaces are preserved (trimming is used only for validation and the "0" token check).
    • End-to-end decrypt TUI smoke tests now cover the real production path from entrypoint through bundle creation, including:
      • success path validation (bundle contents, metadata, checksum),
      • clean abort at the secret prompt,
      • flake reduction and stabilization under coverage/CI load.
  • Context-aware TUI across the board (cancellation and timeouts now “just work”)

    • Introduced App.RunWithContext(ctx) and migrated wizard runners and orchestrator prompts to honor context cancellation/timeouts.
    • Propagated context through:
      • install and new-install TUI,
      • Telegram setup and post-install audit wizards,
      • decrypt and restore prompts (including network commit flows),
      • AGE setup flows and confirmation dialogs (no more context.Background() in modals).
    • Added context-aware identity and filesystem operations (DetectWithContext, immutable attribute ops, identity writes, base-dir resets) using exec.CommandContext and ctx.Err() checks.
    • Improved cancellation correctness in notification paths (email/relay/webhook) and made retry backoffs context-aware.
  • Safety and correctness hardening (atomic operations + better error handling)

    • Atomic restore extraction for regular files: extract to a sibling temp file and rename into place only after successful copy + close, preventing partial/clobbered targets on failure.
    • Restore temp files now created with CreateTemp in the target directory to avoid ENAMETOOLONG collisions while preserving atomic rename semantics.
    • Restored directories are opened before applying final restrictive modes, preventing non-root flows from being blocked by early permission tightening.
    • Backup bundle creation is now atomic: write to a temp file, sync, rename into place, sync directory, and clean up reliably on error.
    • Bundle/restore close handling hardened: avoided duplicate Close() calls while preserving explicit close error reporting.
    • AGE recipient overwrite flow made safe and atomic:
      • backups are created via copy-to-.bak-* at commit time,
      • new recipients written atomically,
      • backup/write failures propagate (abort leaves existing recipients intact),
      • backup filenames are collision-resistant (nanosecond precision).
  • Security and integrity improvements

    • Executable integrity checks hardened:
      • reject symlinked executables via Lstat,
      • close TOCTOU swap gaps by verifying os.SameFile() between Lstat and the opened file,
      • apply permission fixes via file descriptor (fd-based chmod/chown) only after SameFile validation.
    • TUI output safety: escaped user/runtime-provided strings with tview.Escape across screens, prompts, and headers to prevent markup interpretation.
    • Telegram CLI output sanitized: strips terminal escape/control characters from registration status text before printing.
    • Added a cap on Telegram CLI verification retries to prevent infinite loops.
  • Storage reporting and retention correctness

    • Fixed UsedSpace calculation (use Blocks - Bfree, not Total - Bavail) so reserved blocks aren’t misreported as “used”.
    • Propagated UsedSpace consistently through orchestrator and notifications (no recomputation from free/total).
    • Cloud retry backoff bounded (2s, 4s, 8s, 16s, capped at 30s) and made context-aware to honor cancellation during backoff.
    • Normalized GFS retention so RETENTION_DAILY <= 0 consistently yields an effective daily minimum of 1 across all paths (prevents misclassification/deletion).
    • Normalized bundle path handling to avoid double-suffix artifacts like *.bundle.tar.bundle.tar, and prevented duplicate cloud uploads when a bundle exists.
  • Notification config defaults + legacy compatibility

    • Aligned notification defaults with templates/docs: EMAIL_ENABLED now defaults to false when unset.
    • Restored runtime and migration compatibility with legacy *_ENABLE env flags (including env override precedence) and added missing Gotify overrides.
  • Robustness, UX, and test reliability

    • Fixed nil-bootstrap logger panics in install/newkey/new-install flows (nil-safe bootstrap behavior with stdout fallback).
    • Improved rollback countdown internals without behavioral change, and synchronized TUI teardown paths to avoid goroutine leaks.
    • Hardened FakeFS sandbox mapping to prevent ../ traversal escaping the test root.
    • Migrated env-based tests to t.Setenv for safer cleanup and reduced flakiness.
    • Expanded and stabilized TUI simulation tooling (startup synchronization, cancellation timing, builder propagation, screen shell unification, primitive text detection).
  • Dependencies

    • Bumped golang.org/x/crypto to 0.49.0.

Behavior changes to note:

  • Secondary storage validation now applies only when SECONDARY_ENABLED=true, and disabling secondary always clears saved secondary paths.
  • Decrypt secret entry treats "0" as an explicit abort consistently in CLI and TUI.
  • EMAIL_ENABLED defaults to false when unset; legacy *_ENABLE aliases remain supported and now override canonical settings consistently.

Overall: a more predictable installer (one shared decision model), fully context-aware TUI workflows, safer atomic restore/write behavior, and stronger correctness/security guarantees—backed by substantially expanded and stabilized test coverage.

Changelog

Don't miss a new proxsave release

NewReleases is sending notifications on new releases.