dotfiles/scripts/api
rpriven 5b6af65def
Organize scripts and clean up dotfiles
Changes:
- Added 80+ scripts with organized structure
  - payloads/ for third-party pentesting tools
  - pentesting/ for custom security scripts
  - Daily drivers remain flat for fast access
- Converted wes() function to proper script
- Removed .sh extensions from pentesting scripts
- Cleaned up aliases (removed 31 redundant lines)
- Added kanata/, build artifacts to gitignore
- Removed old fre.sh scripts and empty a.out
- Updated configs: helix, tmux, zsh, ulauncher, redshift

Security: All sensitive data excluded via gitignore
2025-11-07 14:48:21 -07:00

443 lines
11 KiB
Bash
Executable file

#!/usr/bin/env bash
set -euo pipefail
# Script Name: api
# Description: API testing helper with saved requests and response management
# Usage: api save login "POST https://api.com/login" -d '{"user":"test"}'
# api run login
# api list
# api history login
VERSION="1.0.0"
API_DIR="$HOME/.api"
REQUESTS_DIR="$API_DIR/requests"
RESPONSES_DIR="$API_DIR/responses"
TOKENS_FILE="$API_DIR/tokens.json"
# Colors
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly BLUE='\033[0;34m'
readonly RED='\033[0;31m'
readonly CYAN='\033[0;36m'
readonly BOLD='\033[1m'
readonly NC='\033[0m'
# Initialize API directory structure
init_api() {
mkdir -p "$REQUESTS_DIR" "$RESPONSES_DIR"
if [[ ! -f "$TOKENS_FILE" ]]; then
echo '{}' > "$TOKENS_FILE"
fi
}
show_help() {
echo -e "${BOLD}api${NC} - API Testing Helper v${VERSION}"
echo
echo -e "${BOLD}USAGE:${NC}"
echo " api <command> [args]"
echo
echo -e "${BOLD}COMMANDS:${NC}"
echo -e " ${CYAN}save NAME CURL_ARGS${NC} Save HTTP request"
echo -e " ${CYAN}run NAME [VARS]${NC} Run saved request"
echo -e " ${CYAN}list${NC} List saved requests"
echo -e " ${CYAN}show NAME${NC} Show request details"
echo -e " ${CYAN}delete NAME${NC} Delete saved request"
echo -e " ${CYAN}history NAME${NC} Show response history"
echo -e " ${CYAN}diff NAME${NC} Diff last two responses"
echo -e " ${CYAN}token set KEY VAL${NC} Save auth token"
echo -e " ${CYAN}token get KEY${NC} Get auth token"
echo -e " ${CYAN}export NAME curl${NC} Export as curl command"
echo
echo -e "${BOLD}EXAMPLES:${NC}"
echo " # Save a login request"
echo " api save login \"POST https://api.example.com/login\" \\"
echo " -H \"Content-Type: application/json\" \\"
echo " -d '{\"user\":\"test\",\"pass\":\"\${PASSWORD}\"}'"
echo
echo " # Run with variable substitution"
echo " api run login PASSWORD=secret123"
echo
echo " # Save auth token from response"
echo " api token set AUTH_TOKEN \"Bearer abc123\""
echo
echo " # Use token in request"
echo " api save profile \"GET https://api.example.com/profile\" \\"
echo " -H \"Authorization: \${AUTH_TOKEN}\""
echo
echo -e "${BOLD}FEATURES:${NC}"
echo " - Variable substitution (\${VAR})"
echo " - Response history"
echo " - Pretty-print JSON"
echo " - Diff responses"
echo " - Token management"
echo
echo -e "${BOLD}NOTES:${NC}"
echo " Requests: $REQUESTS_DIR"
echo " Responses: $RESPONSES_DIR"
echo " Tokens: $TOKENS_FILE"
}
# Save request
save_request() {
local name=$1
shift
local request_file="$REQUESTS_DIR/$name.sh"
# Save the curl command
cat > "$request_file" << EOF
#!/usr/bin/env bash
# API Request: $name
# Saved: $(date)
curl -w "\\n\\nStatus: %{http_code}\\nTime: %{time_total}s\\n" \\
$@
EOF
chmod +x "$request_file"
echo -e "${GREEN}${NC} Saved request: $name"
echo -e "${CYAN}File:${NC} $request_file"
}
# Run saved request
run_request() {
local name=$1
shift
local request_file="$REQUESTS_DIR/$name.sh"
if [[ ! -f "$request_file" ]]; then
echo -e "${RED}Error:${NC} Request not found: $name" >&2
echo "Use 'api list' to see available requests" >&2
exit 1
fi
# Parse variables (KEY=VALUE format)
declare -A vars
for arg in "$@"; do
if [[ "$arg" =~ ^([A-Z_]+)=(.+)$ ]]; then
vars[${BASH_REMATCH[1]}]="${BASH_REMATCH[2]}"
fi
done
# Read request, substitute variables
request_content=$(cat "$request_file")
for var in "${!vars[@]}"; do
request_content="${request_content//\$\{$var\}/${vars[$var]}}"
done
# Also substitute from tokens file
if command -v jq &>/dev/null && [[ -f "$TOKENS_FILE" ]]; then
while IFS= read -r line; do
key=$(echo "$line" | jq -r '.key')
val=$(echo "$line" | jq -r '.value')
request_content="${request_content//\$\{$key\}/$val}"
done < <(jq -c 'to_entries[]' "$TOKENS_FILE")
fi
# Save response with timestamp
timestamp=$(date '+%Y%m%d-%H%M%S')
response_file="$RESPONSES_DIR/${name}_${timestamp}.txt"
echo -e "${BOLD}${CYAN}Running: $name${NC}"
echo
# Execute and save response
echo "$request_content" | bash | tee "$response_file"
echo
echo -e "${GREEN}${NC} Response saved: $response_file"
# Pretty-print JSON if possible
if command -v jq &>/dev/null; then
if head -1 "$response_file" | jq empty 2>/dev/null; then
echo
echo -e "${BOLD}${CYAN}JSON Response:${NC}"
head -n -3 "$response_file" | jq .
fi
fi
}
# List saved requests
list_requests() {
if [[ ! -d "$REQUESTS_DIR" ]] || [[ -z "$(ls -A "$REQUESTS_DIR" 2>/dev/null)" ]]; then
echo -e "${YELLOW}No saved requests${NC}"
exit 0
fi
echo -e "${BOLD}${CYAN}Saved Requests:${NC}"
echo
for file in "$REQUESTS_DIR"/*.sh; do
name=$(basename "$file" .sh)
method=$(grep -oP 'POST|GET|PUT|DELETE|PATCH' "$file" | head -1 || echo "?")
url=$(grep -oP 'https?://[^\s"]+' "$file" | head -1 || echo "?")
printf " %-20s ${CYAN}%-7s${NC} %s\n" "$name" "$method" "$url"
done
}
# Show request details
show_request() {
local name=$1
local request_file="$REQUESTS_DIR/$name.sh"
if [[ ! -f "$request_file" ]]; then
echo -e "${RED}Error:${NC} Request not found: $name" >&2
exit 1
fi
echo -e "${BOLD}${CYAN}Request: $name${NC}"
echo
# Use bat if available for syntax highlighting
if command -v bat &>/dev/null; then
bat "$request_file"
else
cat "$request_file"
fi
}
# Delete request
delete_request() {
local name=$1
local request_file="$REQUESTS_DIR/$name.sh"
if [[ ! -f "$request_file" ]]; then
echo -e "${RED}Error:${NC} Request not found: $name" >&2
exit 1
fi
echo -n "Delete request '$name'? (y/N) "
read -r response
if [[ "$response" =~ ^[Yy]$ ]]; then
rm "$request_file"
echo -e "${GREEN}${NC} Deleted: $name"
else
echo "Cancelled"
fi
}
# Show response history
show_history() {
local name=$1
responses=$(find "$RESPONSES_DIR" -name "${name}_*.txt" 2>/dev/null | sort -r)
if [[ -z "$responses" ]]; then
echo -e "${YELLOW}No response history for: $name${NC}"
exit 0
fi
echo -e "${BOLD}${CYAN}Response History: $name${NC}"
echo
echo "$responses" | while read -r file; do
timestamp=$(basename "$file" | sed "s/${name}_//" | sed 's/.txt//')
status=$(tail -3 "$file" | grep "Status:" | awk '{print $2}')
time=$(tail -3 "$file" | grep "Time:" | awk '{print $2}')
# Color status
if [[ "$status" =~ ^2 ]]; then
status_colored="${GREEN}$status${NC}"
elif [[ "$status" =~ ^4 ]]; then
status_colored="${YELLOW}$status${NC}"
elif [[ "$status" =~ ^5 ]]; then
status_colored="${RED}$status${NC}"
else
status_colored="$status"
fi
echo -e " $timestamp - Status: $status_colored - Time: $time"
done
echo
echo -e "${CYAN}Tip:${NC} Use 'api diff $name' to compare last two responses"
}
# Diff last two responses
diff_responses() {
local name=$1
responses=$(find "$RESPONSES_DIR" -name "${name}_*.txt" 2>/dev/null | sort -r | head -2)
count=$(echo "$responses" | wc -l)
if [[ $count -lt 2 ]]; then
echo -e "${YELLOW}Need at least 2 responses to diff${NC}"
exit 0
fi
file1=$(echo "$responses" | sed -n 1p)
file2=$(echo "$responses" | sed -n 2p)
echo -e "${BOLD}${CYAN}Diff: $name${NC}"
echo -e "${CYAN}Latest:${NC} $(basename "$file1")"
echo -e "${CYAN}Previous:${NC} $(basename "$file2")"
echo
# Remove status/time lines before diff
diff -u <(head -n -3 "$file2") <(head -n -3 "$file1") || true
}
# Token management
manage_token() {
local action=$1
shift
case "$action" in
set)
if [[ $# -lt 2 ]]; then
echo -e "${RED}Error:${NC} Usage: api token set KEY VALUE" >&2
exit 1
fi
key=$1
value=$2
# Update JSON file
if command -v jq &>/dev/null; then
jq --arg k "$key" --arg v "$value" '. + {($k): $v}' "$TOKENS_FILE" > "$TOKENS_FILE.tmp"
mv "$TOKENS_FILE.tmp" "$TOKENS_FILE"
echo -e "${GREEN}${NC} Token saved: $key"
else
echo -e "${RED}Error:${NC} jq required for token management" >&2
exit 1
fi
;;
get)
if [[ $# -lt 1 ]]; then
echo -e "${RED}Error:${NC} Usage: api token get KEY" >&2
exit 1
fi
key=$1
if command -v jq &>/dev/null; then
value=$(jq -r ".$key // empty" "$TOKENS_FILE")
if [[ -n "$value" ]]; then
echo "$value"
else
echo -e "${YELLOW}Token not found: $key${NC}" >&2
exit 1
fi
fi
;;
list)
if command -v jq &>/dev/null; then
echo -e "${BOLD}${CYAN}Saved Tokens:${NC}"
jq -r 'keys[]' "$TOKENS_FILE"
fi
;;
*)
echo -e "${RED}Error:${NC} Unknown token action: $action" >&2
echo "Use: set, get, list" >&2
exit 1
;;
esac
}
# Export request
export_request() {
local name=$1
local format=${2:-curl}
local request_file="$REQUESTS_DIR/$name.sh"
if [[ ! -f "$request_file" ]]; then
echo -e "${RED}Error:${NC} Request not found: $name" >&2
exit 1
fi
case "$format" in
curl)
# Extract the curl command
grep -A 999 'curl' "$request_file" | grep -v '^#'
;;
*)
echo -e "${RED}Error:${NC} Unknown format: $format" >&2
echo "Supported: curl" >&2
exit 1
;;
esac
}
# Initialize
init_api
# Parse command
if [[ $# -eq 0 ]]; then
show_help
exit 0
fi
case $1 in
-h|--help|help)
show_help
;;
save)
if [[ $# -lt 3 ]]; then
echo -e "${RED}Error:${NC} Usage: api save NAME CURL_ARGS" >&2
exit 1
fi
shift
save_request "$@"
;;
run)
if [[ $# -lt 2 ]]; then
echo -e "${RED}Error:${NC} Usage: api run NAME [VARS]" >&2
exit 1
fi
shift
run_request "$@"
;;
list|ls)
list_requests
;;
show)
if [[ $# -lt 2 ]]; then
echo -e "${RED}Error:${NC} Usage: api show NAME" >&2
exit 1
fi
show_request "$2"
;;
delete|rm)
if [[ $# -lt 2 ]]; then
echo -e "${RED}Error:${NC} Usage: api delete NAME" >&2
exit 1
fi
delete_request "$2"
;;
history)
if [[ $# -lt 2 ]]; then
echo -e "${RED}Error:${NC} Usage: api history NAME" >&2
exit 1
fi
show_history "$2"
;;
diff)
if [[ $# -lt 2 ]]; then
echo -e "${RED}Error:${NC} Usage: api diff NAME" >&2
exit 1
fi
diff_responses "$2"
;;
token)
if [[ $# -lt 2 ]]; then
echo -e "${RED}Error:${NC} Usage: api token <set|get|list> ..." >&2
exit 1
fi
shift
manage_token "$@"
;;
export)
if [[ $# -lt 2 ]]; then
echo -e "${RED}Error:${NC} Usage: api export NAME [FORMAT]" >&2
exit 1
fi
export_request "$2" "${3:-curl}"
;;
*)
echo -e "${RED}Error:${NC} Unknown command: $1" >&2
echo "Run 'api --help' for usage" >&2
exit 1
;;
esac