Commit Graph

1101 Commits

Author SHA1 Message Date
neon 04a0f21c8b feat(server): allow configuring the listen address
Allow native and host-network deployments to select an IPv4 or IPv6 bind
address through HOST while preserving the existing wildcard default.
Keep Docker health checks aligned with the configured listener and document
how to restrict host port publishing independently of the container address.
Cover validation, real bootstrap sockets, and health-check commands with tests.

Closes #1315
2026-09-09 10:26:12 +00:00
neon 4febe9ee45 docs: remove stale migration guide links
Closes #1309
2026-09-09 09:19:52 +00:00
neon 6c65c393b5 fix(reader): honor line spacing over publisher styles
Ensure explicit reader spacing overrides higher-specificity EPUB typography and cover the cascade with a regression test.

Fixes #1302
2026-09-09 03:20:08 +00:00
neon 7978ab0230 test(settings): cover fill-crop preference sync payload
Guard against the display preference mismatch reported in #1290 by checking author fields in cover-mode saves and verifying server acceptance of the complete payload.

Ref #1290
2026-09-09 03:12:16 +00:00
neon b9609b198e fix(annotations): preserve source highlight timestamps
Use KOReader highlight times for annotation history while retaining ingestion times for diagnostics. Export all stored location representations and backfill existing rows during sync.

Fixes #1300
2026-09-08 16:52:36 +00:00
neon cf40058cb6 fix(users): select exact content restriction matches
Prioritize exact genre and tag results within bounded catalog searches. Resolve Enter presses against existing IDs and ignore stale lookup responses.

Fixes #1295
2026-09-08 15:43:27 +00:00
dependabot[bot] 3d6afb3149 chore(deps): bump docker/setup-qemu-action in the github-actions group (#1267)
Bumps the github-actions group with 1 update: [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action).


Updates `docker/setup-qemu-action` from 4.2.0 to 4.3.0
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/96fe6ef7f33517b61c61be40b68a1882f3264fb8...1f40c72289eff860ee54a304f1438e3cff362e0a)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-version: 4.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: neon <18559658+neonsolstice@users.noreply.github.com>
2026-09-06 23:38:53 -06:00
neon 5d0c2e6e14 i18n(client): sync translations from Crowdin (#1236)
Keep sparse translated catalogs synchronized with reviewed Crowdin content.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-09-06 23:38:35 -06:00
dependabot[bot] 3833f85bad chore(deps): bump the production-dependencies group across 1 directory with 10 updates (#1289)
Bumps the production-dependencies group with 10 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@lucide/vue](https://github.com/lucide-icons/lucide/tree/HEAD/packages/vue) | `1.35.0` | `1.39.0` |
| [@tiptap/extension-link](https://github.com/ueberdosis/tiptap/tree/HEAD/packages/extension-link) | `3.30.5` | `3.31.0` |
| [@tiptap/pm](https://github.com/ueberdosis/tiptap/tree/HEAD/packages/pm) | `3.30.5` | `3.31.0` |
| [@tiptap/starter-kit](https://github.com/ueberdosis/tiptap/tree/HEAD/packages/starter-kit) | `3.30.5` | `3.31.0` |
| [@tiptap/vue-3](https://github.com/ueberdosis/tiptap/tree/HEAD/packages/vue-3) | `3.30.5` | `3.31.0` |
| [vue-echarts](https://github.com/ecomfe/vue-echarts) | `8.1.0` | `8.2.0` |
| [mysql2](https://github.com/sidorares/node-mysql2) | `3.24.2` | `3.24.3` |
| [nodemailer](https://github.com/nodemailer/nodemailer) | `9.0.6` | `9.1.1` |
| [undici](https://github.com/nodejs/undici) | `8.10.0` | `8.10.1` |
| [zod](https://github.com/colinhacks/zod) | `4.4.3` | `4.5.4` |



Updates `@lucide/vue` from 1.35.0 to 1.39.0
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.39.0/packages/vue)

Updates `@tiptap/extension-link` from 3.30.5 to 3.31.0
- [Release notes](https://github.com/ueberdosis/tiptap/releases)
- [Changelog](https://github.com/ueberdosis/tiptap/blob/v3.31.0/packages/extension-link/CHANGELOG.md)
- [Commits](https://github.com/ueberdosis/tiptap/commits/v3.31.0/packages/extension-link)

Updates `@tiptap/pm` from 3.30.5 to 3.31.0
- [Release notes](https://github.com/ueberdosis/tiptap/releases)
- [Changelog](https://github.com/ueberdosis/tiptap/blob/v3.31.0/packages/pm/CHANGELOG.md)
- [Commits](https://github.com/ueberdosis/tiptap/commits/v3.31.0/packages/pm)

Updates `@tiptap/starter-kit` from 3.30.5 to 3.31.0
- [Release notes](https://github.com/ueberdosis/tiptap/releases)
- [Changelog](https://github.com/ueberdosis/tiptap/blob/v3.31.0/packages/starter-kit/CHANGELOG.md)
- [Commits](https://github.com/ueberdosis/tiptap/commits/v3.31.0/packages/starter-kit)

Updates `@tiptap/vue-3` from 3.30.5 to 3.31.0
- [Release notes](https://github.com/ueberdosis/tiptap/releases)
- [Changelog](https://github.com/ueberdosis/tiptap/blob/v3.31.0/packages/vue-3/CHANGELOG.md)
- [Commits](https://github.com/ueberdosis/tiptap/commits/v3.31.0/packages/vue-3)

Updates `vue-echarts` from 8.1.0 to 8.2.0
- [Release notes](https://github.com/ecomfe/vue-echarts/releases)
- [Changelog](https://github.com/ecomfe/vue-echarts/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ecomfe/vue-echarts/compare/v8.1.0...v8.2.0)

Updates `mysql2` from 3.24.2 to 3.24.3
- [Release notes](https://github.com/sidorares/node-mysql2/releases)
- [Changelog](https://github.com/sidorares/node-mysql2/blob/master/Changelog.md)
- [Commits](https://github.com/sidorares/node-mysql2/compare/v3.24.2...v3.24.3)

Updates `nodemailer` from 9.0.6 to 9.1.1
- [Release notes](https://github.com/nodemailer/nodemailer/releases)
- [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodemailer/nodemailer/compare/v9.0.6...v9.1.1)

Updates `undici` from 8.10.0 to 8.10.1
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v8.10.0...v8.10.1)

Updates `zod` from 4.4.3 to 4.5.4
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](https://github.com/colinhacks/zod/compare/v4.4.3...v4.5.4)

---
updated-dependencies:
- dependency-name: "@lucide/vue"
  dependency-version: 1.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: "@tiptap/extension-link"
  dependency-version: 3.31.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: "@tiptap/pm"
  dependency-version: 3.31.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: "@tiptap/starter-kit"
  dependency-version: 3.31.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: "@tiptap/vue-3"
  dependency-version: 3.31.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: vue-echarts
  dependency-version: 8.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: mysql2
  dependency-version: 3.24.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: nodemailer
  dependency-version: 9.1.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: undici
  dependency-version: 8.10.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: zod
  dependency-version: 4.5.4
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: neon <18559658+neonsolstice@users.noreply.github.com>
2026-09-06 23:38:21 -06:00
neon f0bf903849 fix(books): hide completed audiobooks from continue listening
Keep the listening scroller consistent with terminal per-user read statuses and cover the completion transition with focused regression tests.
2026-09-07 05:35:16 +00:00
neon 5303a50604 security(books): enforce per-file mutation permissions
Require explicit delete or metadata-edit permission before mutating a book file. Keep catalog state intact when physical deletion fails.

Closes #1293
2026-09-07 05:08:33 +00:00
neon 028d4287b4 fix(client): stabilize book detail layout across screen sizes
Keep cover actions and discovery content adjacent to their related sections, and scale the synopsis preview for taller viewports.

Fixes #1259
v2.9.0
2026-09-06 15:39:31 +00:00
neon 836186159a fix(email): keep attachment filenames in sync after rename
Keep relative file paths synchronized during manual renames and repair
stale rows during watcher and full-scan reconciliation. Derive email
attachment names from the file being streamed.

Fixes #1286
2026-09-06 14:26:29 +00:00
neon 5052f170a9 fix(metadata): reject mismatched iTunes media lookups
Validate iTunes lookup identities against the book medium so stale ebook IDs fall back to audiobook search instead of preserving portrait covers.

Closes #1285
2026-09-06 11:40:18 +00:00
neon e3241eea3d security(deps): patch container vulnerabilities
Use the supported Alpine 3.23 Node image to avoid vulnerable util-linux packages in Alpine 3.24. Force fast-uri 3.1.6 to resolve the SSRF advisories reported by the image scan.
2026-09-05 10:06:56 +00:00
neon d8f87d8dd1 fix(client): keep cover controls within their column
Size the cover editor from its assigned container so narrow metadata grids stack controls below the artwork without overlap.

Fixes #1280
2026-09-05 10:05:58 +00:00
neon 978ef8ac2f fix(client): stop compact detail covers shrinking
Keep the observer-derived width cap scoped to the fixed-height wide layout so compact covers cannot feed their own height back into width.

Fixes #1279
2026-09-05 10:04:39 +00:00
neon 43bf1b7cfa fix(metadata): support CBZ archive comments
Retry central-directory discovery at the ZIP comment limit when the default scan reaches the end of the file. Preserve the archive comment while rewriting ComicInfo.xml.

Fixes #1272
2026-09-05 09:49:57 +00:00
neon e63c4b3685 fix(client): keep reading activity text inside card
Preserve the card's intrinsic minimum height when the detail column needs to scroll so empty-state copy remains within its border.

Fixes #1262
2026-09-05 09:30:20 +00:00
neon f5bb88f996 fix(client): restore titles for cached views
Restore the resolved entity title whenever a kept-alive view becomes active.
Prevent inactive cached views from replacing the current page title.

Fixes #1261
2026-09-05 09:15:16 +00:00
neon 16e63f2610 fix(books): scope request ownership by media type
Require a present content file in the requested media class so ebook, audiobook, and comic availability remain independent.
2026-09-02 16:55:17 +00:00
neon 9165dbed1d feat(auth): add SSO-only authentication mode
Require an enabled OIDC-linked superuser before disabling password flows. Track session authentication methods and fail closed across the API, web client, WebSockets, and administrative mutations.

Closes #1002
2026-09-02 05:04:18 +00:00
neon 6edde6c64d fix(metadata): restore Amazon metadata search
Use Amazon's readable mobile search route because the desktop route now returns an Akamai interstitial. Detect bot challenges and ignore sponsored cards before detail lookups.
2026-09-02 02:30:59 +00:00
neon 5346414a70 fix(metadata): accept goodreads pages that preload waf script
Treat challenge.js preload references as valid page content while retaining detection for active AWS WAF runtime markers.

Fixes #1240
2026-09-02 01:34:28 +00:00
neon adab5c8783 fix(scanner): handle legacy Book Dock series indexes
Normalize numeric JSON snapshots at the Book Dock boundary and reject malformed runtime values without aborting filing.

Closes #1241
2026-09-02 00:58:39 +00:00
neon 43a7c671d9 fix(server): resolve numeric-prefixed Hardcover slugs
Require the complete metadata value to be a valid GraphQL integer before using an ID lookup. Keep slug matching and sync change detection consistent through one parser.

Fixes #1243
2026-09-02 00:48:55 +00:00
neon 19afacb0f9 fix(server): handle Prowlarr torznab endpoint responses
Preserve Prowlarr's REST feed route and accept diagnostic responses so a server URL reports a useful Torznab mismatch instead of an opaque 406.

Fixes #1244
2026-09-02 00:32:47 +00:00
neon 3f06d4eee9 fix(cover): respect PDF crop box during extraction
Render the visible page region so wraparound covers do not appear in generated thumbnails.

Fixes #1242
2026-09-02 00:18:51 +00:00
neon e3779c1d7e feat(metadata): restrict autofill to stored provider ids
Prevent automatic metadata refreshes from searching alternate identities when a book already has trusted provider IDs. Preserve discovery and manual search behavior, and avoid dirtying descriptions on empty refreshes.

Closes #1222
2026-09-01 20:55:36 +00:00
neon eb60744494 feat(reader): improve PDF sidebar navigation
Keep the active PDF outline location visible while providing responsive navigation layouts and focused panels across screen sizes.

Closes #1235
2026-09-01 18:34:05 +00:00
wmTJc9IK0Q 04ec495c25 feat(reader): add PDF highlights and annotations on web only (#1213)
* feat(reader): add PDF highlights and annotations

Persist and render PDF highlights through the same annotation system as
EPUB. The annotation_positions table already supported a 'pdf' format, so
this wires the web create path, response, and reader UI to it.

Backend:
- create-annotation DTO accepts a pdf position (page + segment rects) as an
  alternative to a cfi; exactly one is required
- repository createPdf() persists a format='pdf' position (geometry in pos0,
  pageno in extras); selectWithCfi exposes the pdf geometry and status
- response DTO parses the pdf position and derives positionStatus

Frontend (pdf-v4 reader):
- usePdfAnnotations REST store and usePdfHighlights orchestration render
  persisted highlights via the EmbedPDF annotation plugin (autoCommit off,
  DB stays source of truth)
- selection popup (colour/style/note/copy/delete), note dialog, and a
  Highlights sidebar tab with search/colour/notes filters, navigate, delete
- NoteDialog relocated to reader/shared for reuse by both readers

Shared types gain AnnotationRect/AnnotationPdfPosition and an optional pdf
field on AnnotationItem.

* fix(reader): preserve input on failed PDF annotation save; convert mixed PDF+CFI for KOReader

- usePdfHighlights: createFromSelection/restyleExisting now return success;
  applyHighlight and saveNote only clear the selection, dismiss the popup, and
  close the note dialog on success. On failure the mark, popup, and typed note
  are preserved so the user can retry without losing input.
- koreader annotation exchange: the PDF push-down guard now skips only PDF-only
  annotations (no EPUB anchor). A mixed PDF+CFI annotation still converts its CFI
  to xpointer instead of being dropped.
- Tests for both paths.

* fix(reader): label PDF selection buttons and dedupe multi-page highlight retries

- PdfSelectionPopup: add aria-labels to the copy, highlight, note, and delete
  icon-only buttons so screen readers can identify them.
- usePdfHighlights: createFromSelection keeps only the pages that failed, so a
  retry after a partial multi-page failure never duplicates already-saved pages.
- Test for the multi-page partial-failure retry path.

* fix(reader): harden PDF annotation store, validation, and create logging

- usePdfAnnotations: catch rejected api() calls (session expiry / network) so
  load() sets loadError and mutations return null/false instead of rejecting.
- create-annotation DTO: require positive rect width/height so degenerate PDF
  geometry is rejected; tests for zero/negative dimensions.
- annotation.service: add [annotation.create] start/end/fail lifecycle logs with
  IDs, durationMs, and sanitized error for the multi-step create.

* test(reader): cover PDF annotations in the hub and add missing docstrings

Adds a real-DB e2e proving a PDF highlight persists as a pdf position and surfaces in the library-wide Annotations hub with the exact fields the page deep link needs (jumpFileFormat=pdf, cfi=null, pageno). Adds a hub-service unit test for the pdf row mapping. Documents the PDF render helpers, the annotation deep-link builder, and the createPdf repository method.

* fix(annotations): make PDF highlights reliable across reloads

Reconcile persisted highlights after EmbedPDF finishes loading its annotation state. Keep file-scoped pagination bounded and prevent PDF-only positions from starving device sync.

Ref #1195

* fix(annotations): keep pdf annotations stable during reload

Use authenticated native pagination fetches and discard responses that overlap successful mutations. Align shared dialog styling and annotation tests with project conventions.

Ref #1195

---------

Co-authored-by: neon <18559658+neonsolstice@users.noreply.github.com>
2026-09-01 09:16:01 -06:00
neon f41a58ac58 fix(stats): stop estimating sessions from KOReader progress
Keep KOSync limited to position synchronization and rely on measured page timings from the BookOrbit plugin for KOReader reading sessions. Remove legacy estimates at startup and rebuild affected daily totals.

Fixes #1233
2026-09-01 05:05:52 +00:00
neon 2912429ca6 feat(reader): add epub typography controls
Preserve publisher typography by default while allowing explicit spacing and indentation overrides across reader clients.

Ref #1206
2026-09-01 00:15:28 +00:00
neon 53cfe16b04 feat(reader): add epub paragraph spacing
Preserve publisher spacing at the minimum while allowing synchronized
format defaults and per-book overrides.

Closes #1206
2026-08-31 23:04:55 +00:00
neon 7057d350fd feat(reader): show book titles in reader tabs
Use library metadata so browser history and time tracking identify the book being read.

Closes #1147
2026-08-31 22:52:28 +00:00
Gary J. Espitia S. 2498e09083 fix(scanner): invalidate dir scan state on book deletion (#1226)
* fix(scanner): invalidate dir scan state on book deletion

Deleting a book row left its library_dir_scan_state entries intact, so the incremental scanner kept skipping the unchanged directory and never re-created the book on rescan. Invalidate the deleted books' folder paths and ancestors after deleteByIds so the next scan re-reads them and re-discovers the records.

* fix(scanner): make scan-state invalidation atomic

Prevent deleted books and concurrent scans from restoring stale directory state by versioning each library folder and coordinating writes under a database transaction.

* test(server): repair full-suite failures

Update the Book Dock expectation to the unit-record processor contract and bound the watchdog cutoff against timestamps captured around the sweep.

---------

Co-authored-by: neon <18559658+neonsolstice@users.noreply.github.com>
2026-08-31 15:23:57 -06:00
neon 6583fd696e i18n(client): sync translations from Crowdin (#1225)
Keep sparse translated catalogs synchronized with reviewed Crowdin content.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-31 11:07:55 -06:00
neon fc6e6f03d5 feat(book-requests): add automated request fulfillment
Let users request books, route approvals, search configured sources, and import fulfilled releases through the Book Dock. Include scoped permissions, automation, download-client integrations, plugin support, requester visibility, and one consolidated schema migration.

Closes #248
Ref #1115
2026-08-31 16:52:43 +00:00
neon 0f5429131a feat(smart-scope): filter by community review count
Allow provider-aware review count criteria so rating thresholds can be qualified by community review volume.

Closes #1041
2026-08-31 04:54:00 +00:00
neon 79b02e5b35 test(books): cover same-day reading completion
Protect equal manual start and finish dates through the client and status API.

Closes #1097
2026-08-31 02:15:34 +00:00
neon f555f080fe fix(server): merge imported read statuses safely
Preserve target-only statuses and update conflicts only when the source carries newer evidence. Treat timestamp-free source rows as insert-only so they cannot overwrite curated target state.

Fixes #1104
2026-08-31 02:07:33 +00:00
neon 07e8dcb90b test(server): cover narrator-specific rename paths
Verify matching audiobook editions resolve and move to separate destinations when only their narrator metadata differs.

Ref #1108
2026-08-31 01:53:49 +00:00
neon cc1b767264 fix: align Book Dock ready filter with filing readiness
Use the destination-complete predicate for the Ready chip and select-all operations so counts and filtered results remain consistent.

Fixes #1215
2026-08-30 17:21:35 +00:00
neon 9391555859 fix(books): fully expand book synopsis
Keep expanded synopsis content in the existing page or column flow so touch users do not encounter an undiscoverable nested scroll area. Expose the toggle state to assistive technology.

Fixes #1202
2026-08-30 17:00:33 +00:00
neon abc543044f fix(server): normalize Calibre indexes and restore image builds
Normalize integer-like Calibre OPF positions while preserving exact fractional labels. Make the static reply decoration explicit so Nest accepts production container builds.

Fixes #1212
2026-08-30 16:50:23 +00:00
neon cf84e37b2b fix(server): bind dc namespace during epub metadata writes
Preserve well-formed OPF output when publishers scope Dublin Core namespace declarations to individual metadata elements.

Fixes #1207
2026-08-30 16:28:27 +00:00
neon 26503bc9e6 fix(books): open personal review editor from summary
Reveal the collapsible review panel before entering edit mode so the summary action works on every responsive layout.

Fixes #1211
2026-08-30 16:04:52 +00:00
neon 5de4b9206b fix(server): support Fastify 5.12.1 proxy rules
Reject numeric trust-proxy values that Fastify no longer honors and retain explicit boolean or address-based configuration. Bridge Nest and cookie type augmentation differences so the pre-push typecheck succeeds under TypeScript 6.
2026-08-30 06:13:31 +00:00
neon 3196454944 fix(settings): persist complete display preferences
Accept the author display fields already emitted by the client and include them in automatic account sync. Keep older payloads compatible with defaults and cover the client-server contract with regression tests.

Fixes #1209
2026-08-30 05:59:19 +00:00
dependabot[bot] 9f15ced2cb chore(deps): bump fastify from 5.12.0 to 5.12.1 in the production-dependencies group across 1 directory (#1181)
Bumps the production-dependencies group with 1 update in the / directory: [fastify](https://github.com/fastify/fastify).


Updates `fastify` from 5.12.0 to 5.12.1
- [Release notes](https://github.com/fastify/fastify/releases)
- [Commits](https://github.com/fastify/fastify/compare/v5.12.0...v5.12.1)

---
updated-dependencies:
- dependency-name: fastify
  dependency-version: 5.12.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-29 23:48:27 -06:00