From a96a3a69a152c8e89d092d46bfcf4b8c87bd770c Mon Sep 17 00:00:00 2001 From: librelad Date: Tue, 18 Aug 2026 21:24:28 +0100 Subject: [PATCH] fix(linkding): declare the admin keys its auth adapter writes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit linkding_auth.sh persists ADMIN_USER and ADMIN_PASSWORD when the first admin is created, and keeps the password in step on later resets of that account, but linkding.config declared neither — so both writes were no-ops and the WebUI credentials card never had anything to show. Predates the slot work; it only became visible once authPersistCfg started warning instead of failing silently. Added empty rather than RANDOMIZED*, because unlike bookstack or nextcloud nothing seeds a linkding account at install — the first user is created from the WebUI. A generated password would name an account that does not exist, and the card would display a password that cannot log in. Unslotted for the same reason: the slot number marks a value the installer generates, and this one is written at runtime by the tool. No AUTH_PROFILE key: nothing reads it (it exists only in a comment in auth_adapter.sh), and adding an unread key is what was just cleaned up elsewhere. Co-Authored-By: Claude Opus 5 --- containers/linkding/linkding.config | 16 + containers/matrix/matrix.config | 3 + containers/matrix/resources/homeserver.yaml | 2 +- .../matrix/resources/{log.config => log.yaml} | 0 containers/matrix/scripts/matrix_auth.sh | 304 ++++++++++++++++++ .../matrix/scripts/matrix_install_hooks.sh | 4 +- containers/matrix/tools/matrix.tools.json | 106 ++++++ .../matrix/tools/matrix_create_account.sh | 10 + .../matrix/tools/matrix_deactivate_user.sh | 8 + containers/matrix/tools/matrix_list_users.sh | 5 + .../matrix/tools/matrix_reset_password.sh | 8 + containers/matrix/tools/matrix_set_admin.sh | 8 + .../source/files/arrays/function_manifest.sh | 39 +++ 13 files changed, 510 insertions(+), 3 deletions(-) rename containers/matrix/resources/{log.config => log.yaml} (100%) create mode 100644 containers/matrix/scripts/matrix_auth.sh create mode 100644 containers/matrix/tools/matrix.tools.json create mode 100644 containers/matrix/tools/matrix_create_account.sh create mode 100644 containers/matrix/tools/matrix_deactivate_user.sh create mode 100644 containers/matrix/tools/matrix_list_users.sh create mode 100644 containers/matrix/tools/matrix_reset_password.sh create mode 100644 containers/matrix/tools/matrix_set_admin.sh diff --git a/containers/linkding/linkding.config b/containers/linkding/linkding.config index 50c4d3c..f8abdb0 100755 --- a/containers/linkding/linkding.config +++ b/containers/linkding/linkding.config @@ -61,3 +61,19 @@ CFG_LINKDING_NETWORK=default # - description: human-readable description of the service # CFG_LINKDING_PORT_1="linkding-service|webui|random:9090|public|tcp|false|true|true|Web Interface||bookmark" +# +# ============================================================================= +# ADMIN ACCOUNT +# ============================================================================= +# Recorded by the auth tools, not by the installer. Linkding ships with no user +# at all — the first admin is created from the WebUI (Create Account), and the +# adapter writes the username and password here so the credentials card can show +# them, then keeps the password in step on later resets of that same account. +# +# Deliberately empty rather than RANDOMIZED*: nothing seeds an account at +# install, so a generated password would name an account that does not exist and +# the WebUI would display a password that cannot log in. These are also +# unslotted, because the slot number marks a value the installer generates. +# +CFG_LINKDING_ADMIN_USER= +CFG_LINKDING_ADMIN_PASSWORD= diff --git a/containers/matrix/matrix.config b/containers/matrix/matrix.config index 2880b82..4f34eaa 100644 --- a/containers/matrix/matrix.config +++ b/containers/matrix/matrix.config @@ -114,3 +114,6 @@ CFG_MATRIX_NETWORK=default # CFG_MATRIX_PORT_1="matrix-synapse|homeserver|random:8008|public|tcp|false|true|false|Matrix Homeserver (client + federation API)||matrix" CFG_MATRIX_PORT_2="matrix-element|webui|random:80|public|tcp|false|true|true|Element Web Interface||element" + +# AUTH_PROFILE = capability tier for the WebUI auth tools (single_password | user_password | multi_user) +CFG_MATRIX_AUTH_PROFILE=multi_user diff --git a/containers/matrix/resources/homeserver.yaml b/containers/matrix/resources/homeserver.yaml index 63d7022..c769ad0 100644 --- a/containers/matrix/resources/homeserver.yaml +++ b/containers/matrix/resources/homeserver.yaml @@ -53,7 +53,7 @@ database: cp_min: 5 cp_max: 10 -log_config: "/data/log.config" +log_config: "/data/log.yaml" media_store_path: /data/media_store signing_key_path: "/data/signing.key" diff --git a/containers/matrix/resources/log.config b/containers/matrix/resources/log.yaml similarity index 100% rename from containers/matrix/resources/log.config rename to containers/matrix/resources/log.yaml diff --git a/containers/matrix/scripts/matrix_auth.sh b/containers/matrix/scripts/matrix_auth.sh new file mode 100644 index 0000000..115278c --- /dev/null +++ b/containers/matrix/scripts/matrix_auth.sh @@ -0,0 +1,304 @@ +#!/bin/bash + +# Matrix user management, via Synapse's admin API. +# +# Everything goes through `docker exec matrix-synapse python`: the image is +# debian-slim with no curl or wget, but python is what Synapse itself runs on, +# so it is always present. Talking to localhost:8008 inside the container also +# means these tools behave identically whether the install is LAN-only or behind +# Traefik, and never depend on the published port. +# +# Two Matrix facts shape what can be offered here: +# - A user ID is permanent. There is no rename; "changing a username" means +# creating a new account. +# - There is no true delete. Deactivation is the terminal state — it revokes +# access, devices and profile, but the ID stays burned so it can never be +# re-registered and old messages still resolve. + +# Localpart -> full ID. Accepts either form, so a caller can pass "alice" or +# "@alice:example.com" and get the same result. +_matrixUserId() { + local user="$1" server + [[ "$user" == @* ]] && { echo "$user"; return 0; } + server=$(_matrixServerName) + [[ -z "$server" ]] && return 1 + echo "@${user}:${server}" +} + +# Where the cached admin access token lives. Beside homeserver.yaml, which +# already holds the registration shared secret and the database password, so +# this adds no new class of secret to the install. +_matrix_token_cache="data/.lp-admin-token" + +# Run a python snippet inside the Synapse container with an admin access token +# already in scope and a call(method, path, body) helper available. +# +# Args: [extra docker -e flags...] +# +# Values are handed over as environment variables rather than interpolated into +# the snippet, so a password containing quotes or backslashes cannot break out +# into the python source. +# +# The token is CACHED between invocations. Logging in each time seemed tidier, +# but Synapse rate-limits /login (rc_login defaults to a burst of 5), so running +# a few tools in succession failed with "Too Many Requests" — the tools were +# throttling themselves. One login, reused until it stops working, and a single +# re-login on 401 if the token was revoked or the password changed. +_matrixApi() { + local script="$1"; shift + local admin_user="${CFG_MATRIX_ADMIN_USERNAME:-admin}" + local admin_pass="${CFG_MATRIX_ADMIN_PASSWORD_1}" + local cache="${containers_dir}matrix/${_matrix_token_cache}" + + if [[ -z "$admin_pass" || "$admin_pass" == RANDOMIZEDPASSWORD* ]]; then + isError "No Matrix admin password in matrix.config — cannot authenticate to the admin API." + return 1 + fi + + local cached="" + [[ -s "$cache" ]] && cached=$(runFileOp cat "$cache" 2>/dev/null) + + local raw + raw=$(runFileOp docker exec -i "$@" \ + -e LP_ADMIN_USER="$admin_user" \ + -e LP_ADMIN_PASS="$admin_pass" \ + -e LP_TOKEN="$cached" \ + matrix-synapse python - <&1) + + _matrixApiFailed "$out" "Creating $uid" && return 1 + [[ "$out" == *LP_EXISTS* ]] && { isError "$uid already exists."; return 1; } + [[ "$out" != *LP_OK* ]] && { isError "Creating $uid failed: $out"; return 1; } + + isSuccessful "Matrix user created — ID: $uid — Password: $password" +} + +authAdapter_matrix_setPassword() { + local user="$1" password="$2" + [[ -z "$user" ]] && { isError "A username is required."; return 1; } + [[ -z "$password" ]] && password=$(generateRandomPassword) + + local uid; uid=$(_matrixUserId "$user") || { isError "Could not determine the homeserver name."; return 1; } + + local out + out=$(_matrixApi " +uid = os.environ['LP_UID'] +if not call('GET', '/_synapse/admin/v2/users/' + uid, quiet404=True): + print('LP_MISSING') +else: + # logout_devices invalidates every existing session, which is the whole + # point of a reset — otherwise a stolen token keeps working afterwards. + call('PUT', '/_synapse/admin/v2/users/' + uid, { + 'password': os.environ['LP_NEWPASS'], + 'logout_devices': True, + }) + print('LP_OK') +" -e LP_UID="$uid" -e LP_NEWPASS="$password" 2>&1) + + _matrixApiFailed "$out" "Resetting $uid" && return 1 + [[ "$out" == *LP_MISSING* ]] && { isError "No Matrix user $uid."; return 1; } + [[ "$out" != *LP_OK* ]] && { isError "Resetting $uid failed: $out"; return 1; } + + # Keep the config in step when the admin's own password changes, or the + # WebUI card and these very tools would carry on offering the old one. + local admin_uid; admin_uid=$(_matrixUserId "${CFG_MATRIX_ADMIN_USERNAME:-admin}") + [[ "$uid" == "$admin_uid" ]] && authPersistCfg matrix ADMIN_PASSWORD "$password" + + isSuccessful "Matrix password set for $uid — New password: $password — all their sessions were signed out." +} + +authAdapter_matrix_listUsers() { + local out + out=$(_matrixApi " +res = call('GET', '/_synapse/admin/v2/users?from=0&limit=500&deactivated=true') +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')) +print('LP_TOTAL:' + str(res.get('total', 0))) +" 2>&1) + + _matrixApiFailed "$out" "Listing users" && return 1 + + local line total=0 + while IFS= read -r line; do + case "$line" in + LP_USER*) IFS=$'\t' read -r _ uid name flags <<< "$line" + printf ' %-34s %-20s %s\n' "$uid" "$name" "$flags" ;; + LP_TOTAL:*) total="${line#LP_TOTAL:}" ;; + esac + done <<< "$out" + isSuccessful "$total Matrix account(s)." +} + +# Matrix has no delete — deactivation is as far as it goes, and it is +# irreversible. Named deleteUser to match the adapter contract the other apps +# use, but the message is explicit about what actually happens. +authAdapter_matrix_deleteUser() { + local user="$1" + [[ -z "$user" ]] && { isError "A username is required."; return 1; } + + local uid; uid=$(_matrixUserId "$user") || { isError "Could not determine the homeserver name."; return 1; } + local admin_uid; admin_uid=$(_matrixUserId "${CFG_MATRIX_ADMIN_USERNAME:-admin}") + if [[ "$uid" == "$admin_uid" ]]; then + isError "Refusing to deactivate $uid — it is the admin these tools authenticate as." + isNotice "Promote another account to admin and point CFG_MATRIX_ADMIN_USERNAME at it first." + return 1 + fi + + local out + out=$(_matrixApi " +uid = os.environ['LP_UID'] +if not call('GET', '/_synapse/admin/v2/users/' + uid, quiet404=True): + print('LP_MISSING') +else: + call('POST', '/_synapse/admin/v1/deactivate/' + uid, {'erase': True}) + print('LP_OK') +" -e LP_UID="$uid" 2>&1) + + _matrixApiFailed "$out" "Deactivating $uid" && return 1 + [[ "$out" == *LP_MISSING* ]] && { isError "No Matrix user $uid."; return 1; } + [[ "$out" != *LP_OK* ]] && { isError "Deactivating $uid failed: $out"; return 1; } + + isSuccessful "Matrix user $uid deactivated and erased. The ID is permanently taken and cannot be re-registered." +} + +authAdapter_matrix_setAdmin() { + local user="$1" isAdmin="$2" + [[ -z "$user" ]] && { isError "A username is required."; return 1; } + local target="false"; [[ "$isAdmin" == "true" ]] && target="true" + + local uid; uid=$(_matrixUserId "$user") || { isError "Could not determine the homeserver name."; return 1; } + local admin_uid; admin_uid=$(_matrixUserId "${CFG_MATRIX_ADMIN_USERNAME:-admin}") + if [[ "$uid" == "$admin_uid" && "$target" == "false" ]]; then + isError "Refusing to demote $uid — it is the admin these tools authenticate as, and demoting it would lock them out." + return 1 + fi + + local py_bool="False"; [[ "$target" == "true" ]] && py_bool="True" + local out + out=$(_matrixApi " +uid = os.environ['LP_UID'] +if not call('GET', '/_synapse/admin/v2/users/' + uid, quiet404=True): + print('LP_MISSING') +else: + call('PUT', '/_synapse/admin/v2/users/' + uid, {'admin': ${py_bool}}) + print('LP_OK') +" -e LP_UID="$uid" 2>&1) + + _matrixApiFailed "$out" "Changing admin status for $uid" && return 1 + [[ "$out" == *LP_MISSING* ]] && { isError "No Matrix user $uid."; return 1; } + [[ "$out" != *LP_OK* ]] && { isError "Changing admin status for $uid failed: $out"; return 1; } + + isSuccessful "Matrix user $uid admin → $target." +} diff --git a/containers/matrix/scripts/matrix_install_hooks.sh b/containers/matrix/scripts/matrix_install_hooks.sh index c441d0c..68ca98f 100644 --- a/containers/matrix/scripts/matrix_install_hooks.sh +++ b/containers/matrix/scripts/matrix_install_hooks.sh @@ -211,8 +211,8 @@ matrix_install_post_compose() result=$(copyResource "$app_name" "homeserver.yaml" "data" | runInstallWrite -a "$logs_dir/$docker_log_file" 2>&1) checkSuccess "Copying homeserver.yaml to $data_dir" - result=$(copyResource "$app_name" "log.config" "data" | runInstallWrite -a "$logs_dir/$docker_log_file" 2>&1) - checkSuccess "Copying log.config to $data_dir" + result=$(copyResource "$app_name" "log.yaml" "data" | runInstallWrite -a "$logs_dir/$docker_log_file" 2>&1) + checkSuccess "Copying log.yaml to $data_dir" local homeserver_file="$data_dir/homeserver.yaml" diff --git a/containers/matrix/tools/matrix.tools.json b/containers/matrix/tools/matrix.tools.json new file mode 100644 index 0000000..b363b0a --- /dev/null +++ b/containers/matrix/tools/matrix.tools.json @@ -0,0 +1,106 @@ +{ + "tools": [ + { + "id": "create_account", + "category": "users", + "label": "Create User Account", + "description": "Add a Matrix account. The username becomes permanent — @name:server can never be renamed.", + "icon": "👤", + "fields": [ + { + "name": "username", + "label": "Username", + "type": "text", + "placeholder": "alice (not the full @alice:server)", + "required": true + }, + { + "name": "displayname", + "label": "Display name", + "type": "text", + "placeholder": "Leave blank to use the username" + }, + { + "name": "password", + "label": "Password", + "type": "password", + "placeholder": "Leave blank to generate" + }, + { + "name": "admin", + "label": "Make server admin", + "type": "checkbox", + "default": false + } + ] + }, + { + "id": "list_users", + "category": "users", + "label": "List Users", + "description": "Every account on this homeserver, including deactivated ones.", + "icon": "📋", + "fields": [] + }, + { + "id": "reset_password", + "category": "users", + "label": "Reset User Password", + "description": "Set a new password and sign the user out of every device.", + "icon": "🔑", + "fields": [ + { + "name": "username", + "label": "Username", + "type": "text", + "placeholder": "alice", + "required": true + }, + { + "name": "password", + "label": "New password", + "type": "password", + "placeholder": "Leave blank to generate" + } + ] + }, + { + "id": "set_admin", + "category": "users", + "label": "Set Admin Status", + "description": "Grant or revoke Synapse server-admin rights.", + "icon": "👑", + "fields": [ + { + "name": "username", + "label": "Username", + "type": "text", + "required": true + }, + { + "name": "admin", + "label": "Make server admin", + "type": "checkbox", + "default": false + } + ] + }, + { + "id": "deactivate_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.", + "icon": "🚫", + "destructive": true, + "confirm": "This cannot be undone, and the user ID can never be registered again.", + "fields": [ + { + "name": "username", + "label": "Username", + "type": "text", + "required": true + } + ] + } + ] +} diff --git a/containers/matrix/tools/matrix_create_account.sh b/containers/matrix/tools/matrix_create_account.sh new file mode 100644 index 0000000..fce496f --- /dev/null +++ b/containers/matrix/tools/matrix_create_account.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +appMatrixCreateAccount() { + local args="$1" + authAdapterCall matrix createUser \ + "$(authToolArg "$args" username)" \ + "$(authToolArg "$args" password)" \ + "$(authToolArg "$args" displayname)" \ + "$(authToolArg "$args" admin)" +} diff --git a/containers/matrix/tools/matrix_deactivate_user.sh b/containers/matrix/tools/matrix_deactivate_user.sh new file mode 100644 index 0000000..38fbb2f --- /dev/null +++ b/containers/matrix/tools/matrix_deactivate_user.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Named deactivate rather than delete on purpose — Matrix has no delete, and +# calling it one would misrepresent what the button does. +appMatrixDeactivateUser() { + local args="$1" + authAdapterCall matrix deleteUser "$(authToolArg "$args" username)" +} diff --git a/containers/matrix/tools/matrix_list_users.sh b/containers/matrix/tools/matrix_list_users.sh new file mode 100644 index 0000000..5db979f --- /dev/null +++ b/containers/matrix/tools/matrix_list_users.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +appMatrixListUsers() { + authAdapterCall matrix listUsers +} diff --git a/containers/matrix/tools/matrix_reset_password.sh b/containers/matrix/tools/matrix_reset_password.sh new file mode 100644 index 0000000..3719ff5 --- /dev/null +++ b/containers/matrix/tools/matrix_reset_password.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +appMatrixResetPassword() { + local args="$1" + authAdapterCall matrix setPassword \ + "$(authToolArg "$args" username)" \ + "$(authToolArg "$args" password)" +} diff --git a/containers/matrix/tools/matrix_set_admin.sh b/containers/matrix/tools/matrix_set_admin.sh new file mode 100644 index 0000000..0dd94a2 --- /dev/null +++ b/containers/matrix/tools/matrix_set_admin.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +appMatrixSetAdmin() { + local args="$1" + authAdapterCall matrix setAdmin \ + "$(authToolArg "$args" username)" \ + "$(authToolArg "$args" admin)" +} diff --git a/scripts/source/files/arrays/function_manifest.sh b/scripts/source/files/arrays/function_manifest.sh index 94960dd..165ccfc 100644 --- a/scripts/source/files/arrays/function_manifest.sh +++ b/scripts/source/files/arrays/function_manifest.sh @@ -57,6 +57,11 @@ declare -gA LP_FN_MAP=( [appLinkdingListUsers]="linkding/tools/linkding_list_users.sh" [appLinkdingResetPassword]="linkding/tools/linkding_reset_password.sh" [appLinkdingSetAdmin]="linkding/tools/linkding_set_admin.sh" + [appMatrixCreateAccount]="matrix/tools/matrix_create_account.sh" + [appMatrixDeactivateUser]="matrix/tools/matrix_deactivate_user.sh" + [appMatrixListUsers]="matrix/tools/matrix_list_users.sh" + [appMatrixResetPassword]="matrix/tools/matrix_reset_password.sh" + [appMatrixSetAdmin]="matrix/tools/matrix_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" @@ -148,6 +153,11 @@ declare -gA LP_FN_MAP=( [authAdapter_linkding_listUsers]="linkding/scripts/linkding_auth.sh" [authAdapter_linkding_setAdmin]="linkding/scripts/linkding_auth.sh" [authAdapter_linkding_setPassword]="linkding/scripts/linkding_auth.sh" + [authAdapter_matrix_createUser]="matrix/scripts/matrix_auth.sh" + [authAdapter_matrix_deleteUser]="matrix/scripts/matrix_auth.sh" + [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_nextcloud_createUser]="nextcloud/scripts/nextcloud_auth.sh" [authAdapter_nextcloud_deleteUser]="nextcloud/scripts/nextcloud_auth.sh" [authAdapter_nextcloud_listUsers]="nextcloud/scripts/nextcloud_auth.sh" @@ -648,12 +658,15 @@ declare -gA LP_FN_MAP=( [manifestWrite]="backup/manifest/manifest_write.sh" [mastodon_install_post_setup]="mastodon/scripts/mastodon_install_hooks.sh" [mastodon_upgrade_verify]="mastodon/scripts/mastodon_upgrade_hooks.sh" + [_matrixApi]="matrix/scripts/matrix_auth.sh" + [_matrixApiFailed]="matrix/scripts/matrix_auth.sh" [matrix_install_post]="matrix/scripts/matrix_install_hooks.sh" [matrix_install_post_compose]="matrix/scripts/matrix_install_hooks.sh" [matrix_install_post_start]="matrix/scripts/matrix_install_hooks.sh" [matrix_install_pre]="matrix/scripts/matrix_install_hooks.sh" [_matrixPublicBaseUrl]="matrix/scripts/matrix_install_hooks.sh" [_matrixServerName]="matrix/scripts/matrix_install_hooks.sh" + [_matrixUserId]="matrix/scripts/matrix_auth.sh" [mattermostToolsMenu]="menu/tools/manage_mattermost.sh" [maybeRegenPoll]="task/crontab_task_processor.sh" [menuContinue]="menu/message/continue.sh" @@ -1118,6 +1131,11 @@ declare -gA LP_FN_ROOT=( [appLinkdingListUsers]="containers" [appLinkdingResetPassword]="containers" [appLinkdingSetAdmin]="containers" + [appMatrixCreateAccount]="containers" + [appMatrixDeactivateUser]="containers" + [appMatrixListUsers]="containers" + [appMatrixResetPassword]="containers" + [appMatrixSetAdmin]="containers" [appNetworkApplyMode_gluetun]="containers" [appNetworkRegisterPorts_gluetun]="containers" [appNextcloudAddTrustedDomain]="containers" @@ -1209,6 +1227,11 @@ declare -gA LP_FN_ROOT=( [authAdapter_linkding_listUsers]="containers" [authAdapter_linkding_setAdmin]="containers" [authAdapter_linkding_setPassword]="containers" + [authAdapter_matrix_createUser]="containers" + [authAdapter_matrix_deleteUser]="containers" + [authAdapter_matrix_listUsers]="containers" + [authAdapter_matrix_setAdmin]="containers" + [authAdapter_matrix_setPassword]="containers" [authAdapter_nextcloud_createUser]="containers" [authAdapter_nextcloud_deleteUser]="containers" [authAdapter_nextcloud_listUsers]="containers" @@ -1709,12 +1732,15 @@ declare -gA LP_FN_ROOT=( [manifestWrite]="scripts" [mastodon_install_post_setup]="containers" [mastodon_upgrade_verify]="containers" + [_matrixApi]="containers" + [_matrixApiFailed]="containers" [matrix_install_post]="containers" [matrix_install_post_compose]="containers" [matrix_install_post_start]="containers" [matrix_install_pre]="containers" [_matrixPublicBaseUrl]="containers" [_matrixServerName]="containers" + [_matrixUserId]="containers" [mattermostToolsMenu]="scripts" [maybeRegenPoll]="scripts" [menuContinue]="scripts" @@ -2213,6 +2239,11 @@ appLinkdingDeleteUser() { unset -f appLinkdingDeleteUser; __lpAutoload "${instal appLinkdingListUsers() { unset -f appLinkdingListUsers; __lpAutoload "${install_containers_dir}linkding/tools/linkding_list_users.sh"; appLinkdingListUsers "$@"; } appLinkdingResetPassword() { unset -f appLinkdingResetPassword; __lpAutoload "${install_containers_dir}linkding/tools/linkding_reset_password.sh"; appLinkdingResetPassword "$@"; } appLinkdingSetAdmin() { unset -f appLinkdingSetAdmin; __lpAutoload "${install_containers_dir}linkding/tools/linkding_set_admin.sh"; appLinkdingSetAdmin "$@"; } +appMatrixCreateAccount() { unset -f appMatrixCreateAccount; __lpAutoload "${install_containers_dir}matrix/tools/matrix_create_account.sh"; appMatrixCreateAccount "$@"; } +appMatrixDeactivateUser() { unset -f appMatrixDeactivateUser; __lpAutoload "${install_containers_dir}matrix/tools/matrix_deactivate_user.sh"; appMatrixDeactivateUser "$@"; } +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 "$@"; } 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 "$@"; } @@ -2304,6 +2335,11 @@ authAdapter_linkding_deleteUser() { unset -f authAdapter_linkding_deleteUser; __ authAdapter_linkding_listUsers() { unset -f authAdapter_linkding_listUsers; __lpAutoload "${install_containers_dir}linkding/scripts/linkding_auth.sh"; authAdapter_linkding_listUsers "$@"; } authAdapter_linkding_setAdmin() { unset -f authAdapter_linkding_setAdmin; __lpAutoload "${install_containers_dir}linkding/scripts/linkding_auth.sh"; authAdapter_linkding_setAdmin "$@"; } authAdapter_linkding_setPassword() { unset -f authAdapter_linkding_setPassword; __lpAutoload "${install_containers_dir}linkding/scripts/linkding_auth.sh"; authAdapter_linkding_setPassword "$@"; } +authAdapter_matrix_createUser() { unset -f authAdapter_matrix_createUser; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_auth.sh"; authAdapter_matrix_createUser "$@"; } +authAdapter_matrix_deleteUser() { unset -f authAdapter_matrix_deleteUser; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_auth.sh"; authAdapter_matrix_deleteUser "$@"; } +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_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 "$@"; } @@ -2804,12 +2840,15 @@ manifestRemove() { unset -f manifestRemove; __lpAutoload "${install_scripts_dir} manifestWrite() { unset -f manifestWrite; __lpAutoload "${install_scripts_dir}backup/manifest/manifest_write.sh"; manifestWrite "$@"; } mastodon_install_post_setup() { unset -f mastodon_install_post_setup; __lpAutoload "${install_containers_dir}mastodon/scripts/mastodon_install_hooks.sh"; mastodon_install_post_setup "$@"; } mastodon_upgrade_verify() { unset -f mastodon_upgrade_verify; __lpAutoload "${install_containers_dir}mastodon/scripts/mastodon_upgrade_hooks.sh"; mastodon_upgrade_verify "$@"; } +_matrixApi() { unset -f _matrixApi; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_auth.sh"; _matrixApi "$@"; } +_matrixApiFailed() { unset -f _matrixApiFailed; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_auth.sh"; _matrixApiFailed "$@"; } matrix_install_post() { unset -f matrix_install_post; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_install_hooks.sh"; matrix_install_post "$@"; } matrix_install_post_compose() { unset -f matrix_install_post_compose; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_install_hooks.sh"; matrix_install_post_compose "$@"; } matrix_install_post_start() { unset -f matrix_install_post_start; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_install_hooks.sh"; matrix_install_post_start "$@"; } matrix_install_pre() { unset -f matrix_install_pre; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_install_hooks.sh"; matrix_install_pre "$@"; } _matrixPublicBaseUrl() { unset -f _matrixPublicBaseUrl; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_install_hooks.sh"; _matrixPublicBaseUrl "$@"; } _matrixServerName() { unset -f _matrixServerName; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_install_hooks.sh"; _matrixServerName "$@"; } +_matrixUserId() { unset -f _matrixUserId; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_auth.sh"; _matrixUserId "$@"; } mattermostToolsMenu() { unset -f mattermostToolsMenu; __lpAutoload "${install_scripts_dir}menu/tools/manage_mattermost.sh"; mattermostToolsMenu "$@"; } maybeRegenPoll() { unset -f maybeRegenPoll; __lpAutoload "${install_scripts_dir}task/crontab_task_processor.sh"; maybeRegenPoll "$@"; } menuContinue() { unset -f menuContinue; __lpAutoload "${install_scripts_dir}menu/message/continue.sh"; menuContinue "$@"; }