mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-08 18:37:46 +08:00
feat(auth): 添加 Turnstile 注册防护
This commit is contained in:
@@ -15,6 +15,11 @@ export interface SystemConfig {
|
||||
rate_limit_per_minute: number
|
||||
enable_registration: boolean
|
||||
password_policy_level: string
|
||||
turnstile_enabled: boolean
|
||||
turnstile_site_key: string | null
|
||||
turnstile_secret_key: string
|
||||
turnstile_secret_key_is_set: boolean
|
||||
turnstile_allowed_hostnames: string[]
|
||||
// 独立余额 Key 过期管理
|
||||
auto_delete_expired_keys: boolean
|
||||
// 格式转换
|
||||
@@ -56,6 +61,10 @@ const CONFIG_KEYS = [
|
||||
'rate_limit_per_minute',
|
||||
'enable_registration',
|
||||
'password_policy_level',
|
||||
'turnstile_enabled',
|
||||
'turnstile_site_key',
|
||||
'turnstile_secret_key',
|
||||
'turnstile_allowed_hostnames',
|
||||
// 独立余额 Key 过期管理
|
||||
'auto_delete_expired_keys',
|
||||
// 格式转换
|
||||
@@ -98,6 +107,11 @@ function createDefaultConfig(): SystemConfig {
|
||||
rate_limit_per_minute: 0,
|
||||
enable_registration: false,
|
||||
password_policy_level: 'weak',
|
||||
turnstile_enabled: false,
|
||||
turnstile_site_key: null,
|
||||
turnstile_secret_key: '',
|
||||
turnstile_secret_key_is_set: false,
|
||||
turnstile_allowed_hostnames: [],
|
||||
// 独立余额 Key 过期管理
|
||||
auto_delete_expired_keys: false,
|
||||
// 格式转换
|
||||
@@ -165,6 +179,11 @@ export function useSystemConfig() {
|
||||
systemConfig.value.rate_limit_per_minute !== originalConfig.value.rate_limit_per_minute ||
|
||||
systemConfig.value.enable_registration !== originalConfig.value.enable_registration ||
|
||||
systemConfig.value.password_policy_level !== originalConfig.value.password_policy_level ||
|
||||
systemConfig.value.turnstile_enabled !== originalConfig.value.turnstile_enabled ||
|
||||
systemConfig.value.turnstile_site_key !== originalConfig.value.turnstile_site_key ||
|
||||
systemConfig.value.turnstile_secret_key.trim() !== '' ||
|
||||
JSON.stringify(systemConfig.value.turnstile_allowed_hostnames) !==
|
||||
JSON.stringify(originalConfig.value.turnstile_allowed_hostnames) ||
|
||||
systemConfig.value.auto_delete_expired_keys !== originalConfig.value.auto_delete_expired_keys ||
|
||||
systemConfig.value.enable_format_conversion !== originalConfig.value.enable_format_conversion ||
|
||||
systemConfig.value.enable_openai_image_sync_heartbeat !== originalConfig.value.enable_openai_image_sync_heartbeat
|
||||
@@ -233,12 +252,27 @@ export function useSystemConfig() {
|
||||
},
|
||||
})
|
||||
|
||||
const turnstileAllowedHostnamesStr = computed({
|
||||
get: () => systemConfig.value.turnstile_allowed_hostnames.join(', '),
|
||||
set: (val: string) => {
|
||||
systemConfig.value.turnstile_allowed_hostnames = val
|
||||
.split(',')
|
||||
.map((s) => s.trim().toLowerCase())
|
||||
.filter((s) => s.length > 0)
|
||||
},
|
||||
})
|
||||
|
||||
// 加载配置
|
||||
async function loadSystemConfig() {
|
||||
try {
|
||||
for (const key of CONFIG_KEYS) {
|
||||
try {
|
||||
const response = await adminApi.getSystemConfig(key)
|
||||
if (key === 'turnstile_secret_key') {
|
||||
systemConfig.value.turnstile_secret_key = ''
|
||||
systemConfig.value.turnstile_secret_key_is_set = !!response.is_set
|
||||
continue
|
||||
}
|
||||
if (response.value !== null && response.value !== undefined) {
|
||||
; (systemConfig.value as Record<string, unknown>)[key] = response.value
|
||||
}
|
||||
@@ -337,6 +371,21 @@ export function useSystemConfig() {
|
||||
value: systemConfig.value.password_policy_level,
|
||||
description: '密码策略等级',
|
||||
},
|
||||
{
|
||||
key: 'turnstile_enabled',
|
||||
value: systemConfig.value.turnstile_enabled,
|
||||
description: 'Cloudflare Turnstile 注册人机验证开关',
|
||||
},
|
||||
{
|
||||
key: 'turnstile_site_key',
|
||||
value: systemConfig.value.turnstile_site_key?.trim() || null,
|
||||
description: 'Cloudflare Turnstile 站点 Key',
|
||||
},
|
||||
{
|
||||
key: 'turnstile_allowed_hostnames',
|
||||
value: systemConfig.value.turnstile_allowed_hostnames,
|
||||
description: 'Cloudflare Turnstile 允许的 hostname 列表',
|
||||
},
|
||||
{
|
||||
key: 'auto_delete_expired_keys',
|
||||
value: systemConfig.value.auto_delete_expired_keys,
|
||||
@@ -353,6 +402,14 @@ export function useSystemConfig() {
|
||||
description: '同步生图心跳开关:开启后外层 HTTP 状态固定为 200,上游失败写入响应体',
|
||||
},
|
||||
]
|
||||
const turnstileSecret = systemConfig.value.turnstile_secret_key.trim()
|
||||
if (turnstileSecret) {
|
||||
configItems.push({
|
||||
key: 'turnstile_secret_key',
|
||||
value: turnstileSecret,
|
||||
description: 'Cloudflare Turnstile Secret Key',
|
||||
})
|
||||
}
|
||||
|
||||
await Promise.all(
|
||||
configItems.map((item) =>
|
||||
@@ -364,6 +421,17 @@ export function useSystemConfig() {
|
||||
originalConfig.value.rate_limit_per_minute = systemConfig.value.rate_limit_per_minute
|
||||
originalConfig.value.enable_registration = systemConfig.value.enable_registration
|
||||
originalConfig.value.password_policy_level = systemConfig.value.password_policy_level
|
||||
originalConfig.value.turnstile_enabled = systemConfig.value.turnstile_enabled
|
||||
originalConfig.value.turnstile_site_key = systemConfig.value.turnstile_site_key?.trim() || null
|
||||
originalConfig.value.turnstile_allowed_hostnames = [
|
||||
...systemConfig.value.turnstile_allowed_hostnames,
|
||||
]
|
||||
if (turnstileSecret) {
|
||||
systemConfig.value.turnstile_secret_key = ''
|
||||
systemConfig.value.turnstile_secret_key_is_set = true
|
||||
originalConfig.value.turnstile_secret_key = ''
|
||||
originalConfig.value.turnstile_secret_key_is_set = true
|
||||
}
|
||||
originalConfig.value.auto_delete_expired_keys =
|
||||
systemConfig.value.auto_delete_expired_keys
|
||||
originalConfig.value.enable_format_conversion =
|
||||
@@ -380,6 +448,29 @@ export function useSystemConfig() {
|
||||
}
|
||||
}
|
||||
|
||||
async function clearTurnstileSecret() {
|
||||
basicConfigLoading.value = true
|
||||
try {
|
||||
await adminApi.updateSystemConfig(
|
||||
'turnstile_secret_key',
|
||||
'',
|
||||
'Cloudflare Turnstile Secret Key'
|
||||
)
|
||||
systemConfig.value.turnstile_secret_key = ''
|
||||
systemConfig.value.turnstile_secret_key_is_set = false
|
||||
if (originalConfig.value) {
|
||||
originalConfig.value.turnstile_secret_key = ''
|
||||
originalConfig.value.turnstile_secret_key_is_set = false
|
||||
}
|
||||
success('Turnstile 密钥已清空')
|
||||
} catch (err) {
|
||||
error('清空 Turnstile 密钥失败')
|
||||
log.error('清空 Turnstile 密钥失败:', err)
|
||||
} finally {
|
||||
basicConfigLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function saveLogConfig() {
|
||||
logConfigLoading.value = true
|
||||
try {
|
||||
@@ -559,6 +650,7 @@ export function useSystemConfig() {
|
||||
maxRequestBodySizeKB,
|
||||
maxResponseBodySizeKB,
|
||||
sensitiveHeadersStr,
|
||||
turnstileAllowedHostnamesStr,
|
||||
// 加载函数
|
||||
loadSystemConfig,
|
||||
loadSystemVersion,
|
||||
@@ -566,6 +658,7 @@ export function useSystemConfig() {
|
||||
saveSiteInfo,
|
||||
saveProxyConfig,
|
||||
saveBasicConfig,
|
||||
clearTurnstileSecret,
|
||||
saveLogConfig,
|
||||
saveCleanupConfig,
|
||||
handleAutoCleanupToggle,
|
||||
|
||||
Reference in New Issue
Block a user