mirror of
https://github.com/okxlin/appstore.git
synced 2026-09-23 16:01:01 +00:00
83 lines
2.6 KiB
Bash
Executable File
83 lines
2.6 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}"
|
|
|
|
fail() {
|
|
printf '%s\n' "$1" >&2
|
|
exit 1
|
|
}
|
|
|
|
read_env() {
|
|
local value
|
|
|
|
value="$(sed -n "s/^${1}=//p" "${ENV_FILE}" | tail -n 1)"
|
|
if [[ ${#value} -ge 2 && "${value:0:1}" == "${value: -1}" && "${value:0:1}" =~ [\"\'] ]]; then
|
|
value="${value:1:${#value}-2}"
|
|
fi
|
|
printf '%s\n' "${value}"
|
|
}
|
|
|
|
write_env() {
|
|
local key="$1" value="$2" line temp_file
|
|
local found=false
|
|
|
|
case "${value}" in
|
|
*$'\n'* | *$'\r'* | *"'"*) fail "${key} contains unsupported dotenv characters" ;;
|
|
esac
|
|
temp_file="$(mktemp "${ENV_FILE}.tmp.XXXXXX")"
|
|
while IFS= read -r line || [[ -n "${line}" ]]; do
|
|
if [[ "${line}" == "${key}="* ]]; then
|
|
if [[ "${found}" == false ]]; then
|
|
printf "%s='%s'\n" "${key}" "${value}" >>"${temp_file}"
|
|
found=true
|
|
fi
|
|
else
|
|
printf '%s\n' "${line}" >>"${temp_file}"
|
|
fi
|
|
done <"${ENV_FILE}"
|
|
[[ "${found}" == true ]] || printf "%s='%s'\n" "${key}" "${value}" >>"${temp_file}"
|
|
chmod --reference="${ENV_FILE}" "${temp_file}"
|
|
mv -f -- "${temp_file}" "${ENV_FILE}"
|
|
}
|
|
|
|
sync_secret() {
|
|
local key="$1" cache_file="$2"
|
|
local current final temp_file
|
|
|
|
current="$(read_env "${key}")"
|
|
if [[ -e "${cache_file}" || -L "${cache_file}" ]]; then
|
|
[[ -f "${cache_file}" && ! -L "${cache_file}" ]] || fail "${cache_file} must be a regular file"
|
|
fi
|
|
if [[ -s "${cache_file}" ]]; then
|
|
final="$(<"${cache_file}")"
|
|
chmod 600 -- "${cache_file}"
|
|
else
|
|
[[ -n "${current}" ]] || fail "${key} is missing"
|
|
final="${current}"
|
|
temp_file="$(mktemp "${cache_file}.tmp.XXXXXX")"
|
|
(umask 077; printf '%s\n' "${final}" >"${temp_file}")
|
|
mv -f -- "${temp_file}" "${cache_file}"
|
|
fi
|
|
[[ "${current}" == "${final}" ]] || write_env "${key}" "${final}"
|
|
}
|
|
|
|
[[ -f "${ENV_FILE}" && ! -L "${ENV_FILE}" ]] || fail "${ENV_FILE} must be a regular file"
|
|
DATA_DIR="${APP_DATA_DIR:-$(read_env APP_DATA_DIR)}"
|
|
DATA_DIR="${DATA_DIR:-./data}"
|
|
case "${DATA_DIR}" in
|
|
/*) DATA_DIR="$(realpath -m -- "${DATA_DIR}")" ;;
|
|
*)
|
|
DATA_DIR="$(realpath -m -- "${ROOT_DIR}/${DATA_DIR#./}")"
|
|
[[ "${DATA_DIR}" == "${ROOT_DIR}" || "${DATA_DIR}" == "${ROOT_DIR}/"* ]] \
|
|
|| fail "Relative APP_DATA_DIR must stay inside the application directory"
|
|
;;
|
|
esac
|
|
[[ "${DATA_DIR}" != / ]] || fail "APP_DATA_DIR must not be the filesystem root"
|
|
[[ ! -e "${DATA_DIR}" || -d "${DATA_DIR}" ]] || fail "APP_DATA_DIR must be a directory"
|
|
mkdir -p -- "${DATA_DIR}"/{database,uploads,extensions}
|
|
chown 1000:1000 -- "${DATA_DIR}"/{database,uploads,extensions}
|
|
|
|
sync_secret DIRECTUS_SECRET "${DATA_DIR}/.directus-secret"
|