mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Merge pull request #4342 from advplyr/check_path_api_fix
Update pathexists file system API endpoint
This commit is contained in:
		
						commit
						3d0219a866
					
				| @ -359,15 +359,14 @@ export default { | ||||
|       // Check if path already exists before starting upload | ||||
|       //  uploading fails if path already exists | ||||
|       for (const item of items) { | ||||
|         const filepath = Path.join(this.selectedFolder.fullPath, item.directory) | ||||
|         const exists = await this.$axios | ||||
|           .$post(`/api/filesystem/pathexists`, { filepath, directory: item.directory, folderPath: this.selectedFolder.fullPath }) | ||||
|           .$post(`/api/filesystem/pathexists`, { directory: item.directory, folderPath: this.selectedFolder.fullPath }) | ||||
|           .then((data) => { | ||||
|             if (data.exists) { | ||||
|               if (data.libraryItemTitle) { | ||||
|                 this.$toast.error(this.$getString('ToastUploaderItemExistsInSubdirectoryError', [data.libraryItemTitle])) | ||||
|               } else { | ||||
|                 this.$toast.error(this.$getString('ToastUploaderFilepathExistsError', [filepath])) | ||||
|                 this.$toast.error(this.$getString('ToastUploaderFilepathExistsError', [Path.join(this.selectedFolder.fullPath, item.directory)])) | ||||
|               } | ||||
|             } | ||||
|             return data.exists | ||||
|  | ||||
| @ -84,49 +84,67 @@ class FileSystemController { | ||||
|    */ | ||||
|   async checkPathExists(req, res) { | ||||
|     if (!req.user.canUpload) { | ||||
|       Logger.error(`[FileSystemController] Non-admin user "${req.user.username}" attempting to check path exists`) | ||||
|       Logger.error(`[FileSystemController] User "${req.user.username}" without upload permissions attempting to check path exists`) | ||||
|       return res.sendStatus(403) | ||||
|     } | ||||
| 
 | ||||
|     const { filepath, directory, folderPath } = req.body | ||||
|     const { directory, folderPath } = req.body | ||||
| 
 | ||||
|     if (!filepath?.length || typeof filepath !== 'string') { | ||||
|     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({ | ||||
|         error: 'Invalid request body' | ||||
|       }) | ||||
|     } | ||||
| 
 | ||||
|     // Check that library folder exists
 | ||||
|     const libraryFolder = await Database.libraryFolderModel.findOne({ | ||||
|       where: { | ||||
|         path: folderPath | ||||
|       } | ||||
|     }) | ||||
| 
 | ||||
|     if (!libraryFolder) { | ||||
|       Logger.error(`[FileSystemController] Library folder not found: ${folderPath}`) | ||||
|       return res.sendStatus(404) | ||||
|     } | ||||
| 
 | ||||
|     const filepath = Path.posix.join(libraryFolder.path, directory) | ||||
|     // Ensure filepath is inside library folder (prevents directory traversal)
 | ||||
|     if (!filepath.startsWith(libraryFolder.path)) { | ||||
|       Logger.error(`[FileSystemController] Filepath is not inside library folder: ${filepath}`) | ||||
|       return res.sendStatus(400) | ||||
|     } | ||||
| 
 | ||||
|     const exists = await fs.pathExists(filepath) | ||||
| 
 | ||||
|     if (exists) { | ||||
|     if (await fs.pathExists(filepath)) { | ||||
|       return res.json({ | ||||
|         exists: true | ||||
|       }) | ||||
|     } | ||||
| 
 | ||||
|     // If directory and folderPath are passed in, check if a library item exists in a subdirectory
 | ||||
|     // Check if a library item exists in a subdirectory
 | ||||
|     // See: https://github.com/advplyr/audiobookshelf/issues/4146
 | ||||
|     if (typeof directory === 'string' && typeof folderPath === 'string' && directory.length > 0 && folderPath.length > 0) { | ||||
|       const cleanedDirectory = directory.split('/').filter(Boolean).join('/') | ||||
|       if (cleanedDirectory.includes('/')) { | ||||
|         // Can only be 2 levels deep
 | ||||
|         const possiblePaths = [] | ||||
|         const subdir = Path.dirname(directory) | ||||
|         possiblePaths.push(fileUtils.filePathToPOSIX(Path.join(folderPath, subdir))) | ||||
|         if (subdir.includes('/')) { | ||||
|           possiblePaths.push(fileUtils.filePathToPOSIX(Path.join(folderPath, Path.dirname(subdir)))) | ||||
|         } | ||||
|     const cleanedDirectory = directory.split('/').filter(Boolean).join('/') | ||||
|     if (cleanedDirectory.includes('/')) { | ||||
|       // Can only be 2 levels deep
 | ||||
|       const possiblePaths = [] | ||||
|       const subdir = Path.dirname(directory) | ||||
|       possiblePaths.push(fileUtils.filePathToPOSIX(Path.join(folderPath, subdir))) | ||||
|       if (subdir.includes('/')) { | ||||
|         possiblePaths.push(fileUtils.filePathToPOSIX(Path.join(folderPath, Path.dirname(subdir)))) | ||||
|       } | ||||
| 
 | ||||
|         const libraryItem = await Database.libraryItemModel.findOne({ | ||||
|           where: { | ||||
|             path: possiblePaths | ||||
|           } | ||||
|       const libraryItem = await Database.libraryItemModel.findOne({ | ||||
|         where: { | ||||
|           path: possiblePaths | ||||
|         } | ||||
|       }) | ||||
| 
 | ||||
|       if (libraryItem) { | ||||
|         return res.json({ | ||||
|           exists: true, | ||||
|           libraryItemTitle: libraryItem.title | ||||
|         }) | ||||
| 
 | ||||
|         if (libraryItem) { | ||||
|           return res.json({ | ||||
|             exists: true, | ||||
|             libraryItemTitle: libraryItem.title | ||||
|           }) | ||||
|         } | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user