diff --git a/scripts/03_generate_secrets.sh b/scripts/03_generate_secrets.sh index 3cad899..8211a55 100644 --- a/scripts/03_generate_secrets.sh +++ b/scripts/03_generate_secrets.sh @@ -98,6 +98,7 @@ if ! command -v caddy &> /dev/null; then exit 1 fi +require_whiptail # Prompt for the domain name DOMAIN="" # Initialize DOMAIN variable @@ -110,73 +111,52 @@ if [[ -v existing_env_vars[USER_DOMAIN_NAME] && -n "${existing_env_vars[USER_DOM generated_values["USER_DOMAIN_NAME"]="$DOMAIN" else while true; do - echo "" - prompt_text="Enter the primary domain name for your services (e.g., example.com): " # Simplified prompt - read -p "$prompt_text" DOMAIN_INPUT + DOMAIN_INPUT=$(wt_input "Primary Domain" "Enter the primary domain name for your services (e.g., example.com)." "") || true DOMAIN_TO_USE="$DOMAIN_INPUT" # Direct assignment, no default fallback # Validate domain input if [[ -z "$DOMAIN_TO_USE" ]]; then - log_error "Domain name cannot be empty. This field is mandatory." >&2 # Clarified error - continue # Ask again + wt_msg "Validation" "Domain name cannot be empty." + continue fi # Basic check for likely invalid domain characters (very permissive) if [[ "$DOMAIN_TO_USE" =~ [^a-zA-Z0-9.-] ]]; then - log_warning "Warning: Domain name contains potentially invalid characters: '$DOMAIN_TO_USE'" >&2 + wt_msg "Validation" "Warning: Domain contains potentially invalid characters: '$DOMAIN_TO_USE'" fi - - echo "" - read -p "Are you sure '$DOMAIN_TO_USE' is correct? (y/N): " confirm_domain - if [[ "$confirm_domain" =~ ^[Yy]$ ]]; then + if wt_yesno "Confirm Domain" "Use '$DOMAIN_TO_USE' as the primary domain?" "no"; then DOMAIN="$DOMAIN_TO_USE" # Set the final DOMAIN variable generated_values["USER_DOMAIN_NAME"]="$DOMAIN" # Using USER_DOMAIN_NAME log_info "Domain set to '$DOMAIN'. It will be saved in .env." break # Confirmed, exit loop - else - log_info "Please try entering the domain name again." - # No default domain suggestion to retry with. fi done fi # Prompt for user email if [[ -z "${existing_env_vars[LETSENCRYPT_EMAIL]}" ]]; then - echo "" - echo "Please enter your email address. This email will be used for:" - echo " - Login to Flowise" - echo " - Login to Supabase" - echo " - Login to SearXNG" - echo " - Login to Grafana" - echo " - Login to Prometheus" - echo " - SSL certificate generation with Let\'s Encrypt" + wt_msg "Email Required" "Please enter your email address. It will be used for logins and Let's Encrypt SSL." fi if [[ -n "${existing_env_vars[LETSENCRYPT_EMAIL]}" ]]; then USER_EMAIL="${existing_env_vars[LETSENCRYPT_EMAIL]}" else while true; do - echo "" - read -p "Email: " USER_EMAIL + USER_EMAIL=$(wt_input "Email" "Enter your email address." "") || true # Validate email input if [[ -z "$USER_EMAIL" ]]; then - log_error "Email cannot be empty." >&2 - continue # Ask again + wt_msg "Validation" "Email cannot be empty." + continue fi # Basic email format validation if [[ ! "$USER_EMAIL" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then - log_warning "Warning: Email format appears to be invalid: '$USER_EMAIL'" >&2 + wt_msg "Validation" "Warning: Email format appears to be invalid: '$USER_EMAIL'" fi - - echo "" - read -p "Are you sure '$USER_EMAIL' is correct? (y/N): " confirm_email - if [[ "$confirm_email" =~ ^[Yy]$ ]]; then + if wt_yesno "Confirm Email" "Use '$USER_EMAIL' as your email?" "no"; then break # Confirmed, exit loop - else - log_info "Please try entering the email address again." fi done fi diff --git a/scripts/05_configure_services.sh b/scripts/05_configure_services.sh index 1d19a54..f6a397c 100644 --- a/scripts/05_configure_services.sh +++ b/scripts/05_configure_services.sh @@ -44,13 +44,8 @@ log_info "Configuring service options in .env..." EXISTING_OPENAI_API_KEY="$(read_env_var OPENAI_API_KEY)" OPENAI_API_KEY="" if [[ -z "$EXISTING_OPENAI_API_KEY" ]]; then - echo "" - echo "OpenAI API Key (optional). This key will be used for:" - echo " - Supabase: AI services to help with writing SQL queries, statements, and policies" - echo " - Crawl4AI: Default LLM configuration for web crawling capabilities" - echo " You can skip this by leaving it empty." - echo "" - read -p "OpenAI API Key: " OPENAI_API_KEY + require_whiptail + OPENAI_API_KEY=$(wt_input "OpenAI API Key" "Optional: Used by Supabase AI (SQL assistance) and Crawl4AI. Leave empty to skip." "") || true if [[ -n "$OPENAI_API_KEY" ]]; then write_env_var "OPENAI_API_KEY" "$OPENAI_API_KEY" fi @@ -64,13 +59,8 @@ fi # Logic for n8n workflow import (RUN_N8N_IMPORT) # ---------------------------------------------------------------- final_run_n8n_import_decision="false" - -echo "" -echo "Do you want to import 300 ready-made workflows for n8n? This process may take about 30 minutes to complete." -echo "" -read -p "Import workflows? (y/n): " import_workflow_choice - -if [[ "$import_workflow_choice" =~ ^[Yy]$ ]]; then +require_whiptail +if wt_yesno "Import n8n Workflows" "Import ~300 ready-made n8n workflows now? This can take ~30 minutes." "no"; then final_run_n8n_import_decision="true" else final_run_n8n_import_decision="false" @@ -86,24 +76,22 @@ write_env_var "RUN_N8N_IMPORT" "$final_run_n8n_import_decision" echo "" # Add a newline for better formatting log_info "Configuring n8n worker count..." EXISTING_N8N_WORKER_COUNT="$(read_env_var N8N_WORKER_COUNT)" +require_whiptail if [[ -n "$EXISTING_N8N_WORKER_COUNT" ]]; then N8N_WORKER_COUNT_CURRENT="$EXISTING_N8N_WORKER_COUNT" - echo "" - read -p "Do you want to change the number of n8n workers? Current: $N8N_WORKER_COUNT_CURRENT. (Enter new number, or press Enter to keep current): " N8N_WORKER_COUNT_INPUT_RAW + N8N_WORKER_COUNT_INPUT_RAW=$(wt_input "n8n Workers (instances)" "Enter new number of n8n workers, or leave as current ($N8N_WORKER_COUNT_CURRENT)." "") || true if [[ -z "$N8N_WORKER_COUNT_INPUT_RAW" ]]; then N8N_WORKER_COUNT="$N8N_WORKER_COUNT_CURRENT" else if [[ "$N8N_WORKER_COUNT_INPUT_RAW" =~ ^0*[1-9][0-9]*$ ]]; then N8N_WORKER_COUNT_TEMP="$((10#$N8N_WORKER_COUNT_INPUT_RAW))" if [[ "$N8N_WORKER_COUNT_TEMP" -ge 1 ]]; then - echo "" - read -p "Update n8n workers to $N8N_WORKER_COUNT_TEMP? (y/N): " confirm_change - if [[ "$confirm_change" =~ ^[Yy]$ ]]; then + if wt_yesno "Confirm Workers" "Update n8n workers to $N8N_WORKER_COUNT_TEMP?" "no"; then N8N_WORKER_COUNT="$N8N_WORKER_COUNT_TEMP" - else + else N8N_WORKER_COUNT="$N8N_WORKER_COUNT_CURRENT" log_info "Change declined. Keeping N8N_WORKER_COUNT at $N8N_WORKER_COUNT." - fi + fi else log_warning "Invalid input '$N8N_WORKER_COUNT_INPUT_RAW'. Number must be positive. Keeping $N8N_WORKER_COUNT_CURRENT." N8N_WORKER_COUNT="$N8N_WORKER_COUNT_CURRENT" @@ -115,20 +103,14 @@ if [[ -n "$EXISTING_N8N_WORKER_COUNT" ]]; then fi else while true; do - echo "" - read -p "Enter the number of n8n workers to run (e.g., 1, 2, 3; default is 1): " N8N_WORKER_COUNT_INPUT_RAW + N8N_WORKER_COUNT_INPUT_RAW=$(wt_input "n8n Workers" "Enter number of n8n workers to run (default 1)." "1") || true N8N_WORKER_COUNT_CANDIDATE="${N8N_WORKER_COUNT_INPUT_RAW:-1}" - if [[ "$N8N_WORKER_COUNT_CANDIDATE" =~ ^0*[1-9][0-9]*$ ]]; then N8N_WORKER_COUNT_VALIDATED="$((10#$N8N_WORKER_COUNT_CANDIDATE))" if [[ "$N8N_WORKER_COUNT_VALIDATED" -ge 1 ]]; then - echo "" - read -p "Run $N8N_WORKER_COUNT_VALIDATED n8n worker(s)? (y/N): " confirm_workers - if [[ "$confirm_workers" =~ ^[Yy]$ ]]; then + if wt_yesno "Confirm Workers" "Run $N8N_WORKER_COUNT_VALIDATED n8n worker(s)?" "no"; then N8N_WORKER_COUNT="$N8N_WORKER_COUNT_VALIDATED" break - else - log_info "Please try entering the number of workers again." fi else log_error "Number of workers must be a positive integer." >&2 @@ -165,9 +147,8 @@ if [ $cloudflare_selected -eq 1 ]; then log_info "Cloudflare Tunnel token found in .env; reusing it." # Do not prompt; keep existing token as-is else - log_info "Cloudflare Tunnel selected. Please provide your Cloudflare Tunnel token." - echo "" - read -p "Cloudflare Tunnel Token: " input_cf_token + require_whiptail + input_cf_token=$(wt_input "Cloudflare Tunnel Token" "Enter your Cloudflare Tunnel token (leave empty to skip)." "") || true token_to_write="$input_cf_token" # Update the .env with the token (may be empty if user skipped) @@ -187,6 +168,25 @@ if [ $cloudflare_selected -eq 1 ]; then fi +# ---------------------------------------------------------------- +# Safety: If Supabase is present, remove Dify from COMPOSE_PROFILES (no prompts) +# ---------------------------------------------------------------- +if [[ -n "$COMPOSE_PROFILES_VALUE" && "$COMPOSE_PROFILES_VALUE" == *"supabase"* ]]; then + IFS=',' read -r -a profiles_array <<< "$COMPOSE_PROFILES_VALUE" + new_profiles=() + for p in "${profiles_array[@]}"; do + if [[ "$p" != "dify" ]]; then + new_profiles+=("$p") + fi + done + COMPOSE_PROFILES_VALUE_UPDATED=$(IFS=','; echo "${new_profiles[*]}") + if [[ "$COMPOSE_PROFILES_VALUE_UPDATED" != "$COMPOSE_PROFILES_VALUE" ]]; then + write_env_var "COMPOSE_PROFILES" "$COMPOSE_PROFILES_VALUE_UPDATED" + log_info "Supabase present: removed 'dify' from COMPOSE_PROFILES due to conflict with Supabase." + COMPOSE_PROFILES_VALUE="$COMPOSE_PROFILES_VALUE_UPDATED" + fi +fi + # ---------------------------------------------------------------- # Ensure Supabase Analytics targets the correct Postgres service name used by Supabase docker compose # ---------------------------------------------------------------- diff --git a/scripts/utils.sh b/scripts/utils.sh index e9fbfbe..6e2a57c 100644 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -49,3 +49,64 @@ log_info() { local combined_message="[INFO] ${timestamp}: ${message}" log_message "${combined_message}" } + +# --- Whiptail helpers --- +# Ensure whiptail is available +require_whiptail() { + if ! command -v whiptail >/dev/null 2>&1; then + log_error "'whiptail' is not installed. Install with: sudo apt-get install -y whiptail" + exit 1 + fi +} + +# Input box. Usage: wt_input "Title" "Prompt" "default" +# Echoes the input on success; returns 0 on OK, 1 on Cancel +wt_input() { + local title="$1" + local prompt="$2" + local default_value="$3" + local result + result=$(whiptail --title "$title" --inputbox "$prompt" 15 80 "$default_value" 3>&1 1>&2 2>&3) + local status=$? + if [ $status -ne 0 ]; then + return 1 + fi + echo "$result" + return 0 +} + +# Password box. Usage: wt_password "Title" "Prompt" +# Echoes the input on success; returns 0 on OK, 1 on Cancel +wt_password() { + local title="$1" + local prompt="$2" + local result + result=$(whiptail --title "$title" --passwordbox "$prompt" 15 80 3>&1 1>&2 2>&3) + local status=$? + if [ $status -ne 0 ]; then + return 1 + fi + echo "$result" + return 0 +} + +# Yes/No box. Usage: wt_yesno "Title" "Prompt" "default" (default: yes|no) +# Returns 0 for Yes, 1 for No/Cancel +wt_yesno() { + local title="$1" + local prompt="$2" + local default_choice="$3" + if [ "$default_choice" = "yes" ]; then + whiptail --title "$title" --yesno "$prompt" 10 80 + else + whiptail --title "$title" --defaultno --yesno "$prompt" 10 80 + fi +} + +# Message box. Usage: wt_msg "Title" "Message" +wt_msg() { + local title="$1" + local message="$2" + whiptail --title "$title" --msgbox "$message" 10 80 +} +