Compare commits

...

7 Commits

Author SHA1 Message Date
advplyr 777a055fcd Update podcast episode downloads to have a fallback user agent string 2025-06-12 17:31:12 -05:00
advplyr b45085d2d6 Update podcast episode download user agent to fix #4401 2025-06-12 17:19:24 -05:00
advplyr 22f6e86a12 Fix pathexists filepath back to posix 2025-06-11 16:37:07 -05:00
advplyr dc6783ea76 Merge pull request #4398 from advplyr/pathexists_user_access
Update pathexists endpoint to check user has access to library
2025-06-11 16:31:14 -05:00
advplyr a6f10ca48e Update upload endpoint to check user has access to library 2025-06-11 16:14:51 -05:00
advplyr aac01d6d9a Update pathexists endpoint to check user has access to library 2025-06-11 16:04:18 -05:00
advplyr 7a33a412fc Merge pull request #4393 from advplyr/fix_pathexists_join
Fix filesystem pathexists path join
2025-06-10 17:20:23 -05:00
3 changed files with 46 additions and 13 deletions
+7 -1
View File
@@ -108,7 +108,13 @@ class FileSystemController {
return res.sendStatus(404) return res.sendStatus(404)
} }
const filepath = Path.join(libraryFolder.path, directory) if (!req.user.checkCanAccessLibrary(libraryFolder.libraryId)) {
Logger.error(`[FileSystemController] User "${req.user.username}" attempting to check path exists for library "${libraryFolder.libraryId}" without access`)
return res.sendStatus(403)
}
let filepath = Path.join(libraryFolder.path, directory)
filepath = fileUtils.filePathToPOSIX(filepath)
// Ensure filepath is inside library folder (prevents directory traversal) // Ensure filepath is inside library folder (prevents directory traversal)
if (!filepath.startsWith(libraryFolder.path)) { if (!filepath.startsWith(libraryFolder.path)) {
+6
View File
@@ -59,6 +59,12 @@ class MiscController {
if (!library) { if (!library) {
return res.status(404).send('Library not found') return res.status(404).send('Library not found')
} }
if (!req.user.checkCanAccessLibrary(library.id)) {
Logger.error(`[MiscController] User "${req.user.username}" attempting to upload to library "${library.id}" without access`)
return res.sendStatus(403)
}
const folder = library.libraryFolders.find((fold) => fold.id === folderId) const folder = library.libraryFolders.find((fold) => fold.id === folderId)
if (!folder) { if (!folder) {
return res.status(404).send('Folder not found') return res.status(404).send('Folder not found')
+33 -12
View File
@@ -103,18 +103,39 @@ module.exports.resizeImage = resizeImage
*/ */
module.exports.downloadPodcastEpisode = (podcastEpisodeDownload) => { module.exports.downloadPodcastEpisode = (podcastEpisodeDownload) => {
return new Promise(async (resolve) => { return new Promise(async (resolve) => {
const response = await axios({ // Some podcasts fail due to user agent strings
url: podcastEpisodeDownload.url, // See: https://github.com/advplyr/audiobookshelf/issues/3246 (requires iTMS user agent)
method: 'GET', // See: https://github.com/advplyr/audiobookshelf/issues/4401 (requires no iTMS user agent)
responseType: 'stream', const userAgents = ['audiobookshelf (+https://audiobookshelf.org; like iTMS)', 'audiobookshelf (+https://audiobookshelf.org)']
headers: {
'User-Agent': 'audiobookshelf (+https://audiobookshelf.org)' let response = null
}, let lastError = null
timeout: global.PodcastDownloadTimeout
}).catch((error) => { for (const userAgent of userAgents) {
Logger.error(`[ffmpegHelpers] Failed to download podcast episode with url "${podcastEpisodeDownload.url}"`, error) try {
return null response = await axios({
}) url: podcastEpisodeDownload.url,
method: 'GET',
responseType: 'stream',
headers: {
'User-Agent': userAgent
},
timeout: global.PodcastDownloadTimeout
})
Logger.debug(`[ffmpegHelpers] Successfully connected with User-Agent: ${userAgent}`)
break
} catch (error) {
lastError = error
Logger.warn(`[ffmpegHelpers] Failed to download podcast episode with User-Agent "${userAgent}" for url "${podcastEpisodeDownload.url}"`, error.message)
// If this is the last attempt, log the full error
if (userAgent === userAgents[userAgents.length - 1]) {
Logger.error(`[ffmpegHelpers] All User-Agent attempts failed for url "${podcastEpisodeDownload.url}"`, lastError)
}
}
}
if (!response) { if (!response) {
return resolve({ return resolve({
success: false success: false