Skip to content

v2.2.0 "Unopened"

Choose a tag to compare

@bndct-devops bndct-devops released this 09 Aug 18:36
· 16 commits to main since this release
30ec0f9

v2.2.0 "Unopened"

Old books were sold with their pages folded shut and uncut - you sliced each
one open as you read it, so an unopened copy meant something specific: a book
you own but haven't yet begun. That is this release: Tome finally has a real
place for those books, sitting between the wishlist and the first page turn.

Highlights

A place for the books you're about to read. Until now a book was either
unread, being read, or done - "unread" lumping together the book you're
starting tomorrow with the one you forgot you owned. The new Want to Read
status is the missing state: owned, not started, queued next. Set it from the
book page, filter by it on the dashboard, and forget about it - the moment
real progress arrives from KOReader or the web reader, the book promotes
itself to Reading. Series "continue" suggestions prefer a queued volume over
a plain unread one, and the Library Completion tile counts your queue. Best
of all, the wishlist now feeds it: when an admin fulfils your wish - or a new
volume of a series you follow arrives - the book lands on your Want to Read
automatically. The intent that created the wish carries over instead of
evaporating the moment the file shows up.

Hardcover Want to Read syncs both ways. Ratings and reading progress
still flow one way, Tome to Hardcover - but the Want to Read shelf is now a
genuine two-way street. Queue a book in Tome and it appears on your Hardcover
shelf; shelve a book on Hardcover and it turns up queued in Tome. Shelve a
book Tome doesn't even have, and it becomes a wish on your Tome wishlist
instead, cover and author included - un-shelve it and the wish is dismissed,
re-shelve it and the same wish reopens. The sync is deliberately cautious: it
never overwrites a book you're actually reading, and nothing is ever deleted
on Hardcover.

Duplicate cleanup in one pass. The admin Duplicates tab used to reset
your selections after every single merge or dismiss. Now you pick the book to
keep and an action per group - Merge, Delete Others, or Dismiss - and hit one
"Apply All". "Delete Others" is new: keep the selected copy, delete the rest
including their files, with missing-from-disk copies badged so dead entries
are easy to spot. Two long-standing merge bugs died along the way: merging
now actually transfers the removed book's files to the kept book (they were
silently deleted before), and dead file references are dropped instead of
carried over. (#165)

Library Health finds books whose files are gone. Files deleted or moved
outside of Tome used to leave ghost entries that errored on open. Library
Health now lists these orphans and offers a one-click "Remove Dead Entries" -
dead file entries are removed, books left with no files at all are deleted,
and entries whose file still exists are never touched. (#165)

A PDF.js security fix that actually matters. This release updates
pdfjs-dist past an arbitrary-JavaScript-execution advisory - and unlike
most dependency advisories, this one is reachable in Tome: the web reader
renders library PDFs in the app's origin, so a crafted PDF could run script
with access to the session. If you host PDFs for multiple users, update.

Also fixed: OPDS feed links behind a TLS-terminating reverse proxy now carry
the correct https scheme (#167), "Select all" on the dashboard selects every
matching book instead of only the ones infinite scroll had loaded (#165),
and toggling "Group series" no longer occasionally duplicates books in the
grid (#165).

KOReader plugin

This release ships plugin build 38 (1.11.1): popup menus - the series
browser, Authors, Shelves, the Inbox and the TomeSync menu itself - could
freeze on their first page when a full-screen home-screen plugin (such as
bookshelf.koplugin) covers the file browser. The menus now repaint through
their own window. (#166)

Upgrade note: the plugin updates gracefully in-app - TomeSync → Settings →
"Check for updates" (or enable auto-check). No breaking changes; existing
installs keep working untouched until you update.

Upgrade

docker pull ghcr.io/bndct-devops/tome:latest && docker compose up -d

No migrations to run and no configuration changes. On first start the server
creates one new database index automatically (used by the Hardcover shelf
sync). If you use Hardcover sync, there is nothing to re-link - existing
connections pick up the Want to Read direction on their next cycle.


Full changelog

Security

  • Updated pdfjs-dist to 6.2.108, clearing an arbitrary-JavaScript-execution
    advisory triggered by opening a malicious PDF (GHSA / CVE for PDF.js). This
    one is real in Tome: the web reader renders library PDFs with PDF.js in the
    app's origin, so a crafted PDF opened in the reader could run script with
    access to the session. Anyone hosting PDFs for multiple users should update.
  • Updated fast-uri (build-time, via vite-plugin-pwa's workbox tooling) to
    3.1.5, clearing a host-confusion advisory. Not reachable in Tome - it only
    parses our own build configuration during vite build.
  • Updated js-yaml to 4.3.1 in the frontend (dev-only, eslint's config
    loader) and the website build, clearing a quadratic-CPU advisory. Neither
    parses untrusted input.
  • Updated postcss to 8.5.26 in the website build, picking up the completed
    fix for the source-map advisory partially addressed in v2.1.1. Build-time
    only, same as before.

Added

  • New "Want to Read" reading status - the missing state between the wishlist
    and actually starting a book: owned, not started, queued next. Set it from
    the book page (next to Shelved), filter by it on the dashboard, and it
    self-promotes to Reading the moment real progress arrives from KOReader or
    the web reader. Series "continue" suggestions prefer a queued volume over a
    plain unread one, and the Library Completion stats tile shows a queued
    count. When an admin fulfils your wish, the arriving book lands on your
    Want to Read automatically - the intent that created the wish carries over
    (never overwriting a book you're already reading). Volumes arriving for a
    followed series do the same.
  • Hardcover sync now covers Want to Read - in both directions. Queueing a
    book in Tome shelves it as "Want to Read" on your Hardcover profile, and
    books you shelve on Hardcover appear as Want to Read in Tome (for books
    Tome has matched to the Hardcover catalogue). Removing a book from the
    Hardcover shelf reverts it in Tome only when both sides had agreed on it;
    a book you're actively reading in Tome is never touched, and ratings and
    progress remain push-only as before. Shelving a book Tome doesn't have at
    all creates a wish on your Tome wishlist instead (with cover and author from
    the Hardcover catalogue), un-shelving it on Hardcover dismisses that wish
    again, and re-shelving it reopens the same wish. Books already in the
    library that merely lack a catalogue match are recognised and skipped
    rather than wished for twice.
  • Library Health now detects orphaned entries - books whose files no longer
    exist on disk (for example after files were deleted or moved outside of
    Tome). A new section lists them and a one-click "Remove Dead Entries" action
    cleans them up: dead file entries are removed and books left with no files
    at all are deleted entirely. Entries whose file still exists are never
    touched. (#165)
  • Duplicates (Admin) gained a "Delete Others" action: keep the selected book
    and delete the other copies in the group, including their files on disk,
    with an inline confirmation step. Files that are missing from disk are now
    badged as such on each duplicate, so dead copies are easy to spot. (#165)
  • New POST /api/books/bulk-delete endpoint deletes several books in one
    request with per-book permission checks and error reporting. The dashboard's
    multi-select delete now uses it instead of issuing one request per book,
    and failures are reported instead of silently skipped. (#165)
  • The Duplicates tab now works in one pass: pick the book to keep and an
    action (Merge, Delete Others, Dismiss) per group, then hit a single "Apply
    All" - instead of the screen refreshing and resetting your selections after
    every individual merge or dismiss. A summary reports what was applied and
    any failures. (#165)

Fixed

  • OPDS feed links now carry the correct public scheme behind a TLS-terminating
    reverse proxy. The feed built its links from the request as the app server
    saw it - plain http - so every navigation, download, and cover link came out
    as http:// even when the catalog was reached over https. OPDS now resolves
    the public origin the same way the KOReader plugin URL and OIDC redirect do:
    TOME_PUBLIC_URL when set, otherwise the X-Forwarded-Proto header. (#167)
  • KOReader plugin (build 38 / 1.11.1): popup menus - the series browser,
    Authors, Shelves, the Inbox and the TomeSync menu itself - could freeze on
    their first page when a full-screen home-screen plugin (such as
    bookshelf.koplugin) covers the file browser: page turns happened internally
    but the screen never repainted, and stale refreshes could leave blank white
    rectangles behind. The menus now repaint through their own window instead of
    the hidden file browser. (#166)
  • "Select all" on the dashboard now selects every book matching the current
    filters, not just the ones the infinite scroll had already loaded - so bulk
    actions on large libraries no longer silently miss the books further down.
    (#165)
  • Toggling "Group series" no longer occasionally shows duplicate books in the
    grid: an in-flight page request from the previous view could land after the
    toggle and append stale results onto the fresh list. Page requests are now
    cancelled when the view changes, and appends are deduplicated. (#165)
  • Merging duplicates now actually transfers the removed book's files to the
    kept book. Previously the transferred file entries were silently deleted
    together with the removed book, leaving the files on disk untracked.
  • Merging duplicates no longer carries dead file references over to the kept
    book: entries whose file is missing from disk are dropped during the merge
    instead of leaving the kept book with a file that errors on open. (#165)