feat: add tinyauth

This commit is contained in:
okxlin
2026-07-31 03:55:21 +08:00
parent 59ef536922
commit ddab9941f5
15 changed files with 569 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
CONTAINER_NAME=tinyauth
PANEL_APP_PORT_HTTP=3000
TINYAUTH_APP_URL=http://tinyauth.localhost:3000
TINYAUTH_ADMIN_USERNAME=admin
TINYAUTH_ADMIN_PASSWORD=Tinyauth_Admin_Change_Me_2026!
TINYAUTH_SECURE_COOKIE=false
+92
View File
@@ -0,0 +1,92 @@
additionalProperties:
formFields:
- default: 3000
edit: true
envKey: PANEL_APP_PORT_HTTP
labelEn: HTTP Port
labelZh: HTTP 端口
label:
en: HTTP Port
zh: HTTP 端口
zh-Hant: HTTP 連接埠
ja: HTTP ポート
ko: HTTP 포트
ru: Порт HTTP
ms: Port HTTP
pt-br: Porta HTTP
required: true
rule: paramPort
type: number
- default: http://tinyauth.localhost:3000
edit: true
envKey: TINYAUTH_APP_URL
labelEn: External URL
labelZh: 外部访问地址
label:
en: External URL
zh: 外部访问地址
zh-Hant: 外部存取網址
ja: 外部 URL
ko: 외부 URL
ru: Внешний URL
ms: URL Luaran
pt-br: URL externo
required: true
rule: paramExtUrl
type: text
- default: admin
edit: true
envKey: TINYAUTH_ADMIN_USERNAME
labelEn: Admin Username
labelZh: 管理员用户名
label:
en: Admin Username
zh: 管理员用户名
zh-Hant: 管理員使用者名稱
ja: 管理者ユーザー名
ko: 관리자 사용자 이름
ru: Имя администратора
ms: Nama Pengguna Pentadbir
pt-br: Usuario administrador
required: true
rule: paramCommon
type: text
- default: ""
edit: true
envKey: TINYAUTH_ADMIN_PASSWORD
labelEn: Admin Password
labelZh: 管理员密码
label:
en: Admin Password
zh: 管理员密码
zh-Hant: 管理員密碼
ja: 管理者パスワード
ko: 관리자 비밀번호
ru: Пароль администратора
ms: Kata Laluan Pentadbir
pt-br: Senha do administrador
random: true
required: true
rule: paramComplexity
type: password
- default: "false"
edit: true
envKey: TINYAUTH_SECURE_COOKIE
labelEn: Secure Cookies
labelZh: 安全 Cookie
label:
en: Secure Cookies
zh: 安全 Cookie
zh-Hant: 安全 Cookie
ja: Secure Cookie
ko: 보안 Cookie
ru: Secure Cookie
ms: Cookie Selamat
pt-br: Cookie seguro
required: true
type: select
values:
- label: "false"
value: "false"
- label: "true"
value: "true"
+42
View File
@@ -0,0 +1,42 @@
services:
tinyauth:
image: "ghcr.io/tinyauthapp/tinyauth:v5.1.3@sha256:a1bde189951900f84a60f133c26a1ec7a3264073ec7875b548f4fbadb7f5f735"
container_name: ${CONTAINER_NAME}
restart: unless-stopped
user: "1000:1000"
networks:
- 1panel-network
ports:
- "${PANEL_APP_PORT_HTTP}:3000"
environment:
- TINYAUTH_APPURL=${TINYAUTH_APP_URL}
- TINYAUTH_LABELPROVIDER=none
- TINYAUTH_AUTH_USERSFILE=/data/users
- TINYAUTH_AUTH_SECURECOOKIE=${TINYAUTH_SECURE_COOKIE}
- TINYAUTH_ANALYTICS_ENABLED=false
- TINYAUTH_SERVER_ADDRESS=0.0.0.0
- TINYAUTH_SERVER_PORT=3000
- TINYAUTH_DATABASE_DRIVER=sqlite
- TINYAUTH_DATABASE_PATH=/data/tinyauth.db
- TINYAUTH_RESOURCES_PATH=/data/resources
volumes:
- "./data:/data"
read_only: true
tmpfs:
- /tmp:nodev,noexec,nosuid,size=32M
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD", "tinyauth", "healthcheck"]
interval: 30s
timeout: 5s
start_period: 10s
retries: 5
labels:
createdBy: "Apps"
networks:
1panel-network:
external: true
+84
View File
@@ -0,0 +1,84 @@
#!/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.1.3@sha256:a1bde189951900f84a60f133c26a1ec7a3264073ec7875b548f4fbadb7f5f735'
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"
+8
View File
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -euo pipefail
if command -v docker-compose >/dev/null 2>&1; then
docker-compose down --volumes --remove-orphans
else
docker compose down --volumes --remove-orphans
fi
+3
View File
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
set -euo pipefail
exit 0
+68
View File
@@ -0,0 +1,68 @@
# Tinyauth
## 产品介绍
Tinyauth 是一个轻量级身份认证与授权服务,可作为 Traefik、Nginx、Caddy 等反向代理的 Forward Auth 后端,也可独立提供本地用户登录、OAuth、LDAP 和 OpenID Connect 服务。
本应用使用 Tinyauth 官方镜像和本地 SQLite 数据库。安装时输入的管理员密码会通过上游自带命令生成 bcrypt 哈希,运行容器只读取持久化的哈希用户文件,不接收管理员明文密码。
## 主要功能
- 本地用户登录与基于 Cookie 的认证会话
- 适配 Traefik、Nginx 和 Caddy 的 Forward Auth 端点
- OAuth、LDAP 和 Tailscale 身份源集成
- 作为 OpenID Connect 身份提供方服务其他应用
- 按用户、组、IP、域名和路径配置访问控制
## 访问说明
- Web 界面:安装表单中填写的外部访问地址
- 初始管理员:安装表单中的管理员用户名和随机密码
- 使用 HTTP 时保持“安全 Cookie”为 `false`;通过 HTTPS 域名访问时应将其设置为 `true`
- 外部访问地址必须使用至少两级的域名,并与浏览器实际使用的协议、域名和端口一致;Tinyauth 不接受 IP 地址或裸 `localhost`
登录后可直接使用 Tinyauth 的独立认证界面。若要保护其他应用,需要在反向代理中把认证请求转发到 Tinyauth,并按上游文档配置对应的 Forward Auth 端点和请求头。本包不会自动发现或修改其他 1Panel 应用。
## 安全边界
本包明确设置 `TINYAUTH_LABELPROVIDER=none`,不挂载 `/var/run/docker.sock`,也不启用 Docker 或 Kubernetes label provider。容器以 UID/GID `1000:1000` 运行,根文件系统只读,删除全部 Linux capabilities,并启用 `no-new-privileges`
镜像依赖扫描会报告 Docker client 库中的三个 High 漏洞,但这些代码只由已禁用的 Docker label provider 调用;默认包没有 Docker socket、Docker API 地址或 provider 自动探测路径。请勿自行把 label provider 改为 `auto``docker`,也不要向容器添加 Docker socket。
固定版本从 `5.1.3` 开始,因为 `5.1.2` 及更早版本受 `GHSA-r27r-rr9v-vv37` 的 Forward Auth ACL 认证绕过影响。不要降级到 `5.1.2` 或更早版本。
## 数据与升级
`./data` 挂载到容器 `/data`,保存 bcrypt 用户文件、SQLite 数据库、OIDC 密钥和资源文件。卸载只移除容器和 Compose 资源,不删除该目录。升级前应备份整个 `./data` 目录,并确认外部访问地址和反向代理配置保持一致。
`latest` 使用上游 `v5` 移动标签;需要可重复部署时请选择固定版本 `5.1.3`
## Introduction
Tinyauth is a lightweight authentication and authorization server for reverse proxies and standalone applications. It supports local users, OAuth, LDAP, OpenID Connect, and Forward Auth integrations for Traefik, Nginx, and Caddy.
This package uses the official image and a local SQLite database. The install script passes the administrator password to Tinyauth's own bcrypt generator over standard input and persists only the resulting user hash for the runtime container.
## Features
- Local users and cookie-based authentication sessions
- Forward Auth endpoints for Traefik, Nginx, and Caddy
- OAuth, LDAP, and Tailscale identity integrations
- OpenID Connect provider support for downstream applications
- User, group, IP, domain, and path-based access controls
The package explicitly disables label discovery with `TINYAUTH_LABELPROVIDER=none` and does not mount the Docker socket. The container runs as UID/GID `1000:1000` with a read-only root filesystem, all Linux capabilities dropped, and `no-new-privileges` enabled. Do not enable the Docker provider or add a Docker socket mount.
Set the external URL to the exact browser-facing protocol, domain, and port. Tinyauth rejects IP addresses and bare `localhost`; use a domain with at least two labels. Use secure cookies only with HTTPS. To protect another application, configure its reverse proxy to call the appropriate Tinyauth Forward Auth endpoint; this package intentionally does not discover or modify other 1Panel applications.
Version `5.1.3` is the oldest version packaged here because it fixes the Forward Auth ACL authentication bypass in `GHSA-r27r-rr9v-vv37`. Do not downgrade to `5.1.2` or earlier.
Persistent users, SQLite state, OIDC keys, and resources live under `./data`. Uninstall preserves this directory. Back up the entire directory before upgrades.
## References
- Website: <https://tinyauth.app/>
- Documentation: <https://tinyauth.app/docs/getting-started/>
- Source: <https://github.com/tinyauthapp/tinyauth>
- Security advisory: <https://github.com/tinyauthapp/tinyauth/security/advisories/GHSA-r27r-rr9v-vv37>
- Official image: <https://github.com/tinyauthapp/tinyauth/pkgs/container/tinyauth>
+31
View File
@@ -0,0 +1,31 @@
name: Tinyauth
tags:
- Security
title: 轻量级身份认证与授权服务
description: 轻量级身份认证与授权服务
additionalProperties:
key: tinyauth
name: Tinyauth
tags:
- Security
shortDescZh: 轻量级身份认证与授权服务
shortDescEn: Lightweight authentication and authorization server
description:
en: A lightweight authentication and authorization server for reverse proxies and standalone applications
zh: 为反向代理和独立应用提供身份认证、OAuth、LDAP、OIDC 与访问控制
zh-Hant: 為反向代理和獨立應用提供身份驗證、OAuth、LDAP、OIDC 與存取控制
ja: リバースプロキシとスタンドアロンアプリ向けの軽量な認証・認可サーバー
ko: 리버스 프록시와 독립 실행형 앱을 위한 경량 인증 및 권한 부여 서버
ru: Легковесный сервер аутентификации и авторизации для обратных прокси и автономных приложений
ms: Pelayan pengesahan dan kebenaran ringan untuk proksi songsang dan aplikasi kendiri
pt-br: Servidor leve de autenticacao e autorizacao para proxies reversos e aplicativos independentes
type: tool
crossVersionUpdate: true
limit: 0
recommend: 0
website: https://tinyauth.app/
github: https://github.com/tinyauthapp/tinyauth
document: https://tinyauth.app/docs/getting-started/
architectures:
- amd64
- arm64
+6
View File
@@ -0,0 +1,6 @@
CONTAINER_NAME=tinyauth
PANEL_APP_PORT_HTTP=3000
TINYAUTH_APP_URL=http://tinyauth.localhost:3000
TINYAUTH_ADMIN_USERNAME=admin
TINYAUTH_ADMIN_PASSWORD=Tinyauth_Admin_Change_Me_2026!
TINYAUTH_SECURE_COOKIE=false
+92
View File
@@ -0,0 +1,92 @@
additionalProperties:
formFields:
- default: 3000
edit: true
envKey: PANEL_APP_PORT_HTTP
labelEn: HTTP Port
labelZh: HTTP 端口
label:
en: HTTP Port
zh: HTTP 端口
zh-Hant: HTTP 連接埠
ja: HTTP ポート
ko: HTTP 포트
ru: Порт HTTP
ms: Port HTTP
pt-br: Porta HTTP
required: true
rule: paramPort
type: number
- default: http://tinyauth.localhost:3000
edit: true
envKey: TINYAUTH_APP_URL
labelEn: External URL
labelZh: 外部访问地址
label:
en: External URL
zh: 外部访问地址
zh-Hant: 外部存取網址
ja: 外部 URL
ko: 외부 URL
ru: Внешний URL
ms: URL Luaran
pt-br: URL externo
required: true
rule: paramExtUrl
type: text
- default: admin
edit: true
envKey: TINYAUTH_ADMIN_USERNAME
labelEn: Admin Username
labelZh: 管理员用户名
label:
en: Admin Username
zh: 管理员用户名
zh-Hant: 管理員使用者名稱
ja: 管理者ユーザー名
ko: 관리자 사용자 이름
ru: Имя администратора
ms: Nama Pengguna Pentadbir
pt-br: Usuario administrador
required: true
rule: paramCommon
type: text
- default: ""
edit: true
envKey: TINYAUTH_ADMIN_PASSWORD
labelEn: Admin Password
labelZh: 管理员密码
label:
en: Admin Password
zh: 管理员密码
zh-Hant: 管理員密碼
ja: 管理者パスワード
ko: 관리자 비밀번호
ru: Пароль администратора
ms: Kata Laluan Pentadbir
pt-br: Senha do administrador
random: true
required: true
rule: paramComplexity
type: password
- default: "false"
edit: true
envKey: TINYAUTH_SECURE_COOKIE
labelEn: Secure Cookies
labelZh: 安全 Cookie
label:
en: Secure Cookies
zh: 安全 Cookie
zh-Hant: 安全 Cookie
ja: Secure Cookie
ko: 보안 Cookie
ru: Secure Cookie
ms: Cookie Selamat
pt-br: Cookie seguro
required: true
type: select
values:
- label: "false"
value: "false"
- label: "true"
value: "true"
+42
View File
@@ -0,0 +1,42 @@
services:
tinyauth:
image: "ghcr.io/tinyauthapp/tinyauth:v5"
container_name: ${CONTAINER_NAME}
restart: unless-stopped
user: "1000:1000"
networks:
- 1panel-network
ports:
- "${PANEL_APP_PORT_HTTP}:3000"
environment:
- TINYAUTH_APPURL=${TINYAUTH_APP_URL}
- TINYAUTH_LABELPROVIDER=none
- TINYAUTH_AUTH_USERSFILE=/data/users
- TINYAUTH_AUTH_SECURECOOKIE=${TINYAUTH_SECURE_COOKIE}
- TINYAUTH_ANALYTICS_ENABLED=false
- TINYAUTH_SERVER_ADDRESS=0.0.0.0
- TINYAUTH_SERVER_PORT=3000
- TINYAUTH_DATABASE_DRIVER=sqlite
- TINYAUTH_DATABASE_PATH=/data/tinyauth.db
- TINYAUTH_RESOURCES_PATH=/data/resources
volumes:
- "./data:/data"
read_only: true
tmpfs:
- /tmp:nodev,noexec,nosuid,size=32M
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD", "tinyauth", "healthcheck"]
interval: 30s
timeout: 5s
start_period: 10s
retries: 5
labels:
createdBy: "Apps"
networks:
1panel-network:
external: true
+84
View File
@@ -0,0 +1,84 @@
#!/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"
+8
View File
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -euo pipefail
if command -v docker-compose >/dev/null 2>&1; then
docker-compose down --volumes --remove-orphans
else
docker compose down --volumes --remove-orphans
fi
+3
View File
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
set -euo pipefail
exit 0
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB