From c6c8b378ab42fb1c78c8c359b422ffaaef230eaa Mon Sep 17 00:00:00 2001 From: clawdbot Date: Sat, 21 Feb 2026 12:07:53 -0500 Subject: [PATCH] fix: make comic-page endpoint public (like covers) The img src tag doesn't send auth headers, so the comic-page endpoint needs to be publicly accessible like the cover endpoint. --- server/controllers/LibraryItemController.js | 22 ++++++++++++++++----- server/routers/ApiRouter.js | 2 +- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/server/controllers/LibraryItemController.js b/server/controllers/LibraryItemController.js index 1729c1d5c..a139aa36e 100644 --- a/server/controllers/LibraryItemController.js +++ b/server/controllers/LibraryItemController.js @@ -1217,31 +1217,43 @@ class LibraryItemController { /** * GET api/items/:id/comic-page/:page/:fileid? * Get a single comic page (extracted and cached on server) + * Public endpoint (no auth required, like covers) * - * @param {LibraryItemControllerRequest} req + * @param {Request} req * @param {Response} res */ async getComicPage(req, res) { const ComicCacheManager = require('../managers/ComicCacheManager') + const libraryItemId = req.params.id + if (!libraryItemId) { + return res.sendStatus(400) + } + const pageNum = parseInt(req.params.page, 10) if (isNaN(pageNum) || pageNum < 1) { return res.status(400).send('Invalid page number') } + // Fetch library item directly (no auth middleware) + const libraryItem = await Database.libraryItemModel.getExpandedById(libraryItemId) + if (!libraryItem?.media) { + return res.sendStatus(404) + } + let ebookFile = null if (req.params.fileid) { - ebookFile = req.libraryItem.getLibraryFileWithIno(req.params.fileid) + ebookFile = libraryItem.getLibraryFileWithIno(req.params.fileid) if (!ebookFile?.isEBookFile) { Logger.error(`[LibraryItemController] Invalid ebook file id "${req.params.fileid}"`) return res.status(400).send('Invalid ebook file id') } } else { - ebookFile = req.libraryItem.media.ebookFile + ebookFile = libraryItem.media.ebookFile } if (!ebookFile) { - Logger.error(`[LibraryItemController] No ebookFile for library item "${req.libraryItem.media.title}"`) + Logger.error(`[LibraryItemController] No ebookFile for library item "${libraryItem.media.title}"`) return res.sendStatus(404) } @@ -1255,7 +1267,7 @@ class LibraryItemController { const comicPath = ebookFile.metadata.path const fileIno = ebookFile.ino const result = await ComicCacheManager.getPage( - req.libraryItem.id, + libraryItemId, fileIno, comicPath, pageNum diff --git a/server/routers/ApiRouter.js b/server/routers/ApiRouter.js index 3bc989543..cfbcdec70 100644 --- a/server/routers/ApiRouter.js +++ b/server/routers/ApiRouter.js @@ -128,7 +128,7 @@ class ApiRouter { this.router.patch('/items/:id/ebook/:fileid/status', LibraryItemController.middleware.bind(this), LibraryItemController.updateEbookFileStatus.bind(this)) // Comic page routes - server-side extraction with caching for performance this.router.get('/items/:id/comic-pages/:fileid?', LibraryItemController.middleware.bind(this), LibraryItemController.getComicPages.bind(this)) - this.router.get('/items/:id/comic-page/:page/:fileid?', LibraryItemController.middleware.bind(this), LibraryItemController.getComicPage.bind(this)) + this.router.get('/items/:id/comic-page/:page/:fileid?', LibraryItemController.getComicPage.bind(this)) // // User Routes