Merge pull request #303 from qinfendebingshuo/copilot/add-email-verification-content
邮件模块重构: 专业化语言 + V3订阅邮件 + guanghulab.online桥接 + ∞工作流整合
This commit is contained in:
commit
1509cb4726
|
|
@ -201,6 +201,14 @@ jobs:
|
||||||
# Nginx中 _ 是标准的catch-all server_name,不匹配任何实际域名
|
# Nginx中 _ 是标准的catch-all server_name,不匹配任何实际域名
|
||||||
sed -i "s/ZY_DOMAIN_PREVIEW_PLACEHOLDER/_/g" /tmp/zhuyuan-sovereign.conf
|
sed -i "s/ZY_DOMAIN_PREVIEW_PLACEHOLDER/_/g" /tmp/zhuyuan-sovereign.conf
|
||||||
fi
|
fi
|
||||||
|
ZY_BRAIN_HOST="${{ secrets.ZY_BRAIN_HOST }}"
|
||||||
|
if [ -n "$ZY_BRAIN_HOST" ]; then
|
||||||
|
sed -i "s/ZY_BRAIN_HOST_PLACEHOLDER/$ZY_BRAIN_HOST/g" /tmp/zhuyuan-sovereign.conf
|
||||||
|
echo "✅ 大脑服务器已注入V3桥接: $ZY_BRAIN_HOST"
|
||||||
|
else
|
||||||
|
echo "⚠️ ZY_BRAIN_HOST 未配置,V3桥接不可用"
|
||||||
|
sed -i '/ZY_BRAIN_HOST_PLACEHOLDER/d' /tmp/zhuyuan-sovereign.conf
|
||||||
|
fi
|
||||||
scp -i ~/.ssh/zy_key \
|
scp -i ~/.ssh/zy_key \
|
||||||
/tmp/zhuyuan-sovereign.conf \
|
/tmp/zhuyuan-sovereign.conf \
|
||||||
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }}:/opt/zhuyuan/config/nginx/zhuyuan-sovereign.conf
|
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }}:/opt/zhuyuan/config/nginx/zhuyuan-sovereign.conf
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ on:
|
||||||
- 'server/proxy/service/bandwidth-pool-agent.js'
|
- 'server/proxy/service/bandwidth-pool-agent.js'
|
||||||
- 'server/proxy/service/swarm-defense-agent.js'
|
- 'server/proxy/service/swarm-defense-agent.js'
|
||||||
- 'server/proxy/service/user-guardian-agent.js'
|
- 'server/proxy/service/user-guardian-agent.js'
|
||||||
|
- 'server/proxy/service/subscription-server-v3.js'
|
||||||
- 'server/proxy/config/release-notes.json'
|
- 'server/proxy/config/release-notes.json'
|
||||||
- 'server/proxy/ecosystem.brain-proxy-v3.config.js'
|
- 'server/proxy/ecosystem.brain-proxy-v3.config.js'
|
||||||
schedule:
|
schedule:
|
||||||
|
|
@ -40,6 +41,10 @@ on:
|
||||||
- monthly-evolution
|
- monthly-evolution
|
||||||
- deploy-infinity
|
- deploy-infinity
|
||||||
- status
|
- status
|
||||||
|
- add-user
|
||||||
|
- remove-user
|
||||||
|
- list-users
|
||||||
|
- send-subscription-v3
|
||||||
- send-monthly-reset
|
- send-monthly-reset
|
||||||
- send-update-notify
|
- send-update-notify
|
||||||
- send-update-notify-single
|
- send-update-notify-single
|
||||||
|
|
@ -55,9 +60,14 @@ on:
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
email:
|
email:
|
||||||
description: '目标邮箱 (send-update-notify-single/send-bandwidth-auth-single时需要 · 可先用list-user-emails查看)'
|
description: '目标邮箱 (add-user/remove-user/send-subscription-v3/send-update-notify-single/send-bandwidth-auth-single时需要)'
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
|
quota_gb:
|
||||||
|
description: '月配额GB (add-user时可选,默认500)'
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: '500'
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
@ -89,6 +99,7 @@ jobs:
|
||||||
ACTION: ${{ github.event_name == 'push' && 'deploy-infinity' || github.event.inputs.action || 'monthly-evolution' }}
|
ACTION: ${{ github.event_name == 'push' && 'deploy-infinity' || github.event.inputs.action || 'monthly-evolution' }}
|
||||||
MESSAGE: ${{ github.event.inputs.message || '' }}
|
MESSAGE: ${{ github.event.inputs.message || '' }}
|
||||||
EMAIL: ${{ github.event.inputs.email || '' }}
|
EMAIL: ${{ github.event.inputs.email || '' }}
|
||||||
|
QUOTA: ${{ github.event.inputs.quota_gb || '500' }}
|
||||||
ZY_SMTP_USER: ${{ secrets.ZY_SMTP_USER }}
|
ZY_SMTP_USER: ${{ secrets.ZY_SMTP_USER }}
|
||||||
ZY_SMTP_PASS: ${{ secrets.ZY_SMTP_PASS }}
|
ZY_SMTP_PASS: ${{ secrets.ZY_SMTP_PASS }}
|
||||||
run: |
|
run: |
|
||||||
|
|
@ -98,18 +109,20 @@ jobs:
|
||||||
REMOTE_HOST="${{ secrets.ZY_BRAIN_USER }}@${{ secrets.ZY_BRAIN_HOST }}"
|
REMOTE_HOST="${{ secrets.ZY_BRAIN_USER }}@${{ secrets.ZY_BRAIN_HOST }}"
|
||||||
|
|
||||||
# ── 同步邮件模块到服务器 ──
|
# ── 同步邮件模块到服务器 ──
|
||||||
# 确保服务器上的email-hub.js和release-notes.json是最新版本
|
# 确保服务器上的email-hub.js和相关模块是最新版本
|
||||||
sync_email_files() {
|
sync_email_files() {
|
||||||
echo "📦 同步邮件模块到服务器..."
|
echo "📦 同步邮件模块到服务器..."
|
||||||
$SSH_CMD "mkdir -p $PROXY_DIR/.deploy-tmp $PROXY_DIR/config"
|
$SSH_CMD "mkdir -p $PROXY_DIR/.deploy-tmp $PROXY_DIR/config"
|
||||||
$SCP_CMD \
|
$SCP_CMD \
|
||||||
server/proxy/service/email-hub.js \
|
server/proxy/service/email-hub.js \
|
||||||
server/proxy/service/bandwidth-pool-agent.js \
|
server/proxy/service/bandwidth-pool-agent.js \
|
||||||
|
server/proxy/service/subscription-server-v3.js \
|
||||||
server/proxy/config/release-notes.json \
|
server/proxy/config/release-notes.json \
|
||||||
${REMOTE_HOST}:$PROXY_DIR/.deploy-tmp/
|
${REMOTE_HOST}:$PROXY_DIR/.deploy-tmp/
|
||||||
$SSH_CMD "
|
$SSH_CMD "
|
||||||
cp $PROXY_DIR/.deploy-tmp/email-hub.js $PROXY_DIR/service/
|
cp $PROXY_DIR/.deploy-tmp/email-hub.js $PROXY_DIR/service/
|
||||||
cp $PROXY_DIR/.deploy-tmp/bandwidth-pool-agent.js $PROXY_DIR/service/
|
cp $PROXY_DIR/.deploy-tmp/bandwidth-pool-agent.js $PROXY_DIR/service/
|
||||||
|
cp $PROXY_DIR/.deploy-tmp/subscription-server-v3.js $PROXY_DIR/service/
|
||||||
cp $PROXY_DIR/.deploy-tmp/release-notes.json $PROXY_DIR/config/
|
cp $PROXY_DIR/.deploy-tmp/release-notes.json $PROXY_DIR/config/
|
||||||
rm -rf $PROXY_DIR/.deploy-tmp
|
rm -rf $PROXY_DIR/.deploy-tmp
|
||||||
"
|
"
|
||||||
|
|
@ -133,6 +146,7 @@ jobs:
|
||||||
server/proxy/service/bandwidth-pool-agent.js \
|
server/proxy/service/bandwidth-pool-agent.js \
|
||||||
server/proxy/service/swarm-defense-agent.js \
|
server/proxy/service/swarm-defense-agent.js \
|
||||||
server/proxy/service/user-guardian-agent.js \
|
server/proxy/service/user-guardian-agent.js \
|
||||||
|
server/proxy/service/subscription-server-v3.js \
|
||||||
server/proxy/config/release-notes.json \
|
server/proxy/config/release-notes.json \
|
||||||
server/proxy/ecosystem.brain-proxy-v3.config.js \
|
server/proxy/ecosystem.brain-proxy-v3.config.js \
|
||||||
${{ secrets.ZY_BRAIN_USER }}@${{ secrets.ZY_BRAIN_HOST }}:$PROXY_DIR/.deploy-tmp/
|
${{ secrets.ZY_BRAIN_USER }}@${{ secrets.ZY_BRAIN_HOST }}:$PROXY_DIR/.deploy-tmp/
|
||||||
|
|
@ -144,6 +158,7 @@ jobs:
|
||||||
cp $PROXY_DIR/.deploy-tmp/bandwidth-pool-agent.js $PROXY_DIR/service/
|
cp $PROXY_DIR/.deploy-tmp/bandwidth-pool-agent.js $PROXY_DIR/service/
|
||||||
cp $PROXY_DIR/.deploy-tmp/swarm-defense-agent.js $PROXY_DIR/service/
|
cp $PROXY_DIR/.deploy-tmp/swarm-defense-agent.js $PROXY_DIR/service/
|
||||||
cp $PROXY_DIR/.deploy-tmp/user-guardian-agent.js $PROXY_DIR/service/
|
cp $PROXY_DIR/.deploy-tmp/user-guardian-agent.js $PROXY_DIR/service/
|
||||||
|
cp $PROXY_DIR/.deploy-tmp/subscription-server-v3.js $PROXY_DIR/service/
|
||||||
mkdir -p $PROXY_DIR/config
|
mkdir -p $PROXY_DIR/config
|
||||||
cp $PROXY_DIR/.deploy-tmp/release-notes.json $PROXY_DIR/config/
|
cp $PROXY_DIR/.deploy-tmp/release-notes.json $PROXY_DIR/config/
|
||||||
cp $PROXY_DIR/.deploy-tmp/ecosystem.brain-proxy-v3.config.js $PROXY_DIR/
|
cp $PROXY_DIR/.deploy-tmp/ecosystem.brain-proxy-v3.config.js $PROXY_DIR/
|
||||||
|
|
@ -185,6 +200,71 @@ jobs:
|
||||||
"
|
"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
add-user)
|
||||||
|
if [ -z "$EMAIL" ]; then
|
||||||
|
echo "❌ 请提供目标邮箱 (email字段)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! echo "$EMAIL" | grep -qE '^[^@]+@[^@]+\.[^@]+$'; then
|
||||||
|
echo "❌ 邮箱格式不正确: $EMAIL"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "➕ 新增用户: $EMAIL (配额: ${QUOTA}GB/月)"
|
||||||
|
$SSH_CMD "
|
||||||
|
cd $PROXY_DIR
|
||||||
|
node service/user-manager.js add '$EMAIL' '${QUOTA}'
|
||||||
|
"
|
||||||
|
echo ""
|
||||||
|
echo "════════════════════════════════════════"
|
||||||
|
echo "✅ 用户已添加"
|
||||||
|
echo "下一步: 运行 send-subscription-v3 发送V3订阅链接到 $EMAIL"
|
||||||
|
echo "════════════════════════════════════════"
|
||||||
|
;;
|
||||||
|
|
||||||
|
remove-user)
|
||||||
|
if [ -z "$EMAIL" ]; then
|
||||||
|
echo "❌ 请提供目标邮箱 (email字段)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! echo "$EMAIL" | grep -qE '^[^@]+@[^@]+\.[^@]+$'; then
|
||||||
|
echo "❌ 邮箱格式不正确: $EMAIL"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "➖ 移除用户: $EMAIL"
|
||||||
|
$SSH_CMD "
|
||||||
|
cd $PROXY_DIR
|
||||||
|
node service/user-manager.js remove '$EMAIL'
|
||||||
|
"
|
||||||
|
;;
|
||||||
|
|
||||||
|
list-users)
|
||||||
|
echo "📋 用户列表:"
|
||||||
|
$SSH_CMD "
|
||||||
|
cd $PROXY_DIR
|
||||||
|
node service/user-manager.js list
|
||||||
|
"
|
||||||
|
;;
|
||||||
|
|
||||||
|
send-subscription-v3)
|
||||||
|
if [ -z "$EMAIL" ]; then
|
||||||
|
echo "❌ 请提供目标邮箱 (email字段)"
|
||||||
|
echo "💡 可先使用 list-users 或 list-user-emails 查看用户"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! echo "$EMAIL" | grep -qE '^[^@]+@[^@]+\.[^@]+$'; then
|
||||||
|
echo "❌ 邮箱格式不正确: $EMAIL"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sync_email_files
|
||||||
|
echo "发送V3订阅链接 (含系统介绍+带宽共享邀请) 给: $EMAIL ..."
|
||||||
|
$SSH_CMD "
|
||||||
|
cd $PROXY_DIR
|
||||||
|
export ZY_SMTP_USER='$ZY_SMTP_USER'
|
||||||
|
export ZY_SMTP_PASS='$ZY_SMTP_PASS'
|
||||||
|
node service/email-hub.js send-subscription-v3 '$EMAIL'
|
||||||
|
"
|
||||||
|
;;
|
||||||
|
|
||||||
send-monthly-reset)
|
send-monthly-reset)
|
||||||
sync_email_files
|
sync_email_files
|
||||||
echo "发送月初重置邮件..."
|
echo "发送月初重置邮件..."
|
||||||
|
|
|
||||||
|
|
@ -172,6 +172,12 @@ jobs:
|
||||||
else
|
else
|
||||||
sed -i "s/ZY_DOMAIN_PREVIEW_PLACEHOLDER/_/g" /tmp/zhuyuan-sovereign.conf
|
sed -i "s/ZY_DOMAIN_PREVIEW_PLACEHOLDER/_/g" /tmp/zhuyuan-sovereign.conf
|
||||||
fi
|
fi
|
||||||
|
ZY_BRAIN_HOST="${{ secrets.ZY_BRAIN_HOST }}"
|
||||||
|
if [ -n "$ZY_BRAIN_HOST" ]; then
|
||||||
|
sed -i "s/ZY_BRAIN_HOST_PLACEHOLDER/$ZY_BRAIN_HOST/g" /tmp/zhuyuan-sovereign.conf
|
||||||
|
else
|
||||||
|
sed -i '/ZY_BRAIN_HOST_PLACEHOLDER/d' /tmp/zhuyuan-sovereign.conf
|
||||||
|
fi
|
||||||
scp -i $KEY /tmp/zhuyuan-sovereign.conf \
|
scp -i $KEY /tmp/zhuyuan-sovereign.conf \
|
||||||
$USER@$HOST:/opt/zhuyuan/config/nginx/zhuyuan-sovereign.conf 2>&1 || true
|
$USER@$HOST:/opt/zhuyuan/config/nginx/zhuyuan-sovereign.conf 2>&1 || true
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -153,6 +153,26 @@ server {
|
||||||
try_files $uri $uri/ /index.html;
|
try_files $uri $uri/ /index.html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ─── 光湖语言世界V3 · 带宽授权桥接 (大脑服务器反向代理) ───
|
||||||
|
# QQ邮箱拦截大脑服务器域名链接,此桥接通过guanghulab.online域名
|
||||||
|
# 将V3授权/订阅请求透传到大脑服务器的V3订阅服务 (端口3805)
|
||||||
|
# 协议: HTTP (内网通信,大脑服务器Nginx监听80端口default_server)
|
||||||
|
# 部署时由 workflow 自动将 ZY_BRAIN_HOST_PLACEHOLDER 替换为实际IP
|
||||||
|
location /api/proxy-v3/ {
|
||||||
|
proxy_pass http://ZY_BRAIN_HOST_PLACEHOLDER/api/proxy-v3/;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_connect_timeout 10s;
|
||||||
|
proxy_read_timeout 30s;
|
||||||
|
proxy_send_timeout 30s;
|
||||||
|
add_header X-Content-Type-Options nosniff always;
|
||||||
|
add_header X-Frame-Options DENY always;
|
||||||
|
add_header Cache-Control "no-store, no-cache, must-revalidate" always;
|
||||||
|
}
|
||||||
|
|
||||||
# ─── 铸渊 API 反向代理 (端口 3801 · 预览端口) ───
|
# ─── 铸渊 API 反向代理 (端口 3801 · 预览端口) ───
|
||||||
location /api/ {
|
location /api/ {
|
||||||
proxy_pass http://127.0.0.1:3801;
|
proxy_pass http://127.0.0.1:3801;
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
// 6. 带宽共享验证码 — 发送6位验证码 (∞+1·含VPN系统介绍)
|
// 6. 带宽共享验证码 — 发送6位验证码 (∞+1·含VPN系统介绍)
|
||||||
// 7. 风险提示通知 — 全体用户风险提醒 (∞+1)
|
// 7. 风险提示通知 — 全体用户风险提醒 (∞+1)
|
||||||
// 8. 安全恢复通知 — 危机解除后全体通知 (∞+1)
|
// 8. 安全恢复通知 — 危机解除后全体通知 (∞+1)
|
||||||
|
// 9. V3订阅链接 — 含系统介绍 + 带宽共享邀请 (∞+1)
|
||||||
//
|
//
|
||||||
// 所有邮件底部附「意见反馈」链接
|
// 所有邮件底部附「意见反馈」链接
|
||||||
//
|
//
|
||||||
|
|
@ -31,6 +32,7 @@
|
||||||
// node email-hub.js bandwidth-auth-all — 一键发送带宽验证码 (全部用户·∞+1)
|
// node email-hub.js bandwidth-auth-all — 一键发送带宽验证码 (全部用户·∞+1)
|
||||||
// node email-hub.js threat-alert <msg> — 全体用户风险提示 (∞+1)
|
// node email-hub.js threat-alert <msg> — 全体用户风险提示 (∞+1)
|
||||||
// node email-hub.js threat-cleared — 全体用户安全恢复通知 (∞+1)
|
// node email-hub.js threat-cleared — 全体用户安全恢复通知 (∞+1)
|
||||||
|
// node email-hub.js send-subscription-v3 <email> — 发送V3订阅链接 (含系统介绍+带宽共享邀请)
|
||||||
// node email-hub.js list-emails — 列出所有启用用户的邮箱
|
// node email-hub.js list-emails — 列出所有启用用户的邮箱
|
||||||
//
|
//
|
||||||
// 运行方式: CLI调用 (由auto-evolution.js调度)
|
// 运行方式: CLI调用 (由auto-evolution.js调度)
|
||||||
|
|
@ -50,6 +52,11 @@ const POOL_STATUS_FILE = path.join(DATA_DIR, 'pool-quota-status.json');
|
||||||
const EMAIL_LOG_FILE = path.join(DATA_DIR, 'email-hub-log.json');
|
const EMAIL_LOG_FILE = path.join(DATA_DIR, 'email-hub-log.json');
|
||||||
const RELEASE_NOTES_FILE = path.join(__dirname, '../config/release-notes.json');
|
const RELEASE_NOTES_FILE = path.join(__dirname, '../config/release-notes.json');
|
||||||
|
|
||||||
|
// ── 带宽授权页面域名 ─────────────────────────
|
||||||
|
// QQ邮箱拦截guanghulab.com域名链接,使用guanghulab.online桥接
|
||||||
|
// guanghulab.online通过Nginx反向代理桥接到大脑服务器V3订阅服务
|
||||||
|
const BW_AUTH_HOST = process.env.ZY_BW_AUTH_HOST || 'guanghulab.online';
|
||||||
|
|
||||||
// ── 加载版本更新说明 ────────────────────────────
|
// ── 加载版本更新说明 ────────────────────────────
|
||||||
function loadReleaseNotes() {
|
function loadReleaseNotes() {
|
||||||
try {
|
try {
|
||||||
|
|
@ -607,9 +614,9 @@ function generateBandwidthAuthEmail(code, authPageUrl, config) {
|
||||||
|
|
||||||
<h3 class="section-heading" style="color: #1a1a2e; font-size: 16px; margin: 0 0 12px; font-weight: 600;">🔑 带宽共享加速 · 验证码授权</h3>
|
<h3 class="section-heading" style="color: #1a1a2e; font-size: 16px; margin: 0 0 12px; font-weight: 600;">🔑 带宽共享加速 · 验证码授权</h3>
|
||||||
<p style="color: #444; line-height: 1.9; font-size: 14px; margin: 0 0 24px;">
|
<p style="color: #444; line-height: 1.9; font-size: 14px; margin: 0 0 24px;">
|
||||||
您正在参与<strong>光湖语言世界</strong>的带宽共享加速计划。<br>
|
本邮件为<strong>光湖语言世界</strong>带宽共享加速计划的授权验证通知。<br>
|
||||||
这是一项<strong>完全自愿</strong>的功能,参与后可让VPN网络整体更快。<br>
|
带宽共享为<strong>自愿参与</strong>机制,参与后将提升全网连接速度与稳定性。<br>
|
||||||
如果您<strong>同意授权</strong>,请复制以下验证码并提交:
|
如您确认授权,请复制以下验证码并在授权页面提交:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- 验证码展示区 -->
|
<!-- 验证码展示区 -->
|
||||||
|
|
@ -628,31 +635,31 @@ function generateBandwidthAuthEmail(code, authPageUrl, config) {
|
||||||
|
|
||||||
<!-- 同意说明 -->
|
<!-- 同意说明 -->
|
||||||
<div class="info-card" style="background: #f0faf3; border-radius: 10px; padding: 18px 20px; margin: 0 0 12px; border-left: 4px solid #28a745;">
|
<div class="info-card" style="background: #f0faf3; border-radius: 10px; padding: 18px 20px; margin: 0 0 12px; border-left: 4px solid #28a745;">
|
||||||
<h4 style="color: #155724; margin: 0 0 8px; font-size: 14px; font-weight: 600;">✅ 同意授权 = 输入验证码</h4>
|
<h4 style="color: #155724; margin: 0 0 8px; font-size: 14px; font-weight: 600;">✅ 授权确认 · 提交验证码</h4>
|
||||||
<p style="color: #555; font-size: 13px; margin: 0; line-height: 1.9;">
|
<p style="color: #555; font-size: 13px; margin: 0; line-height: 1.9;">
|
||||||
您的多余带宽将用于加速VPN网络。<br>
|
您的闲置带宽将纳入光湖语言世界加速网络。<br>
|
||||||
用的人越多,系统越快。您自己也会享受到加速效果。
|
参与带宽共享的用户越多,全网加速效能越高,您的连接速度将同步提升。
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 不同意说明 -->
|
<!-- 不同意说明 -->
|
||||||
<div class="info-card" style="background: #f8f9fa; border-radius: 10px; padding: 18px 20px; margin: 0 0 12px; border-left: 4px solid #6c757d;">
|
<div class="info-card" style="background: #f8f9fa; border-radius: 10px; padding: 18px 20px; margin: 0 0 12px; border-left: 4px solid #6c757d;">
|
||||||
<h4 style="color: #495057; margin: 0 0 8px; font-size: 14px; font-weight: 600;">❌ 不同意 = 忽略此邮件即可</h4>
|
<h4 style="color: #495057; margin: 0 0 8px; font-size: 14px; font-weight: 600;">❌ 暂不参与 · 无需操作</h4>
|
||||||
<p style="color: #555; font-size: 13px; margin: 0; line-height: 1.9;">
|
<p style="color: #555; font-size: 13px; margin: 0; line-height: 1.9;">
|
||||||
完全没问题,这是您的自由选择。您可以继续正常使用VPN,<br>
|
本功能为自愿参与机制,不影响您的正常服务使用。<br>
|
||||||
只是走系统自身带宽,速度可能慢一些,但也比普通VPN好太多了。<br>
|
未参与带宽共享的用户将通过系统默认带宽通道连接,服务质量不受影响。<br>
|
||||||
如果以后改变主意,随时可以联系我们重新发送验证码。
|
如后续需要参与,可通过仪表盘页面重新发起授权申请。
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 安全说明 -->
|
<!-- 安全说明 -->
|
||||||
<div class="info-card" style="background: #fffbeb; border: 1px solid #ffc107; border-radius: 10px; padding: 16px 20px; margin: 16px 0 0;">
|
<div class="info-card" style="background: #fffbeb; border: 1px solid #ffc107; border-radius: 10px; padding: 16px 20px; margin: 16px 0 0;">
|
||||||
<p style="color: #856404; font-size: 13px; margin: 0; line-height: 1.8;">
|
<p style="color: #856404; font-size: 13px; margin: 0; line-height: 1.8;">
|
||||||
🔒 <strong>安全说明</strong>:本VPN是内部专用的,用户都是团队自己人。
|
🔒 <strong>安全机制说明</strong>:本系统为内部授权用户专用,所有参与者均为受邀成员。
|
||||||
您的IP仅用于带宽加速,系统内部加密存储(SHA256 + 盐值),外部无法看到。
|
您的IP地址仅用于带宽加速调度,系统采用 <strong>SHA256 + 盐值</strong> 加密存储,外部无法访问。
|
||||||
若检测到任何风险,系统会<strong>自动切断您的共享通道</strong>,
|
当系统检测到安全风险时,将自动执行以下保护措施:
|
||||||
并格式化所有共享记录——就像这条路从未出现过一样。
|
即时切断所有共享通道、格式化全部共享记录确保无痕清除。
|
||||||
危机解除后,我们会重新为您推送新的订阅链接。您的隐私安全,铸渊守护。
|
风险解除后,系统将自动重新分配订阅链接。您的隐私安全由铸渊守护体系全程保障。
|
||||||
</p>
|
</p>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
|
|
@ -722,6 +729,108 @@ function generateThreatClearedEmail(config) {
|
||||||
return wrapEmailTemplate('安全恢复通知', content, config);
|
return wrapEmailTemplate('安全恢复通知', content, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════
|
||||||
|
// 📧 邮件类型 9: V3订阅链接 (含系统介绍 + 带宽共享邀请)
|
||||||
|
// ═══════════════════════════════════════════════
|
||||||
|
function generateSubscriptionV3Email(subUrl, dashboardUrl, bwAuthUrl, config) {
|
||||||
|
const releaseNotes = loadReleaseNotesObj();
|
||||||
|
const vpnIntro = getVpnSystemIntroHtml(releaseNotes);
|
||||||
|
|
||||||
|
const content = `
|
||||||
|
<div class="alert-box" style="background: #d4edda; border: 1px solid #c3e6cb; border-radius: 10px; padding: 16px 20px; margin: 0 0 24px;">
|
||||||
|
<strong style="color: #155724; font-size: 15px;">✅ 光湖语言世界 V3 正式版 · 专属订阅</strong>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3 class="section-heading" style="color: #1a1a2e; font-size: 16px; margin: 0 0 12px; font-weight: 600;">📱 订阅链接</h3>
|
||||||
|
<div class="info-card" style="background: #f0f4ff; border: 1px solid #d0d8ff; border-radius: 10px; padding: 16px 20px; word-break: break-all; font-family: Consolas, Monaco, 'Courier New', monospace; font-size: 13px; margin: 0 0 8px; color: #333;">
|
||||||
|
${escapeHtml(subUrl)}
|
||||||
|
</div>
|
||||||
|
<p style="color: #999; font-size: 12px; margin: 0 0 24px;">
|
||||||
|
⚠️ 此链接为个人专属,请勿对外分享。全部用户共享 2000GB 月流量池。
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3 class="section-heading" style="color: #1a1a2e; font-size: 16px; margin: 0 0 12px; font-weight: 600;">📊 流量仪表盘</h3>
|
||||||
|
<div class="info-card" style="background: #fff8e1; border: 1px solid #ffe082; border-radius: 10px; padding: 16px 20px; word-break: break-all; font-family: Consolas, Monaco, 'Courier New', monospace; font-size: 13px; margin: 0 0 8px; color: #333;">
|
||||||
|
${escapeHtml(dashboardUrl)}
|
||||||
|
</div>
|
||||||
|
<p style="color: #999; font-size: 12px; margin: 0 0 24px;">
|
||||||
|
💡 在浏览器中打开,可查看实时流量统计与节点状态。
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3 class="section-heading" style="color: #1a1a2e; font-size: 16px; margin: 0 0 16px; font-weight: 600;">📋 客户端配置指引</h3>
|
||||||
|
<div class="info-card" style="background: #fafbfc; border-radius: 10px; padding: 20px; border: 1px solid #e8eaed; margin: 0 0 24px;">
|
||||||
|
<h4 style="color: #555; margin: 0 0 8px; font-size: 14px; font-weight: 600;">🍎 iOS (Shadowrocket)</h4>
|
||||||
|
<ol style="color: #666; line-height: 2; font-size: 13px; padding-left: 20px; margin: 0 0 16px;">
|
||||||
|
<li>打开 Shadowrocket → 点击右上角 <strong>+</strong></li>
|
||||||
|
<li>选择 <strong>Subscribe</strong> (订阅) → 粘贴订阅链接</li>
|
||||||
|
<li>点击完成 → 选择节点 → 开启连接</li>
|
||||||
|
</ol>
|
||||||
|
<h4 style="color: #555; margin: 0 0 8px; font-size: 14px; font-weight: 600;">💻 Mac / Windows (Clash Verge)</h4>
|
||||||
|
<ol style="color: #666; line-height: 2; font-size: 13px; padding-left: 20px; margin: 0 0 16px;">
|
||||||
|
<li>打开 Clash Verge → 点击 <strong>Profiles</strong></li>
|
||||||
|
<li>粘贴订阅链接到输入框 → 点击 <strong>Import</strong></li>
|
||||||
|
<li>选中新配置 → 开启系统代理</li>
|
||||||
|
</ol>
|
||||||
|
<h4 style="color: #555; margin: 0 0 8px; font-size: 14px; font-weight: 600;">🤖 Android (ClashMi / Clash Meta)</h4>
|
||||||
|
<ol style="color: #666; line-height: 2; font-size: 13px; padding-left: 20px; margin: 0;">
|
||||||
|
<li>打开 ClashMi → <strong>Profile</strong> → <strong>New Profile</strong></li>
|
||||||
|
<li>选择 <strong>URL</strong> → 粘贴订阅链接</li>
|
||||||
|
<li>保存 → 选中配置 → 启动</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
${vpnIntro}
|
||||||
|
|
||||||
|
<h3 class="section-heading" style="color: #1a1a2e; font-size: 16px; margin: 0 0 12px; font-weight: 600;">📊 服务配额</h3>
|
||||||
|
<table class="data-table" role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="border-collapse: collapse; margin: 0 0 24px;">
|
||||||
|
<tr style="border-bottom: 1px solid #f0f2f5;">
|
||||||
|
<td style="padding: 12px 16px; color: #666; font-size: 14px; width: 40%;">月流量池</td>
|
||||||
|
<td style="padding: 12px 16px; font-weight: 600; color: #1a1a2e; font-size: 14px;">2000 GB (共享配额)</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="border-bottom: 1px solid #f0f2f5; background: #fafbfc;">
|
||||||
|
<td style="padding: 12px 16px; color: #666; font-size: 14px;">重置日期</td>
|
||||||
|
<td style="padding: 12px 16px; color: #1a1a2e; font-size: 14px;">每月1日</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="border-bottom: 1px solid #f0f2f5;">
|
||||||
|
<td style="padding: 12px 16px; color: #666; font-size: 14px;">传输协议</td>
|
||||||
|
<td style="padding: 12px 16px; color: #1a1a2e; font-size: 14px;">VLESS + Reality</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 12px 16px; color: #666; font-size: 14px;">节点位置</td>
|
||||||
|
<td style="padding: 12px 16px; color: #1a1a2e; font-size: 14px;">🇸🇬 新加坡 (多节点)</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- 带宽共享邀请 -->
|
||||||
|
<div style="background: linear-gradient(135deg, #e8f4fd 0%, #f0f7ff 100%); border: 1px solid #b8daff; border-radius: 12px; padding: 20px; margin: 0 0 16px;">
|
||||||
|
<h3 style="color: #004085; font-size: 15px; margin: 0 0 12px; font-weight: 700;">🌊 带宽共享加速计划 · 自愿参与</h3>
|
||||||
|
<p style="color: #444; font-size: 13px; margin: 0 0 16px; line-height: 1.9;">
|
||||||
|
光湖语言世界支持带宽共享加速机制。参与用户的闲置带宽将纳入全网加速池,
|
||||||
|
提升所有用户的连接速度与稳定性。此功能为<strong>自愿参与</strong>机制,
|
||||||
|
不参与不影响正常服务使用。
|
||||||
|
</p>
|
||||||
|
${bwAuthUrl ? `
|
||||||
|
<div style="text-align: center; margin: 0 0 16px;">
|
||||||
|
<a href="${bwAuthUrl}" class="action-btn" style="display: inline-block; background: linear-gradient(135deg, #667eea, #764ba2); color: white; padding: 14px 36px; border-radius: 10px; text-decoration: none; font-size: 15px; font-weight: 600; letter-spacing: 0.5px;">
|
||||||
|
🌊 前往参与带宽共享
|
||||||
|
</a>
|
||||||
|
</div>` : ''}
|
||||||
|
<p style="color: #888; font-size: 12px; margin: 0; line-height: 1.8;">
|
||||||
|
点击上方按钮进入授权页面,在页面中申请验证码完成授权。<br>
|
||||||
|
如暂不参与,无需任何操作。此邮件仅为系统通知,不参与不产生任何影响。
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-card" style="background: #f8f9fa; border-radius: 10px; padding: 16px 20px; margin: 0; border-left: 4px solid #667eea;">
|
||||||
|
<p style="color: #555; font-size: 13px; margin: 0; line-height: 1.8;">
|
||||||
|
🔒 <strong>安全机制说明</strong>:所有参与带宽共享的用户IP地址均采用 SHA256 + 盐值 加密存储。
|
||||||
|
系统检测到风险时将自动切断共享通道并清除所有记录。您的隐私安全由铸渊守护体系全程保障。
|
||||||
|
</p>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
return wrapEmailTemplate('V3 专属订阅 · 光湖语言世界', content, config);
|
||||||
|
}
|
||||||
|
|
||||||
// ── HTML转义 ─────────────────────────────────
|
// ── HTML转义 ─────────────────────────────────
|
||||||
function escapeHtml(str) {
|
function escapeHtml(str) {
|
||||||
return String(str)
|
return String(str)
|
||||||
|
|
@ -936,6 +1045,40 @@ async function sendThreatClearedEmail() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送V3订阅链接给单个用户 (含系统介绍 + 带宽共享邀请)
|
||||||
|
* 自动从users.json查找用户token,构建订阅/仪表盘/授权URL
|
||||||
|
* @param {string} email 目标邮箱
|
||||||
|
*/
|
||||||
|
async function sendSubscriptionV3Email(email) {
|
||||||
|
const config = loadConfig();
|
||||||
|
const users = getEnabledUsers();
|
||||||
|
const user = users.find(u => u.email === email);
|
||||||
|
|
||||||
|
if (!user || !user.token) {
|
||||||
|
console.error(`[邮件中枢] ❌ 用户不存在或token无效: ${email}`);
|
||||||
|
return { sent: 0, failed: 1 };
|
||||||
|
}
|
||||||
|
|
||||||
|
const host = config.server_host || 'guanghulab.com';
|
||||||
|
const subUrl = `https://${host}/api/proxy-v3/sub/${user.token}`;
|
||||||
|
const dashboardUrl = `https://${host}/api/proxy-v3/dashboard/${user.token}`;
|
||||||
|
const bwAuthUrl = `https://${BW_AUTH_HOST}/api/proxy-v3/bandwidth-auth/${user.token}`;
|
||||||
|
|
||||||
|
const html = generateSubscriptionV3Email(subUrl, dashboardUrl, bwAuthUrl, config);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await sendEmail(email, '🌐 光湖语言世界 · V3专属订阅链接', html);
|
||||||
|
console.log(`[邮件中枢] ✅ V3订阅已发送: ${email}`);
|
||||||
|
logEmail('subscription-v3', email, true, null);
|
||||||
|
return { sent: 1, failed: 0 };
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`[邮件中枢] ❌ V3订阅发送失败: ${err.message}`);
|
||||||
|
logEmail('subscription-v3', email, false, err.message);
|
||||||
|
return { sent: 0, failed: 1 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 一键发送带宽共享验证码给所有用户 (∞+1)
|
* 一键发送带宽共享验证码给所有用户 (∞+1)
|
||||||
* 自动提取所有启用用户邮箱,为每位用户生成独立验证码并加密发送
|
* 自动提取所有启用用户邮箱,为每位用户生成独立验证码并加密发送
|
||||||
|
|
@ -968,11 +1111,10 @@ async function sendBandwidthAuthAllEmail() {
|
||||||
// 为每位用户生成独立验证码
|
// 为每位用户生成独立验证码
|
||||||
const authCode = bwPool.createAuthCode(user.email);
|
const authCode = bwPool.createAuthCode(user.email);
|
||||||
|
|
||||||
// 构建用户专属授权页面URL
|
// 构建用户专属授权页面URL (使用guanghulab.online桥接域名)
|
||||||
let authPageUrl;
|
let authPageUrl;
|
||||||
if (user.token) {
|
if (user.token) {
|
||||||
const host = config.server_host || 'guanghulab.com';
|
authPageUrl = `https://${BW_AUTH_HOST}/api/proxy-v3/bandwidth-auth/${user.token}`;
|
||||||
authPageUrl = `https://${host}/api/proxy-v3/bandwidth-auth/${user.token}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const html = generateBandwidthAuthEmail(authCode, authPageUrl, config);
|
const html = generateBandwidthAuthEmail(authCode, authPageUrl, config);
|
||||||
|
|
@ -1013,6 +1155,7 @@ async function main() {
|
||||||
console.log(' node email-hub.js bandwidth-auth-all — 一键发送带宽验证码 (全部用户·∞+1)');
|
console.log(' node email-hub.js bandwidth-auth-all — 一键发送带宽验证码 (全部用户·∞+1)');
|
||||||
console.log(' node email-hub.js threat-alert <消息> — 全体用户风险提示 (∞+1)');
|
console.log(' node email-hub.js threat-alert <消息> — 全体用户风险提示 (∞+1)');
|
||||||
console.log(' node email-hub.js threat-cleared — 全体用户安全恢复通知 (∞+1)');
|
console.log(' node email-hub.js threat-cleared — 全体用户安全恢复通知 (∞+1)');
|
||||||
|
console.log(' node email-hub.js send-subscription-v3 <邮箱> — V3订阅链接 (含系统介绍+带宽共享邀请)');
|
||||||
console.log(' node email-hub.js list-emails — 列出所有用户邮箱');
|
console.log(' node email-hub.js list-emails — 列出所有用户邮箱');
|
||||||
console.log('');
|
console.log('');
|
||||||
console.log('💡 描述支持分号分隔多条内容,自动渲染为功能清单:');
|
console.log('💡 描述支持分号分隔多条内容,自动渲染为功能清单:');
|
||||||
|
|
@ -1108,14 +1251,12 @@ async function main() {
|
||||||
const bwPool = require('./bandwidth-pool-agent');
|
const bwPool = require('./bandwidth-pool-agent');
|
||||||
const authCode = bwPool.createAuthCode(arg1);
|
const authCode = bwPool.createAuthCode(arg1);
|
||||||
|
|
||||||
// 查找用户token以构建授权页面URL
|
// 查找用户token以构建授权页面URL (使用guanghulab.online桥接域名)
|
||||||
let bwAuthPageUrl;
|
let bwAuthPageUrl;
|
||||||
const bwConfig = loadConfig();
|
|
||||||
const bwUsers = getEnabledUsers();
|
const bwUsers = getEnabledUsers();
|
||||||
const bwUser = bwUsers.find(u => u.email === arg1);
|
const bwUser = bwUsers.find(u => u.email === arg1);
|
||||||
if (bwUser && bwUser.token) {
|
if (bwUser && bwUser.token) {
|
||||||
const bwHost = bwConfig.server_host || 'guanghulab.com';
|
bwAuthPageUrl = `https://${BW_AUTH_HOST}/api/proxy-v3/bandwidth-auth/${bwUser.token}`;
|
||||||
bwAuthPageUrl = `https://${bwHost}/api/proxy-v3/bandwidth-auth/${bwUser.token}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await sendBandwidthAuthEmail(arg1, authCode, bwAuthPageUrl);
|
const result = await sendBandwidthAuthEmail(arg1, authCode, bwAuthPageUrl);
|
||||||
|
|
@ -1146,6 +1287,17 @@ async function main() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'send-subscription-v3': {
|
||||||
|
if (!arg1) {
|
||||||
|
console.error('❌ 请提供邮箱');
|
||||||
|
console.error('用法: node email-hub.js send-subscription-v3 <邮箱>');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
const result = await sendSubscriptionV3Email(arg1);
|
||||||
|
console.log(`📧 V3订阅链接: ${result.sent}成功 / ${result.failed}失败`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
console.error(`❌ 未知操作: ${action}`);
|
console.error(`❌ 未知操作: ${action}`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
|
|
@ -1164,6 +1316,7 @@ module.exports = {
|
||||||
sendBandwidthAuthAllEmail,
|
sendBandwidthAuthAllEmail,
|
||||||
sendThreatAlertEmail,
|
sendThreatAlertEmail,
|
||||||
sendThreatClearedEmail,
|
sendThreatClearedEmail,
|
||||||
|
sendSubscriptionV3Email,
|
||||||
getEnabledUsers,
|
getEnabledUsers,
|
||||||
listUserEmails,
|
listUserEmails,
|
||||||
loadReleaseNotes,
|
loadReleaseNotes,
|
||||||
|
|
|
||||||
|
|
@ -1046,7 +1046,7 @@ mode: direct
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h3>🔑 输入验证码</h3>
|
<h3>🔑 输入验证码</h3>
|
||||||
<p style="font-size: 0.88em; color: #888; margin-bottom: 12px; line-height: 1.7;">请查看您的QQ邮箱,将收到的6位验证码输入以下框中</p>
|
<p style="font-size: 0.88em; color: #888; margin-bottom: 12px; line-height: 1.7;">请查看您的邮箱,将收到的6位验证码输入以下框中。如尚未收到验证码,请点击下方按钮申请。</p>
|
||||||
|
|
||||||
<form id="authForm" onsubmit="submitCode(event)">
|
<form id="authForm" onsubmit="submitCode(event)">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
|
|
@ -1055,22 +1055,30 @@ mode: direct
|
||||||
<button type="submit" class="submit-btn" id="submitBtn">🔓 提交授权</button>
|
<button type="submit" class="submit-btn" id="submitBtn">🔓 提交授权</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<div style="text-align: center; margin-top: 14px;">
|
||||||
|
<button onclick="requestCode()" id="requestCodeBtn" style="background: transparent; border: 1px solid #667eea; color: #667eea; padding: 10px 24px; border-radius: 8px; font-size: 0.9em; cursor: pointer; transition: all 0.3s;">
|
||||||
|
📧 申请发送验证码
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="codeResult" class="result"></div>
|
||||||
|
|
||||||
<div id="result" class="result"></div>
|
<div id="result" class="result"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="info-box green">
|
<div class="info-box green">
|
||||||
<strong>✅ 同意授权 = 输入验证码</strong>
|
<strong>✅ 授权确认 · 提交验证码</strong>
|
||||||
您的多余带宽将用于加速VPN网络。用的人越多,系统越快。您自己也会享受到加速效果。
|
您的闲置带宽将纳入光湖语言世界加速网络。参与带宽共享的用户越多,全网加速效能越高,您的连接速度将同步提升。
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="info-box gray">
|
<div class="info-box gray">
|
||||||
<strong>❌ 不同意 = 关闭此页面</strong>
|
<strong>❌ 暂不参与 · 关闭此页面</strong>
|
||||||
完全没问题。您可以继续正常使用VPN,只是走我们系统的带宽,速度可能慢一些,但也比普通VPN好太多了。无论您选择什么,都不影响正常使用。
|
本功能为自愿参与机制,不影响您的正常服务使用。未参与带宽共享的用户将通过系统默认带宽通道连接,服务质量不受影响。
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="info-box yellow">
|
<div class="info-box yellow">
|
||||||
<strong>🔒 安全保障</strong>
|
<strong>🔒 安全机制说明</strong>
|
||||||
本VPN是内部专用的,用户都是团队自己人,已经相对安全。您的IP仅用于带宽加速,系统内部加密存储。若检测到任何风险,系统会自动切断您的共享通道并格式化所有共享记录——就像这条路从未出现过。危机解除后会重新推送新的订阅链接。您的隐私安全,铸渊守护。
|
本系统为内部授权用户专用,所有参与者均为受邀成员。您的IP地址仅用于带宽加速调度,系统采用 SHA256 + 盐值 加密存储,外部无法访问。当系统检测到安全风险时,将自动切断所有共享通道并格式化全部共享记录,确保无痕清除。风险解除后,系统将自动重新分配订阅链接。您的隐私安全由铸渊守护体系全程保障。
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
|
|
@ -1080,6 +1088,45 @@ mode: direct
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
var RESEND_COOLDOWN_MS = 60000; // 验证码重发冷却时间(毫秒)
|
||||||
|
|
||||||
|
async function requestCode() {
|
||||||
|
const btn = document.getElementById('requestCodeBtn');
|
||||||
|
const codeResult = document.getElementById('codeResult');
|
||||||
|
|
||||||
|
btn.disabled = true;
|
||||||
|
btn.textContent = '⏳ 发送中...';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const sendCodeUrl = window.location.pathname.replace('/bandwidth-auth/', '/bandwidth-send-code/');
|
||||||
|
const resp = await fetch(sendCodeUrl, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({})
|
||||||
|
});
|
||||||
|
const data = await resp.json();
|
||||||
|
|
||||||
|
codeResult.style.display = 'block';
|
||||||
|
if (data.success) {
|
||||||
|
codeResult.className = 'result success';
|
||||||
|
codeResult.textContent = '✅ ' + data.message;
|
||||||
|
btn.textContent = '✅ 验证码已发送';
|
||||||
|
setTimeout(() => { btn.disabled = false; btn.textContent = '📧 重新发送验证码'; }, RESEND_COOLDOWN_MS);
|
||||||
|
} else {
|
||||||
|
codeResult.className = 'result error';
|
||||||
|
codeResult.textContent = '❌ ' + data.message;
|
||||||
|
btn.disabled = false;
|
||||||
|
btn.textContent = '📧 申请发送验证码';
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
codeResult.style.display = 'block';
|
||||||
|
codeResult.className = 'result error';
|
||||||
|
codeResult.textContent = '❌ 网络异常,请稍后重试';
|
||||||
|
btn.disabled = false;
|
||||||
|
btn.textContent = '📧 申请发送验证码';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function submitCode(e) {
|
async function submitCode(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const code = document.getElementById('codeInput').value.trim();
|
const code = document.getElementById('codeInput').value.trim();
|
||||||
|
|
@ -1150,8 +1197,9 @@ async function submitCode(e) {
|
||||||
const emailHub = require('./email-hub');
|
const emailHub = require('./email-hub');
|
||||||
const code = bwPool.createAuthCode(user.email);
|
const code = bwPool.createAuthCode(user.email);
|
||||||
|
|
||||||
const serverHost = getServerHost();
|
// 使用guanghulab.online桥接域名 (QQ邮箱反拦截)
|
||||||
const authPageUrl = `https://${serverHost}/api/proxy-v3/bandwidth-auth/${token}`;
|
const bwAuthHost = process.env.ZY_BW_AUTH_HOST || 'guanghulab.online';
|
||||||
|
const authPageUrl = `https://${bwAuthHost}/api/proxy-v3/bandwidth-auth/${token}`;
|
||||||
|
|
||||||
emailHub.sendBandwidthAuthEmail(user.email, code, authPageUrl).then(() => {
|
emailHub.sendBandwidthAuthEmail(user.email, code, authPageUrl).then(() => {
|
||||||
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
|
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue