The rootless WebUI container reads its bind-mount sources (configs/webui/*) through the container-owner GROUP since a2376e2 switched those files from world-readable to 0640 group=container-owner. But the WebUI credential randomizer rewrites webui_logins via `sed -i` as the non-root manager, which recreates the file with the manager's own group — dropping the container-owner group. The installer then started the container immediately, so node hit EACCES on /app/webui_logins at require-time (parseConfigFile) and exited 1; nothing listened on the WebUI port. `libreportal webui login reset` had the same latent bug (rewrite → restart). Under the old world-readable model a post-sed file stayed o+r so the container could still read it, which is why this only surfaced on fresh rootless installs after a2376e2. Fix: make reconcileWebuiDirOwnership the single "ready the WebUI for its container" pass — it now also restores the configs/webui bind access (new `webui-bind` ownership action) on top of the container-dir chown. Reorder the installer so the credential randomizer runs BEFORE the before-start permission pass, making that pass the last ownership touch before the container starts; and call reconcileWebuiDirOwnership before the restart in login reset. Live box recovered via `libreportal-ownership reconcile`; WebUI 200. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
114 lines
4.0 KiB
Bash
Executable File
114 lines
4.0 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# WebUI Commands Handler
|
|
# Handles all webui subcommands by calling core functions
|
|
|
|
cliHandleWebuiCommands()
|
|
{
|
|
local action="$initial_command2"
|
|
local config_type="$initial_command3"
|
|
local options="$initial_command4"
|
|
|
|
if [[ -z "$action" ]]; then
|
|
cliShowWebuiHelp
|
|
fi
|
|
|
|
case "$action" in
|
|
"generate")
|
|
if [[ -z "$config_type" ]]; then
|
|
isNotice "Generate option required. Use: backup [source] or config [options]"
|
|
cliShowWebuiHelp
|
|
elif [ "$config_type" = "backup" ]; then
|
|
webuiGenerateBackupLocations
|
|
webuiGenerateBackupDashboard
|
|
webuiGenerateBackupSnapshots "${options:-all}"
|
|
webuiGenerateBackupAppStatus
|
|
webuiGenerateBackupSchema
|
|
webuiGenerateBackupPasswords
|
|
elif [ "$config_type" = "system" ]; then
|
|
webuiSystemUpdate
|
|
elif [ "$config_type" = "config" ]; then
|
|
webuiGenerateSystemConfigs
|
|
elif [ "$config_type" = "all" ]; then
|
|
webuiLibrePortalUpdate
|
|
else
|
|
isNotice "Invalid generate option: $config_type. Use: backup, system, config, or all"
|
|
cliShowWebuiHelp
|
|
fi
|
|
;;
|
|
"service")
|
|
installLibrePortalWebUITaskService;
|
|
;;
|
|
"login")
|
|
case "$config_type" in
|
|
"show")
|
|
sourceScanFiles "libreportal_configs"
|
|
if [[ -z "$CFG_WEBUI_USERNAME" || -z "$CFG_WEBUI_PASSWORD" ]]; then
|
|
isError "WebUI credentials not found. Run 'libreportal webui login reset' to generate."
|
|
return 1
|
|
fi
|
|
webuiDisplayLogins "show"
|
|
;;
|
|
"reset"|"recover")
|
|
cliWebuiLoginReset
|
|
;;
|
|
*)
|
|
isNotice "Invalid login action: $config_type. Use: show, reset"
|
|
cliShowWebuiHelp
|
|
;;
|
|
esac
|
|
;;
|
|
"recover")
|
|
isNotice "'libreportal webui recover' is deprecated — use 'libreportal webui login reset'."
|
|
cliWebuiLoginReset
|
|
;;
|
|
*)
|
|
isNotice "Invalid webui action: $action"
|
|
cliShowWebuiHelp
|
|
;;
|
|
esac
|
|
}
|
|
|
|
cliWebuiLoginReset()
|
|
{
|
|
local auth_file="$containers_dir/libreportal/frontend/.auth.json"
|
|
local webui_logins_file="$configs_dir/webui/webui_logins"
|
|
|
|
isNotice "Resetting WebUI credentials..."
|
|
|
|
# Restore placeholders so the scan re-randomizes them
|
|
if [ -f "$webui_logins_file" ]; then
|
|
runInstallOp sed -i -E 's/^(CFG_WEBUI_USERNAME=).*$/\1RANDOMIZEDUSERNAME1/' "$webui_logins_file"
|
|
runInstallOp sed -i -E 's/^(CFG_WEBUI_PASSWORD=).*$/\1RANDOMIZEDPASSWORD1/' "$webui_logins_file"
|
|
fi
|
|
|
|
# Remove auth file to force credential regeneration on next container start
|
|
if [ -f "$auth_file" ]; then
|
|
rm -f "$auth_file"
|
|
isSuccessful "Removed WebUI auth file."
|
|
fi
|
|
|
|
# Re-randomize credentials in webui_logins
|
|
scanFileForRandomPasswordKeysUsers "$webui_logins_file"
|
|
sourceScanFiles "libreportal_configs"
|
|
isSuccessful "WebUI credentials have been reset."
|
|
|
|
# Regenerate all WebUI config files
|
|
isNotice "Regenerating WebUI config files..."
|
|
webuiLibrePortalUpdate
|
|
|
|
# The credential rewrite above ran as the non-root manager, which resets
|
|
# webui_logins' group and drops the container-owner group the rootless WebUI
|
|
# reads it through. Restore it before restarting, or the container can't read
|
|
# its own login file and exits on boot.
|
|
reconcileWebuiDirOwnership
|
|
|
|
# Restart the libreportal container so it picks up the new credentials
|
|
isNotice "Restarting LibrePortal container..."
|
|
dockerComposeRestart libreportal
|
|
isSuccessful "LibrePortal container restarted."
|
|
|
|
# Display the new credentials
|
|
webuiDisplayLogins "reset"
|
|
}
|