mirror of
https://github.com/okxlin/appstore.git
synced 2026-09-23 16:01:01 +00:00
85 lines
3.8 KiB
Bash
Executable File
85 lines
3.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
|
|
ENV_FILE="${ENV_FILE:-$ROOT_DIR/.env}"
|
|
DOCKER_BIN="${DOCKER_BIN:-docker}"
|
|
IMAGE='ghcr.io/tinyauthapp/tinyauth:v5'
|
|
|
|
fail() {
|
|
printf '%s\n' "$1" >&2
|
|
exit 1
|
|
}
|
|
|
|
read_env_value() {
|
|
local key="$1"
|
|
local value
|
|
value="$(sed -n "s/^${key}=//p" "$ENV_FILE" | tail -n 1)"
|
|
case "$value" in
|
|
\"*\") value="${value#\"}"; value="${value%\"}" ;;
|
|
\'*\') value="${value#\'}"; value="${value%\'}" ;;
|
|
esac
|
|
printf '%s\n' "$value"
|
|
}
|
|
|
|
[[ -f "$ENV_FILE" && ! -L "$ENV_FILE" ]] || fail "$ENV_FILE must be a regular file"
|
|
command -v "$DOCKER_BIN" >/dev/null 2>&1 || fail 'Docker is required to generate the Tinyauth password hash'
|
|
|
|
username="${TINYAUTH_ADMIN_USERNAME:-$(read_env_value TINYAUTH_ADMIN_USERNAME)}"
|
|
password="${TINYAUTH_ADMIN_PASSWORD:-$(read_env_value TINYAUTH_ADMIN_PASSWORD)}"
|
|
app_url="${TINYAUTH_APP_URL:-$(read_env_value TINYAUTH_APP_URL)}"
|
|
secure_cookie="${TINYAUTH_SECURE_COOKIE:-$(read_env_value TINYAUTH_SECURE_COOKIE)}"
|
|
|
|
data_dir="$(realpath -m -- "$ROOT_DIR/data")"
|
|
case "$data_dir" in
|
|
"$ROOT_DIR"/*) ;;
|
|
*) fail 'Tinyauth data directory must remain inside the application version directory' ;;
|
|
esac
|
|
for path in "$data_dir" "$data_dir/resources" "$data_dir/oidc"; do
|
|
[[ ! -L "$path" ]] || fail "$path must not be a symbolic link"
|
|
[[ ! -e "$path" || -d "$path" ]] || fail "$path must be a directory"
|
|
done
|
|
users_file="$data_dir/users"
|
|
[[ ! -L "$users_file" ]] || fail 'Tinyauth users file must not be a symbolic link'
|
|
[[ ! -e "$users_file" || -f "$users_file" ]] || fail 'Tinyauth users path must be a regular file'
|
|
|
|
[[ "$username" =~ ^[A-Za-z0-9._-]{1,64}$ ]] || fail 'TINYAUTH_ADMIN_USERNAME must contain only letters, digits, dot, underscore, or hyphen'
|
|
[[ ${#password} -ge 12 && ${#password} -le 256 ]] || fail 'TINYAUTH_ADMIN_PASSWORD must contain 12 to 256 characters'
|
|
[[ "$password" != *$'\n'* && "$password" != *$'\r'* ]] || fail 'TINYAUTH_ADMIN_PASSWORD must not contain line breaks'
|
|
[[ "$app_url" =~ ^https?://[^[:space:]]+$ ]] || fail 'TINYAUTH_APP_URL must be an absolute HTTP or HTTPS URL without whitespace'
|
|
app_host="${app_url#*://}"
|
|
app_host="${app_host%%/*}"
|
|
app_host="${app_host%%:*}"
|
|
[[ "$app_host" == *.* && "$app_host" =~ ^[A-Za-z0-9][A-Za-z0-9.-]*[A-Za-z0-9]$ ]] || fail 'TINYAUTH_APP_URL must use a domain name with at least two labels'
|
|
[[ ! "$app_host" =~ ^[0-9.]+$ ]] || fail 'TINYAUTH_APP_URL must not use an IP address'
|
|
[[ "$secure_cookie" == false || "$secure_cookie" == true ]] || fail 'TINYAUTH_SECURE_COOKIE must be true or false'
|
|
|
|
install -d -m 0750 -o 1000 -g 1000 -- "$data_dir" "$data_dir/resources" "$data_dir/oidc"
|
|
|
|
# Variables in this command are expanded by the shell inside the generator container.
|
|
# shellcheck disable=SC2016
|
|
generator_command='IFS= read -r password; exec tinyauth user create --username "$1" --password "$password"'
|
|
generator_output="$(
|
|
printf '%s\n' "$password" |
|
|
"$DOCKER_BIN" run --rm -i --network none --read-only --user 1000:1000 \
|
|
--cap-drop ALL --security-opt no-new-privileges --env NO_COLOR=1 \
|
|
--entrypoint /bin/sh "$IMAGE" -ec \
|
|
"$generator_command" \
|
|
sh "$username"
|
|
)"
|
|
user_entry="$(printf '%s\n' "$generator_output" | sed -n 's/^TINYAUTH_AUTH_USERS=//p' | head -n 1)"
|
|
[[ "$user_entry" =~ ^[A-Za-z0-9._-]{1,64}:\$2[aby]\$[0-9]{2}\$[./A-Za-z0-9]{53}$ ]] || fail 'Failed to generate a valid bcrypt user entry'
|
|
|
|
umask 077
|
|
temporary="$(mktemp "$data_dir/.users.tmp.XXXXXX")"
|
|
trap 'rm -f -- "${temporary:-}"' EXIT
|
|
printf '%s\n' "$user_entry" >"$temporary"
|
|
chmod 0600 "$temporary"
|
|
chown 1000:1000 "$temporary"
|
|
mv -f -- "$temporary" "$users_file"
|
|
trap - EXIT
|
|
|
|
chown 1000:1000 "$data_dir" "$data_dir/resources" "$data_dir/oidc" "$users_file"
|
|
chmod 0750 "$data_dir" "$data_dir/resources" "$data_dir/oidc"
|
|
chmod 0600 "$users_file"
|