From eb31132fa089e239e20b140b5c83d8347fe7a388 Mon Sep 17 00:00:00 2001 From: aiyimickey <39365912+aiyimickey@users.noreply.github.com> Date: Wed, 8 Jul 2026 10:35:59 +0800 Subject: [PATCH] feat: /api/internal/users endpoint for OA user sync --- src/app/api/internal/users/route.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/app/api/internal/users/route.ts diff --git a/src/app/api/internal/users/route.ts b/src/app/api/internal/users/route.ts new file mode 100644 index 0000000..6bba9cb --- /dev/null +++ b/src/app/api/internal/users/route.ts @@ -0,0 +1,22 @@ +// GET /api/internal/users — 供 OA 查询 monitor 用户列表 +import { NextResponse } from 'next/server' +import { execFileSync } from 'child_process' + +const INTERNAL_KEY = process.env.INTERNAL_API_KEY || 'oa-internal-key-tlyq-2026' +const DB_PATH = process.env.DATABASE_PATH || '/app/data/monitor.db' + +export async function GET(request: Request) { + const key = request.headers.get('x-internal-key') + if (key !== INTERNAL_KEY) return NextResponse.json({ error: 'Forbidden' }, { status: 403 }) + + try { + const out = execFileSync('sqlite3', [DB_PATH, 'SELECT username, display_name, role FROM users WHERE is_active = 1 ORDER BY username'], { timeout: 3000, encoding: 'utf8' }).trim() + const users = out.split('\n').filter(Boolean).map(line => { + const [username, display_name, role] = line.split('|') + return { username, display_name: display_name || username, role } + }) + return NextResponse.json({ users }) + } catch { + return NextResponse.json({ users: [] }) + } +}