mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-06-23 01:18:59 +02:00
Add new options and fix path
This commit is contained in:
parent
7a33a412fc
commit
d2d558754f
@ -88,7 +88,10 @@ class FileSystemController {
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
|
||||
const { directory, folderPath } = req.body
|
||||
// fileName - If fileName is provided, the check only returns true if the actual file exists, not just the directory
|
||||
// allowBookFiles - If true, allows containing other book related files (e.g. .pdf, .epub, etc.)
|
||||
// allowAudioFiles - If true, allows containing other audio related files (e.g. .mp3, .m4b, etc.)
|
||||
const { directory, folderPath, fileName, allowBookFiles, allowAudioFiles } = req.body
|
||||
if (!directory?.length || typeof directory !== 'string' || !folderPath?.length || typeof folderPath !== 'string') {
|
||||
Logger.error(`[FileSystemController] Invalid request body: ${JSON.stringify(req.body)}`)
|
||||
return res.status(400).json({
|
||||
@ -96,6 +99,20 @@ class FileSystemController {
|
||||
})
|
||||
}
|
||||
|
||||
if (fileName && typeof fileName !== 'string') {
|
||||
Logger.error(`[FileSystemController] Invalid fileName in request body: ${JSON.stringify(req.body)}`)
|
||||
return res.status(400).json({
|
||||
error: 'Invalid fileName'
|
||||
})
|
||||
}
|
||||
|
||||
if (allowBookFiles && typeof allowBookFiles !== 'boolean' || allowAudioFiles && typeof allowAudioFiles !== 'boolean' || (allowBookFiles && allowAudioFiles)) {
|
||||
Logger.error(`[FileSystemController] Invalid allowBookFiles or allowAudioFiles in request body: ${JSON.stringify(req.body)}`)
|
||||
return res.status(400).json({
|
||||
error: 'Invalid allowBookFiles or allowAudioFiles'
|
||||
})
|
||||
}
|
||||
|
||||
// Check that library folder exists
|
||||
const libraryFolder = await Database.libraryFolderModel.findOne({
|
||||
where: {
|
||||
@ -110,20 +127,52 @@ class FileSystemController {
|
||||
|
||||
const filepath = Path.join(libraryFolder.path, directory)
|
||||
|
||||
// Ensure filepath is inside library folder (prevents directory traversal)
|
||||
if (!filepath.startsWith(libraryFolder.path)) {
|
||||
// Ensure filepath is inside library folder (prevents directory traversal) (And convert libraryFolder to Path to normalize)
|
||||
if (!filepath.startsWith(Path.join(libraryFolder.path))) {
|
||||
Logger.error(`[FileSystemController] Filepath is not inside library folder: ${filepath}`)
|
||||
return res.sendStatus(400)
|
||||
}
|
||||
|
||||
if (await fs.pathExists(filepath)) {
|
||||
if (fileName) {
|
||||
// Check if a specific file exists
|
||||
const filePath = Path.join(filepath, fileName)
|
||||
if (await fs.pathExists(filePath)) {
|
||||
return res.json({
|
||||
exists: true,
|
||||
})
|
||||
}
|
||||
} else if(allowBookFiles || allowAudioFiles) {
|
||||
let allowedExtensions = []
|
||||
if (allowBookFiles && !allowAudioFiles) {
|
||||
allowedExtensions = ['epub', 'pdf', 'mobi', 'azw3', 'cbr', 'cbz']
|
||||
} else if (allowAudioFiles && !allowBookFiles) {
|
||||
allowedExtensions = ['m4b', 'mp3', 'm4a', 'flac', 'opus', 'ogg', 'oga', 'mp4', 'aac', 'wma', 'aiff', 'aif', 'wav', 'webm', 'webma', 'mka', 'awb', 'caf', 'mpeg', 'mpg']
|
||||
} else {
|
||||
allowedExtensions = []
|
||||
}
|
||||
const files = await fs.readdir(filepath)
|
||||
const exists = allowedExtensions.length === 0
|
||||
? files.length > 0
|
||||
: files.some((file) => {
|
||||
const ext = Path.extname(file).toLowerCase().replace(/^\./, '')
|
||||
return allowedExtensions.includes(ext)
|
||||
})
|
||||
|
||||
// To let the sub dir check run
|
||||
if(exists) return res.json({
|
||||
exists: exists
|
||||
})
|
||||
} else {
|
||||
return res.json({
|
||||
exists: true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Check if a library item exists in a subdirectory
|
||||
// See: https://github.com/advplyr/audiobookshelf/issues/4146
|
||||
// For filenames it does not matter if the file is in a subdirectory or not because the file is not allowed to be created
|
||||
const cleanedDirectory = directory.split('/').filter(Boolean).join('/')
|
||||
if (cleanedDirectory.includes('/')) {
|
||||
// Can only be 2 levels deep
|
||||
|
Loading…
Reference in New Issue
Block a user