76 lines
3.3 KiB
TypeScript
76 lines
3.3 KiB
TypeScript
import { rconServers } from "@minecraft-account-manager/database";
|
|
import { asc } from "drizzle-orm";
|
|
import { RconConsole, type RconTerminalNotice } from "@/components/rcon-console";
|
|
import { db } from "@/lib/database";
|
|
|
|
export const dynamic = "force-dynamic";
|
|
|
|
const savedMessages: Record<string, string> = {
|
|
created: "RCON connection created.",
|
|
updated: "RCON connection updated.",
|
|
enabled: "RCON connection enabled.",
|
|
disabled: "RCON connection disabled.",
|
|
deleted: "RCON connection deleted.",
|
|
tested: "RCON authentication succeeded.",
|
|
};
|
|
|
|
const errorMessages: Record<string, string> = {
|
|
"invalid-connection": "Enter a valid DNS hostname, port, name, and password.",
|
|
"duplicate-name": "Connection names must be unique.",
|
|
configuration: "RCON credential encryption is not configured.",
|
|
"save-failed": "The RCON connection could not be saved.",
|
|
"unknown-connection": "That RCON connection no longer exists.",
|
|
"confirmation-required": "Confirm the connection before deleting it.",
|
|
"connection-unavailable": "The connection is invalid or its credential is unavailable.",
|
|
"test-busy": "Another RCON operation is already using that server.",
|
|
"test-timeout": "RCON authentication timed out.",
|
|
"test-unavailable": "The RCON server was unavailable or rejected authentication.",
|
|
};
|
|
|
|
function queryValue(value: string | string[] | undefined) {
|
|
return Array.isArray(value) ? value[0] : value;
|
|
}
|
|
|
|
export default async function RconPage({
|
|
searchParams,
|
|
}: {
|
|
searchParams: Promise<Record<string, string | string[] | undefined>>;
|
|
}) {
|
|
const query = await searchParams;
|
|
const saved = queryValue(query.saved);
|
|
const error = queryValue(query.error);
|
|
const notice: RconTerminalNotice | undefined = error
|
|
? { status: "error", message: errorMessages[error] ?? "The RCON operation failed." }
|
|
: saved
|
|
? { status: "success", message: savedMessages[saved] ?? "RCON settings saved." }
|
|
: undefined;
|
|
const servers = await db.select({
|
|
id: rconServers.id,
|
|
name: rconServers.name,
|
|
host: rconServers.host,
|
|
port: rconServers.port,
|
|
enabled: rconServers.enabled,
|
|
}).from(rconServers).orderBy(asc(rconServers.name));
|
|
|
|
return (
|
|
<main className="mx-auto max-w-6xl px-6 py-14">
|
|
<header className="border-b border-line pb-8">
|
|
<p className="font-mono text-xs font-bold uppercase tracking-[0.25em] text-accent">Server operations</p>
|
|
<h1 className="mt-4 font-display text-5xl font-black uppercase sm:text-7xl">RCON</h1>
|
|
<p className="mt-5 max-w-2xl text-sm leading-6 text-muted">Select and manage a connection, then run commands through the portal backend. Credentials are never sent to the browser.</p>
|
|
</header>
|
|
|
|
<section className="mt-10">
|
|
<div className="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
|
|
<div>
|
|
<p className="font-mono text-[9px] font-bold uppercase tracking-widest text-muted">Command proxy</p>
|
|
<h2 className="mt-2 font-display text-3xl font-black uppercase">Terminal</h2>
|
|
</div>
|
|
<p className="max-w-xl text-xs leading-5 text-muted">Only the latest bounded response is shown. Commands and responses are not saved as console history.</p>
|
|
</div>
|
|
<RconConsole notice={notice} servers={servers} />
|
|
</section>
|
|
</main>
|
|
);
|
|
}
|