Files

107 lines
5.8 KiB
YAML
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 里设的密码登录,登录后建议立刻改密。"