From 5b6ed924d2a7f3719d664f1c5e562a6661afa449 Mon Sep 17 00:00:00 2001 From: librelad Date: Tue, 18 Aug 2026 23:23:12 +0100 Subject: [PATCH] fix(chat tools): wire list_users into the WebUI user-list modal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Tools tab has an interactive modal: when a list_users task completes it parses the task log for EZ_USER lines and renders one row per account with reset / promote / delete buttons. All four new apps failed its contract in every respect, so running List Users produced log text and nothing else. - The marker is EZ_USER, tab-separated as email, username, roles. Matrix and Stoat emitted LP_USER in a different field order; Mattermost and Rocket.Chat emitted no marker at all. - Matrix and Stoat then consumed their own marker lines in the formatting loop and printed only the pretty version, so nothing reached the log to parse. - The row buttons look up tools by id: reset_password, set_admin, delete_user. The deactivate tools were named deactivate_user / disable_user, so no delete button rendered. - Prefill only fills a field named email or username. Rocket.Chat's and Stoat's identifier field was called user, so a row action would have opened with an empty box. - '-' placeholders are truthy, so the modal's `email || username` fallback picked '-' over the real username for accounts without an email (rocket.cat). The EZ_USER line now carries an empty string; '-' stays in the readable line. Mattermost's listing is rebuilt on `mmctl --json`, which carries roles and delete_at. The text listing has neither, and there is no --system-admin filter on user list, so every account was reported as a plain user. Two parsing notes that cost time: mmctl prints status lines both before and after the JSON, so it needs raw_decode rather than json.loads; and --per-page above 200 makes it emit a warning line ahead of the payload. The modal's delete button also stops asserting "Delete user" over whatever the tool actually does — it takes its label and icon from the tool, because most of these deactivate and Matrix cannot delete at all. Verified by replaying the modal's own parser over real tool output: 2 rows for Matrix, 4 for Mattermost, 3 for Rocket.Chat, with admin and deactivated states resolving correctly. Co-Authored-By: Claude Opus 5 --- .../components/apps/tools/js/tools-manager.js | 6 ++- containers/matrix/scripts/matrix_auth.sh | 12 ++++- containers/matrix/tools/matrix.tools.json | 2 +- ...activate_user.sh => matrix_delete_user.sh} | 2 +- .../mattermost/scripts/mattermost_auth.sh | 53 +++++++++++++++---- .../mattermost/tools/mattermost.tools.json | 2 +- ...vate_user.sh => mattermost_delete_user.sh} | 2 +- .../rocketchat/scripts/rocketchat_auth.sh | 7 ++- .../rocketchat/tools/rocketchat.tools.json | 10 ++-- ...vate_user.sh => rocketchat_delete_user.sh} | 4 +- .../tools/rocketchat_enable_user.sh | 2 +- .../tools/rocketchat_reset_password.sh | 2 +- .../rocketchat/tools/rocketchat_set_admin.sh | 2 +- containers/stoat/scripts/stoat_auth.sh | 11 ++-- .../stoat/scripts/stoat_install_hooks.sh | 25 +++++++-- containers/stoat/tools/stoat.tools.json | 6 +-- ...t_disable_user.sh => stoat_delete_user.sh} | 4 +- containers/stoat/tools/stoat_enable_user.sh | 2 +- scripts/function/checks/check_success.sh | 4 +- .../source/files/arrays/function_manifest.sh | 9 ++-- 20 files changed, 120 insertions(+), 47 deletions(-) rename containers/matrix/tools/{matrix_deactivate_user.sh => matrix_delete_user.sh} (89%) rename containers/mattermost/tools/{mattermost_deactivate_user.sh => mattermost_delete_user.sh} (77%) rename containers/rocketchat/tools/{rocketchat_deactivate_user.sh => rocketchat_delete_user.sh} (71%) rename containers/stoat/tools/{stoat_disable_user.sh => stoat_delete_user.sh} (76%) diff --git a/containers/libreportal/frontend/components/apps/tools/js/tools-manager.js b/containers/libreportal/frontend/components/apps/tools/js/tools-manager.js index 053fa29..975d9c7 100644 --- a/containers/libreportal/frontend/components/apps/tools/js/tools-manager.js +++ b/containers/libreportal/frontend/components/apps/tools/js/tools-manager.js @@ -98,6 +98,10 @@ class ToolsManager { _openUserListModal(appName, users) { const tools = (window.toolsCatalog?.apps?.[appName]?.tools) || []; const resetTool = tools.find(t => t.id === 'reset_password'); + // Its id is delete_user by convention, but what it actually does is the + // app's business — most deactivate rather than delete, and Matrix cannot + // delete at all. The row button therefore takes its label and icon from the + // tool itself instead of asserting "Delete user" over the top of it. const deleteTool = tools.find(t => t.id === 'delete_user'); const adminTool = tools.find(t => t.id === 'set_admin'); const appLabel = (window.getAppDisplayName ? window.getAppDisplayName(appName) : appName); @@ -121,7 +125,7 @@ class ToolsManager {
${resetTool ? `` : ''} ${adminTool ? `` : ''} - ${deleteTool ? `` : ''} + ${deleteTool ? `` : ''}
`; }).join('') diff --git a/containers/matrix/scripts/matrix_auth.sh b/containers/matrix/scripts/matrix_auth.sh index 115278c..083ccca 100644 --- a/containers/matrix/scripts/matrix_auth.sh +++ b/containers/matrix/scripts/matrix_auth.sh @@ -224,7 +224,10 @@ for u in res.get('users', []): flags = [] if u.get('admin'): flags.append('admin') if u.get('deactivated'): flags.append('deactivated') - print('LP_USER\t' + u['name'] + '\t' + (u.get('displayname') or '-') + '\t' + (','.join(flags) or 'user')) + # EZ_USERidentifierdisplayroles — the exact shape the WebUI's + # user-list modal parses. The first column is what a row action gets + # prefilled with, so it must be the Matrix ID, not the display name. + print('EZ_USER\t' + u['name'] + '\t' + (u.get('displayname') or '') + '\t' + (','.join(flags) or 'user')) print('LP_TOTAL:' + str(res.get('total', 0))) " 2>&1) @@ -233,7 +236,12 @@ print('LP_TOTAL:' + str(res.get('total', 0))) local line total=0 while IFS= read -r line; do case "$line" in - LP_USER*) IFS=$'\t' read -r _ uid name flags <<< "$line" + EZ_USER*) IFS=$'\t' read -r _ uid name flags <<< "$line" + # Re-emit the raw marker line as well as the readable one: + # the WebUI modal reads the task log looking for EZ_USER, + # so consuming it here and printing only the pretty version + # left the modal with nothing to parse. + printf '%s\n' "$line" printf ' %-34s %-20s %s\n' "$uid" "$name" "$flags" ;; LP_TOTAL:*) total="${line#LP_TOTAL:}" ;; esac diff --git a/containers/matrix/tools/matrix.tools.json b/containers/matrix/tools/matrix.tools.json index b363b0a..867ff15 100644 --- a/containers/matrix/tools/matrix.tools.json +++ b/containers/matrix/tools/matrix.tools.json @@ -86,7 +86,7 @@ ] }, { - "id": "deactivate_user", + "id": "delete_user", "category": "users", "label": "Deactivate User Account", "description": "Matrix has no delete. This revokes access and erases the profile, and the user ID stays permanently taken.", diff --git a/containers/matrix/tools/matrix_deactivate_user.sh b/containers/matrix/tools/matrix_delete_user.sh similarity index 89% rename from containers/matrix/tools/matrix_deactivate_user.sh rename to containers/matrix/tools/matrix_delete_user.sh index 38fbb2f..620441d 100644 --- a/containers/matrix/tools/matrix_deactivate_user.sh +++ b/containers/matrix/tools/matrix_delete_user.sh @@ -2,7 +2,7 @@ # Named deactivate rather than delete on purpose — Matrix has no delete, and # calling it one would misrepresent what the button does. -appMatrixDeactivateUser() { +appMatrixDeleteUser() { local args="$1" authAdapterCall matrix deleteUser "$(authToolArg "$args" username)" } diff --git a/containers/mattermost/scripts/mattermost_auth.sh b/containers/mattermost/scripts/mattermost_auth.sh index 2a8a9b1..35db7ea 100644 --- a/containers/mattermost/scripts/mattermost_auth.sh +++ b/containers/mattermost/scripts/mattermost_auth.sh @@ -73,19 +73,54 @@ authAdapter_mattermost_setPassword() { } authAdapter_mattermost_listUsers() { + # --json rather than the human format: it carries `roles` and `delete_at`, + # which the plain listing does not. There is no --system-admin filter on + # `user list` (only --inactive), so parsing the text output left every + # account looking like a plain user. local out - out=$(_mmctl user list --per-page 500) + # 200 is mmctl's maximum; asking for more makes it print a warning line + # BEFORE the JSON, which then fails to parse. + out=$(_mmctl --json user list --per-page 200) _mmctlFailed "$out" "Listing users" && return 1 - # `user list` prints "id: username (email)" per line, plus a trailing count. - local line count=0 + local rendered + rendered=$(printf '%s' "$out" | python3 -c " +import sys, json +# _mmctl folds stderr into stdout, and mmctl prints status lines such as +# 'There are 4 users on local instance' AFTER the JSON as well as warnings +# before it. raw_decode stops at the end of the first complete JSON value and +# ignores whatever trails it, which plain json.loads will not do. +raw = sys.stdin.read() +start = min([i for i in (raw.find('['), raw.find('{')) if i >= 0], default=-1) +users = [] +if start >= 0: + try: + users, _ = json.JSONDecoder().raw_decode(raw[start:]) + except Exception: + users = [] +if isinstance(users, dict): + users = users.get('users', []) +for u in users: + roles = 'admin' if 'system_admin' in (u.get('roles') or '') else 'user' + if u.get('delete_at'): + roles += ',deactivated' + email = u.get('email') or '-' + name = u.get('username') or '-' + # EZ_USERemailusernameroles is what the WebUI user-list modal + # parses; the aligned line after it is for whoever reads the log. + print('EZ_USER\\t%s\\t%s\\t%s' % (email, name, roles)) + print(' %-30s %-22s %s' % (email, name, roles)) +print('LP_TOTAL:%d' % len(users)) +" 2>/dev/null) + + local line total=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)." + case "$line" in + LP_TOTAL:*) total="${line#LP_TOTAL:}" ;; + *) [[ -n "$line" ]] && printf '%s\n' "$line" ;; + esac + done <<< "$rendered" + isSuccessful "$total Mattermost account(s)." } # Mattermost distinguishes deactivate (reversible, frees nothing) from delete diff --git a/containers/mattermost/tools/mattermost.tools.json b/containers/mattermost/tools/mattermost.tools.json index afe553e..0e95ec5 100644 --- a/containers/mattermost/tools/mattermost.tools.json +++ b/containers/mattermost/tools/mattermost.tools.json @@ -85,7 +85,7 @@ ] }, { - "id": "deactivate_user", + "id": "delete_user", "category": "users", "label": "Deactivate User Account", "description": "Revoke access without deleting content. Reversible from the System Console.", diff --git a/containers/mattermost/tools/mattermost_deactivate_user.sh b/containers/mattermost/tools/mattermost_delete_user.sh similarity index 77% rename from containers/mattermost/tools/mattermost_deactivate_user.sh rename to containers/mattermost/tools/mattermost_delete_user.sh index 405c3af..a25f406 100644 --- a/containers/mattermost/tools/mattermost_deactivate_user.sh +++ b/containers/mattermost/tools/mattermost_delete_user.sh @@ -1,6 +1,6 @@ #!/bin/bash -appMattermostDeactivateUser() { +appMattermostDeleteUser() { local args="$1" authAdapterCall mattermost deleteUser "$(authToolArg "$args" email)" } diff --git a/containers/rocketchat/scripts/rocketchat_auth.sh b/containers/rocketchat/scripts/rocketchat_auth.sh index 3a81f9b..5c60a17 100644 --- a/containers/rocketchat/scripts/rocketchat_auth.sh +++ b/containers/rocketchat/scripts/rocketchat_auth.sh @@ -180,7 +180,12 @@ for u in users: roles = ','.join(u.get('roles') or []) or 'user' state = '' if u.get('active', True) else ' (deactivated)' email = (u.get('emails') or [{}])[0].get('address', '-') - print(' %-22s %-30s %s%s' % (u.get('username', '-'), email, roles, state)) + # EZ_USERemailusernameroles drives the WebUI's user-list + # modal; the aligned line below it is what a human reads in the log. + # Empty, not '-': the modal falls back to the username with + # \`email || username\`, and a '-' placeholder is truthy so it would win. + print('EZ_USER\t%s\t%s\t%s' % ('' if email == '-' else email, u.get('username', ''), roles + state)) + print(' %-30s %-22s %s%s' % (email, u.get('username', '-'), roles, state)) print('LP_TOTAL:%d' % d.get('total', len(users))) " 2>/dev/null) diff --git a/containers/rocketchat/tools/rocketchat.tools.json b/containers/rocketchat/tools/rocketchat.tools.json index 1912df8..e039931 100644 --- a/containers/rocketchat/tools/rocketchat.tools.json +++ b/containers/rocketchat/tools/rocketchat.tools.json @@ -50,7 +50,7 @@ "icon": "🔑", "fields": [ { - "name": "user", + "name": "username", "label": "Username or email", "type": "text", "required": true @@ -71,7 +71,7 @@ "icon": "👑", "fields": [ { - "name": "user", + "name": "username", "label": "Username or email", "type": "text", "required": true @@ -85,7 +85,7 @@ ] }, { - "id": "deactivate_user", + "id": "delete_user", "category": "users", "label": "Deactivate User Account", "description": "Revoke access without deleting messages. Reversible from Admin → Users.", @@ -94,7 +94,7 @@ "confirm": "The user will be signed out and unable to log in.", "fields": [ { - "name": "user", + "name": "username", "label": "Username or email", "type": "text", "required": true @@ -109,7 +109,7 @@ "icon": "✅", "fields": [ { - "name": "user", + "name": "username", "label": "Username or email", "type": "text", "required": true diff --git a/containers/rocketchat/tools/rocketchat_deactivate_user.sh b/containers/rocketchat/tools/rocketchat_delete_user.sh similarity index 71% rename from containers/rocketchat/tools/rocketchat_deactivate_user.sh rename to containers/rocketchat/tools/rocketchat_delete_user.sh index cc85a53..78d9d0e 100644 --- a/containers/rocketchat/tools/rocketchat_deactivate_user.sh +++ b/containers/rocketchat/tools/rocketchat_delete_user.sh @@ -1,6 +1,6 @@ #!/bin/bash -appRocketchatDeactivateUser() { +appRocketchatDeleteUser() { local args="$1" - authAdapterCall rocketchat deleteUser "$(authToolArg "$args" user)" + authAdapterCall rocketchat deleteUser "$(authToolArg "$args" username)" } diff --git a/containers/rocketchat/tools/rocketchat_enable_user.sh b/containers/rocketchat/tools/rocketchat_enable_user.sh index c8bb0d5..c493af7 100644 --- a/containers/rocketchat/tools/rocketchat_enable_user.sh +++ b/containers/rocketchat/tools/rocketchat_enable_user.sh @@ -2,5 +2,5 @@ appRocketchatEnableUser() { local args="$1" - authAdapterCall rocketchat enableUser "$(authToolArg "$args" user)" + authAdapterCall rocketchat enableUser "$(authToolArg "$args" username)" } diff --git a/containers/rocketchat/tools/rocketchat_reset_password.sh b/containers/rocketchat/tools/rocketchat_reset_password.sh index bede644..e1e1c7f 100644 --- a/containers/rocketchat/tools/rocketchat_reset_password.sh +++ b/containers/rocketchat/tools/rocketchat_reset_password.sh @@ -3,6 +3,6 @@ appRocketchatResetPassword() { local args="$1" authAdapterCall rocketchat setPassword \ - "$(authToolArg "$args" user)" \ + "$(authToolArg "$args" username)" \ "$(authToolArg "$args" password)" } diff --git a/containers/rocketchat/tools/rocketchat_set_admin.sh b/containers/rocketchat/tools/rocketchat_set_admin.sh index badeaec..8b18e78 100644 --- a/containers/rocketchat/tools/rocketchat_set_admin.sh +++ b/containers/rocketchat/tools/rocketchat_set_admin.sh @@ -3,6 +3,6 @@ appRocketchatSetAdmin() { local args="$1" authAdapterCall rocketchat setAdmin \ - "$(authToolArg "$args" user)" \ + "$(authToolArg "$args" username)" \ "$(authToolArg "$args" admin)" } diff --git a/containers/stoat/scripts/stoat_auth.sh b/containers/stoat/scripts/stoat_auth.sh index 0145c23..77de63e 100644 --- a/containers/stoat/scripts/stoat_auth.sh +++ b/containers/stoat/scripts/stoat_auth.sh @@ -51,7 +51,9 @@ users.forEach(u => { const a = byId[u._id] || {}; const handle = u.username + (u.discriminator ? "#" + u.discriminator : ""); const state = a.disabled ? " (disabled)" : ""; - print("LP_USER\t" + handle + "\t" + (a.email || "-") + "\t" + (u.display_name || "-") + state); + // EZ_USERidentifierdisplayroles, as the WebUI modal expects. + // Email first where there is one: it is the field a row action prefills. + print("EZ_USER\t" + (a.email || handle) + "\t" + handle + "\t" + (a.disabled ? "disabled" : "user")); }); print("LP_TOTAL:" + users.length); ') @@ -60,8 +62,11 @@ print("LP_TOTAL:" + users.length); local line total=0 while IFS= read -r line; do case "$line" in - LP_USER*) IFS=$'\t' read -r _ handle email display <<< "$line" - printf ' %-24s %-30s %s\n' "$handle" "$email" "$display" ;; + EZ_USER*) IFS=$'\t' read -r _ ident handle state <<< "$line" + # The marker line has to reach the task log for the WebUI + # user-list modal to build its rows from. + printf '%s\n' "$line" + printf ' %-30s %-24s %s\n' "$ident" "$handle" "$state" ;; LP_TOTAL:*) total="${line#LP_TOTAL:}" ;; esac done <<< "$out" diff --git a/containers/stoat/scripts/stoat_install_hooks.sh b/containers/stoat/scripts/stoat_install_hooks.sh index f6ebdfa..52e1e69 100644 --- a/containers/stoat/scripts/stoat_install_hooks.sh +++ b/containers/stoat/scripts/stoat_install_hooks.sh @@ -187,6 +187,25 @@ EOF isSuccessful "Generated secrets.env" } +# Own the LibrePortal-written config files (Caddyfile, Revolt.toml, .env.web, +# stoat.json, secrets.env, livekit.yml, the compose + app config) as the docker +# install user, so the containers can read their bind-mount sources. +# +# Top level ONLY. This used to be `chown -R "$app_dir"`, which walked into +# data/db, data/minio and friends — content created by the containers and owned +# by THEIR uids (mongo's, minio's; under rootless those are subuids the docker +# install user has no authority over). Every reinstall therefore printed a screen +# of "Operation not permitted" plus "Permission denied" on the 0700 dirs it +# couldn't even enter, and then failed the step outright — an ✗ Error on a +# healthy install, which is the kind of noise that teaches you to skip error +# lines. Those files must keep their container ownership anyway: chowning mongo's +# data away from mongo is what would actually break stoat. +_stoatOwnConfigFiles() { + local app_dir="$1" + runFileOp find "$app_dir" -maxdepth 1 -type f \ + -exec chown "$docker_install_user":"$docker_install_user" {} + +} + stoat_install_post_compose() { local app_name="$1" @@ -267,8 +286,8 @@ webhook: EOF checkSuccess "Writing livekit.yml" - runFileOp chown -R "$docker_install_user":"$docker_install_user" "$app_dir" - checkSuccess "Setting ownership on the $app_name install directory" + _stoatOwnConfigFiles "$app_dir" + checkSuccess "Setting ownership on the $app_name config files" } stoat_install_post_start() @@ -294,7 +313,7 @@ stoat_install_post_start() local video_enabled="" [[ "$CFG_STOAT_ENABLE_VIDEO" != "false" ]] && video_enabled="true" _stoatWriteUrlFiles "$app_dir" "$base" "$video_enabled" "$CFG_STOAT_RABBITMQ_PASSWORD_1" - runFileOp chown -R "$docker_install_user":"$docker_install_user" "$app_dir" + _stoatOwnConfigFiles "$app_dir" isSuccessful "Public URL settled as $base (was ${current:-unset})" # The web client compiles VITE_* at container start, so it has to come back diff --git a/containers/stoat/tools/stoat.tools.json b/containers/stoat/tools/stoat.tools.json index 626cdbc..d086e3a 100644 --- a/containers/stoat/tools/stoat.tools.json +++ b/containers/stoat/tools/stoat.tools.json @@ -9,7 +9,7 @@ "fields": [] }, { - "id": "disable_user", + "id": "delete_user", "category": "users", "label": "Disable User Account", "description": "Block sign-in without deleting the account or its messages. Reversible.", @@ -18,7 +18,7 @@ "confirm": "The user will not be able to sign in again until re-enabled.", "fields": [ { - "name": "user", + "name": "username", "label": "Username or email", "type": "text", "required": true @@ -33,7 +33,7 @@ "icon": "✅", "fields": [ { - "name": "user", + "name": "username", "label": "Username or email", "type": "text", "required": true diff --git a/containers/stoat/tools/stoat_disable_user.sh b/containers/stoat/tools/stoat_delete_user.sh similarity index 76% rename from containers/stoat/tools/stoat_disable_user.sh rename to containers/stoat/tools/stoat_delete_user.sh index 51b7e86..cd58dda 100644 --- a/containers/stoat/tools/stoat_disable_user.sh +++ b/containers/stoat/tools/stoat_delete_user.sh @@ -1,6 +1,6 @@ #!/bin/bash -appStoatDisableUser() { +appStoatDeleteUser() { local args="$1" - authAdapterCall stoat deleteUser "$(authToolArg "$args" user)" + authAdapterCall stoat deleteUser "$(authToolArg "$args" username)" } diff --git a/containers/stoat/tools/stoat_enable_user.sh b/containers/stoat/tools/stoat_enable_user.sh index f3e113c..b3e8799 100644 --- a/containers/stoat/tools/stoat_enable_user.sh +++ b/containers/stoat/tools/stoat_enable_user.sh @@ -2,5 +2,5 @@ appStoatEnableUser() { local args="$1" - authAdapterCall stoat enableUser "$(authToolArg "$args" user)" + authAdapterCall stoat enableUser "$(authToolArg "$args" username)" } diff --git a/scripts/function/checks/check_success.sh b/scripts/function/checks/check_success.sh index 3b6bcf8..5fd4f5d 100755 --- a/scripts/function/checks/check_success.sh +++ b/scripts/function/checks/check_success.sh @@ -33,7 +33,7 @@ function checkSuccess() local _where="${BASH_SOURCE[1]##*/}:${BASH_LINENO[0]}" local _stamp; _stamp="$(date '+%F %T' 2>/dev/null || echo now)" printf '%s\t[exit %s]\t%s\t(%s)\n' "$_stamp" "$rc" "$msg" "$_where" \ - | runInstallWrite -a "$logs_dir/error_report.log" 2>/dev/null || true + | runInstallWrite -a "${logs_dir%/}/error_report.log" 2>/dev/null || true if [ -f "$logs_dir/$docker_log_file" ]; then isError " $msg (exit $rc, $_where)" | runInstallWrite -a "$logs_dir/$docker_log_file" >/dev/null 2>&1 || true fi @@ -42,7 +42,7 @@ function checkSuccess() # doesn't abort the whole run and we surface EVERY issue in one pass. Turn # CFG_REQUIREMENT_CONTINUE_ON_ERROR off for strict abort once things are clean. if [[ "${CFG_REQUIREMENT_CONTINUE_ON_ERROR:-true}" == "true" ]]; then - isNotice "continue-on-error: logged to $logs_dir/error_report.log — continuing." + isNotice "continue-on-error: logged to ${logs_dir%/}/error_report.log — continuing." return 0 fi diff --git a/scripts/source/files/arrays/function_manifest.sh b/scripts/source/files/arrays/function_manifest.sh index b43520a..2a5e080 100644 --- a/scripts/source/files/arrays/function_manifest.sh +++ b/scripts/source/files/arrays/function_manifest.sh @@ -175,9 +175,7 @@ declare -gA LP_FN_MAP=( [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" @@ -955,6 +953,7 @@ declare -gA LP_FN_MAP=( [_stoatMongo]="stoat/scripts/stoat_auth.sh" [_stoatMongoFailed]="stoat/scripts/stoat_auth.sh" [_stoatMongoWho]="stoat/scripts/stoat_auth.sh" + [_stoatOwnConfigFiles]="stoat/scripts/stoat_install_hooks.sh" [_stoatSetDisabled]="stoat/scripts/stoat_auth.sh" [_stoatWriteSecrets]="stoat/scripts/stoat_install_hooks.sh" [_stoatWriteUrlFiles]="stoat/scripts/stoat_install_hooks.sh" @@ -1299,9 +1298,7 @@ declare -gA LP_FN_ROOT=( [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" @@ -2079,6 +2076,7 @@ declare -gA LP_FN_ROOT=( [_stoatMongo]="containers" [_stoatMongoFailed]="containers" [_stoatMongoWho]="containers" + [_stoatOwnConfigFiles]="containers" [_stoatSetDisabled]="containers" [_stoatWriteSecrets]="containers" [_stoatWriteUrlFiles]="containers" @@ -2458,9 +2456,7 @@ authAdapter_matrix_listUsers() { unset -f authAdapter_matrix_listUsers; __lpAuto 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 "$@"; } @@ -3238,6 +3234,7 @@ stoat_install_pre() { unset -f stoat_install_pre; __lpAutoload "${install_contai _stoatMongo() { unset -f _stoatMongo; __lpAutoload "${install_containers_dir}stoat/scripts/stoat_auth.sh"; _stoatMongo "$@"; } _stoatMongoFailed() { unset -f _stoatMongoFailed; __lpAutoload "${install_containers_dir}stoat/scripts/stoat_auth.sh"; _stoatMongoFailed "$@"; } _stoatMongoWho() { unset -f _stoatMongoWho; __lpAutoload "${install_containers_dir}stoat/scripts/stoat_auth.sh"; _stoatMongoWho "$@"; } +_stoatOwnConfigFiles() { unset -f _stoatOwnConfigFiles; __lpAutoload "${install_containers_dir}stoat/scripts/stoat_install_hooks.sh"; _stoatOwnConfigFiles "$@"; } _stoatSetDisabled() { unset -f _stoatSetDisabled; __lpAutoload "${install_containers_dir}stoat/scripts/stoat_auth.sh"; _stoatSetDisabled "$@"; } _stoatWriteSecrets() { unset -f _stoatWriteSecrets; __lpAutoload "${install_containers_dir}stoat/scripts/stoat_install_hooks.sh"; _stoatWriteSecrets "$@"; } _stoatWriteUrlFiles() { unset -f _stoatWriteUrlFiles; __lpAutoload "${install_containers_dir}stoat/scripts/stoat_install_hooks.sh"; _stoatWriteUrlFiles "$@"; }