Tap the Advanced card 10 times and a full-width "Dev mode activated" strip slides in beneath the two cards — the same 10-tap pattern as the topbar logo and services-manager unlocks, now at install time. The choice rides the setup payload (dev_mode) so setup_apply.sh persists CFG_DEV_MODE=true, and it's mirrored in-process via LpUi.dev so the next surface already reflects it. 10 more taps toggles it back off. Counting the Advanced radio's click (not the label's) sidesteps the label->input double-fire; the radio is pointer-events:none, so each tap reaches it exactly once. The strip is [hidden] by default (no phantom gap in the flex column) and replays its entrance keyframes each reveal. Signed-off-by: librelad <librelad@digitalangels.vip>
168 lines
5.9 KiB
Bash
168 lines
5.9 KiB
Bash
#!/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 dev_mode=$(echo "$payload" | jq -r '.dev_mode // 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
|
|
|
|
# Developer mode — opt-in via the wizard's Advanced-card easter egg (10
|
|
# taps). Unlocks the **DEV**-marked CFG_* fields across the WebUI.
|
|
if [[ "$dev_mode" == "true" ]]; then
|
|
updateConfigOption "CFG_DEV_MODE" "true"
|
|
isSuccessful "Developer mode enabled"
|
|
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_<APP>_<OPT>=<bool>) and dockerInstallApp writes
|
|
# them into the template config before install<App> 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"
|
|
}
|