mirror of
https://github.com/tw93/Mole.git
synced 2026-02-16 14:43:39 +00:00
Touch ID is supported in password scenarios
This commit is contained in:
103
bin/clean.sh
103
bin/clean.sh
@@ -77,18 +77,54 @@ note_activity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Cleanup background processes
|
# Cleanup background processes
|
||||||
|
CLEANUP_DONE=false
|
||||||
cleanup() {
|
cleanup() {
|
||||||
if [[ -n "$SUDO_KEEPALIVE_PID" ]]; then
|
local signal="${1:-EXIT}"
|
||||||
kill "$SUDO_KEEPALIVE_PID" 2>/dev/null || true
|
local exit_code="${2:-$?}"
|
||||||
SUDO_KEEPALIVE_PID=""
|
|
||||||
|
# Prevent multiple executions
|
||||||
|
if [[ "$CLEANUP_DONE" == "true" ]]; then
|
||||||
|
return 0
|
||||||
fi
|
fi
|
||||||
|
CLEANUP_DONE=true
|
||||||
|
|
||||||
|
# Stop all spinners and clear the line
|
||||||
if [[ -n "$SPINNER_PID" ]]; then
|
if [[ -n "$SPINNER_PID" ]]; then
|
||||||
kill "$SPINNER_PID" 2>/dev/null || true
|
kill "$SPINNER_PID" 2>/dev/null || true
|
||||||
|
wait "$SPINNER_PID" 2>/dev/null || true
|
||||||
SPINNER_PID=""
|
SPINNER_PID=""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$INLINE_SPINNER_PID" ]]; then
|
||||||
|
kill "$INLINE_SPINNER_PID" 2>/dev/null || true
|
||||||
|
wait "$INLINE_SPINNER_PID" 2>/dev/null || true
|
||||||
|
INLINE_SPINNER_PID=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clear any spinner output
|
||||||
|
if [[ -t 1 ]]; then
|
||||||
|
printf "\r\033[K"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Stop sudo keepalive
|
||||||
|
if [[ -n "$SUDO_KEEPALIVE_PID" ]]; then
|
||||||
|
kill "$SUDO_KEEPALIVE_PID" 2>/dev/null || true
|
||||||
|
wait "$SUDO_KEEPALIVE_PID" 2>/dev/null || true
|
||||||
|
SUDO_KEEPALIVE_PID=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
show_cursor
|
||||||
|
|
||||||
|
# If interrupted, show message
|
||||||
|
if [[ "$signal" == "INT" ]] || [[ $exit_code -eq 130 ]]; then
|
||||||
|
printf "\r\033[K"
|
||||||
|
echo -e "${YELLOW}Interrupted by user${NC}"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
trap cleanup EXIT INT TERM
|
trap 'cleanup EXIT $?' EXIT
|
||||||
|
trap 'cleanup INT 130; exit 130' INT
|
||||||
|
trap 'cleanup TERM 143; exit 143' TERM
|
||||||
|
|
||||||
# Loading animation functions
|
# Loading animation functions
|
||||||
SPINNER_PID=""
|
SPINNER_PID=""
|
||||||
@@ -285,7 +321,7 @@ safe_clean() {
|
|||||||
start_cleanup() {
|
start_cleanup() {
|
||||||
clear
|
clear
|
||||||
printf '\n'
|
printf '\n'
|
||||||
echo -e "${PURPLE}🧹 Clean Your Mac${NC}"
|
echo -e "${PURPLE}Clean Your Mac${NC}"
|
||||||
if [[ "$DRY_RUN" != "true" && -t 0 ]]; then
|
if [[ "$DRY_RUN" != "true" && -t 0 ]]; then
|
||||||
printf '\n'
|
printf '\n'
|
||||||
echo -e "${YELLOW}Tip:${NC} Safety first—run 'mo clean --dry-run'. Important Macs should stop."
|
echo -e "${YELLOW}Tip:${NC} Safety first—run 'mo clean --dry-run'. Important Macs should stop."
|
||||||
@@ -293,17 +329,32 @@ start_cleanup() {
|
|||||||
|
|
||||||
if [[ "$DRY_RUN" == "true" ]]; then
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
echo ""
|
echo ""
|
||||||
echo -e "${YELLOW}🧪 Dry Run mode:${NC} showing what would be removed (no deletions)."
|
echo -e "${YELLOW}Dry Run mode:${NC} showing what would be removed (no deletions)."
|
||||||
echo ""
|
echo ""
|
||||||
SYSTEM_CLEAN=false
|
SYSTEM_CLEAN=false
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -t 0 ]]; then
|
if [[ -t 0 ]]; then
|
||||||
echo -ne "${BLUE}System cleanup? Password to include (Enter skips)${NC}\n${BLUE}> ${NC}"; read -s password; echo ""
|
echo ""
|
||||||
|
echo -ne "${BLUE}System cleanup? ${GRAY}Enter to continue, any key to skip${NC} "
|
||||||
|
|
||||||
if [[ -n "$password" ]] && echo "$password" | sudo -S true 2>/dev/null; then
|
# Use IFS= and read without -n to allow Ctrl+C to work properly
|
||||||
|
IFS= read -r -s -n 1 choice
|
||||||
|
local read_status=$?
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# If read was interrupted (Ctrl+C), exit cleanly
|
||||||
|
if [[ $read_status -ne 0 ]]; then
|
||||||
|
exit 130
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Enter or y = yes, do system cleanup
|
||||||
|
if [[ -z "$choice" ]] || [[ "$choice" == $'\n' ]] || [[ "$choice" =~ ^[Yy]$ ]]; then
|
||||||
|
echo ""
|
||||||
|
if request_sudo_access "System cleanup requires admin access"; then
|
||||||
SYSTEM_CLEAN=true
|
SYSTEM_CLEAN=true
|
||||||
|
echo -e "${GREEN}✓ Admin access granted${NC}"
|
||||||
# Start sudo keepalive with error handling
|
# Start sudo keepalive with error handling
|
||||||
(
|
(
|
||||||
local retry_count=0
|
local retry_count=0
|
||||||
@@ -324,15 +375,19 @@ start_cleanup() {
|
|||||||
SUDO_KEEPALIVE_PID=$!
|
SUDO_KEEPALIVE_PID=$!
|
||||||
else
|
else
|
||||||
SYSTEM_CLEAN=false
|
SYSTEM_CLEAN=false
|
||||||
if [[ -n "$password" ]]; then
|
|
||||||
echo ""
|
echo ""
|
||||||
echo -e "${YELLOW}⚠️ Invalid password, continuing with user-level cleanup${NC}"
|
echo -e "${YELLOW}Authentication failed, continuing with user-level cleanup${NC}"
|
||||||
fi
|
fi
|
||||||
|
else
|
||||||
|
# Any other key = no system cleanup
|
||||||
|
SYSTEM_CLEAN=false
|
||||||
|
echo ""
|
||||||
|
echo -e "Skipped system cleanup, user-level only"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
SYSTEM_CLEAN=false
|
SYSTEM_CLEAN=false
|
||||||
echo ""
|
echo ""
|
||||||
echo -e "${BLUE}ℹ${NC} Running in non-interactive mode"
|
echo -e " Running in non-interactive mode"
|
||||||
echo " • System-level cleanup skipped (requires interaction)"
|
echo " • System-level cleanup skipped (requires interaction)"
|
||||||
echo " • User-level cleanup will proceed automatically"
|
echo " • User-level cleanup will proceed automatically"
|
||||||
echo ""
|
echo ""
|
||||||
@@ -341,7 +396,7 @@ start_cleanup() {
|
|||||||
|
|
||||||
perform_cleanup() {
|
perform_cleanup() {
|
||||||
echo ""
|
echo ""
|
||||||
echo "🍎 $(detect_architecture) | 💾 Free space: $(get_free_space)"
|
echo "$(detect_architecture) | Free space: $(get_free_space)"
|
||||||
|
|
||||||
# Get initial space
|
# Get initial space
|
||||||
space_before=$(df / | tail -1 | awk '{print $4}')
|
space_before=$(df / | tail -1 | awk '{print $4}')
|
||||||
@@ -1248,8 +1303,8 @@ perform_cleanup() {
|
|||||||
if [[ -n "${backup_kb:-}" && "$backup_kb" -gt 102400 ]]; then
|
if [[ -n "${backup_kb:-}" && "$backup_kb" -gt 102400 ]]; then
|
||||||
backup_human=$(du -sh "$backup_dir" 2>/dev/null | awk '{print $1}')
|
backup_human=$(du -sh "$backup_dir" 2>/dev/null | awk '{print $1}')
|
||||||
note_activity
|
note_activity
|
||||||
echo -e " ${BLUE}💾${NC} Found ${GREEN}${backup_human}${NC} iOS backups"
|
echo -e " Found ${GREEN}${backup_human}${NC} iOS backups"
|
||||||
echo -e " ${YELLOW}💡${NC} You can delete them manually: ${backup_dir}"
|
echo -e " You can delete them manually: ${backup_dir}"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
end_section
|
end_section
|
||||||
@@ -1261,41 +1316,41 @@ perform_cleanup() {
|
|||||||
echo ""
|
echo ""
|
||||||
echo "===================================================================="
|
echo "===================================================================="
|
||||||
if [[ "$DRY_RUN" == "true" ]]; then
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
echo "🧪 DRY RUN COMPLETE!"
|
echo "DRY RUN COMPLETE!"
|
||||||
else
|
else
|
||||||
echo "🎉 CLEANUP COMPLETE!"
|
echo "CLEANUP COMPLETE!"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $total_size_cleaned -gt 0 ]]; then
|
if [[ $total_size_cleaned -gt 0 ]]; then
|
||||||
local freed_gb=$(echo "$total_size_cleaned" | awk '{printf "%.2f", $1/1024/1024}')
|
local freed_gb=$(echo "$total_size_cleaned" | awk '{printf "%.2f", $1/1024/1024}')
|
||||||
if [[ "$DRY_RUN" == "true" ]]; then
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
echo "💾 Potential reclaimable space: ${GREEN}${freed_gb}GB${NC} (no changes made) | Free space now: $(get_free_space)"
|
echo "Potential reclaimable space: ${GREEN}${freed_gb}GB${NC} (no changes made) | Free space now: $(get_free_space)"
|
||||||
else
|
else
|
||||||
echo "💾 Space freed: ${GREEN}${freed_gb}GB${NC} | Free space now: $(get_free_space)"
|
echo "Space freed: ${GREEN}${freed_gb}GB${NC} | Free space now: $(get_free_space)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$DRY_RUN" != "true" ]]; then
|
if [[ "$DRY_RUN" != "true" ]]; then
|
||||||
if [[ $(echo "$freed_gb" | awk '{print ($1 >= 1) ? 1 : 0}') -eq 1 ]]; then
|
if [[ $(echo "$freed_gb" | awk '{print ($1 >= 1) ? 1 : 0}') -eq 1 ]]; then
|
||||||
local movies=$(echo "$freed_gb" | awk '{printf "%.0f", $1/4.5}')
|
local movies=$(echo "$freed_gb" | awk '{printf "%.0f", $1/4.5}')
|
||||||
if [[ $movies -gt 0 ]]; then
|
if [[ $movies -gt 0 ]]; then
|
||||||
echo "🎬 That's like ~$movies 4K movies worth of space!"
|
echo "That's like ~$movies 4K movies worth of space!"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if [[ "$DRY_RUN" == "true" ]]; then
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||||||
echo "💾 No significant reclaimable space detected (already clean) | Free space: $(get_free_space)"
|
echo "No significant reclaimable space detected (already clean) | Free space: $(get_free_space)"
|
||||||
else
|
else
|
||||||
echo "💾 No significant space was freed (system was already clean) | Free space: $(get_free_space)"
|
echo "No significant space was freed (system was already clean) | Free space: $(get_free_space)"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $files_cleaned -gt 0 && $total_items -gt 0 ]]; then
|
if [[ $files_cleaned -gt 0 && $total_items -gt 0 ]]; then
|
||||||
printf "📊 Files cleaned: %s | Categories processed: %s\n" "$files_cleaned" "$total_items"
|
printf "Files cleaned: %s | Categories processed: %s\n" "$files_cleaned" "$total_items"
|
||||||
elif [[ $files_cleaned -gt 0 ]]; then
|
elif [[ $files_cleaned -gt 0 ]]; then
|
||||||
printf "📊 Files cleaned: %s\n" "$files_cleaned"
|
printf "Files cleaned: %s\n" "$files_cleaned"
|
||||||
elif [[ $total_items -gt 0 ]]; then
|
elif [[ $total_items -gt 0 ]]; then
|
||||||
printf "🗂️ Categories processed: %s\n" "$total_items"
|
printf "Categories processed: %s\n" "$total_items"
|
||||||
fi
|
fi
|
||||||
printf "====================================================================\n"
|
printf "====================================================================\n"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ log_success() {
|
|||||||
|
|
||||||
log_warning() {
|
log_warning() {
|
||||||
rotate_log
|
rotate_log
|
||||||
echo -e "${YELLOW}⚠️ $1${NC}"
|
echo -e "${YELLOW}$1${NC}"
|
||||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] WARNING: $1" >> "$LOG_FILE" 2>/dev/null || true
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] WARNING: $1" >> "$LOG_FILE" 2>/dev/null || true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,6 +254,48 @@ check_sudo() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Check if Touch ID is configured for sudo
|
||||||
|
check_touchid_support() {
|
||||||
|
if [[ -f /etc/pam.d/sudo ]]; then
|
||||||
|
grep -q "pam_tid.so" /etc/pam.d/sudo 2>/dev/null
|
||||||
|
return $?
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Request sudo access with Touch ID support
|
||||||
|
# Usage: request_sudo_access "prompt message" [optional: force_password]
|
||||||
|
request_sudo_access() {
|
||||||
|
local prompt_msg="${1:-Admin access required}"
|
||||||
|
local force_password="${2:-false}"
|
||||||
|
|
||||||
|
# Check if already has sudo access
|
||||||
|
if sudo -n true 2>/dev/null; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If Touch ID is supported and not forced to use password
|
||||||
|
if [[ "$force_password" != "true" ]] && check_touchid_support; then
|
||||||
|
echo -e "${BLUE}${prompt_msg}${NC} ${GRAY}(Touch ID or password)${NC}"
|
||||||
|
if sudo -v 2>/dev/null; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# Traditional password method
|
||||||
|
echo -e "${BLUE}${prompt_msg}${NC}"
|
||||||
|
echo -ne "${BLUE} Password> ${NC}"
|
||||||
|
read -s password
|
||||||
|
echo ""
|
||||||
|
if [[ -n "$password" ]] && echo "$password" | sudo -S true 2>/dev/null; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
request_sudo() {
|
request_sudo() {
|
||||||
echo "This operation requires administrator privileges."
|
echo "This operation requires administrator privileges."
|
||||||
echo -n "Please enter your password: "
|
echo -n "Please enter your password: "
|
||||||
@@ -564,7 +606,7 @@ print_space_stat() {
|
|||||||
current_free=$(get_free_space)
|
current_free=$(get_free_space)
|
||||||
local human
|
local human
|
||||||
human=$(bytes_to_human_kb "$freed_kb")
|
human=$(bytes_to_human_kb "$freed_kb")
|
||||||
echo "💾 Space freed: ${GREEN}${human}${NC} | Free space now: $current_free"
|
echo "Space freed: ${GREEN}${human}${NC} | Free space now: $current_free"
|
||||||
}
|
}
|
||||||
|
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user