mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2024-12-20 19:06:06 +01:00
Fix:Access series that are in multiple libraries and user does not have access to all #1899, new libraries/series endpoint
This commit is contained in:
parent
7e377297d7
commit
e378b79fbc
@ -19,7 +19,7 @@ export default {
|
||||
return redirect(`/library/${libraryId}`)
|
||||
}
|
||||
|
||||
const series = await app.$axios.$get(`/api/series/${params.id}?include=progress,rssfeed`).catch((error) => {
|
||||
const series = await app.$axios.$get(`/api/libraries/${library.id}/series/${params.id}?include=progress,rssfeed`).catch((error) => {
|
||||
console.error('Failed', error)
|
||||
return false
|
||||
})
|
||||
|
@ -387,7 +387,13 @@ class LibraryController {
|
||||
res.sendStatus(200)
|
||||
}
|
||||
|
||||
// api/libraries/:id/series
|
||||
/**
|
||||
* api/libraries/:id/series
|
||||
* Optional query string: `?include=rssfeed` that adds `rssFeed` to series if a feed is open
|
||||
*
|
||||
* @param {*} req
|
||||
* @param {*} res
|
||||
*/
|
||||
async getAllSeriesForLibrary(req, res) {
|
||||
const libraryItems = req.libraryItems
|
||||
|
||||
@ -448,6 +454,42 @@ class LibraryController {
|
||||
res.json(payload)
|
||||
}
|
||||
|
||||
/**
|
||||
* api/libraries/:id/series/:seriesId
|
||||
*
|
||||
* Optional includes (e.g. `?include=rssfeed,progress`)
|
||||
* rssfeed: adds `rssFeed` to series object if a feed is open
|
||||
* progress: adds `progress` to series object with { libraryItemIds:Array<llid>, libraryItemIdsFinished:Array<llid>, isFinished:boolean }
|
||||
*
|
||||
* @param {*} req
|
||||
* @param {*} res - Series
|
||||
*/
|
||||
async getSeriesForLibrary(req, res) {
|
||||
const include = (req.query.include || '').split(',').map(v => v.trim().toLowerCase()).filter(v => !!v)
|
||||
|
||||
const series = this.db.series.find(se => se.id === req.params.seriesId)
|
||||
if (!series) return res.sendStatus(404)
|
||||
|
||||
const libraryItemsInSeries = req.libraryItems.filter(li => li.media.metadata.hasSeries?.(series.id))
|
||||
|
||||
const seriesJson = series.toJSON()
|
||||
if (include.includes('progress')) {
|
||||
const libraryItemsFinished = libraryItemsInSeries.filter(li => !!req.user.getMediaProgress(li.id)?.isFinished)
|
||||
seriesJson.progress = {
|
||||
libraryItemIds: libraryItemsInSeries.map(li => li.id),
|
||||
libraryItemIdsFinished: libraryItemsFinished.map(li => li.id),
|
||||
isFinished: libraryItemsFinished.length >= libraryItemsInSeries.length
|
||||
}
|
||||
}
|
||||
|
||||
if (include.includes('rssfeed')) {
|
||||
const feedObj = this.rssFeedManager.findFeedForEntityId(seriesJson.id)
|
||||
seriesJson.rssFeed = feedObj?.toJSONMinified() || null
|
||||
}
|
||||
|
||||
res.json(seriesJson)
|
||||
}
|
||||
|
||||
// api/libraries/:id/collections
|
||||
async getCollectionsForLibrary(req, res) {
|
||||
const libraryItems = req.libraryItems
|
||||
@ -855,7 +897,7 @@ class LibraryController {
|
||||
middleware(req, res, next) {
|
||||
if (!req.user.checkCanAccessLibrary(req.params.id)) {
|
||||
Logger.warn(`[LibraryController] Library ${req.params.id} not accessible to user ${req.user.username}`)
|
||||
return res.sendStatus(404)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
const library = this.db.libraries.find(lib => lib.id === req.params.id)
|
||||
|
@ -4,6 +4,16 @@ const SocketAuthority = require('../SocketAuthority')
|
||||
class SeriesController {
|
||||
constructor() { }
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* /api/series/:id
|
||||
*
|
||||
* TODO: Update mobile app to use /api/libraries/:id/series/:seriesId API route instead
|
||||
* Series are not library specific so we need to know what the library id is
|
||||
*
|
||||
* @param {*} req
|
||||
* @param {*} res
|
||||
*/
|
||||
async findOne(req, res) {
|
||||
const include = (req.query.include || '').split(',').map(v => v.trim()).filter(v => !!v)
|
||||
|
||||
@ -28,7 +38,7 @@ class SeriesController {
|
||||
seriesJson.rssFeed = feedObj?.toJSONMinified() || null
|
||||
}
|
||||
|
||||
return res.json(seriesJson)
|
||||
res.json(seriesJson)
|
||||
}
|
||||
|
||||
async search(req, res) {
|
||||
@ -55,9 +65,13 @@ class SeriesController {
|
||||
const series = this.db.series.find(se => se.id === req.params.id)
|
||||
if (!series) return res.sendStatus(404)
|
||||
|
||||
const libraryItemsInSeries = this.db.libraryItems.filter(li => li.media.metadata.hasSeries?.(series.id))
|
||||
if (libraryItemsInSeries.some(li => !req.user.checkCanAccessLibrary(li.libraryId))) {
|
||||
Logger.warn(`[SeriesController] User attempted to access series "${series.id}" without access to the library`, req.user)
|
||||
/**
|
||||
* Filter out any library items not accessible to user
|
||||
*/
|
||||
const libraryItems = this.db.libraryItems.filter(li => li.media.metadata.hasSeries?.(series.id))
|
||||
const libraryItemsAccessible = libraryItems.filter(req.user.checkCanAccessLibraryItem)
|
||||
if (libraryItems.length && !libraryItemsAccessible.length) {
|
||||
Logger.warn(`[SeriesController] User attempted to access series "${series.id}" without access to any of the books`, req.user)
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
@ -70,7 +84,7 @@ class SeriesController {
|
||||
}
|
||||
|
||||
req.series = series
|
||||
req.libraryItemsInSeries = libraryItemsInSeries
|
||||
req.libraryItemsInSeries = libraryItemsAccessible
|
||||
next()
|
||||
}
|
||||
}
|
||||
|
@ -78,6 +78,7 @@ class ApiRouter {
|
||||
this.router.delete('/libraries/:id/issues', LibraryController.middleware.bind(this), LibraryController.removeLibraryItemsWithIssues.bind(this))
|
||||
this.router.get('/libraries/:id/episode-downloads', LibraryController.middleware.bind(this), LibraryController.getEpisodeDownloadQueue.bind(this))
|
||||
this.router.get('/libraries/:id/series', LibraryController.middleware.bind(this), LibraryController.getAllSeriesForLibrary.bind(this))
|
||||
this.router.get('/libraries/:id/series/:seriesId', LibraryController.middleware.bind(this), LibraryController.getSeriesForLibrary.bind(this))
|
||||
this.router.get('/libraries/:id/collections', LibraryController.middleware.bind(this), LibraryController.getCollectionsForLibrary.bind(this))
|
||||
this.router.get('/libraries/:id/playlists', LibraryController.middleware.bind(this), LibraryController.getUserPlaylistsForLibrary.bind(this))
|
||||
this.router.get('/libraries/:id/albums', LibraryController.middleware.bind(this), LibraryController.getAlbumsForLibrary.bind(this))
|
||||
|
Loading…
Reference in New Issue
Block a user