4 Commits

Author SHA1 Message Date
librelad
655dbc2bb9 fix(install): restore webui_logins container-group after credential write
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>
2026-06-21 23:00:47 +01:00
librelad
8b14f26125 refactor(desudo): route scattered runtime sudo through privilege helpers
Convert the remaining ad-hoc 'sudo' calls across the data plane to the
run_privileged helpers so every file op lands as the correct owner with
no blanket root:

- DB/configs (manager-owned): db_list_all_apps, delete_db_file,
  install_sqlite, cli_webui_commands -> runInstallOp
- containers (dockerinstall-owned): scan_container_socket, delete_data,
  webui_task_files, webui_app_log, webui_config_patch,
  application_missing_variables, uninstall_app -> runFileOp/runFileWrite
- genuine root: passwd, tailscale, ufw-docker, sysctl grep, systemd
  unit read, authorized_keys read, nobody chown -> runSystem
- interactive editors and 'id -u': drop sudo entirely (run as caller)
- owncloud/adguard container-UID config edits -> runSystem (funnel;
  docker-exec rework deferred)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-24 18:00:19 +01:00
librelad
d6e7df8ada refactor(backup): move location field schema to a generated JSON
The per-type field map lived hardcoded in backup-page.js. Add a
webuiGenerateBackupSchema generator that emits the type -> ordered field list
to data/backup/generated/schema.json (wired into the backup regen chain and
the CLI 'webui generate backup'). The editor fetches it into this.locSchema
and reads it via locFieldsForType; BACKUP_LOC_FIELDS_BY_TYPE stays only as a
fallback if the fetch fails.

Keeps the data-in-generators pattern consistent — the schema now has one
backend source of truth. The dynamic show/hide behaviors (SSH auth, path
mode, engine filtering) remain frontend logic by nature.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-23 15:22:53 +01:00
librelad
875a60f90f LibrePortal v0.1.0 — initial release
A free, open, self-hosted app platform (GNU AGPLv3): one-click app deploys,
Traefik reverse proxy with automatic SSL, rootless Docker support, gluetun
VPN routing, and a web dashboard to manage it all.

Free & open forever to self-host; optional paid hosted services fund it.
See PROMISE.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-21 20:37:54 +01:00