Files
CubeAdmin/app/api/players/route.ts
2026-03-08 15:49:34 +01:00

43 lines
1.6 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { db } from "@/lib/db";
import { mcPlayers } from "@/lib/db/schema";
import { checkRateLimit, getClientIp } from "@/lib/security/rateLimit";
import { desc, like, or, eq } from "drizzle-orm";
export async function GET(req: NextRequest) {
const session = await auth.api.getSession({ headers: req.headers });
if (!session) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
const ip = getClientIp(req);
const { allowed } = checkRateLimit(ip);
if (!allowed) return NextResponse.json({ error: "Too many requests" }, { status: 429 });
const { searchParams } = new URL(req.url);
const search = searchParams.get("q")?.trim() ?? "";
const onlineOnly = searchParams.get("online") === "true";
const bannedOnly = searchParams.get("banned") === "true";
const page = Math.max(1, parseInt(searchParams.get("page") ?? "1"));
const limit = Math.min(100, Math.max(1, parseInt(searchParams.get("limit") ?? "50")));
const offset = (page - 1) * limit;
let query = db.select().from(mcPlayers);
const conditions = [];
if (search) {
conditions.push(like(mcPlayers.username, `%${search}%`));
}
if (onlineOnly) conditions.push(eq(mcPlayers.isOnline, true));
if (bannedOnly) conditions.push(eq(mcPlayers.isBanned, true));
const rows = await db
.select()
.from(mcPlayers)
.where(conditions.length ? (conditions.length === 1 ? conditions[0] : or(...conditions)) : undefined)
.orderBy(desc(mcPlayers.lastSeen))
.limit(limit)
.offset(offset);
return NextResponse.json({ players: rows, page, limit });
}