mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-03 08:53:36 +00:00
refactor: implement ALLOWED_ROOT_DIRECTORY security and fix path validation
This commit consolidates directory security from two environment variables (WORKSPACE_DIR, ALLOWED_PROJECT_DIRS) into a single ALLOWED_ROOT_DIRECTORY variable while maintaining backward compatibility. Changes: - Re-enabled path validation in security.ts (was previously disabled) - Implemented isPathAllowed() to check ALLOWED_ROOT_DIRECTORY with DATA_DIR exception - Added backward compatibility for legacy ALLOWED_PROJECT_DIRS and WORKSPACE_DIR - Implemented path traversal protection via isPathWithinDirectory() helper - Added PathNotAllowedError custom exception for security violations - Updated all FS route endpoints to validate paths and return 403 on violation - Updated template clone endpoint to validate project paths - Updated workspace config endpoints to use ALLOWED_ROOT_DIRECTORY - Fixed stat() response property access bug in project-init.ts - Updated security tests to expect actual validation behavior Security improvements: - Path validation now enforced at all layers (routes, project init, agent services) - appData directory (DATA_DIR) always allowed for settings/credentials - Backward compatible with existing ALLOWED_PROJECT_DIRS/WORKSPACE_DIR configurations - Protection against path traversal attacks Backend test results: 654/654 passing ✅ 🤖 Generated with Claude Code Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -46,28 +46,31 @@ test.describe("Spec Editor Persistence", () => {
|
||||
// Step 4: Click on the Spec Editor in the sidebar
|
||||
await navigateToSpecEditor(page);
|
||||
|
||||
// Step 5: Wait for the spec editor to load
|
||||
// Step 5: Wait for the spec view to load (not empty state)
|
||||
await waitForElement(page, "spec-view", { timeout: 10000 });
|
||||
|
||||
// Step 6: Wait for the spec editor to load
|
||||
const specEditor = await getByTestId(page, "spec-editor");
|
||||
await specEditor.waitFor({ state: "visible", timeout: 10000 });
|
||||
|
||||
// Step 6: Wait for CodeMirror to initialize (it has a .cm-content element)
|
||||
// Step 7: Wait for CodeMirror to initialize (it has a .cm-content element)
|
||||
await specEditor.locator(".cm-content").waitFor({ state: "visible", timeout: 10000 });
|
||||
|
||||
// Step 7: Modify the editor content to "hello world"
|
||||
// Step 8: Modify the editor content to "hello world"
|
||||
await setEditorContent(page, "hello world");
|
||||
|
||||
// Verify content was set before saving
|
||||
const contentBeforeSave = await getEditorContent(page);
|
||||
expect(contentBeforeSave.trim()).toBe("hello world");
|
||||
|
||||
// Step 8: Click the save button and wait for save to complete
|
||||
// Step 9: Click the save button and wait for save to complete
|
||||
await clickSaveButton(page);
|
||||
|
||||
// Step 9: Refresh the page
|
||||
// Step 10: Refresh the page
|
||||
await page.reload();
|
||||
await waitForNetworkIdle(page);
|
||||
|
||||
// Step 10: Navigate back to the spec editor
|
||||
// Step 11: Navigate back to the spec editor
|
||||
// After reload, we need to wait for the app to initialize
|
||||
await waitForElement(page, "sidebar", { timeout: 10000 });
|
||||
|
||||
@@ -116,7 +119,7 @@ test.describe("Spec Editor Persistence", () => {
|
||||
);
|
||||
}
|
||||
|
||||
// Step 11: Verify the content was persisted
|
||||
// Step 12: Verify the content was persisted
|
||||
const persistedContent = await getEditorContent(page);
|
||||
expect(persistedContent.trim()).toBe("hello world");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user