feat(matrix): user-management tools, and stop shipping a file named *.config

Five Tools-tab actions backed by Synapse's admin API: create account, list
users, reset password, set admin, deactivate. All driven through
`docker exec matrix-synapse python` — the image has no curl, python is what
Synapse itself runs on, and talking to localhost:8008 means the tools work the
same LAN-only or behind Traefik and never depend on the published port.

Two Matrix facts are surfaced rather than hidden: a user ID is permanent, and
there is no delete — deactivation is terminal and burns the ID. The tool is
named "Deactivate" for that reason. Both destructive actions refuse to touch the
account the tools themselves authenticate as, which would otherwise lock the
Tools tab out of the server it manages.

The admin token is cached under data/. Logging in per invocation looked tidier
and was wrong: Synapse rate-limits /login, so a few tools in succession failed
with "Too Many Requests" — the tools were throttling themselves. One login,
reused, with a single re-login on 401 and a 429 retry that honours
retry_after_ms.

Also renames the Synapse logging config from log.config to log.yaml. The config
loader runs

    find "$containers_dir" -maxdepth 3 -type f -name '*.config'

and `source`s every match as bash. The file lands at <app>/data/log.yaml, which
is exactly depth 3, so under its old name EVERY libreportal command sourced a
YAML document as a shell script. It printed "command not found" per line and
took a CLI call from 1 second to 100. Only resources/ is pruned from that scan,
not data/ — so *.config is effectively a reserved extension anywhere under an
app directory, not just at its root.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
librelad 2026-08-18 21:25:29 +01:00
parent a96a3a69a1
commit ca7fca5007
2 changed files with 9 additions and 0 deletions

View File

@ -1,5 +1,13 @@
# Synapse logging configuration.
#
# Named .yaml and NOT .config, deliberately. LibrePortal's config loader does
# find "$containers_dir" -maxdepth 3 -type f -name '*.config'
# and `source`s every hit as bash. This file lands at
# <app>/data/log.yaml — exactly depth 3 — so calling it log.config made every
# single libreportal command source a YAML document as a shell script, spewing
# "command not found" for each line and slowing the CLI to a crawl.
# Only `resources/` is pruned from that scan; `data/` is not.
#
# Logs go to stdout only, so `docker logs matrix-synapse` and the LibrePortal
# log viewer both see them, and nothing accumulates inside the container that
# the host does not rotate.

View File

@ -2167,6 +2167,7 @@ LP_EAGER_FILES=(
"scripts:catalog/catalog_sources.sh"
"scripts:docker/install/rootless/rootless_apparmor.sh"
"scripts:docker/type_switcher/swap_docker_type.sh"
"containers:matrix/scripts/matrix_auth.sh"
"scripts:migrate/migrate_url_rewrite.sh"
"containers:nextcloud/scripts/nextcloud_upgrade_hooks.sh"
"scripts:setup/setup_lock.sh"