Skip to content

Conversation

@duquesnay
Copy link

Summary

Adds file move operation to the PATCH endpoint, allowing files to be moved within the vault while preserving internal links.

Dependencies

Changes

  • Add move operation to PATCH endpoint for files
  • Implement handleMoveOperation method
  • Add path traversal security validation
  • Add 8 test cases covering success and error scenarios
  • Update OpenAPI documentation
  • Refactor PATCH validation logic

Security

  • Blocks path traversal attempts (../)
  • Rejects absolute paths
  • Validates and normalizes all input paths

Usage

curl -X PATCH https://localhost:27124/vault/old/path/file.md \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Operation: move" \
  -H "Target-Type: file" \
  -H "Target: path" \
  -H "Content-Type: text/plain" \
  -d "new/location/file.md"

Implementation

  • Uses FileManager.renameFile() to preserve links
  • Creates parent directories as needed
  • Returns appropriate error codes and messages
  • Follows existing error handling patterns

duquesnay added 9 commits July 8, 2025 15:31
Prevents potential error when Target header is missing by providing empty string default
- MissingTargetTypeHeader: List all valid Target-Type options with descriptions
- InvalidTargetTypeHeader: Show available options when invalid type provided
- MissingTargetHeader: Explain expected Target values based on Target-Type
- MissingOperation: List all operations with context about when to use each
- InvalidOperation: Show valid operations with their specific use cases

These improved error messages guide users to correct API usage by providing
helpful context and listing all available options directly in the error response.
- Implemented rename operation using PATCH with Target-Type: file, Target: name
- Uses app.fileManager.renameFile() to preserve internal links
- Added comprehensive error handling for missing files and existing destinations
- Test successful rename with Target-Type: file, Target: name
- Test rename fails with non-existent file
- Test rename fails when destination already exists
- Mock fileManager.renameFile() to verify proper API usage
- Add rename operation to PATCH endpoint enum
- Add file Target-Type to support file operations
- Include example and description for file rename
- Documents Operation: rename, Target-Type: file usage
- Add move operation to PATCH endpoint for files
- Use Operation: move, Target-Type: file, Target: path
- Automatically creates parent directories if needed
- Preserves all internal links using FileManager.renameFile()
- Validates paths and prevents overwrites
- Add tests for edge cases
- Add new error codes for clearer validation messages
- Use consistent returnCannedResponse pattern throughout
- Reorder validation checks for better flow
- Separate file operations from applyPatch operations early
- Maintain upstream coding style and patterns
…ile move

- Add path traversal protection to prevent access outside vault
- Use returnCannedResponse consistently throughout handleMoveOperation
- Add proper error codes to ErrorCode enum and ERROR_CODE_MESSAGES
- Validate paths early to prevent directory path destinations
- Check parent directory existence before creating
- Add comprehensive security tests for path traversal attempts
- Normalize paths to handle backslashes and multiple slashes
- Add move operation to PATCH endpoint enum
- Update Target parameter description for move operations
- Include example for file move functionality
- Documents Operation: move, Target-Type: file usage
Copy link
Owner

@coddingtonbear coddingtonbear left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this PR might be a good solution for the concerns I had around #176 so I think this is worth talking over more!

This PR, though, looks like it includes all of the changes of both #176 and this PR rather than being just the unique work for this particular problem. To make this PR reviewable, what you need to do is set its base branch to be the branch you made for #176 rather than main.

@coddingtonbear coddingtonbear added the needs more discussion More information or discussion is necessary before proceeding label Aug 3, 2025
@duquesnay duquesnay closed this Aug 4, 2025
@duquesnay duquesnay deleted the feat/file-move branch August 4, 2025 09:22
@duquesnay duquesnay restored the feat/file-move branch August 4, 2025 09:26
@duquesnay duquesnay reopened this Aug 4, 2025
@j-standfast
Copy link

j-standfast commented Aug 14, 2025

a) coddingtonbear - thanks for this plugin; it's great and much needed
b) duquesnay - thanks for this timely PR; I was about to take a stab at implementing exactly this functionality, only to discover you'd just done it; it too, is much needed
c) I'm now running a build from this PR and so far, so smooth - intuitive, running as expected, etc. etc.

no notes

@coddingtonbear
Copy link
Owner

I talked this over briefly with @duquesnay and I'm suggesting to him that he approach this via creating an API extension as the first pass. See https://github.com/coddingtonbear/obsidian-local-rest-api/wiki/Adding-your-own-API-Routes-via-an-Extension for insight into what that might look like.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs more discussion More information or discussion is necessary before proceeding

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants