fix: address PR #8 security and cross-platform issues
Fixed all critical and high-priority issues from code review: Security fixes: - Fix shell injection vulnerability with proper path escaping - Add timestamped backup creation before modifying shell configs Reliability improvements: - Add comprehensive user input path validation - Add iCloud sync state checking with soft warnings - Improve shell detection to use default shell (not current session) Cross-platform support: - Add platform detection for iCloud features (macOS only) - Document error handling approach - Add helpful error messages with actionable suggestions All changes ensure the commands work safely across Linux, macOS, and Windows while providing better UX and preventing common user mistakes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -34,8 +34,11 @@ The command will be an alias that:
|
||||
- Changes to the vault directory: `cd /path/to/your/vault`
|
||||
- Tries to resume existing session: `claude --resume 2>/dev/null`
|
||||
- Falls back to new session if no existing one: `|| claude`
|
||||
- All in one command:
|
||||
`(cd /path/to/vault && (claude --resume 2>/dev/null || claude))`
|
||||
- All in one command with properly escaped path:
|
||||
`(cd "/path/to/vault" && (claude --resume 2>/dev/null || claude))`
|
||||
|
||||
**Important:** The path must be properly escaped to handle spaces and special
|
||||
characters.
|
||||
|
||||
This automatically enters resume mode if there's an existing session, or starts
|
||||
a new one if not.
|
||||
@@ -56,32 +59,75 @@ Add the alias to the appropriate config file:
|
||||
|
||||
## Shell Detection
|
||||
|
||||
Detects the user's default shell, with support for command-line override:
|
||||
|
||||
```bash
|
||||
# Detect current shell
|
||||
if [ -n "$ZSH_VERSION" ]; then
|
||||
SHELL_TYPE="zsh"
|
||||
CONFIG_FILE="$HOME/.zshrc"
|
||||
elif [ -n "$BASH_VERSION" ]; then
|
||||
SHELL_TYPE="bash"
|
||||
# Prefer .bashrc on Linux, .bash_profile on macOS
|
||||
if [ -f "$HOME/.bashrc" ]; then
|
||||
CONFIG_FILE="$HOME/.bashrc"
|
||||
else
|
||||
CONFIG_FILE="$HOME/.bash_profile"
|
||||
fi
|
||||
elif [ -n "$FISH_VERSION" ]; then
|
||||
SHELL_TYPE="fish"
|
||||
CONFIG_FILE="$HOME/.config/fish/config.fish"
|
||||
# Check if shell specified as argument (/install-claudesidian-command zsh)
|
||||
if [ -n "$1" ]; then
|
||||
# User provided shell type as argument
|
||||
SHELL_TYPE="$1"
|
||||
else
|
||||
# Auto-detect from $SHELL (user's default shell, not current shell)
|
||||
SHELL_TYPE=$(basename "$SHELL")
|
||||
fi
|
||||
|
||||
# Validate shell type and set appropriate config file
|
||||
case "$SHELL_TYPE" in
|
||||
zsh)
|
||||
CONFIG_FILE="$HOME/.zshrc"
|
||||
;;
|
||||
bash)
|
||||
# Prefer .bashrc on Linux, .bash_profile on macOS
|
||||
if [ -f "$HOME/.bashrc" ]; then
|
||||
CONFIG_FILE="$HOME/.bashrc"
|
||||
else
|
||||
CONFIG_FILE="$HOME/.bash_profile"
|
||||
fi
|
||||
;;
|
||||
fish)
|
||||
CONFIG_FILE="$HOME/.config/fish/config.fish"
|
||||
;;
|
||||
*)
|
||||
echo "❌ Unsupported shell: $SHELL_TYPE"
|
||||
echo " Supported shells: bash, zsh, fish"
|
||||
echo " Usage: /install-claudesidian-command [bash|zsh|fish]"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "🐚 Installing for: $SHELL_TYPE"
|
||||
echo "📝 Config file: $CONFIG_FILE"
|
||||
```
|
||||
|
||||
**Key improvements:**
|
||||
- Uses `$SHELL` to detect default shell (not `$ZSH_VERSION`/`$BASH_VERSION` which detect current session)
|
||||
- Supports command-line argument to override auto-detection
|
||||
- Shows detected shell and config file for transparency
|
||||
- Validates shell type and provides clear error message for unsupported shells
|
||||
|
||||
## Installation Steps
|
||||
|
||||
1. **Get vault path**: Use `pwd` to get current directory
|
||||
2. **Check if already installed**: Search config file for existing
|
||||
1. **Detect shell**: Use argument if provided, otherwise auto-detect from `$SHELL`
|
||||
2. **Get vault path**: Use `pwd` to get current directory
|
||||
3. **Escape the path**: Properly escape quotes and special characters for shell
|
||||
safety
|
||||
```bash
|
||||
# Escape any double quotes in the path
|
||||
ESCAPED_PATH="${VAULT_PATH//\"/\\\"}"
|
||||
# Also escape backslashes
|
||||
ESCAPED_PATH="${ESCAPED_PATH//\\/\\\\}"
|
||||
```
|
||||
4. **Check if already installed**: Search config file for existing
|
||||
`claudesidian` alias
|
||||
3. **Add alias**: Append to config file if not present
|
||||
4. **Show success message**: With instructions to reload shell
|
||||
5. **Create backup**: Before modifying, create timestamped backup of config file
|
||||
```bash
|
||||
# Create backup with timestamp
|
||||
BACKUP_FILE="$CONFIG_FILE.backup-$(date +%Y%m%d-%H%M%S)"
|
||||
cp "$CONFIG_FILE" "$BACKUP_FILE"
|
||||
echo "💾 Backup created: $BACKUP_FILE"
|
||||
```
|
||||
6. **Add alias**: Append to config file if not present, using double-quoted path
|
||||
7. **Show success message**: With instructions to reload shell
|
||||
|
||||
## Example Output
|
||||
|
||||
@@ -92,8 +138,10 @@ fi
|
||||
🐚 Shell detected: zsh
|
||||
📝 Config file: /home/user/.zshrc
|
||||
|
||||
💾 Backup created: /home/user/.zshrc.backup-20250107-143025
|
||||
|
||||
✅ Installed! Added to /home/user/.zshrc:
|
||||
alias claudesidian='(cd /home/user/my-vault && (claude --resume 2>/dev/null || claude))'
|
||||
alias claudesidian='(cd "/home/user/my-vault" && (claude --resume 2>/dev/null || claude))'
|
||||
|
||||
🔄 To activate, run:
|
||||
source ~/.zshrc
|
||||
@@ -103,6 +151,15 @@ fi
|
||||
✨ Test it: Type 'claudesidian' from any directory!
|
||||
```
|
||||
|
||||
## Handling Special Characters
|
||||
|
||||
The implementation properly handles paths with:
|
||||
- Spaces: `/Users/noah/My Vault`
|
||||
- Quotes: `/Users/noah/vault's backup`
|
||||
- Special characters that need escaping
|
||||
|
||||
Paths are double-quoted and any embedded quotes/backslashes are escaped.
|
||||
|
||||
## Important Notes
|
||||
|
||||
- The command uses a subshell `()` so it returns to your original directory
|
||||
@@ -110,32 +167,43 @@ fi
|
||||
- Automatically tries to resume existing sessions, falls back to new session
|
||||
- If alias already exists, ask user if they want to replace it
|
||||
- Always show what will be added before modifying config files
|
||||
- Create backup of config file before modifying
|
||||
- **Always create timestamped backup** of config file before modifying (format:
|
||||
`YYYYMMDD-HHMMSS`)
|
||||
- Backups are kept indefinitely - users can manually clean up old backups if
|
||||
needed
|
||||
- Show backup location so users know where to restore from if needed
|
||||
|
||||
## Usage Examples
|
||||
|
||||
Install for current shell:
|
||||
Install for your default shell (auto-detected):
|
||||
|
||||
```
|
||||
/install-claudesidian-command
|
||||
```
|
||||
|
||||
Install for specific shell:
|
||||
Install for specific shell (override auto-detection):
|
||||
|
||||
```
|
||||
/install-claudesidian-command zsh
|
||||
/install-claudesidian-command bash
|
||||
/install-claudesidian-command fish
|
||||
```
|
||||
|
||||
**When to specify shell:**
|
||||
- You use multiple shells and want to install for a specific one
|
||||
- Auto-detection picked the wrong shell
|
||||
- You're setting up for someone else
|
||||
|
||||
## How It Works
|
||||
|
||||
The alias uses a clever pattern:
|
||||
|
||||
```bash
|
||||
alias claudesidian='(cd /path/to/vault && (claude --resume 2>/dev/null || claude))'
|
||||
alias claudesidian='(cd "/path/to/vault" && (claude --resume 2>/dev/null || claude))'
|
||||
```
|
||||
|
||||
1. `(cd /path/to/vault && ...)` - Subshell that changes directory temporarily
|
||||
1. `(cd "/path/to/vault" && ...)` - Subshell that changes directory temporarily
|
||||
(path is double-quoted for safety)
|
||||
2. `claude --resume 2>/dev/null` - Tries to resume existing session, suppresses
|
||||
error
|
||||
3. `|| claude` - If resume fails (no session), starts new session
|
||||
|
||||
Reference in New Issue
Block a user