107 lines
5.8 KiB
YAML
Executable File
107 lines
5.8 KiB
YAML
Executable File
name: Grant Super Admin (设超管 · 可带外建号)
|
||
|
||
# 超管不是"某个预置账号+密码"——代码里没有种子管理员、密码全是 salt+hash 不可反推。
|
||
# 超管 = .env 的 SUPER_ADMIN_EMAILS 白名单:【白名单里的邮箱,谁拥有这个账号,谁就是超管】。
|
||
#
|
||
# ⚠ 重要(安全策略变更后的正确顺序):
|
||
# 为堵住"管理员邮箱可被任何人抢注→拿全部后台权限"的漏洞,后端【已禁止用白名单邮箱自助注册】。
|
||
# 所以【先加白名单、再去注册】这条老路已经走不通(注册会被 403 挡掉)。
|
||
# 现在有两条路:
|
||
# A) 已有账号:你的邮箱【已经】在平台注册过 → 直接跑本工作流加白名单 → 重新登录即为超管。
|
||
# B) 没有账号:勾选 create_or_reset_account → 本工作流【带外】在库里建号/重置密码(密码取自
|
||
# 仓库 Secret: ADMIN_INIT_PASSWORD)→ 加白名单 → 用该邮箱+该密码登录即为超管。
|
||
#
|
||
# 走 B 之前请先在 GitHub 仓库 Settings → Secrets and variables → Actions 添加:
|
||
# ADMIN_INIT_PASSWORD = 你的强密码(≥8位)。用 Secret 而不是工作流输入框——输入框的值会明文
|
||
# 留在 Actions 运行记录里,Secret 会在日志中被自动打码。
|
||
#
|
||
# 前置:后端需已部署过(含 scripts/create-admin.js)。若提示脚本不存在,先跑一次后端部署工作流。
|
||
|
||
on:
|
||
workflow_dispatch:
|
||
inputs:
|
||
admin_email:
|
||
description: '要设为超管的邮箱(用你自己的)'
|
||
required: true
|
||
type: string
|
||
create_or_reset_account:
|
||
description: '带外建号/重置密码(账号还不存在、或忘了密码时勾选;密码取自 Secret ADMIN_INIT_PASSWORD)'
|
||
required: false
|
||
default: false
|
||
type: boolean
|
||
delete_orphan_admin:
|
||
description: '同时删除误建的孤儿账号 admin@test.com(密码随机无人知道,建议删)'
|
||
required: false
|
||
default: true
|
||
type: boolean
|
||
|
||
jobs:
|
||
grant:
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- name: Set SUPER_ADMIN_EMAILS (+ optional out-of-band account provisioning)
|
||
uses: appleboy/ssh-action@v1
|
||
env:
|
||
ADMIN_EMAIL: ${{ inputs.admin_email }}
|
||
ADMIN_PASSWORD: ${{ secrets.ADMIN_INIT_PASSWORD }}
|
||
DO_CREATE: ${{ inputs.create_or_reset_account }}
|
||
DO_DELETE_ORPHAN: ${{ inputs.delete_orphan_admin }}
|
||
with:
|
||
host: ${{ secrets.ECS_HOST }}
|
||
username: ${{ secrets.ECS_USER }}
|
||
password: ${{ secrets.ECS_PASSWORD }}
|
||
command_timeout: 5m
|
||
envs: ADMIN_EMAIL,ADMIN_PASSWORD,DO_CREATE,DO_DELETE_ORPHAN
|
||
script: |
|
||
set -e
|
||
cd /var/www/digitalme-api.invoratec.cn
|
||
[ -f .env ] || { echo "❌ 生产 .env 缺失,中止"; exit 1; }
|
||
|
||
echo "──── 当前 SUPER_ADMIN_EMAILS ────"
|
||
grep '^SUPER_ADMIN_EMAILS=' .env || echo "(未设置 → 现在没有任何人是超管)"
|
||
|
||
EMAIL="$(echo "$ADMIN_EMAIL" | tr '[:upper:]' '[:lower:]' | tr -d ' ')"
|
||
if [ -z "$EMAIL" ]; then echo "❌ 邮箱为空"; exit 1; fi
|
||
|
||
# ── 带外建号/重置密码(账号不存在时的唯一入口,因为白名单邮箱已禁止自助注册) ──
|
||
if [ "$DO_CREATE" = "true" ]; then
|
||
if [ -z "$ADMIN_PASSWORD" ]; then
|
||
echo "❌ 勾了「带外建号」但仓库 Secret ADMIN_INIT_PASSWORD 未设置。"
|
||
echo " 去 GitHub → Settings → Secrets and variables → Actions 添加 ADMIN_INIT_PASSWORD(≥8位) 再重跑。"
|
||
exit 1
|
||
fi
|
||
[ -f scripts/create-admin.js ] || { echo "❌ 服务器上没有 scripts/create-admin.js —— 请先跑一次【后端部署】工作流再来。"; exit 1; }
|
||
echo "──── 带外建号/重置密码 ────"
|
||
ADMIN_EMAIL="$EMAIL" ADMIN_PASSWORD="$ADMIN_PASSWORD" node scripts/create-admin.js
|
||
fi
|
||
|
||
# ── 写入/覆盖超管白名单(只放这一个邮箱,最小权限) ──
|
||
if grep -q '^SUPER_ADMIN_EMAILS=' .env; then
|
||
sed -i "s|^SUPER_ADMIN_EMAILS=.*|SUPER_ADMIN_EMAILS=$EMAIL|" .env
|
||
else
|
||
echo "SUPER_ADMIN_EMAILS=$EMAIL" >> .env
|
||
fi
|
||
echo "──── 写入后 ────"
|
||
grep '^SUPER_ADMIN_EMAILS=' .env
|
||
|
||
# 删掉被误建的孤儿账号 admin@test.com(随机密码、无人知道、白占邮箱)
|
||
if [ "$DO_DELETE_ORPHAN" = "true" ] && [ "$EMAIL" != "admin@test.com" ]; then
|
||
MONGO_URI="$(grep '^MONGO_URI=' .env | cut -d= -f2- || echo 'mongodb://localhost:27017')"
|
||
MONGO_DB="$(grep '^MONGO_DB=' .env | cut -d= -f2- || echo 'creator_cn')"
|
||
echo "──── 删除孤儿账号 admin@test.com ────"
|
||
mongosh "$MONGO_URI/$MONGO_DB" --quiet --eval '
|
||
const u = db.users.findOne({ email: "admin@test.com" });
|
||
if (!u) { print("admin@test.com 不存在,无需清理"); }
|
||
else {
|
||
const r = db.users.deleteOne({ _id: u._id });
|
||
print("已删除 admin@test.com,deletedCount=" + r.deletedCount);
|
||
}
|
||
' || echo "⚠ mongosh 执行失败(可手动清理),不影响超管设置"
|
||
fi
|
||
|
||
# 重启后端让新的 .env 生效
|
||
pm2 restart digitalme-api --update-env
|
||
pm2 describe digitalme-api | grep -E 'status|restarts' || true
|
||
echo "✅ 完成。用 $EMAIL 登录 → 即为超管(右上角出现盾牌图标 / 可进 /admin)。"
|
||
echo " 若刚带外建号:用你在 Secret ADMIN_INIT_PASSWORD 里设的密码登录,登录后建议立刻改密。"
|