| import { Router } from "express"; |
| import { db, geminiAccountsTable } from "@workspace/db"; |
| import { eq, desc } from "drizzle-orm"; |
| import { requireAdmin } from "./admin"; |
| import { requireJwtAuth } from "./auth"; |
|
|
| const router = Router(); |
|
|
| router.use(requireJwtAuth); |
|
|
| router.get("/", requireAdmin, async (_req, res) => { |
| const rows = await db |
| .select() |
| .from(geminiAccountsTable) |
| .orderBy(desc(geminiAccountsTable.createdAt)); |
|
|
| res.json( |
| rows.map((r) => ({ |
| id: r.id, |
| label: r.label, |
| tokenPreview: r.bearerToken ? r.bearerToken.substring(0, 12) + "..." : null, |
| hasRefreshToken: !!r.refreshToken, |
| isActive: r.isActive, |
| lastUsedAt: r.lastUsedAt?.toISOString() ?? null, |
| createdAt: r.createdAt.toISOString(), |
| })) |
| ); |
| }); |
|
|
| router.post("/", requireAdmin, async (req, res) => { |
| const { label, bearerToken, refreshToken } = req.body as { |
| label?: string; |
| bearerToken?: string; |
| refreshToken?: string; |
| }; |
|
|
| if (!bearerToken?.trim()) { |
| return res.status(400).json({ error: "bearerToken is required" }); |
| } |
|
|
| const [inserted] = await db |
| .insert(geminiAccountsTable) |
| .values({ |
| label: (label || "帳戶").trim(), |
| bearerToken: bearerToken.trim(), |
| refreshToken: refreshToken?.trim() || null, |
| isActive: true, |
| }) |
| .returning(); |
|
|
| res.json({ |
| id: inserted.id, |
| label: inserted.label, |
| tokenPreview: inserted.bearerToken.substring(0, 12) + "...", |
| isActive: inserted.isActive, |
| createdAt: inserted.createdAt.toISOString(), |
| }); |
| }); |
|
|
| router.patch("/:id/label", requireAdmin, async (req, res) => { |
| const id = Number(req.params.id); |
| const { label } = req.body as { label?: string }; |
| if (!label?.trim()) return res.status(400).json({ error: "label is required" }); |
|
|
| await db.update(geminiAccountsTable).set({ label: label.trim() }).where(eq(geminiAccountsTable.id, id)); |
| res.json({ success: true }); |
| }); |
|
|
| router.patch("/:id/toggle", requireAdmin, async (req, res) => { |
| const id = Number(req.params.id); |
| const rows = await db.select().from(geminiAccountsTable).where(eq(geminiAccountsTable.id, id)).limit(1); |
| if (!rows.length) return res.status(404).json({ error: "Account not found" }); |
|
|
| const newActive = !rows[0].isActive; |
| await db.update(geminiAccountsTable).set({ isActive: newActive }).where(eq(geminiAccountsTable.id, id)); |
| res.json({ success: true, isActive: newActive }); |
| }); |
|
|
| router.delete("/:id", requireAdmin, async (req, res) => { |
| const id = Number(req.params.id); |
| await db.delete(geminiAccountsTable).where(eq(geminiAccountsTable.id, id)); |
| res.json({ success: true }); |
| }); |
|
|
| export default router; |
|
|