Commit Graph

978 Commits

Author SHA1 Message Date
neon 5290e63375 refactor(metadata): await metadata score calculations on metadata changes
Ensure metadata score calculations are awaited when book metadata or covers are saved or updated, and add concurrency queuing for on-demand score recalculations.
2026-07-27 06:13:54 +00:00
neon 20561c28df feat(audit): add detailed entry metadata and filtering to audit logs
Expand audit log entries to record detailed resource metadata (such as book titles on deletion), and add rich filtering by action, actor, and resource in the audit log viewer UI.

Closes #747
2026-07-27 05:42:38 +00:00
neon e850e929d9 feat(reader): add configurable spread gap for two-page comic view
Allow users to adjust the gap between pages when reading comics in two-page spread mode. Include backend preference validation, shared settings defaults, translation keys, and reader settings UI controls.

Closes #740
2026-07-27 04:28:22 +00:00
neon 92ade7dbba i18n(client): migrate plural messages to ICU MessageFormat
Replace pipe-delimited Vue I18n plural messages with ICU MessageFormat syntax across all locale catalogs and Vue components. Configure custom message formatting and validation to enforce ICU syntax and argument parity.

Closes #792
2026-07-27 01:28:52 +00:00
neon 5aedd93ad5 i18n(client): sync translations from Crowdin (#763)
* i18n(client): sync Portuguese, Brazilian translations from Crowdin

Keep translated catalogs synchronized with reviewed Crowdin content.

* i18n(client): sync German translations from Crowdin

Keep translated catalogs synchronized with reviewed Crowdin content.

* i18n(client): restore Portuguese plural fallbacks

Keep the Crowdin sync mergeable while the malformed translations are
corrected at their source.
2026-07-26 17:20:32 -06:00
dependabot[bot] 9b2e8c25c3 chore(deps): bump the github-actions group with 5 updates (#770)
Bumps the github-actions group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [actions/checkout](https://github.com/actions/checkout) | `7.0.0` | `7.0.1` |
| [docker/login-action](https://github.com/docker/login-action) | `4.4.0` | `4.5.0` |
| [actions/labeler](https://github.com/actions/labeler) | `6.2.0` | `7.0.0` |
| [ossf/scorecard-action](https://github.com/ossf/scorecard-action) | `2.4.3` | `2.4.4` |
| [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) | `4.37.1` | `4.37.3` |


Updates `actions/checkout` from 7.0.0 to 7.0.1
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0...3d3c42e5aac5ba805825da76410c181273ba90b1)

Updates `docker/login-action` from 4.4.0 to 4.5.0
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/af1e73f918a031802d376d3c8bbc3fe56130a9b0...06fb636fac595d6fb4b28a5dfcb21a6f5091859c)

Updates `actions/labeler` from 6.2.0 to 7.0.0
- [Release notes](https://github.com/actions/labeler/releases)
- [Commits](https://github.com/actions/labeler/compare/b8dd2d9be0f68b860e7dae5dae7d772984eacd6d...bf12e9b00b37c5c0ca2b87b79b2daf7891dbda13)

Updates `ossf/scorecard-action` from 2.4.3 to 2.4.4
- [Release notes](https://github.com/ossf/scorecard-action/releases)
- [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md)
- [Commits](https://github.com/ossf/scorecard-action/compare/4eaacf0543bb3f2c246792bd56e8cdeffafb205a...2d1146689b8cda280b9bc96326124645441f03bc)

Updates `github/codeql-action/upload-sarif` from 4.37.1 to 4.37.3
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/7188fc363630916deb702c7fdcf4e481b751f97a...e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: docker/login-action
  dependency-version: 4.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: actions/labeler
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: ossf/scorecard-action
  dependency-version: 2.4.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.37.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  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-07-26 16:40:00 -06:00
Samuel Painter 631ff92fa2 fix(reader): fall back to percentage jump when kosync response has no xpointer (#777)
* fix(reader): fall back to percentage jump when kosync response has no xpointer

The KOReader plugin's progress pull calls syncToProgress(body.progress),
which fires GotoXPointer(nil) or GotoPage(nil) when body.progress is nil.
Both silently no-op, so the reader position does not move and the user
sees 'Progress has been synchronized.' with nothing changing.

This happens whenever the kosync response has percentage-only progress
(e.g. progress written by the BookOrbit web reader, or by an external
audiobook->ebook progress bridge that only knows the percentage, not
an EPUB xpointer). hasUsableRemoteProgress already guards this case in
reconcileProgressBeforeBookSync, but getProgress / applyRemoteProgress
never got the same guard.

Extend syncToProgress to accept an optional percentage_fallback (0-1,
kosync scale). When there is no usable xpointer/page but a fallback
percentage is present, fire GotoPercent (0-100 scale) so the reader
actually jumps.

* fix(reader): apply percentage fallback in pre-book-sync reconcile

Drop the hasUsableRemoteProgress short-circuit so the reconcile that runs before a manual book
sync behaves like the pull paths. Now that syncToProgress falls back to a percentage jump, the
two flows disagreed on identical data: a manual pull moved the reader while the pre-sync
reconcile reported "no exact location" and changed nothing, which also left the percentage
argument passed to applyRemoteProgress unreachable.

An earlier guard already returns when body.percentage is absent, so every response reaching this
point can resolve a target. The strategy branches keep the conservative path intact: DISABLE
still skips the progress push when the remote is newer.

---------

Co-authored-by: neon <18559658+neonsolstice@users.noreply.github.com>
2026-07-26 16:39:11 -06:00
neon 3fabadcf0d fix(kobo): use server reading streak on plugin dashboard
Prefer the server account reading streak when provided by the dashboard endpoint, falling back to local KOReader statistics database data when offline or absent. This aligns the KOReader plugin day streak display with the web app.

Closes #711
2026-07-26 22:27:26 +00:00
neon 8db3656633 build(deps): update dependencies across root, server, and client
Update dependency versions across root, server, and client package files and refresh the lockfile.
Upgrade @fastify/static to the patched major release and verify production static-serving compatibility.
2026-07-26 22:03:55 +00:00
neon c0bd9ecf69 fix(smart-scope): handle invalid filters gracefully in count calculation
Validate smart scope filter rules before constructing query clauses during count computation. Catch validation errors for broken rules so invalid filters return null for bookCount rather than triggering an internal server error when fetching all smart scopes.

Closes #787
2026-07-26 21:08:51 +00:00
neon 9b2430a47e fix(server): allow google translate origin in content security policy
Add translate.googleapis.com to the connect-src Content-Security-Policy directive so the built-in eBook reader's translation feature can perform fetch requests without being blocked by CSP.

Closes #786
2026-07-26 19:17:33 +00:00
neon 3c6e8ed0d4 fix(scanner): annotate findBookFilesByBookIds return type
Add an explicit return type to findBookFilesByBookIds so TypeScript
resolves the bookFiles row shape instead of collapsing it to an index
signature, which broke structural typing against fileStateMatches.
2026-07-26 19:09:17 +00:00
neon bb6696c0d1 fix(cover): re-encode custom covers as baseline jpegs
Re-encode uploaded progressive JPEG custom cover images to baseline JPEG format so they render correctly across OPDS clients that lack progressive JPEG support.

Closes #782
2026-07-26 18:42:05 +00:00
neon b37335306c fix(smart-scope): enable series collapsing when scope contains saved series rules
Separate transient query filter rules from saved smart scope rules when evaluating series collapsing eligibility so series collapse as expected when requested in smart scopes.

Closes #780
2026-07-26 18:03:22 +00:00
neon a94f5068be fix(server): set ssl host from database url in postgres client config
When creating Postgres connection clients or pools, pg-connection-string
parsed SSL configurations did not explicitly set the SSL host matching
the database host, causing hostname verification failures against
localhost when DATABASE_URL specified an external host.

Use a helper to construct postgres client configurations that set the
SSL host from the parsed DATABASE_URL host across the server database
module and CLI scripts.

Closes #778
2026-07-26 17:50:21 +00:00
neon bcc80d7bf4 fix(books): hash duplicate scan keys to prevent btree index overflow
Raw file hash and exact metadata signatures can exceed PostgreSQL's btree tuple size limit (2704 bytes) for books with large file counts or long author lists, causing duplicate scans to fail. Hashing signature values with md5 ensures indexed duplicate scan keys maintain a fixed length within PostgreSQL index limits.

Closes #762

Closes #768
2026-07-26 17:28:38 +00:00
neon d4b6f65791 fix(server): send HSTS header conditionally for HTTPS requests
Disable default HSTS header in fastifyHelmet and register an onSend hook that includes Strict-Transport-Security only when request protocol is HTTPS. This prevents unencrypted HTTP setups and other services on the host from being forced onto HTTPS by browser HSTS caching.

Closes #760
2026-07-26 17:02:45 +00:00
neon b1357457fe fix(scanner): suppress file watcher events during internal file writes
Register internally written and renamed library files with a self-write registry to prevent the file watcher from triggering redundant rescan events during application file operations.

Update metadata and cover editing components to align UI state handling with self-write updates.
2026-07-23 06:06:06 +00:00
neon 58c5b422d3 feat(scanner): align bookdock duplicate detection with upload behavior
Replace metadata-based duplicate checks (ISBN, title/author) during BookDock finalization with destination path lookup. This allows books with shared or incorrect metadata to be imported whenever their resolved library target paths differ, matching the standard upload workflow.

Closes #736
2026-07-22 20:06:49 +00:00
neon fb93f6ec20 fix(kobo): support GET request on analytics gettests endpoint
Kobo devices send GET requests to /v1/analytics/gettests during sync checks. Previously only POST was handled, causing 404 errors during subsequent syncs.

Closes #697
2026-07-22 17:39:45 +00:00
neon 068de92b33 fix(koreader): align download dialog preview with device path
Ensure the catalog download dialog previews and resolves the destination folder and filename from devicePath when configured.

Fixes #752
2026-07-22 17:15:13 +00:00
neon 596284c389 feat(settings): expand accent color palette options
Add vivid and pastel accent color choices across client themes, user preferences, and shared types.
2026-07-22 16:47:06 +00:00
neon 0cacd0b9b8 fix(scanner): re-evaluate primary file format priority on upload
Re-evaluate the library format priority when uploading additional files to an existing book so higher-priority file formats properly take over as the primary file.

Closes #755
2026-07-22 15:21:33 +00:00
neon d406f42885 fix(client): remove html extension from documentation links
Update the header documentation URL and README links to use clean routes without the legacy .html extension, resolving broken navigation links.

Closes #754
2026-07-22 14:56:41 +00:00
neon a38288b1a2 fix(books): join metadata table when resolving query-based book ids
Query-based book selections failed with a 500 error when filtering by metadata fields because findIdsByWhere queried the bare books table without joining book_metadata. Left join book_metadata so WHERE clause predicates referencing metadata fields resolve correctly.

Closes #732
2026-07-22 06:31:31 +00:00
neon 8c287e9b42 fix(reader): preserve cbz reading position in continuous scroll mode
Virtualize CBZ strip pages using TanStack Virtual to reliably anchor
and update reading position during continuous scrolling, prevent initial
zero-page overwrites when reopening the reader, and flush pending progress
saves when navigating away.

Fixes #735
2026-07-22 05:51:28 +00:00
neon 0ee6cfe7ec fix(metadata): normalize book dock metadata schema and field sources
Normalize legacy and invalid fields in BookDock metadata objects before returning them to the client or processing DTO updates. This prevents unexpected properties such as legacy duration keys or extra rating attributes from failing DTO validation during file updates and finalize operations.

Closes #729
2026-07-22 05:26:31 +00:00
neon daed7d8fa7 fix(authors): prevent author header from shrinking in scroll container
Prevent the author header section from compressing or disappearing when
displaying large lists or grids of books on the author detail view.

Closes #737
2026-07-22 05:00:06 +00:00
neon ac129ce754 fix(cover): write compliant epub cover images and metadata structures
Ensure EPUB cover image updates produce standards-compliant EPUB2 and
EPUB3 metadata, manifest items, guide entries, and landmarks so e-readers
such as Readest and KOReader can render updated covers correctly.

Closes #730
2026-07-22 04:55:28 +00:00
neon 544f4d5e53 fix(books): respect library cover aspect ratio for combined media books
Books containing both ebook and audiobook formats were incorrectly rendered with square covers in dashboard widgets, series views, and cards because aspect ratio logic checked for any audio format file instead of relying on the configured cover aspect ratio or primary media profile.

Closes #712
2026-07-22 04:12:13 +00:00
chooh2 d051039a2d fix(storygraph): preserve reading attempt start date (#687)
* fix(storygraph): preserve reading attempt start date

Skip redundant active-reading status updates before syncing progress so StoryGraph keeps the existing reading attempt and start date.

Fixes #667

* test(storygraph): cover active status equivalence

Exercise exact and cross-mapped active reading statuses so patch coverage verifies every start-date preservation path.

* test(storygraph): complete active status matrix

Cover the exact rereading status pair and retain literal tuple types for every active-reading equivalence case.

---------

Co-authored-by: chooh2 <chooh2@users.noreply.github.com>
Co-authored-by: neon <18559658+neonsolstice@users.noreply.github.com>
2026-07-21 21:48:44 -06:00
neon 8db7cb796f security(deps): patch vulnerable transitive dependencies
Pin patched releases required by the production image security scan.
2026-07-22 02:22:03 +00:00
dependabot[bot] 4ecc44b2e5 chore(deps): bump the production-dependencies group with 15 updates (#714)
Bumps the production-dependencies group with 15 updates:

| Package | From | To |
| --- | --- | --- |
| [@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite) | `4.3.2` | `4.3.3` |
| [@tanstack/vue-virtual](https://github.com/TanStack/virtual/tree/HEAD/packages/vue-virtual) | `3.13.31` | `3.13.32` |
| [@tiptap/extension-link](https://github.com/ueberdosis/tiptap/tree/HEAD/packages/extension-link) | `3.27.3` | `3.28.0` |
| [@tiptap/pm](https://github.com/ueberdosis/tiptap/tree/HEAD/packages/pm) | `3.27.3` | `3.28.0` |
| [@tiptap/starter-kit](https://github.com/ueberdosis/tiptap/tree/HEAD/packages/starter-kit) | `3.27.3` | `3.28.0` |
| [@tiptap/vue-3](https://github.com/ueberdosis/tiptap/tree/HEAD/packages/vue-3) | `3.27.3` | `3.28.0` |
| [dompurify](https://github.com/cure53/DOMPurify) | `3.4.11` | `3.4.12` |
| [driver.js](https://github.com/nilbuild/driver.js) | `1.6.0` | `1.7.0` |
| [tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss) | `4.3.2` | `4.3.3` |
| [vue](https://github.com/vuejs/core) | `3.5.39` | `3.5.40` |
| [vue-router](https://github.com/vuejs/router) | `5.1.0` | `5.2.0` |
| [@fastify/compress](https://github.com/fastify/fastify-compress) | `9.0.0` | `9.1.0` |
| [@fastify/cookie](https://github.com/fastify/fastify-cookie) | `11.1.1` | `11.1.2` |
| [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) | `5.9.3` | `5.10.1` |
| [mysql2](https://github.com/sidorares/node-mysql2) | `3.22.6` | `3.23.0` |


Updates `@tailwindcss/vite` from 4.3.2 to 4.3.3
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.3/packages/@tailwindcss-vite)

Updates `@tanstack/vue-virtual` from 3.13.31 to 3.13.32
- [Release notes](https://github.com/TanStack/virtual/releases)
- [Changelog](https://github.com/TanStack/virtual/blob/main/packages/vue-virtual/CHANGELOG.md)
- [Commits](https://github.com/TanStack/virtual/commits/@tanstack/vue-virtual@3.13.32/packages/vue-virtual)

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

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

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

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

Updates `dompurify` from 3.4.11 to 3.4.12
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.4.11...3.4.12)

Updates `driver.js` from 1.6.0 to 1.7.0
- [Release notes](https://github.com/nilbuild/driver.js/releases)
- [Commits](https://github.com/nilbuild/driver.js/compare/1.6.0...1.7.0)

Updates `tailwindcss` from 4.3.2 to 4.3.3
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.3/packages/tailwindcss)

Updates `vue` from 3.5.39 to 3.5.40
- [Release notes](https://github.com/vuejs/core/releases)
- [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vuejs/core/compare/v3.5.39...v3.5.40)

Updates `vue-router` from 5.1.0 to 5.2.0
- [Release notes](https://github.com/vuejs/router/releases)
- [Commits](https://github.com/vuejs/router/compare/v5.1.0...v5.2.0)

Updates `@fastify/compress` from 9.0.0 to 9.1.0
- [Release notes](https://github.com/fastify/fastify-compress/releases)
- [Commits](https://github.com/fastify/fastify-compress/compare/v9.0.0...v9.1.0)

Updates `@fastify/cookie` from 11.1.1 to 11.1.2
- [Release notes](https://github.com/fastify/fastify-cookie/releases)
- [Commits](https://github.com/fastify/fastify-cookie/compare/v11.1.1...v11.1.2)

Updates `fast-xml-parser` from 5.9.3 to 5.10.1
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.9.3...v5.10.1)

Updates `mysql2` from 3.22.6 to 3.23.0
- [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.22.6...v3.23.0)

---
updated-dependencies:
- dependency-name: "@tailwindcss/vite"
  dependency-version: 4.3.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: "@tanstack/vue-virtual"
  dependency-version: 3.13.32
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: "@tiptap/extension-link"
  dependency-version: 3.28.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: "@tiptap/pm"
  dependency-version: 3.28.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: "@tiptap/starter-kit"
  dependency-version: 3.28.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: "@tiptap/vue-3"
  dependency-version: 3.28.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: dompurify
  dependency-version: 3.4.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: driver.js
  dependency-version: 1.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: tailwindcss
  dependency-version: 4.3.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: vue
  dependency-version: 3.5.40
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: vue-router
  dependency-version: 5.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: "@fastify/compress"
  dependency-version: 9.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: "@fastify/cookie"
  dependency-version: 11.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: fast-xml-parser
  dependency-version: 5.10.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: mysql2
  dependency-version: 3.23.0
  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>
2026-07-21 20:03:56 -06:00
dependabot[bot] 831f76b677 chore(deps): bump the github-actions group with 3 updates (#713)
Bumps the github-actions group with 3 updates: [actions/checkout](https://github.com/actions/checkout), [actions/setup-node](https://github.com/actions/setup-node) and [github/codeql-action/upload-sarif](https://github.com/github/codeql-action).


Updates `actions/checkout` from 6.0.3 to 7.0.0
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6.0.3...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0)

Updates `actions/setup-node` from 6.4.0 to 7.0.0
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e...820762786026740c76f36085b0efc47a31fe5020)

Updates `github/codeql-action/upload-sarif` from 4.37.0 to 4.37.1
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/99df26d4f13ea111d4ec1a7dddef6063f76b97e9...7188fc363630916deb702c7fdcf4e481b751f97a)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/setup-node
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.37.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-21 20:03:45 -06:00
neon 5fb785cb1d i18n(client): sync translations from Crowdin (#734)
* i18n(client): sync Portuguese, Brazilian translations from Crowdin

Keep translated catalogs synchronized with reviewed Crowdin content.

* i18n(client): sync German translations from Crowdin

Keep translated catalogs synchronized with reviewed Crowdin content.

* i18n(client): sync Slovenian translations from Crowdin

Keep translated catalogs synchronized with reviewed Crowdin content.
2026-07-21 20:03:16 -06:00
neon 06286d49b1 fix(metadata): persist hardcover and open library ids during book dock import
Pass external provider IDs (including Hardcover and Open Library IDs) from book dock metadata selection through ingest and finalization so they are saved to book metadata on import.

Closes #704
2026-07-16 05:45:36 +00:00
neon 095b347aff feat(books): add jump rail display preference
Let readers disable jump rails from grid display controls and skip bucket queries while the preference is off.
2026-07-15 22:32:59 -06:00
neon 504c9ce0e7 feat(books): expand and refine library jump navigation
Extend jump rails across alphabetical, temporal, and categorical sorts.

Keep large libraries responsive with bounded database buckets and exact offsets.

Refine active-state tracking, Unicode initials, localized labels, accessibility, adaptive sizing, and flat or collapsed-series navigation.
2026-07-15 22:32:59 -06:00
neon 5923ea95a5 feat(books): add adaptive temporal jump rail
Add bounded, user-scoped temporal buckets for supported date sorts and adapt resolution to populated dates. Keep rail navigation responsive with viewport sizing, sparse-gap compression, and virtual-grid synchronization.
2026-07-15 22:32:58 -06:00
neon 014c0af456 i18n(client): sync translations from Crowdin (#706)
* i18n(client): sync German translations from Crowdin

Keep translated catalogs synchronized with reviewed Crowdin content.

* i18n(client): sync Dutch translations from Crowdin

Keep translated catalogs synchronized with reviewed Crowdin content.

* i18n(client): sync Slovenian translations from Crowdin

Keep translated catalogs synchronized with reviewed Crowdin content.

* i18n(client): sync Portuguese, Brazilian translations from Crowdin

Keep translated catalogs synchronized with reviewed Crowdin content.
2026-07-15 13:54:21 -06:00
neon f6394a9b0c security: remediate dependency and code scanning alerts
Upgrade vulnerable transitive dependencies and harden filesystem, URL, HTML, cryptographic, and input-processing boundaries identified by security scans.
2026-07-15 18:42:07 +00:00
neon 876e32654a feat(client): support system theme mode
Add system preference option for appearance theme with auto-switching based on OS color scheme settings. Update default theme preference to system and listen for OS dark mode changes dynamically.

Closes #695
2026-07-15 15:22:15 +00:00
neon 8c8293b797 fix(stats): convert postgres storage sum from string to number
Parse the sum aggregation for book file sizes as a JavaScript number to match the statistics API contract, preventing missing values in the library stats overview.

Closes #696
2026-07-15 15:01:28 +00:00
neon ed5dbc9507 feat(books): add duplicate book detection and resolution tools
Introduce backend duplicate scanning services, persistence schemas, and frontend view components to allow users to scan their library for duplicate books by title/author similarity, group potential matches, and bulk delete redundant duplicates safely.
2026-07-15 05:20:16 +00:00
neon 940f9bbe5e docs: document Crowdin translation progress (#693) 2026-07-14 13:43:25 -06:00
neon 04d2ce0732 i18n(client): sync translations from Crowdin (#692)
* i18n(client): sync German translations from Crowdin

Keep translated catalogs synchronized with reviewed Crowdin content.

* i18n(client): sync Dutch translations from Crowdin

Keep translated catalogs synchronized with reviewed Crowdin content.

* i18n(client): sync Slovenian translations from Crowdin

Keep translated catalogs synchronized with reviewed Crowdin content.

* i18n(client): sync Portuguese, Brazilian translations from Crowdin

Keep translated catalogs synchronized with reviewed Crowdin content.
2026-07-14 13:29:44 -06:00
neon 66056a6eb9 ci(client): add Crowdin translation workflow
Establish native GitHub synchronization, scoped translation PR checks, locale safeguards, semantic-release handling, and contributor guidance.
2026-07-14 18:31:49 +00:00
neon 07b1ddb150 fix(annotations): filter out deleted highlights in highlight widget
Add isNull(annotations.deletedAt) condition to both count and offset queries in DashboardWidgetRepository to prevent soft-deleted annotations from being selected for the Highlight of the Day widget.

Closes #685
2026-07-14 11:53:57 -06:00
zanivann 6544d23002 feat(client): add Portuguese language localization (#688)
Expose Portuguese through shared locale preferences and keep the catalog synchronized with current English messages. Use keyed interpolation so series headings follow each language’s natural word order.

Closes #673

Co-authored-by: neon <18559658+neonsolstice@users.noreply.github.com>
2026-07-14 11:53:16 -06:00
Jadehawk ec84703cef feat(koreader): enhance settings and plugin behavior (#669)
* feat(koreader): add device file naming and improve plugin downloads (BO-658)

* fix(koreader): secure download paths and test collisions

* fix(koreader): preserve bulk collision identities

* fix(koreader): improve device file naming validation and path generation

* fix(koreader): remove duplicate settings lookup and audit file naming changes

* fix(koreader): resolve remaining CodeRabbit review issues

* fix(koreader): validate book detail query and finalize file naming release

validate book detail deviceId via DTO and ValidationPipe

localize new KOReader file naming settings (de, nl, sl)

bump KOReader plugin version to 1.3.0

* chore: rerun CI

* chore: normalized Closes #658 to not have embedded URL to issue. This is failing PR Conventions test

* test(koreader): align source and device removal assertions

* test(koreader): cover file naming settings flows

* test(koreader): cover file naming sync requests

* test(koreader): close remaining patch coverage gaps

* test(koreader): cover file naming server paths

* docs: add fixed2 modifier to file naming reference

* feat(koreader): support custom file naming patterns for KOReader sync

Add support for configurable KOReader file naming patterns, allowing users to define dynamic path templates for sync targets. Include UI draft settings, preview updates, and server path resolution.

Closes #658

---------

Co-authored-by: neon <18559658+neonsolstice@users.noreply.github.com>
Co-authored-by: jadehawk <jadehawk@hotmail.com>
2026-07-14 11:26:27 -06:00