import { NextRequest, NextResponse } from "next/server"; import { Pool } from "pg"; import { requireAdmin, requireSuperAdmin, getSession } from "@/lib/auth-utils"; const pool = new Pool({ connectionString: process.env.DATABASE_URL, }); // GET /api/admin/users/[id] - Get a single user export async function GET( request: NextRequest, { params }: { params: Promise<{ id: string }> } ) { const { error } = await requireAdmin(); if (error) return error; try { const { id } = await params; const result = await pool.query( `SELECT id, name, email, email_verified, image, role, banned, banned_reason, ban_expires, requires_setup, created_at, updated_at FROM "user" WHERE id = $1`, [id] ); if (result.rows.length === 0) { return NextResponse.json({ error: "User not found" }, { status: 404 }); } // Get user's sessions const sessions = await pool.query( `SELECT id, ip_address, user_agent, created_at, expires_at FROM "session" WHERE user_id = $1 ORDER BY created_at DESC`, [id] ); return NextResponse.json({ user: result.rows[0], sessions: sessions.rows, }); } catch (error) { console.error("Error fetching user:", error); return NextResponse.json( { error: "Failed to fetch user" }, { status: 500 } ); } } // PATCH /api/admin/users/[id] - Update a user export async function PATCH( request: NextRequest, { params }: { params: Promise<{ id: string }> } ) { const { session, error } = await requireSuperAdmin(); if (error) return error; try { const { id } = await params; const body = await request.json(); const { name, email, role, banned, banned_reason } = body; // Check if user exists const existingUser = await pool.query( 'SELECT id, role FROM "user" WHERE id = $1', [id] ); if (existingUser.rows.length === 0) { return NextResponse.json({ error: "User not found" }, { status: 404 }); } // Prevent modifying own role if (session?.user.id === id && role && role !== existingUser.rows[0].role) { return NextResponse.json( { error: "Cannot modify your own role" }, { status: 400 } ); } // Build update query dynamically const updates: string[] = []; const values: (string | boolean | null)[] = []; let paramIndex = 1; if (name !== undefined) { updates.push(`name = $${paramIndex++}`); values.push(name); } if (email !== undefined) { updates.push(`email = $${paramIndex++}`); values.push(email); } if (role !== undefined) { updates.push(`role = $${paramIndex++}`); values.push(role); } if (banned !== undefined) { updates.push(`banned = $${paramIndex++}`); values.push(banned); if (banned && banned_reason) { updates.push(`banned_reason = $${paramIndex++}`); values.push(banned_reason); } else if (!banned) { updates.push(`banned_reason = NULL`); updates.push(`ban_expires = NULL`); } } if (updates.length === 0) { return NextResponse.json( { error: "No fields to update" }, { status: 400 } ); } updates.push(`updated_at = NOW()`); values.push(id); const result = await pool.query( `UPDATE "user" SET ${updates.join(", ")} WHERE id = $${paramIndex} RETURNING id, name, email, role, banned, banned_reason, updated_at`, values ); return NextResponse.json({ user: result.rows[0] }); } catch (error) { console.error("Error updating user:", error); return NextResponse.json( { error: "Failed to update user" }, { status: 500 } ); } } // DELETE /api/admin/users/[id] - Delete a user export async function DELETE( request: NextRequest, { params }: { params: Promise<{ id: string }> } ) { const { session, error } = await requireSuperAdmin(); if (error) return error; try { const { id } = await params; // Prevent self-deletion if (session?.user.id === id) { return NextResponse.json( { error: "Cannot delete your own account" }, { status: 400 } ); } // Check if user exists const existingUser = await pool.query( 'SELECT id FROM "user" WHERE id = $1', [id] ); if (existingUser.rows.length === 0) { return NextResponse.json({ error: "User not found" }, { status: 404 }); } // Delete user (cascades to sessions and accounts) await pool.query('DELETE FROM "user" WHERE id = $1', [id]); return NextResponse.json({ success: true }); } catch (error) { console.error("Error deleting user:", error); return NextResponse.json( { error: "Failed to delete user" }, { status: 500 } ); } }