UNPKG

uascript

Version:
72 lines (71 loc) 2.51 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ShellCommand = void 0; const fs = require('fs/promises'); const path = require('path'); class ShellCommand { validatePath(inputPath, basePath) { const normalized = path.resolve(inputPath); if (basePath) { const base = path.resolve(basePath); const relative = path.relative(base, normalized); if (relative.startsWith('..') || path.isAbsolute(relative)) { throw new Error(`Path traversal detected: ${inputPath} is outside ${basePath}`); } } if (normalized.includes('\0') || normalized.includes('\n')) { throw new Error(`Invalid characters in path: ${inputPath}`); } return normalized; } async mkdir(dirPath, deep = false, basePath) { const normalizedPath = this.validatePath(dirPath, basePath); try { await fs.mkdir(normalizedPath, { recursive: deep }); return normalizedPath; } catch (error) { if (error.code === 'EEXIST') { return normalizedPath; } throw new Error(`Failed to create directory: ${error.message}`); } } async rmrf(dirPath, basePath) { const normalizedPath = this.validatePath(dirPath, basePath); const forbiddenPaths = [ '/', '/usr', '/etc', '/bin', '/sbin', '/var', '/sys', '/proc', '/dev' ]; for (const forbidden of forbiddenPaths) { if (normalizedPath === forbidden || normalizedPath.startsWith(forbidden + '/')) { throw new Error(`Cannot remove system directory: ${dirPath}`); } } try { await fs.rm(normalizedPath, { recursive: true, force: true }); return normalizedPath; } catch (error) { throw new Error(`Failed to remove directory: ${error.message}`); } } async ls(dirPath, basePath) { const normalizedPath = this.validatePath(dirPath, basePath); try { const entries = await fs.readdir(normalizedPath, { withFileTypes: true }); return entries.map((entry) => entry.name); } catch (error) { throw new Error(`Failed to list directory: ${error.message}`); } } } exports.ShellCommand = ShellCommand;