import { NextResponse } from 'next/server' import { cookies } from 'next/headers' import { exec } from 'child_process' import { promisify } from 'util' import { verifySharedJwt } from '@/lib/jwt' const execAsync = promisify(exec) export async function POST(request: Request) { try { const cookieStore = await cookies() const token = cookieStore.get('tlyq_session')?.value if (!token) return NextResponse.json({ error: '未登录' }, { status: 401 }) const session = verifySharedJwt(token) if (!session) return NextResponse.json({ error: '会话已过期' }, { status: 401 }) const { currentPassword, newPassword } = await request.json() if (!currentPassword || !newPassword) { return NextResponse.json({ error: '请输入当前密码和新密码' }, { status: 400 }) } if (newPassword.length < 8) { return NextResponse.json({ error: '新密码至少 8 位' }, { status: 400 }) } // 密码复杂度:大写/小写/数字/特殊字符 4选3 const hasUpper = /[A-Z]/.test(newPassword) const hasLower = /[a-z]/.test(newPassword) const hasDigit = /[0-9]/.test(newPassword) const hasSpecial = /[^A-Za-z0-9]/.test(newPassword) const complexityScore = [hasUpper, hasLower, hasDigit, hasSpecial].filter(Boolean).length if (complexityScore < 3) { return NextResponse.json({ error: '密码需包含大写字母、小写字母、数字、特殊字符中至少 3 种' }, { status: 400 }) } // 从 LLDAP 容器动态获取 admin 密码(不硬编码,admin 改密码后无需改 OA 配置) const { stdout: adminPassOut } = await execAsync('docker exec lldap printenv LLDAP_ADMIN_PASSWORD', { timeout: 3000 }) const adminPass = (adminPassOut.trim() || 'admin123').replace(/'/g, "'\\''") const safeUser = session.username.replace(/'/g, "'\\''") const safePass = newPassword.replace(/'/g, "'\\''") const cmd = `docker exec lldap ./lldap_set_password --base-url http://localhost:17170 --admin-username admin --admin-password '${adminPass}' --username '${safeUser}' --password '${safePass}'` const { stdout, stderr } = await execAsync(cmd, { timeout: 10000 }) if (stderr && !stderr.includes('Successfully')) { return NextResponse.json({ error: stderr.trim() || '修改失败' }, { status: 500 }) } return NextResponse.json({ success: true }) } catch (err) { const msg = err instanceof Error ? err.message : '修改失败' if (msg.includes('command not found') || msg.includes('No such container')) { return NextResponse.json({ error: '密码服务不可用' }, { status: 503 }) } return NextResponse.json({ error: msg }, { status: 500 }) } }