feat(email): add email configuration and verification settings

This commit is contained in:
cnlimiter
2026-03-28 00:23:45 +08:00
parent 4ed740e1be
commit 25cf4f6588
3 changed files with 67 additions and 50 deletions

View File

@@ -386,6 +386,7 @@ class EmailCodeSettings(BaseModel):
"""验证码等待设置"""
timeout: int = 120 # 验证码等待超时(秒)
poll_interval: int = 3 # 验证码轮询间隔(秒)
resend_max_retries: int = 2 # 收件箱未找到验证码时最多重新发送次数
@router.get("/tempmail")
@@ -423,6 +424,7 @@ async def get_email_code_settings():
return {
"timeout": settings.email_code_timeout,
"poll_interval": settings.email_code_poll_interval,
"resend_max_retries": settings.email_code_resend_max_retries,
}
@@ -435,9 +437,13 @@ async def update_email_code_settings(request: EmailCodeSettings):
if request.poll_interval < 1 or request.poll_interval > 30:
raise HTTPException(status_code=400, detail="轮询间隔必须在 1-30 秒之间")
if request.resend_max_retries < 0 or request.resend_max_retries > 10:
raise HTTPException(status_code=400, detail="重发次数必须在 0-10 之间")
update_settings(
email_code_timeout=request.timeout,
email_code_poll_interval=request.poll_interval,
email_code_resend_max_retries=request.resend_max_retries,
)
return {"success": True, "message": "验证码等待设置已更新"}

View File

@@ -399,6 +399,7 @@ async function loadSettings() {
if (data.email_code) {
document.getElementById('email-code-timeout').value = data.email_code.timeout || 120;
document.getElementById('email-code-poll-interval').value = data.email_code.poll_interval || 3;
document.getElementById('email-code-resend-max-retries').value = data.email_code.resend_max_retries ?? 2;
}
// 加载 Outlook 设置
@@ -563,9 +564,17 @@ async function handleSaveEmailCode(e) {
return;
}
const resendMaxRetries = parseInt(document.getElementById('email-code-resend-max-retries').value);
if (resendMaxRetries < 0 || resendMaxRetries > 10) {
toast.error('重发次数必须在 0-10 之间');
return;
}
const data = {
timeout: timeout,
poll_interval: pollInterval
poll_interval: pollInterval,
resend_max_retries: resendMaxRetries
};
try {

View File

@@ -39,9 +39,8 @@
<button class="tab-btn active" data-tab="proxy">🌐 代理设置</button>
<button class="tab-btn" data-tab="webui">🔒 访问控制</button>
<button class="tab-btn" data-tab="upload">☁️ 上传</button>
<button class="tab-btn" data-tab="outlook">📮 Outlook配置</button>
<button class="tab-btn" data-tab="email">📧 邮箱配置</button>
<button class="tab-btn" data-tab="registration">⚙️ 注册配置</button>
<button class="tab-btn" data-tab="email-code">📧 验证码配置</button>
<button class="tab-btn" data-tab="database">💾 数据库</button>
</div>
@@ -535,7 +534,8 @@ MyProxy|socks5://user:pass@host:port"></textarea>
</div>
<!-- Outlook 配置 -->
<div class="tab-content" id="outlook-tab">
<!-- 邮箱配置Outlook OAuth + 验证码) -->
<div class="tab-content" id="email-tab">
<div class="card">
<div class="card-header">
<h3>Outlook OAuth 配置</h3>
@@ -549,6 +549,39 @@ MyProxy|socks5://user:pass@host:port"></textarea>
placeholder="24d9a0ed-8787-4584-883c-2fd79308940a">
<p class="hint">Outlook OAuth 应用的 Client ID。导入账户时未填写 client_id 则使用此默认值。</p>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">💾 保存设置</button>
</div>
</form>
</div>
</div>
<div class="card" style="margin-top: var(--spacing-lg);">
<div class="card-header">
<h3>验证码等待配置</h3>
<span class="hint">配置 Outlook 邮箱验证码获取的超时时间和轮询间隔</span>
</div>
<div class="card-body">
<form id="email-code-form">
<div class="form-row">
<div class="form-group">
<label for="email-code-timeout">等待超时 (秒)</label>
<input type="number" id="email-code-timeout" name="timeout" value="120" min="30" max="600">
<span class="hint">等待验证码的最大时间,建议 60-300 秒</span>
</div>
<div class="form-group">
<label for="email-code-poll-interval">轮询间隔 (秒)</label>
<input type="number" id="email-code-poll-interval" name="poll_interval" value="3" min="1" max="30">
<span class="hint">检查邮箱的时间间隔,建议 2-5 秒</span>
</div>
<div class="form-group">
<label for="email-code-resend-max-retries">最多重发次数</label>
<input type="number" id="email-code-resend-max-retries" name="resend_max_retries" value="2" min="0" max="10">
<span class="hint">收件箱未找到验证码时,最多重新触发发送的次数</span>
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">💾 保存设置</button>
@@ -556,6 +589,21 @@ MyProxy|socks5://user:pass@host:port"></textarea>
</form>
</div>
</div>
<div class="card" style="margin-top: var(--spacing-lg);">
<div class="card-header">
<h3>验证码获取策略</h3>
</div>
<div class="card-body">
<ul class="info-list">
<li><strong>渐进式检查</strong>:前 3 次轮询只检查未读邮件,之后检查所有邮件</li>
<li><strong>时间戳过滤</strong>:自动跳过 OTP 发送前的旧邮件</li>
<li><strong>验证码去重</strong>:避免重复使用同一验证码</li>
<li><strong>多策略提取</strong>:主题优先 → 语义匹配 → 兜底匹配</li>
<li><strong>发件人验证</strong>:严格验证邮件来自 OpenAI 官方</li>
</ul>
</div>
</div>
</div>
<!-- 注册配置 -->
@@ -603,52 +651,6 @@ MyProxy|socks5://user:pass@host:port"></textarea>
</div>
</div>
<!-- 验证码配置 -->
<div class="tab-content" id="email-code-tab">
<div class="card">
<div class="card-header">
<h3>验证码等待配置</h3>
<span class="hint">配置 Outlook 邮箱验证码获取的超时时间和轮询间隔</span>
</div>
<div class="card-body">
<form id="email-code-form">
<div class="form-row">
<div class="form-group">
<label for="email-code-timeout">等待超时 (秒)</label>
<input type="number" id="email-code-timeout" name="timeout" value="120" min="30" max="600">
<span class="hint">等待验证码的最大时间,建议 60-300 秒</span>
</div>
<div class="form-group">
<label for="email-code-poll-interval">轮询间隔 (秒)</label>
<input type="number" id="email-code-poll-interval" name="poll_interval" value="3" min="1" max="30">
<span class="hint">检查邮箱的时间间隔,建议 2-5 秒</span>
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">💾 保存设置</button>
</div>
</form>
</div>
</div>
<div class="card" style="margin-top: var(--spacing-lg);">
<div class="card-header">
<h3>验证码获取策略</h3>
</div>
<div class="card-body">
<ul class="info-list">
<li><strong>渐进式检查</strong>:前 3 次轮询只检查未读邮件,之后检查所有邮件</li>
<li><strong>时间戳过滤</strong>:自动跳过 OTP 发送前的旧邮件</li>
<li><strong>验证码去重</strong>:避免重复使用同一验证码</li>
<li><strong>多策略提取</strong>:主题优先 → 语义匹配 → 兜底匹配</li>
<li><strong>发件人验证</strong>:严格验证邮件来自 OpenAI 官方</li>
</ul>
</div>
</div>
</div>
<!-- 数据库 -->
<div class="tab-content" id="database-tab">
<div class="card">