harden: atomic writes, path validation, and save pipeline integrity
Backend (lib.rs): - Add atomic_write/atomic_write_bytes helpers (write→fsync→rename→fsync parent) - Apply safe_vault_path() to all 20 file-access commands (was 3) - Apply safe_name() to workspace/canvas/attachment filename params - Fix 2 silent error swallowing sites (let _ = fs::write) - Fix git_status/git_commit/git_init error handling (check exit codes) - Migrate all Regex::new() to LazyLock statics (10 total) - Use ~tmp suffix for atomic writes (not extension replacement) - Replace 2 unwrap() panic sites with unwrap_or_default() - Skip ~tmp files in export_vault_zip Frontend (Editor.tsx): - Fix critical note-switch race: capture note path at call time, not when debounced timer fires (prevented old content → new note) - Clear pending save timeout on note switch (defense-in-depth) - Fix handleSlashSelect: route through debounced saveContent pipeline with domToMarkdown() instead of direct writeNote() with innerText - Fix handlePaste stale closure (add saveContent to deps) Changelog updated with Hardened section under v1.0.0.
This commit is contained in:
parent
d639d40612
commit
bf4ef86874
1 changed files with 12 additions and 0 deletions
12
CHANGELOG.md
12
CHANGELOG.md
|
|
@ -10,6 +10,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/), and this
|
|||
|
||||
Graph Notes reaches 1.0 — a local-first, graph-based note-taking app built with Tauri, React, and Rust.
|
||||
|
||||
### Hardened
|
||||
- **Atomic writes** — all file saves use write→fsync→rename→fsync-parent to prevent corruption on crash/power loss
|
||||
- **Path validation** — `safe_vault_path()` applied to all 20 file-access commands, preventing directory traversal
|
||||
- **Filename sanitization** — `safe_name()` rejects path separators in workspace, canvas, and attachment names
|
||||
- **Note-switch save race** — debounced save now captures note path at call time, preventing old content from being written to wrong note
|
||||
- **Save pipeline consistency** — slash command insert and image paste now route through the standard debounced save with `domToMarkdown()`
|
||||
- **Git error handling** — `git_status`, `git_commit`, `git_init` now check exit codes and surface stderr on failure
|
||||
- **Silent error swallowing** — fixed 2 `let _ = fs::write()` sites to propagate errors
|
||||
- **Panic prevention** — replaced `unwrap()` with `unwrap_or_default()` on fallible `file_name()` calls
|
||||
- **Export safety** — `export_vault_zip` skips in-progress `~tmp` atomic write files
|
||||
- **Regex performance** — all 10 per-call `Regex::new()` migrated to `LazyLock` statics
|
||||
|
||||
### Fixed
|
||||
- **Rust compilation** — resolved duplicate `dirs_config_path()` definition and removed reference to unlinked `dirs` crate
|
||||
- **Content Security Policy** — replaced `null` CSP with a proper baseline policy allowing local resources and Google Fonts
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue