#!/bin/bash setupApplyConfig() { local payload_b64="$1" if [[ -z "$payload_b64" ]]; then isError "setupApplyConfig: no payload provided" return 1 fi local payload payload=$(echo "$payload_b64" | base64 -d 2>/dev/null) if [[ -z "$payload" ]]; then isError "setupApplyConfig: failed to decode payload" return 1 fi isHeader "Applying Setup Wizard Configuration" local install_name=$(echo "$payload" | jq -r '.install_name // empty') local timezone=$(echo "$payload" | jq -r '.timezone // empty') local install_level=$(echo "$payload" | jq -r '.install_level // empty') local traefik_email=$(echo "$payload" | jq -r '.traefik_email // empty') local domains_json=$(echo "$payload" | jq -c '.domains // []') if [[ -n "$install_name" ]]; then updateConfigOption "CFG_INSTALL_NAME" "$install_name" isSuccessful "Install name set to '$install_name'" fi if [[ -n "$timezone" ]]; then updateConfigOption "CFG_TIMEZONE" "$timezone" isSuccessful "Timezone set to '$timezone'" fi # Experience level — seeds the WebUI's Advanced UI mode on first paint # so a Beginner gets a stripped-down view and an Advanced user sees # everything by default. The WebUI also exposes a per-browser toggle # that overrides this; we just provide the install-time default. if [[ "$install_level" == "beginner" || "$install_level" == "advanced" ]]; then updateConfigOption "CFG_INSTALL_LEVEL" "$install_level" isSuccessful "Experience level set to '$install_level'" fi local domains_count=$(echo "$domains_json" | jq -r 'length') if [[ "$domains_count" -gt 0 ]]; then local i=0 while [[ $i -lt $domains_count && $i -lt 9 ]]; do local d=$(echo "$domains_json" | jq -r ".[$i]") updateConfigOption "CFG_DOMAIN_$((i+1))" "$d" isSuccessful "Domain $((i+1)) set to '$d'" ((i++)) done fi if [[ -n "$traefik_email" && "$traefik_email" != "null" ]]; then # CFG_TRAEFIK_EMAIL lives in containers/traefik/traefik.config, not in # the system $configs_dir, so findConfigFileForOption can't auto-locate # it. Point updateConfigOption at the source file directly. Traefik # may not be installed yet at this point — config gets copied from # install_containers_dir into containers_dir during the app-install # task, so we always update the source. local traefik_config_file="$install_containers_dir/traefik/traefik.config" if [[ -f "$traefik_config_file" ]]; then updateConfigOption "CFG_TRAEFIK_EMAIL" "$traefik_email" "$traefik_config_file" isSuccessful "Traefik LetsEncrypt email set to '$traefik_email'" else isNotice "Traefik source config not found at $traefik_config_file; skipping email write." fi fi # App sub-options are no longer handled here. The setup-routes backend # folds payload.appOptions into each install command's config_variables # arg (CFG_REQUIREMENT__=) and dockerInstallApp writes # them into the template config before install runs. sourceScanFiles "libreportal_configs" isSuccessful "Configuration written. Selected apps will install next." } setupApplyFinalize() { isNotice "Initializing backup engine..." if declare -f installResticHost >/dev/null 2>&1; then installResticHost else isNotice "installResticHost not loaded; backup repos will init on first backup." fi isNotice "Refreshing WebUI data snapshots so the config page reflects wizard changes..." if declare -f webuiLibrePortalUpdate >/dev/null 2>&1; then webuiLibrePortalUpdate else isNotice "webuiLibrePortalUpdate not loaded; skipping refresh." fi if declare -f webuiGenerateBackupLocations >/dev/null 2>&1; then webuiGenerateBackupLocations webuiGenerateBackupDashboard webuiGenerateBackupSnapshots all webuiGenerateBackupAppStatus fi setupWizardMarkComplete isSuccessful "Setup Wizard complete — your install is configured and ready." } setupApply() { setupApplyConfig "$1" || return 1 local payload=$(echo "$1" | base64 -d 2>/dev/null) local apps_json=$(echo "$payload" | jq -c '.apps // []') local apps_count=$(echo "$apps_json" | jq -r 'length') if [[ "$apps_count" -gt 0 ]]; then isHeader "Installing Selected Apps" local i=0 while [[ $i -lt $apps_count ]]; do local app_name=$(echo "$apps_json" | jq -r ".[$i]") isNotice "[$((i+1))/$apps_count] Installing $app_name..." dockerInstallApp "$app_name" ((i++)) done fi setupApplyFinalize } setupGenerateName() { if declare -f generateInstallName >/dev/null 2>&1; then generateInstallName else echo "QuantumOtter" fi } setupCheckDomainPointsHere() { local domain="$1" if [[ -z "$domain" ]]; then echo '{"matches":false,"error":"no domain"}' return 1 fi local server_ip server_ip=$(dig +short +time=3 +tries=1 myip.opendns.com @resolver1.opendns.com 2>/dev/null | head -1) [[ -z "$server_ip" ]] && server_ip=$(hostname -I 2>/dev/null | awk '{print $1}') local domain_ip domain_ip=$(dig +short +time=3 +tries=1 "$domain" A 2>/dev/null | head -1) local matches="false" [[ -n "$server_ip" && "$server_ip" == "$domain_ip" ]] && matches="true" printf '{"matches":%s,"server_ip":"%s","domain_ip":"%s"}\n' "$matches" "$server_ip" "$domain_ip" }