Replaced pre-compiled kepubify binaries (built with Go 1.17.8, 53
HIGH/CRITICAL CVEs) with binaries rebuilt from source using Go 1.26.3
and golang.org/x/text upgraded to v0.3.8, resolving all fixable CVEs.
Also fixed KepubifyBinaryService incorrectly falling back to downloading
the binary on every startup in read-only containers. chmod() was throwing
EROFS, and the single catch block treated it as a missing file. Split
stat and chmod into separate try/catch so only a missing-file error
triggers the download fallback.
Show a clear too-many-attempts message on the login page when the server
throttles the request. Remove the nova and golden-ratio background options,
whose CSS definitions were already deleted.
In book_per_file mode the scanner identifies books by the file's absolute
path (not its parent directory). The finalize service was always using
dirname(destPath) regardless of organization mode, so the scanner would
see the freshly-moved file as unknown, create a second book record, and
then steal the book_file from the first record via the onConflictDoUpdate
upsert - leaving the original book as a ghost with a stale primary_file_id.
Fix: check library.organizationMode after fetching the library and pass
destPath directly as bookFolderPath when the mode is book_per_file.
Add a dedicated test case that asserts createBookRecord receives the file
path (not its parent dir) in book_per_file mode.
When APP_DATA_PATH is set to a relative path (e.g. ../local/data), the
stored absolutePath in book_dock_files was relative. The file watcher
(@parcel/watcher) always reports events with fully resolved absolute
paths, so findByAbsolutePath never matched an uploaded file, causing the
watcher to ingest it again as a duplicate record.
- Replace music-metadata and mediainfo with @ffprobe-installer for all audio metadata extraction; remove mediainfo dependency
- Show BookCoverPlaceholder in all missing-cover locations: Similar/Series/Author Books carousel, cover editor panel, metadata search result cards, and metadata diff panel
- Extend BookRecommendation and SeriesBookRecommendation shared types with hasCover and authors; update recommendation and book repositories to supply them via parallel queries
- Fix cover refresh not updating in grid: BookCoverCard now merges refreshed BookDetail into the local BookCard and emits update:book; VirtualBookGrid forwards the event; Home, Series, Author, and Collection views wire the handler so covers update without a page reload
- Add audiobook covers checkbox to the Online Search drawer so users can toggle between square and portrait cover searches; result thumbnails and loading skeletons adapt their aspect ratio to match the selection
Replace the live self-join scan (O(N^2), times out at 100K+ authors) with a
background-computed candidates table served instantly at read time.
Key changes:
- Add entity_duplicate_candidates and entity_duplicate_scan_status tables
- Background job batches 1K authors at a time (~58s total for 200K authors)
- Scan endpoint reads from the indexed table (<10ms regardless of scale)
- Candidates are invalidated after merge/delete, not recomputed from scratch
- Add GET /duplicates/status and POST /duplicates/refresh endpoints
- Frontend updates clusters locally after merge/dismiss (no re-scan)
- Status bar shows last computed time and recompute button with progress
- Author browse in entity manager now shows all authors, not just those with books
- overhaul EPUB/CBZ/PDF mobile header, footer, toolbar, sidebar, and settings interactions
- add EPUB search minimum query length enforcement with updated unit tests
- improve PDF rendering stability by drawing from an offscreen render canvas
- add app-shell level horizontal overflow/touch constraints to prevent sideways pan and double-tap zoom issues
- make statistics header controls and configure drawer responsive on mobile
- refactor ViewHeader into reusable desktop/mobile subcomponents (desktop search, display controls, mobile menu, mobile search sheet)
- standardize mobile search/sort/filter behavior across Home, Collection, Smart Scope, Authors, and Series
- fix duplicate search clear icons by suppressing native search cancel controls where custom clear buttons are used
- move Authors and Series into contained scroll regions and tighten mobile paddings/margins for better header alignment
- fix author card count/kebab z-index overlap with sticky headers
- clamp author bio to 2 lines on mobile with show more/less toggle
- simplify Series filters by removing separate author filter and support searching series by title or author name
- update series repository query logic to include author-name matching in `q` search
- improve mobile sheet sizing for Customize Dashboard and Notifications; add compact personalized dashboard greeting
- remove sidebar trigger tooltip and prevent action-bar icon/button shrink issues
- add local provider icon assets and a shared providerIconPath helper for metadata providers
- switch provider links in book details and quick view to use bundled SVG icons
- proxy external metadata cover URLs through /api/v1/books/cover/proxy for display while keeping same-origin/data/blob URLs untouched
- apply proxied display cover URLs in metadata diff/result UI and Book Dock surfaces
- keep raw provider cover URLs in metadata patches and add composable tests for proxy behavior
- add optional CSP_ALLOW_CLOUDFLARE_INSIGHTS env support and document it in server/root env examples and README
- wire conditional Cloudflare Insights script/connect sources into CSP directives
- remove pino HTTP customProps context injection to avoid duplicated context labels
- reduce file-write log noise by using debug level for write start and auto-skipped completions
- tune entity-manager duplicate scans by setting pg_trgm similarity_threshold per query/transaction to align with minSimilarity and prevent scan blowups
Handle existing upload folder paths without creating duplicate books, tolerate partial RAR 1.5 archive reads, and clean up related production defaults and dashboard type safety.
- Switch EPUB provider identifiers to opf:scheme style (Calibre-compatible)
and teach the OPF parser to read both opf:scheme and legacy urn: formats
- Extract all provider IDs, rating, pageCount, and tags from EPUB on scan
- Validate publication years (1000-2200) across all metadata providers
- Guard SmartScope service against null filter to prevent runtime crash
- Replace window.confirm() in EditCollectionDialog with inline confirm state
- Fix useLiveScanBooks to apply book updates, not just prepend new arrivals
- Add toast feedback and fix route name on SmartScope/Collection delete
- Streamline onboarding tour order (left-to-right, no page jumps)
- Remove author insights and duplicate suggestions panels, composables, DTOs, and all backend support
- Add genre and tag duplicate detection, merge, and dismiss with server-side paginated scan results
- Consolidate per-entity-type tools into a single entity-manager module backed by the Strategy pattern
- Support browse, merge, rename, delete, split, and dismiss across all entity types (author, genre, tag, narrator, publisher, language, series)
- Replace old tools module with unified entity-manager controller, service, and repository; add 85+ unit tests