From 3171c9dc63788db03a6e0a1c0632ac5ad94dfa1b Mon Sep 17 00:00:00 2001
From: RizonFTW
Date: Thu, 8 Jan 2026 23:32:24 +0000
Subject: [PATCH] feat(add): add client api key support
---
app/admin/settings/page.tsx | 89 +++++++++++++++++++++++-----
app/api/admin/settings/route.ts | 6 ++
packages/core/lib/config.ts | 4 ++
packages/core/lib/system-settings.ts | 1 +
4 files changed, 84 insertions(+), 16 deletions(-)
diff --git a/app/admin/settings/page.tsx b/app/admin/settings/page.tsx
index e47603d..65b986f 100644
--- a/app/admin/settings/page.tsx
+++ b/app/admin/settings/page.tsx
@@ -69,8 +69,9 @@ interface SystemSettings {
// Pterodactyl
pterodactylUrl: string
pterodactylApiKey: string
+ pterodactylClientApiKey: string
pterodactylApi: string
-
+
// Virtfusion
virtfusionUrl: string
virtfusionApiKey: string
@@ -117,6 +118,7 @@ export default function SettingsPage() {
const [resetting, setResetting] = useState(null)
const [testingConnection, setTestingConnection] = useState(null)
const [showApiKey, setShowApiKey] = useState(false)
+ const [showApiKeyclient, setShowApiKeyclient] = useState(false)
const [showResend, setShowResend] = useState(false)
const [showCrowdin, setShowCrowdin] = useState(false)
const [showGithub, setShowGithub] = useState(false)
@@ -153,6 +155,7 @@ export default function SettingsPage() {
const [settings, setSettings] = useState({
pterodactylUrl: "",
pterodactylApiKey: "",
+ pterodactylClientApiKey: "",
pterodactylApi: "",
virtfusionUrl: "",
virtfusionApiKey: "",
@@ -189,6 +192,7 @@ export default function SettingsPage() {
// Track which fields are masked (already set)
const masked = new Set()
if (data.settings.pterodactylApiKey === MASKED_VALUE) masked.add("pterodactylApiKey")
+ if (data.settings.pterodactylClientApiKey === MASKED_VALUE) masked.add("pterodactylClientApiKey")
if (data.settings.virtfusionApiKey === MASKED_VALUE) masked.add("virtfusionApiKey")
if (data.settings.crowdinPersonalToken === MASKED_VALUE) masked.add("crowdinPersonalToken")
if (data.settings.githubToken === MASKED_VALUE) masked.add("githubToken")
@@ -255,6 +259,7 @@ export default function SettingsPage() {
body: JSON.stringify({
pterodactylUrl: settings.pterodactylUrl,
pterodactylApiKey: settings.pterodactylApiKey,
+ pterodactylClientApiKey: settings.pterodactylClientApiKey,
virtfusionUrl: settings.virtfusionUrl,
virtfusionApiKey: settings.virtfusionApiKey,
}),
@@ -776,21 +781,73 @@ export default function SettingsPage() {
-
-
-
setSettings({
- ...settings,
- pterodactylApi: e.target.value
- })}
- />
-
- {t("settings.pterodactyl.apiUrlNote")}
-
-
+
+
+
+
setSettings({
+ ...settings,
+ pterodactylApi: e.target.value
+ })}
+ />
+
+ {t("settings.pterodactyl.apiUrlNote")}
+
+
+
+
+
+
+
setSettings({
+ ...settings,
+ pterodactylClientApiKey: e.target.value
+ })}
+ disabled={maskedFields.has("pterodactylClientApiKey")}
+ />
+
+
+
+
+ {maskedFields.has("pterodactylClientApiKey") && (
+
+ )}
+
+
+ {t("settings.pterodactyl.apiKeyNoteclient")}
+
+
+
{pterodactylStatus.version && (
{t("settings.pterodactyl.version")}:
{pterodactylStatus.version}
diff --git a/app/api/admin/settings/route.ts b/app/api/admin/settings/route.ts
index d368246..06e8c1d 100644
--- a/app/api/admin/settings/route.ts
+++ b/app/api/admin/settings/route.ts
@@ -134,6 +134,7 @@ export async function GET() {
settings: {
pterodactylUrl: allSettings.pterodactyl_url || "",
pterodactylApiKey: isSuperAdmin(userRoles) && allSettings.pterodactyl_api_key ? allSettings.pterodactyl_api_key : (allSettings.pterodactyl_api_key ? "••••••••••••••••••••" : ""),
+ pterodactylClientApiKey: isSuperAdmin(userRoles) && allSettings.pterodactyl_client_api_key ? allSettings.pterodactyl_client_api_key : (allSettings.pterodactyl_client_api_key ? "••••••••••••••••••••" : ""),
pterodactylApi: allSettings.pterodactyl_api || "",
virtfusionUrl: allSettings.virtfusion_url || "",
virtfusionApiKey: isSuperAdmin(userRoles) && allSettings.virtfusion_api_key ? allSettings.virtfusion_api_key : (allSettings.virtfusion_api_key ? "••••••••••••••••••••" : ""),
@@ -241,6 +242,11 @@ export async function POST(request: Request) {
changedFields.push("Pterodactyl API Key")
}
+ if (body.pterodactylClientApiKey && body.pterodactylClientApiKey !== MASKED_VALUE) {
+ await setConfig("pterodactyl_client_api_key", body.pterodactylClientApiKey)
+ changedFields.push("Pterodactyl Client API Key")
+ }
+
if (body.virtfusionUrl) {
await setConfig("virtfusion_url", body.virtfusionUrl)
changedFields.push("Virtfusion URL")
diff --git a/packages/core/lib/config.ts b/packages/core/lib/config.ts
index b9b5d1e..d3bd106 100644
--- a/packages/core/lib/config.ts
+++ b/packages/core/lib/config.ts
@@ -5,6 +5,7 @@
* Configuration Keys - Panel Settings:
* - pterodactyl_url: Pterodactyl panel URL
* - pterodactyl_api_key: Pterodactyl admin API key
+ * - pterodactyl_client_api_key: Pterodactyl client API key
* - pterodactyl_api: Pterodactyl API endpoint path (default: /api/application)
* - virtfusion_url: Virtfusion panel URL
* - virtfusion_api_key: Virtfusion API key
@@ -51,6 +52,7 @@ import { prisma } from "./prisma"
export interface PterodactylSettings {
url: string | null
apiKey: string | null
+ clientapiKey: string | null
api: string | null
}
@@ -175,6 +177,7 @@ export async function getPanelSettings(): Promise
{
const config = await getConfigs(
"pterodactyl_url",
"pterodactyl_api_key",
+ "pterodactyl_client_api_key",
"pterodactyl_api",
"virtfusion_url",
"virtfusion_api_key",
@@ -185,6 +188,7 @@ export async function getPanelSettings(): Promise {
pterodactyl: {
url: config.pterodactyl_url,
apiKey: config.pterodactyl_api_key,
+ clientapiKey: config.pterodactyl_client_api_key,
api: config.pterodactyl_api,
},
virtfusion: {
diff --git a/packages/core/lib/system-settings.ts b/packages/core/lib/system-settings.ts
index 339ed47..295de97 100644
--- a/packages/core/lib/system-settings.ts
+++ b/packages/core/lib/system-settings.ts
@@ -8,6 +8,7 @@ export interface SystemState {
export interface PterodactylSettings {
url: string | null
apiKey: string | null
+ clientapiKey: string | null
api: string | null
}