Compare commits

..

No commits in common. "e6c63af3391c0ab876a729a5af83923dd36d1880" and "a96a3a69a152c8e89d092d46bfcf4b8c87bd770c" have entirely different histories.

11 changed files with 0 additions and 328 deletions

View File

@ -17,17 +17,3 @@ lp-shot /admin/system /tmp/x.png 12 ".sys-strip" # just one element, crisp
Use it (and read the PNG) to self-check UI work instead of assuming it looks right or
asking the user to look. Skip it for purely backend/non-visual edits. If `lp-shot`
isn't present, fall back to asking the user for a screenshot.
Every route except `/` is behind the WebUI login, so `lp-shot` needs a session in
the environment — `LP_SHOT_TOKEN` (the `libreportal_token` cookie) or
`LP_SHOT_USER` + `LP_SHOT_PASS`. Without one it stops with that message rather
than screenshotting the sign-in box. Only the maintainer sets those: ask them to
export it (or to run the `lp-shot` command for you) — never go looking for the
credentials yourself. `lp-shot --help` lists the rest (`LP_SHOT_URL`,
`LP_SHOT_VIEWPORT`, `LP_SHOT_SCALE`, …).
Testing against the live WebUI means updating the running install, not just the
repo: `/libreportal-containers/libreportal/frontend/` is bind-mounted into the
container, so copying changed files there (owned `dockerinstall:dockerinstall`)
takes effect on the next browser load — no rebuild or restart. Diff before you
copy; the live tree can hold changes the repo doesn't.

View File

@ -1,13 +1,5 @@
# 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

@ -74,9 +74,3 @@ CFG_MATTERMOST_NETWORK=default
# - description: human-readable description of the service
#
CFG_MATTERMOST_PORT_1="mattermost-service|webui|random:8065|public|tcp|false|true|true|Web Interface||mattermost"
# AUTH_PROFILE = capability tier for the WebUI auth tools (single_password | user_password | multi_user)
CFG_MATTERMOST_AUTH_PROFILE=multi_user
# Email of the account the WebUI card advertises; set by whoever runs the setup
# wizard or the create-account tool, and kept in step by the reset-password tool.
CFG_MATTERMOST_ADMIN_EMAIL=

View File

@ -1,121 +0,0 @@
#!/bin/bash
# Mattermost user management, via mmctl in local mode.
#
# mmctl is the current CLI — not the long-deprecated `mattermost` binary that
# used to ship alongside it. It lives in the image at /usr/local/bin/mmctl and
# is the only reason these tools are possible at all: the v11 image is
# distroless, with no shell, so every call has to be a direct exec of a binary
# with no pipes, redirects or shell built-ins available.
#
# --local talks to the server's unix socket instead of the REST API, which means
# no credentials to store, no token to expire, and it keeps working even when
# the admin account is locked out or the site URL is wrong.
_mmctl() {
runFileOp docker exec -i mattermost-service mmctl --local "$@" 2>&1
}
# mmctl exits non-zero on failure and writes the reason to stderr, which _mmctl
# folds into stdout.
#
# Its errors are multi-line — a summary ("Error: 1 error occurred:") followed by
# an indented bullet carrying the part that actually explains anything. Reporting
# only the first line threw the useful half away, so prefer the bullet when
# there is one.
_mmctlFailed() {
local out="$1" what="$2"
[[ "$out" != *"Error:"* ]] && return 1
local detail
detail=$(printf '%s' "$out" | sed -n 's/^[[:space:]]*\*[[:space:]]*//p' | head -1)
[[ -z "$detail" ]] && detail=$(printf '%s' "$out" | grep -m1 'Error:' | sed 's/.*Error: *//')
isError "$what failed: $detail"
return 0
}
authAdapter_mattermost_createUser() {
local email="$1" password="$2" username="$3" isAdmin="$4"
[[ -z "$email" ]] && { isError "An email address is required."; return 1; }
[[ -z "$username" ]] && username="${email%@*}"
[[ -z "$password" ]] && password=$(generateRandomPassword)
# Mattermost usernames are lowercase and restricted to letters, numbers and
# . - _ — sanitise rather than let the server reject the whole call.
username=$(printf '%s' "$username" | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9._-' '-' | sed 's/^-*//; s/-*$//')
[[ -z "$username" ]] && username="user"
local out
out=$(_mmctl user create --email "$email" --username "$username" --password "$password")
_mmctlFailed "$out" "Creating $email" && return 1
if [[ "$isAdmin" == "true" ]]; then
local promote
promote=$(_mmctl roles system-admin "$email")
_mmctlFailed "$promote" "Granting system admin to $email" && return 1
fi
isSuccessful "Mattermost user created — Email: $email — Username: $username — Password: $password"
}
authAdapter_mattermost_setPassword() {
local email="$1" password="$2"
[[ -z "$email" ]] && { isError "An email address is required."; return 1; }
[[ -z "$password" ]] && password=$(generateRandomPassword)
local out
out=$(_mmctl user change-password "$email" --password "$password")
_mmctlFailed "$out" "Resetting $email" && return 1
# Keep the config in step if this is the account the WebUI card advertises.
[[ "$email" == "${CFG_MATTERMOST_ADMIN_EMAIL:-}" ]] && authPersistCfg mattermost ADMIN_PASSWORD "$password"
isSuccessful "Mattermost password set for $email — New password: $password"
}
authAdapter_mattermost_listUsers() {
local out
out=$(_mmctl user list --per-page 500)
_mmctlFailed "$out" "Listing users" && return 1
# `user list` prints "id: username (email)" per line, plus a trailing count.
local line count=0
while IFS= read -r line; do
[[ "$line" =~ ^[a-z0-9]+:\ ]] || continue
local rest="${line#*: }"
printf ' %s\n' "$rest"
((count++))
done <<< "$out"
isSuccessful "$count Mattermost account(s)."
}
# Mattermost distinguishes deactivate (reversible, frees nothing) from delete
# (permanent, purges content). This is the reversible one: it is what the
# product itself recommends, and a real delete is not undoable from a WebUI
# button click.
authAdapter_mattermost_deleteUser() {
local email="$1"
[[ -z "$email" ]] && { isError "An email address is required."; return 1; }
local out
out=$(_mmctl user deactivate "$email")
_mmctlFailed "$out" "Deactivating $email" && return 1
isSuccessful "Mattermost user '$email' deactivated. Re-enable them from the System Console if needed."
}
authAdapter_mattermost_setAdmin() {
local email="$1" isAdmin="$2"
[[ -z "$email" ]] && { isError "An email address is required."; return 1; }
# `roles system-admin` / `roles member`, NOT `user promote` / `user demote`:
# those two convert between guest and member accounts and have no bearing on
# administrator rights at all.
local out target="false"
if [[ "$isAdmin" == "true" ]]; then
target="true"
out=$(_mmctl roles system-admin "$email")
else
out=$(_mmctl roles member "$email")
fi
_mmctlFailed "$out" "Changing admin status for $email" && return 1
isSuccessful "Mattermost user '$email' system admin → $target."
}

View File

@ -1,105 +0,0 @@
{
"tools": [
{
"id": "create_account",
"category": "users",
"label": "Create User Account",
"description": "Add a Mattermost user. Tick \"Make system admin\" for full rights.",
"icon": "👤",
"fields": [
{
"name": "email",
"label": "Email",
"type": "text",
"placeholder": "user@example.com",
"required": true
},
{
"name": "username",
"label": "Username",
"type": "text",
"placeholder": "Leave blank to derive from the email"
},
{
"name": "password",
"label": "Password",
"type": "password",
"placeholder": "Leave blank to generate"
},
{
"name": "admin",
"label": "Make system admin",
"type": "checkbox",
"default": false
}
]
},
{
"id": "list_users",
"category": "users",
"label": "List Users",
"description": "Every account on this server.",
"icon": "📋",
"fields": []
},
{
"id": "reset_password",
"category": "users",
"label": "Reset User Password",
"description": "Set a new password for an existing user.",
"icon": "🔑",
"fields": [
{
"name": "email",
"label": "User email",
"type": "text",
"required": true
},
{
"name": "password",
"label": "New password",
"type": "password",
"placeholder": "Leave blank to generate"
}
]
},
{
"id": "set_admin",
"category": "users",
"label": "Set Admin Status",
"description": "Promote or demote a system administrator.",
"icon": "👑",
"fields": [
{
"name": "email",
"label": "User email",
"type": "text",
"required": true
},
{
"name": "admin",
"label": "Make system admin",
"type": "checkbox",
"default": false
}
]
},
{
"id": "deactivate_user",
"category": "users",
"label": "Deactivate User Account",
"description": "Revoke access without deleting content. Reversible from the System Console.",
"icon": "🚫",
"destructive": true,
"confirm": "The user will be signed out and unable to log in.",
"fields": [
{
"name": "email",
"label": "User email",
"type": "text",
"required": true
}
]
}
]
}

View File

@ -1,10 +0,0 @@
#!/bin/bash
appMattermostCreateAccount() {
local args="$1"
authAdapterCall mattermost createUser \
"$(authToolArg "$args" email)" \
"$(authToolArg "$args" password)" \
"$(authToolArg "$args" username)" \
"$(authToolArg "$args" admin)"
}

View File

@ -1,6 +0,0 @@
#!/bin/bash
appMattermostDeactivateUser() {
local args="$1"
authAdapterCall mattermost deleteUser "$(authToolArg "$args" email)"
}

View File

@ -1,5 +0,0 @@
#!/bin/bash
appMattermostListUsers() {
authAdapterCall mattermost listUsers
}

View File

@ -1,8 +0,0 @@
#!/bin/bash
appMattermostResetPassword() {
local args="$1"
authAdapterCall mattermost setPassword \
"$(authToolArg "$args" email)" \
"$(authToolArg "$args" password)"
}

View File

@ -1,8 +0,0 @@
#!/bin/bash
appMattermostSetAdmin() {
local args="$1"
authAdapterCall mattermost setAdmin \
"$(authToolArg "$args" email)" \
"$(authToolArg "$args" admin)"
}

View File

@ -62,11 +62,6 @@ declare -gA LP_FN_MAP=(
[appMatrixListUsers]="matrix/tools/matrix_list_users.sh"
[appMatrixResetPassword]="matrix/tools/matrix_reset_password.sh"
[appMatrixSetAdmin]="matrix/tools/matrix_set_admin.sh"
[appMattermostCreateAccount]="mattermost/tools/mattermost_create_account.sh"
[appMattermostDeactivateUser]="mattermost/tools/mattermost_deactivate_user.sh"
[appMattermostListUsers]="mattermost/tools/mattermost_list_users.sh"
[appMattermostResetPassword]="mattermost/tools/mattermost_reset_password.sh"
[appMattermostSetAdmin]="mattermost/tools/mattermost_set_admin.sh"
[appNetworkApplyMode_gluetun]="gluetun/scripts/gluetun_network.sh"
[appNetworkRegisterPorts_gluetun]="gluetun/scripts/gluetun_network.sh"
[appNextcloudAddTrustedDomain]="nextcloud/tools/nextcloud_add_trusted_domain.sh"
@ -163,11 +158,6 @@ declare -gA LP_FN_MAP=(
[authAdapter_matrix_listUsers]="matrix/scripts/matrix_auth.sh"
[authAdapter_matrix_setAdmin]="matrix/scripts/matrix_auth.sh"
[authAdapter_matrix_setPassword]="matrix/scripts/matrix_auth.sh"
[authAdapter_mattermost_createUser]="mattermost/scripts/mattermost_auth.sh"
[authAdapter_mattermost_deleteUser]="mattermost/scripts/mattermost_auth.sh"
[authAdapter_mattermost_listUsers]="mattermost/scripts/mattermost_auth.sh"
[authAdapter_mattermost_setAdmin]="mattermost/scripts/mattermost_auth.sh"
[authAdapter_mattermost_setPassword]="mattermost/scripts/mattermost_auth.sh"
[authAdapter_nextcloud_createUser]="nextcloud/scripts/nextcloud_auth.sh"
[authAdapter_nextcloud_deleteUser]="nextcloud/scripts/nextcloud_auth.sh"
[authAdapter_nextcloud_listUsers]="nextcloud/scripts/nextcloud_auth.sh"
@ -700,8 +690,6 @@ declare -gA LP_FN_MAP=(
[migrateRunHook]="migrate/migrate_hooks.sh"
[migrateSystem]="migrate/migrate_apply.sh"
[migrateUrlRewriteEnabled]="migrate/migrate_url_rewrite.sh"
[_mmctl]="mattermost/scripts/mattermost_auth.sh"
[_mmctlFailed]="mattermost/scripts/mattermost_auth.sh"
[moneyapp_install_post_compose]="moneyapp/scripts/moneyapp_install_hooks.sh"
[moneyapp_install_pre]="moneyapp/scripts/moneyapp_install_hooks.sh"
[monitoringAppEnabled]="network/monitoring/monitoring.sh"
@ -1148,11 +1136,6 @@ declare -gA LP_FN_ROOT=(
[appMatrixListUsers]="containers"
[appMatrixResetPassword]="containers"
[appMatrixSetAdmin]="containers"
[appMattermostCreateAccount]="containers"
[appMattermostDeactivateUser]="containers"
[appMattermostListUsers]="containers"
[appMattermostResetPassword]="containers"
[appMattermostSetAdmin]="containers"
[appNetworkApplyMode_gluetun]="containers"
[appNetworkRegisterPorts_gluetun]="containers"
[appNextcloudAddTrustedDomain]="containers"
@ -1249,11 +1232,6 @@ declare -gA LP_FN_ROOT=(
[authAdapter_matrix_listUsers]="containers"
[authAdapter_matrix_setAdmin]="containers"
[authAdapter_matrix_setPassword]="containers"
[authAdapter_mattermost_createUser]="containers"
[authAdapter_mattermost_deleteUser]="containers"
[authAdapter_mattermost_listUsers]="containers"
[authAdapter_mattermost_setAdmin]="containers"
[authAdapter_mattermost_setPassword]="containers"
[authAdapter_nextcloud_createUser]="containers"
[authAdapter_nextcloud_deleteUser]="containers"
[authAdapter_nextcloud_listUsers]="containers"
@ -1786,8 +1764,6 @@ declare -gA LP_FN_ROOT=(
[migrateRunHook]="scripts"
[migrateSystem]="scripts"
[migrateUrlRewriteEnabled]="scripts"
[_mmctl]="containers"
[_mmctlFailed]="containers"
[moneyapp_install_post_compose]="containers"
[moneyapp_install_pre]="containers"
[monitoringAppEnabled]="scripts"
@ -2191,7 +2167,6 @@ 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"
@ -2269,11 +2244,6 @@ appMatrixDeactivateUser() { unset -f appMatrixDeactivateUser; __lpAutoload "${in
appMatrixListUsers() { unset -f appMatrixListUsers; __lpAutoload "${install_containers_dir}matrix/tools/matrix_list_users.sh"; appMatrixListUsers "$@"; }
appMatrixResetPassword() { unset -f appMatrixResetPassword; __lpAutoload "${install_containers_dir}matrix/tools/matrix_reset_password.sh"; appMatrixResetPassword "$@"; }
appMatrixSetAdmin() { unset -f appMatrixSetAdmin; __lpAutoload "${install_containers_dir}matrix/tools/matrix_set_admin.sh"; appMatrixSetAdmin "$@"; }
appMattermostCreateAccount() { unset -f appMattermostCreateAccount; __lpAutoload "${install_containers_dir}mattermost/tools/mattermost_create_account.sh"; appMattermostCreateAccount "$@"; }
appMattermostDeactivateUser() { unset -f appMattermostDeactivateUser; __lpAutoload "${install_containers_dir}mattermost/tools/mattermost_deactivate_user.sh"; appMattermostDeactivateUser "$@"; }
appMattermostListUsers() { unset -f appMattermostListUsers; __lpAutoload "${install_containers_dir}mattermost/tools/mattermost_list_users.sh"; appMattermostListUsers "$@"; }
appMattermostResetPassword() { unset -f appMattermostResetPassword; __lpAutoload "${install_containers_dir}mattermost/tools/mattermost_reset_password.sh"; appMattermostResetPassword "$@"; }
appMattermostSetAdmin() { unset -f appMattermostSetAdmin; __lpAutoload "${install_containers_dir}mattermost/tools/mattermost_set_admin.sh"; appMattermostSetAdmin "$@"; }
appNetworkApplyMode_gluetun() { unset -f appNetworkApplyMode_gluetun; __lpAutoload "${install_containers_dir}gluetun/scripts/gluetun_network.sh"; appNetworkApplyMode_gluetun "$@"; }
appNetworkRegisterPorts_gluetun() { unset -f appNetworkRegisterPorts_gluetun; __lpAutoload "${install_containers_dir}gluetun/scripts/gluetun_network.sh"; appNetworkRegisterPorts_gluetun "$@"; }
appNextcloudAddTrustedDomain() { unset -f appNextcloudAddTrustedDomain; __lpAutoload "${install_containers_dir}nextcloud/tools/nextcloud_add_trusted_domain.sh"; appNextcloudAddTrustedDomain "$@"; }
@ -2370,11 +2340,6 @@ authAdapter_matrix_deleteUser() { unset -f authAdapter_matrix_deleteUser; __lpAu
authAdapter_matrix_listUsers() { unset -f authAdapter_matrix_listUsers; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_auth.sh"; authAdapter_matrix_listUsers "$@"; }
authAdapter_matrix_setAdmin() { unset -f authAdapter_matrix_setAdmin; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_auth.sh"; authAdapter_matrix_setAdmin "$@"; }
authAdapter_matrix_setPassword() { unset -f authAdapter_matrix_setPassword; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_auth.sh"; authAdapter_matrix_setPassword "$@"; }
authAdapter_mattermost_createUser() { unset -f authAdapter_mattermost_createUser; __lpAutoload "${install_containers_dir}mattermost/scripts/mattermost_auth.sh"; authAdapter_mattermost_createUser "$@"; }
authAdapter_mattermost_deleteUser() { unset -f authAdapter_mattermost_deleteUser; __lpAutoload "${install_containers_dir}mattermost/scripts/mattermost_auth.sh"; authAdapter_mattermost_deleteUser "$@"; }
authAdapter_mattermost_listUsers() { unset -f authAdapter_mattermost_listUsers; __lpAutoload "${install_containers_dir}mattermost/scripts/mattermost_auth.sh"; authAdapter_mattermost_listUsers "$@"; }
authAdapter_mattermost_setAdmin() { unset -f authAdapter_mattermost_setAdmin; __lpAutoload "${install_containers_dir}mattermost/scripts/mattermost_auth.sh"; authAdapter_mattermost_setAdmin "$@"; }
authAdapter_mattermost_setPassword() { unset -f authAdapter_mattermost_setPassword; __lpAutoload "${install_containers_dir}mattermost/scripts/mattermost_auth.sh"; authAdapter_mattermost_setPassword "$@"; }
authAdapter_nextcloud_createUser() { unset -f authAdapter_nextcloud_createUser; __lpAutoload "${install_containers_dir}nextcloud/scripts/nextcloud_auth.sh"; authAdapter_nextcloud_createUser "$@"; }
authAdapter_nextcloud_deleteUser() { unset -f authAdapter_nextcloud_deleteUser; __lpAutoload "${install_containers_dir}nextcloud/scripts/nextcloud_auth.sh"; authAdapter_nextcloud_deleteUser "$@"; }
authAdapter_nextcloud_listUsers() { unset -f authAdapter_nextcloud_listUsers; __lpAutoload "${install_containers_dir}nextcloud/scripts/nextcloud_auth.sh"; authAdapter_nextcloud_listUsers "$@"; }
@ -2907,8 +2872,6 @@ _migrateResolveLocation() { unset -f _migrateResolveLocation; __lpAutoload "${in
migrateRunHook() { unset -f migrateRunHook; __lpAutoload "${install_scripts_dir}migrate/migrate_hooks.sh"; migrateRunHook "$@"; }
migrateSystem() { unset -f migrateSystem; __lpAutoload "${install_scripts_dir}migrate/migrate_apply.sh"; migrateSystem "$@"; }
migrateUrlRewriteEnabled() { unset -f migrateUrlRewriteEnabled; __lpAutoload "${install_scripts_dir}migrate/migrate_url_rewrite.sh"; migrateUrlRewriteEnabled "$@"; }
_mmctl() { unset -f _mmctl; __lpAutoload "${install_containers_dir}mattermost/scripts/mattermost_auth.sh"; _mmctl "$@"; }
_mmctlFailed() { unset -f _mmctlFailed; __lpAutoload "${install_containers_dir}mattermost/scripts/mattermost_auth.sh"; _mmctlFailed "$@"; }
moneyapp_install_post_compose() { unset -f moneyapp_install_post_compose; __lpAutoload "${install_containers_dir}moneyapp/scripts/moneyapp_install_hooks.sh"; moneyapp_install_post_compose "$@"; }
moneyapp_install_pre() { unset -f moneyapp_install_pre; __lpAutoload "${install_containers_dir}moneyapp/scripts/moneyapp_install_hooks.sh"; moneyapp_install_pre "$@"; }
monitoringAppEnabled() { unset -f monitoringAppEnabled; __lpAutoload "${install_scripts_dir}network/monitoring/monitoring.sh"; monitoringAppEnabled "$@"; }