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 ? `${isAdmin ? '👤' : '👑'} ` : ''}
- ${deleteTool ? `🗑 ` : ''}
+ ${deleteTool ? `${escapeHtml(deleteTool.icon || '🗑')} ` : ''}
`;
}).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 "$@"; }