mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2024-12-27 00:59:14 +01:00
Update:Only emit library socket events to users with access to lib
This commit is contained in:
parent
725f8eecdb
commit
0e292c64c4
@ -109,7 +109,7 @@ class Auth {
|
||||
Logger.error('JWT Verify Token Failed', err)
|
||||
return resolve(null)
|
||||
}
|
||||
var user = this.users.find(u => u.id === payload.userId && u.username === payload.username)
|
||||
const user = this.users.find(u => u.id === payload.userId && u.username === payload.username)
|
||||
resolve(user || null)
|
||||
})
|
||||
})
|
||||
|
@ -31,9 +31,13 @@ class SocketAuthority {
|
||||
}
|
||||
|
||||
// Emits event to all authorized clients
|
||||
emitter(evt, data) {
|
||||
// optional filter function to only send event to specific users
|
||||
// TODO: validate that filter is actually a function
|
||||
emitter(evt, data, filter = null) {
|
||||
for (const socketId in this.clients) {
|
||||
if (this.clients[socketId].user) {
|
||||
if (filter && !filter(this.clients[socketId].user)) continue
|
||||
|
||||
this.clients[socketId].socket.emit(evt, data)
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ class LibraryController {
|
||||
constructor() { }
|
||||
|
||||
async create(req, res) {
|
||||
var newLibraryPayload = {
|
||||
const newLibraryPayload = {
|
||||
...req.body
|
||||
}
|
||||
if (!newLibraryPayload.name || !newLibraryPayload.folders || !newLibraryPayload.folders.length) {
|
||||
@ -26,9 +26,9 @@ class LibraryController {
|
||||
f.fullPath = Path.resolve(f.fullPath)
|
||||
return f
|
||||
})
|
||||
for (var folder of newLibraryPayload.folders) {
|
||||
for (const folder of newLibraryPayload.folders) {
|
||||
try {
|
||||
var direxists = await fs.pathExists(folder.fullPath)
|
||||
const direxists = await fs.pathExists(folder.fullPath)
|
||||
if (!direxists) { // If folder does not exist try to make it and set file permissions/owner
|
||||
await fs.mkdir(folder.fullPath)
|
||||
await filePerms.setDefault(folder.fullPath)
|
||||
@ -39,12 +39,16 @@ class LibraryController {
|
||||
}
|
||||
}
|
||||
|
||||
var library = new Library()
|
||||
const library = new Library()
|
||||
newLibraryPayload.displayOrder = this.db.libraries.length + 1
|
||||
library.setData(newLibraryPayload)
|
||||
await this.db.insertEntity('library', library)
|
||||
// TODO: Only emit to users that have access
|
||||
SocketAuthority.emitter('library_added', library.toJSON())
|
||||
|
||||
// Only emit to users with access to library
|
||||
const userFilter = (user) => {
|
||||
return user.checkCanAccessLibrary && user.checkCanAccessLibrary(library.id)
|
||||
}
|
||||
SocketAuthority.emitter('library_added', library.toJSON(), userFilter)
|
||||
|
||||
// Add library watcher
|
||||
this.watcher.addLibrary(library)
|
||||
@ -53,7 +57,7 @@ class LibraryController {
|
||||
}
|
||||
|
||||
findAll(req, res) {
|
||||
var librariesAccessible = req.user.librariesAccessible || []
|
||||
const librariesAccessible = req.user.librariesAccessible || []
|
||||
if (librariesAccessible && librariesAccessible.length) {
|
||||
return res.json(this.db.libraries.filter(lib => librariesAccessible.includes(lib.id)).map(lib => lib.toJSON()))
|
||||
}
|
||||
@ -75,12 +79,12 @@ class LibraryController {
|
||||
}
|
||||
|
||||
async update(req, res) {
|
||||
var library = req.library
|
||||
const library = req.library
|
||||
|
||||
// Validate new folder paths exist or can be created & resolve rel paths
|
||||
// returns 400 if a new folder fails to access
|
||||
if (req.body.folders) {
|
||||
var newFolderPaths = []
|
||||
const newFolderPaths = []
|
||||
req.body.folders = req.body.folders.map(f => {
|
||||
if (!f.id) {
|
||||
f.fullPath = Path.resolve(f.fullPath)
|
||||
@ -88,11 +92,11 @@ class LibraryController {
|
||||
}
|
||||
return f
|
||||
})
|
||||
for (var path of newFolderPaths) {
|
||||
var pathExists = await fs.pathExists(path)
|
||||
for (const path of newFolderPaths) {
|
||||
const pathExists = await fs.pathExists(path)
|
||||
if (!pathExists) {
|
||||
// Ensure dir will recursively create directories which might be preferred over mkdir
|
||||
var success = await fs.ensureDir(path).then(() => true).catch((error) => {
|
||||
const success = await fs.ensureDir(path).then(() => true).catch((error) => {
|
||||
Logger.error(`[LibraryController] Failed to ensure folder dir "${path}"`, error)
|
||||
return false
|
||||
})
|
||||
@ -105,7 +109,7 @@ class LibraryController {
|
||||
}
|
||||
}
|
||||
|
||||
var hasUpdates = library.update(req.body)
|
||||
const hasUpdates = library.update(req.body)
|
||||
// TODO: Should check if this is an update to folder paths or name only
|
||||
if (hasUpdates) {
|
||||
// Update watcher
|
||||
@ -115,7 +119,7 @@ class LibraryController {
|
||||
this.cronManager.updateLibraryScanCron(library)
|
||||
|
||||
// Remove libraryItems no longer in library
|
||||
var itemsToRemove = this.db.libraryItems.filter(li => li.libraryId === library.id && !library.checkFullPathInLibrary(li.path))
|
||||
const itemsToRemove = this.db.libraryItems.filter(li => li.libraryId === library.id && !library.checkFullPathInLibrary(li.path))
|
||||
if (itemsToRemove.length) {
|
||||
Logger.info(`[Scanner] Updating library, removing ${itemsToRemove.length} items`)
|
||||
for (let i = 0; i < itemsToRemove.length; i++) {
|
||||
@ -123,32 +127,37 @@ class LibraryController {
|
||||
}
|
||||
}
|
||||
await this.db.updateEntity('library', library)
|
||||
SocketAuthority.emitter('library_updated', library.toJSON())
|
||||
|
||||
// Only emit to users with access to library
|
||||
const userFilter = (user) => {
|
||||
return user.checkCanAccessLibrary && user.checkCanAccessLibrary(library.id)
|
||||
}
|
||||
SocketAuthority.emitter('library_updated', library.toJSON(), userFilter)
|
||||
}
|
||||
return res.json(library.toJSON())
|
||||
}
|
||||
|
||||
async delete(req, res) {
|
||||
var library = req.library
|
||||
const library = req.library
|
||||
|
||||
// Remove library watcher
|
||||
this.watcher.removeLibrary(library)
|
||||
|
||||
// Remove collections for library
|
||||
var collections = this.db.collections.filter(c => c.libraryId === library.id)
|
||||
const collections = this.db.collections.filter(c => c.libraryId === library.id)
|
||||
for (const collection of collections) {
|
||||
Logger.info(`[Server] deleting collection "${collection.name}" for library "${library.name}"`)
|
||||
await this.db.removeEntity('collection', collection.id)
|
||||
}
|
||||
|
||||
// Remove items in this library
|
||||
var libraryItems = this.db.libraryItems.filter(li => li.libraryId === library.id)
|
||||
const libraryItems = this.db.libraryItems.filter(li => li.libraryId === library.id)
|
||||
Logger.info(`[Server] deleting library "${library.name}" with ${libraryItems.length} items"`)
|
||||
for (let i = 0; i < libraryItems.length; i++) {
|
||||
await this.handleDeleteLibraryItem(libraryItems[i])
|
||||
}
|
||||
|
||||
var libraryJson = library.toJSON()
|
||||
const libraryJson = library.toJSON()
|
||||
await this.db.removeEntity('library', library.id)
|
||||
SocketAuthority.emitter('library_removed', libraryJson)
|
||||
return res.json(libraryJson)
|
||||
@ -170,10 +179,10 @@ class LibraryController {
|
||||
minified: req.query.minified === '1',
|
||||
collapseseries: req.query.collapseseries === '1'
|
||||
}
|
||||
var mediaIsBook = payload.mediaType === 'book'
|
||||
const mediaIsBook = payload.mediaType === 'book'
|
||||
|
||||
// Step 1 - Filter the retrieved library items
|
||||
var filterSeries = null
|
||||
let filterSeries = null
|
||||
if (payload.filterBy) {
|
||||
libraryItems = libraryHelpers.getFilteredLibraryItems(libraryItems, payload.filterBy, req.user, this.rssFeedManager.feedsArray)
|
||||
payload.total = libraryItems.length
|
||||
@ -216,7 +225,7 @@ class LibraryController {
|
||||
|
||||
if (payload.sortBy) {
|
||||
// old sort key TODO: should be mutated in dbMigration
|
||||
var sortKey = payload.sortBy
|
||||
let sortKey = payload.sortBy
|
||||
if (sortKey.startsWith('book.')) {
|
||||
sortKey = sortKey.replace('book.', 'media.metadata.')
|
||||
}
|
||||
@ -246,7 +255,7 @@ class LibraryController {
|
||||
}
|
||||
|
||||
// Sort series based on the sortBy attribute
|
||||
var direction = payload.sortDesc ? 'desc' : 'asc'
|
||||
const direction = payload.sortDesc ? 'desc' : 'asc'
|
||||
sortArray.push({
|
||||
[direction]: (li) => {
|
||||
if (mediaIsBook && sortBySequence) {
|
||||
@ -332,7 +341,7 @@ class LibraryController {
|
||||
}
|
||||
|
||||
async removeLibraryItemsWithIssues(req, res) {
|
||||
var libraryItemsWithIssues = req.libraryItems.filter(li => li.hasIssues)
|
||||
const libraryItemsWithIssues = req.libraryItems.filter(li => li.hasIssues)
|
||||
if (!libraryItemsWithIssues.length) {
|
||||
Logger.warn(`[LibraryController] No library items have issues`)
|
||||
return res.sendStatus(200)
|
||||
@ -349,8 +358,8 @@ class LibraryController {
|
||||
|
||||
// api/libraries/:id/series
|
||||
async getAllSeriesForLibrary(req, res) {
|
||||
var libraryItems = req.libraryItems
|
||||
var payload = {
|
||||
const libraryItems = req.libraryItems
|
||||
const payload = {
|
||||
results: [],
|
||||
total: 0,
|
||||
limit: req.query.limit && !isNaN(req.query.limit) ? Number(req.query.limit) : 0,
|
||||
@ -361,7 +370,7 @@ class LibraryController {
|
||||
minified: req.query.minified === '1'
|
||||
}
|
||||
|
||||
var series = libraryHelpers.getSeriesFromBooks(libraryItems, this.db.series, null, payload.filterBy, req.user, payload.minified)
|
||||
let series = libraryHelpers.getSeriesFromBooks(libraryItems, this.db.series, null, payload.filterBy, req.user, payload.minified)
|
||||
|
||||
const direction = payload.sortDesc ? 'desc' : 'asc'
|
||||
series = naturalSort(series).by([
|
||||
|
Loading…
Reference in New Issue
Block a user