fix: FileTree showing entire workspace instead of project directory
- Add debug logging to track project directory resolution - Improve path traversal security check with proper separator handling - Log entry count and first 10 entries for debugging - Fix project root validation to prevent listing workspace root The issue was that the tree was listing from the workspace root (containing gadget-code/, gadget-drone/, packages/) instead of the specific project directory. Added logging to help diagnose.
This commit is contained in:
parent
71f213d8d1
commit
2b029ebf2e
@ -724,22 +724,43 @@ class GadgetDrone extends GadgetProcess {
|
||||
return cb(false, { error: "No session lock active" });
|
||||
}
|
||||
|
||||
const projectRoot = WorkspaceService.getProjectDirectory(this.sessionLock.project.slug);
|
||||
// Get the project directory for this session
|
||||
const projectSlug = this.sessionLock.project.slug;
|
||||
const projectRoot = WorkspaceService.getProjectDirectory(projectSlug);
|
||||
|
||||
this.log.debug("fileTreeRequest received", {
|
||||
projectSlug,
|
||||
projectRoot,
|
||||
requestedPath: args.path,
|
||||
});
|
||||
|
||||
if (!projectRoot) {
|
||||
return cb(false, { error: "Project directory not found" });
|
||||
return cb(false, { error: `Project directory not found for slug: ${projectSlug}` });
|
||||
}
|
||||
|
||||
// If no path specified, list from project root
|
||||
// If path specified, resolve it relative to project root
|
||||
const targetPath = args.path
|
||||
? path.resolve(projectRoot, args.path)
|
||||
: projectRoot;
|
||||
|
||||
// Security: Ensure path is within project root
|
||||
// Security: Ensure resolved path is within project root
|
||||
const normalizedTarget = path.normalize(targetPath);
|
||||
const normalizedRoot = path.normalize(projectRoot);
|
||||
if (!normalizedTarget.startsWith(normalizedRoot)) {
|
||||
if (!normalizedTarget.startsWith(normalizedRoot + path.sep) && normalizedTarget !== normalizedRoot) {
|
||||
this.log.warn("fileTreeRequest path traversal attempt", {
|
||||
targetPath: normalizedTarget,
|
||||
projectRoot: normalizedRoot,
|
||||
});
|
||||
return cb(false, { error: "Access denied: path outside project root" });
|
||||
}
|
||||
|
||||
this.log.debug("fileTreeRequest resolved paths", {
|
||||
projectRoot,
|
||||
targetPath,
|
||||
isRoot: targetPath === projectRoot,
|
||||
});
|
||||
|
||||
try {
|
||||
const stat = await fs.stat(targetPath);
|
||||
if (!stat.isDirectory()) {
|
||||
@ -754,11 +775,17 @@ class GadgetDrone extends GadgetProcess {
|
||||
projectRoot,
|
||||
);
|
||||
|
||||
this.log.debug("fileTreeRequest completed", {
|
||||
entryCount: entries.length,
|
||||
entries: entries.slice(0, 10).map(e => e.name), // Log first 10 entries
|
||||
});
|
||||
|
||||
cb(true, { entries });
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
this.log.error("failed to list directory for file tree", {
|
||||
path: args.path,
|
||||
targetPath,
|
||||
error: errorMessage,
|
||||
});
|
||||
cb(false, { error: `Failed to list directory: ${errorMessage}` });
|
||||
|
||||
Loading…
Reference in New Issue
Block a user