fix(deploy): 初始化并校验公开 API 地址
This commit is contained in:
Executable
+157
@@ -0,0 +1,157 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 初始化并持久化后端对外公开 API 地址。不会 source .env,避免执行其中内容。
|
||||
|
||||
public_url_read_env_value() {
|
||||
local file="$1"
|
||||
local key="$2"
|
||||
local value
|
||||
value="$(awk -v key="$key" 'index($0, key "=") == 1 { print substr($0, length(key) + 2); exit }' "$file")"
|
||||
value="$(printf '%s' "$value" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
|
||||
case "$value" in
|
||||
\"*\") value="${value#\"}"; value="${value%\"}" ;;
|
||||
\'*\') value="${value#\'}"; value="${value%\'}" ;;
|
||||
esac
|
||||
printf '%s' "$value"
|
||||
}
|
||||
|
||||
public_url_write_env_value() {
|
||||
local file="$1"
|
||||
local key="$2"
|
||||
local value="$3"
|
||||
local tmp
|
||||
tmp="$(mktemp "${file}.tmp.XXXXXX")"
|
||||
awk -v key="$key" -v value="$value" '
|
||||
BEGIN { replaced = 0 }
|
||||
index($0, key "=") == 1 {
|
||||
if (!replaced) {
|
||||
print key "=" value
|
||||
replaced = 1
|
||||
}
|
||||
next
|
||||
}
|
||||
{ print }
|
||||
END {
|
||||
if (!replaced) print key "=" value
|
||||
}
|
||||
' "$file" > "$tmp"
|
||||
chmod 600 "$tmp"
|
||||
mv "$tmp" "$file"
|
||||
}
|
||||
|
||||
public_url_normalize() {
|
||||
local value
|
||||
value="$(printf '%s' "$1" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
|
||||
while [ "${value%/}" != "$value" ]; do value="${value%/}"; done
|
||||
printf '%s' "$value"
|
||||
}
|
||||
|
||||
public_url_validate() {
|
||||
local value rest authority host port
|
||||
value="$(public_url_normalize "$1")"
|
||||
case "$value" in
|
||||
http://*|https://*) ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
case "$value" in
|
||||
*[[:space:]@?#]*) return 1 ;;
|
||||
esac
|
||||
|
||||
rest="${value#*://}"
|
||||
authority="${rest%%/*}"
|
||||
[ -n "$authority" ] || return 1
|
||||
if [[ "$authority" == \[* ]]; then
|
||||
[[ "$authority" =~ ^\[[0-9A-Fa-f:.]+\](:[0-9]+)?$ ]] || return 1
|
||||
if [[ "$authority" == *]:* ]]; then port="${authority##*:}"; fi
|
||||
else
|
||||
[[ "$authority" =~ ^[A-Za-z0-9._-]+(:[0-9]+)?$ ]] || return 1
|
||||
if [[ "$authority" == *:* ]]; then
|
||||
host="${authority%:*}"
|
||||
port="${authority##*:}"
|
||||
[ -n "$host" ] || return 1
|
||||
fi
|
||||
fi
|
||||
if [ -n "${port:-}" ]; then
|
||||
[[ "$port" =~ ^[0-9]+$ ]] || return 1
|
||||
[ "$port" -ge 1 ] && [ "$port" -le 65535 ] || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
public_url_derive_from_env() {
|
||||
local file="$1"
|
||||
local api_url socket_url security_origin origin scheme combined
|
||||
api_url="$(public_url_read_env_value "$file" "NUXT_PUBLIC_BASE_APIURL")"
|
||||
if public_url_validate "$api_url"; then
|
||||
public_url_normalize "$api_url"
|
||||
return 0
|
||||
fi
|
||||
[[ "$api_url" == /* ]] || return 1
|
||||
|
||||
socket_url="$(public_url_read_env_value "$file" "NUXT_PUBLIC_BASE_SOCKETURL")"
|
||||
if [[ "$socket_url" =~ ^(ws|wss)://([^/?#[:space:]]+) ]]; then
|
||||
scheme="http"
|
||||
[ "${BASH_REMATCH[1]}" = "wss" ] && scheme="https"
|
||||
origin="${scheme}://${BASH_REMATCH[2]}"
|
||||
fi
|
||||
|
||||
if [ -z "${origin:-}" ]; then
|
||||
security_origin="$(public_url_read_env_value "$file" "CONFIG_SECURITY_ORIGIN")"
|
||||
security_origin="${security_origin%%,*}"
|
||||
security_origin="$(public_url_normalize "$security_origin")"
|
||||
if [[ "$security_origin" =~ ^(https?://[^/]+) ]]; then
|
||||
origin="${BASH_REMATCH[1]}"
|
||||
fi
|
||||
fi
|
||||
|
||||
[ -n "${origin:-}" ] || return 1
|
||||
combined="$(public_url_normalize "${origin}${api_url}")"
|
||||
public_url_validate "$combined" || return 1
|
||||
printf '%s' "$combined"
|
||||
}
|
||||
|
||||
init_public_api_base_url() {
|
||||
local file="${1:-.env}"
|
||||
local mode="${2:-upgrade}"
|
||||
local override="${3:-${DEPLOY_PUBLIC_API_BASE_URL:-}}"
|
||||
local current selected
|
||||
if [ ! -f "$file" ]; then
|
||||
echo "❌ 环境配置文件不存在: $file" >&2
|
||||
return 1
|
||||
fi
|
||||
if [ "$mode" != "configure" ] && [ "$mode" != "upgrade" ]; then
|
||||
echo "❌ 公开 API 地址初始化模式无效: $mode(仅支持 configure/upgrade)" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "$override" ]; then
|
||||
override="$(public_url_read_env_value "$file" "DEPLOY_PUBLIC_API_BASE_URL")"
|
||||
fi
|
||||
current="$(public_url_read_env_value "$file" "CONFIG_PUBLIC_API_BASE_URL")"
|
||||
if [ -n "$override" ]; then
|
||||
selected="$(public_url_normalize "$override")"
|
||||
elif [ -n "$current" ]; then
|
||||
if ! public_url_validate "$current"; then
|
||||
echo "❌ CONFIG_PUBLIC_API_BASE_URL 配置无效: $current" >&2
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
else
|
||||
selected="$(public_url_derive_from_env "$file")" || {
|
||||
echo "❌ 无法从现有前端配置推导 CONFIG_PUBLIC_API_BASE_URL" >&2
|
||||
echo " 请设置完整地址,例如 https://example.com/api" >&2
|
||||
return 1
|
||||
}
|
||||
fi
|
||||
|
||||
if ! public_url_validate "$selected"; then
|
||||
echo "❌ 公开 API 地址配置无效: $selected" >&2
|
||||
return 1
|
||||
fi
|
||||
selected="$(public_url_normalize "$selected")"
|
||||
public_url_write_env_value "$file" "CONFIG_PUBLIC_API_BASE_URL" "$selected"
|
||||
echo " ✓ 已配置公开 API 地址: $selected"
|
||||
}
|
||||
|
||||
if [ "${BASH_SOURCE[0]}" = "$0" ]; then
|
||||
init_public_api_base_url "${1:-.env}" "${2:-upgrade}" "${3:-}"
|
||||
fi
|
||||
Reference in New Issue
Block a user