mirror of
https://github.com/getnora-io/nora.git
synced 2026-04-12 06:50:31 +00:00
- Whitelist approach: only known safe extensions allowed (.rs, .toml, .yml, etc.) - Block sensitive patterns (.env, .key, .pem, secrets, credentials) - Warn but allow .md files - Check only NEW files, modifications to tracked files always allowed - Block large files (>5MB) with warning - Run cargo fmt check on Rust files - Update CONTRIBUTING.md with hook setup instructions
143 lines
3.5 KiB
Bash
Executable File
143 lines
3.5 KiB
Bash
Executable File
#!/bin/bash
|
|
# Pre-commit hook to prevent accidental commits of sensitive files
|
|
# Enable: git config core.hooksPath .githooks
|
|
|
|
set -e
|
|
|
|
RED='\033[0;31m'
|
|
YELLOW='\033[1;33m'
|
|
GREEN='\033[0;32m'
|
|
NC='\033[0m'
|
|
|
|
# Allowed file extensions (whitelist)
|
|
ALLOWED_EXTENSIONS=(
|
|
'\.rs$'
|
|
'\.toml$'
|
|
'\.lock$'
|
|
'\.yml$'
|
|
'\.yaml$'
|
|
'\.json$'
|
|
'\.sh$'
|
|
'\.html$'
|
|
'\.css$'
|
|
'\.js$'
|
|
'\.gitignore$'
|
|
'\.dockerignore$'
|
|
'Dockerfile$'
|
|
'LICENSE$'
|
|
'Makefile$'
|
|
)
|
|
|
|
# Extensions that trigger a warning (not blocked)
|
|
WARN_EXTENSIONS=(
|
|
'\.md$'
|
|
)
|
|
|
|
# Always blocked patterns (regardless of extension)
|
|
BLOCKED_PATTERNS=(
|
|
'\.env$'
|
|
'\.env\.'
|
|
'\.key$'
|
|
'\.pem$'
|
|
'\.p12$'
|
|
'\.pfx$'
|
|
'\.htpasswd$'
|
|
'secret'
|
|
'credential'
|
|
'password'
|
|
'\.bak$'
|
|
'\.swp$'
|
|
'\.swo$'
|
|
'node_modules/'
|
|
'target/debug/'
|
|
'\.DS_Store'
|
|
)
|
|
|
|
# Get staged files (only NEW files, not already tracked)
|
|
STAGED_FILES=$(git diff --cached --name-only --diff-filter=A)
|
|
|
|
if [ -z "$STAGED_FILES" ]; then
|
|
# No new files, only modifications to existing - allow
|
|
exit 0
|
|
fi
|
|
|
|
# Build patterns
|
|
ALLOWED_PATTERN=$(IFS='|'; echo "${ALLOWED_EXTENSIONS[*]}")
|
|
WARN_PATTERN=$(IFS='|'; echo "${WARN_EXTENSIONS[*]}")
|
|
BLOCKED_PATTERN=$(IFS='|'; echo "${BLOCKED_PATTERNS[*]}")
|
|
|
|
# Check for blocked patterns first
|
|
BLOCKED_FILES=$(echo "$STAGED_FILES" | grep -iE "$BLOCKED_PATTERN" || true)
|
|
|
|
if [ -n "$BLOCKED_FILES" ]; then
|
|
echo -e "${RED}BLOCKED: Suspicious files detected in commit${NC}"
|
|
echo ""
|
|
echo -e "${YELLOW}Files:${NC}"
|
|
echo "$BLOCKED_FILES" | sed 's/^/ - /'
|
|
echo ""
|
|
echo "If intentional, use: git commit --no-verify"
|
|
exit 1
|
|
fi
|
|
|
|
# Check for files with unknown extensions
|
|
UNKNOWN_FILES=""
|
|
WARN_FILES=""
|
|
|
|
while IFS= read -r file; do
|
|
[ -z "$file" ] && continue
|
|
|
|
if echo "$file" | grep -qE "$BLOCKED_PATTERN"; then
|
|
continue # Already handled above
|
|
elif echo "$file" | grep -qE "$WARN_PATTERN"; then
|
|
WARN_FILES="$WARN_FILES$file"$'\n'
|
|
elif ! echo "$file" | grep -qE "$ALLOWED_PATTERN"; then
|
|
UNKNOWN_FILES="$UNKNOWN_FILES$file"$'\n'
|
|
fi
|
|
done <<< "$STAGED_FILES"
|
|
|
|
# Warn about .md files
|
|
if [ -n "$WARN_FILES" ]; then
|
|
echo -e "${YELLOW}WARNING: Markdown files in commit:${NC}"
|
|
echo "$WARN_FILES" | sed '/^$/d' | sed 's/^/ - /'
|
|
echo ""
|
|
fi
|
|
|
|
# Block unknown extensions
|
|
if [ -n "$UNKNOWN_FILES" ]; then
|
|
echo -e "${RED}BLOCKED: Files with unknown extensions:${NC}"
|
|
echo "$UNKNOWN_FILES" | sed '/^$/d' | sed 's/^/ - /'
|
|
echo ""
|
|
echo "Allowed extensions: rs, toml, lock, yml, yaml, json, sh, html, css, js, md"
|
|
echo "If intentional, use: git commit --no-verify"
|
|
exit 1
|
|
fi
|
|
|
|
# Check for large files (>5MB)
|
|
LARGE_FILES=$(echo "$STAGED_FILES" | while read f; do
|
|
if [ -f "$f" ]; then
|
|
size=$(stat -f%z "$f" 2>/dev/null || stat -c%s "$f" 2>/dev/null || echo 0)
|
|
if [ "$size" -gt 5242880 ]; then
|
|
echo "$f ($(numfmt --to=iec $size 2>/dev/null || echo "${size}B"))"
|
|
fi
|
|
fi
|
|
done)
|
|
|
|
if [ -n "$LARGE_FILES" ]; then
|
|
echo -e "${YELLOW}WARNING: Large files (>5MB) in commit:${NC}"
|
|
echo "$LARGE_FILES" | sed 's/^/ - /'
|
|
echo ""
|
|
fi
|
|
|
|
# Run cargo fmt check if Rust files changed
|
|
if git diff --cached --name-only | grep -q '\.rs$'; then
|
|
if command -v cargo &> /dev/null; then
|
|
if ! cargo fmt --check &> /dev/null; then
|
|
echo -e "${RED}BLOCKED: cargo fmt check failed${NC}"
|
|
echo "Run: cargo fmt"
|
|
exit 1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
exit 0
|