mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-11-03 19:07:00 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			102 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			102 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
const { Request, Response } = require('express')
 | 
						|
const Path = require('path')
 | 
						|
const Logger = require('../Logger')
 | 
						|
const fs = require('../libs/fsExtra')
 | 
						|
const { toNumber } = require('../utils/index')
 | 
						|
const fileUtils = require('../utils/fileUtils')
 | 
						|
 | 
						|
/**
 | 
						|
 * @typedef RequestUserObject
 | 
						|
 * @property {import('../models/User')} user
 | 
						|
 *
 | 
						|
 * @typedef {Request & RequestUserObject} RequestWithUser
 | 
						|
 */
 | 
						|
 | 
						|
class FileSystemController {
 | 
						|
  constructor() {}
 | 
						|
 | 
						|
  /**
 | 
						|
   *
 | 
						|
   * @param {RequestWithUser} req
 | 
						|
   * @param {Response} res
 | 
						|
   */
 | 
						|
  async getPaths(req, res) {
 | 
						|
    if (!req.user.isAdminOrUp) {
 | 
						|
      Logger.error(`[FileSystemController] Non-admin user "${req.user.username}" attempting to get filesystem paths`)
 | 
						|
      return res.sendStatus(403)
 | 
						|
    }
 | 
						|
 | 
						|
    const relpath = req.query.path
 | 
						|
    const level = toNumber(req.query.level, 0)
 | 
						|
 | 
						|
    // Validate path. Must be absolute
 | 
						|
    if (relpath && (!Path.isAbsolute(relpath) || !(await fs.pathExists(relpath)))) {
 | 
						|
      Logger.error(`[FileSystemController] Invalid path in query string "${relpath}"`)
 | 
						|
      return res.status(400).send('Invalid "path" query string')
 | 
						|
    }
 | 
						|
    Logger.debug(`[FileSystemController] Getting file paths at ${relpath || 'root'} (${level})`)
 | 
						|
 | 
						|
    let directories = []
 | 
						|
 | 
						|
    // Windows returns drives first
 | 
						|
    if (global.isWin) {
 | 
						|
      if (relpath) {
 | 
						|
        directories = await fileUtils.getDirectoriesInPath(relpath, level)
 | 
						|
      } else {
 | 
						|
        const drives = await fileUtils.getWindowsDrives().catch((error) => {
 | 
						|
          Logger.error(`[FileSystemController] Failed to get windows drives`, error)
 | 
						|
          return []
 | 
						|
        })
 | 
						|
        if (drives.length) {
 | 
						|
          directories = drives.map((d) => {
 | 
						|
            return {
 | 
						|
              path: d,
 | 
						|
              dirname: d,
 | 
						|
              level: 0
 | 
						|
            }
 | 
						|
          })
 | 
						|
        }
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      directories = await fileUtils.getDirectoriesInPath(relpath || '/', level)
 | 
						|
    }
 | 
						|
 | 
						|
    // Exclude some dirs from this project to be cleaner in Docker
 | 
						|
    const excludedDirs = ['node_modules', 'client', 'server', '.git', 'static', 'build', 'dist', 'metadata', 'config', 'sys', 'proc', '.devcontainer', '.nyc_output', '.github', '.vscode'].map((dirname) => {
 | 
						|
      return fileUtils.filePathToPOSIX(Path.join(global.appRoot, dirname))
 | 
						|
    })
 | 
						|
    directories = directories.filter((dir) => {
 | 
						|
      return !excludedDirs.includes(dir.path)
 | 
						|
    })
 | 
						|
 | 
						|
    res.json({
 | 
						|
      posix: !global.isWin,
 | 
						|
      directories
 | 
						|
    })
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * POST: /api/filesystem/pathexists
 | 
						|
   *
 | 
						|
   * @param {RequestWithUser} req
 | 
						|
   * @param {Response} res
 | 
						|
   */
 | 
						|
  async checkPathExists(req, res) {
 | 
						|
    if (!req.user.canUpload) {
 | 
						|
      Logger.error(`[FileSystemController] Non-admin user "${req.user.username}" attempting to check path exists`)
 | 
						|
      return res.sendStatus(403)
 | 
						|
    }
 | 
						|
 | 
						|
    const filepath = req.body.filepath
 | 
						|
    if (!filepath?.length) {
 | 
						|
      return res.sendStatus(400)
 | 
						|
    }
 | 
						|
 | 
						|
    const exists = await fs.pathExists(filepath)
 | 
						|
    res.json({
 | 
						|
      exists
 | 
						|
    })
 | 
						|
  }
 | 
						|
}
 | 
						|
module.exports = new FileSystemController()
 |