会员服务器:上传肥牛应用源码 v1.5.1(fnnas.huiyuan 完整 fpk 工程结构)
含 app/server/server.cjs 服务端、app/www 网页(admin/auth/项目云/库备份/settings)、 app/ui 图标、cmd 安装脚本、config、wizard、manifest、图标与对接文档。 按仓库规则排除构建产物 *.fpk 与 .mimosa 缓存。
This commit is contained in:
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
|
||||
### 配置变更回调(应用设置向导提交后):更新 app.env,向导留空的项保持不变
|
||||
|
||||
CFG="${TRIM_PKGETC}/app.env"
|
||||
[ -f "${CFG}" ] || exit 0
|
||||
|
||||
if [ -n "${wizard_port}" ]; then
|
||||
sed -i "s|^HY_PORT=.*|HY_PORT=${wizard_port}|" "${CFG}"
|
||||
fi
|
||||
|
||||
if [ -n "${wizard_dbdir}" ]; then
|
||||
if [ ! -d "${wizard_dbdir}" ]; then
|
||||
if mkdir -p "${wizard_dbdir}" 2>/dev/null; then
|
||||
[ -n "${TRIM_UID}" ] && chown "${TRIM_UID}:${TRIM_GID}" "${wizard_dbdir}" 2>/dev/null
|
||||
else
|
||||
echo "警告:数据目录 ${wizard_dbdir} 创建失败,保持原目录不变" >> "${TRIM_TEMP_LOGFILE}" 2>/dev/null
|
||||
fi
|
||||
fi
|
||||
[ -d "${wizard_dbdir}" ] && sed -i "s|^HY_DB_DIR=.*|HY_DB_DIR=${wizard_dbdir}|" "${CFG}"
|
||||
fi
|
||||
|
||||
# 管理密码(留空不修改;更新盐+哈希两行,不存在则追加)
|
||||
if [ -n "${wizard_admin_pwd}" ]; then
|
||||
SALT="$(date +%s%N)$RANDOM"
|
||||
HASH="$(printf '%s' "${SALT}${wizard_admin_pwd}" | sha256sum | cut -d' ' -f1)"
|
||||
if grep -q "^ADMIN_PWD_SALT=" "${CFG}"; then
|
||||
sed -i "s|^ADMIN_PWD_SALT=.*|ADMIN_PWD_SALT=${SALT}|" "${CFG}"
|
||||
else
|
||||
echo "ADMIN_PWD_SALT=${SALT}" >> "${CFG}"
|
||||
fi
|
||||
if grep -q "^ADMIN_PWD_SHA256=" "${CFG}"; then
|
||||
sed -i "s|^ADMIN_PWD_SHA256=.*|ADMIN_PWD_SHA256=${HASH}|" "${CFG}"
|
||||
else
|
||||
echo "ADMIN_PWD_SHA256=${HASH}" >> "${CFG}"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - config updated port=${wizard_port:-保持} dbdir=${wizard_dbdir:-保持} admin_pwd=$([ -n "${wizard_admin_pwd}" ] && echo 已修改 || echo 保持)" >> "${TRIM_PKGVAR}/app.log" 2>/dev/null
|
||||
|
||||
exit 0
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
### This script is called before the user change environment variables in application setting page.
|
||||
|
||||
exit 0
|
||||
Executable
+50
@@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
|
||||
### 安装完成回调:把向导值合并写入 app.env(cmd/main 与服务进程读取)。
|
||||
### 合并式:只覆盖本脚本管理的键(HY_PORT/HY_DB_DIR/ADMIN_*),设置页保存的其他键(如 HY_REG_OPEN)保留。
|
||||
|
||||
mkdir -p "${TRIM_PKGETC}" 2>/dev/null
|
||||
CFG="${TRIM_PKGETC}/app.env"
|
||||
|
||||
PORT="${wizard_port}"
|
||||
DBDIR="${wizard_dbdir}"
|
||||
[ -z "${PORT}" ] && PORT="${TRIM_SERVICE_PORT:-12701}"
|
||||
|
||||
# 向导填了自定义数据目录:目录不存在则创建,新建目录归属应用用户(已存在的目录不动,由 ACL/目录授权控制)
|
||||
if [ -n "${DBDIR}" ] && [ ! -d "${DBDIR}" ]; then
|
||||
if mkdir -p "${DBDIR}" 2>/dev/null; then
|
||||
[ -n "${TRIM_UID}" ] && chown "${TRIM_UID}:${TRIM_GID}" "${DBDIR}" 2>/dev/null
|
||||
else
|
||||
echo "警告:数据目录 ${DBDIR} 创建失败,将使用默认目录" >> "${TRIM_TEMP_LOGFILE}" 2>/dev/null
|
||||
DBDIR=""
|
||||
fi
|
||||
fi
|
||||
|
||||
# 合并旧配置:跳过本脚本管理的键,其余原样保留
|
||||
TMP="${CFG}.new"
|
||||
: > "${TMP}"
|
||||
if [ -f "${CFG}" ]; then
|
||||
while IFS='=' read -r k v; do
|
||||
[ -z "${k}" ] && continue
|
||||
case "${k}" in
|
||||
HY_PORT|HY_DB_DIR|ADMIN_PWD_SALT|ADMIN_PWD_SHA256) ;;
|
||||
*) printf '%s=%s\n' "${k}" "${v}" >> "${TMP}" ;;
|
||||
esac
|
||||
done < "${CFG}"
|
||||
fi
|
||||
|
||||
# 管理密码(向导必填;留空则保留旧哈希,若从未设置过则服务端登录时会提示未设置)
|
||||
if [ -n "${wizard_admin_pwd}" ]; then
|
||||
SALT="$(date +%s%N)$RANDOM${TRIM_APPNAME:-hy}"
|
||||
HASH="$(printf '%s' "${SALT}${wizard_admin_pwd}" | sha256sum | cut -d' ' -f1)"
|
||||
printf 'ADMIN_PWD_SALT=%s\n' "${SALT}" >> "${TMP}"
|
||||
printf 'ADMIN_PWD_SHA256=%s\n' "${HASH}" >> "${TMP}"
|
||||
fi
|
||||
|
||||
printf 'HY_PORT=%s\n' "${PORT}" >> "${TMP}"
|
||||
printf 'HY_DB_DIR=%s\n' "${DBDIR}" >> "${TMP}"
|
||||
mv "${TMP}" "${CFG}"
|
||||
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - installed v${TRIM_APPVER} port=${PORT} dbdir=${DBDIR:-默认} admin_pwd=$([ -n "${wizard_admin_pwd}" ] && echo 已设置 || echo 保持)" >> "${TRIM_PKGVAR}/app.log" 2>/dev/null
|
||||
|
||||
exit 0
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
### 安装初始化:建默认数据目录;若数据目录存在上次卸载前备份的 TLS/RSA 密钥与配置则恢复
|
||||
### (保证已导入的正规 SSL 证书跨升级保留)。安装包不带任何会员数据,空库由服务首次启动创建。
|
||||
|
||||
DB_DIR="${TRIM_DATA_SHARE_PATHS%%:*}"
|
||||
[ -z "${DB_DIR}" ] && DB_DIR="${TRIM_PKGVAR}/files"
|
||||
mkdir -p "${DB_DIR}" 2>/dev/null
|
||||
|
||||
BAK="${DB_DIR}/.huiyuan-密钥备份"
|
||||
if [ -d "${BAK}" ]; then
|
||||
mkdir -p "${TRIM_PKGETC}" 2>/dev/null
|
||||
for f in tls.key tls.crt huiyuan_rsa.pem app.env; do
|
||||
if [ -f "${BAK}/${f}" ] && [ ! -f "${TRIM_PKGETC}/${f}" ]; then
|
||||
cp -f "${BAK}/${f}" "${TRIM_PKGETC}/${f}" 2>/dev/null
|
||||
fi
|
||||
done
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - 已从 ${BAK} 恢复 TLS/RSA 密钥与配置" >> "${TRIM_PKGVAR}/app.log" 2>/dev/null
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Executable
+130
@@ -0,0 +1,130 @@
|
||||
#!/bin/bash
|
||||
|
||||
LOG_FILE="${TRIM_PKGVAR}/info.log"
|
||||
PID_FILE="${TRIM_PKGVAR}/app.pid"
|
||||
|
||||
NODE_BIN="/var/apps/nodejs_v22/target/bin/node"
|
||||
[ ! -x "${NODE_BIN}" ] && NODE_BIN="$(command -v node || echo node)"
|
||||
SERVER="${TRIM_APPDEST}/server/server.cjs"
|
||||
|
||||
# 从 app.env 读取向导持久化的配置(install_callback/config_callback 写入)
|
||||
CFG_FILE="${TRIM_PKGETC}/app.env"
|
||||
HY_PORT=""
|
||||
HY_DB_DIR=""
|
||||
if [ -f "${CFG_FILE}" ]; then
|
||||
while IFS='=' read -r k v; do
|
||||
case "$k" in
|
||||
HY_PORT) HY_PORT="$v" ;;
|
||||
HY_DB_DIR) HY_DB_DIR="$v" ;;
|
||||
esac
|
||||
done < "${CFG_FILE}"
|
||||
fi
|
||||
[ -z "${HY_PORT}" ] && HY_PORT="${TRIM_SERVICE_PORT:-12701}"
|
||||
|
||||
CMD="${NODE_BIN} ${SERVER}"
|
||||
|
||||
log_msg() {
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> ${LOG_FILE}
|
||||
}
|
||||
|
||||
start_process() {
|
||||
if status; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
log_msg "Starting process (port=${HY_PORT} dbdir=${HY_DB_DIR:-默认}) ..."
|
||||
# run cmd to start process
|
||||
HY_PORT="${HY_PORT}" HY_DB_DIR="${HY_DB_DIR}" HY_CFG="${CFG_FILE}" \
|
||||
bash -c "${CMD}" >> ${LOG_FILE} 2>&1 &
|
||||
# write pid to pidfile
|
||||
printf "%s" "$!" > "${PID_FILE}"
|
||||
sleep 2
|
||||
# 启动后确认进程仍在,失败时提示日志位置
|
||||
if status; then
|
||||
return 0
|
||||
fi
|
||||
echo "会员服务器启动失败,请查看日志: ${LOG_FILE}" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
stop_process() {
|
||||
log_msg "Stopping process ..."
|
||||
|
||||
if [ -r "${PID_FILE}" ]; then
|
||||
pid=$(head -n 1 "${PID_FILE}" | tr -d '[:space:]')
|
||||
|
||||
log_msg "pid=${pid}"
|
||||
if ! check_process "${pid}"; then
|
||||
# process not exist, delete pidfile
|
||||
rm -f "${PID_FILE}"
|
||||
log_msg "remove pid file 1"
|
||||
return
|
||||
fi
|
||||
|
||||
log_msg "send TERM signal to PID:${pid}..."
|
||||
kill -TERM ${pid} >> ${LOG_FILE} 2>&1
|
||||
|
||||
local count=0
|
||||
while check_process "${pid}" && [ $count -lt 10 ]; do
|
||||
sleep 1
|
||||
count=$((count + 1))
|
||||
log_msg "waiting process terminal... (${count}s/10s)"
|
||||
done
|
||||
|
||||
if check_process "${pid}"; then
|
||||
log_msg "send KILL signal to PID:${pid}..."
|
||||
kill -KILL ${pid}
|
||||
sleep 1
|
||||
rm -f "${PID_FILE}"
|
||||
else
|
||||
log_msg "process killed... "
|
||||
fi
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
check_process() {
|
||||
local pid=$1
|
||||
if kill -0 "$pid" 2>/dev/null; then
|
||||
return 0 # process exist
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
status() {
|
||||
if [ -f "${PID_FILE}" ]; then
|
||||
pid=$(head -n 1 "${PID_FILE}" | tr -d '[:space:]')
|
||||
if check_process "${pid}"; then
|
||||
return 0
|
||||
else
|
||||
# Process is not running but pidfile exists - clean it up
|
||||
rm -f "${PID_FILE}"
|
||||
fi
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
case $1 in
|
||||
start)
|
||||
# run start command. exit 0 if success, exit 1 if failed
|
||||
start_process
|
||||
;;
|
||||
stop)
|
||||
# run stop command. exit 0 if success, exit 1 if failed
|
||||
stop_process
|
||||
;;
|
||||
status)
|
||||
# check application status command. exit 0 if running, exit 3 if not running
|
||||
if status; then
|
||||
exit 0
|
||||
else
|
||||
exit 3
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
### This script is called after the user uninstalls the application.
|
||||
|
||||
exit 0
|
||||
Executable
+29
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
|
||||
### 卸载初始化:把 TLS 证书/RSA 密钥/配置备份到数据目录(数据目录在应用目录外,卸载不清除),
|
||||
### 这样升级重装后 install_init 可以恢复,已导入的正规 SSL 证书不会丢失。
|
||||
|
||||
DB_DIR="${TRIM_DATA_SHARE_PATHS%%:*}"
|
||||
|
||||
# 自定义数据目录优先(与 install_callback 的写法一致)
|
||||
CFG="${TRIM_PKGETC}/app.env"
|
||||
if [ -f "${CFG}" ]; then
|
||||
while IFS='=' read -r k v; do
|
||||
case "$k" in
|
||||
HY_DB_DIR) DB_DIR="$v" ;;
|
||||
esac
|
||||
done < "${CFG}"
|
||||
fi
|
||||
[ -z "${DB_DIR}" ] && DB_DIR="${TRIM_PKGVAR}/files"
|
||||
|
||||
BAK="${DB_DIR}/.huiyuan-密钥备份"
|
||||
mkdir -p "${BAK}" 2>/dev/null
|
||||
for f in tls.key tls.crt huiyuan_rsa.pem app.env; do
|
||||
if [ -f "${TRIM_PKGETC}/${f}" ]; then
|
||||
cp -f "${TRIM_PKGETC}/${f}" "${BAK}/${f}" 2>/dev/null
|
||||
fi
|
||||
done
|
||||
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - 卸载前已备份 TLS/RSA 密钥与配置到 ${BAK}" >> "${TRIM_PKGVAR}/app.log" 2>/dev/null
|
||||
|
||||
exit 0
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
### 升级完成回调:正常升级不覆盖 TRIM_PKGETC,配置自动延续。此处再校验兜底:
|
||||
### 若 app.env 因升级异常丢失,从 upgrade_init 在数据目录做的备份恢复,
|
||||
### 保证其他服务器上的端口/数据目录/管理密码/注册开关等配置全部沿用,绝不被重置。
|
||||
|
||||
CFG="${TRIM_PKGETC}/app.env"
|
||||
DB_DIR="${TRIM_DATA_SHARE_PATHS%%:*}"
|
||||
|
||||
if [ -f "${CFG}" ]; then
|
||||
while IFS='=' read -r k v; do
|
||||
case "$k" in
|
||||
HY_DB_DIR) DB_DIR="$v" ;;
|
||||
esac
|
||||
done < "${CFG}"
|
||||
fi
|
||||
[ -z "${DB_DIR}" ] && DB_DIR="${TRIM_PKGVAR}/files"
|
||||
|
||||
BAK="${DB_DIR}/.huiyuan-升级备份"
|
||||
|
||||
if [ ! -f "${CFG}" ] && [ -f "${BAK}/app.env" ]; then
|
||||
mkdir -p "${TRIM_PKGETC}" 2>/dev/null
|
||||
cp -f "${BAK}/app.env" "${CFG}" 2>/dev/null
|
||||
for f in tls.key tls.crt huiyuan_rsa.pem; do
|
||||
[ -f "${BAK}/${f}" ] && cp -f "${BAK}/${f}" "${TRIM_PKGETC}/${f}" 2>/dev/null
|
||||
done
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - 升级后检测到配置丢失,已从 ${BAK} 恢复 app.env 与密钥" >> "${TRIM_PKGVAR}/app.log" 2>/dev/null
|
||||
# 重读恢复出的数据目录,一并恢复数据库(若升级后库文件异常缺失)
|
||||
while IFS='=' read -r k v; do
|
||||
case "$k" in
|
||||
HY_DB_DIR) DB_DIR="$v" ;;
|
||||
esac
|
||||
done < "${CFG}"
|
||||
if [ -f "${BAK}/huiyuan.json" ] && [ ! -f "${DB_DIR}/huiyuan.json" ]; then
|
||||
cp -f "${BAK}/huiyuan.json" "${DB_DIR}/huiyuan.json" 2>/dev/null
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - 已从备份恢复数据库 huiyuan.json 到 ${DB_DIR}" >> "${TRIM_PKGVAR}/app.log" 2>/dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - upgraded to v${TRIM_APPVER} (from v${TRIM_OLD_APPVER:-unknown}) 配置与数据沿用" >> "${TRIM_PKGVAR}/app.log" 2>/dev/null
|
||||
|
||||
exit 0
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
#!/bin/bash
|
||||
|
||||
### 升级初始化:升级覆盖的是 TRIM_APPDEST(target),不动 TRIM_PKGETC(配置)与数据目录。
|
||||
### 但为防升级流程异常导致配置丢失,升级前把 app.env/TLS/RSA 密钥/数据库打包备份到
|
||||
### 数据目录(应用目录之外,升级不清除),upgrade_callback 检测到配置丢失时用此备份恢复。
|
||||
### 备份内容不含任何会员数据和配置本体,只在升级窗口存在,升级正常完成后保留最近一份
|
||||
### 作为兜底,不参与运行。
|
||||
|
||||
DB_DIR="${TRIM_DATA_SHARE_PATHS%%:*}"
|
||||
|
||||
# 自定义数据目录优先(与 install_callback/uninstall_init 的解析规则一致)
|
||||
CFG="${TRIM_PKGETC}/app.env"
|
||||
if [ -f "${CFG}" ]; then
|
||||
while IFS='=' read -r k v; do
|
||||
case "$k" in
|
||||
HY_DB_DIR) DB_DIR="$v" ;;
|
||||
esac
|
||||
done < "${CFG}"
|
||||
fi
|
||||
[ -z "${DB_DIR}" ] && DB_DIR="${TRIM_PKGVAR}/files"
|
||||
|
||||
BAK="${DB_DIR}/.huiyuan-升级备份"
|
||||
mkdir -p "${BAK}" 2>/dev/null
|
||||
|
||||
# 备份配置目录里的 app.env 与密钥证书(若存在)
|
||||
for f in app.env tls.key tls.crt huiyuan_rsa.pem; do
|
||||
if [ -f "${TRIM_PKGETC}/${f}" ]; then
|
||||
cp -f "${TRIM_PKGETC}/${f}" "${BAK}/${f}" 2>/dev/null
|
||||
fi
|
||||
done
|
||||
|
||||
# 备份数据库(小 JSON 文件,整库快照)
|
||||
if [ -f "${DB_DIR}/huiyuan.json" ]; then
|
||||
cp -f "${DB_DIR}/huiyuan.json" "${BAK}/huiyuan.json" 2>/dev/null
|
||||
fi
|
||||
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - 升级前已备份配置与数据库到 ${BAK} (v${TRIM_OLD_APPVER:-?} → v${TRIM_APPVER})" >> "${TRIM_PKGVAR}/app.log" 2>/dev/null
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user