From a784137df412bf373732b17989be05ba83812c26 Mon Sep 17 00:00:00 2001 From: 0verwrite <31691645+overwrite00@users.noreply.github.com> Date: Wed, 4 Nov 2026 15:52:21 +0100 Subject: [PATCH] docs: bring the README, usage guide and security policy up to date with 0.5.0 --- README.md | 26 +++++++++++++++++--------- SECURITY.md | 6 ++++-- docs/USAGE.md | 4 ++-- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 28bcd8c..df39fc4 100644 --- a/README.md +++ b/README.md @@ -49,17 +49,19 @@ File (image / audio / video / document / anything) │ ▼ ┌─────────────────────────────────────────────┐ -│ 🖼️ Images → EXIF, XMP, IPTC (JPEG edit) │ +│ 🖼️ Images → EXIF, XMP, IPTC, ICC, RAW │ │ 🎵 Audio → ID3, Vorbis, ASF, APEv2, MP4 │ -│ 🎬 Video → MP4/MOV tags, other: read │ +│ 🎬 Video → MP4/MOV atoms, MKV/WebM │ │ 📄 PDF → document info + XMP │ -│ 📊 Office → OOXML core/app/custom, OLE │ +│ 📊 Office → OOXML, OpenDocument, OLE │ +│ 📚 E-books → EPUB package metadata │ │ 📁 Any file → size, timestamps, attributes,│ │ xattr; hachoir fallback │ └─────────────────────────────────────────────┘ │ ▼ - 👁️ View · ✏️ Edit · 🗑️ Delete · ⚖️ Diff · 🔑 Hash + 👁️ View · ✏️ Edit · 🗑️ Delete · 🛡️ Share safely + ⚖️ Diff · 🔑 Hash · 🗂️ Batch ``` --- @@ -71,10 +73,14 @@ File (image / audio / video / document / anything) - ✏️ **Typed editing** — read, edit, add and delete individual fields with inputs matching their type (text, numbers, booleans, dates with UTC offset, exact rationals, lists); the sidecar validates every value and decides what is editable - 🔒 **Verified atomic writes** — changes go to a private copy beside the file, are read back and checked, then replace the original (`ReplaceFileW` on Windows, `os.replace` elsewhere); a failure leaves the file untouched - ↩️ **Exact Undo** — up to 50 saves per session, restored byte for byte in the usual case (pictures and other binaries included; very large changes fall back to restoring the values); refused if the file changed meanwhile +- 🛡️ **Prepare files for sharing** — the *Share* tab removes location, identity, device, dates, software, thumbnails and edit history in one undoable step; each field shows a privacy badge +- 🗂️ **Batch operations** — on many files: prepare for sharing, shift dates, copy metadata, add a position (fixed or from a GPX track), rename from metadata, export a folder to CSV/JSON +- 🔎 **Files recognized by content** — a file without (or with a wrong) extension is handled as its real format - 🔑 **File integrity hashes** — on-demand MD5 / SHA-1 / SHA-256 / SHA-512 / BLAKE2b with one-click copy - 🎨 **Cyber dark theme** — professional dark UI with cyan/blue accents - 📦 **Compiled binaries** — no Python or Node.js required to run - 💾 **Offline-first** — zero telemetry; the only network call is the optional update check +- 🚪 **Clean exit** — the *Exit* button stops the background process and everything it started, and releases its memory and port - 🔔 **Update check** — manual from *About* / *Help*, or opt-in at startup; downloads are SHA-256 verified - 🆓 **Free & open-source** — MIT license @@ -82,9 +88,7 @@ File (image / audio / video / document / anything) ## 🔧 Version -**v0.3.5** (latest stable) — Security and reliability release: every sidecar API call is authenticated with a per-session token, the Electron renderer is sandboxed with a Content Security Policy, PDF/Office edits preserve unrelated content, audio/video edits are atomic, and Undo restores original values. Dependencies updated (Pillow, pypdf, Vite, Electron). No API changes. - -**Next: 0.4.0** (in development, not yet released) — update check and repository link in *About*; XMP and IPTC reading and writing for JPEG; typed values (lists, numbers, dates, exact rationals) instead of joined strings; adding fields; exact server-side Undo; uniform API errors; Linux packages built on a RHEL 9 baseline (Ubuntu 22.04+, Debian 12+, Fedora, RHEL 9/10). +The badges at the top of this page always show the latest stable and beta releases. 📖 **See full version history** → [CHANGELOG.md](./CHANGELOG.md) @@ -180,14 +184,18 @@ Python Sidecar (FastAPI) ├── /read — full metadata extraction (format + filesystem layer) ├── /write — verified atomic write (and optional deletes) in one save ├── /delete — field removal + ├── /sanitize, /sanitize-many — prepare one or many files for sharing + ├── /shift-dates, /copy-tags, /geotag, /rename, /export — operations on several files ├── /undo — exact undo of a save by its token ├── /diff — metadata comparison + ├── /aliases — common names used by the search box └── /hash — on-demand file hashing React Frontend (Vite + TailwindCSS) ├── FolderPanel — folder tree navigation ├── FilePanel — file list with metadata summary - └── DetailPanel — Metadata / Edit / Diff tabs + ├── DetailPanel — Metadata / Edit / Share / Diff tabs + └── BatchDialog — operations on several files ``` 📖 Full endpoint reference → [API.md](docs/API.md) @@ -258,5 +266,5 @@ Distributed with MIT License · [View License](LICENSE) --- -*Last updated: 2026-11-03* +*Last updated: 2026-11-04* *← [Requirements](docs/REQUIREMENTS.md) | [Docs →](docs/)* diff --git a/SECURITY.md b/SECURITY.md index c2a2f02..4eb065a 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -11,6 +11,8 @@ MetaLens is designed with security-first principles: - **Atomic, verified writes** — every save (edits and deletions together) is prepared on a copy in a private temporary directory beside the target, read back and checked against the request, and checked for concurrent modification before the copy replaces the original (`ReplaceFileW` on Windows, preserving the security descriptor, alternate data streams and file attributes such as *hidden*; `os.replace` elsewhere). Any failure leaves the original content intact. The replacement is a new file, so hard links to the original are detached. A read-only file is refused (HTTP 403), not modified - **Path validation** — a dedicated `core.path_security` module normalizes every path (resolves `~`, `..` and symbolic links) and checks that it is an existing, readable regular file or directory before any filesystem access, across all API routes. This is normalization, not a sandbox: an authenticated caller may name any file the user account can access, which is why every request must carry the session token - **Hardened update check** — requests are made by the Electron main process, never by the renderer (whose CSP still only allows the local sidecar). It queries the GitHub Releases API of `overwrite00/MetaLens` only, and the renderer cannot supply URLs. Release and asset URLs must point to that repository, and the installer is downloaded only when you click *Download & install* (Windows installed builds), checked against its size and the SHA-256 digest published by GitHub, and discarded on any mismatch. Release notes are shown as plain text +- **No internal details in errors** — API error bodies carry fixed, structured messages only; the text of internal exceptions stays in the local log +- **Clean shutdown** — the *Exit* button (and closing the app) stops the sidecar's whole process tree, cancels any update download and releases the port and memory - **Transparent code** — all handler and analysis logic is open-source and auditable --- @@ -39,7 +41,7 @@ MetaLens is designed with security-first principles: ### Metadata Handlers - Uses established libraries per format: Pillow (image properties), piexif tag tables plus MetaLens's own structure-preserving EXIF/XMP/IPTC codecs and JPEG segment writer (images), mutagen (audio/MP4), pypdf (PDF), Python's `zipfile`/`xml.etree` (Office Open XML packages), olefile (legacy Office), hachoir (read-only fallback for other formats). XMP packets (JPEG, PDF) containing DOCTYPE or entity declarations are refused -- Field capabilities are enforced by the API; client-provided editability flags cannot override them. Writable: JPEG EXIF/XMP/IPTC, audio tags (except AAC), MP4/MOV atoms, PDF document info, Office core properties, `fs:mtime` and Linux `user.` extended attributes. Read-only: other image formats and RAW, AAC, MKV/AVI and other non-MP4 video, encrypted or digitally signed PDFs, digitally signed Office packages (so a signature is never silently invalidated), Office `app.xml`/`custom.xml`, legacy Office, everything read through hachoir +- Field capabilities are enforced by the API; client-provided editability flags cannot override them. Writable: EXIF/XMP/IPTC of JPEG, PNG, WebP, TIFF, TIFF-based RAW and HEIC/AVIF (what a format cannot hold is refused), audio tags (except AAC), MP4/MOV and MKV/WebM metadata, PDF document info and XMP, Office and OpenDocument/EPUB properties, `fs:mtime` and Linux `user.` extended attributes; legacy Office (DOC/XLS/PPT) allows removing properties only. Read-only: GIF/BMP, Canon CR3 and Fujifilm RAF, AAC, AVI and other video read through hachoir, encrypted or digitally signed PDFs, digitally signed Office packages (so a signature is never silently invalidated), everything read through hachoir. Every write is checked so that the picture, audio or video data comes out identical - Every value is validated before the file is touched; library errors caused by a value are reported as validation errors (HTTP 422), never as crashes - Filesystem access always goes through `validate_file_path`/`validate_directory_path` before touching disk @@ -108,5 +110,5 @@ We appreciate responsible disclosure and will credit you in the security advisor --- -*Last updated: 2026-11-02* +*Last updated: 2026-11-04* *← [Contributing](./CONTRIBUTING.md) | [Back to README →](./README.md)* diff --git a/docs/USAGE.md b/docs/USAGE.md index 9a73dd7..2c0f5be 100644 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -51,7 +51,7 @@ The **detail panel** (`DetailPanel`) opens on the **Metadata** tab by default, s - Multi-valued fields (artists, keywords, …) are shown as lists, never joined into one string. - A line above the table tells what sharing the file would reveal (location, identity, device, dates...), and each sensitive field carries a badge with its category. - Binary values (cover art, pictures, MakerNote, thumbnails) are shown as size, MIME type and SHA-256, not as their bytes. -- Notices above the table explain why the format metadata is read-only (e.g. signed PDF, AAC, legacy Office), report read errors and show warnings (e.g. an EXIF MakerNote that is moved on rewrite, duplicated metadata segments). +- Notices above the table explain why the format metadata is read-only (e.g. signed PDF, AAC, CR3/RAF), report read errors and show warnings (e.g. an EXIF MakerNote that is moved on rewrite, duplicated metadata segments). --- @@ -62,7 +62,7 @@ Switch to the **Edit** tab to open `MetadataEditor`: - Editable fields show an input matching their type: text, multi-line text, number, checkbox (booleans), dropdown (enumerated values), exact `n/d` rationals, a list editor for multi-valued fields, fixed-size inputs for pairs such as track `[number, total]`, and date-time with a separate UTC offset (EXIF dates are local times without offset) - **Add field** offers the fields the format can store but the file does not have yet (e.g. an ID3 title on an untagged WAV, an XMP keyword list on a JPEG) - **Save** sends all edits, additions and deletions as **one** save. The sidecar validates every value first (invalid values are reported next to their field and nothing is written), applies the changes to a private copy next to the file, reads the copy back to check that exactly the requested changes were stored, and only then replaces the original (`ReplaceFileW` on Windows, keeping the security descriptor, alternate data streams and attributes such as *hidden*; `os.replace` elsewhere). A failure at any step leaves the original untouched. The file is replaced by a new one, so hard links to it are detached -- When the format metadata is read-only (e.g. RAW, TIFF/PNG/WebP/GIF, AAC, MKV/AVI, legacy `.doc`/`.xls`/`.ppt`, encrypted or digitally signed PDFs, signed Office packages), the Edit tab shows a **read-only** notice with the reason; filesystem fields such as the modification time (`fs:mtime`) stay editable +- When the format metadata is read-only (e.g. GIF/BMP, Canon CR3 and Fujifilm RAF raw files, AAC, AVI and other video read through the fallback, encrypted or digitally signed PDFs, signed Office packages; legacy `.doc`/`.xls`/`.ppt` allow removing properties but not editing them), the Edit tab shows a **read-only** notice with the reason; filesystem fields such as the modification time (`fs:mtime`) stay editable ---