fix(chat tools): wire list_users into the WebUI user-list modal
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 <noreply@anthropic.com>
This commit is contained in:
parent
77b50e5226
commit
5b6ed924d2
@ -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 {
|
||||
<div class="user-row-actions">
|
||||
${resetTool ? `<button type="button" class="user-row-btn" data-act="reset" data-idx="${idx}" title="Reset password">🔑</button>` : ''}
|
||||
${adminTool ? `<button type="button" class="user-row-btn" data-act="admin" data-idx="${idx}" title="${isAdmin ? 'Demote from admin' : 'Promote to admin'}">${isAdmin ? '👤' : '👑'}</button>` : ''}
|
||||
${deleteTool ? `<button type="button" class="user-row-btn danger" data-act="delete" data-idx="${idx}" title="Delete user">🗑</button>` : ''}
|
||||
${deleteTool ? `<button type="button" class="user-row-btn danger" data-act="delete" data-idx="${idx}" title="${escapeHtml(deleteTool.label || 'Delete user')}">${escapeHtml(deleteTool.icon || '🗑')}</button>` : ''}
|
||||
</div>
|
||||
</div>`;
|
||||
}).join('')
|
||||
|
||||
@ -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_USER<TAB>identifier<TAB>display<TAB>roles — 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
|
||||
|
||||
@ -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.",
|
||||
|
||||
@ -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)"
|
||||
}
|
||||
@ -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_USER<TAB>email<TAB>username<TAB>roles 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
|
||||
|
||||
@ -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.",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
appMattermostDeactivateUser() {
|
||||
appMattermostDeleteUser() {
|
||||
local args="$1"
|
||||
authAdapterCall mattermost deleteUser "$(authToolArg "$args" email)"
|
||||
}
|
||||
@ -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_USER<TAB>email<TAB>username<TAB>roles 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)
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
appRocketchatDeactivateUser() {
|
||||
appRocketchatDeleteUser() {
|
||||
local args="$1"
|
||||
authAdapterCall rocketchat deleteUser "$(authToolArg "$args" user)"
|
||||
authAdapterCall rocketchat deleteUser "$(authToolArg "$args" username)"
|
||||
}
|
||||
@ -2,5 +2,5 @@
|
||||
|
||||
appRocketchatEnableUser() {
|
||||
local args="$1"
|
||||
authAdapterCall rocketchat enableUser "$(authToolArg "$args" user)"
|
||||
authAdapterCall rocketchat enableUser "$(authToolArg "$args" username)"
|
||||
}
|
||||
|
||||
@ -3,6 +3,6 @@
|
||||
appRocketchatResetPassword() {
|
||||
local args="$1"
|
||||
authAdapterCall rocketchat setPassword \
|
||||
"$(authToolArg "$args" user)" \
|
||||
"$(authToolArg "$args" username)" \
|
||||
"$(authToolArg "$args" password)"
|
||||
}
|
||||
|
||||
@ -3,6 +3,6 @@
|
||||
appRocketchatSetAdmin() {
|
||||
local args="$1"
|
||||
authAdapterCall rocketchat setAdmin \
|
||||
"$(authToolArg "$args" user)" \
|
||||
"$(authToolArg "$args" username)" \
|
||||
"$(authToolArg "$args" admin)"
|
||||
}
|
||||
|
||||
@ -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_USER<TAB>identifier<TAB>display<TAB>roles, 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"
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
appStoatDisableUser() {
|
||||
appStoatDeleteUser() {
|
||||
local args="$1"
|
||||
authAdapterCall stoat deleteUser "$(authToolArg "$args" user)"
|
||||
authAdapterCall stoat deleteUser "$(authToolArg "$args" username)"
|
||||
}
|
||||
@ -2,5 +2,5 @@
|
||||
|
||||
appStoatEnableUser() {
|
||||
local args="$1"
|
||||
authAdapterCall stoat enableUser "$(authToolArg "$args" user)"
|
||||
authAdapterCall stoat enableUser "$(authToolArg "$args" username)"
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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 "$@"; }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user