// src/app/api/monitor/settings/route.ts import { NextRequest, NextResponse } from 'next/server' import { initDatabase } from '@/lib/db-schema' import { getCurrentUser } from '@/lib/auth' import { hasPermission } from '@/lib/permissions' import { getMaskedConfig, updateMonitorConfig } from '@/lib/monitor/settings-manager' import { writeAuditLog, getClientIP } from '@/lib/audit' const VALIDATORS: Record boolean> = { 'monitor.enabled': (v) => typeof v === 'boolean', 'monitor.interval_seconds': (v) => typeof v === 'number' && v >= 10 && v <= 3600, 'monitor.push_delay_ms': (v) => typeof v === 'number' && v >= 0 && v <= 10000, 'monitor.silent_start_hour': (v) => typeof v === 'number' && v >= 0 && v <= 23, 'monitor.silent_end_hour': (v) => typeof v === 'number' && v >= 0 && v <= 23, 'mail.address': (v) => typeof v === 'string' && v.includes('@'), 'mail.imap_port': (v) => typeof v === 'number' && v > 0 && v <= 65535, 'mail.smtp_port': (v) => typeof v === 'number' && v > 0 && v <= 65535, 'wechat.webhook_url': (v) => typeof v === 'string' && (v === '' || v.startsWith('https://qyapi.weixin.qq.com/')), } export async function GET(request: NextRequest) { initDatabase() const user = await getCurrentUser() if (!user || !hasPermission(user, 'monitor:read')) return NextResponse.json({ error: '权限不足' }, { status: 403 }) return NextResponse.json(getMaskedConfig()) } export async function PUT(request: NextRequest) { initDatabase() const user = await getCurrentUser() if (!user || !hasPermission(user, 'monitor:write')) return NextResponse.json({ error: '权限不足' }, { status: 403 }) const body = await request.json() // 保留未修改的密码 if (body.mail?.password === '••••••••' || body.mail?.password === undefined) { delete body.mail?.password } // 先展平嵌套对象 const flat: Record = {} for (const [section, values] of Object.entries(body)) { if (typeof values === 'object' && values !== null) { for (const [key, value] of Object.entries(values as Record)) { flat[`${section}.${key}`] = value } } else { flat[section] = values } } // 展平后验证 for (const [key, value] of Object.entries(flat)) { const validator = VALIDATORS[key] if (validator && !validator(value)) return NextResponse.json({ error: `参数 ${key} 验证失败` }, { status: 400 }) } updateMonitorConfig(flat) writeAuditLog({ userId: user.id, action: 'update', entityType: 'monitor_config', details: { keys: Object.keys(flat) }, ipAddress: getClientIP(request) }) return NextResponse.json({ success: true }) }