oa-ai/src/app/api/admin/sync-emails/route.ts

49 lines
1.7 KiB
TypeScript

import { NextResponse } from 'next/server'
import { cookies } from 'next/headers'
import { exec } from 'child_process'
import { promisify } from 'util'
import { verifySharedJwt } from '@/lib/jwt'
import { isLldapAdmin } from '@/lib/ldap'
const execAsync = promisify(exec)
const ASSETS_DB = process.env.ASSETS_DB_PATH || '/Users/niuniu/programs/docker/assets-ai/data/assets.db'
const ISSUE_DB = process.env.ISSUE_DB_PATH || '/Users/niuniu/programs/docker/issue-ai/data/issue.db'
export async function POST() {
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 || !(await isLldapAdmin(session.username))) {
return NextResponse.json({ error: '仅管理员可操作' }, { status: 403 })
}
const { stdout } = await execAsync(
`docker exec lldap sqlite3 /data/users.db "SELECT user_id, email FROM users WHERE email != '';"`,
{ timeout: 5000 }
)
const lines = stdout.trim().split('\n').filter(Boolean)
let synced = 0
for (const line of lines) {
const [user, mail] = line.split('|')
const su = user.replace(/'/g, "''")
const sm = (mail || '').replace(/'/g, "''")
for (const db of [ASSETS_DB, ISSUE_DB]) {
try {
await execAsync(
`sqlite3 "${db}" "UPDATE users SET email = '${sm}', updated_at = datetime('now', '+8 hours') WHERE username = '${su}';"`,
{ timeout: 3000 }
)
} catch {}
}
synced++
}
return NextResponse.json({ success: true, synced })
} catch (e) {
return NextResponse.json({ error: '同步失败' }, { status: 500 })
}
}