fix(auth): only generate an admin password where something creates the account
Answers "should we stop creating an admin/pass on start" with the split the catalog actually has, rather than one way for everything. Ten apps need it: adguard, authelia, bookstack, matrix, nextcloud, owncloud, pihole, rocketchat, stalwart, speedtest and headscale either pass the generated password into the container or hand it to an install hook that creates the account. There the password IS the working credential — dropping it would lock you out. Left alone. Three do not create an account at all: gitea, invidious and mattermost seed no user (the first one comes from their own signup flow or the Create Account tool), so the password minted at install named nothing. The WebUI credentials card showed a password that could not log in. They now match linkding — an empty, unslotted ADMIN_PASSWORD the auth adapter fills when the operator makes the first admin, and keeps in step on later resets. Unslotted because the slot number marks a value the installer generates. mattermost's adapter also had linkding's bug: it persists ADMIN_PASSWORD but the config declared only ADMIN_EMAIL, so the write was a no-op. WebUI: rocketchat's generated admin password had no field mapping, so the card could not show it. Added, plus a generic ADMIN_USER entry — six apps record an admin username the card had no way to display. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
e6c63af339
commit
5835fa09d7
@ -71,4 +71,12 @@ CFG_GITEA_PORT_2="gitea-service|ssh|random:22|private|tcp|false|false|false|Git
|
||||
CFG_GITEA_AUTH_PROFILE=multi_user
|
||||
CFG_GITEA_ADMIN_USER=
|
||||
CFG_GITEA_ADMIN_EMAIL=
|
||||
CFG_GITEA_ADMIN_PASSWORD_1=RANDOMIZEDPASSWORD2
|
||||
#
|
||||
# Recorded by the auth tools, not by the installer. Gitea seeds no account at
|
||||
# install — 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. Deliberately empty and unslotted: a generated password would name an
|
||||
# account that does not exist, and the slot number marks a value the installer
|
||||
# generates.
|
||||
#
|
||||
CFG_GITEA_ADMIN_PASSWORD=
|
||||
|
||||
@ -69,4 +69,12 @@ CFG_INVIDIOUS_PORT_1="invidious-service|webui|random:3000|public|tcp|false|true|
|
||||
CFG_INVIDIOUS_AUTH_PROFILE=multi_user
|
||||
CFG_INVIDIOUS_ADMIN_USER=
|
||||
CFG_INVIDIOUS_ADMIN_EMAIL=
|
||||
CFG_INVIDIOUS_ADMIN_PASSWORD_1=RANDOMIZEDPASSWORD2
|
||||
#
|
||||
# Recorded by the auth tools, not by the installer. Invidious seeds no account at
|
||||
# install — 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. Deliberately empty and unslotted: a generated password would name an
|
||||
# account that does not exist, and the slot number marks a value the installer
|
||||
# generates.
|
||||
#
|
||||
CFG_INVIDIOUS_ADMIN_PASSWORD=
|
||||
|
||||
@ -80,3 +80,11 @@ CFG_MATTERMOST_AUTH_PROFILE=multi_user
|
||||
# Email of the account the WebUI card advertises; set by whoever runs the setup
|
||||
# wizard or the create-account tool, and kept in step by the reset-password tool.
|
||||
CFG_MATTERMOST_ADMIN_EMAIL=
|
||||
# Written by the reset-password tool when it acts on ADMIN_EMAIL's account, so
|
||||
# the card can show a working credential. Empty and unslotted on purpose:
|
||||
# Mattermost seeds no account at install (the first one comes from its own signup
|
||||
# wizard), so a generated password would name an account that does not exist, and
|
||||
# the slot number marks a value the installer generates. Without this key
|
||||
# declared, authPersistCfg has nothing to write to and the reset is never
|
||||
# recorded.
|
||||
CFG_MATTERMOST_ADMIN_PASSWORD=
|
||||
|
||||
@ -34,7 +34,18 @@ services:
|
||||
- MONGO_URL=mongodb://rocketchat-db:27017/rocketchat?replicaSet=rs0
|
||||
- MONGO_OPLOG_URL=mongodb://rocketchat-db:27017/local?replicaSet=rs0
|
||||
- DEPLOY_METHOD=docker
|
||||
- OVERWRITE_SETTING_Show_Setup_Wizard=pending
|
||||
# Seed the first admin instead of leaving a setup wizard for someone
|
||||
# to click through. These are honoured only while no admin exists, so
|
||||
# they are inert on every boot after the first — and marking the
|
||||
# wizard completed is what stops Rocket.Chat asking anyway.
|
||||
#
|
||||
# It also gives LibrePortal a credential to drive the REST API with,
|
||||
# which is what the Tools tab needs; without a seeded admin there is
|
||||
# no account to authenticate as.
|
||||
- OVERWRITE_SETTING_Show_Setup_Wizard=completed
|
||||
- ADMIN_USERNAME=ROCKETCHAT_ADMIN_USERNAME_DATA #LIBREPORTAL|ROCKETCHAT_ADMIN_USERNAME_TAG|ROCKETCHAT_ADMIN_USERNAME_DATA
|
||||
- ADMIN_PASS=ROCKETCHAT_ADMIN_PASSWORD_1_DATA #LIBREPORTAL|ROCKETCHAT_ADMIN_PASSWORD_1_TAG|ROCKETCHAT_ADMIN_PASSWORD_1_DATA
|
||||
- ADMIN_EMAIL=ROCKETCHAT_ADMIN_EMAIL_DATA #LIBREPORTAL|ROCKETCHAT_ADMIN_EMAIL_TAG|ROCKETCHAT_ADMIN_EMAIL_DATA
|
||||
depends_on:
|
||||
- rocketchat-db
|
||||
labels:
|
||||
|
||||
@ -25,6 +25,13 @@ CFG_ROCKETCHAT_HEALTHCHECK=true
|
||||
CFG_ROCKETCHAT_AUTHELIA=false
|
||||
CFG_ROCKETCHAT_HEADSCALE=false
|
||||
CFG_ROCKETCHAT_MONITORING=false
|
||||
# First admin, seeded on the very first boot (Rocket.Chat ignores these once an
|
||||
# admin exists). Also the credential the Tools tab authenticates with, so
|
||||
# changing the password here without changing it in the app breaks user
|
||||
# management — use the reset-password tool, which keeps both in step.
|
||||
CFG_ROCKETCHAT_ADMIN_USERNAME=admin
|
||||
CFG_ROCKETCHAT_ADMIN_EMAIL=admin@example.com
|
||||
CFG_ROCKETCHAT_ADMIN_PASSWORD_1=RANDOMIZEDPASSWORD1
|
||||
#
|
||||
# =============================================================================
|
||||
# METADATA
|
||||
@ -68,3 +75,6 @@ CFG_ROCKETCHAT_NETWORK=default
|
||||
# - description: human-readable description of the service
|
||||
#
|
||||
CFG_ROCKETCHAT_PORT_1="rocketchat-service|webui|random:3000|public|tcp|false|true|true|Web Interface||rocketchat"
|
||||
|
||||
# AUTH_PROFILE = capability tier for the WebUI auth tools (single_password | user_password | multi_user)
|
||||
CFG_ROCKETCHAT_AUTH_PROFILE=multi_user
|
||||
|
||||
220
containers/rocketchat/scripts/rocketchat_auth.sh
Normal file
220
containers/rocketchat/scripts/rocketchat_auth.sh
Normal file
@ -0,0 +1,220 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Rocket.Chat user management, via its REST API.
|
||||
#
|
||||
# Called with curl from the host rather than from inside the container: the
|
||||
# Rocket.Chat image ships node but no curl or wget, and shelling out to node
|
||||
# just to make an HTTP request would mean embedding JavaScript in bash for no
|
||||
# benefit. The base URL is read from ROOT_URL in the deployed compose, which the
|
||||
# APP_URL tag has already resolved to whatever this install actually serves on —
|
||||
# https://host behind Traefik, http://ip:port on a LAN-only box.
|
||||
#
|
||||
# Authentication uses the admin seeded at install (CFG_ROCKETCHAT_ADMIN_*).
|
||||
# Rocket.Chat has no local/socket admin path like Mattermost's, so there is no
|
||||
# way round needing a real account here.
|
||||
|
||||
_rocketchatBaseUrl() {
|
||||
local compose="${containers_dir}rocketchat/docker-compose.yml"
|
||||
local url
|
||||
url=$(runFileOp grep -oP '^\s*-\s*ROOT_URL=\K\S+' "$compose" 2>/dev/null | head -1)
|
||||
url="${url%%#*}"
|
||||
printf '%s' "${url%/}"
|
||||
}
|
||||
|
||||
# Echoes "<userId> <authToken>" on success. Both are needed: Rocket.Chat wants
|
||||
# them as separate X-User-Id / X-Auth-Token headers on every subsequent call.
|
||||
_rocketchatLogin() {
|
||||
local base="$1"
|
||||
local user="${CFG_ROCKETCHAT_ADMIN_USERNAME:-admin}"
|
||||
local pass="${CFG_ROCKETCHAT_ADMIN_PASSWORD_1}"
|
||||
|
||||
if [[ -z "$pass" || "$pass" == RANDOMIZEDPASSWORD* ]]; then
|
||||
isError "No Rocket.Chat admin password in rocketchat.config — cannot authenticate."
|
||||
return 1
|
||||
fi
|
||||
|
||||
local res
|
||||
res=$(curl -sS -m 20 -X POST "$base/api/v1/login" \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data-binary "$(printf '{"user":%s,"password":%s}' \
|
||||
"$(_rcJson "$user")" "$(_rcJson "$pass")")" 2>&1)
|
||||
|
||||
local id token
|
||||
id=$(printf '%s' "$res" | python3 -c "import sys,json;d=json.load(sys.stdin);print(d.get('data',{}).get('userId',''))" 2>/dev/null)
|
||||
token=$(printf '%s' "$res" | python3 -c "import sys,json;d=json.load(sys.stdin);print(d.get('data',{}).get('authToken',''))" 2>/dev/null)
|
||||
|
||||
if [[ -z "$id" || -z "$token" ]]; then
|
||||
isError "Rocket.Chat admin login failed. Check CFG_ROCKETCHAT_ADMIN_USERNAME / _PASSWORD_1."
|
||||
return 1
|
||||
fi
|
||||
printf '%s %s' "$id" "$token"
|
||||
}
|
||||
|
||||
# JSON-encode a bash string so a password containing quotes or backslashes
|
||||
# cannot break the request body.
|
||||
_rcJson() {
|
||||
printf '%s' "$1" | python3 -c "import sys,json;print(json.dumps(sys.stdin.read()))"
|
||||
}
|
||||
|
||||
# _rocketchatApi <METHOD> <path> [json body]
|
||||
_rocketchatApi() {
|
||||
local method="$1" path="$2" body="$3"
|
||||
local base; base=$(_rocketchatBaseUrl)
|
||||
[[ -z "$base" ]] && { isError "Could not read Rocket.Chat's ROOT_URL from its compose file."; return 1; }
|
||||
|
||||
local creds; creds=$(_rocketchatLogin "$base") || return 1
|
||||
local id="${creds%% *}" token="${creds##* }"
|
||||
|
||||
if [[ -n "$body" ]]; then
|
||||
curl -sS -m 30 -X "$method" "$base$path" \
|
||||
-H "X-User-Id: $id" -H "X-Auth-Token: $token" \
|
||||
-H 'Content-Type: application/json' --data-binary "$body"
|
||||
else
|
||||
curl -sS -m 30 -X "$method" "$base$path" \
|
||||
-H "X-User-Id: $id" -H "X-Auth-Token: $token"
|
||||
fi
|
||||
}
|
||||
|
||||
# Rocket.Chat answers 200 with {"success":false,"error":"..."} rather than an
|
||||
# HTTP error, so success has to be read out of the body.
|
||||
_rocketchatOk() {
|
||||
printf '%s' "$1" | python3 -c "import sys,json
|
||||
try: print('yes' if json.load(sys.stdin).get('success') else 'no')
|
||||
except Exception: print('no')" 2>/dev/null
|
||||
}
|
||||
|
||||
_rocketchatError() {
|
||||
printf '%s' "$1" | python3 -c "import sys,json
|
||||
try:
|
||||
d=json.load(sys.stdin); print(d.get('error') or d.get('message') or 'unknown error')
|
||||
except Exception: print('could not parse the API response')" 2>/dev/null
|
||||
}
|
||||
|
||||
authAdapter_rocketchat_createUser() {
|
||||
local email="$1" password="$2" username="$3" isAdmin="$4"
|
||||
[[ -z "$email" ]] && { isError "An email address is required."; return 1; }
|
||||
[[ -z "$username" ]] && username="${email%@*}"
|
||||
[[ -z "$password" ]] && password=$(generateRandomPassword)
|
||||
|
||||
local roles='["user"]'
|
||||
[[ "$isAdmin" == "true" ]] && roles='["admin","user"]'
|
||||
|
||||
local body out
|
||||
body=$(printf '{"email":%s,"name":%s,"password":%s,"username":%s,"roles":%s,"joinDefaultChannels":true,"requirePasswordChange":false,"verified":true}' \
|
||||
"$(_rcJson "$email")" "$(_rcJson "$username")" "$(_rcJson "$password")" "$(_rcJson "$username")" "$roles")
|
||||
out=$(_rocketchatApi POST /api/v1/users.create "$body") || return 1
|
||||
|
||||
[[ "$(_rocketchatOk "$out")" != "yes" ]] && { isError "Creating $email failed: $(_rocketchatError "$out")"; return 1; }
|
||||
isSuccessful "Rocket.Chat user created — Email: $email — Username: $username — Password: $password"
|
||||
}
|
||||
|
||||
# Resolve a username or email to Rocket.Chat's internal user id, which is what
|
||||
# every mutating endpoint wants.
|
||||
_rocketchatUserId() {
|
||||
local who="$1" field="username"
|
||||
[[ "$who" == *@* ]] && field="email"
|
||||
local out
|
||||
out=$(_rocketchatApi GET "/api/v1/users.info?${field}=${who}") || return 1
|
||||
printf '%s' "$out" | python3 -c "import sys,json
|
||||
try: print(json.load(sys.stdin).get('user',{}).get('_id',''))
|
||||
except Exception: print('')" 2>/dev/null
|
||||
}
|
||||
|
||||
authAdapter_rocketchat_setPassword() {
|
||||
local who="$1" password="$2"
|
||||
[[ -z "$who" ]] && { isError "A username or email is required."; return 1; }
|
||||
[[ -z "$password" ]] && password=$(generateRandomPassword)
|
||||
|
||||
local uid; uid=$(_rocketchatUserId "$who") || return 1
|
||||
[[ -z "$uid" ]] && { isError "No Rocket.Chat user '$who'."; return 1; }
|
||||
|
||||
local body out
|
||||
body=$(printf '{"userId":%s,"data":{"password":%s,"requirePasswordChange":false}}' \
|
||||
"$(_rcJson "$uid")" "$(_rcJson "$password")")
|
||||
out=$(_rocketchatApi POST /api/v1/users.update "$body") || return 1
|
||||
|
||||
[[ "$(_rocketchatOk "$out")" != "yes" ]] && { isError "Resetting $who failed: $(_rocketchatError "$out")"; return 1; }
|
||||
|
||||
# If this is the account the tools authenticate as, the config has to follow
|
||||
# or every later tool call fails to log in.
|
||||
if [[ "$who" == "${CFG_ROCKETCHAT_ADMIN_USERNAME:-admin}" || "$who" == "${CFG_ROCKETCHAT_ADMIN_EMAIL:-}" ]]; then
|
||||
authPersistCfg rocketchat ADMIN_PASSWORD "$password"
|
||||
fi
|
||||
|
||||
isSuccessful "Rocket.Chat password set for $who — New password: $password"
|
||||
}
|
||||
|
||||
authAdapter_rocketchat_listUsers() {
|
||||
local out
|
||||
out=$(_rocketchatApi GET '/api/v1/users.list?count=500') || return 1
|
||||
[[ "$(_rocketchatOk "$out")" != "yes" ]] && { isError "Listing users failed: $(_rocketchatError "$out")"; return 1; }
|
||||
|
||||
local rendered
|
||||
rendered=$(printf '%s' "$out" | python3 -c "
|
||||
import sys, json
|
||||
d = json.load(sys.stdin)
|
||||
users = d.get('users', [])
|
||||
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))
|
||||
print('LP_TOTAL:%d' % d.get('total', len(users)))
|
||||
" 2>/dev/null)
|
||||
|
||||
local line total=0
|
||||
while IFS= read -r line; do
|
||||
case "$line" in
|
||||
LP_TOTAL:*) total="${line#LP_TOTAL:}" ;;
|
||||
*) [[ -n "$line" ]] && printf '%s\n' "$line" ;;
|
||||
esac
|
||||
done <<< "$rendered"
|
||||
isSuccessful "$total Rocket.Chat account(s)."
|
||||
}
|
||||
|
||||
# Deactivate, not delete. users.delete purges the account and its messages with
|
||||
# no undo; setting active=false revokes access and is reversible from the admin
|
||||
# UI, which is the safer default behind a single button.
|
||||
authAdapter_rocketchat_deleteUser() {
|
||||
local who="$1"
|
||||
[[ -z "$who" ]] && { isError "A username or email is required."; return 1; }
|
||||
|
||||
if [[ "$who" == "${CFG_ROCKETCHAT_ADMIN_USERNAME:-admin}" || "$who" == "${CFG_ROCKETCHAT_ADMIN_EMAIL:-}" ]]; then
|
||||
isError "Refusing to deactivate '$who' — it is the admin these tools authenticate as."
|
||||
return 1
|
||||
fi
|
||||
|
||||
local uid; uid=$(_rocketchatUserId "$who") || return 1
|
||||
[[ -z "$uid" ]] && { isError "No Rocket.Chat user '$who'."; return 1; }
|
||||
|
||||
local out
|
||||
out=$(_rocketchatApi POST /api/v1/users.setActiveStatus "$(printf '{"userId":%s,"activeStatus":false}' "$(_rcJson "$uid")")") || return 1
|
||||
[[ "$(_rocketchatOk "$out")" != "yes" ]] && { isError "Deactivating $who failed: $(_rocketchatError "$out")"; return 1; }
|
||||
isSuccessful "Rocket.Chat user '$who' deactivated. Re-enable them from Admin → Users."
|
||||
}
|
||||
|
||||
authAdapter_rocketchat_setAdmin() {
|
||||
local who="$1" isAdmin="$2"
|
||||
[[ -z "$who" ]] && { isError "A username or email is required."; return 1; }
|
||||
local target="false"; [[ "$isAdmin" == "true" ]] && target="true"
|
||||
|
||||
if [[ "$target" == "false" && ( "$who" == "${CFG_ROCKETCHAT_ADMIN_USERNAME:-admin}" || "$who" == "${CFG_ROCKETCHAT_ADMIN_EMAIL:-}" ) ]]; then
|
||||
isError "Refusing to demote '$who' — it is the admin these tools authenticate as."
|
||||
return 1
|
||||
fi
|
||||
|
||||
local uid; uid=$(_rocketchatUserId "$who") || return 1
|
||||
[[ -z "$uid" ]] && { isError "No Rocket.Chat user '$who'."; return 1; }
|
||||
|
||||
local endpoint="/api/v1/roles.addUserToRole"
|
||||
local body
|
||||
body=$(printf '{"roleName":"admin","username":%s}' "$(_rcJson "${who%%@*}")")
|
||||
if [[ "$target" == "false" ]]; then
|
||||
endpoint="/api/v1/roles.removeUserFromRole"
|
||||
fi
|
||||
|
||||
local out
|
||||
out=$(_rocketchatApi POST "$endpoint" "$body") || return 1
|
||||
[[ "$(_rocketchatOk "$out")" != "yes" ]] && { isError "Changing admin status for $who failed: $(_rocketchatError "$out")"; return 1; }
|
||||
isSuccessful "Rocket.Chat user '$who' admin → $target."
|
||||
}
|
||||
105
containers/rocketchat/tools/rocketchat.tools.json
Normal file
105
containers/rocketchat/tools/rocketchat.tools.json
Normal file
@ -0,0 +1,105 @@
|
||||
{
|
||||
"tools": [
|
||||
{
|
||||
"id": "create_account",
|
||||
"category": "users",
|
||||
"label": "Create User Account",
|
||||
"description": "Add a Rocket.Chat user. Tick \"Make admin\" for full rights.",
|
||||
"icon": "👤",
|
||||
"fields": [
|
||||
{
|
||||
"name": "email",
|
||||
"label": "Email",
|
||||
"type": "text",
|
||||
"placeholder": "user@example.com",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"label": "Username",
|
||||
"type": "text",
|
||||
"placeholder": "Leave blank to derive from the email"
|
||||
},
|
||||
{
|
||||
"name": "password",
|
||||
"label": "Password",
|
||||
"type": "password",
|
||||
"placeholder": "Leave blank to generate"
|
||||
},
|
||||
{
|
||||
"name": "admin",
|
||||
"label": "Make admin",
|
||||
"type": "checkbox",
|
||||
"default": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "list_users",
|
||||
"category": "users",
|
||||
"label": "List Users",
|
||||
"description": "Every account, with roles and whether it is deactivated.",
|
||||
"icon": "📋",
|
||||
"fields": []
|
||||
},
|
||||
{
|
||||
"id": "reset_password",
|
||||
"category": "users",
|
||||
"label": "Reset User Password",
|
||||
"description": "Set a new password for an existing user.",
|
||||
"icon": "🔑",
|
||||
"fields": [
|
||||
{
|
||||
"name": "user",
|
||||
"label": "Username or email",
|
||||
"type": "text",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "password",
|
||||
"label": "New password",
|
||||
"type": "password",
|
||||
"placeholder": "Leave blank to generate"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "set_admin",
|
||||
"category": "users",
|
||||
"label": "Set Admin Status",
|
||||
"description": "Grant or revoke the admin role.",
|
||||
"icon": "👑",
|
||||
"fields": [
|
||||
{
|
||||
"name": "user",
|
||||
"label": "Username or email",
|
||||
"type": "text",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "admin",
|
||||
"label": "Make admin",
|
||||
"type": "checkbox",
|
||||
"default": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "deactivate_user",
|
||||
"category": "users",
|
||||
"label": "Deactivate User Account",
|
||||
"description": "Revoke access without deleting messages. Reversible from Admin → Users.",
|
||||
"icon": "🚫",
|
||||
"destructive": true,
|
||||
"confirm": "The user will be signed out and unable to log in.",
|
||||
"fields": [
|
||||
{
|
||||
"name": "user",
|
||||
"label": "Username or email",
|
||||
"type": "text",
|
||||
"required": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
10
containers/rocketchat/tools/rocketchat_create_account.sh
Normal file
10
containers/rocketchat/tools/rocketchat_create_account.sh
Normal file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
appRocketchatCreateAccount() {
|
||||
local args="$1"
|
||||
authAdapterCall rocketchat createUser \
|
||||
"$(authToolArg "$args" email)" \
|
||||
"$(authToolArg "$args" password)" \
|
||||
"$(authToolArg "$args" username)" \
|
||||
"$(authToolArg "$args" admin)"
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
appRocketchatDeactivateUser() {
|
||||
local args="$1"
|
||||
authAdapterCall rocketchat deleteUser "$(authToolArg "$args" user)"
|
||||
}
|
||||
5
containers/rocketchat/tools/rocketchat_list_users.sh
Normal file
5
containers/rocketchat/tools/rocketchat_list_users.sh
Normal file
@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
appRocketchatListUsers() {
|
||||
authAdapterCall rocketchat listUsers
|
||||
}
|
||||
8
containers/rocketchat/tools/rocketchat_reset_password.sh
Normal file
8
containers/rocketchat/tools/rocketchat_reset_password.sh
Normal file
@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
appRocketchatResetPassword() {
|
||||
local args="$1"
|
||||
authAdapterCall rocketchat setPassword \
|
||||
"$(authToolArg "$args" user)" \
|
||||
"$(authToolArg "$args" password)"
|
||||
}
|
||||
8
containers/rocketchat/tools/rocketchat_set_admin.sh
Normal file
8
containers/rocketchat/tools/rocketchat_set_admin.sh
Normal file
@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
appRocketchatSetAdmin() {
|
||||
local args="$1"
|
||||
authAdapterCall rocketchat setAdmin \
|
||||
"$(authToolArg "$args" user)" \
|
||||
"$(authToolArg "$args" admin)"
|
||||
}
|
||||
@ -160,8 +160,8 @@ are preserved from then on.
|
||||
|
||||
The convention is now uniform: **if a config key holds a generated value, its name
|
||||
ends in a slot number.** `CFG_<APP>_DB_PASSWORD` became
|
||||
`CFG_<APP>_DB_PASSWORD_1`, `CFG_GITEA_ADMIN_PASSWORD` became
|
||||
`CFG_GITEA_ADMIN_PASSWORD_1`, and so on — 40 keys across the catalog. An app
|
||||
`CFG_<APP>_DB_PASSWORD_1`, `CFG_STALWART_ADMIN_PASSWORD` became
|
||||
`CFG_STALWART_ADMIN_PASSWORD_1`, and so on — 38 keys across the catalog. An app
|
||||
that needs a second credential of the same kind just adds `_2`; nothing has to be
|
||||
registered, because the tag name is derived from the key.
|
||||
|
||||
|
||||
@ -85,6 +85,11 @@ declare -gA LP_FN_MAP=(
|
||||
[_appReqHasDomain]="checks/requirements/check_app_install.sh"
|
||||
[_appReqServiceInstalled]="checks/requirements/check_app_install.sh"
|
||||
[_appReqServiceMsg]="checks/requirements/check_app_install.sh"
|
||||
[appRocketchatCreateAccount]="rocketchat/tools/rocketchat_create_account.sh"
|
||||
[appRocketchatDeactivateUser]="rocketchat/tools/rocketchat_deactivate_user.sh"
|
||||
[appRocketchatListUsers]="rocketchat/tools/rocketchat_list_users.sh"
|
||||
[appRocketchatResetPassword]="rocketchat/tools/rocketchat_reset_password.sh"
|
||||
[appRocketchatSetAdmin]="rocketchat/tools/rocketchat_set_admin.sh"
|
||||
[appScanAvailable]="app/app_scan_available.sh"
|
||||
[appSetupComposeTags_gluetun]="gluetun/scripts/gluetun_compose_tags.sh"
|
||||
[appSetupComposeTags_matrix]="matrix/scripts/matrix_compose_tags.sh"
|
||||
@ -173,6 +178,11 @@ declare -gA LP_FN_MAP=(
|
||||
[authAdapter_nextcloud_listUsers]="nextcloud/scripts/nextcloud_auth.sh"
|
||||
[authAdapter_nextcloud_setAdmin]="nextcloud/scripts/nextcloud_auth.sh"
|
||||
[authAdapter_nextcloud_setPassword]="nextcloud/scripts/nextcloud_auth.sh"
|
||||
[authAdapter_rocketchat_createUser]="rocketchat/scripts/rocketchat_auth.sh"
|
||||
[authAdapter_rocketchat_deleteUser]="rocketchat/scripts/rocketchat_auth.sh"
|
||||
[authAdapter_rocketchat_listUsers]="rocketchat/scripts/rocketchat_auth.sh"
|
||||
[authAdapter_rocketchat_setAdmin]="rocketchat/scripts/rocketchat_auth.sh"
|
||||
[authAdapter_rocketchat_setPassword]="rocketchat/scripts/rocketchat_auth.sh"
|
||||
[authAdapter_traefik_setPassword]="traefik/scripts/traefik_auth.sh"
|
||||
[authelia_install_post]="authelia/scripts/authelia_install_hooks.sh"
|
||||
[authelia_install_post_compose]="authelia/scripts/authelia_install_hooks.sh"
|
||||
@ -779,6 +789,7 @@ declare -gA LP_FN_MAP=(
|
||||
[processBcryptPassword]="config/password/bcrypt/password_process_bcrypt.sh"
|
||||
[prometheus_install_post_compose]="prometheus/scripts/prometheus_install_hooks.sh"
|
||||
[prometheus_install_post_start]="prometheus/scripts/prometheus_install_hooks.sh"
|
||||
[_rcJson]="rocketchat/scripts/rocketchat_auth.sh"
|
||||
[readTaskField]="task/crontab_task_processor.sh"
|
||||
[reclaimDockerSpace]="cli/commands/system/cli_system_commands.sh"
|
||||
[reconcileConfigFile]="config/core/variables/config_scan_variables.sh"
|
||||
@ -848,8 +859,14 @@ declare -gA LP_FN_MAP=(
|
||||
[restoreFirstRunBulk]="restore/restore_first_run.sh"
|
||||
[restoreFirstRunDiscover]="restore/restore_first_run.sh"
|
||||
[restorePickSnapshot]="restore/restore_app_pick.sh"
|
||||
[_rocketchatApi]="rocketchat/scripts/rocketchat_auth.sh"
|
||||
[_rocketchatBaseUrl]="rocketchat/scripts/rocketchat_auth.sh"
|
||||
[_rocketchatError]="rocketchat/scripts/rocketchat_auth.sh"
|
||||
[rocketchat_install_post]="rocketchat/scripts/rocketchat_install_hooks.sh"
|
||||
[rocketchat_install_post_start]="rocketchat/scripts/rocketchat_install_hooks.sh"
|
||||
[_rocketchatLogin]="rocketchat/scripts/rocketchat_auth.sh"
|
||||
[_rocketchatOk]="rocketchat/scripts/rocketchat_auth.sh"
|
||||
[_rocketchatUserId]="rocketchat/scripts/rocketchat_auth.sh"
|
||||
[runAppCfg]="docker/command/run_privileged.sh"
|
||||
[runAsManager]="docker/command/run_privileged.sh"
|
||||
[runBackupOp]="docker/command/run_privileged.sh"
|
||||
@ -1171,6 +1188,11 @@ declare -gA LP_FN_ROOT=(
|
||||
[_appReqHasDomain]="scripts"
|
||||
[_appReqServiceInstalled]="scripts"
|
||||
[_appReqServiceMsg]="scripts"
|
||||
[appRocketchatCreateAccount]="containers"
|
||||
[appRocketchatDeactivateUser]="containers"
|
||||
[appRocketchatListUsers]="containers"
|
||||
[appRocketchatResetPassword]="containers"
|
||||
[appRocketchatSetAdmin]="containers"
|
||||
[appScanAvailable]="scripts"
|
||||
[appSetupComposeTags_gluetun]="containers"
|
||||
[appSetupComposeTags_matrix]="containers"
|
||||
@ -1259,6 +1281,11 @@ declare -gA LP_FN_ROOT=(
|
||||
[authAdapter_nextcloud_listUsers]="containers"
|
||||
[authAdapter_nextcloud_setAdmin]="containers"
|
||||
[authAdapter_nextcloud_setPassword]="containers"
|
||||
[authAdapter_rocketchat_createUser]="containers"
|
||||
[authAdapter_rocketchat_deleteUser]="containers"
|
||||
[authAdapter_rocketchat_listUsers]="containers"
|
||||
[authAdapter_rocketchat_setAdmin]="containers"
|
||||
[authAdapter_rocketchat_setPassword]="containers"
|
||||
[authAdapter_traefik_setPassword]="containers"
|
||||
[authelia_install_post]="containers"
|
||||
[authelia_install_post_compose]="containers"
|
||||
@ -1865,6 +1892,7 @@ declare -gA LP_FN_ROOT=(
|
||||
[processBcryptPassword]="scripts"
|
||||
[prometheus_install_post_compose]="containers"
|
||||
[prometheus_install_post_start]="containers"
|
||||
[_rcJson]="containers"
|
||||
[readTaskField]="scripts"
|
||||
[reclaimDockerSpace]="scripts"
|
||||
[reconcileConfigFile]="scripts"
|
||||
@ -1934,8 +1962,14 @@ declare -gA LP_FN_ROOT=(
|
||||
[restoreFirstRunBulk]="scripts"
|
||||
[restoreFirstRunDiscover]="scripts"
|
||||
[restorePickSnapshot]="scripts"
|
||||
[_rocketchatApi]="containers"
|
||||
[_rocketchatBaseUrl]="containers"
|
||||
[_rocketchatError]="containers"
|
||||
[rocketchat_install_post]="containers"
|
||||
[rocketchat_install_post_start]="containers"
|
||||
[_rocketchatLogin]="containers"
|
||||
[_rocketchatOk]="containers"
|
||||
[_rocketchatUserId]="containers"
|
||||
[runAppCfg]="scripts"
|
||||
[runAsManager]="scripts"
|
||||
[runBackupOp]="scripts"
|
||||
@ -2292,6 +2326,11 @@ _appPostStartIntegrations() { unset -f _appPostStartIntegrations; __lpAutoload "
|
||||
_appReqHasDomain() { unset -f _appReqHasDomain; __lpAutoload "${install_scripts_dir}checks/requirements/check_app_install.sh"; _appReqHasDomain "$@"; }
|
||||
_appReqServiceInstalled() { unset -f _appReqServiceInstalled; __lpAutoload "${install_scripts_dir}checks/requirements/check_app_install.sh"; _appReqServiceInstalled "$@"; }
|
||||
_appReqServiceMsg() { unset -f _appReqServiceMsg; __lpAutoload "${install_scripts_dir}checks/requirements/check_app_install.sh"; _appReqServiceMsg "$@"; }
|
||||
appRocketchatCreateAccount() { unset -f appRocketchatCreateAccount; __lpAutoload "${install_containers_dir}rocketchat/tools/rocketchat_create_account.sh"; appRocketchatCreateAccount "$@"; }
|
||||
appRocketchatDeactivateUser() { unset -f appRocketchatDeactivateUser; __lpAutoload "${install_containers_dir}rocketchat/tools/rocketchat_deactivate_user.sh"; appRocketchatDeactivateUser "$@"; }
|
||||
appRocketchatListUsers() { unset -f appRocketchatListUsers; __lpAutoload "${install_containers_dir}rocketchat/tools/rocketchat_list_users.sh"; appRocketchatListUsers "$@"; }
|
||||
appRocketchatResetPassword() { unset -f appRocketchatResetPassword; __lpAutoload "${install_containers_dir}rocketchat/tools/rocketchat_reset_password.sh"; appRocketchatResetPassword "$@"; }
|
||||
appRocketchatSetAdmin() { unset -f appRocketchatSetAdmin; __lpAutoload "${install_containers_dir}rocketchat/tools/rocketchat_set_admin.sh"; appRocketchatSetAdmin "$@"; }
|
||||
appScanAvailable() { unset -f appScanAvailable; __lpAutoload "${install_scripts_dir}app/app_scan_available.sh"; appScanAvailable "$@"; }
|
||||
appSetupComposeTags_gluetun() { unset -f appSetupComposeTags_gluetun; __lpAutoload "${install_containers_dir}gluetun/scripts/gluetun_compose_tags.sh"; appSetupComposeTags_gluetun "$@"; }
|
||||
appSetupComposeTags_matrix() { unset -f appSetupComposeTags_matrix; __lpAutoload "${install_containers_dir}matrix/scripts/matrix_compose_tags.sh"; appSetupComposeTags_matrix "$@"; }
|
||||
@ -2380,6 +2419,11 @@ authAdapter_nextcloud_deleteUser() { unset -f authAdapter_nextcloud_deleteUser;
|
||||
authAdapter_nextcloud_listUsers() { unset -f authAdapter_nextcloud_listUsers; __lpAutoload "${install_containers_dir}nextcloud/scripts/nextcloud_auth.sh"; authAdapter_nextcloud_listUsers "$@"; }
|
||||
authAdapter_nextcloud_setAdmin() { unset -f authAdapter_nextcloud_setAdmin; __lpAutoload "${install_containers_dir}nextcloud/scripts/nextcloud_auth.sh"; authAdapter_nextcloud_setAdmin "$@"; }
|
||||
authAdapter_nextcloud_setPassword() { unset -f authAdapter_nextcloud_setPassword; __lpAutoload "${install_containers_dir}nextcloud/scripts/nextcloud_auth.sh"; authAdapter_nextcloud_setPassword "$@"; }
|
||||
authAdapter_rocketchat_createUser() { unset -f authAdapter_rocketchat_createUser; __lpAutoload "${install_containers_dir}rocketchat/scripts/rocketchat_auth.sh"; authAdapter_rocketchat_createUser "$@"; }
|
||||
authAdapter_rocketchat_deleteUser() { unset -f authAdapter_rocketchat_deleteUser; __lpAutoload "${install_containers_dir}rocketchat/scripts/rocketchat_auth.sh"; authAdapter_rocketchat_deleteUser "$@"; }
|
||||
authAdapter_rocketchat_listUsers() { unset -f authAdapter_rocketchat_listUsers; __lpAutoload "${install_containers_dir}rocketchat/scripts/rocketchat_auth.sh"; authAdapter_rocketchat_listUsers "$@"; }
|
||||
authAdapter_rocketchat_setAdmin() { unset -f authAdapter_rocketchat_setAdmin; __lpAutoload "${install_containers_dir}rocketchat/scripts/rocketchat_auth.sh"; authAdapter_rocketchat_setAdmin "$@"; }
|
||||
authAdapter_rocketchat_setPassword() { unset -f authAdapter_rocketchat_setPassword; __lpAutoload "${install_containers_dir}rocketchat/scripts/rocketchat_auth.sh"; authAdapter_rocketchat_setPassword "$@"; }
|
||||
authAdapter_traefik_setPassword() { unset -f authAdapter_traefik_setPassword; __lpAutoload "${install_containers_dir}traefik/scripts/traefik_auth.sh"; authAdapter_traefik_setPassword "$@"; }
|
||||
authelia_install_post() { unset -f authelia_install_post; __lpAutoload "${install_containers_dir}authelia/scripts/authelia_install_hooks.sh"; authelia_install_post "$@"; }
|
||||
authelia_install_post_compose() { unset -f authelia_install_post_compose; __lpAutoload "${install_containers_dir}authelia/scripts/authelia_install_hooks.sh"; authelia_install_post_compose "$@"; }
|
||||
@ -2986,6 +3030,7 @@ portUpdateComposeTags() { unset -f portUpdateComposeTags; __lpAutoload "${instal
|
||||
processBcryptPassword() { unset -f processBcryptPassword; __lpAutoload "${install_scripts_dir}config/password/bcrypt/password_process_bcrypt.sh"; processBcryptPassword "$@"; }
|
||||
prometheus_install_post_compose() { unset -f prometheus_install_post_compose; __lpAutoload "${install_containers_dir}prometheus/scripts/prometheus_install_hooks.sh"; prometheus_install_post_compose "$@"; }
|
||||
prometheus_install_post_start() { unset -f prometheus_install_post_start; __lpAutoload "${install_containers_dir}prometheus/scripts/prometheus_install_hooks.sh"; prometheus_install_post_start "$@"; }
|
||||
_rcJson() { unset -f _rcJson; __lpAutoload "${install_containers_dir}rocketchat/scripts/rocketchat_auth.sh"; _rcJson "$@"; }
|
||||
readTaskField() { unset -f readTaskField; __lpAutoload "${install_scripts_dir}task/crontab_task_processor.sh"; readTaskField "$@"; }
|
||||
reclaimDockerSpace() { unset -f reclaimDockerSpace; __lpAutoload "${install_scripts_dir}cli/commands/system/cli_system_commands.sh"; reclaimDockerSpace "$@"; }
|
||||
reconcileConfigFile() { unset -f reconcileConfigFile; __lpAutoload "${install_scripts_dir}config/core/variables/config_scan_variables.sh"; reconcileConfigFile "$@"; }
|
||||
@ -3055,8 +3100,14 @@ restoreFilesRehydratePreStart() { unset -f restoreFilesRehydratePreStart; __lpAu
|
||||
restoreFirstRunBulk() { unset -f restoreFirstRunBulk; __lpAutoload "${install_scripts_dir}restore/restore_first_run.sh"; restoreFirstRunBulk "$@"; }
|
||||
restoreFirstRunDiscover() { unset -f restoreFirstRunDiscover; __lpAutoload "${install_scripts_dir}restore/restore_first_run.sh"; restoreFirstRunDiscover "$@"; }
|
||||
restorePickSnapshot() { unset -f restorePickSnapshot; __lpAutoload "${install_scripts_dir}restore/restore_app_pick.sh"; restorePickSnapshot "$@"; }
|
||||
_rocketchatApi() { unset -f _rocketchatApi; __lpAutoload "${install_containers_dir}rocketchat/scripts/rocketchat_auth.sh"; _rocketchatApi "$@"; }
|
||||
_rocketchatBaseUrl() { unset -f _rocketchatBaseUrl; __lpAutoload "${install_containers_dir}rocketchat/scripts/rocketchat_auth.sh"; _rocketchatBaseUrl "$@"; }
|
||||
_rocketchatError() { unset -f _rocketchatError; __lpAutoload "${install_containers_dir}rocketchat/scripts/rocketchat_auth.sh"; _rocketchatError "$@"; }
|
||||
rocketchat_install_post() { unset -f rocketchat_install_post; __lpAutoload "${install_containers_dir}rocketchat/scripts/rocketchat_install_hooks.sh"; rocketchat_install_post "$@"; }
|
||||
rocketchat_install_post_start() { unset -f rocketchat_install_post_start; __lpAutoload "${install_containers_dir}rocketchat/scripts/rocketchat_install_hooks.sh"; rocketchat_install_post_start "$@"; }
|
||||
_rocketchatLogin() { unset -f _rocketchatLogin; __lpAutoload "${install_containers_dir}rocketchat/scripts/rocketchat_auth.sh"; _rocketchatLogin "$@"; }
|
||||
_rocketchatOk() { unset -f _rocketchatOk; __lpAutoload "${install_containers_dir}rocketchat/scripts/rocketchat_auth.sh"; _rocketchatOk "$@"; }
|
||||
_rocketchatUserId() { unset -f _rocketchatUserId; __lpAutoload "${install_containers_dir}rocketchat/scripts/rocketchat_auth.sh"; _rocketchatUserId "$@"; }
|
||||
runAppCfg() { unset -f runAppCfg; __lpAutoload "${install_scripts_dir}docker/command/run_privileged.sh"; runAppCfg "$@"; }
|
||||
runAsManager() { unset -f runAsManager; __lpAutoload "${install_scripts_dir}docker/command/run_privileged.sh"; runAsManager "$@"; }
|
||||
runBackupOp() { unset -f runBackupOp; __lpAutoload "${install_scripts_dir}docker/command/run_privileged.sh"; runBackupOp "$@"; }
|
||||
|
||||
@ -462,13 +462,25 @@ PORTEOF
|
||||
"tooltip": "Object store root password (auto-generated), shared by MinIO and the bucket-creation job.",
|
||||
"advanced": true
|
||||
},
|
||||
"ROCKETCHAT_ADMIN_PASSWORD_1": {
|
||||
"category": "general",
|
||||
"label": "Rocket.Chat Admin Password",
|
||||
"type": "password",
|
||||
"tooltip": "Password for the admin account seeded on install"
|
||||
},
|
||||
"ADMIN_USER": {
|
||||
"category": "general",
|
||||
"label": "Admin Username",
|
||||
"type": "text",
|
||||
"tooltip": "Username of the admin account the credentials card shows"
|
||||
},
|
||||
"ADGUARD_ADMIN_PASSWORD_1": {
|
||||
"category": "general",
|
||||
"label": "AdGuard Admin Password",
|
||||
"type": "password",
|
||||
"tooltip": "AdGuard Home admin password (auto-generated)"
|
||||
},
|
||||
"GITEA_ADMIN_PASSWORD_1": {
|
||||
"GITEA_ADMIN_PASSWORD": {
|
||||
"category": "general",
|
||||
"label": "Gitea Admin Password",
|
||||
"type": "password",
|
||||
@ -487,7 +499,7 @@ PORTEOF
|
||||
"type": "password",
|
||||
"tooltip": "Password protecting the Headscale endpoint"
|
||||
},
|
||||
"INVIDIOUS_ADMIN_PASSWORD_1": {
|
||||
"INVIDIOUS_ADMIN_PASSWORD": {
|
||||
"category": "general",
|
||||
"label": "Invidious Admin Password",
|
||||
"type": "password",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user